《付録》Tetrimino4.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 hexagon import HexStone
from TetrisContext import *

## --------------------               
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 = 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._spot(X, Y, M)

        return [self._spot(Ox + W*(x+ix), Oy + H*(y+iy), M)
            for ix, iy in matrix]

    def _spot(self, x, y, m):
        return XPointCollection([XPoint(x + dx*m, y + dy*m)
            for dx, dy in HexStone(x, y, False).vertices])

    # --------------------
    def _shape(self, x, y, phase):
        self.phase = self._rotate1(phase)
        
        return [XPolygon(
            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):     # counter-clockwise        
        self.rotate(-1)

    def rotate(self, sign):
        self.phase = self._rotate1(1, sign)
            
        def _points(n):
            return self.matrix1[self._rotate1(n)]
        for e, n in zip(self.shape[self.offset:], self.mino1):
            e.update(_points, n)
        self._update()
        
    # --------------------
    def shiftRight(self):           # shift-right
        self.shift(1)

    def shiftLeft(self):            # shift-left
        self.shift(-1)

    def shift(self, n=0):
        self.x += n
        self.matrix1 = self._matrix(self.x, self.y, self._mat1)
        W = HexStone._width

        def _points(s):
            return XPointCollection([XPoint(e.X + n*W, e.Y) for e in s])
        for s in self.shape:
            s.update(_points, s)
        self._update()

    # --------------------
    def _update(self):
        s = self.spots()
        if self.any([e in self.tray.leftEdge  for e in s]):
            self.shiftRight()       # left -> right
        if self.any([e in self.tray.rightEdge for e in s]):
            self.shiftLeft()        # right -> left

    def spots(self):
        return [self._sPoint1(self.x, self.y, e) for e in self.mino1]

    def _sPoint1(self, x, y, e):
        dx, dy = self._mat1[self._rotate1(e)]
        return x+dx, y+dy
    
    def all(self, s):
        return False not in s
    
    def any(self, s):
        return True in s
    
## --------------------               
class SigOmino(Omino):
    def _shape(self, x, y, phase):
        return [XPolygon(
            Stroke=self._strokeColor,
            Fill=self.color,
            Points=self.pivot,
            )] + super(SigOmino, self)._shape(x, y, phase)
    
    def spots(self):
        return [(self.x, self.y)] + super(SigOmino, self).spots()
    
## --------------------               
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) + [
            XPolygon(
                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)
             
        def _points(n):
            return self.matrix2[self._rotate2(n)]
        for e, n in zip(self.shape[len(self.mino1)+1:], self.mino2):
            e.update(_points, n)

    # --------------------
    def shift(self, n=0):
        super(PiOmino, self).shift(n)
        self.matrix2 = self._matrix(self.x, self.y, self._mat2)

    # --------------------
    def spots(self):
        s = super(PiOmino, self).spots()
        return s + [self._sPoint2(self.x, self.y, e) for e in self.mino2]

    def _sPoint2(self, x, y, e):
        dx, dy = self._mat2[self._rotate2(e)]
        return x+dx, y+dy

## --------------------               
class TetriminoC(Omino):
    def __init__(self, x, y, phase=0):
        super(self.__class__, self).__init__(x, y, phase,
            mino1=(0, 1, 2, 3), color=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=Yellow,
            )
class TetriminoP(SigOmino):
    def __init__(self, x, y, phase=0):
        super(self.__class__, self).__init__(x, y, phase,
            mino1=(0, 1, 3), color=Magenta,
            )
class TetriminoB(SigOmino):
    def __init__(self, x, y, phase=0):
        super(self.__class__, self).__init__(x, y, phase,
            mino1=(0, 2, 3), color=Purple,
            )
class TetriminoY(SigOmino):
    def __init__(self, x, y, phase=0):
        super(self.__class__, self).__init__(x, y, phase,
            mino1=(0, 2, 4), color=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=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=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=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=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=Lime,
            )
## --------------------