Ejemplo n.º 1
0
 def walking(self):
     self.setimages(None)
     n = 0
     lemmap = self.lemmings.lemmap
     y0 = self.y // 16
     while self.y == y0 * 16:
         yield None
         nx = self.x + self.dir * 2
         x0 = (nx + 15) // 16
         if bget(x0, y0 + 1) == ' ':
             if bget(x0, y0 + 2) == ' ':
                 y0 += 1  # fall
         elif bget(x0, y0) != ' ':
             self.dir = -self.dir
             self.resetimages()
             continue
         else:  # climb
             y0 -= 1
             n2 = 0
             while self.y > y0 * 16:
                 self.step(0, -2)
                 if n2:
                     n2 -= 1
                 else:
                     self.seticon(lemmap['lem-walk', self.dir, n & 7])
                     n += 1
                     n2 = 2
                 yield None
         self.move(nx, self.y, lemmap['lem-walk', self.dir, n & 7])
         n += 1
         yield None
         yield None
     self.gen.append(self.falling())
Ejemplo n.º 2
0
    def frame(self):
        windline = '>>' + '^' * (curboard.width - 4) + '<<'
        curboard.winds = [windline] * curboard.height

        countholes = 0
        ymax = curboard.height - 1
        for x in range(2, curboard.width - 2):
            if bget(x, ymax) == ' ':
                countholes += 1

        xrange = []
        try:
            for delta in range(2, curboard.width):
                for x in [delta, curboard.width - delta - 1]:
                    if x in xrange: raise StopIteration
                    xrange.append(x)
        except StopIteration:
            pass

        for x in xrange:
            if countholes > curboard.width // 6 and bget(x, ymax) == ' ':
                curboard.putwall(x, ymax)
                curboard.reorder_walls()
                countholes -= 1
            for y in range(0, ymax):
                if bget(x, y) == ' ':
                    break
                curboard.killwall(x, y)
            yield None

        testing = {}

        def addlemming():
            for x, y in testing.items():
                if bget(x, y) != ' ' == bget(x, y - 1):
                    if x <= curboard.width // 2:
                        dir = 1
                    else:
                        dir = -1
                    s = Lemming(self, x * CELL - HALFCELL, (y - 2) * CELL, dir)
                    self.lemtotal += 1
                if y < ymax:
                    testing[x] = y + 1
                else:
                    del testing[x]

        for x in xrange:
            testing[x] = 1
            addlemming()
            yield None
        while testing:
            addlemming()
            yield None

        while self.lemlist:
            yield None
Ejemplo n.º 3
0
 def addlemming():
     for x, y in testing.items():
         if bget(x, y) != ' ' == bget(x, y - 1):
             if x <= curboard.width // 2:
                 dir = 1
             else:
                 dir = -1
             s = Lemming(self, x * CELL - HALFCELL, (y - 2) * CELL, dir)
             self.lemtotal += 1
         if y < ymax:
             testing[x] = y + 1
         else:
             del testing[x]
