]> git.lizzy.rs Git - xdecor.git/commitdiff
Fix checkmate logic
authorJean-Patrick Guerrero <jeanpatrick.guerrero@gmail.com>
Sat, 25 Aug 2018 10:55:03 +0000 (12:55 +0200)
committerJean-Patrick Guerrero <jeanpatrick.guerrero@gmail.com>
Sat, 25 Aug 2018 10:55:03 +0000 (12:55 +0200)
src/chess.lua

index 193149013719a1b3716f706a1eaa703964f4558d..53d05f1157880ba044dcaad292a4dc7e297be84e 100644 (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",