| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- #include "ttt_multi_game.h"
- struct TttMultiGame {
- TttMultiGameState state;
- TttMultiGameResult result;
- uint8_t board[3][3];
- };
- void ttt_multi_game_move_reset(TttMultiGameMove* move) {
- furi_assert(move);
- // make the move invalid
- move->player = TttMultiGamePlayerNone;
- move->x = 0xff;
- move->y = 0xff;
- }
- void ttt_multi_game_move_copy(TttMultiGameMove* dst, const TttMultiGameMove* src) {
- furi_assert(dst);
- furi_assert(src);
- dst->player = src->player;
- dst->x = src->x;
- dst->y = src->y;
- }
- TttMultiGameMove* ttt_multi_game_move_alloc() {
- TttMultiGameMove* move = malloc(sizeof(TttMultiGameMove));
- ttt_multi_game_move_reset(move);
- return move;
- }
- void ttt_multi_game_move_free(TttMultiGameMove* move) {
- furi_assert(move);
- free(move);
- }
- void ttt_multi_game_reset(TttMultiGame* game) {
- furi_assert(game);
- game->state = TttMultiGameStateTurnX;
- game->result = TttMultiGameResultNone;
- for(uint8_t i = 0; i < 3; i++) {
- for(uint8_t j = 0; j < 3; j++) {
- game->board[i][j] = TttMultiGamePlayerNone;
- }
- }
- }
- TttMultiGameState ttt_multi_game_get_state(TttMultiGame* game) {
- furi_assert(game);
- return game->state;
- }
- TttMultiGameResult ttt_multi_game_get_result(TttMultiGame* game) {
- furi_assert(game);
- if(game->state != TttMultiGameStateFinished) {
- return TttMultiGameResultNone;
- }
- return game->result;
- }
- bool ttt_multi_game_is_draw(TttMultiGame* game) {
- furi_assert(game);
- for(uint8_t i = 0; i < 3; i++) {
- for(uint8_t j = 0; j < 3; j++) {
- if(game->board[i][j] == TttMultiGamePlayerNone) {
- return false;
- }
- }
- }
- return true;
- }
- TttMultiGamePlayer ttt_multi_game_get_winner(TttMultiGame* game) {
- furi_assert(game);
- // Check rows
- for(uint8_t i = 0; i < 3; i++) {
- if(game->board[i][0] != TttMultiGamePlayerNone && game->board[i][0] == game->board[i][1] &&
- game->board[i][1] == game->board[i][2]) {
- return (TttMultiGamePlayer)game->board[i][0];
- }
- }
- // Check columns
- for(uint8_t i = 0; i < 3; i++) {
- if(game->board[0][i] != TttMultiGamePlayerNone && game->board[0][i] == game->board[1][i] &&
- game->board[1][i] == game->board[2][i]) {
- return (TttMultiGamePlayer)game->board[0][i];
- }
- }
- // Check diagonals
- if(game->board[0][0] == game->board[1][1] && game->board[1][1] == game->board[2][2]) {
- return (TttMultiGamePlayer)game->board[0][0];
- }
- if(game->board[0][2] == game->board[1][1] && game->board[1][1] == game->board[2][0]) {
- return (TttMultiGamePlayer)game->board[0][2];
- }
- return TttMultiGamePlayerNone;
- }
- static void ttt_multi_game_update_result(TttMultiGame* game) {
- furi_assert(game);
- if(game->state == TttMultiGameStateFinished) {
- return;
- }
- TttMultiGamePlayer winner = ttt_multi_game_get_winner(game);
- if(winner != TttMultiGamePlayerNone) {
- game->state = TttMultiGameStateFinished;
- if(winner == TttMultiGamePlayerX) {
- game->result = TttMultiGameResultXWin;
- } else if(winner == TttMultiGamePlayerO) {
- game->result = TttMultiGameResultOWin;
- }
- return;
- }
- if(ttt_multi_game_is_draw(game)) {
- game->result = TttMultiGameResultDraw;
- game->state = TttMultiGameStateFinished;
- }
- }
- bool ttt_multi_game_is_move_valid(TttMultiGame* game, TttMultiGameMove* move) {
- furi_assert(game);
- furi_assert(move);
- if(move->x > 2 || move->y > 2) {
- return false;
- }
- if(move->player != ttt_multi_game_current_player(game)) {
- return false;
- }
- if(game->board[move->x][move->y] != TttMultiGamePlayerNone) {
- return false;
- }
- return true;
- }
- TttMultiGamePlayer ttt_multi_game_current_player(TttMultiGame* game) {
- furi_assert(game);
- if(game->state == TttMultiGameStateTurnX) {
- return TttMultiGamePlayerX;
- } else if(game->state == TttMultiGameStateTurnO) {
- return TttMultiGamePlayerO;
- }
- return TttMultiGamePlayerNone;
- }
- void ttt_multi_game_swap_player(TttMultiGame* game) {
- furi_assert(game);
- if(game->state == TttMultiGameStateTurnX) {
- game->state = TttMultiGameStateTurnO;
- } else if(game->state == TttMultiGameStateTurnO) {
- game->state = TttMultiGameStateTurnX;
- }
- }
- void ttt_multi_game_make_move(TttMultiGame* game, TttMultiGameMove* move) {
- furi_assert(game);
- furi_assert(move);
- furi_assert(ttt_multi_game_is_move_valid(game, move));
- game->board[move->x][move->y] = (uint8_t)move->player;
- ttt_multi_game_swap_player(game);
- ttt_multi_game_update_result(game);
- }
- TttMultiGamePlayer ttt_multi_game_player_at(TttMultiGame* game, uint8_t x, uint8_t y) {
- furi_assert(game);
- furi_assert(x < 3);
- furi_assert(y < 3);
- return (TttMultiGamePlayer)game->board[x][y];
- }
- TttMultiGame* ttt_multi_game_alloc() {
- TttMultiGame* game = malloc(sizeof(TttMultiGame));
- ttt_multi_game_reset(game);
- return game;
- }
- void ttt_multi_game_free(TttMultiGame* game) {
- furi_assert(game);
- free(game);
- }
|