(●`ε´●):本当にランダムにパネルを配置してしまうと
解けない問題になる可能性があるらしい・・・。
必ず解けるように問題を作るにはどうしたらいいだ?
【´・ω・`】:最初にパネルをきちんと配置する。
(●`ε´●):きちんと?
【´・ω・`】:そう、1~15までの数字とブランクパネルを解きあがった
状態に配置する。それから、ブランクパネルを適当な
回数だけ、ランダムに上下左右の数字パネルと交換してやる。
そうすれば、その逆回しをすれば元に戻るわけだから
解無しの問題にはならないというわけだ。
(●`ε´●):なるほど。
【´・ω・`】:まず初期化コードだ。これは「15パズル(9)」ですでに作った
ものをそのまま使えばいい。下のコードがそれだ。
For %y = 5 To 8
For %x = 2 To 5
Cells(%y, %x)=%x +%y*4 -21
Next
Next
Cells(8,5)=""
(●`ε´●):このコードはここで使うつもりだったのか。
【´・ω・`】:まあね。下がパネルをシャッフルするためのコードだ。
%X=5 !!初期化時のブランクパネルセルの列番号
%Y=8 !!初期化時のブランクパネルセルの行番号
Randomize(ThisTime())
!!シャッフル
for %i = 1 To 3000
!!ブランクパネルと交換する数字パネル
!!の方向
%DX = Int(Rand() * 3)-1
%DY = Int(Rand() * 3)-1
!!斜め方向のパネルと交換するのを避ける
If Abs(%DX + %DY) = 1 Then
If Cells(%Y+%DY, %X+%DX) = "" Then
!!4×4のマス目の外のセルとの交換
!!はしない
continue for
Else
!!交換
%Temp = Cells(%Y+%DY, %X+%DX)
Cells(%Y+%DY, %X+%DX) = Cells(%Y, %X)
Cells(%Y, %X) = %Temp
!!交換後、新たにブランクパネルになった
!!セルの行番号と列番号を記憶
%Y = %Y+%DY
%X = %X+%DX
End If
End if
next
【´・ω・`】:それでは解説しよう。まず最初の2行・・・。
%X=5 !!初期化時のブランクパネルセルの列番号
%Y=8 !!初期化時のブランクパネルセルの行番号
これは初期化してきちんとパネルが整列しているときの
ブランクパネルの位置を表している。すなわちセルE8だ。
そして・・・
!!ブランクパネルと交換する数字パネル
!!の方向
%DX = Int(Rand() * 3)-1
%DY = Int(Rand() * 3)-1
・・・は-1、0,1のどれかの数値をランダムに生成する。
%DXが-1ならブランクパネルの左方向
%DXが1ならブランクパネルの右方向
%DYが-1ならブランクパネルの上方向
%DYが1ならブランクパネルの下方向を示す。
(●`ε´●):Abs(%DX + %DY) = 1 というのは何だ?
【´・ω・`】:Abs()は絶対値を求めるときに使う関数だ。
(●`ε´●):???
【´・ω・`】:15パズルではブランクパネルの上下左右にある数字パネルを
交換するのであって、斜め方向には交換しない。Abs(%DX + %DY)が
1ならばそれが保証される。
(●`ε´●):%DXが1、%DYが1だとすると和の絶対値は2.
その場合はもしもブランクセルがCells(5,2)だとすると
それに対しての数値セルがCells(5+1,2+1)じゃ
斜め方向になってしまうもんね。
【´・ω・`】::そう、どちらか一方が0でなければ上下左右方向にならない。
つぎの
If Cells(%Y+%DY, %X+%DX) = "" Then
!!4×4のマス目の外のセルとの交換
!!はしない
continue for
・・・コメントの通り。次の
!!交換
%Temp = Cells(%Y+%DY, %X+%DX)
Cells(%Y+%DY, %X+%DX) = Cells(%Y, %X)
Cells(%Y, %X) = %Temp
【´・ω・`】: ここはちょっと修正しよう。上のコードは2つのものの値を
交換するときは定石と言えるコードだが、この場合は一方の
値はブランクだと限定されている。つまり、交換後は今までの
ブランクセルの Cells(%Y, %X) が数値セルに
数値セルのCells(%Y+%DY, %X+%DX)がブランクパネルに
なるので・・・
Cells(%Y, %X) = Cells(%Y+%DY, %X+%DX)
Cells(%Y+%DY, %X+%DX) = ""
・・・の2行で十分だ。
・・・ブランクパネルの行番号を示す%Yに今までの数値パネルの
行番号を、列番号を示す%Xに今までの数値パネルの列番号を
忘れずに代入しておく。
%Y = %Y+%DY
%X = %X+%DX
これで1回分のシャッフルが終わる。
これを適当な回数(この場合は3000回)繰り返すというわけだ。
(●`ε´●):なるほど。これでやっとプレイヤーはゲームを始めることが
出来るわけだな。
【´・ω・`】:次はプレイヤーがマウスでクリックしたときに数値パネルとブランクパネル
交換するコードだ。
(続く)
最近のコメント