Pythonプログラミングで

2048を作る

Stage 4 盤面を動かす

4-1 概観を把握する

基本的には 1-2 でご覧に入れたことを一般化します。

なんだ、あれそのまんまやるんなら概説もクソもいらねぇわ

という猛者は早速 4-2 に飛んでいただいて結構です。

もうちょい説明あったほうがいいな

という方に向けて、以下では 1-2 を詳しくご説明してご覧に入れます。

~~~~~~~~~~~~~~~

盤面を動かす向きは上下左右の 4 通りです。1-2 では上、しかも [0, 0] から [1, 0] に数字を持ってくときだけを考えましたが、そのときこんなフローチャートをお見せしました。

UNAVAILABLE

なんの説明もなしに root だの focused だのという変数名を使っていましたが、ここで一度しっかりその役割をお見せしましょう。

例えば盤面を上に動かすとき、まずは [row, column] = [1, 0] にある数字を [0, 0] に移動させることを考えます。このときの [0, 0] が root, [1, 0] が focused です。要は focused の数字を root に移動させます。

~~~~~~~~~~~~~~~

で、その root と focused ってどうやって決めんねん

まずはこういう場合を考えてみましょう。

UNAVAILABLE
from https://glebbahmutov.com/2048/

この左端の column では、最初どこの数字をどのマスに持ってくることを考えればいいでしょうか。

上の 2 に下の 2 を持っていけばいいんじゃないか?

まあ実際はそうするのですが、アルゴリズム的に考えてください。我々人間の目からしたら真ん中二つの数を弄るのは当然なのですが、機械からしたら 2 と 4 の違いなんて実際に比べてみるまでわかりませんからね。

じゃあ上の 2 を上の 4 に持ってくって言えばいいの?

そういうことになります。つまり一番最初、root == [0, 0] で focused == [1, 0] となりますね。

~~~~~~~~~~~~~~~

さて、[0, 0] と [1, 0] を比べたときに違う数字が入っていますよね。

UNAVAILABLE
from https://glebbahmutov.com/2048/

こんな場合は [1, 0] から [0, 0] に数字を移動させることはできませんから、rootfocused の位置取りを変更しないといけませんね。

ここで focused == [2, 0] の場合は結局 focused == [1, 0] とやることが変わりませんから、focused == [3, 0] になるわけですが、さて [3, 0] の 4 という数字は [0, 0] に持ってくることはできるでしょうか?

できるわけないやないか

つまり [1, 0] に [0, 0] とは違う数字が入っている時点で、もう root == [0, 0] に数字を持ってくることはできないということがわかってたわけですよ。つまり 0 != root != focused != 0 なら root を移動させないといけませんね?

で、次は下の 2 を上の 2 に持ってくるから root == [1, 0] になるんやな

その通りです。

~~~~~~~~~~~~~~~

root == [1, 0] としたら、最初の focused はどこにしますか?

下の 2 を上に持ってくんだから [2, 0] やろ

ええ、そうなります。

UNAVAILABLE
from https://glebbahmutov.com/2048/

仰せの通りに [2, 0] の数字を [1, 0] に持ってくると、root == focused != 0 ですから二つの数が足し合わされて root == 4 になりますね。この時点で左端の column はこうなっていますよね。

まだ root == [1, 0], focused == [2, 0] の状態ですよ。今度 rootfocused の位置はどう動かしましょうか。

普通なら root を 1 個下にずらすんだろうけど、
さっきの「アルゴリズム的に考えて」を使えば root はそのままで focused を [3, 0] にするのがええんちゃうか?

いい洞察力です。

よっしゃ

でもまだ甘いですよ。[3, 0] の数字って [1, 0] に持って来れそうですか?

へ?

つまり、

UNAVAILABLE
from https://glebbahmutov.com/2048/

この盤面を上に移動させたら、[1, 0] はどうなりますか?

あっ、無理や
テメェ騙したな

そんなそんな。最終的に盤面はこうなりますよね。

UNAVAILABLE
from https://glebbahmutov.com/2048/

じゃあ root はサッサとズラさないとあかんのか

そういうことになります。まとめておくと、root == focused != 0 のときは数字を足し合わせて root を移動させなければいけません。

~~~~~~~~~~~~~~~

今度は rootfocused をどこに持っていきますか?

アルゴリズム的に考えてぇ
root == [2, 0]
focused == [3, 0]
やろな

その通りです。

この状態であれば [3, 0] にある 4 を [2, 0] に持ってくなんて余裕でしょ?

まあ数移動させるだけだし

ということで、root == 0 != focused であれば、数を移動させるだけとなります。この時は普通に focused を移動させればいいでしょう。

~~~~~~~~~~~~~~~

root 移動させちゃいけないのか?

こんな盤面で右端一番上 [0, 3] を root にして考えましょう。

UNAVAILABLE
from https://glebbahmutov.com/2048/

とりあえず focused == [1, 3] で 2 を [0, 3] に移しますよね。

このあと [3, 3] にある 2 ってどこ持ってきますか?

ああ、[0, 3] 持ってくから root を変えちゃいけないのか

ということになります。

~~~~~~~~~~~~~~~

したがって、rootfocused について一般的にこういうフローチャートができます。

盤面を上に動かすときの rootfocused の検討の順番はこんな感じでしょうか。

他の方向でも同じです。盤面を下に動かす場合、rootfocused はこうなりますね。

左であればこう。

右ならこうなります。

次回からこの面倒な移動をコーディングしていきますよ。

NEXT 4-2 4 通りの場合わけをして盤面を動かす