《付録》HoneyComb3.py
# -*- coding: utf-8 -*- #=============================================================================== # Copyright (C) 2000-2008, 小泉ひよ子とタマゴ倶楽部 # # Change History: WPF examples # 2008/01/25, IronPython 1.1.1 (download) # 2008/08/22, IronPython 1.1.2 (download) # 2008/03/16, ver.2.0, WPF # 2008/00/00, ver.2.1, IronPython 1.1.2 # Change History: Games # 1988/05, Smalltalk # 2004/09, Java # 2005/02, C# # 2005/03, Jython #=============================================================================== from hexagon import HexStone from HoneyContext import * ## -------------------- class Ostone(object): _bounds = (1, -2), (2, 0), (1, 2), _bounds = list(_bounds)+[(-x, -y) for x, y in _bounds] onColor = Cyan ; offColor = Black; def __init__(self, client, x, y, state, Stroke=None, Fill=None): self.client = client self.name = self._name (x, y) self.shape = self._shape(x, y, Stroke, Fill) self.neighbors = [None]*6 def __repr__(self): return self.name def _name(self, x, y): s1 = s2 = "_%d" if x<0: x = -x; s1 = "_"+s1; if y<0: y = -y; s2 = "_"+s2; return (s1+s2)%(x, y) def _shape(self, x, y, Stroke, Fill): gap = 1 x = HexStone._dx + x * (HexStone._width +gap) y = HexStone._dy + y * (HexStone._height+gap) s = Polygon( Name=self.name, HorizontalAlignment=HorizontalAlignment.Center, VerticalAlignment=VerticalAlignment.Center, Stroke=Stroke, Fill=Fill, Points=self.pointCollection([Point(x+dx*2, y+dy*2) for dx, dy in HexStone(x, y, False).vertices]), ) s.MouseDown += self.mouseDown s.MouseUp += self.mouseUp return s def mouseDown(self, sender, e): print ">>>", sender.Name, sender.Fill def mouseUp(self, sender, e): self._turnOff() self._reset() off, on = self.offColor, self.onColor; s = self.shape.Stroke ; self.shape.Stroke = (off, on)[s == off] self._setUp() self._turnOn() def update(self, offset): self._turnOff() target = self.neighbors[offset] if target: self._setUp([self]+target._detect(offset)) self._turnOn() def _detect(self, offset): s = [self] pivot = self.neighbors[offset] if pivot: s += pivot._detect(offset) return s def _reset(self): self.client.reset(self) def _setUp(self, targets=None): if not targets: targets = self._detect(0) self.client.setUp(targets) def _turnOn(self): self._turn(self.onColor) def _turnOff(self): self._turn(self.offColor) def _turn(self, color): self.client.turnOver(color) def pointCollection(self, vertices): s = PointCollection() for e in vertices: s.Add(e) return s def addNeighbors(self, x, y, matrix): self._clearNeighbor() for i, (dx, dy) in enumerate(self._bounds): e = matrix[self._name(x+dx, y+dy)] e.neighbors[(i+3)%6] = self self._addNeighbor(e) def _clearNeighbor(self): self.neighbors = [] def _addNeighbor(self, cell): self.neighbors.append(cell) ## -------------------- class CombStone(Ostone): def __init__(self, client, x, y): super(self.__class__, self).__init__(client, x, y, state=False, Stroke=Brushes.Black, Fill=Brushes.Green) class BlackStone(Ostone): def __init__(self, client, x, y): super(self.__class__, self).__init__(client, x, y, state=False, Stroke=Brushes.Black, Fill=Brushes.Black) class WhiteStone(Ostone): def __init__(self, client, x, y): super(self.__class__, self).__init__(client, x, y, state=False, Stroke=Brushes.Black, Fill=Brushes.White) class NullStone(Ostone): def __init__(self, client, x, y): super(self.__class__, self).__init__(client, x, y, state=False, Stroke=Brushes.Gray, Fill=None) ## --------------------
第7章 オセロゲーム(trinity/hexagon)8/24, IronPython
‖記事一覧‖ C#.use(better, IronPython=”WPF”)
IronPython で学ぶ WPF プログラミングの世界
等方向に隣接するオブジェクト群を検出する
ゲーム版に生息するオブジェクト群は、自分と隣接する存在だけを知っています。また、これらのオブジェクト群はマトリックス管理のもとで、特定の座標系には依存しません。
相手の領地を奪うときには、特定の方向に自分の領地があるかを知る必要があります。その場合にも「オフセット」を使って、任意の方向にある他のオブジェクト群の存在を把握できます。
たとえば、左下方向にあるオブジェクトを知るには、オフセット位置3にあるコレクション内の要素だけを、順に参照すればよいことが分かります。
《TIPS》伝統的な手法(2次元配列などを使う)と比べてみるのも一興です。ここで着目して欲しいのは「要求仕様の変更に際して柔軟に対処できるか」ということです。もしそうでないなら、再考の余地があります。□
オリジナル仕様に準拠した(Smalltalk/Smalltalk 版、Swing/Jython 版)では、隣接するオブジェクト群をコレクションを介して管理しています。すると、今回の仕様変更では、その要素数が8から6へと変化しただけだと分かります。つまり、要求仕様の変更に際して、柔軟に対処できることを再確認したことになります。
class Ostone(object):
def mouseUp(self, sender, e):
self._turnOff()
self._reset()
off, on = self.offColor, self.onColor;
s = self.shape.Stroke ;
self.shape.Stroke = (off, on)[s == off]
self._setUp()
self._turnOn()
マウス操作をしたときに、等方向に隣接するオブジェクト群を強調(色の変化)します。
def update(self, offset): self._turnOff() target = self.neighbors[offset] if target: self._setUp([self]+target._detect(offset)) self._turnOn()
マウス操作に伴って、等方向に隣接するオブジェクト群を強調(色の変化)します。これらの変化は、時計回り(反時計回り)に on/off を繰り返します。
def _detect(self, offset): s = [self] pivot = self.neighbors[offset] if pivot: s += pivot._detect(offset) return s
同じオフセット値 offset を持ち、等方向に隣接するオブジェクト群を順に獲得します。これを再帰呼び出し _detect によって実現しています。
》こちらに移動中です《
↑TOP