diff options
author | Atle Hellvik Havsø <atle@havso.net> | 2010-11-22 20:08:56 +0100 |
---|---|---|
committer | Atle Hellvik Havsø <atle@havso.net> | 2010-11-22 20:09:18 +0100 |
commit | 62a05732e05a25f40fbb409e49ff30e3fc8bd28c (patch) | |
tree | f01f1b3946696042e532f423b7e3435befec6f8d /server | |
parent | 56e4891bcdd693cfba540aec186f151012d96870 (diff) |
Moved lots of code in Game out into a separate class.
Signed-off-by: Atle Hellvik Havsø <atle@havso.net>
Diffstat (limited to 'server')
-rw-r--r-- | server/game.cpp | 408 | ||||
-rw-r--r-- | server/game.h | 21 | ||||
-rw-r--r-- | server/gamevariant.h | 20 | ||||
-rw-r--r-- | server/standard.cpp | 418 | ||||
-rw-r--r-- | server/standard.h | 37 |
5 files changed, 499 insertions, 405 deletions
diff --git a/server/game.cpp b/server/game.cpp index ed5bf3f..d13235b 100644 --- a/server/game.cpp +++ b/server/game.cpp @@ -3,17 +3,14 @@ #include <boost/bind.hpp> #include <iostream> -#include <algorithm> + +#ifdef DEBUG #include <ctime> +#endif #include "../common/set.h" -bool MyDataSortPredicate(const Tile& d1, const Tile& d2) -{ - return d1.type < d2.type; -} - Game::p Game::create(Player::p player_1, Player::p player_2, Player::p player_3, Player::p player_4) { Game::p p(new Game(player_1, player_2, player_3, player_4)); p->start(); @@ -22,6 +19,7 @@ Game::p Game::create(Player::p player_1, Player::p player_2, Player::p player_3, Game::~Game() { std::cout << "Game destroyed." << std::endl; + delete ruleset; } Game::Game(Player::p player_1, Player::p player_2, Player::p player_3, Player::p player_4) { @@ -49,253 +47,30 @@ void Game::round_start() { players[2]->round_start(); players[3]->round_start(); - - // Sett opp runden sin state - //game_state = make_shared<State>(); - - // Simulates drawing 4, 4 ,4 for each player - for (int i = 0; i < 3; i++) { - for (int player_num = 0; player_num < 4; player_num++) { - for (int y = 0; y < 4; y++) { - game_state.players[player_num].hand.push_back(wall.take_one()); - } - } - } - - // Simulates the second part of drawing with only 1 tile - for (int player_num = 0; player_num < 4; player_num++) { - game_state.players[player_num].hand.push_back(wall.take_one()); - } - - std::sort(game_state.players[0].hand.begin(),game_state.players[0].hand.end(), MyDataSortPredicate); - std::sort(game_state.players[1].hand.begin(),game_state.players[1].hand.end(), MyDataSortPredicate); - std::sort(game_state.players[2].hand.begin(),game_state.players[2].hand.end(), MyDataSortPredicate); - std::sort(game_state.players[3].hand.begin(),game_state.players[3].hand.end(), MyDataSortPredicate); - - - most_value_action.type = Action::Pass; - current_player = 3; - num_player_actions = 0; - draw_phase = true; + ruleset = new RuleSet::Standard(); + ruleset->round_start(); round_update(); } void Game::round_update() { - char smart = 0; - // We're in the draw_phase whenever a player draws a tile from the wall - if(draw_phase) { - // If the wall is empty (Contains only 14 tiles) when we enter draw phase the round is over. - if(wall.is_done()) { - round_end(); - } - - // Since we've entered the draw-phase it's the next players turn - if (current_player == 3) { - current_player = 0; - } else { - current_player++; - } - - #ifdef DEBUG - - time_t current_time = std::time(0); - std::cout << std::ctime(¤t_time) << " - Waiting for action from player: " << current_player << std::endl; - - #endif - - // Let's take a tile - Tile from_wall = wall.take_one(); - - // We then add the tile to the current players hand - game_state.players[current_player].hand.push_back(from_wall); - - // Need to sort again. - std::sort(game_state.players[current_player].hand.begin(),game_state.players[current_player].hand.end(), MyDataSortPredicate); - - // Construct the discard action that the player can do. - Action discard; - discard.type = Action::Discard; - discard.player = current_player; - - - game_state.possible_actions.push_back(discard); - - //num_player_actions++; - - // Enter the discard phase next loop; - draw_phase = false; - smart = smart | (1 << current_player); - } else { - //We chwck to see if player can chi from last discard - - - int temp_next_player; - if (current_player == 3) { - temp_next_player = 0; - } else { - temp_next_player = current_player + 1; - } - - Tiles* pond = &game_state.players[current_player].pond; - Tile temp_tile = pond->back(); - Tiles::iterator it; - Tile* tile_2u = NULL; - Tile* tile_1u = NULL; - Tile* tile_1o = NULL; - Tile* tile_2o = NULL; - unsigned int count = 0, tile_2u_id,tile_1u_id,tile_1o_id,tile_2o_id; - Tile::Type check_tile; - for(it = game_state.players[temp_next_player].hand.begin(); it != game_state.players[temp_next_player].hand.end(); ++it) { - #ifdef DEBUG - Tile debug = *it; - #endif - - check_tile = Tile::Type(temp_tile.type - 2); - if(it->type == check_tile) { - tile_2u = &(*it); - tile_2u_id = count; - } - check_tile = Tile::Type(temp_tile.type - 1); - if(it->type == check_tile) { - tile_1u = &(*it); - tile_1u_id = count; - } - check_tile = Tile::Type(temp_tile.type + 1); - if(it->type == check_tile) { - tile_1o = &(*it); - tile_1o_id = count; - } - check_tile = Tile::Type(temp_tile.type + 2); - if(it->type == check_tile) { - tile_2o = &(*it); - tile_2o_id = count; - } - count++; - } - - bool chi; - if(tile_2u && tile_1u) { - Action temp_action; - chi = false; - //Make sure we have a chi within the same series. - if(tile_2u->type <= Tile::Man_7 && tile_2u->type >= Tile::Man_1) { - chi = true; - } else if(tile_2u->type <= Tile::Pin_7 && tile_2u->type >= Tile::Pin_1) { - chi = true; - } else if(tile_2u->type <= Tile::Sou_7 && tile_2u->type >= Tile::Sou_1) { - chi = true; - } - if(chi) { - temp_action.player = temp_next_player; - temp_action.target = tile_2u_id; - temp_action.type = Action::Chi; - game_state.possible_actions.push_back(temp_action); - #ifdef DEBUG - - time_t current_time = std::time(0); - std::cout << std::ctime(¤t_time) << " Player: " << temp_action.player << " Can do action: " << temp_action.type << " On target: " << temp_action.target << std::endl; - - #endif - } - } - - if(tile_1u && tile_1o) { - Action temp_action; - chi = false; - //Make sure we have a chi within the same series. - if(tile_1u->type <= Tile::Man_7 && tile_1u->type >= Tile::Man_1) { - chi = true; - } else if(tile_1u->type <= Tile::Pin_7 && tile_1u->type >= Tile::Pin_1) { - chi = true; - } else if(tile_1u->type <= Tile::Sou_7 && tile_1u->type >= Tile::Sou_1) { - chi = true; - } - if(chi) { - temp_action.player = temp_next_player; - temp_action.target = tile_1u_id; - temp_action.type = Action::Chi; - game_state.possible_actions.push_back(temp_action); - - #ifdef DEBUG - - time_t current_time = std::time(0); - std::cout << std::ctime(¤t_time) << " Player: " << temp_action.player << " Can do action: " << temp_action.type << " On target: " << temp_action.target << std::endl; - - #endif - } - } - - if(tile_1o && tile_2o) { - Action temp_action; - chi = false; - //Make sure we have a chi within the same series. - if(temp_tile.type <= Tile::Man_7 && temp_tile.type >= Tile::Man_1) { - chi = true; - } else if(temp_tile.type <= Tile::Pin_7 && temp_tile.type >= Tile::Pin_1) { - chi = true; - } else if(temp_tile.type <= Tile::Sou_7 && temp_tile.type >= Tile::Sou_1) { - chi = true; - } - if(chi) { - temp_action.player = temp_next_player; - temp_action.target = tile_1o_id; - temp_action.type = Action::Chi; - game_state.possible_actions.push_back(temp_action); - - #ifdef DEBUG - - time_t current_time = std::time(0); - std::cout << std::ctime(¤t_time) << " Player: " << temp_action.player << " Can do action: " << temp_action.type << " On target: " << temp_action.target << std::endl; - - #endif - } - } - - //Go back into draw_phase0 - draw_phase = true; - // Not implemented yet - for(Actions::iterator it = game_state.possible_actions.begin(); it != game_state.possible_actions.end(); ++it) { - smart = smart | (0x0001 << it->player); - } - - if(smart & 1) { - Action pass; - pass.type = Action::Pass; - pass.player = 0; - game_state.possible_actions.push_back(pass); - } - if(smart & 2) { - Action pass; - pass.type = Action::Pass; - pass.player = 1; - game_state.possible_actions.push_back(pass); - } - if(smart & 4) { - Action pass; - pass.type = Action::Pass; - pass.player = 2; - game_state.possible_actions.push_back(pass); - } - if(smart & 8) { - Action pass; - pass.type = Action::Pass; - pass.player = 3; - game_state.possible_actions.push_back(pass); - } - } - + State gamestate = ruleset->round_update(); // Send the updates state to the players - players[0]->round_state(game_state); - players[1]->round_state(game_state); - players[2]->round_state(game_state); - players[3]->round_state(game_state); + players[0]->round_state(gamestate); + players[1]->round_state(gamestate); + players[2]->round_state(gamestate); + players[3]->round_state(gamestate); // Only implemented discard so far, so only current player that needs to be able to do a action. - + int smart = 0; + for(Actions::iterator it = gamestate.possible_actions.begin(); it != gamestate.possible_actions.end(); ++it) { + smart = smart | (1 << it->player); + } + + int num_player_actions = 0; if(smart & 1) { num_player_actions++; @@ -321,156 +96,13 @@ void Game::round_update() { void Game::handle_action(Action action) { - players[action.player]->kill_action(); - - #ifdef DEBUG - - time_t current_time = std::time(0); - std::cout << std::ctime(¤t_time) << " Player: " << action.player << " Did action: " << action.type << " On target: " << action.target << std::endl; - - #endif + //players[action.player]->kill_action(); - // Lots of actions to test if the player doing the action is allowed to do it - - // Check if we're actually waiting for actions. - if (game_state.possible_actions.empty()) { - return; - } - - // Check if the player is allowed to do this action - bool found_action = false; - - for(Actions::iterator it = game_state.possible_actions.begin(); it != game_state.possible_actions.end(); ++it) { - if(it->player == action.player && it->type == action.type) { - found_action = true; - } - } - - if(!found_action) { - return; - } + bool done = ruleset->round_action(action); - switch ( action.type ) { - - case Action::Pass: { - - } break; - - case Action::Discard: { - Tile discarded_tile = game_state.players[action.player].hand[action.target]; - game_state.players[action.player].pond.push_back(discarded_tile); - game_state.players[action.player].hand.erase(game_state.players[action.player].hand.begin() + action.target); - - } break; - - case Action::Riichi: { - - } break; - - case Action::Chi: { - if(most_value_action.type != Action::Pon && most_value_action.type != Action::Kan && most_value_action.type != Action::Ron) { - most_value_action = action; - } - } break; - - case Action::Pon: { - if(most_value_action.type != Action::Ron) { - most_value_action = action; - } - } break; - - case Action::Kan: { - - } break; - - case Action::Ron: { - - } break; - - case Action::Tsumo: { - - } break; - - case Action::Draw: { - - } break; - - default: - break; - } - - - num_player_actions--; - - // Remove all the actions that this player could do since he now did one. - - std::vector<int> positions; - int position = 0; - for(Actions::iterator it = game_state.possible_actions.begin(); it != game_state.possible_actions.end(); ++it) { - if (it->player == action.player) { - positions.push_back(position); - } - position++; - } - if (!positions.empty()) { - int found = 0; - for(std::vector<int>::iterator it = positions.begin(); it != positions.end(); ++it) { - game_state.possible_actions.erase(game_state.possible_actions.begin() + (*it - found)); - found++; - } - } - - //When everyone has done their action we empty the list (just to be sure) and then do a round_update() - if(num_player_actions == 0) { - game_state.possible_actions.empty(); - - if(most_value_action.type != Action::Pass) { - switch (most_value_action.type) { - case Action::Chi: { - Set chi; - Tile left_tile = game_state.players[current_player].pond.back(); - left_tile.rotated = true; - chi.add_tile(left_tile); - - Tile middle_tile = game_state.players[action.player].hand[action.target]; - chi.add_tile(middle_tile); - - Tile right_tile; - if(Tile::Type(game_state.players[action.player].hand[action.target].type + 1) == left_tile.type) { - right_tile = game_state.players[action.player].hand[action.target + 2]; - } else { - right_tile = game_state.players[action.player].hand[action.target + 1]; - } - chi.add_tile(right_tile); - - game_state.players[action.player].open.push_back(chi); - game_state.players[action.player].hand.erase(game_state.players[action.player].hand.begin() + action.target); - game_state.players[action.player].hand.erase(game_state.players[action.player].hand.begin() + action.target); - - - } break; - - case Action::Pon: { - - } break; - - case Action::Kan: { - - } break; - - case Action::Ron: { - - } break; - - default: break; - } - - most_value_action.type = Action::Pass; - } - + if(done) { round_update(); } - // Sjekk action, sjekk om endelig action er avgjort // Oppdater state // Evt. round_end() diff --git a/server/game.h b/server/game.h index f88ffd4..f0f1564 100644 --- a/server/game.h +++ b/server/game.h @@ -10,6 +10,9 @@ #include "player.h" #include "../common/action.h" +#include "gamevariant.h" +#include "standard.h" + class Game : public boost::enable_shared_from_this<Game> { public: typedef boost::shared_ptr<Game> p; @@ -25,23 +28,7 @@ class Game : public boost::enable_shared_from_this<Game> { Game(Player::p player_1, Player::p player_2, Player::p player_3, Player::p player_4); - //! The wall that belongs to this game - Wall wall; - - //! The current state of the game - State game_state; - - //! Current player, used when discarding etc - int current_player; - - //! Are we in draw or discard phase? - bool draw_phase; - - //! Number of players doing action - int num_player_actions; - - //! Highest value action done - Action most_value_action; + GameVariant *ruleset; //! Handle Ready message from player. void handle_ready(); diff --git a/server/gamevariant.h b/server/gamevariant.h new file mode 100644 index 0000000..6fb2c56 --- /dev/null +++ b/server/gamevariant.h @@ -0,0 +1,20 @@ +#ifndef GAMEVARIANT_H +#define GAMEVARIANT_H + +#include "../common/state.h" +#include "../common/action.h" + +class GameVariant { + private: + State game_state; + + public: + virtual ~GameVariant(){}; + + virtual void round_start() = 0; + virtual State& round_update() = 0; + virtual bool round_action(Action action) = 0; +}; + +#endif // GAMEVARIANT_H + diff --git a/server/standard.cpp b/server/standard.cpp new file mode 100644 index 0000000..a45c018 --- /dev/null +++ b/server/standard.cpp @@ -0,0 +1,418 @@ +#include "standard.h" + +#include <algorithm> + +#ifdef DEBUG +#include <ctime> +#include <iostream> +#endif + +using namespace RuleSet; +bool MyDataSortPredicate(const Tile& d1, const Tile& d2) { + return d1.type < d2.type; +} + +void Standard::round_start() { + + // Sett opp runden sin state + //game_state = make_shared<State>(); + + // Simulates drawing 4, 4 ,4 for each player + for (int i = 0; i < 3; i++) { + for (int player_num = 0; player_num < 4; player_num++) { + for (int y = 0; y < 4; y++) { + game_state.players[player_num].hand.push_back(wall.take_one()); + } + } + } + + // Simulates the second part of drawing with only 1 tile + for (int player_num = 0; player_num < 4; player_num++) { + game_state.players[player_num].hand.push_back(wall.take_one()); + } + + std::sort(game_state.players[0].hand.begin(),game_state.players[0].hand.end(), MyDataSortPredicate); + std::sort(game_state.players[1].hand.begin(),game_state.players[1].hand.end(), MyDataSortPredicate); + std::sort(game_state.players[2].hand.begin(),game_state.players[2].hand.end(), MyDataSortPredicate); + std::sort(game_state.players[3].hand.begin(),game_state.players[3].hand.end(), MyDataSortPredicate); + + + most_value_action.type = Action::Pass; + current_player = 3; + num_player_actions = 0; + draw_phase = true; + +} + + +State& Standard::round_update() { + char smart = 0; + // We're in the draw_phase whenever a player draws a tile from the wall + if(draw_phase) { + // If the wall is empty (Contains only 14 tiles) when we enter draw phase the round is over. + + // Since we've entered the draw-phase it's the next players turn + if (current_player == 3) { + current_player = 0; + } else { + current_player++; + } + + #ifdef DEBUG + + time_t current_time = std::time(0); + std::cout << std::ctime(¤t_time) << " - Waiting for action from player: " << current_player << std::endl; + + #endif + + // Let's take a tile + Tile from_wall = wall.take_one(); + + // We then add the tile to the current players hand + game_state.players[current_player].hand.push_back(from_wall); + + // Need to sort again. + std::sort(game_state.players[current_player].hand.begin(),game_state.players[current_player].hand.end(), MyDataSortPredicate); + + // Construct the discard action that the player can do. + Action discard; + discard.type = Action::Discard; + discard.player = current_player; + + + game_state.possible_actions.push_back(discard); + + //num_player_actions++; + + // Enter the discard phase next loop; + draw_phase = false; + smart = smart | (1 << current_player); + } else { + //We chwck to see if player can chi from last discard + + + int temp_next_player; + if (current_player == 3) { + temp_next_player = 0; + } else { + temp_next_player = current_player + 1; + } + + Tiles* pond = &game_state.players[current_player].pond; + Tile temp_tile = pond->back(); + Tiles::iterator it; + Tile* tile_2u = NULL; + Tile* tile_1u = NULL; + Tile* tile_1o = NULL; + Tile* tile_2o = NULL; + unsigned int count = 0, tile_2u_id,tile_1u_id,tile_1o_id,tile_2o_id; + Tile::Type check_tile; + for(it = game_state.players[temp_next_player].hand.begin(); it != game_state.players[temp_next_player].hand.end(); ++it) { + #ifdef DEBUG + Tile debug = *it; + #endif + + check_tile = Tile::Type(temp_tile.type - 2); + if(it->type == check_tile) { + tile_2u = &(*it); + tile_2u_id = count; + } + check_tile = Tile::Type(temp_tile.type - 1); + if(it->type == check_tile) { + tile_1u = &(*it); + tile_1u_id = count; + } + check_tile = Tile::Type(temp_tile.type + 1); + if(it->type == check_tile) { + tile_1o = &(*it); + tile_1o_id = count; + } + check_tile = Tile::Type(temp_tile.type + 2); + if(it->type == check_tile) { + tile_2o = &(*it); + tile_2o_id = count; + } + count++; + } + + bool chi; + if(tile_2u && tile_1u) { + Action temp_action; + chi = false; + //Make sure we have a chi within the same series. + if(tile_2u->type <= Tile::Man_7 && tile_2u->type >= Tile::Man_1) { + chi = true; + } else if(tile_2u->type <= Tile::Pin_7 && tile_2u->type >= Tile::Pin_1) { + chi = true; + } else if(tile_2u->type <= Tile::Sou_7 && tile_2u->type >= Tile::Sou_1) { + chi = true; + } + if(chi) { + temp_action.player = temp_next_player; + temp_action.target = tile_2u_id; + temp_action.type = Action::Chi; + game_state.possible_actions.push_back(temp_action); + #ifdef DEBUG + + time_t current_time = std::time(0); + std::cout << std::ctime(¤t_time) << " Player: " << temp_action.player << " Can do action: " << temp_action.type << " On target: " << temp_action.target << std::endl; + + #endif + } + } + + if(tile_1u && tile_1o) { + Action temp_action; + chi = false; + //Make sure we have a chi within the same series. + if(tile_1u->type <= Tile::Man_7 && tile_1u->type >= Tile::Man_1) { + chi = true; + } else if(tile_1u->type <= Tile::Pin_7 && tile_1u->type >= Tile::Pin_1) { + chi = true; + } else if(tile_1u->type <= Tile::Sou_7 && tile_1u->type >= Tile::Sou_1) { + chi = true; + } + if(chi) { + temp_action.player = temp_next_player; + temp_action.target = tile_1u_id; + temp_action.type = Action::Chi; + game_state.possible_actions.push_back(temp_action); + + #ifdef DEBUG + + time_t current_time = std::time(0); + std::cout << std::ctime(¤t_time) << " Player: " << temp_action.player << " Can do action: " << temp_action.type << " On target: " << temp_action.target << std::endl; + + #endif + } + } + + if(tile_1o && tile_2o) { + Action temp_action; + chi = false; + //Make sure we have a chi within the same series. + if(temp_tile.type <= Tile::Man_7 && temp_tile.type >= Tile::Man_1) { + chi = true; + } else if(temp_tile.type <= Tile::Pin_7 && temp_tile.type >= Tile::Pin_1) { + chi = true; + } else if(temp_tile.type <= Tile::Sou_7 && temp_tile.type >= Tile::Sou_1) { + chi = true; + } + if(chi) { + temp_action.player = temp_next_player; + temp_action.target = tile_1o_id; + temp_action.type = Action::Chi; + game_state.possible_actions.push_back(temp_action); + + #ifdef DEBUG + + time_t current_time = std::time(0); + std::cout << std::ctime(¤t_time) << " Player: " << temp_action.player << " Can do action: " << temp_action.type << " On target: " << temp_action.target << std::endl; + + #endif + } + } + + //Go back into draw_phase0 + draw_phase = true; + // Not implemented yet + + for(Actions::iterator it = game_state.possible_actions.begin(); it != game_state.possible_actions.end(); ++it) { + smart = smart | (0x0001 << it->player); + } + + if(smart & 1) { + Action pass; + pass.type = Action::Pass; + pass.player = 0; + game_state.possible_actions.push_back(pass); + } + if(smart & 2) { + Action pass; + pass.type = Action::Pass; + pass.player = 1; + game_state.possible_actions.push_back(pass); + } + if(smart & 4) { + Action pass; + pass.type = Action::Pass; + pass.player = 2; + game_state.possible_actions.push_back(pass); + } + if(smart & 8) { + Action pass; + pass.type = Action::Pass; + pass.player = 3; + game_state.possible_actions.push_back(pass); + } + } + + for(Actions::iterator it = game_state.possible_actions.begin(); it != game_state.possible_actions.end(); ++it) { + smart = smart | (1 << it->player); + } + + if(smart & 1) { + num_player_actions++; + } + if(smart & 2) { + num_player_actions++; + } + if(smart & 4) { + num_player_actions++; + } + if(smart & 8) { + num_player_actions++; + } + + return game_state; +} + +bool Standard::round_action(Action action) { + #ifdef DEBUG + + time_t current_time = std::time(0); + std::cout << std::ctime(¤t_time) << " Player: " << action.player << " Did action: " << action.type << " On target: " << action.target << std::endl; + + #endif + + // Lots of actions to test if the player doing the action is allowed to do it + + // Check if we're actually waiting for actions. + if (game_state.possible_actions.empty()) { + return false; + } + + // Check if the player is allowed to do this action + bool found_action = false; + + for(Actions::iterator it = game_state.possible_actions.begin(); it != game_state.possible_actions.end(); ++it) { + if(it->player == action.player && it->type == action.type) { + found_action = true; + } + } + + if(!found_action) { + return false; + } + + switch ( action.type ) { + + case Action::Pass: { + + } break; + + case Action::Discard: { + Tile discarded_tile = game_state.players[action.player].hand[action.target]; + game_state.players[action.player].pond.push_back(discarded_tile); + game_state.players[action.player].hand.erase(game_state.players[action.player].hand.begin() + action.target); + + } break; + + case Action::Riichi: { + + } break; + + case Action::Chi: { + if(most_value_action.type != Action::Pon && most_value_action.type != Action::Kan && most_value_action.type != Action::Ron) { + most_value_action = action; + } + } break; + + case Action::Pon: { + if(most_value_action.type != Action::Ron) { + most_value_action = action; + } + } break; + + case Action::Kan: { + + } break; + + case Action::Ron: { + + } break; + + case Action::Tsumo: { + + } break; + + case Action::Draw: { + + } break; + + default: + break; + } + + + num_player_actions--; + + // Remove all the actions that this player could do since he now did one. + + std::vector<int> positions; + int position = 0; + for(Actions::iterator it = game_state.possible_actions.begin(); it != game_state.possible_actions.end(); ++it) { + if (it->player == action.player) { + positions.push_back(position); + } + position++; + } + if (!positions.empty()) { + int found = 0; + for(std::vector<int>::iterator it = positions.begin(); it != positions.end(); ++it) { + game_state.possible_actions.erase(game_state.possible_actions.begin() + (*it - found)); + found++; + } + } + + //When everyone has done their action we empty the list (just to be sure) and then do a round_update() + if(num_player_actions == 0) { + game_state.possible_actions.empty(); + + if(most_value_action.type != Action::Pass) { + switch (most_value_action.type) { + case Action::Chi: { + Set chi; + Tile left_tile = game_state.players[current_player].pond.back(); + left_tile.rotated = true; + chi.add_tile(left_tile); + + Tile middle_tile = game_state.players[action.player].hand[action.target]; + chi.add_tile(middle_tile); + + Tile right_tile; + if(Tile::Type(game_state.players[action.player].hand[action.target].type + 1) == left_tile.type) { + right_tile = game_state.players[action.player].hand[action.target + 2]; + } else { + right_tile = game_state.players[action.player].hand[action.target + 1]; + } + chi.add_tile(right_tile); + + game_state.players[action.player].open.push_back(chi); + game_state.players[action.player].hand.erase(game_state.players[action.player].hand.begin() + action.target); + game_state.players[action.player].hand.erase(game_state.players[action.player].hand.begin() + action.target); + + + } break; + + case Action::Pon: { + + } break; + + case Action::Kan: { + + } break; + + case Action::Ron: { + + } break; + + default: break; + } + most_value_action.type = Action::Pass; + } + return true; + } else { + return false; + } +} diff --git a/server/standard.h b/server/standard.h new file mode 100644 index 0000000..de81e7f --- /dev/null +++ b/server/standard.h @@ -0,0 +1,37 @@ +#ifndef STANDARD_H +#define STANDARD_H + +#include "gamevariant.h" + +#include "wall.h" +#include "../common/set.h" + +namespace RuleSet { + class Standard : public GameVariant { + private: + //! The wall that belongs to this game + Wall wall; + + //! The current state of the game + State game_state; + + //! Current player, used when discarding etc + int current_player; + + //! Are we in draw or discard phase? + bool draw_phase; + + //! Number of players doing action + int num_player_actions; + + //! Highest value action done + Action most_value_action; + + public: + virtual void round_start(); + virtual State& round_update(); + virtual bool round_action(Action action); + }; +}; +#endif // STANDARD_H + |