《付録》HoneyCell.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 #=============================================================================== ## -------------------- class CombCell(object): def __init__(self): self.matrix = {} def addCell(self, cell): self._addMatrix(cell) def addNeighbors(self, cell, x, y): self._addMatrix(cell) cell.addNeighbors(x, y, self.matrix) def _addMatrix(self, cell): self.matrix[cell.name] = cell ## --------------------
第7章 オセロゲーム(trinity/hexagon)6/24, IronPython
‖記事一覧‖ C#.use(better, IronPython=”WPF”)
IronPython で学ぶ WPF プログラミングの世界
隣接するオブジェクト群を管理する
ゲーム盤を構成する各セルを一元管理するのが、Board です。
class Board(object):
def __init__(self):
self.matrix = {}
インスタンス属性 self.matrix は、各セルの名前(キー要素)とその実体(値要素)との対を管理します。このとき、キー要素は重複しない文字列を、値要素は Ostone の傘下にあるオブジェクトを対象にします。
def addCell(self, cell): self._addMatrix(cell)
引数に指定されたセル cell を、追加登録します。
def addNeighbors(self, cell, x, y): self._addMatrix(cell) cell.addNeighbors(x, y, self.matrix)
引数に指定されたセル cell を登録するとともに、その cell と隣接する他のセルとの対応関係を更新します。
def _addMatrix(self, cell): self.matrix[cell.name] = cell
引数に指定されたセル cell をもとに、キーには重複しない文字列 cell.name を、値には cell そのものを登録します。
隣接するオブジェクト群を相互に設定する
新たなテストケースに沿って、隣接するオブジェクト群を相互に設定する必要が生じます。
class Ostone(object):
_bounds = (1, -2), (2, 0), (1, 2),
_bounds = list(_bounds)+[(-x, -y) for x, y in _bounds]
クラス属性 _bounds は、隣接するオブジェクト群との相対位置を把握するのに「一度だけ」利用します。ここでは、オブジェクト群の点対称性を利用して、二段階を経て初期設定しています。相互の位置関係を形成した後はマトリックス管理のもとで、特定の座標系には依存せずに、オフセット位置だけで参照できるようになるので便利です。
def __init__(self, client, x, y, state, Stroke=None, Fill=None):
...
self.neighbors = [None]*6
インスタンス属性 self.neighbors を介して、隣接するオブジェクト群を管理します。
def mouseDown(self, sender, e):
on, off = Brushes.Magenta, Brushes.Black
for e in self.neighbors:
if not e: continue
s = e.shape.Stroke
e.shape.Stroke = (on, off)[s == on]
マウス操作をしたときに、隣接するオブジェクト群を強調(色の変化)します。これらはトグルになっていて、on/off 状態変化を繰り返します。
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)
隣接するオブジェクト群との相対位置を用いて、相互参照可能です。つまり、自身 self が隣接するオブジェクト群を把握するとともに、自身の存在を相手からも把握できるように設定します。
def clearNeighbor(self):
self.neighbors = []
隣接するオブジェクト群を消去して、初期設定に備えます。
def addNeighbor(self, cell):
self.neighbors.append(cell)
隣接するオブジェクト群として、新たに cell を追加します。
》こちらに移動中です《
↑TOP
《付録》HoneyComb2.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 System.Windows import * from System.Windows.Media import * from System.Windows.Shapes import * from hexagon import HexStone ## -------------------- class Ostone(object): _bounds = (1, -2), (2, 0), (1, 2), _bounds = list(_bounds)+[(-x, -y) for x, y in _bounds] 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) ; if Stroke: self.shape.Stroke = Stroke; if Fill : self.shape.Fill = 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): 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, 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): on, off = Brushes.Magenta, Brushes.Black for e in self.neighbors: if not e: continue s = e.shape.Stroke e.shape.Stroke = (on, off)[s == on] def mouseUp(self, sender, e): print ">>>", sender.Name, sender.Fill 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) ## --------------------