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 | |
| parent | 56e4891bcdd693cfba540aec186f151012d96870 (diff) | |
Moved lots of code in Game out into a separate class.
Signed-off-by: Atle Hellvik Havsø <atle@havso.net>
| -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 + | 
