Chess: Simplify checks for king safe moves in bot
This commit is contained in:
parent
2828e5644a
commit
9fd4bafee7
@ -884,7 +884,7 @@ end
|
|||||||
-- * theoretical_moves: moves table returned by realchess.get_theoretical_moves_for()
|
-- * theoretical_moves: moves table returned by realchess.get_theoretical_moves_for()
|
||||||
-- * board: board table
|
-- * board: board table
|
||||||
-- * player: player color ("white" or "black")
|
-- * player: player color ("white" or "black")
|
||||||
function realchess.get_king_safe_move(theoretical_moves, board, player)
|
function realchess.get_king_safe_moves(theoretical_moves, board, player)
|
||||||
local safe_moves = {}
|
local safe_moves = {}
|
||||||
local safe_moves_count = 0
|
local safe_moves_count = 0
|
||||||
-- create a virtual board
|
-- create a virtual board
|
||||||
@ -1917,19 +1917,19 @@ local function update_game_result(meta)
|
|||||||
king_idx = black_king_idx
|
king_idx = black_king_idx
|
||||||
end
|
end
|
||||||
|
|
||||||
-- King attacked? This reduces the list of available moves,
|
-- King attacked?
|
||||||
-- so remove these, too and check if there are still any left.
|
|
||||||
local isKingAttacked = realchess.attacked(checkPlayer, king_idx, board_t)
|
local isKingAttacked = realchess.attacked(checkPlayer, king_idx, board_t)
|
||||||
if isKingAttacked then
|
if isKingAttacked then
|
||||||
meta:set_string(checkPlayer.."Attacked", "true")
|
meta:set_string(checkPlayer.."Attacked", "true")
|
||||||
local _, save_moves = realchess.get_king_safe_move(checkMoves, board_t, checkPlayer)
|
end
|
||||||
-- If not safe moves left, player can't move
|
|
||||||
if save_moves == 0 then
|
-- If not safe moves left, player can't move
|
||||||
if checkPlayer == "black" then
|
local safe_moves, safe_moves_count = realchess.get_king_safe_moves(checkMoves, board_t, checkPlayer)
|
||||||
blackCanMove = false
|
if safe_moves_count == 0 then
|
||||||
else
|
if checkPlayer == "black" then
|
||||||
whiteCanMove = false
|
blackCanMove = false
|
||||||
end
|
else
|
||||||
|
whiteCanMove = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -66,9 +66,13 @@ function chessbot.move(inv, meta)
|
|||||||
botName = meta:get_string("playerBlack")
|
botName = meta:get_string("playerBlack")
|
||||||
end
|
end
|
||||||
if (lastMove == opponentColor or ((botColor == "white" or botColor == "both") and lastMove == "")) and gameResult == "" then
|
if (lastMove == opponentColor or ((botColor == "white" or botColor == "both") and lastMove == "")) and gameResult == "" then
|
||||||
local moves = realchess.get_theoretical_moves_for(meta, board_t, currentBotColor)
|
|
||||||
|
|
||||||
local choice_from, choice_to = best_move(moves)
|
local moves = realchess.get_theoretical_moves_for(meta, board_t, currentBotColor)
|
||||||
|
local safe_moves, safe_moves_count = realchess.get_king_safe_moves(moves, board_t, currentBotColor)
|
||||||
|
if safe_moves_count == 0 then
|
||||||
|
-- No safe move: stalemate or checkmate
|
||||||
|
end
|
||||||
|
local choice_from, choice_to = best_move(safe_moves)
|
||||||
if choice_from == nil then
|
if choice_from == nil then
|
||||||
-- No best move: stalemate or checkmate
|
-- No best move: stalemate or checkmate
|
||||||
return
|
return
|
||||||
@ -77,26 +81,6 @@ function chessbot.move(inv, meta)
|
|||||||
local pieceFrom = inv:get_stack("board", choice_from):get_name()
|
local pieceFrom = inv:get_stack("board", choice_from):get_name()
|
||||||
local pieceTo = inv:get_stack("board", choice_to):get_name()
|
local pieceTo = inv:get_stack("board", choice_to):get_name()
|
||||||
|
|
||||||
local black_king_idx, white_king_idx = realchess.locate_kings(board_t)
|
|
||||||
local bot_king_idx
|
|
||||||
if currentBotColor == "black" then
|
|
||||||
bot_king_idx = black_king_idx
|
|
||||||
else
|
|
||||||
bot_king_idx = white_king_idx
|
|
||||||
end
|
|
||||||
local botAttacked = realchess.attacked(currentBotColor, bot_king_idx, board_t)
|
|
||||||
local kingSafe = true
|
|
||||||
local bestMoveSaveFrom, bestMoveSaveTo
|
|
||||||
|
|
||||||
if botAttacked then
|
|
||||||
kingSafe = false
|
|
||||||
meta:set_string(currentBotColor.."Attacked", "true")
|
|
||||||
local safe_moves, save_moves_count = realchess.get_king_safe_move(moves, board_t, currentBotColor)
|
|
||||||
if save_moves_count >= 1 then
|
|
||||||
bestMoveSaveFrom, bestMoveSaveTo = best_move(safe_moves)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.after(BOT_DELAY_MOVE, function()
|
minetest.after(BOT_DELAY_MOVE, function()
|
||||||
local gameResult = meta:get_string("gameResult")
|
local gameResult = meta:get_string("gameResult")
|
||||||
if gameResult ~= "" then
|
if gameResult ~= "" then
|
||||||
@ -109,33 +93,20 @@ function chessbot.move(inv, meta)
|
|||||||
local lastMove = meta:get_string("lastMove")
|
local lastMove = meta:get_string("lastMove")
|
||||||
local lastMoveTime = meta:get_int("lastMoveTime")
|
local lastMoveTime = meta:get_int("lastMoveTime")
|
||||||
if lastMoveTime > 0 or lastMove == "" then
|
if lastMoveTime > 0 or lastMove == "" then
|
||||||
|
-- Set the bot name if not set already
|
||||||
if currentBotColor == "black" and meta:get_string("playerBlack") == "" then
|
if currentBotColor == "black" and meta:get_string("playerBlack") == "" then
|
||||||
meta:set_string("playerBlack", botName)
|
meta:set_string("playerBlack", botName)
|
||||||
elseif currentBotColor == "white" and meta:get_string("playerWhite") == "" then
|
elseif currentBotColor == "white" and meta:get_string("playerWhite") == "" then
|
||||||
meta:set_string("playerWhite", botName)
|
meta:set_string("playerWhite", botName)
|
||||||
end
|
end
|
||||||
local moveOK = false
|
|
||||||
if not kingSafe then
|
-- Make a move
|
||||||
-- Make a move to put the king out of check
|
local moveOK = realchess.move(meta, "board", choice_from, "board", choice_to, botName)
|
||||||
if bestMoveSaveTo ~= nil then
|
if not moveOK then
|
||||||
moveOK = realchess.move(meta, "board", bestMoveSaveFrom, "board", bestMoveSaveTo, botName)
|
minetest.log("error", "[xdecor] Chess: Bot tried to make an invalid move from "..
|
||||||
if not moveOK then
|
realchess.index_to_notation(choice_from).." to "..realchess.index_to_notation(choice_to))
|
||||||
minetest.log("error", "[xdecor] Chess: Bot tried to make an invalid move (to protect the king) from "..
|
|
||||||
realchess.index_to_notation(bestMoveSaveFrom).." to "..realchess.index_to_notation(bestMoveSaveTo))
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- No safe move left: checkmate or stalemate
|
|
||||||
return
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Make a regular move
|
|
||||||
moveOK = realchess.move(meta, "board", choice_from, "board", choice_to, botName)
|
|
||||||
if not moveOK then
|
|
||||||
minetest.log("error", "[xdecor] Chess: Bot tried to make an invalid move from "..
|
|
||||||
realchess.index_to_notation(choice_from).." to "..realchess.index_to_notation(choice_to))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
-- Bot resigns if it made an incorrect move
|
-- Bot resigns if it tried to make an invalid move
|
||||||
if not moveOK then
|
if not moveOK then
|
||||||
realchess.resign(meta, currentBotColor)
|
realchess.resign(meta, currentBotColor)
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user