feat: implement sessions, lobby, roles, and rematch lifecycle
This commit is contained in:
@@ -3,9 +3,10 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "command_queue.h"
|
||||
#include "game_lifecycle.h"
|
||||
|
||||
/* The application task is the sole owner of game_state_t mutations. */
|
||||
typedef struct { command_queue_t command_queue; game_state_t state; } application_t;
|
||||
/* The application task is the sole owner of lifecycle and game mutations. */
|
||||
typedef struct { command_queue_t command_queue; game_lifecycle_t lifecycle; } application_t;
|
||||
|
||||
bool application_enqueue(application_t *application, const app_command_t *command);
|
||||
bool application_take_next_command(application_t *application, app_command_t *command);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "fleet_generator.h"
|
||||
#include "game_engine.h"
|
||||
#include "session_manager.h"
|
||||
#include "statistics.h"
|
||||
|
||||
typedef uint8_t lifecycle_result_t;
|
||||
enum {
|
||||
LIFECYCLE_RESULT_OK,
|
||||
LIFECYCLE_RESULT_INVALID_NAME,
|
||||
LIFECYCLE_RESULT_INVALID_ROLE,
|
||||
LIFECYCLE_RESULT_INVALID_MODE,
|
||||
LIFECYCLE_RESULT_UNAUTHORIZED,
|
||||
LIFECYCLE_RESULT_NO_PLAYER_SLOT,
|
||||
LIFECYCLE_RESULT_NO_SPECTATOR_SLOT,
|
||||
LIFECYCLE_RESULT_FORBIDDEN_ROLE,
|
||||
LIFECYCLE_RESULT_WRONG_PHASE,
|
||||
LIFECYCLE_RESULT_NOT_YOUR_TURN,
|
||||
LIFECYCLE_RESULT_CELL_ALREADY_SHOT,
|
||||
LIFECYCLE_RESULT_INVALID_COORDINATE,
|
||||
LIFECYCLE_RESULT_STALE_GAME,
|
||||
LIFECYCLE_RESULT_GENERATION_FAILED,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
game_engine_t game;
|
||||
session_manager_t sessions;
|
||||
cumulative_statistics_t cumulative[kPlayerCapacity];
|
||||
random_source_t random;
|
||||
bool bot_reserved;
|
||||
bool rematch_confirmed[kPlayerCapacity];
|
||||
uint32_t next_game_id;
|
||||
} game_lifecycle_t;
|
||||
|
||||
void game_lifecycle_init(game_lifecycle_t *lifecycle, random_source_t random);
|
||||
lifecycle_result_t game_lifecycle_join(game_lifecycle_t *lifecycle, role_t requested_role, const char *name,
|
||||
uint8_t *session_index);
|
||||
lifecycle_result_t game_lifecycle_resume(game_lifecycle_t *lifecycle,
|
||||
const uint8_t token[kSessionTokenBytes], uint8_t *session_index);
|
||||
lifecycle_result_t game_lifecycle_disconnect(game_lifecycle_t *lifecycle, uint8_t session_index);
|
||||
lifecycle_result_t game_lifecycle_leave(game_lifecycle_t *lifecycle, uint8_t session_index);
|
||||
lifecycle_result_t game_lifecycle_configure(game_lifecycle_t *lifecycle, uint8_t session_index,
|
||||
uint32_t game_id, game_mode_t mode);
|
||||
lifecycle_result_t game_lifecycle_start(game_lifecycle_t *lifecycle, uint8_t session_index, uint32_t game_id);
|
||||
lifecycle_result_t game_lifecycle_shot(game_lifecycle_t *lifecycle, uint8_t session_index, uint32_t game_id,
|
||||
coordinate_t coordinate, shot_result_t *result);
|
||||
lifecycle_result_t game_lifecycle_rematch(game_lifecycle_t *lifecycle, uint8_t session_index, uint32_t game_id);
|
||||
lifecycle_result_t game_lifecycle_abort(game_lifecycle_t *lifecycle, uint8_t session_index, uint32_t game_id);
|
||||
|
||||
_Static_assert(sizeof(game_lifecycle_t) <= 1600, "lifecycle state grew beyond fixed budget");
|
||||
@@ -1,7 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_interfaces.h"
|
||||
#include "app_config.h"
|
||||
#include "game_types.h"
|
||||
|
||||
typedef struct { role_t role; bool occupied; uint8_t token[kSessionTokenBytes]; char name[kDisplayNameBytes + 1]; } session_t;
|
||||
typedef uint8_t session_result_t;
|
||||
enum {
|
||||
SESSION_RESULT_OK,
|
||||
SESSION_RESULT_INVALID_NAME,
|
||||
SESSION_RESULT_INVALID_ROLE,
|
||||
SESSION_RESULT_NO_PLAYER_SLOT,
|
||||
SESSION_RESULT_NO_SPECTATOR_SLOT,
|
||||
SESSION_RESULT_UNAUTHORIZED,
|
||||
SESSION_RESULT_WRONG_PHASE,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
role_t role;
|
||||
bool occupied;
|
||||
bool connected;
|
||||
uint8_t token[kSessionTokenBytes];
|
||||
char name[kDisplayNameBytes + 1];
|
||||
} session_t;
|
||||
typedef struct { session_t entries[kSessionCapacity]; } session_manager_t;
|
||||
|
||||
void session_manager_init(session_manager_t *manager);
|
||||
session_result_t session_manager_join(session_manager_t *manager, role_t requested_role, const char *name,
|
||||
random_source_t random, uint8_t *session_index);
|
||||
session_result_t session_manager_resume(session_manager_t *manager, const uint8_t token[kSessionTokenBytes],
|
||||
uint8_t *session_index);
|
||||
bool session_manager_disconnect(session_manager_t *manager, uint8_t session_index);
|
||||
session_result_t session_manager_leave(session_manager_t *manager, uint8_t session_index, phase_t phase);
|
||||
bool session_manager_player_present(const session_manager_t *manager, uint8_t player_index);
|
||||
|
||||
_Static_assert(sizeof(session_t) <= 104, "session grew beyond fixed budget");
|
||||
_Static_assert(sizeof(session_manager_t) <= 1040, "session table grew beyond fixed budget");
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct { uint16_t shots; uint16_t hits; uint16_t misses; uint8_t ships_sunk; } match_statistics_t;
|
||||
#include "game_types.h"
|
||||
|
||||
typedef struct { uint16_t games; uint16_t wins; uint16_t losses; uint32_t shots; uint32_t hits; } cumulative_statistics_t;
|
||||
|
||||
Reference in New Issue
Block a user