knucklebones/states/game/scoring.lua
2023-08-12 11:36:14 +02:00

94 lines
2.8 KiB
Lua

function state_game_scoring()
local dice_to_destroy = {}
--- @type EventBus
local event_bus
local destroyed = 0
local function update_board_and_score(player, col, row)
assert(player)
assert(col)
assert(row)
-- Create a Die and place it on the cell
local cell = get_cell_coords(player, col, row)
local die = Die:new({ value = PLACED_DICE:get(player, col, row), x = cell.x + 3, y = cell.y + 1 })
-- Set the score to 0
PLACED_DICE:set(player, col, row, 0)
table.insert(dice_to_destroy, die)
addcoroutine(function()
waitframes(10)
local tween = Tween.new(0.5, die, { scale = 0.1 }, "inOutQuad")
repeat
coroutine.yield()
until tween:update(dt)
table.remove_item(dice_to_destroy, die)
end)
end
---comment
---@param self any
---@param _die Die|nil
---@param _event_bus EventBus
---@param player 'player'|'enemy'
local function _enter(self, _die, _event_bus, player)
assert(_event_bus)
assert(player == "player" or player == "enemy")
event_bus = _event_bus
destroyed = 0
local other_player = player == "player" and "enemy" or "player"
-- Check if the newly placed die must remove other dice
local current_dice = PLACED_DICE[player]
local other_dice = PLACED_DICE[other_player]
-- Check the dice for each column, and remove corresponding dice in the opposing column
for col = 1, 3 do
for row = 1, 3 do
local value = current_dice[col][row]
for row2 = 1, 3 do
local value2 = other_dice[col][row2]
if value > 0 and value2 > 0 and value2 == value then
trace("destroy " .. other_player .. " " .. col .. " " .. row2 .. " = " .. value2)
update_board_and_score(other_player, col, row2)
destroyed = destroyed + 1
end
end
end
end
-- Update the scores and move on to next state
addcoroutine(function()
waitsecs((destroyed > 0) and 0.6 or 0.3)
SCORES:update()
-- Check if it's game over
if PLACED_DICE:is_game_over() then
SCORES:update()
event_bus:emit(EVENT_SET_STEP, "game_over")
else
event_bus:emit(EVENT_CHANGE_TURN)
end
end)
end
local function update(self)
for _, die in ipairs(dice_to_destroy) do
die:draw()
end
end
local function _leave(self)
end
return {
_enter = _enter,
update = update,
_leave = _leave
}
end