Add a singleplayer mode to the chess

master
Jean-Patrick Guerrero 2019-03-10 23:50:16 +01:00
parent b5bbb1be2e
commit 63794662ee
1 changed files with 62 additions and 51 deletions

View File

@ -38,30 +38,28 @@ local piece_values = {
king = 900
}
local function get_possible_moves(inv, from_idx)
local piece, color = inv:get_stack("board", from_idx):get_name():match(":(%w+)_(%w+)")
local function get_possible_moves(board, from_idx)
local piece, color = board[from_idx]:match(":(%w+)_(%w+)")
if not piece then return end
local moves = {}
local from_x, from_y = index_to_xy(from_idx)
for i = 1, 64 do
local stack = inv:get_stack("board", i)
local stack_name = stack:get_name()
local stack_name = board[i]
if stack_name:find((color == "black" and "white" or "black")) or
stack:is_empty() then
stack_name == "" then
moves[i] = 0
end
end
for to_idx in pairs(moves) do
local pieceTo = inv:get_stack("board", to_idx):get_name()
local pieceTo = board[to_idx]
local to_x, to_y = index_to_xy(to_idx)
-- PAWN
if piece == "pawn" then
if color == "white" then
local pawnWhiteMove = inv:get_stack("board", xy_to_index(from_x, from_y - 1)):get_name()
local pawnWhiteMove = board[xy_to_index(from_x, from_y - 1)]
-- white pawns can go up only
if from_y - 1 == to_y then
if from_x == to_x then
@ -105,7 +103,7 @@ local function get_possible_moves(inv, from_idx)
end
elseif color == "black" then
local pawnBlackMove = inv:get_stack("board", xy_to_index(from_x, from_y + 1)):get_name()
local pawnBlackMove = board[xy_to_index(from_x, from_y + 1)]
-- black pawns can go down only
if from_y + 1 == to_y then
if from_x == to_x then
@ -159,7 +157,7 @@ local function get_possible_moves(inv, from_idx)
-- Moving down
-- Ensure that no piece disturbs the way
for i = from_y + 1, to_y - 1 do
if inv:get_stack("board", xy_to_index(from_x, i)):get_name() ~= "" then
if board[xy_to_index(from_x, i)] ~= "" then
moves[to_idx] = nil
end
end
@ -167,7 +165,7 @@ local function get_possible_moves(inv, from_idx)
-- Mocing up
-- Ensure that no piece disturbs the way
for i = to_y + 1, from_y - 1 do
if inv:get_stack("board", xy_to_index(from_x, i)):get_name() ~= "" then
if board[xy_to_index(from_x, i)] ~= "" then
moves[to_idx] = nil
end
end
@ -178,7 +176,7 @@ local function get_possible_moves(inv, from_idx)
-- mocing right
-- ensure that no piece disturbs the way
for i = from_x + 1, to_x - 1 do
if inv:get_stack("board", xy_to_index(i, from_y)):get_name() ~= "" then
if board[xy_to_index(i, from_y)] ~= "" then
moves[to_idx] = nil
end
end
@ -186,7 +184,7 @@ local function get_possible_moves(inv, from_idx)
-- Mocing left
-- Ensure that no piece disturbs the way
for i = to_x + 1, from_x - 1 do
if inv:get_stack("board", xy_to_index(i, from_y)):get_name() ~= "" then
if board[xy_to_index(i, from_y)] ~= "" then
moves[to_idx] = nil
end
end
@ -248,8 +246,7 @@ local function get_possible_moves(inv, from_idx)
-- Moving right-down
-- Ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then
if board[xy_to_index(from_x + i, from_y + i)] ~= "" then
moves[to_idx] = nil
end
end
@ -257,8 +254,7 @@ local function get_possible_moves(inv, from_idx)
-- Moving right-up
-- Ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then
if board[xy_to_index(from_x + i, from_y - i)] ~= "" then
moves[to_idx] = nil
end
end
@ -268,8 +264,7 @@ local function get_possible_moves(inv, from_idx)
-- Moving left-down
-- Ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then
if board[xy_to_index(from_x - i, from_y + i)] ~= "" then
moves[to_idx] = nil
end
end
@ -277,8 +272,7 @@ local function get_possible_moves(inv, from_idx)
-- Moving left-up
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then
if board[xy_to_index(from_x - i, from_y - i)] ~= "" then
moves[to_idx] = nil
end
end
@ -310,7 +304,7 @@ local function get_possible_moves(inv, from_idx)
-- Moving down
-- Ensure that no piece disturbs the way
for i = from_y + 1, to_y - 1 do
if inv:get_stack("board", xy_to_index(from_x, i)):get_name() ~= "" then
if board[xy_to_index(from_x, i)] ~= "" then
moves[to_idx] = nil
end
end
@ -318,7 +312,7 @@ local function get_possible_moves(inv, from_idx)
-- Mocing up
-- Ensure that no piece disturbs the way
for i = to_y + 1, from_y - 1 do
if inv:get_stack("board", xy_to_index(from_x, i)):get_name() ~= "" then
if board[xy_to_index(from_x, i)] ~= "" then
moves[to_idx] = nil
end
end
@ -328,8 +322,7 @@ local function get_possible_moves(inv, from_idx)
-- Goes right
-- Ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x + i, from_y)):get_name() ~= "" then
if board[xy_to_index(from_x + i, from_y)] ~= "" then
moves[to_idx] = nil
end
end
@ -337,8 +330,7 @@ local function get_possible_moves(inv, from_idx)
-- Goes right-down
-- Ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then
if board[xy_to_index(from_x + i, from_y + i)] ~= "" then
moves[to_idx] = nil
end
end
@ -346,8 +338,7 @@ local function get_possible_moves(inv, from_idx)
-- Goes right-up
-- Ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then
if board[xy_to_index(from_x + i, from_y - i)] ~= "" then
moves[to_idx] = nil
end
end
@ -359,7 +350,7 @@ local function get_possible_moves(inv, from_idx)
-- mocing right
-- ensure that no piece disturbs the way
for i = from_x + 1, to_x - 1 do
if inv:get_stack("board", xy_to_index(i, from_y)):get_name() ~= "" then
if board[xy_to_index(i, from_y)] ~= "" then
moves[to_idx] = nil
end
end
@ -367,7 +358,7 @@ local function get_possible_moves(inv, from_idx)
-- Mocing left
-- Ensure that no piece disturbs the way
for i = to_x + 1, from_x - 1 do
if inv:get_stack("board", xy_to_index(i, from_y)):get_name() ~= "" then
if board[xy_to_index(i, from_y)] ~= "" then
moves[to_idx] = nil
end
end
@ -376,8 +367,7 @@ local function get_possible_moves(inv, from_idx)
-- Goes left-down
-- Ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then
if board[xy_to_index(from_x - i, from_y + i)] ~= "" then
moves[to_idx] = nil
end
end
@ -385,8 +375,7 @@ local function get_possible_moves(inv, from_idx)
-- Goes left-up
-- Ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(
"board", xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then
if board[xy_to_index(from_x - i, from_y - i)] ~= "" then
moves[to_idx] = nil
end
end
@ -415,9 +404,7 @@ local function get_possible_moves(inv, from_idx)
if not next(moves) then return end
for i in pairs(moves) do
local stack = inv:get_stack("board", tonumber(i))
local stack_name = stack:get_name()
local stack_name = board[tonumber(i)]
if stack_name ~= "" then
for p, value in pairs(piece_values) do
if stack_name:find(p) then
@ -593,6 +580,14 @@ for i = 1, #pieces do
end
pieces_str = pieces_str .. "69=mailbox_blank16.png"
local fs_init = [[
size[4,1.2;]
no_prepend[]
label[0,0;Select a mode:]
button[0,0.5;2,1;single;Singleplayer]
button[2,0.5;2,1;multi;Multiplayer]
]]
local fs = [[
size[14.7,10;]
no_prepend[]
@ -686,7 +681,7 @@ function realchess.init(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
meta:set_string("formspec", fs)
meta:set_string("formspec", fs_init)
meta:set_string("infotext", "Chess Board")
meta:set_string("playerBlack", "")
meta:set_string("playerWhite", "")
@ -702,6 +697,7 @@ function realchess.init(pos)
meta:set_string("moves", "")
meta:set_string("eaten", "")
meta:set_string("mode", "")
inv:set_list("board", pieces)
inv:set_size("board", 64)
@ -1233,24 +1229,19 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player
get_moves_list(meta, pieceFrom, pieceTo, pieceTo_s, from_index, to_index)
get_eaten_list(meta, pieceTo, pieceTo_s)
--print("from_index: " .. from_index)
--print("to_index: " .. to_index)
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 function ai_move(inv, meta)
local board_t = board_to_table(inv)
local lastMove = meta:get_string("lastMove")
if lastMove == "white" then
update_formspec(meta)
local moves = {}
for i = 1, 64 do
local possibleMoves = get_possible_moves(inv, i)
local possibleMoves = get_possible_moves(board_t, i)
local stack_name = inv:get_stack("board", i):get_name()
if stack_name:find("black") then
@ -1258,9 +1249,8 @@ function realchess.on_move(pos, from_list, from_index)
end
end
--minetest.log("warning", "moves: " .. dump(moves))
local choice_from, choice_to = best_move(moves)
local pieceFrom = inv:get_stack("board", choice_from):get_name()
local pieceTo = inv:get_stack("board", choice_to):get_name()
local pieceTo_s = pieceTo ~= "" and pieceTo:match(":(%w+_%w+)") or ""
@ -1313,7 +1303,12 @@ function realchess.on_move(pos, from_list, from_index)
return
end
else
inv:set_stack("board", choice_to, pieceFrom)
if pieceFrom:find("pawn") and choice_to >= 57 and choice_to <= 64 then
inv:set_stack("board", choice_to, "realchess:queen_black")
else
inv:set_stack("board", choice_to, pieceFrom)
end
inv:set_stack("board", choice_from, "")
end
@ -1341,6 +1336,16 @@ function realchess.on_move(pos, from_list, from_index)
else
update_formspec(meta)
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, "")
if meta:get_string("mode") == "single" then
ai_move(inv, meta)
end
return false
end
@ -1366,6 +1371,12 @@ function realchess.fields(pos, _, fields, sender)
local lastMoveTime = meta:get_int("lastMoveTime")
if fields.quit then return end
if fields.single or fields.multi then
meta:set_string("mode", (fields.single and "single" or "multi"))
update_formspec(meta)
return
end
-- Timeout is 5 min. by default for resetting the game (non-players only)
if fields.new then
if (playerWhite == playerName or playerBlack == playerName) then