Game of 'Corner the Queen'

(2) Grundy numbers

Part (1) に戻る   Part (3) に進む   Workbench に戻る
Grundy数

座標 (i,j) のマス目ごとに Grundy 数 Gi,jという量が付随します。 簡潔に表すために

とおくと p のGrundy数は
で得られます。
ここで move p とは p から縦・横・斜め45°に進んで到達できる場所の集合を表します。それらの Grundy 数について mex を求めればそれが p のGrundy数に等しいというのが式の意味です。

また、G0,0=0 と定義します。

mex(S) 関数

minimum excluded、つまり [0,∞) から S の要素を取り除いた集合(補集合)で最も小さい要素を返す関数です。S がゼロを含んでいなければ mex=0 です。

Grundy数の計算は意外と簡単

左の式はなんともわけが分からないと思えますが、順を追って具体的に式を書き出すと意外と簡単です。例えばゴールに接したマス目について次の通りになります。

Grundy数の表 (1), CornerTheQueen.MOD

上の計算を XDS Modula-2/TopSpeed extension で自動的に行った結果が下表で、テキストウィンドウへの出力です。 ゼロは朱で強調してあります。なぜならそこが最強位置 (winning position) だからです。

Grundy数の表 (2), CornerTheQueen.Py

同様に Python で計算し、コンソール画面に出力した結果が下です。やはりゼロを強調してあります。

2つのテキスト画面

上の2つの画面は一見同じに見えますが、プログラミングとしては大きな違いがあります。 まず類似点から。縦座標が j の行データを書き出す関数を printArray(j) とすると表示プログラムは両者とも
  for j in range(N):
    printArray(N - 1 - j)
という形になります。

次に相違点ですが、右画面ではコンソール画面に直接書き出しています。なのでカーソルは最後の出力位置にあります。

一方左画面では w:= Window.Open(...) を実行してテキストウィンドウをまず開きます。そして、その画面上でカーソル制御ができます。 例えば Window.WhereX(), Window.WhereY() によってカーソル位置を読み取ることができ、Window.GotoXY(...)によって画面上の任意の場所に移動できます。 また Window.TextColor() によって文字の色が変えられます。この Window モジュールは元々 TopSpeed Modula-2 for DOS に入っていたものです。

テキストウィンドウの中にさらにテキストウィンドウを作ることも可能です。一時的に利用するだけなら Window.Close(...) で閉じます。

Grundy数がゼロの位置の簡便計算

上の数表からGrundy数がゼロの位置に規則性のあることが分かります。傾きがほぼ a=(√5 ± 1)/2 であることを活用すると次の関数で得られます。


この関数は Part (3) で取りあげる パソコンゲームソフトで使われています(O. Kreylos, 1999)。

9-14-2023, S. Hayashi