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 queenThreats = {true, true, true, true, true, true, true, true}
|
||||||
local kingThreats = {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 threatDetected = false
|
||||||
local kill = color == "white"
|
local kill = color == "white"
|
||||||
local pawnThreats = {kill, false, kill, false, false, not kill, false, not kill}
|
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
|
if row >= 1 and row <= 8 and col >= 1 and col <= 8 then
|
||||||
local square = get_square(row, col)
|
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+)")
|
local piece, pieceColor = square_name:match(":(%w+)_(%w+)")
|
||||||
|
|
||||||
if piece then
|
if piece then
|
||||||
@ -75,10 +84,10 @@ local function attacked(color, idx, inv)
|
|||||||
return threatDetected
|
return threatDetected
|
||||||
end
|
end
|
||||||
|
|
||||||
local function locate_kings(inv)
|
local function locate_kings(board)
|
||||||
local Bidx, Widx
|
local Bidx, Widx
|
||||||
for i = 1, 64 do
|
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 piece == "king" then
|
||||||
if color == "black" then
|
if color == "black" then
|
||||||
Bidx = i
|
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("castlingWhiteL", 0)
|
||||||
meta:set_int("castlingWhiteR", 0)
|
meta:set_int("castlingWhiteR", 0)
|
||||||
|
|
||||||
local whiteAttacked = attacked("white", to_index, inv)
|
|
||||||
if whiteAttacked then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif thisMove == "black" then
|
elseif thisMove == "black" then
|
||||||
meta:set_int("castlingBlackL", 0)
|
meta:set_int("castlingBlackL", 0)
|
||||||
meta:set_int("castlingBlackR", 0)
|
meta:set_int("castlingBlackR", 0)
|
||||||
|
|
||||||
local blackAttacked = attacked("black", to_index, inv)
|
|
||||||
if blackAttacked then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
end
|
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
|
lastMove = thisMove
|
||||||
|
|
||||||
meta:set_string("lastMove", lastMove)
|
meta:set_string("lastMove", lastMove)
|
||||||
@ -713,6 +725,39 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player
|
|||||||
return 1
|
return 1
|
||||||
end
|
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 function timeout_format(timeout_limit)
|
||||||
local time_remaining = timeout_limit - minetest.get_gametime()
|
local time_remaining = timeout_limit - minetest.get_gametime()
|
||||||
local minutes = math.floor(time_remaining / 60)
|
local minutes = math.floor(time_remaining / 60)
|
||||||
@ -771,38 +816,6 @@ function realchess.dig(pos, player)
|
|||||||
timeout_format(timeout_limit))
|
timeout_format(timeout_limit))
|
||||||
end
|
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", {
|
minetest.register_node(":realchess:chessboard", {
|
||||||
description = "Chess Board",
|
description = "Chess Board",
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
|
Loading…
Reference in New Issue
Block a user