25
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ぷよぷよ in python

Last updated at Posted at 2014-09-26

ぷよぷよ in python

haskellの記事眺めてたらこんなの見付けた。
http://qiita.com/tanakh/items/c2e157f0a48667370b0e

問題はこっち。
http://okajima.air-nifty.com/b/2011/01/2011-ffac.html

まだ全然haskell力(はすけるちから)が足りないからさっぱり理解できないので、
とりあえずhaskellは置いといて、
せっかくなのでpythonで書いてみる事にした。

なんか

  • pythonの文字列がindex指定で書き換えられないからbytearrayにしたり
  • 探索で隣同士で再帰しちゃって無限再帰しちゃったり

予想外に手間取ったけど、2時間ちょうどくらい…かな。
いや、ちょっと超えちゃったかな。まぁいいや。

c++で書けば良かった。
for(int i=0; i<10; ++i) 形式のループが使えないのがものすごい不便。

ぷよの箱の横幅/縦幅はベタ書きしてないので、縦横広がってもそのまま動くと思う。
まぁ縦横広がる事があるのかわからんけど。

動かしたのはpython2.7.6

puyo.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

puyo_array = [
    "  GYRR",
    "RYYGYG",
    "GYGYRR",
    "RYGYRG",
    "YGYRYG",
    "GYRYRG",
    "YGYRYR",
    "YGYRYR",
    "YRRGRG",
    "RYGYGG",
    "GRYGYR",
    "GRYGYR",
    "GRYGYR",
]

# pythonの文字列はindex指定で書き換えられないのでbytearrayに変換
puyo = [ bytearray(line) for line in puyo_array ]

def show():
    print "-" * 8
    for x in puyo:
        print "|{}|".format(x)
    print "-" * 8
    print

def erase():
    u'''4つ以上繋がってるの消す'''
    class Way:
        u'''どっちから探索来たか'''
        UP = 1
        DOWN = 2
        LEFT = 3
        RIGHT = 4

    def mark(dx, dy, p, dst = None):
        u'''隣接してる同色を辿る'''
        if dx < 0 or dy < 0:
            return

        try:
            if puyo[dy][dx] == p:
                points.append((dx, dy))
                # 入ってきた方向に探索すると無限再帰するので
                if dst != Way.RIGHT:
                    mark(dx+1, dy, p, Way.LEFT)
                if dst != Way.UP:
                    mark(dx, dy+1, p, Way.DOWN)
                if dst != Way.LEFT:
                    mark(dx-1, dy, p, Way.RIGHT)
                if dst != Way.DOWN:
                    mark(dx, dy-1, p, Way.UP)
        except IndexError as e:
            pass

    for y, line in enumerate(puyo):
        for x, p in enumerate(line):
            if chr(p) != " ":
                points = []
                mark(x, y, puyo[y][x])

                if len(points) >= 4:    # 4連結以上
                    for x, y in points:
                        puyo[y][x] = " " # 消す

def drop():
    u'''浮いてるの落とす'''
    height = len(puyo)
    assert(height > 0)
    width = len(puyo[0])
    is_zenkeshi = True
    for x in range(width):
        for y in range(0, height)[::-1]:    # 下から嘗める
            if chr(puyo[y][x]) == " ":
                for y2 in range(0, y+1)[::-1]:
                    if chr(puyo[y2][x]) != " ":
                        puyo[y][x] = puyo[y2][x]
                        puyo[y2][x] = " "
                        break
            else:
                is_zenkeshi = False
    # 全部消えてたらTrue
    return is_zenkeshi


if __name__ == '__main__':
    import itertools
    for i in itertools.count():
        print i
        show()

        erase()
        if drop():
            break
    
    print "finish!!"
    show()
25
26
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?