ref: 0cca37a43310c04d62de099d6337d276064848c3
dir: /libmarkus.h/
/* this libmarkus only supports static M_MAX_BOARD_ROW and M_MAX_BOARD_COL */ #ifndef __LIBMARKUS__H #define __LIBMARKUS__H #define M_MAX_BOARD_ROW 6 #define M_MAX_BOARD_COL 6 #define M_EMPTY_CELL ' ' #include <stdint.h> #include <stdbool.h> #include <limits.h> typedef struct { int free_pieces[2]; char player; int direction; int ecode; char winner; uint64_t ad_pieces; uint64_t tag_pieces; } m_game_t; typedef struct { int row; int col; // y = col, x = row } m_point_t; typedef struct { m_point_t src; m_point_t dst; } m_swap_t; enum m_ply_type {M_PLY_TYPE_MOVE, M_PLY_TYPE_PUT, M_PLY_TYPE_SWAP}; typedef struct { enum m_ply_type ply_type; m_swap_t ply_data; } m_ply_t; /* initializes a m_game_t, you should always call this function before any * other function on that m_game_t instance */ void m_init_game(m_game_t* game); /* check if the game is over, return ' ' if it isn't, * and the winner's char (game->winner) if it is, it also * set's game->winner. */ char m_game_state(m_game_t* game); /* these functions are the three main operations of the game, * they also check if the game is over and refuse to do anything to * the game structure if it is(M_ECODE_GAMEOVER). */ int m_put(m_game_t* game, m_point_t* point); int m_move(m_game_t* game, m_point_t* point); int m_swap(m_game_t* game, m_swap_t* swap); /* Parses "string" and passes it to m_swap/m_move/m_put * "string" should be null-terminated. string's format should * be a single command charachter (m|p|s) followed by * its arguments, 'm' and 'p' require only one argument * indicating the square that you wish to move/fill, and * 's' requires two arguments, a source and a destination square. * squares are addressed as ROWCOL without any space in between, * for example '45' represents the 4th row, 5th column. * examples: * "m50" => move the piece in 5th row, 0th column one square forward. * "p00" => put a free piece on the 0th row, 0th column, and decrement free_pieces[player] by 1. * "s2040" => swap the piece on the 2nd row, 0th column with the piece on the 4th row, 0th column*/ int m_play_notation(m_game_t* game, char* string); /* returns a null-terminated string describing game.ecode, every library function * should and does set game.ecode.*/ char* m_error_str(m_game_t* game); enum { M_ECODE_OUTOFRANGE = INT_MIN, M_ECODE_INVALIDINPUT, M_ECODE_DSTNOTEMPTY, M_ECODE_SRCNOTYOURS, M_ECODE_NOTFIRSTROWS, M_ECODE_NOTADJECENT, M_ECODE_SRCORDSTEMPTY, M_ECODE_SRCDSTSAMEPIECE, M_ECODE_SRCDSTSAME, M_ECODE_GAMEOVER, M_ECODE_SUCCESS = 1 }; int m_is_move_legal(m_game_t* game, m_point_t* point); int m_is_swap_legal(m_game_t* game, m_swap_t* swap); int m_is_put_legal(m_game_t* game, m_point_t* point); int m_is_ply_legal(m_game_t* game, m_ply_t* p); //setters and getters int m_set_square(m_game_t*, int row, int col, char); char m_get_square(m_game_t*, int row, int col); char* m_get_board(m_game_t*); // returns a heap-allocated string representing the board. int m_get_free_pieces(m_game_t*, char player); int m_get_turn(m_game_t*); int m_game_is_over(m_game_t*); void m_ply_set_move(m_ply_t* p, int row, int col); void m_ply_set_put(m_ply_t* p, int row, int col); void m_ply_set_swap(m_ply_t*, int row1, int col1, int row2, int col2); m_swap_t m_ply_get_swap(m_ply_t* p); m_point_t m_ply_get_move(m_ply_t* p); m_point_t m_ply_get_put(m_ply_t* p); bool m_tag_wins(m_game_t* game); bool m_ad_wins(m_game_t* game); enum m_ply_type m_ply_get_type(m_ply_t* p); int m_undo_move(m_game_t*, m_point_t*); int m_undo_put(m_game_t*, m_point_t*); int m_undo_swap(m_game_t*, m_swap_t*); int m_do_ply(m_game_t* game, m_ply_t* ply); int m_undo_ply(m_game_t* game, m_ply_t* ply); #endif