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