更新:
靈感來自clwhisk的建議,我有以下想法:
散列所有板的位置爲30位 - 前15位作爲計算機的位置,接下來的15位作爲玩家的位置(每個典當5位)。對於每25個選擇3個(= 2300)的計算機位置,產生22個選擇3(= 1540)匹配的玩家位置,並將哈希設置爲指向下一個棋盤位置(其中前15個比特是計算機的棋子)這可能是由其中一臺計算機棋子的移動造成的。
這樣沒有移動將需要產生,也贏得位置進行測試。看起來哈希大小似乎爲2300 * 1540 = 3,542,000,但會包括預先計算的所有三個棋子的下一個棋子狀態,包括散列獲勝位置。此外,董事會可以表示爲一個數字,而不是代表每個玩家位置的兩個比特板(在一些其他棋盤遊戲中常見)。
那麼,即使有網絡工作者,我的Firefox瀏覽器也會崩潰。所以我的另一個想法是使用2300項散列作爲二維數組的關鍵點(2300x2300; player_1_position x player_2_position),其值是可以跟隨player_1的可用動作的棋盤狀態。此外,可以嘗試散列一半的位置 - 如果它不在散列中,則位於鏡像位置。
結束更新。
這裏是一個JavaScript的例子,試圖散列所有倉板,電路板和動作 - 在我看來,有25選5 = 53130個可能的狀態董事會(不包括典當爲此我們想要移動);並且每個棋盤狀態爲我們的棋子提供20個可能的位置。
我不確定在這個可觀的哈希中查找的速度可能與在動態生成可用的動作時相比。如預期的那樣,預先計算哈希需要幾秒鐘才能在瀏覽器上加載。
要查找可用的移動,類型:hash[board<<5|position]
,
例如:
console.log(hash[31<<5|6])
[1048576,512,8388608]
console.log(hash[31<<5|7])
[2097152,512,32,16777216,1024]
JavaScript代碼(功能,comb
和main
,適於在C來自此Rosetta Code):
var hash = {}
function comb(m, n, c)
{
var i;
for (i = 0; i < n; i++) c[i] = n - i;
while (1) {
var s = 0
for (i = n; i--;)
s|=1<<c[i]-1;
//hash boards, positions, and moves
for (var j=1; j<=25; j++){
var pos = 1 << (j - 1)
if (pos & s)
continue
hash[(s<<5)|j] = moves(pos,s)
}
/* this check is not strictly necessary, but if m is not close to n,
it makes the whole thing quite a bit faster */
if (c[i]++ < m) continue;
for (i = 0; c[i] >= m - i;) if (++i >= n) return;
for (c[i]++; i; i--) c[i-1] = c[i] + 1;
}
}
function moves(position,board){
var leftBorder = 17318416,
rightBorder = 1082401,
moves = [],
positionTemp = position
//up
while (positionTemp < 1<<20 && !((positionTemp<<5) & board))
positionTemp <<= 5
if (positionTemp != position)
moves.push(positionTemp)
positionTemp = position
//down
while (positionTemp > 1<<4 && !((positionTemp>>5) & board))
positionTemp >>= 5
if (positionTemp != position)
moves.push(positionTemp)
positionTemp = position
//left
while (!((positionTemp<<1) & board)){
if (positionTemp & leftBorder || positionTemp == 1<<24)
break
positionTemp <<= 1
}
if (positionTemp != position)
moves.push(positionTemp)
positionTemp = position
//right
while (!((positionTemp>>1) & board)){
if (positionTemp & rightBorder || positionTemp == 1)
break
positionTemp >>= 1
}
if (positionTemp != position)
moves.push(positionTemp)
positionTemp = position
//NW
while (!((positionTemp<<6) & board)){
if (positionTemp & leftBorder || positionTemp >= 1<<20)
break
positionTemp <<= 6
}
if (positionTemp != position)
moves.push(positionTemp)
positionTemp = position
//NE
while (!((positionTemp<<4) & board)){
if (positionTemp & rightBorder || positionTemp >= 1<<20)
break
positionTemp <<= 4
}
if (positionTemp != position)
moves.push(positionTemp)
positionTemp = position
//SW
while (!((positionTemp>>4) & board)){
if (positionTemp & leftBorder || positionTemp <= 1<<4)
break
positionTemp >>= 4
}
if (positionTemp != position)
moves.push(positionTemp)
positionTemp = position
//SE
while (!((positionTemp>>6) & board)){
if (positionTemp & rightBorder || positionTemp <= 1<<4)
break
positionTemp >>= 6
}
if (positionTemp != position)
moves.push(positionTemp)
return moves
}
function main()
{
var buf = new Array(100);
comb(25, 5, buf);
console.log("done")
}
main()
這裏至少有一個想法,http://chessprogramming.wikispaces.com/Efficient+Generation+of+Sliding+Piece+Atta cks,在名爲「通過計算滑動攻擊」的部分中。 –
@groovy - 一定會檢查出來,謝謝。 – Straightfw
......如果你進一步閱讀下面的內容,可以預先計算任何一種射線的所有選項 - (2^5 = 32)個可能性。 –