Fix checkmate logic
This commit is contained in:
parent
70277d4216
commit
ed931905be
105
src/chess.lua
105
src/chess.lua
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user