Fix checkmate logic

master
Jean-Patrick Guerrero 2018-08-25 12:55:03 +02:00
parent 70277d4216
commit ed931905be
1 changed files with 59 additions and 46 deletions

View File

@ -27,7 +27,16 @@ 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, inv)
local function board_to_table(inv)
local t = {}
for i = 1, 64 do
t[#t + 1] = inv:get_stack("board", i):get_name()
end
return t
end
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}
@ -43,7 +52,7 @@ local function attacked(color, idx, inv)
if row >= 1 and row <= 8 and col >= 1 and col <= 8 then
local square = get_square(row, col)
local square_name = inv:get_stack("board", square):get_name()
local square_name = board[square]
local piece, pieceColor = square_name:match(":(%w+)_(%w+)")
if piece then
@ -75,10 +84,10 @@ local function attacked(color, idx, inv)
return threatDetected
end
local function locate_kings(inv)
local function locate_kings(board)
local Bidx, Widx
for i = 1, 64 do
local piece, color = inv:get_stack("board", i):get_name():match(":(%w+)_(%w+)")
local piece, color = board[i]:match(":(%w+)_(%w+)")
if piece == "king" then
if color == "black" then
Bidx = i
@ -683,22 +692,25 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player
meta:set_int("castlingWhiteL", 0)
meta:set_int("castlingWhiteR", 0)
local whiteAttacked = attacked("white", to_index, inv)
if whiteAttacked then
return 0
end
elseif thisMove == "black" then
meta:set_int("castlingBlackL", 0)
meta:set_int("castlingBlackR", 0)
local blackAttacked = attacked("black", to_index, inv)
if blackAttacked then
return 0
end
end
end
local board = board_to_table(inv)
board[to_index] = board[from_index]
board[from_index] = ""
local black_king_idx, white_king_idx = locate_kings(board)
local blackAttacked = attacked("black", black_king_idx, board)
local whiteAttacked = attacked("white", white_king_idx, board)
if (thisMove == "black" and blackAttacked) or
(thisMove == "white" and whiteAttacked) then
return 0
end
lastMove = thisMove
meta:set_string("lastMove", lastMove)
@ -713,6 +725,39 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player
return 1
end
function realchess.on_move(pos, from_list, from_index)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_stack(from_list, from_index, '')
local board = board_to_table(inv)
local black_king_idx, white_king_idx = locate_kings(board)
local black_king_attacked = attacked("black", black_king_idx, board)
local white_king_attacked = attacked("white", white_king_idx, board)
local playerWhite = meta:get_string("playerWhite")
local playerBlack = meta:get_string("playerBlack")
local moves = meta:get_string("moves")
local eaten_img = meta:get_string("eaten_img")
local lastMove = meta:get_string("lastMove")
local turnBlack = minetest.colorize("#000001", (lastMove == "white" and playerBlack ~= "") and
playerBlack .. "..." or playerBlack)
local turnWhite = minetest.colorize("#000001", (lastMove == "black" and playerWhite ~= "") and
playerWhite .. "..." or playerWhite)
local check_s = minetest.colorize("#FF0000", "\\[check\\]")
local formspec = fs ..
"label[1.9,0.3;" .. turnBlack .. (black_king_attacked and " " .. check_s or "") .. "]" ..
"label[1.9,9.15;" .. turnWhite .. (white_king_attacked and " " .. check_s or "") .. "]" ..
"table[8.9,1.05;5.07,3.75;moves;" .. moves:sub(1,-2) .. ";1]" ..
eaten_img
meta:set_string("formspec", formspec)
return false
end
local function timeout_format(timeout_limit)
local time_remaining = timeout_limit - minetest.get_gametime()
local minutes = math.floor(time_remaining / 60)
@ -771,38 +816,6 @@ function realchess.dig(pos, player)
timeout_format(timeout_limit))
end
function realchess.on_move(pos, from_list, from_index)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_stack(from_list, from_index, '')
local black_king_idx, white_king_idx = locate_kings(inv)
local black_king_attacked = attacked("black", black_king_idx, inv)
local white_king_attacked = attacked("white", white_king_idx, inv)
local playerWhite = meta:get_string("playerWhite")
local playerBlack = meta:get_string("playerBlack")
local moves = meta:get_string("moves")
local eaten_img = meta:get_string("eaten_img")
local lastMove = meta:get_string("lastMove")
local turnBlack = minetest.colorize("#000001", (lastMove == "white" and playerBlack ~= "") and
playerBlack .. "..." or playerBlack)
local turnWhite = minetest.colorize("#000001", (lastMove == "black" and playerWhite ~= "") and
playerWhite .. "..." or playerWhite)
local check_s = minetest.colorize("#FF0000", "\\[check\\]")
local formspec = fs ..
"label[1.9,0.3;" .. turnBlack .. (black_king_attacked and " " .. check_s or "") .. "]" ..
"label[1.9,9.15;" .. turnWhite .. (white_king_attacked and " " .. check_s or "") .. "]" ..
"table[8.9,1.05;5.07,3.75;moves;" .. moves:sub(1,-2) .. ";1]" ..
eaten_img
meta:set_string("formspec", formspec)
return false
end
minetest.register_node(":realchess:chessboard", {
description = "Chess Board",
drawtype = "nodebox",