summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtle Hellvik Havsø <atle@havso.net>2010-11-21 18:07:45 +0100
committerAtle Hellvik Havsø <atle@havso.net>2010-11-21 18:07:45 +0100
commitd7892a9e7aa204ecaa19bd9b4d71887217fa18d0 (patch)
tree4e38ac9287ae0c7fe7eba6a76ffa358a10435eca
parentb9942d8af0400f943b9b5bd67faf417a932750f5 (diff)
Rewrote parts of round_update and handle_action
Signed-off-by: Atle Hellvik Havsø <atle@havso.net>
-rw-r--r--server/game.cpp127
1 files changed, 79 insertions, 48 deletions
diff --git a/server/game.cpp b/server/game.cpp
index 72183bf..3548e13 100644
--- a/server/game.cpp
+++ b/server/game.cpp
@@ -3,6 +3,12 @@
#include <boost/bind.hpp>
#include <iostream>
+#include <algorithm>
+
+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));
@@ -66,68 +72,56 @@ void Game::round_start() {
void Game::round_update() {
- if ( draw_phase ) {
- if ( current_player == 3) {
+ // We're in the draw_phase whenever a player draws a tile from the wall
+ if(draw_phase) {
+ // Since we've entered the draw-phase it's the next players turn
+ if (current_player == 3) {
current_player = 0;
} else {
- current_player++;
+ current_player++;
}
- #ifdef DEBUG
-
- std::cout << "Next players turn: " << current_player << std::endl;
+
+ // Let's take a tile
+ Tile from_wall = wall.take_one();
- #endif
+ // 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);
- // Is the wall empty? Then the round is over and we have a draw
- if (wall.is_done()) {
- round_end();
- }
-
- game_state.players[current_player].hand.push_back(wall.take_one());
+ // Construct the discard action that the player can do.
+ Action discard;
+ discard.type = Action::Discard;
+ discard.player = current_player;
- Action discard_action;
- discard_action.type = Action::Discard;
- discard_action.player = current_player;
- game_state.possible_actions.push_back(discard_action);
-
- // TODO
- // Add code for calculation of possible riichi, tsumo, kan and draw
+ game_state.possible_actions.push_back(discard);
num_player_actions++;
- } else { // Run if we're in the discard phase
+
+ // Enter the discard phase next loop;
+ draw_phase = false;
+ } else {
+ //Go back into draw_phase
+ draw_phase = true;
+ // Not implemented yet
- // TODO
- // Add code for calculation of possible chi, pon, kan and ron.
}
-
- // Send RoundState, inkl. liste av mulige actions.
- for(int i = 0; i <= 3; i++) {
- if ( i != current_player ) {
- State send_state = game_state;
-
- send_state.possible_actions.clear();
-
- players[i]->round_state(send_state);
- } else {
- players[i]->round_state(game_state);
- #ifdef DEBUG
- std::cout << "Waiting for action from player: " << i << std::endl;
- #endif
- }
- }
+ // 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);
- // Kall player->get_action(handle_action) for hver spiller som har actions, om ingen kan gjøre noe så blir
- // det neste spiller sin tur.
- draw_phase = !draw_phase;
- if(num_player_actions) {
+ // Only implemented discard so far, so only current player that needs to be able to do a action.
+ if(num_player_actions > 0) {
players[current_player]->get_action(boost::bind(&Game::handle_action, shared_from_this(), _1));
} else {
round_update();
}
-
}
void Game::handle_action(Action action) {
@@ -136,8 +130,28 @@ void Game::handle_action(Action action) {
std::cout << "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;
+ }
+
+ // 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;
+ }
+
switch ( action.type ) {
case Action::Pass: {
@@ -187,11 +201,28 @@ void Game::handle_action(Action action) {
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()) {
+ for(std::vector<int>::iterator it = positions.begin(); it != positions.end(); ++it) {
+ game_state.possible_actions.erase(game_state.possible_actions.begin() + *it);
+ }
+ }
+
+ //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();
round_update();
}