Chess "AI" now uses move function like the player
This commit is contained in:
parent
ef65e86547
commit
c1bb45d8b2
217
src/chess.lua
217
src/chess.lua
@ -58,7 +58,7 @@ local letters = {'a','b','c','d','e','f','g','h'}
|
|||||||
|
|
||||||
local function index_to_notation(idx)
|
local function index_to_notation(idx)
|
||||||
local x, y = index_to_xy(idx)
|
local x, y = index_to_xy(idx)
|
||||||
if not x then
|
if not x or not y then
|
||||||
return "??"
|
return "??"
|
||||||
end
|
end
|
||||||
local xstr = letters[x+1] or "?"
|
local xstr = letters[x+1] or "?"
|
||||||
@ -893,6 +893,7 @@ local starting_grid = {
|
|||||||
"realchess:bishop_black_2",
|
"realchess:bishop_black_2",
|
||||||
"realchess:knight_black_2",
|
"realchess:knight_black_2",
|
||||||
"realchess:rook_black_2",
|
"realchess:rook_black_2",
|
||||||
|
-- rank '8'
|
||||||
-- rank '7'
|
-- rank '7'
|
||||||
"realchess:pawn_black_1",
|
"realchess:pawn_black_1",
|
||||||
"realchess:pawn_black_2",
|
"realchess:pawn_black_2",
|
||||||
@ -903,8 +904,10 @@ local starting_grid = {
|
|||||||
"realchess:pawn_black_7",
|
"realchess:pawn_black_7",
|
||||||
"realchess:pawn_black_8",
|
"realchess:pawn_black_8",
|
||||||
-- ranks '6' thru '3'
|
-- ranks '6' thru '3'
|
||||||
'','','','','','','','','','','','','','','','',
|
'','','','','','','','',
|
||||||
'','','','','','','','','','','','','','','','',
|
'','','','','','','','',
|
||||||
|
'','','','','','','','',
|
||||||
|
'','','','','','','','',
|
||||||
-- rank '2'
|
-- rank '2'
|
||||||
"realchess:pawn_white_1",
|
"realchess:pawn_white_1",
|
||||||
"realchess:pawn_white_2",
|
"realchess:pawn_white_2",
|
||||||
@ -1412,34 +1415,36 @@ function realchess.init(pos)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- The move logic of Chess.
|
-- The move logic of Chess.
|
||||||
-- This is meant to be called when the player *ATTEMPTS* to move a piece
|
-- This is meant to be called when a player *ATTEMPTS* to move a piece
|
||||||
-- from one slot of the inventory to another one and reacts accordingly.
|
-- from one slot of the inventory to another one and reacts accordingly.
|
||||||
-- If the move is valid, the inventory is changed to reflect the new
|
-- If the move is valid, the inventory is changed to reflect the new
|
||||||
-- situation. If the move is invalid, nothing happens.
|
-- situation, and the game state and UI is upated as well and true
|
||||||
|
-- is returned.
|
||||||
|
-- If the move is invalid, nothing happens and false is returned.
|
||||||
|
-- Note: The move can also be done by a computer player.
|
||||||
--
|
--
|
||||||
-- * pos: Chessboard node pos
|
-- * meta: Chessboard node metadata
|
||||||
-- * from_list: Inventory list of source square
|
-- * from_list: Inventory list of source square
|
||||||
-- * from_index: Inventory index of source square
|
-- * from_index: Inventory index of source square
|
||||||
-- * to_list: Inventory list of destination square
|
-- * to_list: Inventory list of destination square
|
||||||
-- * to_index: Inventory list of destination square
|
-- * to_index: Inventory list of destination square
|
||||||
function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
-- * playerName: Name of player to move
|
||||||
|
function realchess.move(meta, from_list, from_index, to_list, to_index, playerName)
|
||||||
if from_list ~= "board" and to_list ~= "board" then
|
if from_list ~= "board" and to_list ~= "board" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local promo = meta:get_string("promotionActive")
|
local promo = meta:get_string("promotionActive")
|
||||||
if promo ~= "" then
|
if promo ~= "" then
|
||||||
-- Can't move when waiting for selecting a pawn promotion
|
-- Can't move when waiting for selecting a pawn promotion
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
local gameResult = meta:get_string("gameResult")
|
local gameResult = meta:get_string("gameResult")
|
||||||
if gameResult ~= "" then
|
if gameResult ~= "" then
|
||||||
-- No moves if game is over
|
-- No moves if game is over
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local playerName = player:get_player_name()
|
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
local pieceFrom = inv:get_stack(from_list, from_index):get_name()
|
local pieceFrom = inv:get_stack(from_list, from_index):get_name()
|
||||||
local pieceTo = inv:get_stack(to_list, to_index):get_name()
|
local pieceTo = inv:get_stack(to_list, to_index):get_name()
|
||||||
@ -1452,7 +1457,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
if pieceFrom:find("white") then
|
if pieceFrom:find("white") then
|
||||||
if pieceTo:find("white") then
|
if pieceTo:find("white") then
|
||||||
-- Don't replace pieces of same color
|
-- Don't replace pieces of same color
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if lastMove == "white" then
|
if lastMove == "white" then
|
||||||
@ -1462,7 +1467,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
|
|
||||||
if playerWhite ~= "" and playerWhite ~= playerName then
|
if playerWhite ~= "" and playerWhite ~= playerName then
|
||||||
minetest.chat_send_player(playerName, chat_prefix .. S("Someone else plays white pieces!"))
|
minetest.chat_send_player(playerName, chat_prefix .. S("Someone else plays white pieces!"))
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
playerWhite = playerName
|
playerWhite = playerName
|
||||||
@ -1471,22 +1476,22 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
elseif pieceFrom:find("black") then
|
elseif pieceFrom:find("black") then
|
||||||
if pieceTo:find("black") then
|
if pieceTo:find("black") then
|
||||||
-- Don't replace pieces of same color
|
-- Don't replace pieces of same color
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if lastMove == "black" then
|
if lastMove == "black" then
|
||||||
-- let the other invocation decide in case of a capture
|
-- let the other invocation decide in case of a capture
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if playerBlack ~= "" and playerBlack ~= playerName then
|
if playerBlack ~= "" and playerBlack ~= playerName then
|
||||||
minetest.chat_send_player(playerName, chat_prefix .. S("Someone else plays black pieces!"))
|
minetest.chat_send_player(playerName, chat_prefix .. S("Someone else plays black pieces!"))
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if lastMove == "" then
|
if lastMove == "" then
|
||||||
-- Nobody has moved yet, and Black cannot move first
|
-- Nobody has moved yet, and Black cannot move first
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
playerBlack = playerName
|
playerBlack = playerName
|
||||||
@ -1511,7 +1516,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- single step
|
-- single step
|
||||||
if from_x == to_x then
|
if from_x == to_x then
|
||||||
if pieceTo ~= "" then
|
if pieceTo ~= "" then
|
||||||
return
|
return false
|
||||||
elseif to_index >= 1 and to_index <= 8 then
|
elseif to_index >= 1 and to_index <= 8 then
|
||||||
-- activate promotion
|
-- activate promotion
|
||||||
promotion = true
|
promotion = true
|
||||||
@ -1528,17 +1533,17 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
meta:set_int("promotionPawnToIdx", to_index)
|
meta:set_int("promotionPawnToIdx", to_index)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
elseif from_y - 2 == to_y then
|
elseif from_y - 2 == to_y then
|
||||||
-- double step
|
-- double step
|
||||||
if pieceTo ~= "" or from_y < 6 or pawnWhiteMove ~= "" then
|
if pieceTo ~= "" or from_y < 6 or pawnWhiteMove ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
-- store the destination of this double step in meta (needed for en passant check)
|
-- store the destination of this double step in meta (needed for en passant check)
|
||||||
doublePawnStep = to_index
|
doublePawnStep = to_index
|
||||||
else
|
else
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
@ -1552,7 +1557,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
|
|
||||||
if from_x == to_x then
|
if from_x == to_x then
|
||||||
if pieceTo ~= "" then
|
if pieceTo ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
elseif from_x - 1 == to_x or from_x + 1 == to_x then
|
elseif from_x - 1 == to_x or from_x + 1 == to_x then
|
||||||
-- capture
|
-- capture
|
||||||
@ -1568,10 +1573,10 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not can_capture then
|
if not can_capture then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif thisMove == "black" then
|
elseif thisMove == "black" then
|
||||||
@ -1581,7 +1586,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- single step
|
-- single step
|
||||||
if from_x == to_x then
|
if from_x == to_x then
|
||||||
if pieceTo ~= "" then
|
if pieceTo ~= "" then
|
||||||
return
|
return false
|
||||||
elseif to_index >= 57 and to_index <= 64 then
|
elseif to_index >= 57 and to_index <= 64 then
|
||||||
-- activate promotion
|
-- activate promotion
|
||||||
promotion = true
|
promotion = true
|
||||||
@ -1598,17 +1603,17 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
meta:set_int("promotionPawnToIdx", to_index)
|
meta:set_int("promotionPawnToIdx", to_index)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
elseif from_y + 2 == to_y then
|
elseif from_y + 2 == to_y then
|
||||||
-- double step
|
-- double step
|
||||||
if pieceTo ~= "" or from_y > 1 or pawnBlackMove ~= "" then
|
if pieceTo ~= "" or from_y > 1 or pawnBlackMove ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
-- store the destination of this double step in meta (needed for en passant check)
|
-- store the destination of this double step in meta (needed for en passant check)
|
||||||
doublePawnStep = to_index
|
doublePawnStep = to_index
|
||||||
else
|
else
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
@ -1622,7 +1627,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
|
|
||||||
if from_x == to_x then
|
if from_x == to_x then
|
||||||
if pieceTo ~= "" then
|
if pieceTo ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
elseif from_x - 1 == to_x or from_x + 1 == to_x then
|
elseif from_x - 1 == to_x or from_x + 1 == to_x then
|
||||||
-- capture
|
-- capture
|
||||||
@ -1638,13 +1643,13 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not can_capture then
|
if not can_capture then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ROOK
|
-- ROOK
|
||||||
@ -1656,7 +1661,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- Ensure that no piece disturbs the way
|
-- Ensure that no piece disturbs the way
|
||||||
for i = from_y + 1, to_y - 1 do
|
for i = from_y + 1, to_y - 1 do
|
||||||
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
|
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1664,7 +1669,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- Ensure that no piece disturbs the way
|
-- Ensure that no piece disturbs the way
|
||||||
for i = to_y + 1, from_y - 1 do
|
for i = to_y + 1, from_y - 1 do
|
||||||
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
|
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1675,7 +1680,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- ensure that no piece disturbs the way
|
-- ensure that no piece disturbs the way
|
||||||
for i = from_x + 1, to_x - 1 do
|
for i = from_x + 1, to_x - 1 do
|
||||||
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
|
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1683,13 +1688,13 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- Ensure that no piece disturbs the way
|
-- Ensure that no piece disturbs the way
|
||||||
for i = to_x + 1, from_x - 1 do
|
for i = to_x + 1, from_x - 1 do
|
||||||
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
|
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Attempt to move arbitrarily -> abort
|
-- Attempt to move arbitrarily -> abort
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Lose castling right when moving rook
|
-- Lose castling right when moving rook
|
||||||
@ -1726,7 +1731,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
|
|
||||||
-- Ensure that dx == 1 and dy == 2
|
-- Ensure that dx == 1 and dy == 2
|
||||||
if dx ~= 1 or dy ~= 2 then
|
if dx ~= 1 or dy ~= 2 then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
-- Just ensure that destination cell does not contain friend piece
|
-- Just ensure that destination cell does not contain friend piece
|
||||||
-- ^ It was done already thus everything ok
|
-- ^ It was done already thus everything ok
|
||||||
@ -1742,7 +1747,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
if dy < 0 then dy = -dy end
|
if dy < 0 then dy = -dy end
|
||||||
|
|
||||||
-- Ensure dx and dy are equal
|
-- Ensure dx and dy are equal
|
||||||
if dx ~= dy then return end
|
if dx ~= dy then return false end
|
||||||
|
|
||||||
if from_x < to_x then
|
if from_x < to_x then
|
||||||
if from_y < to_y then
|
if from_y < to_y then
|
||||||
@ -1751,7 +1756,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
for i = 1, dx - 1 do
|
for i = 1, dx - 1 do
|
||||||
if inv:get_stack(
|
if inv:get_stack(
|
||||||
from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then
|
from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1760,7 +1765,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
for i = 1, dx - 1 do
|
for i = 1, dx - 1 do
|
||||||
if inv:get_stack(
|
if inv:get_stack(
|
||||||
from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then
|
from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1771,7 +1776,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
for i = 1, dx - 1 do
|
for i = 1, dx - 1 do
|
||||||
if inv:get_stack(
|
if inv:get_stack(
|
||||||
from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then
|
from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1780,7 +1785,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
for i = 1, dx - 1 do
|
for i = 1, dx - 1 do
|
||||||
if inv:get_stack(
|
if inv:get_stack(
|
||||||
from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then
|
from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1797,7 +1802,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
|
|
||||||
-- Ensure valid relative move
|
-- Ensure valid relative move
|
||||||
if dx ~= 0 and dy ~= 0 and dx ~= dy then
|
if dx ~= 0 and dy ~= 0 and dx ~= dy then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if from_x == to_x then
|
if from_x == to_x then
|
||||||
@ -1806,7 +1811,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- Ensure that no piece disturbs the way
|
-- Ensure that no piece disturbs the way
|
||||||
for i = from_y + 1, to_y - 1 do
|
for i = from_y + 1, to_y - 1 do
|
||||||
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
|
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1814,7 +1819,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- Ensure that no piece disturbs the way
|
-- Ensure that no piece disturbs the way
|
||||||
for i = to_y + 1, from_y - 1 do
|
for i = to_y + 1, from_y - 1 do
|
||||||
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
|
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1824,7 +1829,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- Ensure that no piece disturbs the way
|
-- Ensure that no piece disturbs the way
|
||||||
for i = from_x + 1, to_x - 1 do
|
for i = from_x + 1, to_x - 1 do
|
||||||
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
|
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif from_y < to_y then
|
elseif from_y < to_y then
|
||||||
@ -1833,7 +1838,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
for i = 1, dx - 1 do
|
for i = 1, dx - 1 do
|
||||||
if inv:get_stack(
|
if inv:get_stack(
|
||||||
from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then
|
from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1842,7 +1847,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
for i = 1, dx - 1 do
|
for i = 1, dx - 1 do
|
||||||
if inv:get_stack(
|
if inv:get_stack(
|
||||||
from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then
|
from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1852,7 +1857,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- Ensure that no piece disturbs the way and destination cell does
|
-- Ensure that no piece disturbs the way and destination cell does
|
||||||
for i = to_x + 1, from_x - 1 do
|
for i = to_x + 1, from_x - 1 do
|
||||||
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
|
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif from_y < to_y then
|
elseif from_y < to_y then
|
||||||
@ -1861,7 +1866,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
for i = 1, dx - 1 do
|
for i = 1, dx - 1 do
|
||||||
if inv:get_stack(
|
if inv:get_stack(
|
||||||
from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then
|
from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1870,7 +1875,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
for i = 1, dx - 1 do
|
for i = 1, dx - 1 do
|
||||||
if inv:get_stack(
|
if inv:get_stack(
|
||||||
from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then
|
from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1903,7 +1908,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if dx > 1 or dy > 1 then
|
if dx > 1 or dy > 1 then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
kingMoved = true
|
kingMoved = true
|
||||||
@ -1916,7 +1921,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
|
|
||||||
local black_king_idx, white_king_idx = locate_kings(board)
|
local black_king_idx, white_king_idx = locate_kings(board)
|
||||||
if not black_king_idx or not white_king_idx then
|
if not black_king_idx or not white_king_idx then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
local blackAttacked = attacked("black", black_king_idx, board)
|
local blackAttacked = attacked("black", black_king_idx, board)
|
||||||
local whiteAttacked = attacked("white", white_king_idx, board)
|
local whiteAttacked = attacked("white", white_king_idx, board)
|
||||||
@ -1924,10 +1929,10 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
-- Refuse to move if it would put or leave the own king
|
-- Refuse to move if it would put or leave the own king
|
||||||
-- under attack
|
-- under attack
|
||||||
if blackAttacked and thisMove == "black" then
|
if blackAttacked and thisMove == "black" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
if whiteAttacked and thisMove == "white" then
|
if whiteAttacked and thisMove == "white" then
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if en_passant_target then
|
if en_passant_target then
|
||||||
@ -1959,7 +1964,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
|||||||
|
|
||||||
realchess.move_piece(meta, pieceFrom, from_list, from_index, to_list, to_index)
|
realchess.move_piece(meta, pieceFrom, from_list, from_index, to_list, to_index)
|
||||||
|
|
||||||
return
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ai_move(inv, meta)
|
local function ai_move(inv, meta)
|
||||||
@ -2019,65 +2024,43 @@ local function ai_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
|
||||||
if not kingSafe then
|
|
||||||
if bestMoveSaveTo ~= nil then
|
|
||||||
inv:set_stack("board", bestMoveSaveTo, board[bestMoveSaveFrom])
|
|
||||||
inv:set_stack("board", bestMoveSaveFrom, "")
|
|
||||||
meta:set_string(aiColor.."Attacked", "")
|
|
||||||
else
|
|
||||||
return
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if aiColor == "black" and pieceFrom:find("pawn") and choice_to >= 57 and choice_to <= 64 then
|
|
||||||
inv:set_stack("board", choice_to, "realchess:queen_black")
|
|
||||||
elseif aiColor == "white" and pieceFrom:find("pawn") and choice_to >= 1 and choice_to <= 8 then
|
|
||||||
inv:set_stack("board", choice_to, "realchess:queen_white")
|
|
||||||
else
|
|
||||||
inv:set_stack("board", choice_to, pieceFrom)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Note the pawn double step
|
|
||||||
local c_from_x, c_from_y = index_to_xy(choice_from)
|
|
||||||
local c_to_x, c_to_y = index_to_xy(choice_to)
|
|
||||||
if pieceFrom:find("pawn") and math.abs(c_from_y - c_to_y) == 2 then
|
|
||||||
meta:set_int("prevDoublePawnStepTo", choice_to)
|
|
||||||
else
|
|
||||||
meta:set_int("prevDoublePawnStepTo", 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
inv:set_stack("board", choice_from, "")
|
|
||||||
end
|
|
||||||
|
|
||||||
board = board_to_table(inv)
|
|
||||||
black_king_idx, white_king_idx = locate_kings(board)
|
|
||||||
local opponent_king_idx
|
|
||||||
if opponentColor == "white" then
|
|
||||||
opponent_king_idx = white_king_idx
|
|
||||||
else
|
|
||||||
opponent_king_idx = black_king_idx
|
|
||||||
end
|
|
||||||
local opponentAttacked = attacked(opponentColor, opponent_king_idx, board)
|
|
||||||
|
|
||||||
if opponentAttacked then
|
|
||||||
meta:set_string(opponentColor.."Attacked", "true")
|
|
||||||
end
|
|
||||||
|
|
||||||
if aiColor == "black" and meta:get_string("playerBlack") == "" then
|
if aiColor == "black" and meta:get_string("playerBlack") == "" then
|
||||||
meta:set_string("playerBlack", AI_NAME)
|
meta:set_string("playerBlack", AI_NAME)
|
||||||
elseif aiColor == "white" and meta:get_string("playerWhite") == "" then
|
elseif aiColor == "white" and meta:get_string("playerWhite") == "" then
|
||||||
meta:set_string("playerWhite", AI_NAME)
|
meta:set_string("playerWhite", AI_NAME)
|
||||||
end
|
end
|
||||||
|
local moveOK = false
|
||||||
meta:set_string("lastMove", aiColor)
|
if not kingSafe then
|
||||||
meta:set_int("lastMoveTime", minetest.get_gametime())
|
-- Make a move to put the king out of check
|
||||||
|
if bestMoveSaveTo ~= nil then
|
||||||
add_move_to_moves_list(meta, pieceFrom, pieceTo, choice_from, choice_to)
|
moveOK = realchess.move(meta, "board", bestMoveSaveFrom, "board", bestMoveSaveTo, AI_NAME)
|
||||||
add_to_eaten_list(meta, pieceTo)
|
if not moveOK then
|
||||||
|
minetest.log("error", "[xdecor] Chess: AI tried to make an invalid move (to protect the king) from "..
|
||||||
update_game_result(meta)
|
index_to_notation(bestMoveSaveFrom).." to "..index_to_notation(bestMoveSaveTo))
|
||||||
|
end
|
||||||
update_formspec(meta)
|
else
|
||||||
else
|
return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Make a regular move
|
||||||
|
moveOK = realchess.move(meta, "board", choice_from, "board", choice_to, AI_NAME)
|
||||||
|
if not moveOK then
|
||||||
|
minetest.log("error", "[xdecor] Chess: AI tried to make an invalid move from "..
|
||||||
|
index_to_notation(choice_from).." to "..index_to_notation(choice_to))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- AI resigns if it made an incorrect move
|
||||||
|
if not moveOK then
|
||||||
|
meta:set_string("gameResultReason", "resign")
|
||||||
|
if aiColor == "black" then
|
||||||
|
meta:set_string("gameResult", "whiteWon")
|
||||||
|
add_special_to_moves_list(meta, "whiteWon")
|
||||||
|
else
|
||||||
|
meta:set_string("gameResult", "blackWon")
|
||||||
|
add_special_to_moves_list(meta, "blackWon")
|
||||||
|
end
|
||||||
|
update_formspec(meta)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
@ -2408,7 +2391,15 @@ if ENABLE_CHESS_GAMES then
|
|||||||
-- to move pieces to.
|
-- to move pieces to.
|
||||||
-- This function may manipulate the inventory. This is a bit dirty
|
-- This function may manipulate the inventory. This is a bit dirty
|
||||||
-- because this is not really what the allow function is meant to do.
|
-- because this is not really what the allow function is meant to do.
|
||||||
realchess.move(pos, from_list, from_index, to_list, to_index, player)
|
local meta = minetest.get_meta(pos)
|
||||||
|
local playerName
|
||||||
|
if player and player:is_player() then
|
||||||
|
playerName = player:get_player_name()
|
||||||
|
else
|
||||||
|
playerName = "<UNKNOWN PLAYER>"
|
||||||
|
minetest.log("error", "[xdecor] Chess: An unknown player tried to move a piece in the chessboard inventory")
|
||||||
|
end
|
||||||
|
realchess.move(meta, from_list, from_index, to_list, to_index, playerName)
|
||||||
-- We always return 0 to disable all *builtin* inventory moves, since
|
-- We always return 0 to disable all *builtin* inventory moves, since
|
||||||
-- we do it ourselves. This should be fine because there shouldn't be a
|
-- we do it ourselves. This should be fine because there shouldn't be a
|
||||||
-- conflict between this mod and Minetest then.
|
-- conflict between this mod and Minetest then.
|
||||||
|
Loading…
Reference in New Issue
Block a user