我最近遇到了一個遊戲,它會生成一個NxN(2x2,4x4 ...)棋盤,其中包含編號的棋盤(1,2,3 ...),其中每個數字確定允許的棋步。如果可能的話,目標是清空整個棋盤,而每塊棋子只能使用一次。如何存儲具有未知深度的遞歸函數的結果?
小板看起來是這樣的:
| 1 1 |
| 1 1 |
大板:
| 1 2 2 3 |
| 2 1 1 1 |
| 3 2 1 3 |
| 2 2 3 1 |
由於我經常穿過其中一個解決方案是不可能的情況迷迷糊糊中,我試着寫一個簡短的腳本在使用電路板之前檢查是否可以找到解決方案。
雖然這部分工作,檢查每個可能的組合並分開存儲所有結果變得更加複雜,我甚至不知道這是否可能。
下面是簡單的例子:
$tiles[1][1] = 'p1';
$tiles[2][1] = 'p1';
$tiles[1][2] = 'p1';
$tiles[2][2] = 'p1';
$moves = array(
array('x' => -1, 'y' => -1),
array('x' => 0, 'y' => -1),
array('x' => 1, 'y' => -1),
array('x' => -1, 'y' => 0),
array('x' => 1, 'y' => 0),
array('x' => -1, 'y' => 1),
array('x' => 0, 'y' => 1),
array('x' => 1, 'y' => 1)
);
function nextMove($x, $y, &$visited)
{
global $moves;
$max_loops = count($moves);
$visited[] = $x. ', ' .$y;
for ($j = 0; $j < $max_loops; $j++)
{
$new_x = $x + $moves[$j]['x'];
$new_y = $y + $moves[$j]['y'];
if (($new_x >= 1) && ($new_x <= 2) && ($new_y >= 1) && ($new_y <= 2))
{
$new_pos = $new_x. ', ' .$new_y;
if (!in_array($new_pos, $visited))
{
$j = $max_loops - 1;
nextMove($new_x, $new_y, $visited);
}
}
}
}
nextMove(1, 1, $visited, $moves_done);
var_dump($visited);
所以,這裏所發生相當簡單:
調用該函數與初始座標,計算的移動最大的量(即瓦)和將當前位置添加到$visited
陣列。
之後,for
循環重複遍歷可能的移動數組,產生新的座標並檢查它們是否在棋盤上,或者如果該棋盤之前被「訪問過」。如果找到有效的移動,則函數將再次用新座標調用。
(正如你所看到$j = $max_loops - 1;
這裏結束循環,以避免錯誤的值加到$visited
,如果沒有有效的舉措後來被發現)
這是發生了什麼現在:
array(4) {
[0]=>
string(4) "1, 1"
[1]=>
string(4) "1, 2"
[2]=>
string(4) "2, 1"
[3]=>
string(4) "2, 2"
}
到目前爲止,腳本正在工作,但只要沒有可能的移動,腳本就會結束,並且不會檢查更多組合(與$j = $max_loops - 1;
)或將錯誤的座標添加到$visited
。爲了避免這種情況,我必須單獨存儲結果或更改函數,這就是我卡住的地方。
一個大問題是未知數量的可能移動,因爲有時遊戲在2次移動後結束,有時可以清除棋盤。
是否有任何方法讓函數遍歷所有可能的組合並分別存儲/返回它們(可能太多以至於無法處理,也不是必須的,但是如果只有1-2個瓷磚不能使用,可能會很有趣)或至少檢查整個電路板是否可以清除並返回解決方案(這很重要,因爲結果應該稍後存儲和使用)?
腳本應該工作是這樣的:
array(4) {
[0]=>
string(4) "1, 1"
[1]=>
string(4) "1, 2"
[2]=>
string(4) "2, 1"
[3]=>
string(4) "2, 2"
}
array(4) {
[0]=>
string(4) "1, 1"
[1]=>
string(4) "1, 2"
[2]=>
string(4) "2, 2"
[3]=>
string(4) "2, 1"
}
array(4) {
[0]=>
string(4) "1, 1"
[1]=>
string(4) "2, 1"
[2]=>
string(4) "1, 2"
[3]=>
string(4) "2, 2"
}
array(4) {
[0]=>
string(4) "1, 1"
[1]=>
string(4) "2, 1"
[2]=>
string(4) "2, 2"
[3]=>
string(4) "1, 2"
}
array(4) {
[0]=>
string(4) "1, 1"
[1]=>
string(4) "2, 2"
[2]=>
string(4) "2, 1"
[3]=>
string(4) "1, 2"
}
array(4) {
[0]=>
string(4) "1, 1"
[1]=>
string(4) "2, 2"
[2]=>
string(4) "1, 2"
[3]=>
string(4) "2, 1"
}
[...]
我不明白遊戲是如何工作的,你能解釋一下嗎?你如何清除董事會? –
我會嘗試更好地解釋它是如何工作的:通過點擊棋盤上的任何圖塊開始遊戲。該數字確定接下來可以點擊哪個圖塊,可以水平,垂直或對角地點擊。這有點像在女王棋盤上移動皇后,我想,數字決定了她必須移動多少個方格。所以,如果你點擊一個3,你必須移動3個瓷磚,而不是1或2 ..一旦你使用了一個瓷磚,它就會被鎖定,所以你不能再次使用它(儘管如此,你仍然可以跳過它)。這意味着,要清除整個板子,如果可能的話,你必須找到一個包含所有瓷磚的序列。 – qlt
你只能朝一個方向移動?所以,如果你點擊一個有3的瓦片,你不能移動2個瓦片和1個向下的..對吧?你垂直移動3個瓷磚,或水平或對角? –