#ifndef GAME_H #define GAME_H #include #include #include #include "wall.h" #include "client.h" #include "../common/action.h" #include "../common/state.h" #include "../common/cyclicint.h" class Game : public boost::enable_shared_from_this { public: typedef boost::shared_ptr p; static p create(ClientBase::p player_1, ClientBase::p player_2, ClientBase::p player_3, ClientBase::p player_4); ~Game(); private: typedef CyclicInt<4> PlayerNum; class Player { public: ClientBase::p client; Tiles hand; Tilegroups open; Tiles pond; bool riichi; int score; int wind; //! Prepare for a new round. void round_start(int w); //! Get a state snapshot. PlayerState get_state(); //! Get a state snapshot, with concealed tiles filtered. PlayerState get_state_filtered(); //! Get possible actions after a draw. Actions get_actions_draw(); //! Get possible actions on discarded tile. Actions get_actions_discard(Tile tile, PlayerNum discarder); typedef std::vector Targets; //! Check if player can declare riichi. bool can_riichi(); //! Check if tile can be called for a chi. Targets can_chi(Tile tile); //! Check if tile can be called for a pon. int can_pon(Tile tile); //! Check if it's possible to make a concealed kan or extend an open kan. Targets can_kan(); //! Check if tile can be called to kan target. bool can_kan(Tile tile, int target); //! Check if hand is complete. bool can_tsumo(); //! Check if tile can be called to complete hand. bool can_ron(Tile tile); //! Draw tile. void draw(Tile tile); //! Discard tile. void discard(int target); //! Look at last discard in pond. Tile last_discard(); //! Claim last discard from pond. Tile claim(); //! Make chi from tile. void make_chi(Tile tile, int target); //! Make pon from tile. void make_pon(Tile tile, int target, PlayerNum discarder); //! Make open kan from tile. void make_kan(Tile tile, int target, PlayerNum discarder); }; Player players[4]; Wall wall; Tiles dora; bool kan_dora_pending; PlayerNum current_player; PlayerNum round_wind; PlayerNum round_num; int awaiting_players; Action preceding_action; int preceding_action_owner; Game(ClientBase::p player_1, ClientBase::p player_2, ClientBase::p player_3, ClientBase::p player_4); //! Handle Ready message from player. void handle_ready(); //! Start the game. void start(); //! Start a new round. void round_start(); //! Send update after a tile is drawn. void round_update_draw(); //! Send update after a tile is discarded. void round_update_discard(); //! Handle action after draw. void handle_action_draw(Action action); //! Handle actions after discard. void handle_action_discard(Action action, int player); //! End the game. void round_end(); }; #endif