include "board" include "classes.die" include "states.game.loading" include "states.game.rolling" include "states.game.placing" include "states.game.scoring" include "states.game.gameover" include "utils.event_bus" function state_game() local game = {} local event_bus = EventBus:new() --- @type "player"|"enemy" local turn = "player" --- @type "waiting"|"rolling"|"placing" local step = "rolling" --- @type Die|nil local die local function reset_die() die = Die:new({ box = get_dice_box(turn), bouncing = false }) end -- -- #region State management -- --- Sub-states --- @type StateManager local state_manager = StateManager:new() local states = { loading = state_game_loading(), rolling = state_game_rolling(), placing = state_game_placing(), scoring = state_game_scoring(), game_over = state_game_gameover(), } event_bus:on(EVENT_SET_STEP, function(new_step) trace("[Event] set_step: " .. step .. " -> " .. new_step) assert(states[new_step], "state " .. new_step .. " does not exist") state_manager:change_state(states[new_step], die, event_bus, turn) step = new_step end) event_bus:on(EVENT_CHANGE_TURN, function() turn = turn == "player" and "enemy" or "player" reset_die() state_manager:change_state(states.rolling, die, event_bus) step = "rolling" end) event_bus:on(EVENT_REMOVE_DIE, function() die = nil end) event_bus:on(EVENT_RESET_DIE, function() reset_die() end) -- -- #endregion State management -- game._enter = function(self, data) assert(data.covering, "needs data.covering") trace("entering game state") turn = math.random(1, 2) == 1 and "player" or "enemy" state_manager:change_state(states.loading, { turn = turn, event_bus = event_bus, covering = data.covering }) end game.update = function() cls() if die then die:update() end draw_board() print_scores() print_names() draw_dice_boxes() state_manager:update() if die and die.value then die:draw() end -- prn_border("Turn: " .. turn, 1, 1, 2) -- prn_border("Step: " .. step, 1, 10, 2) reset_colors() end game._leave = function() end return game end