Added preliminary level 4. No lasers yet.
This commit is contained in:
parent
5904d29aef
commit
b61f54963d
|
@ -1 +1,8 @@
|
|||
This is a good game.
|
||||
|
||||
|
||||
The rolling boulder task in level 1 is not guaranteed to be solvable, because
|
||||
you might not be able to move an arrow block to the position you need to move
|
||||
it to. However, this scenario is so unlikely that we have chosen to ignore it.
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
# This file is part of ROBOTGAME
|
||||
#
|
||||
# ROBOTGAME is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# ROBOTGAME is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# ROBOTGAME. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
|
||||
#
|
||||
# level1.py
|
||||
# --------------------
|
||||
# date created : Fri Aug 10 2012
|
||||
# copyright : (C) 2012 Niels G. W. Serup
|
||||
# maintained by : Niels G. W. Serup <ns@metanohi.name>
|
||||
|
||||
"""
|
||||
The fourth level.
|
||||
"""
|
||||
|
||||
import os
|
||||
import pygame
|
||||
import random
|
||||
import re
|
||||
import itertools
|
||||
|
||||
import level
|
||||
import player
|
||||
import tile
|
||||
import block
|
||||
import boulder
|
||||
import lever
|
||||
import mirror
|
||||
import trigger
|
||||
import misc
|
||||
import worldobject
|
||||
|
||||
import logic.lasermirror as lm
|
||||
|
||||
class Level4(level.Level):
|
||||
def __init__(self, game, graphics_dir, paused=False):
|
||||
level.Level.__init__(self, game, graphics_dir,
|
||||
size=(64 * 16, 48 * 16), paused=paused)
|
||||
|
||||
self.dimensions = 16, 16
|
||||
|
||||
for i in range(self.dimensions[0]):
|
||||
for j in range(self.dimensions[1]):
|
||||
self.tiles.append(
|
||||
tile.Tile(self, i*64, (j+1)*48,
|
||||
self.imgs['indoor%d' % random.randint(1, 6)]))
|
||||
|
||||
self.draw_background()
|
||||
|
||||
playfield = lm.generate_simple_playfield(16)
|
||||
|
||||
for (x, y), t in playfield.items():
|
||||
x, y = 64 * x, 48 * (y + 1)
|
||||
self.objects.append({
|
||||
lm.Mirror: mirror.Mirror(self, x, y, random.choice((True, False))),
|
||||
lm.Lever: lever.Lever(
|
||||
self, x, y, [], toggling=True,
|
||||
anim='lever_leftright' if x == 0 or x == 15 * 64
|
||||
else 'lever_updown'),
|
||||
lm.Target: block.Block(self, x, y, self.imgs['block3'],
|
||||
movable=False),
|
||||
lm.Blocker: block.Block(self, x, y, self.imgs['block1'],
|
||||
movable=False)
|
||||
}[t])
|
||||
mirrors = list(filter(lambda obj: isinstance(obj, mirror.Mirror),
|
||||
self.objects))
|
||||
levers = list(filter(lambda obj: isinstance(obj, lever.Lever),
|
||||
self.objects))
|
||||
random.shuffle(levers)
|
||||
for l in levers:
|
||||
m = min(mirrors, key=lambda m: misc.manhattan_dist(
|
||||
(m.x, m.y), (l.x, l.y)))
|
||||
mirrors.remove(m)
|
||||
l.links.append((lambda m: lambda setting: m.rotate())(m))
|
||||
|
||||
self.player.set_pos(64 * 7, 48 * 2)
|
||||
self.player.set_init_pos()
|
||||
|
||||
|
||||
def restart(self):
|
||||
for obj in self.objects:
|
||||
obj.reset_pos()
|
||||
|
|
@ -85,7 +85,9 @@ class Loader(object):
|
|||
('arrow_down', os.path.join('matt', 'down')),
|
||||
('arrow_left', os.path.join('matt', 'right')),
|
||||
|
||||
('stairs', 'stairs')]
|
||||
('stairs', 'stairs'),
|
||||
|
||||
('mirror', 'mirror')]
|
||||
):
|
||||
|
||||
self.imgs[anim] = []
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
#
|
||||
# lasermirror.py
|
||||
# --------------------
|
||||
# date created : Tue Aug 7 2012
|
||||
# copyright : (C) 2012 Niels G. W. Serup
|
||||
# date created : Tue Aug 7 2016
|
||||
# copyright : (C) 2016 Niels G. W. Serup
|
||||
# maintained by : Niels G. W. Serup <ns@metanohi.name>
|
||||
|
||||
"""
|
||||
|
@ -33,6 +33,7 @@ import random
|
|||
import itertools
|
||||
from robotgame.logic.direction import *
|
||||
import robotgame.logic.rollingstone as rstone
|
||||
from robotgame.logic.rollingstone import Blocker
|
||||
import robotgame.misc as misc
|
||||
|
||||
class Mirror(object):
|
||||
|
@ -46,12 +47,12 @@ class Target(object):
|
|||
|
||||
def generate_simple_playfield(nmirrors):
|
||||
"""
|
||||
Generate a completable 12x12 playfield where:
|
||||
Generate a completable 16x16 playfield where:
|
||||
* there are four laser sources, one in each corner
|
||||
+ the one in the upper left corner (0, 0) starts in (0, -1) heading down
|
||||
+ the one in the upper right corner (11, 0) starts in (12, 0), heading left
|
||||
+ the one in the lower right corner (11, 11) starts in (11, 12), heading up
|
||||
+ the one in the lower left corner (0, 11) starts in (-1, 11), heading right
|
||||
+ the one in the upper right corner (15, 0) starts in (16, 0), heading left
|
||||
+ the one in the lower right corner (15, 15) starts in (15, 16), heading up
|
||||
+ the one in the lower left corner (0, 15) starts in (-1, 15), heading right
|
||||
* there are four laser targets
|
||||
* there are nmirrors mirrors
|
||||
* there are nmirrors levers
|
||||
|
@ -59,14 +60,14 @@ def generate_simple_playfield(nmirrors):
|
|||
|
||||
Return playfield : {(x, y): Target | Mirror | rstone.Blocker | Lever}
|
||||
"""
|
||||
playfield = {(4, 4): Target,
|
||||
(7, 4): Target,
|
||||
(4, 7): Target,
|
||||
(7, 7): Target,
|
||||
(5, 5): rstone.Blocker,
|
||||
(5, 6): rstone.Blocker,
|
||||
(6, 5): rstone.Blocker,
|
||||
(6, 6): rstone.Blocker,
|
||||
playfield = {(6, 6): Target,
|
||||
(9, 6): Target,
|
||||
(6, 9): Target,
|
||||
(9, 9): Target,
|
||||
(7, 7): rstone.Blocker,
|
||||
(7, 8): rstone.Blocker,
|
||||
(8, 7): rstone.Blocker,
|
||||
(8, 8): rstone.Blocker,
|
||||
}
|
||||
succs = lambda d: d
|
||||
source_direc = Up
|
||||
|
@ -75,23 +76,21 @@ def generate_simple_playfield(nmirrors):
|
|||
nm = nmirrors / missing
|
||||
nmirrors -= nm
|
||||
stone_playfield, _ = rstone.generate_simple_playfield(
|
||||
5, 5, nm, 0, False, False)
|
||||
7, 7, nm, 0, False, False)
|
||||
for pos, direc in stone_playfield.items():
|
||||
if direc is not None and pos >= (0, 0):
|
||||
playfield[_adjust(source_direc, 12 - 1, 12 - 1, *pos)] = Mirror
|
||||
playfield[_adjust(source_direc, 16 - 1, 16 - 1, *pos)] = Mirror
|
||||
succs = (lambda s: lambda d: succ(s(d)))(succs)
|
||||
source_direc = succ(source_direc)
|
||||
|
||||
occup = set(playfield.keys())
|
||||
emptys = list(
|
||||
set([(0, y) for y in filter(lambda y: (1, y) not in occup, range(12))]
|
||||
+ [(11, y) for y in filter(lambda y: (10, y) not in occup, range(12))]
|
||||
+ [(x, 0) for x in filter(lambda x: (x, 1) not in occup, range(12))]
|
||||
+ [(x, 11) for x in filter(lambda x: (x, 10) not in occup, range(12))])
|
||||
- occup)
|
||||
if len(emptys) < nlevers:
|
||||
raise Exception("Not enough space for all levers!")
|
||||
for pos in misc.pick_random_elements(emptys, nlevers):
|
||||
for _ in range(nlevers):
|
||||
# This needs to be optimized...
|
||||
occup = set(playfield.keys())
|
||||
emptys = list(
|
||||
set([(0, y) for y in filter(lambda y: (1, y) not in occup, range(16))]
|
||||
+ [(15, y) for y in filter(lambda y: (10, y) not in occup, range(16))]
|
||||
+ [(x, 0) for x in filter(lambda x: (x, 1) not in occup, range(16))]
|
||||
+ [(x, 15) for x in filter(lambda x: (x, 10) not in occup, range(16))]) - occup)
|
||||
pos = emptys[random.randrange(len(emptys))]
|
||||
playfield[pos] = Lever
|
||||
return playfield
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ def generate_simple_playfield(width, height, nturns, nstones,
|
|||
break
|
||||
else:
|
||||
allowed = set(range(0, height)) - set(not_allowed_y)
|
||||
if missing == 3:
|
||||
if missing <= 3:
|
||||
allowed -= set((height - 1,))
|
||||
if missing == nturns:
|
||||
allowed -= set((0,))
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# This file is part of ROBOTGAME
|
||||
#
|
||||
# ROBOTGAME is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# ROBOTGAME is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# ROBOTGAME. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
|
||||
#
|
||||
# mirror.py
|
||||
# --------------------
|
||||
# date created : Fri Aug 10 2012
|
||||
# copyright : (C) 2012 Niels G. W. Serup
|
||||
# maintained by : Niels G. W. Serup <ns@metanohi.name>
|
||||
|
||||
"""
|
||||
A generic mirror for drawing.
|
||||
"""
|
||||
|
||||
import pygame
|
||||
|
||||
import worldobject
|
||||
|
||||
class Mirror(worldobject.WorldObject):
|
||||
def __init__(self, level, x, y, left_up=True):
|
||||
self.__dict__.update(locals())
|
||||
worldobject.WorldObject.__init__(self, level, x, y)
|
||||
|
||||
self.in_rotation = False
|
||||
|
||||
self.frame = 7
|
||||
self.anim_speed = 12
|
||||
self._half_anim_len = len(self.level.imgs['mirror']) / 2
|
||||
|
||||
def rotate(self):
|
||||
if self.in_rotation:
|
||||
return
|
||||
self.in_rotation = True
|
||||
self.left_up = not self.left_up
|
||||
self.frame = 0
|
||||
|
||||
def update(self, e, t, dt):
|
||||
if self.in_rotation:
|
||||
top = self._half_anim_len - 1
|
||||
self.frame = min(self.frame + self.anim_speed * dt, top)
|
||||
if self.frame == top:
|
||||
self.in_rotation = False
|
||||
|
||||
worldobject.WorldObject.update(self, e, t, dt)
|
||||
|
||||
def draw(self, window):
|
||||
fn = self.frame + 1 if not self.left_up else self.frame + self._half_anim_len
|
||||
self.img = self.level.imgs['mirror'][int(fn)]
|
||||
window.blit(self.img, (self.x - 32 - self.level.camera_x,
|
||||
self.y - self.img.get_size()[1] + 24
|
||||
- self.level.camera_y))
|
|
@ -7,3 +7,7 @@ def pick_random_elements(xs, n):
|
|||
yield xs[i1]
|
||||
xs[i1] = xs[i]
|
||||
|
||||
def manhattan_dist(p0, p1):
|
||||
x0, y0 = p0
|
||||
x1, y1 = p1
|
||||
return abs(x1 - x0) + abs(y1 - y0)
|
||||
|
|
|
@ -8,7 +8,7 @@ from robotgame.logic.direction import *
|
|||
class LaserMirrorTest(unittest.TestCase):
|
||||
def test_playfield_generation(self):
|
||||
print()
|
||||
playfield = generate_simple_playfield(13)
|
||||
playfield = generate_simple_playfield(16)
|
||||
print_playfield(playfield, 12, 12)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Reference in New Issue