テトリスのソースを読む(その2)

http://www.zetcode.com/wxpython/thetetrisgame/続き。
Boardクラスのメソッドstartを呼ぶところから。メソッドstartは、

def start(self):
    if self.isPaused:     #最初はself.isPaused=Falseだった。いつTrueになるのか今後注目する
        return

    self.isStarted = True
    self.isWaitingAfterLine = False  #いつTrueになるのか今後注目する
    self.numLinesRemoved = 0
    self.clearBoard()               #ここでもclearBoardしている

    self.newPiece()         #同じクラス内のメソッド
    self.timer.Start(Board.Speed)  # wxTimer.Start  何かわからないがスタートしている

ここで、BoardクラスのメソッドnewPieceは、次の通り。

def newPiece(self):
    self.curPiece = self.nextPiece  #これらはShapeのインスタンスオブジェクトなんだよなー
    statusbar = self.GetParent().statusbar   #※1
    self.nextPiece.setRandomShape()            #※2
    self.curX = Board.BoardWidth / 2 + 1
    self.curY = Board.BoardHeight - 1 + self.curPiece.minY()       #※3

    if not self.tryMove(self.curPiece, self.curX, self.curY):      #※4
         self.curPiece.setShape(Tetrominoes.NoShape)      #NoShapeにしている
         self.timer.Stop()                #wxTimer.Stopはタイマーを止めている
         self.isStarted = False
         statusbar.SetStatusText('Game over')     #ステータスバーに表示

ここで※1だが、やっていることはなんとなく分かる。クラスTetrisで定義したstatusbarを使うときこうやるのだろうが、自分ではとても書けない。GetParentというのは知らなかった。
※2のメソッドは、クラスShapeで定義されている。関連するのは以下のところ。

 def setShape(self, shape):           #shapeに対応した座標をcoordsに入れておく
     table = Shape.coordsTable[shape]
     for i in range(4):
         for j in range(2):
            self.coords[i][j] = table[i][j]

     self.pieceShape = shape

 def setRandomShape(self):
     self.setShape(random.randint(1, 7))  #乱数(1から7のどれか)を発生させる

※3のminYというメソッドは、次の通りなのだが、

def minY(self):
    m = self.coords[0][1]     # [1]はy座標を取り出すことに対応している。mはy座標の値
    for i in range(4):
        m = min(m, self.coords[i][1])   #ブロックを構成する4つの要素の最小y座標をmに入れる

    return m

curXやcurYに1足したり、1引いたりのところが引っかかる。原点をどう定義しているかによると思うが、もう少し読み進んでから考える。

※4のtryMoveはBoardクラスのメソッドであり、Falseを返せばゲームオーバーとなる条件なので何をやっているかは想像がつくのであるが、

def tryMove(self, newPiece, newX, newY):
    for i in range(4):
        x = newX + newPiece.x(i)      # ブロックを構成する4要素のそれぞれのx座標
        y = newY - newPiece.y(i)      # ブロックを構成する4要素のそれぞれのy座標
        if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight:
            return False
        if self.shapeAt(x, y) != Tetrominoes.NoShape:
            return False

    self.curPiece = newPiece
    self.curX = newX
    self.curY = newY
    self.Refresh()
    return True

ここで、self.shapeAtは、Boardクラスのメソッドであり、

def shapeAt(self, x, y):
    return self.board[(y * Board.BoardWidth) + x]

y*Board.BoardWidth+xがどういう働きをするのかわからん。

今のところ文法の理解は問題ないと思うが、それだけでは内容を理解できないのだな。とりあえずは最後まで読み進めたい。