Escape Simulator

Escape Simulator

Design your own escape rooms!
Try community-built escape rooms (more than 3000 of them), or try your hand at designing your own! Create new puzzles, riddles, or whatever comes to your mind!
Learn More
I'm trying to make an interactive Chessboard with lua script, run into issue need help
I'm trying to make an interactive chessboard in lua script for EscapeSimulator.
it seems to correctly start the first move with white and check the location after white has changed something on the board. however if I try this manually with black it will not register a change on the board.

anyone with knowledge of lua and EscapeSimulator who can help me with my script:

-- Define the chessboard with positions directly from triggers
board_positions = {}

local columns = {"A", "B", "C", "D", "E", "F", "G", "H"}
local rows = {1, 2, 3, 4, 5, 6, 7, 8}

-- Fill board_positions by referencing the transform locations of triggers
for _, col in ipairs(columns) do
for _, row in ipairs(rows) do
local tile = col .. row
local tile_object = _G[tile] -- Access global variable by name
if tile_object and tile_object.transform then
board_positions[tile] = tile_object.transform.position
else
api.levelNote("Error: Could not find trigger for tile " .. tile)
end
end
end

-- Initialize chess pieces
chess_pieces = {}

function initialize_piece(piece_name, piece_type, piece_color, start_tile)
local piece = _G[piece_name]
local start_position = board_positions[start_tile]

if not piece then
api.levelNote("Error: Could not find object for " .. piece_name)
return
end

if not start_position then
api.levelNote("Error: Could not find starting position for " .. start_tile)
return
end

piece.transform.position = start_position
chess_pieces[piece_name] = { type = piece_type, color = piece_color, position = start_tile }

api.levelNote(piece_name .. " initialized at " .. start_tile)
end

-- Initialization for white and black pieces
function initialize_game()
-- White pieces
initialize_piece("WhiteKing", "King", "White", "E1")
initialize_piece("WhiteQueen", "Queen", "White", "D1")
initialize_piece("WhiteRookLeft", "Rook", "White", "A1")
initialize_piece("WhiteRookRight", "Rook", "White", "H1")
initialize_piece("WhiteBishopLeft", "Bishop", "White", "C1")
initialize_piece("WhiteBishopRight", "Bishop", "White", "F1")
initialize_piece("WhiteKnightLeft", "Knight", "White", "B1")
initialize_piece("WhiteKnightRight", "Knight", "White", "G1")

for i = 1, 8 do
initialize_piece("WhitePawn" .. i, "Pawn", "White", columns .. "2")
end

-- Black pieces
initialize_piece("BlackKing", "King", "Black", "E8")
initialize_piece("BlackQueen", "Queen", "Black", "D8")
initialize_piece("BlackRookLeft", "Rook", "Black", "A8")
initialize_piece("BlackRookRight", "Rook", "Black", "H8")
initialize_piece("BlackBishopLeft", "Bishop", "Black", "C8")
initialize_piece("BlackBishopRight", "Bishop", "Black", "F8")
initialize_piece("BlackKnightLeft", "Knight", "Black", "B8")
initialize_piece("BlackKnightRight", "Knight", "Black", "G8")

for i = 1, 8 do
initialize_piece("BlackPawn" .. i, "Pawn", "Black", columns .. "7")
end
end

-- Function to remove a piece from the board
function remove_piece_at(tile)
for piece_name, piece_data in pairs(chess_pieces) do
if piece_data.position == tile then
api.levelNote(piece_name .. " captured at " .. tile)
local piece_object = _G[piece_name]
if piece_object then
piece_object.transform.position = Vector3.zero -- Move captured piece off the board
end
chess_pieces[piece_name] = nil -- Remove from chess_pieces
return
end
end
end

-- Function to validate moves
function is_valid_move(piece_name, target_tile)
local piece_data = chess_pieces[piece_name]
if not piece_data then
api.levelNote("Error: Piece " .. piece_name .. " not found.")
return false
end

local piece_type = piece_data.type
local current_tile = piece_data.position

-- Validate pawn moves as an example (extend for other pieces)
if piece_type == "Pawn" then
local current_row = tonumber(current_tile:sub(2, 2))
local target_row = tonumber(target_tile:sub(2, 2))
local current_col = current_tile:sub(1, 1)
local target_col = target_tile:sub(1, 1)

if piece_data.color == "White" then
if current_col == target_col and (target_row == current_row + 1 or (current_row == 2 and target_row == current_row + 2)) then
return true
end
elseif piece_data.color == "Black" then
if current_col == target_col and (target_row == current_row - 1 or (current_row == 7 and target_row == current_row - 2)) then
return true
end
end
end

-- Add validation for other pieces here
return false
end

-- Function to move a piece
function move_piece(piece_name, target_tile)
local piece_data = chess_pieces[piece_name]
local target_position = board_positions[target_tile]

