SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

よろずプログラマーのためのPython導入ガイド

Java meets Python - 第6回 配列と別れる50の方法(3) ライフゲーム

よろずプログラマーのためのPython導入ガイド (8)

なごり雪:コードを巡る旅の縁(よすが)に

 同じ景色を眺めるにしても、思い入れがあるのとないのとでは、その感動も違ってきます。そこで、漠然とコードを眺めるのではなく、構造化ブログラミング〔SP〕とオブジェクト指向プログラミング〔OOP〕との違いを示しながら、その相互理解を深めます。

そこに生命体が誕生するのは

 任意の生命体は、隣接する他の生命体の数によって次世代の状態(誕生/生存/死滅)が決定します。

class LifeGamePanel(JPanel):
    def locateLife(self):
        points = [(x, y)
            for y in range(self.dim)
            for x in range(self.dim)]
        for x, y in points:
            self.items.append(Life(x, y))
    def addNeighbor(self):
        for e in self.items:
            self.addNeighbor1(e)
    def addNeighbor1(self, life):
        ix = life.x
        iy = life.y
        points = [(x, y)
            for y in (iy-1, iy, iy+1)
            for x in (ix-1, ix, ix+1)]
        for x, y in points:
            if (x, y) == (ix, iy): continue
            life.add(self.detect(x, y))
    def detectLife(self, e):
        edge = Life.Edge
        return self.detect(e.x/edge, e.y/edge)

 メソッドlocateLifeは、生命体Lifeをパネル全面に配置します。

 メソッドaddNeighborは、各生命体ごとに隣接する8つの生命体(Nullを含む)を登録します。実際の処理は、補助関数addNeighbor1に委ねます。

 メソッドdetectLifeは、イベントeが発生したときに、その座標e.x/e.yに位置する生命体を検出detectします。

class LifeGamePanel(JPanel):
    def nextGeneration(self):
        self.updateFuture()
        self.updatePresent()
        self.repaint()
    def updateFuture(self):
        for e in self.items:
            e.updateFuture()
    def updatePresent(self):
        for e in self.items:
            e.updatePresent()

 メソッドnextGenerationは、生命体の状態(誕生/生存/死滅)を更新します。メソッドupdateFuture/updatePresentは、現世/次世代の生命体の状態を更新します。どちらも、実際の処理は各生命体eに委ねます。

ゲームの達人:ゲームを始める前に

 パズルゲームでは、空いたマス目とそれを囲む4つのコマとの対話が必要でした。ライフゲームでは、対象の生命体とそれを囲む8つの生命体との対話が必要です。

 パズルゲームではコマの配置が変るので、移動する度にそれを囲むコマを特定する必要がありました。ライフゲームでは生命体の配置は変わりませんが、それを囲む8つの生命体との対話が鍵となります。なぜなら、オブジェクト指向の醍醐味は、そのコラボレーションにあるからです。

class LifeGamePanel(JPanel):
    def initialize(self):
        self.items = []
        self.locateLife()
        self.addNeighbor()

 メソッドinitializeは、生命体をパネルに配置します。このとき、ボードからはみ出さないように注意します。最後に、隣接する生命体を登録します。

ゲームの達人:if/switch が消え、最後に生き残るのは

 巨大な一枚岩のクラスは、孤独な生命体のようなものです。アジャイル開発では、そのようなクラスは短命に終わります。

class Life:
    def updateFuture(self):
        n = self.neighbors()
        if n == 2:
            self.future = self.present
        elif n == 3:
            self.future = True
        else:
            self.future = False

 メソッドupdateFutureは次世代の生命体の生死を決定します。neighborsを利用して、その周囲に生存する生命体の数を獲得します。要求仕様(ルール)に従って、その周囲に2つの生命体が生存する場合、現在の生死状態をそのまま次世代に引き継ぐのでpresentを設定します。その周囲に3つの生命体が生存する場合、次の世代でもその生命体は生存するのでTrueを設定します。上記以外の場合、次の世代でその生命体は死滅するので、Falseを設定します。

【付記】
 さらに OOP を極めると、メソッド updateFuture 内の if/elif/else も消す事ができます。その話題については、別の機会に紹介します。
class Life:
    def neighbors(self):
        return len([None for e in self.neighbor if e.present])

 メソッド neighbors は、隣接する生命体の生存数をリターン値とします。

《Tea Break》old-timer には根強い人気
 switchの魅力は忘れ難く「なごり惜しい」気持ちは、分からないでもありません。Pythonに限らず、ハイブリッド型の言語では、純粋なOOP言語と違ってプログラマーの選択に委ねられます。switch文は、ハードコーディングの象徴であり、OOPではタブーのひとつとされています。しかし、その誘惑に抗えないプログラマー心理もあってか、old-timerから寄せられるswitch待望論があるのも事実です。3項演算子に相当する構文が導入されるなど、近い将来switchが導入されるなら、old-timerには朗報です。このような論議に興味のある皆さんは、1970-80年代の論文を紐解くのも一興です。

次のページ
イベント処理

この記事は参考になりましたか?

よろずプログラマーのためのPython導入ガイド連載記事一覧

もっと読む

この記事の著者

小泉ひよ子とタマゴ倶楽部(コイズミヒヨコトタマゴクラブ)

http://tamago-club.cocolog-nifty.com/「楽しくなければ仕事じゃない」が私たちのモットー。99%の苦悩の連続も、1%の成功に報われます。だからこそ、この仕事が楽しくて仕方がないのです。楽をするための努力なら惜しみません。何もせず楽をしているのと、努力をしたから楽ができるのと...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

伊藤うさぎ(イトウ ウサギ)

ペンネームの「由来は」と言うと。苗字の方は、セミナー研修で同じチームになった、3人の合体ユニット名 [I:石塚, T:田川, O:尾沢] から来ています。名前の方は、同じ干支(卯:1987 年生)に因んだものです。既に2人は卒業して、残る1人がその名跡を継承しています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2252 2008/06/13 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー