diff options
-rw-r--r-- | .gitmodules | 3 | ||||
m--------- | common | 0 | ||||
-rw-r--r-- | common/action.cpp | 14 | ||||
-rw-r--r-- | common/action.h | 55 | ||||
-rw-r--r-- | common/config.cpp | 84 | ||||
-rw-r--r-- | common/config.h | 48 | ||||
-rw-r--r-- | common/connectionbase.cpp | 229 | ||||
-rw-r--r-- | common/connectionbase.h | 49 | ||||
-rw-r--r-- | common/cyclicint.h | 84 | ||||
-rw-r--r-- | common/list.h | 51 | ||||
-rw-r--r-- | common/message.h | 286 | ||||
-rw-r--r-- | common/set.h | 24 | ||||
-rw-r--r-- | common/state.h | 64 | ||||
-rw-r--r-- | common/tile.cpp | 62 | ||||
-rw-r--r-- | common/tile.h | 105 |
15 files changed, 3 insertions, 1155 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b0045a7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "common"] + path = common + url = git://git.jvnv.net/aotenjou_common diff --git a/common b/common new file mode 160000 +Subproject dd64a35c949738c2c321989d065e0754556823d diff --git a/common/action.cpp b/common/action.cpp deleted file mode 100644 index 527d25e..0000000 --- a/common/action.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "action.h" -#include <algorithm> - -Action::Action() : target_type(None), target_offset(0) { - -} - -Action::Action(Type ty, TargetType tt, int to) : type(ty), target_type(tt), target_offset(to) { - -} - -bool Action::operator==(const Action& other) { - return type == other.type && target_type == other.target_type && target_offset == other.target_offset; -} diff --git a/common/action.h b/common/action.h deleted file mode 100644 index e229d2c..0000000 --- a/common/action.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef ACTION_H -#define ACTION_H - -#include "list.h" - -class Action { - public: - //! Action types. - enum Type { - Pass, // discard - Discard, // draw - Riichi, // draw - Chi, // discard - Pon, // discard - Kan, // draw, discard - Ron, // discard - Tsumo, // draw - Draw // draw - }; - - //! Action target type. - enum TargetType { - //! Action is targetless. - None, - //! Target is index in first group (concealed hand). - Index, - //! Target is index of group. - Group - }; - - //! Type of action. - Type type; - - //! Target of action (if applicable). - TargetType target_type; - int target_offset; - - Action(); - Action(Type ty, TargetType tt = None, int to = 0); - - //! Compare to another action. - bool operator==(const Action& other); - - template<class Archive> - void serialize(Archive & ar, const unsigned int version) { - ar & type; - ar & target_type; - ar & target_offset; - } -}; - -//! List of actions. -typedef List<Action> Actions; - -#endif diff --git a/common/config.cpp b/common/config.cpp deleted file mode 100644 index f106304..0000000 --- a/common/config.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "config.h" - -#include <fstream> -#include <iostream> -#include <sstream> - -Config::Config() { - path = "aotenjou.conf"; - load_conf(); -} - -Config::Config(std::string path) { - path = path; - load_conf(); -} - -Config::~Config() { - save_conf(); -} - -/* - Adds a config-element to the list - */ -void Config::add_element(std::string keyword, std::string value) { - config[keyword] = value; -} - -void Config::add_element(std::string keyword, int value) { - std::stringstream out; - out << value; - config[keyword] = out.str(); -} - -/* -Load a value from the config. - */ -std::string Config::get_element(std::string keyword) { - return config[keyword]; -} - -/* - Initializes and loads the config from disk if it exists - */ -void Config::load_conf(){ - - std::ifstream config_file(path.c_str()); - - if(config_file.is_open()) { - while(config_file.good()) { - std::string config_line; - std::getline(config_file, config_line); - std::string id = config_line.substr(0, config_line.find("=") - 1); - //Skip empty lines - if (id != "") { - std::string value = config_line.substr(config_line.find("=") + 2, config_line.length()-1); - config[id] = value; - } - } - - config_file.close(); - - } else { - std::cerr << "Unable to open configuration file..." << std::endl; - } -} - -/* - Saves the current config to disk - */ -void Config::save_conf(){ - - std::ofstream config_file(path.c_str(), std::ios::out | std::ios::trunc); - - if(config_file.is_open()) { - for(std::map<std::string, std::string>::iterator it = config.begin(); it != config.end(); ++it) { - config_file << it->first << " = " << it->second << std::endl; - } - - config_file.close(); - } else { - std::cerr << "Unable to save to configuration file..." << std::endl; - } -} - diff --git a/common/config.h b/common/config.h deleted file mode 100644 index 87e9765..0000000 --- a/common/config.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H - -#include <string> -#include <map> - -//! Utility class for handling configuration file -//! Supported format in config file is: -//! keyword = value -//! example: nick = xyz -class Config{ - private: - //! Map in the format <id, value> - std::map<std::string, std::string> config; - - //! The path to the configuration file - std::string path; - - //! Loads configuration from file - void load_conf(); - - //! Saves configuration to file - void save_conf(); - - public: - //! Constructs a object with the default configuration path - Config(); - //! Constructs a object with a custom configuration path - Config(std::string path); - //! Deletes the object, saving the configuration to a file - ~Config(); - - //! Adds a std::string value to the configuration - //! \param keyword Keyword associated with the value inserted - //! \param value The value for the associated keyword - void add_element(std::string keyword, std::string value); - - //! Adds a int value to the configuration - //! \param keyword Keyword associated with the value inserted - //! \param value The value for the associated keyword - void add_element(std::string keyword, const int value); - - //! Gets a element from the configuration - //! \param keyword The keyword you want the value from - std::string get_element(std::string keyword); -}; - -#endif diff --git a/common/connectionbase.cpp b/common/connectionbase.cpp deleted file mode 100644 index a0c5ab8..0000000 --- a/common/connectionbase.cpp +++ /dev/null @@ -1,229 +0,0 @@ -#include "connectionbase.h" - -#include <boost/serialization/vector.hpp> -#include <boost/serialization/string.hpp> -#include <boost/serialization/utility.hpp> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/archive/binary_oarchive.hpp> -#include <boost/archive/binary_iarchive.hpp> - -#include <cstring> -#include <sstream> -#include <exception> -#include <stdexcept> - -#include <iostream> - -void ConnectionBase::start_recv() { - request_data(4); -} - -void ConnectionBase::got_data(uint8_t* data, std::size_t bytes) { - if(pending_size == 0) { - if(bytes != 4) { - error("Deserialization header error."); - } - - uint16_t* header = (uint16_t*)data; - - pending_type = (Message::Type)header[0]; - pending_size = (std::size_t)header[1]; - - if(pending_size) { - request_data(pending_size); - return; - } - - bytes = 0; - } - - if(bytes != pending_size) { - std::cout << "Bytes: " << bytes << " Pending size: " << pending_size << std::endl; - error("Deserialization attempted with incomplete data."); - // TODO: Calling got_data() with incomplete data should be allowed. - } - - pending_size = 0; - - try { - // Create Boost.Serialization archive of data. - std::istringstream is(std::string((char*)data, bytes)); - boost::archive::binary_iarchive ia(is); - - switch(pending_type) { - case Message::Types::Hello: { - Message::Hello::p m = make_shared<Message::Hello>(); - ia & m; - got_message(m); - } break; - - case Message::Types::Login: { - Message::Login::p m = make_shared<Message::Login>(); - ia & m; - got_message(m); - } break; - - case Message::Types::LoginResponse: { - Message::LoginResponse::p m = make_shared<Message::LoginResponse>(); - ia & m; - got_message(m); - } break; - - case Message::Types::LobbyStatus: { - Message::LobbyStatus::p m = make_shared<Message::LobbyStatus>(); - ia & m; - got_message(m); - } break; - - case Message::Types::LobbyAction: { - Message::LobbyAction::p m = make_shared<Message::LobbyAction>(); - ia & m; - got_message(m); - } break; - - case Message::Types::GameStart: { - Message::GameStart::p m = make_shared<Message::GameStart>(); - ia & m; - got_message(m); - } break; - - case Message::Types::Ready: { - Message::Ready::p m = make_shared<Message::Ready>(); - ia & m; - got_message(m); - } break; - - case Message::Types::RoundStart: { - Message::RoundStart::p m = make_shared<Message::RoundStart>(); - ia & m; - got_message(m); - } break; - - case Message::Types::RoundState: { - Message::RoundState::p m = make_shared<Message::RoundState>(); - ia & m; - got_message(m); - } break; - - case Message::Types::RoundAction: { - Message::RoundAction::p m = make_shared<Message::RoundAction>(); - ia & m; - got_message(m); - } break; - - case Message::Types::RoundEnd: { - Message::RoundEnd::p m = make_shared<Message::RoundEnd>(); - ia & m; - got_message(m); - } break; - - case Message::Types::GameEnd: { - Message::GameEnd::p m = make_shared<Message::GameEnd>(); - ia & m; - got_message(m); - } break; - - default: - throw std::runtime_error("Deserialization attempted on unknown message type."); - } - - } catch(std::exception& e) { - error(std::string("Deserialization failed: ") + e.what()); - } -} - -void ConnectionBase::send(const Message::p& msg) { - // Create Boost.Serialization archive. - std::ostringstream os; - boost::archive::binary_oarchive oa(os); - - switch(msg->type) { - case Message::Types::Hello: { - Message::Hello::p m = dynamic_pointer_cast<Message::Hello>(msg); - oa & m; - } break; - - case Message::Types::Login: { - Message::Login::p m = dynamic_pointer_cast<Message::Login>(msg); - oa & m; - } break; - - case Message::Types::LoginResponse: { - Message::LoginResponse::p m = dynamic_pointer_cast<Message::LoginResponse>(msg); - oa & m; - } break; - - case Message::Types::LobbyStatus: { - Message::LobbyStatus::p m = dynamic_pointer_cast<Message::LobbyStatus>(msg); - oa & m; - } break; - - case Message::Types::LobbyAction: { - Message::LobbyAction::p m = dynamic_pointer_cast<Message::LobbyAction>(msg); - oa & m; - } break; - - case Message::Types::GameStart: { - Message::GameStart::p m = dynamic_pointer_cast<Message::GameStart>(msg); - oa & m; - } break; - - case Message::Types::Ready: { - Message::Ready::p m = dynamic_pointer_cast<Message::Ready>(msg); - oa & m; - } break; - - case Message::Types::RoundStart: { - Message::RoundStart::p m = dynamic_pointer_cast<Message::RoundStart>(msg); - oa & m; - } break; - - case Message::Types::RoundState: { - Message::RoundState::p m = dynamic_pointer_cast<Message::RoundState>(msg); - oa & m; - } break; - - case Message::Types::RoundAction: { - Message::RoundAction::p m = dynamic_pointer_cast<Message::RoundAction>(msg); - oa & m; - } break; - - case Message::Types::RoundEnd: { - Message::RoundEnd::p m = dynamic_pointer_cast<Message::RoundEnd>(msg); - oa & m; - } break; - - case Message::Types::GameEnd: { - Message::GameEnd::p m = dynamic_pointer_cast<Message::GameEnd>(msg); - oa & m; - } break; - - default: - throw std::runtime_error("Serialization attempted on unknown message type."); - } - - // Extract data. - std::string s = os.str(); - - // Allocate buffer. - uint8_t* buf = new uint8_t[4 + s.size()]; - - // Write header. - uint16_t* header = (uint16_t*)buf; - header[0] = uint16_t(msg->type); - header[1] = uint16_t(s.size()); - - // Copy data. - memcpy(buf + 4, s.c_str(), s.size()); - - // Send buffer. - write_data(buf, 4 + s.size()); -} - -ConnectionBase::ConnectionBase() { - pending_size = 0; -} - -ConnectionBase::~ConnectionBase() { - std::cout << "Connection destroyed." << std::endl; -} diff --git a/common/connectionbase.h b/common/connectionbase.h deleted file mode 100644 index f86a9ab..0000000 --- a/common/connectionbase.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef CONNECTIONBASE_H -#define CONNECTIONBASE_H - -#include <stdint.h> -#include <cstdlib> -#include <string> - -#include "message.h" - -class ConnectionBase { - private: - Message::Type pending_type; - std::size_t pending_size; - - protected: - //! Initiate reception of a message. - void start_recv(); - - //! Deliver received data. - //! \param data Pointer to received data. Ownership is retained by caller. - //! \param bytes Size of data. - void got_data(uint8_t* data, std::size_t bytes); - - //! Called to request data. - //! \param bytes Amount of data requested. - virtual void request_data(std::size_t bytes) = 0; - - //! Called to write data. - //! \param data Pointer to data to send. Ownership is transferred to callee. - //! \param bytes Size of data. - virtual void write_data(uint8_t* data, std::size_t bytes) = 0; - - //! Called when a message is received. - //! \param msg Received message. - virtual void got_message(const Message::p& msg) = 0; - - //! Called upon error (lost connection or failed deserialization). - //! \param msg Error message. - virtual void error(const std::string& msg) = 0; - - public: - ConnectionBase(); - virtual ~ConnectionBase(); - - //! Send a message. - void send(const Message::p& msg); -}; - -#endif diff --git a/common/cyclicint.h b/common/cyclicint.h deleted file mode 100644 index 7c06877..0000000 --- a/common/cyclicint.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef CYCLICINT_H -#define CYCLICINT_H - -//! Class containing an integer which ranges from 0..N-1. -//! -//! Exceeding the ends will overflow to the other end. Implicit cast to/from int is provided. -template<int N> -class CyclicInt { - private: - int value; - - CyclicInt set(int v) { - value = v < N ? v < 0 ? N - -v % N : v : v % N; - return *this; - } - - public: - CyclicInt() { - - } - - CyclicInt(int v) { - set(v); - } - - CyclicInt operator=(int v) { - return set(v); - } - - CyclicInt operator+(CyclicInt v) { - return value + v.value; - } - - CyclicInt operator+(int v) { - return value + v; - } - - CyclicInt operator+=(CyclicInt v) { - return set(value + v.value); - } - - CyclicInt operator++() { - return set(value + 1); - } - - CyclicInt operator++(int) { - int v = value; - set(value + 1); - return v; - } - - CyclicInt operator-() { - return -value; - } - - CyclicInt operator-(CyclicInt v) { - return value - v.value; - } - - CyclicInt operator-(int v) { - return value - v; - } - - CyclicInt operator-=(CyclicInt v) { - return set(value - v.value); - } - - CyclicInt operator--() { - return set(value - 1); - } - - CyclicInt operator--(int) { - int v = value; - set(value - 1); - return v; - } - - operator int() { - return value; - } -}; - - -#endif diff --git a/common/list.h b/common/list.h deleted file mode 100644 index 513f79c..0000000 --- a/common/list.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef LIST_H -#define LIST_H - -#include <vector> -#include <algorithm> -#include <boost/serialization/base_object.hpp> - -//! List class with extended functionality over std::vector. -template<class T, class B = std::vector<T> > -class List : public B { - public: - //! Default constructor. - List() : B() {} - - //! Iterator constructor. - template <class InputIterator> - List(InputIterator first, InputIterator last) : B(first, last) {} - - //! Sort the list. - void sort() { - std::sort(B::begin(), B::end()); - } - - //! Check if specified item is present in list. - bool contains(const T& item) { - return std::find(B::begin(), B::end(), item) != B::end(); - } - - //! Count number of instances of specified item in list. - std::size_t count(const T& item) { - return std::count(B::begin(), B::end(), item); - } - - //! Delete item by index. - void del(std::size_t index) { - erase(B::begin() + index); - } - - //! Check whether list is empty or not. - operator bool() const { - return !B::empty(); - } - - //! Allow serialization through Boost.Serialize. - template<class Archive> - void serialize(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object<B>(*this); - } -}; - -#endif diff --git a/common/message.h b/common/message.h deleted file mode 100644 index 7cddbe3..0000000 --- a/common/message.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef MESSAGE_H -#define MESSAGE_H - -#include <boost/shared_ptr.hpp> -#include <boost/make_shared.hpp> -using boost::make_shared; -using boost::dynamic_pointer_cast; - -#include <stdint.h> -#include <vector> -#include <string> - -#include "action.h" -#include "tile.h" -#include "state.h" - -namespace Message { - namespace Types { - //! Message types. - enum Type { - Undefined, - Hello, - Login, - LoginResponse, - LobbyStatus, - LobbyAction, - GameStart, - GameResume, - Ready, - RoundStart, - RoundState, - RoundAction, - RoundEnd, - GameEnd - }; - } - using Types::Type; - - class Base { - protected: - Base(Type t) : type(t) {} - virtual ~Base() {} - - public: - const Type type; - }; - - class Hello : public Base { - public: - typedef boost::shared_ptr<Hello> p; - - Hello(const std::string& v = "") : Base(Types::Hello), version(v) {} - - std::string version; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & version; - } - }; - - class Login : public Base { - public: - typedef boost::shared_ptr<Login> p; - - Login(const std::string& n = "", uint64_t c = 0) : Base(Types::Login), nick(n), cookie(c) {} - - std::string nick; - - uint64_t cookie; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & nick; - ar & cookie; - } - }; - - class LoginResponse : public Base { - public: - typedef boost::shared_ptr<LoginResponse> p; - - //! Response type. - enum Type { - //! Invalid login attempt. - Invalid, - //! Login to lobby. - Lobby, - //! Login to resume ongoing game. - Resume - }; - - LoginResponse(Type t = Invalid, uint64_t c = 0) : Base(Types::LoginResponse), type(t), cookie(c) {} - - Type type; - - uint64_t cookie; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & type; - ar & cookie; - } - }; - - class LobbyStatus : public Base { - public: - typedef boost::shared_ptr<LobbyStatus> p; - - LobbyStatus() : Base(Types::LobbyStatus) {} - - std::vector<std::string> game_modes; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & game_modes; - } - }; - - class LobbyAction : public Base { - public: - typedef boost::shared_ptr<LobbyAction> p; - - LobbyAction(int i = 0) : Base(Types::LobbyAction), index(i) {} - - int index; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & index; - } - }; - - class GameStart : public Base { - public: - typedef boost::shared_ptr<GameStart> p; - - GameStart() : Base(Types::GameStart) {} - - std::vector<std::string> players; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & players; - } - }; - - class GameResume : public Base { - public: - typedef boost::shared_ptr<GameResume> p; - - GameResume() : Base(Types::GameResume) {} - - std::vector<std::string> players; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & players; - } - }; - - class Ready : public Base { - public: - typedef boost::shared_ptr<Ready> p; - - Ready() : Base(Types::Ready) {} - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - - } - }; - - class RoundStart : public Base { - public: - typedef boost::shared_ptr<RoundStart> p; - - RoundStart() : Base(Types::RoundStart) {} - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - - } - }; - - class RoundState : public Base { - public: - typedef boost::shared_ptr<RoundState> p; - - RoundState() : Base(Types::RoundState) {} - RoundState(const PlayerState& pl_d, const PlayerState& pl_r, const PlayerState& pl_u, const PlayerState& pl_l, const GameState& g, const Actions& a) - : Base(Types::RoundState), game(g), possible_actions(a) { - players[0] = pl_d; - players[1] = pl_r; - players[2] = pl_u; - players[3] = pl_l; - } - - //! Player states. - PlayerState players[4]; - - //! Game state. - GameState game; - - //! List of actions client must return one of. - Actions possible_actions; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & players; - ar & game; - ar & possible_actions; - } - }; - - class RoundAction : public Base { - public: - typedef boost::shared_ptr<RoundAction> p; - - RoundAction() : Base(Types::RoundAction) {} - - Action action; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & action; - } - }; - - class RoundEnd : public Base { - public: - typedef boost::shared_ptr<RoundEnd> p; - - struct Score { - std::string nick; - int score; - int won; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & nick; - ar & score; - ar & won; - } - }; - - RoundEnd() : Base(Types::RoundEnd) {} - Tiles hand; - std::vector<std::pair<std::string, int> > yakus; - int total_han; - int total_fu; - int won; - Score score[4]; - - bool game_end; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & hand; - ar & yakus; - ar & total_han; - ar & total_fu; - ar & won; - ar & score; - ar & game_end; - } - }; - - class GameEnd : public Base { - public: - typedef boost::shared_ptr<GameEnd> p; - Message::RoundEnd::Score scores[4]; - - GameEnd() : Base(Types::GameEnd) {} - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & scores; - } - - }; - - typedef boost::shared_ptr<Base> p; -}; - -#endif diff --git a/common/set.h b/common/set.h deleted file mode 100644 index faf9a3b..0000000 --- a/common/set.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef SET_H -#define SET_H - -#include "tile.h" - -class Set { - public: - enum Type { - Pair, - Chi, - Pon, - Kan - }; - - Type type; - Tiles tiles; - bool open; - - Set(Type ty, Tiles ti, bool o) : type(ty), tiles(ti), open(o) {} -}; - -typedef List<Set> Sets; - -#endif diff --git a/common/state.h b/common/state.h deleted file mode 100644 index d9b24c4..0000000 --- a/common/state.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef STATE_H -#define STATE_H - -#include "tile.h" - -//! Class containing the game state related to each player. -struct PlayerState { - //! Player's hand. Concealed tiles is first set, open sets follow in the order they was called in. - Tilegroups hand; - - //! Discarded tiles. - Tiles pond; - - //! Flag indicating whether player has declared riichi. - bool riichi; - - //! Player's score. - int score; - - //! Player's seat wind. - int wind; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & hand; - ar & pond; - ar & riichi; - ar & score; - ar & wind; - } -}; - -//! Class containing the game state unrelated to the players. -struct GameState { - //! List of dora/kandora. - Tiles dora; - - //! Current player, relative to context. 0 = self, 1 = shimocha and so on. - int current_player; - - //! Round (prevalent) wind. - int round_wind; - - //! Round number (of this wind). - int round_number; - - //! Count of riichi sticks on table (current and leftovers). - int riichibou; - - //! Count of honba sticks on table (indicating renchan). - int honba; - - template<class Archive> - void serialize(Archive & ar, const unsigned int v) { - ar & dora; - ar & current_player; - ar & round_wind; - ar & round_number; - ar & riichibou; - ar & honba; - } -}; - -#endif diff --git a/common/tile.cpp b/common/tile.cpp deleted file mode 100644 index 4b1f8b5..0000000 --- a/common/tile.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "tile.h" - -#include <algorithm> - -Tile::Tile(Tile::Type t, bool re) : type(t), red(re), rotated(false), invisible(false) { - -} - -Tile::Tile(Set s, int num, bool re) : red(re), rotated(false), invisible(false) { - switch(s) { - case Man: - type = Type(Man_1 + num - 1); - break; - case Pin: - type = Type(Pin_1 + num - 1); - break; - case Sou: - type = Type(Sou_1 + num - 1); - break; - default: - // Invalid. - break; - } -} - -int Tile::get_num() const { - if(type >= Man_1 && type <= Sou_9) { - return (type - Man_1) % 9 + 1; - } else { - return 0; - } -} - -Tile::Set Tile::get_set() const { - if(type >= Man_1 && type <= Man_9) { - return Man; - } else if(type >= Pin_1 && type <= Pin_9) { - return Pin; - } else if(type >= Sou_1 && type <= Sou_9) { - return Sou; - } else { - return Honor; - } -} - -bool Tile::is_simple() const { - int n = get_num(); - return n > 1 && n < 9; -} - -bool Tile::operator==(const Tile& other) const { - return type == other.type; -} - -bool Tile::operator<(const Tile& other) const { - return type == other.type ? red : type < other.type; -} - -Tile Tile::operator++(int) { - type = Type(type + 1); - return *this; -} diff --git a/common/tile.h b/common/tile.h deleted file mode 100644 index 83ec10b..0000000 --- a/common/tile.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef TILE_H -#define TILE_H - -#include "list.h" - -class Tile { - public: - enum Type { - // Face-down tile: - Back, - // Characters set: - Man_1, - Man_2, - Man_3, - Man_4, - Man_5, - Man_6, - Man_7, - Man_8, - Man_9, - // Circles set: - Pin_1, - Pin_2, - Pin_3, - Pin_4, - Pin_5, - Pin_6, - Pin_7, - Pin_8, - Pin_9, - // Bamboo set: - Sou_1, - Sou_2, - Sou_3, - Sou_4, - Sou_5, - Sou_6, - Sou_7, - Sou_8, - Sou_9, - // Winds: - Ton, - Nan, - Xia, - Pei, - // Dragons: - Chun, - Haku, - Hatsu - }; - - enum Set { - Honor, - Man, - Pin, - Sou - }; - - Type type; - bool red; - bool rotated; - bool invisible; - - //! Construct tile by type. - Tile(Type t = Back, bool re = false); - - //! Construct tile by set and number. - Tile(Set s, int num, bool re = false); - - virtual ~ |