《付録》TetrisContext.py

# -*- coding: utf-8 -*-
#===============================================================================
#    Copyright (C) 2000-2008, 小泉ひよ子とタマゴ倶楽部
#
# Change History: Games
#    1988/05, Smalltalk
#    2004/09, Java
#    2005/02, C#
#    2005/03, Jython
# 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.Input import Key

Key_Right = Key.Right
Key_Left  = Key.Left
Key_Up    = Key.Up
Key_Down  = Key.Down

## --------------------
from System.Windows import Point

class XPoint:
    def __init__(self, x, y):
        self.value = Point(x, y)

## --------------------
from System.Windows.Shapes import Polygon
from System.Windows import HorizontalAlignment
from System.Windows import VerticalAlignment

class XPolygon:
    def __init__(self, Points=None, **args):
        self.value = Polygon(
            HorizontalAlignment=HorizontalAlignment.Center,
            VerticalAlignment=VerticalAlignment.Center,
            Points=Points.value,
            **args)
        
    def __iter__(self):
        for e in self.value.Points:
            yield e

    def update(self, points, *args):
        self.value.Points = points(*args).value

## --------------------
from System.Windows.Media import PointCollection

class XPointCollection:
    def __init__(self, xpoints):
        self.value = self._value(xpoints)

    def _value(self, xpoints):
        s = PointCollection()
        for e in xpoints:
            s.Add(e.value)
        return s

## --------------------               
from System.Windows.Media import Brushes

Black     = Brushes.Black
LightGray = Brushes.LightGray
Gray      = Brushes.Gray

Brown   = Brushes.Brown
Yellow  = Brushes.Yellow
Magenta = Brushes.Magenta
Purple  = Brushes.Purple
Red     = Brushes.Red
Orange  = Brushes.Orange
Cyan    = Brushes.Cyan
Blue    = Brushes.Blue
Lime    = Brushes.Lime

## --------------------               

リファクタリング:内包の隘路

(遅まきながら)Python 3 では list 以外(たとえば dict)にも、内包表現ができるようになりました。しかし、Smalltalk のような汎用的な記述はできず、VDM++ が期待しているプログラミング言語仕様と比べても、Python 3 ではまだそのギャップを埋めるには大きな溝があり、今後の Python 4 ?に期待するしかありません。そこで、

《付録》exTetrimino4.py

# -*- coding: utf-8 -*-
#===============================================================================
#    Copyright (C) 2000-2008, 小泉ひよ子とタマゴ倶楽部
#
# Change History: Games
#    1988/05, Smalltalk
#    2004/09, Java
#    2005/02, C#
#    2005/03, Jython
# 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 _ant import *
from System.Windows import *
from System.Windows.Controls import *
from System.Windows.Input import *

from Tetrimino4 import *
from TetrisWorld import *
from TetrisCenter import *
## --------------------
class TestCase:
    types = "COpbYZLIJS"

    def __iter__(self):
        m = self.items()
        for e in self.types:
            yield e, m[e]

    def items(self):
        return dict((e, eval("Tetrimino%s(4, 4)"%e.upper()))
            for e in self.types)

## --------------------               
class ExWindow(Window):
    def __init__(self, Content=None, **args):
        self.InitializeComponent(Content)
        self.init()

    def InitializeComponent(self, Content):
        self.Content = LoadXaml(Content)

    def _Controls(self, target):
        controls = xaml_controls(self)
        for e in target:
            setattr(self, e, controls[e])

    def init(self):
        target = "tabControl", "button",
        self._Controls(target)

        self._items = {}
        self.testCase = TestCase()
        self._panels = {}
        self._tetris = Tetris(self)
            
        self.tabControl.SelectionChanged += self.selectionChanged
        self.button.Click += self.click
        self.KeyDown += self._tetris.keyDown

    def addItem(self, e, mino):
        self._addTabItem(e)
        self._addMinoItem(e, mino)

    def _addTabItem(self, item):
        tabItem = TabItem(
            Header=item,
            Content=Canvas(),
            )
        self.tabControl.Items.Add(tabItem)
        self._panels[item] = tabItem.Content
        
    def _addMinoItem(self, e, mino):
        self._items[e] = mino
        self._attach(e, mino.dispatch)

    def addShape(self, shape, item):
        self._panels[item].Children.Add(shape.value)    #

    ## --------------------               
    def selectionChanged(self, sender, e):
        self.mino = self._items[sender.SelectedItem.Header]
        self.button.Content = self.state()

    def click(self, sender, e):
        self.mino.rotateClockwise()
        sender.Content = self.state()

    def update(self):
        self.button.Content = self.state()

    def state(self):
        return "Type-%s: rotation = %d"%(
            self.mino.__class__.__name__[-1], self.mino.phase)

    ## --------------------
    def cases(self):
        return self.mino.dispatch
    
    def _attach(self, e, dispatch):
        key = Key.Space
        if key in dispatch: return
        if e == "C":
            dispatch[key] = self.downC; print "**C**"
        if e == "O":
            dispatch[key] = self.downO; print "**O**"

    def downC(self): print "<<< C"
    def downO(self): print "<<< O"

## --------------------               
if __name__ == "__main__":
    import sys
    xaml = sys.argv[1]
    win = ExWindow(
        Title=__file__,
        Width=238, Height=350,
        Content=xaml,
        )
    Application().Run(win)

## --------------------