Chess: Fix AI moving king into attacked squares
This commit is contained in:
parent
d834d41c41
commit
077b7d66b8
152
src/chess.lua
152
src/chess.lua
@ -52,6 +52,80 @@ local piece_values = {
|
|||||||
king = 900
|
king = 900
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local rowDirs = {-1, -1, -1, 0, 0, 1, 1, 1}
|
||||||
|
local colDirs = {-1, 0, 1, -1, 1, -1, 0, 1}
|
||||||
|
|
||||||
|
local rowDirsKnight = { 2, 1, 2, 1, -2, -1, -2, -1}
|
||||||
|
local colDirsKnight = {-1, -2, 1, 2, 1, 2, -1, -2}
|
||||||
|
|
||||||
|
local bishopThreats = {true, false, true, false, false, true, false, true}
|
||||||
|
local rookThreats = {false, true, false, true, true, false, true, false}
|
||||||
|
local queenThreats = {true, true, true, true, true, true, true, true}
|
||||||
|
local kingThreats = {true, true, true, true, true, true, true, true}
|
||||||
|
|
||||||
|
local function attacked(color, idx, board)
|
||||||
|
local threatDetected = false
|
||||||
|
local kill = color == "white"
|
||||||
|
local pawnThreats = {kill, false, kill, false, false, not kill, false, not kill}
|
||||||
|
|
||||||
|
for dir = 1, 8 do
|
||||||
|
if not threatDetected then
|
||||||
|
local col, row = index_to_xy(idx)
|
||||||
|
col, row = col + 1, row + 1
|
||||||
|
|
||||||
|
for step = 1, 8 do
|
||||||
|
row = row + rowDirs[dir]
|
||||||
|
col = col + colDirs[dir]
|
||||||
|
|
||||||
|
if row >= 1 and row <= 8 and col >= 1 and col <= 8 then
|
||||||
|
local square = get_square(row, col)
|
||||||
|
local square_name = board[square]
|
||||||
|
local piece, pieceColor = square_name:match(":(%w+)_(%w+)")
|
||||||
|
|
||||||
|
if piece then
|
||||||
|
if pieceColor ~= color then
|
||||||
|
if piece == "bishop" and bishopThreats[dir] then
|
||||||
|
threatDetected = true
|
||||||
|
elseif piece == "rook" and rookThreats[dir] then
|
||||||
|
threatDetected = true
|
||||||
|
elseif piece == "queen" and queenThreats[dir] then
|
||||||
|
threatDetected = true
|
||||||
|
else
|
||||||
|
if step == 1 then
|
||||||
|
if piece == "pawn" and pawnThreats[dir] then
|
||||||
|
threatDetected = true
|
||||||
|
end
|
||||||
|
if piece == "king" and kingThreats[dir] then
|
||||||
|
threatDetected = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local colK, rowK = index_to_xy(idx)
|
||||||
|
colK, rowK = colK + 1, rowK + 1
|
||||||
|
rowK = rowK + rowDirsKnight[dir]
|
||||||
|
colK = colK + colDirsKnight[dir]
|
||||||
|
|
||||||
|
if rowK >= 1 and rowK <= 8 and colK >= 1 and colK <= 8 then
|
||||||
|
local square = get_square(rowK, colK)
|
||||||
|
local square_name = board[square]
|
||||||
|
local piece, pieceColor = square_name:match(":(%w+)_(%w+)")
|
||||||
|
|
||||||
|
if piece and pieceColor ~= color and piece == "knight" then
|
||||||
|
threatDetected = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return threatDetected
|
||||||
|
end
|
||||||
|
|
||||||
local function get_possible_moves(board, from_idx)
|
local function get_possible_moves(board, from_idx)
|
||||||
local piece, color = board[from_idx]:match(":(%w+)_(%w+)")
|
local piece, color = board[from_idx]:match(":(%w+)_(%w+)")
|
||||||
if not piece then
|
if not piece then
|
||||||
@ -414,6 +488,10 @@ local function get_possible_moves(board, from_idx)
|
|||||||
if dx > 1 or dy > 1 then
|
if dx > 1 or dy > 1 then
|
||||||
moves[to_idx] = nil
|
moves[to_idx] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if attacked(color, xy_to_index(to_x, to_y), board) then
|
||||||
|
moves[to_idx] = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -461,80 +539,6 @@ local function best_move(moves)
|
|||||||
return tonumber(choice_from), choice_to
|
return tonumber(choice_from), choice_to
|
||||||
end
|
end
|
||||||
|
|
||||||
local rowDirs = {-1, -1, -1, 0, 0, 1, 1, 1}
|
|
||||||
local colDirs = {-1, 0, 1, -1, 1, -1, 0, 1}
|
|
||||||
|
|
||||||
local rowDirsKnight = { 2, 1, 2, 1, -2, -1, -2, -1}
|
|
||||||
local colDirsKnight = {-1, -2, 1, 2, 1, 2, -1, -2}
|
|
||||||
|
|
||||||
local bishopThreats = {true, false, true, false, false, true, false, true}
|
|
||||||
local rookThreats = {false, true, false, true, true, false, true, false}
|
|
||||||
local queenThreats = {true, true, true, true, true, true, true, true}
|
|
||||||
local kingThreats = {true, true, true, true, true, true, true, true}
|
|
||||||
|
|
||||||
local function attacked(color, idx, board)
|
|
||||||
local threatDetected = false
|
|
||||||
local kill = color == "white"
|
|
||||||
local pawnThreats = {kill, false, kill, false, false, not kill, false, not kill}
|
|
||||||
|
|
||||||
for dir = 1, 8 do
|
|
||||||
if not threatDetected then
|
|
||||||
local col, row = index_to_xy(idx)
|
|
||||||
col, row = col + 1, row + 1
|
|
||||||
|
|
||||||
for step = 1, 8 do
|
|
||||||
row = row + rowDirs[dir]
|
|
||||||
col = col + colDirs[dir]
|
|
||||||
|
|
||||||
if row >= 1 and row <= 8 and col >= 1 and col <= 8 then
|
|
||||||
local square = get_square(row, col)
|
|
||||||
local square_name = board[square]
|
|
||||||
local piece, pieceColor = square_name:match(":(%w+)_(%w+)")
|
|
||||||
|
|
||||||
if piece then
|
|
||||||
if pieceColor ~= color then
|
|
||||||
if piece == "bishop" and bishopThreats[dir] then
|
|
||||||
threatDetected = true
|
|
||||||
elseif piece == "rook" and rookThreats[dir] then
|
|
||||||
threatDetected = true
|
|
||||||
elseif piece == "queen" and queenThreats[dir] then
|
|
||||||
threatDetected = true
|
|
||||||
else
|
|
||||||
if step == 1 then
|
|
||||||
if piece == "pawn" and pawnThreats[dir] then
|
|
||||||
threatDetected = true
|
|
||||||
end
|
|
||||||
if piece == "king" and kingThreats[dir] then
|
|
||||||
threatDetected = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local colK, rowK = index_to_xy(idx)
|
|
||||||
colK, rowK = colK + 1, rowK + 1
|
|
||||||
rowK = rowK + rowDirsKnight[dir]
|
|
||||||
colK = colK + colDirsKnight[dir]
|
|
||||||
|
|
||||||
if rowK >= 1 and rowK <= 8 and colK >= 1 and colK <= 8 then
|
|
||||||
local square = get_square(rowK, colK)
|
|
||||||
local square_name = board[square]
|
|
||||||
local piece, pieceColor = square_name:match(":(%w+)_(%w+)")
|
|
||||||
|
|
||||||
if piece and pieceColor ~= color and piece == "knight" then
|
|
||||||
threatDetected = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return threatDetected
|
|
||||||
end
|
|
||||||
|
|
||||||
local function locate_kings(board)
|
local function locate_kings(board)
|
||||||
local Bidx, Widx
|
local Bidx, Widx
|
||||||
for i = 1, 64 do
|
for i = 1, 64 do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user