Ejemplo n.º 4
0
 def onground(self):
     for b in self.bricks:
         if b.gen:  # brick still moving
             return 0
     for px, py in self.brick_positions():
         if bget(px // CELL, py // CELL + 1) >= '#':
             return 1
     return 0
Ejemplo n.º 5
0
 def moving(self):
     import boards
     dx = dy = 0
     turned = None
     was_clear = 0
     while 1:
         if dx or dy:
             frontx = self.x + CELL + dx * (CELL + 1)
             fronty = self.y + CELL + dy * (CELL + 1)
             clear = (bget((frontx + dy) // CELL,
                           (fronty - dx) // CELL) == ' '
                      and bget((frontx - dy) // CELL,
                               (fronty + dx) // CELL) == ' ')
             if clear:
                 blocked = 0
             else:
                 blocked = (was_clear or (self.x <= 2 * CELL and dx < 0) or
                            (self.x >= boards.bwidth - 4 * CELL and dx > 0))
         else:
             blocked = 1
         if blocked:
             if turned:
                 dx, dy = turned
                 turned = None
                 continue
             self.lastmove = None
         else:
             if turned:
                 self.resetimages(dx, dy)
                 turned = None
             self.lastmove = dx, dy
             self.step(2 * dx, 2 * dy)
             self.vertical_warp()
             was_clear = clear
         yield None
         if self.wannadx != dx or self.wannady != dy:
             if ((self.wannadx and not (self.y % CELL))
                     or (self.wannady and not (self.x % CELL))):
                 turned = dx, dy
                 dx = self.wannadx
                 dy = self.wannady
Ejemplo n.º 6
0
 def moved(self, old_position):
     for b in self.bricks:
         b.set(' ')
     try:
         for px, py in self.brick_positions():
             if bget(px // CELL, py // CELL) != ' ':
                 self.restore_position(old_position)
                 return 0
         for b, (px, py) in zip(self.bricks, self.brick_positions()):
             b.follow(px, py)
     finally:
         for b in self.bricks:
             b.set('!')  # note: we need '!' < '#'
     return 1
Ejemplo n.º 7
0
        def rdig(x1, y1, x2, y2, reversed, holes=holes):
            # digs the rectangle (x1,y1,x2,y2) and marks it as
            # processed.  Also recursively mark as processed all existing
            # holes that are pacman-connected to the rectangle.
            xrange = range(x1, x2)
            yrange = range(y1, y2)
            if not reversed:
                xrange.reverse()
                yrange.reverse()
            if len(xrange) > len(yrange):
                xylist = [(x, y) for x in xrange for y in yrange]
            else:
                xylist = [(x, y) for y in yrange for x in xrange]
            t = 0
            for x, y in xylist:
                if bget(x, y) == '#':
                    curboard.killwall(x, y)
                    if t == 0:
                        yield None
                        t = 2
                    else:
                        t -= 1
                holes.setdefault((x, y), 0)
            fill = []
            for x in range(x1, x2 - 1):
                for y in range(y1, y2 - 1):
                    fill.append((x, y))
            for x, y in fill:
                if ((x, y) in holes and (x, y + 1) in holes
                        and (x + 1, y) in holes and (x + 1, y + 1) in holes):
                    if (holes[x, y] == 0 or holes[x, y + 1] == 0
                            or holes[x + 1, y] == 0
                            or holes[x + 1, y + 1] == 0):

                        holes[x, y] = 1
                        holes[x, y + 1] = 1
                        holes[x + 1, y] = 1
                        holes[x + 1, y + 1] = 1
                        fill.append((x + 1, y))
                        fill.append((x - 1, y))
                        fill.append((x, y + 1))
                        fill.append((x, y - 1))
Ejemplo n.º 8
0
 def onground(self):
     if self.y & 15:
         return 0
     x0 = (self.x + 15) // 16
     y0 = self.y // 16 + 2
     return bget(x0, y0) != ' ' == bget(x0, y0 - 1)
Ejemplo n.º 9
0
    def digwalls(self):
        import boards
        holes = {}
        for x in range(2, boards.width - 2):
            y = boards.height - 1
            if bget(x, 0) == '#' or bget(x, y) == '#':
                if bget(x, 0) == ' ': curboard.putwall(x, 0)
                if bget(x, y) == ' ': curboard.putwall(x, y)
            curboard.reorder_walls()
            for y in range(1, boards.height - 1):
                if bget(x, y) == ' ':
                    holes[x, y] = 0
            if x % 7 == 0:
                yield None

        # 'holes' maps coordinates (x,y) to 0 (not processed)
        #                                or 1 (processed).
        # All processed holes are pacman-connected.

        def rdig(x1, y1, x2, y2, reversed, holes=holes):
            # digs the rectangle (x1,y1,x2,y2) and marks it as
            # processed.  Also recursively mark as processed all existing
            # holes that are pacman-connected to the rectangle.
            xrange = range(x1, x2)
            yrange = range(y1, y2)
            if not reversed:
                xrange.reverse()
                yrange.reverse()
            if len(xrange) > len(yrange):
                xylist = [(x, y) for x in xrange for y in yrange]
            else:
                xylist = [(x, y) for y in yrange for x in xrange]
            t = 0
            for x, y in xylist:
                if bget(x, y) == '#':
                    curboard.killwall(x, y)
                    if t == 0:
                        yield None
                        t = 2
                    else:
                        t -= 1
                holes.setdefault((x, y), 0)
            fill = []
            for x in range(x1, x2 - 1):
                for y in range(y1, y2 - 1):
                    fill.append((x, y))
            for x, y in fill:
                if ((x, y) in holes and (x, y + 1) in holes
                        and (x + 1, y) in holes and (x + 1, y + 1) in holes):
                    if (holes[x, y] == 0 or holes[x, y + 1] == 0
                            or holes[x + 1, y] == 0
                            or holes[x + 1, y + 1] == 0):

                        holes[x, y] = 1
                        holes[x, y + 1] = 1
                        holes[x + 1, y] = 1
                        holes[x + 1, y + 1] = 1
                        fill.append((x + 1, y))
                        fill.append((x - 1, y))
                        fill.append((x, y + 1))
                        fill.append((x, y - 1))

        def joined(x1, y1, x2, y2, holes=holes, boards=boards):
            # returns
            #    1 if the rectangle (x1,y1,x2,y2) is pac-connected to
            #        some already-processed holes
            #    0 if it is not
            #   -1 if (x1,y1,x2,y2) is out of the screen
            if x1 < 2 or y1 < 1 or x2 > boards.width - 2 or y2 > boards.height - 1:
                return -1
            accum1 = accum2 = 0
            for x in range(x1, x2):
                if holes.get((x, y1 - 1)):
                    accum1 += 1
                    if accum1 == 2:
                        return 1
                else:
                    accum1 = 0
                if holes.get((x, y2)):
                    accum2 += 1
                    if accum2 == 2:
                        return 1
                else:
                    accum2 = 0
            accum1 = accum2 = 0
            for y in range(y1, y2):
                if holes.get((x1 - 1, y)):
                    accum1 += 1
                    if accum1 == 2:
                        return 1
                else:
                    accum1 = 0
                if holes.get((x2, y)):
                    accum2 += 1
                    if accum2 == 2:
                        return 1
                else:
                    accum2 = 0
            return 0

        if not holes:
            holes[boards.width // 2, boards.height // 2] = 0
        holeslist = holes.keys()
        random.shuffle(holeslist)
        startx, starty = holeslist.pop()
        # make the hole larger (2x2) towards the center of the board
        if startx > boards.width // 2:
            startx -= 1
        if starty > boards.height // 2:
            starty -= 1
        # initial 2x2 hole
        for t in rdig(startx, starty, startx + 2, starty + 2, 0):
            yield t

        dlist = [
            (0, 0, 1, 0, 0, -1),
            (0, 0, 1, 0, 0, 0),  # right
            (0, 0, 0, 1, -1, 0),
            (0, 0, 0, 1, 0, 0),  # bottom
            (-1, 0, 0, 0, -1, -1),
            (-1, 0, 0, 0, -1, 0),  # left
            (0, -1, 0, 0, -1, -1),
            (0, -1, 0, 0, 0, -1),  # top
        ]
        while holeslist:
            random.shuffle(dlist)
            pending = holeslist
            holeslist = []
            progress = 0
            for x, y in pending:
                if holes[x, y] != 0:
                    continue
                for dx1, dy1, dx2, dy2, dx, dy in dlist:
                    x1 = x + dx
                    y1 = y + dy
                    x2 = x1 + 2
                    y2 = y1 + 2
                    result = 0
                    while result == 0:
                        result = joined(x1, y1, x2, y2)
                        if result == 1:
                            # rectangle (x1,y1,x2,y2) is good
                            for t in rdig(
                                    x1, y1, x2, y2, dx1 < 0 or dy1 < 0
                                    or dx2 < 0 or dy2 < 0):
                                yield t
                            progress = 1
                            break
                        x1 += dx1
                        y1 += dy1
                        x2 += dx2
                        y2 += dy2
                    else:
                        # rectangle (x1,y1,x2,y2) is too large for the screen
                        # failure
                        continue
                    break
                else:
                    # no successful direction found from this point
                    holeslist.append((x, y))  # try again later
            if not progress:
                # deadlocked situation, add a new random hole
                x = random.randrange(2, boards.width - 2)
                y = random.randrange(1, boards.height - 1)
                holeslist.insert(0, (x, y))
                holes.setdefault((x, y), 0)
            yield None

        # pattern transformation:
        #    X.          ..
        #    ...    -->  ...
        #     .X          .X
        progress = 1
        while progress:
            progress = 0
            for y in range(1, boards.height - 1):
                for x in range(3, boards.width - 3):
                    if (' ' == bget(x, y) == bget(x + 1, y) == bget(x - 1, y)
                            == bget(x, y + 1) == bget(x, y - 1)):
                        if '#' == bget(x - 1, y - 1) == bget(x + 1, y + 1):
                            curboard.killwall(x - 1, y - 1)
                            progress = 1
                        elif '#' == bget(x + 1, y - 1) == bget(x - 1, y + 1):
                            curboard.killwall(x + 1, y - 1)
                            progress = 1
            yield None
Ejemplo n.º 10
0
 def anywall(x1, y1, x2, y2):
     for tx in range(x1, x2):
         for ty in range(y1, y2):
             if bget(tx, ty) == '#':
                 return 1
     return 0
Ejemplo n.º 11
0
    def frame(self):
        heights = {1: curboard.height, curboard.width - 2: curboard.height}
        ymax = curboard.height - 1
        maxheight = curboard.height * 3 // 4
        for x in range(2, curboard.width - 2):
            if bget(x, ymax) == ' ':
                curboard.putwall(x, ymax)
            height = 1
            for y in range(ymax - 1, -1, -1):
                if bget(x, y) == '#':
                    if height == maxheight:
                        curboard.killwall(x, y)
                    else:
                        height += 1
            heights[x] = height
        xlist = range(2, curboard.width - 2)
        random.shuffle(xlist)
        for x in xlist:
            h = heights[x]
            x1 = x2 = x
            while heights[x1 - 1] == h:
                x1 -= 1
            while heights[x2] == h:
                x2 += 1
            parts = (x2 - x1) // 8
            if not parts:
                continue
            left = 0
            if heights[x1 - 1] > h:
                x1 -= 1
                left += 1
            right = parts + 1
            if heights[x2] > h:
                x2 += 1
                right -= 1
            for p in range(left, right):
                x = x1 + ((x2 - x1 - 1) * p + parts // 2) // parts
                y = ymax
                for i in range(2):
                    while bget(x, y) == '#':
                        y -= 1
                    if y >= 3:
                        curboard.putwall(x, y)
                        heights[x] += 1
        curboard.reorder_walls()

        walls_by_pos = curboard.walls_by_pos
        moves = 1
        s = 8.0
        while moves:
            moves = 0
            for y in range(curboard.height - 3, -1, -1):
                for x in range(2, curboard.width - 2):
                    if ((y, x) in walls_by_pos
                            and (y + 1, x) not in walls_by_pos):
                        y0 = y
                        while (y0 - 1, x) in walls_by_pos:
                            y0 -= 1
                        w = curboard.killwall(x, y0, 0)
                        curboard.putwall(x, y + 1, w)
                        moves = 1
            curboard.reorder_walls()
            for i in range(int(s) + 2):
                yield None
            s *= 0.95
        self.ready = 1
        while 1:
            yield None
Ejemplo n.º 12
0
 def stopping(self):
     self.move(self.x, -self.ico.h)
     positions = [(py // CELL, px // CELL)
                  for px, py in self.brick_positions() if py >= 0]
     positions.sort()
     positions = [(px, py) for py, px in positions]
     for b in self.bricks:
         b.stop(self.tetris)
         if b.ty < 0:
             b.remove()
     self.bricks = []
     staticbricks = self.tetris.staticbricks
     pts = 500
     while 1:
         for px, py in positions:
             y = py
             x1 = px
             while (x1 - 1, y) in staticbricks:
                 x1 -= 1
             if bget(x1 - 1, y) != '#':
                 continue
             x2 = px
             while (x2, y) in staticbricks:
                 x2 += 1
             if bget(x2, y) != '#':
                 continue
             if x2 - x1 < 2:
                 continue
             # full line
             ico = images.sprget(Bubble.exploding_bubbles[0])
             self.tetris.score[self.bubber] = self.tetris.score.get(
                 self.bubber, 0) + 1
             xlist = range(x1, x2)
             for x in xlist:
                 s = ActiveSprite(ico,
                                  x * CELL + random.randrange(CELL) - CELL,
                                  y * CELL + random.randrange(CELL) - CELL)
                 s.gen.append(s.die(Bubble.exploding_bubbles))
                 s = staticbricks[x, y]
                 points(x * CELL + HALFCELL, y * CELL + HALFCELL, s, pts)
                 s.remove()
             if pts == 500:
                 self.play(images.Snd.Fruit)
             elif pts == 4000:
                 self.play(images.Snd.Extralife)
             else:
                 self.play(images.Snd.Extra)
             pts *= 2
             for y in range(py - 1, -1, -1):
                 if not [x for x in xlist if (x, y) in staticbricks]:
                     break
                 for t in range(4):
                     yield None
                 if [x for x in xlist if (x, y + 1) in staticbricks]:
                     break
                 for x in xlist:
                     if (x, y) in staticbricks:
                         staticbricks[x, y].shiftdown()
             yield None
             break
         else:
             break
     if self.tetris.ready < 2:
         self.gen.append(self.playing_bubble(self))