diff --git a/chess.lua b/chess.lua index 5d08f86..8e0691e 100644 --- a/chess.lua +++ b/chess.lua @@ -1,12 +1,10 @@ --- See https://github.com/kilbith/realchess for the main repository - local realchess = {} screwdriver = screwdriver or {} -local function index_to_xy(index) - index = index - 1 - local x = index % 8 - local y = (index - x) / 8 +local function index_to_xy(idx) + idx = idx - 1 + local x = idx % 8 + local y = (idx - x) / 8 return x, y end @@ -17,8 +15,6 @@ end function realchess.init(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - - inv:set_size("board", 64) local formspec = [[ size[8,8.6;] bgcolor[#080808BB;true] @@ -28,13 +24,13 @@ function realchess.init(pos) listcolors[#00000000;#00000000;#00000000;#30434C;#FFF] ]] meta:set_string("formspec", formspec) - meta:set_string("infotext", "Chess Board") meta:set_string("playerBlack", "") meta:set_string("playerWhite", "") meta:set_string("lastMove", "") - meta:set_int("lastMoveTime", 0) meta:set_string("winner", "") + + meta:set_int("lastMoveTime", 0) meta:set_int("castlingBlackL", 1) meta:set_int("castlingBlackR", 1) meta:set_int("castlingWhiteL", 1) @@ -56,11 +52,9 @@ function realchess.init(pos) "realchess:pawn_black_5", "realchess:pawn_black_6", "realchess:pawn_black_7", - "realchess:pawn_black_8", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", + "realchess:pawn_black_8", + '','','','','','','','','','','','','','','','', + '','','','','','','','','','','','','','','','', "realchess:pawn_white_1", "realchess:pawn_white_2", "realchess:pawn_white_3", @@ -78,9 +72,11 @@ function realchess.init(pos) "realchess:knight_white_2", "realchess:rook_white_2" }) + + inv:set_size("board", 64) end -function realchess.move(pos, from_list, from_index, to_list, to_index, count, player) +function realchess.move(pos, from_list, from_index, to_list, to_index, _, player) if from_list ~= "board" and to_list ~= "board" then return 0 end @@ -138,8 +134,9 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl local from_x, from_y = index_to_xy(from_index) local to_x, to_y = index_to_xy(to_index) - if pieceFrom:find("pawn") then + if pieceFrom:sub(11,14) == "pawn" then if thisMove == "white" then + local pawnWhiteMove = inv:get_stack(from_list, xy_to_index(from_x, from_y - 1)):get_name() -- white pawns can go up only if from_y - 1 == to_y then if from_x == to_x then @@ -158,13 +155,14 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl return 0 end elseif from_y - 2 == to_y then - if pieceTo ~= "" or from_y < 6 or inv:get_stack(from_list, xy_to_index(from_x, from_y - 1)):get_name() ~= "" then + if pieceTo ~= "" or from_y < 6 or pawnWhiteMove ~= "" then return 0 end else return 0 end elseif thisMove == "black" then + local pawnBlackMove = inv:get_stack(from_list, xy_to_index(from_x, from_y + 1)):get_name() -- black pawns can go down only if from_y + 1 == to_y then if from_x == to_x then @@ -183,7 +181,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl return 0 end elseif from_y + 2 == to_y then - if pieceTo ~= "" or from_y > 1 or inv:get_stack(from_list, xy_to_index(from_x, from_y + 1)):get_name() ~= "" then + if pieceTo ~= "" or from_y > 1 or pawnBlackMove ~= "" then return 0 end else @@ -212,7 +210,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl return 0 end - elseif pieceFrom:find("rook") then + elseif pieceFrom:sub(11,14) == "rook" then if from_x == to_x then -- moving vertically if from_y < to_y then @@ -256,37 +254,25 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl return 0 end - if thisMove == "white" then - if pieceFrom:find("1") then + if thisMove == "white" or thisMove == "black" then + if pieceFrom:sub(-1) == "1" then meta:set_int("castlingWhiteL", 0) - elseif pieceFrom:find("2") then - meta:set_int("castlingWhiteR", 0) - end - elseif thisMove == "black" then - if pieceFrom:find("1") then - meta:set_int("castlingWhiteL", 0) - elseif pieceFrom:find("2") then + elseif pieceFrom:sub(-1) == "2" then meta:set_int("castlingWhiteR", 0) end end - elseif pieceFrom:find("knight") then + elseif pieceFrom:sub(11,16) == "knight" then -- get relative pos local dx = from_x - to_x local dy = from_y - to_y -- get absolute values - if dx < 0 then - dx = -dx - end - if dy < 0 then - dy = -dy - end + if dx < 0 then dx = -dx end + if dy < 0 then dy = -dy end -- sort x and y - if dx > dy then - dx, dy = dy, dx - end + if dx > dy then dx, dy = dy, dx end -- ensure that dx == 1 and dy == 2 if dx ~= 1 or dy ~= 2 then @@ -295,23 +281,17 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl -- just ensure that destination cell does not contain friend piece -- ^ it was done already thus everything ok - elseif pieceFrom:find("bishop") then + elseif pieceFrom:sub(11,16) == "bishop" then -- get relative pos local dx = from_x - to_x local dy = from_y - to_y -- get absolute values - if dx < 0 then - dx = -dx - end - if dy < 0 then - dy = -dy - end + if dx < 0 then dx = -dx end + if dy < 0 then dy = -dy end -- ensure dx and dy are equal - if dx ~= dy then - return 0 - end + if dx ~= dy then return 0 end if from_x < to_x then if from_y < to_y then @@ -351,17 +331,13 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl end end - elseif pieceFrom:find("queen") then + elseif pieceFrom:sub(11,15) == "queen" then local dx = from_x - to_x local dy = from_y - to_y -- get absolute values - if dx < 0 then - dx = -dx - end - if dy < 0 then - dy = -dy - end + if dx < 0 then dx = -dx end + if dy < 0 then dy = -dy end -- ensure valid relative move if dx ~= 0 and dy ~= 0 and dx ~= dy then @@ -440,7 +416,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl end end - elseif pieceFrom:find("king") then + elseif pieceFrom:sub(11,14) == "king" then local dx = from_x - to_x local dy = from_y - to_y local check = true @@ -448,7 +424,10 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl if thisMove == "white" then if from_y == 7 and to_y == 7 then if to_x == 1 then - if meta:get_int("castlingWhiteL") == 1 and inv:get_stack(from_list, 57):get_name() == "realchess:rook_white_1" then + local castlingWhiteL = meta:get_int("castlingWhiteL") + local idx57 = inv:get_stack(from_list, 57):get_name() + + if castlingWhiteL == 1 and idx57 == "realchess:rook_white_1" then for i = 58, from_index - 1 do if inv:get_stack(from_list, i):get_name() ~= "" then return 0 @@ -459,7 +438,10 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl check = false end elseif to_x == 6 then - if meta:get_int("castlingWhiteR") == 1 and inv:get_stack(from_list, 64):get_name() == "realchess:rook_white_2" then + local castlingWhiteR = meta:get_int("castlingWhiteR") + local idx64 = inv:get_stack(from_list, 64):get_name() + + if castlingWhiteR == 1 and idx64 == "realchess:rook_white_2" then for i = from_index + 1, 63 do if inv:get_stack(from_list, i):get_name() ~= "" then return 0 @@ -474,7 +456,10 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl elseif thisMove == "black" then if from_y == 0 and to_y == 0 then if to_x == 1 then - if meta:get_int("castlingBlackL") == 1 and inv:get_stack(from_list, 1):get_name() == "realchess:rook_black_1" then + local castlingBlackL = meta:get_int("castlingBlackL") + local idx1 = inv:get_stack(from_list, 1):get_name() + + if castlingBlackL == 1 and idx1 == "realchess:rook_black_1" then for i = 2, from_index - 1 do if inv:get_stack(from_list, i):get_name() ~= "" then return 0 @@ -485,7 +470,10 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl check = false end elseif to_x == 6 then - if meta:get_int("castlingBlackR") == 1 and inv:get_stack(from_list, 8):get_name() == "realchess:rook_black_2" then + local castlingBlackR = meta:get_int("castlingBlackR") + local idx8 = inv:get_stack(from_list, 1):get_name() + + if castlingBlackR == 1 and idx8 == "realchess:rook_black_2" then for i = from_index + 1, 7 do if inv:get_stack(from_list, i):get_name() ~= "" then return 0 @@ -500,16 +488,9 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl end if check then - if dx < 0 then - dx = -dx - end - if dy < 0 then - dy = -dy - end - - if dx > 1 or dy > 1 then - return 0 - end + if dx < 0 then dx = -dx end + if dy < 0 then dy = -dy end + if dx > 1 or dy > 1 then return 0 end end if thisMove == "white" then @@ -525,16 +506,17 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, count, pl meta:set_string("playerBlack", playerBlack) meta:set_string("lastMove", thisMove) meta:set_int("lastMoveTime", minetest.get_gametime()) + local lastMove = meta:get_string("lastMove") - if meta:get_string("lastMove") == "black" then + if lastMove == "black" then minetest.chat_send_player(playerWhite, "["..os.date("%H:%M:%S").."] ".. - playerName.." has moved a "..pieceFrom:match(":(.-)%_")..", it's now your turn.") - elseif meta:get_string("lastMove") == "white" then + playerName.." moved a "..pieceFrom:match(":(%a+)")..", it's now your turn.") + elseif lastMove == "white" then minetest.chat_send_player(playerBlack, "["..os.date("%H:%M:%S").."] ".. - playerName.." has moved a "..pieceFrom:match(":(.-)%_")..", it's now your turn.") + playerName.." moved a "..pieceFrom:match(":(%a+)")..", it's now your turn.") end - if pieceTo:find("king") then + if pieceTo:sub(11,14) == "king" then minetest.chat_send_player(playerBlack, playerName.." won the game.") minetest.chat_send_player(playerWhite, playerName.." won the game.") meta:set_string("winner", thisMove) @@ -552,20 +534,20 @@ local function timeout_format(timeout_limit) return minutes.." min. "..seconds.." sec." end -function realchess.fields(pos, formname, fields, sender) +function realchess.fields(pos, _, fields, sender) local playerName = sender:get_player_name() local meta = minetest.get_meta(pos) local timeout_limit = meta:get_int("lastMoveTime") + 300 + local playerWhite = meta:get_string("playerWhite") + local playerBlack = meta:get_string("playerBlack") + local lastMoveTime = meta:get_int("lastMoveTime") if fields.quit then return end -- timeout is 5 min. by default for resetting the game (non-players only) - if fields.new and (meta:get_string("playerWhite") == playerName or - meta:get_string("playerBlack") == playerName) then + if fields.new and (playerWhite == playerName or playerBlack == playerName) then realchess.init(pos) - elseif fields.new and meta:get_int("lastMoveTime") ~= 0 and - minetest.get_gametime() >= timeout_limit and - (meta:get_string("playerWhite") ~= playerName or - meta:get_string("playerBlack") ~= playerName) then + elseif fields.new and lastMoveTime ~= 0 and minetest.get_gametime() >= timeout_limit and + (playerWhite ~= playerName or playerBlack ~= playerName) then realchess.init(pos) else minetest.chat_send_player(playerName, "[!] You can't reset the chessboard, a game has been started.\n".. @@ -577,18 +559,15 @@ function realchess.dig(pos, player) local meta = minetest.get_meta(pos) local playerName = player:get_player_name() local timeout_limit = meta:get_int("lastMoveTime") + 300 + local lastMoveTime = meta:get_int("lastMoveTime") -- timeout is 5 min. by default for digging the chessboard (non-players only) - if meta:get_int("lastMoveTime") ~= 0 and minetest.get_gametime() <= timeout_limit then + return (lastMoveTime == 0 and minetest.get_gametime() > timeout_limit) or minetest.chat_send_player(playerName, "[!] You can't dig the chessboard, a game has been started.\n".. "Reset it first if you're a current player, or dig again in "..timeout_format(timeout_limit)) - return false - end - - return true end -function realchess.on_move(pos, from_list, from_index, to_list, to_index, count, player) +function realchess.on_move(pos, from_list, from_index) local inv = minetest.get_meta(pos):get_inventory() inv:set_stack(from_list, from_index, '') return false