テストケースを記述する(2)
(Jython で作成した)既存のモジュール hexagon.py を再利用しながら、新たなモジュールの動作を検証するために、テストケースを作成します。
class ExWindow(Window): def init(self): target = "tabControl", "button", self._Controls(target) self.items = {} for e, mino in TestCase(): self.items[e] = mino item = TabItem(Header=e) self.tabControl.Items.Add(item) panel = Canvas() item.Content = panel self.addMino(panel, mino) self.tabControl.SelectionChanged += self.selectionChanged self.button.Click += self.click self.KeyDown += self.keyDown
ジェネレーター TestCase によって、10種類のテトリミノが得られます。
def keyDown(self, sender, e): KeyValues(e.Key).switch({ Key.Left : (self.mino.shift, (-1,)), Key.Right: (self.mino.shift, ( 1,)), Key.Up : (self.mino.counterClockwise, ()), Key.Down : (self.mino.rotateClockwise , ()), })
矢印キーを選択すると、テトリミノを回転(↓|↑)シフト(←|→)できます。
class KeyValues: def __init__(self, value): self.value = value def switch(self, cases): for key, (f, args) in cases.items(): if key == self.value: apply(f, args)
押されたキーに対応するアクションを起動します。
《付録》Tetrimino2.py
# -*- coding: utf-8 -*- #=============================================================================== # Copyright (C) 2000-2008, 小泉ひよ子とタマゴ倶楽部 # # Change History: Games # 1988/05, Smalltalk # 2004/09, Java # 2005/02, C# # 2005/03, Jython # 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 #=============================================================================== from System.Windows import * from System.Windows.Media import * from System.Windows.Shapes import * from hexagon import HexStone ## -------------------- class Omino(object): _mat1 = [ ( 1, -2), ( 2, 0), ( 1, 2), (-1, 2), (-2, 0), (-1, -2), ] _mat2 = [ ( 0, -4), ( 2, -4), ( 3, -2), ( 4, 0), ( 3, 2), ( 2, 4), ( 0, 4), (-2, 4), (-3, 2), (-4, 0), (-3, -2), (-2, -4), ] _strokeColor = Brushes.Black def __init__(self, x, y, phase=0, color=None, mino1=, offset=1, ): self.x = x self.y = y self.phase = phase self.color = color self.mino1 = mino1 self.offset = offset self.matrix1 = self._matrix(x, y, self._mat1) self.shape = self._shape (x, y, self.phase) def _matrix(self, x, y, matrix): M = 2 Ox = HexStone._dx; W = HexStone._width Oy = HexStone._dy; H = HexStone._height X = Ox + W*x Y = Oy + H*y self.pivot = self.pointCollection([Point(X + dx*M, Y + dy*M) for dx, dy in HexStone(X, Y, False).vertices]) s = for ix, iy in matrix: X = Ox + W*(x+ix) Y = Oy + H*(y+iy) s.append(self.pointCollection([Point(X + dx*M, Y + dy*M) for dx, dy in HexStone(X, Y, False).vertices])) return s def pointCollection(self, vertices): s = PointCollection() for e in vertices: s.Add(e) return s def _shape(self, x, y, phase): self.phase = self._rotate1(phase) return [Polygon( HorizontalAlignment=HorizontalAlignment.Center, VerticalAlignment=VerticalAlignment.Center, Stroke=self._strokeColor, Fill=self.color, Points=self.matrix1[self._rotate1(n)], ) for n in self.mino1] def _rotate1(self, n, sign=1): return (n*sign + self.phase) % len(self._mat1) def rotateClockwise(self): # clockwise self.rotate(1) def counterClockwise(self): # counterclockwise self.rotate(-1) def rotate(self, sign): self.phase = self._rotate1(1, sign) for e, n in zip(self.shape[self.offset:], self.mino1): e.Points = self.matrix1[self._rotate1(n)] def shift(self, n=0): self.x += n self.matrix1 = self._matrix(self.x, self.y, self._mat1) W = HexStone._width for s in self.shape: s.Points = self.pointCollection([Point(e.X + n*W, e.Y) for e in s.Points]) ## -------------------- class SigOmino(Omino): def _shape(self, x, y, phase): return [Polygon( HorizontalAlignment=HorizontalAlignment.Center, VerticalAlignment=VerticalAlignment.Center, Stroke=self._strokeColor, Fill=self.color, Points=self.pivot, )] + super(SigOmino, self)._shape(x, y, phase) ## -------------------- class PiOmino(SigOmino): def __init__(self, x, y, phase=0, color=None, mino1=[], offset=1, mino2=None, ): self.mino2 = mino2 self.matrix2 = self._matrix(x, y, self._mat2) super(PiOmino, self).__init__(x, y, phase, color, mino1, offset) def _shape(self, x, y, phase): return super(PiOmino, self)._shape(x, y, phase) + [ Polygon( HorizontalAlignment=HorizontalAlignment.Center, VerticalAlignment=VerticalAlignment.Center, Stroke=self._strokeColor, Fill=self.color, Points=self.matrix2[self._rotate2(n)], ) for n in self.mino2] def _rotate2(self, n, sign=1): return (n*sign + self.phase*2) % len(self._mat2) def rotate(self, sign): super(PiOmino, self).rotate(sign) for e, n in zip(self.shape[len(self.mino1)+1:], self.mino2): e.Points = self.matrix2[self._rotate2(n)] def shift(self, n=0): super(PiOmino, self).shift(n) self.matrix2 = self._matrix(self.x, self.y, self._mat2) ## -------------------- class TetriminoC(Omino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 1, 2, 3), color=Brushes.Brown, offset=0, ) ## -------------------- class TetriminoO(SigOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 1, 2), color=Brushes.Yellow, ) class TetriminoP(SigOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 1, 3), color=Brushes.Magenta, ) class TetriminoB(SigOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 2, 3), color=Brushes.Purple, ) class TetriminoY(SigOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 2, 4), color=Brushes.Gray, ) ## -------------------- class TetriminoZ(PiOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 2), mino2=(0,), color=Brushes.Red, ) class TetriminoL(PiOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 3), mino2=(0,), color=Brushes.Orange, ) class TetriminoI(PiOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 3), mino2=(1,), color=Brushes.Cyan, ) class TetriminoJ(PiOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 3), mino2=(2,), color=Brushes.Blue, ) class TetriminoS(PiOmino): def __init__(self, x, y, phase=0): super(self.__class__, self).__init__(x, y, phase, mino1=(0, 4), mino2=(2,), color=Brushes.Lime, ) ## --------------------