summaryrefslogtreecommitdiff
path: root/server/game.cpp
diff options
context:
space:
mode:
authorAtle Hellvik Havsø <atle@havso.net>2010-11-22 20:08:56 +0100
committerAtle Hellvik Havsø <atle@havso.net>2010-11-22 20:09:18 +0100
commit62a05732e05a25f40fbb409e49ff30e3fc8bd28c (patch)
treef01f1b3946696042e532f423b7e3435befec6f8d /server/game.cpp
parent56e4891bcdd693cfba540aec186f151012d96870 (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/game.cpp')
-rw-r--r--server/game.cpp408
1 files changed, 20 insertions, 388 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(&current_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(&current_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(&current_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(&current_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(&current_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()