15 拼图(也称为宝石拼图、老板拼图、十五游戏、神秘广场和许多其他拼图)是一个滑动拼图,在 4 块高和 4 块宽的框架中具有 15 块编号为 1-15 的正方形块,留下一个空置瓷砖位置。打开位置的同一行或列中的瓷砖可以分别通过水平或垂直滑动来移动。拼图的目标是按数字顺序放置瓷砖。
以框架中的瓷砖数量命名,15 拼图也可以称为 16 拼图,暗指其总瓷砖容量。类似的名称用于 15 拼图的不同大小的变体,例如8 拼图,在 3×3 框架中有 8 个图块。
n谜题是涉及启发式算法建模的经典问题。该问题常用的启发式方法包括计算错放瓷砖的数量,并找出每个街区之间的出租车距离之和及其在目标配置中的位置。请注意,两者都是可接受的,即它们永远不会高估剩余的移动次数,这确保了某些搜索算法(例如A* )的最优性。
参考代码:
Size := 20
Grid := [], Deltas := ["-1,0","1,0","0,-1","0,1"], Width := Size * 2.5
Gui, font, S%Size%
Gui, add, text, y1
loop, 4
{
Row := A_Index
loop, 4
{
Col := A_Index
Gui, add, button, % (Col=1 ? "xs y+1" : "x+1 yp") " v" Row "_" Col " w" Width " gButton -TabStop", % Grid[Row,Col] := Col + (Row-1)*4 ; 1-16
}
}
GuiControl, Hide, % Row "_" Col ; 4_4
Gui, add, Button, % "xs gShuffle w" 4 * Width + 3, Shuffle
Gui, show,, 15 Puzzle
return
;------------------------------
GuiClose:
ExitApp
return
;------------------------------
Shuffle:
Shuffle := true
loop, 1000
{
Random, Rnd, 1,4
Move(StrSplit(Deltas[Rnd], ",").1, StrSplit(Deltas[Rnd], ",").2)
}
Shuffle := false
return
;------------------------------
Button:
buttonRow := SubStr(A_GuiControl, 1, 1), ButtonCol := SubStr(A_GuiControl, 3, 1)
if Abs(buttonRow-Row) > 1 || Abs(ButtonCol-Col) > 1 || Abs(buttonRow-Row) = Abs(ButtonCol-Col)
return
Move(buttonRow-Row, ButtonCol-Col)
return
;------------------------------
#IfWinActive, 15 Puzzle
;------------------------------
Down::
Move(-1, 0)
return
;------------------------------
Up::
Move(1, 0)
return
;------------------------------
Right::
Move(0, -1)
return
;------------------------------
Left::
Move(0, 1)
return
;------------------------------
#IfWinActive
;------------------------------
Move(deltaRow, deltaCol){
global
if (Row+deltaRow=0) || (Row+deltaRow=5) || (Col+deltaCol=0) || (Col+deltaCol=5)
return
GuiControl, Hide, % Row+deltaRow "_" Col+deltaCol
GuiControl, Show, % Row "_" Col
GuiControl,, %Row%_%Col%, % Grid[Row+deltaRow, Col+deltaCol]
Grid[Row, Col] := Grid[Row+deltaRow, Col+deltaCol]
Grid[Row+=deltaRow, Col+=deltaCol] := 16
if Shuffle
return
gridCont := ""
for m, obj in grid
for n, val in obj
gridCont .= val ","
if (Trim(gridCont, ",") = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16")
MsgBox, 262208, 15 Puzzle, You solved 15 Puzzle
}
我还以为是ahk有划线的功能了,原来是用按钮代替划线的方块。