if not piece_data then
api.levelNote("Error: Piece " .. piece_name .. " not found in chess_pieces.")
return false
end

if not target_position then
api.levelNote("Error: Target tile " .. target_tile .. " is not valid.")
return false
end

-- Validate move
if not is_valid_move(piece_name, target_tile) then
api.levelNote("Invalid move for " .. piece_name .. ". Returning to original position.")
return false
end

-- Remove opponent's piece if present
remove_piece_at(target_tile)

-- Move the piece
local piece_object = _G[piece_name]
piece_object.transform.position = target_position
piece_data.position = target_tile

api.levelNote(piece_name .. " moved to " .. target_tile)

-- Check for board state changes and log them
check_for_changes()

return true
end

-- White's automatic response
function white_response()
-- Example response move: WhitePawn4 to D4
local piece_name = "WhitePawn4"
local target_tile = "D4" -- Update logic to dynamically calculate moves
api.levelNote("White responds: " .. piece_name .. " to " .. target_tile) -- Debug log
move_piece(piece_name, target_tile)
end

-- Function to get player input for Black's move
function get_player_move()
local piece_name, target_tile = api.get_user_input("Enter piece name (e.g. BlackKnightLeft): ", "Enter target tile (e.g. F6): ")
api.levelNote("Player's input: " .. piece_name .. " to " .. target_tile) -- Debugging log
return piece_name, target_tile
end

-- Function to validate player (Black) move
function is_valid_player_move(piece_name, target_tile)
local piece_data = chess_pieces[piece_name]
if not piece_data then
api.levelNote("Error: Piece " .. piece_name .. " not found.")
return false
end

-- Check if it's the correct color (Black)
if piece_data.color ~= "Black" then
api.levelNote("Error: It's not Black's turn.")
return false
end

-- Validate move for the specific piece
if not is_valid_move(piece_name, target_tile) then
api.levelNote("Invalid move for " .. piece_name .. ".")
return false
end

return true
end

-- Function for Black's turn (with validation)
function black_turn()
local piece_name, target_tile = get_player_move() -- Get the player's input for Black's move
api.levelNote("Black's move attempt: " .. piece_name .. " to " .. target_tile) -- Debugging log

-- Validate the move before proceeding
if is_valid_player_move(piece_name, target_tile) then
-- Move the piece
local success = move_piece(piece_name, target_tile)
if success then
api.levelNote("Player moved " .. piece_name .. " to " .. target_tile)
else
api.levelNote("Invalid move. Please try again.")
black_turn() -- Recursively call black_turn until a valid move is made
end
else
api.levelNote("Invalid move. Please try again.")
black_turn() -- Recursively call black_turn to allow retry
end
end

-- Initialize previous board state to an empty table
local previous_board_state = {}

-- Function to log the current board state
function log_board_state()
api.levelNote("Board state has changed:")
for piece_name, piece_data in pairs(chess_pieces) do
api.levelNote(piece_name .. " is at " .. piece_data.position)
end
end

-- Function to check if the board has changed
function check_for_changes()
local has_changed = false

-- Ensure previous_board_state exists before comparing
if not previous_board_state then
previous_board_state = {}
return false
end

-- Compare current board state to the previous state
for piece_name, piece_data in pairs(chess_pieces) do
-- Log each piece's position for debugging
api.levelNote("Checking " .. piece_name .. " at " .. piece_data.position)

-- Initialize previous piece state if it doesn't exist
if not previous_board_state[piece_name] then
previous_board_state[piece_name] = { position = piece_data.position }
has_changed = true
elseif previous_board_state[piece_name].position ~= piece_data.position then
has_changed = true
break
end
end

-- If the board has changed, log it and update the previous state
if has_changed then
log_board_state()
-- Update previous state
previous_board_state = {}
for piece_name, piece_data in pairs(chess_pieces) do
previous_board_state[piece_name] = { position = piece_data.position }
end
end
end

-- Main game loop (with adjustments)
if callType == LuaCallType.Init then
api.levelNote("Game initialized. White starts.")
initialize_game()
white_response() -- White makes the first move

-- Loop for player turns (Black and White)
while game_state_is_ongoing do
api.levelNote("Waiting for Black's turn...") -- Debugging log
black_turn() -- Wait for player (Black) to move
api.levelNote("White is responding...") -- Debugging log
white_response() -- White responds after Black's move
end
end
< >
Showing 1-1 of 1 comments
Thoroniul 8 17 Dec, 2024 @ 7:45am 
I would avoid using a while loop as the code already cycles, and this just unnecessarily locks it. Instead use something like callType == LuaCallType.Update. Or use the event of the person clicking the piece to change the state.
< >
Showing 1-1 of 1 comments
Per page: 1530 50