diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2010-12-25 12:54:59 +0100 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2010-12-25 12:54:59 +0100 |
commit | fae209a9e93400c3a2072befda9c820634cf9278 (patch) | |
tree | 2d69e2c75fff0e08468c168f773abbc939a2ff03 /server/game.cpp | |
parent | 94a1189d757f0269ac081ad2d750152e30564986 (diff) |
Diffstat (limited to 'server/game.cpp')
-rw-r--r-- | server/game.cpp | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/server/game.cpp b/server/game.cpp deleted file mode 100644 index e791379..0000000 --- a/server/game.cpp +++ /dev/null @@ -1,456 +0,0 @@ -#include "game.h" - -#include <boost/bind.hpp> - -#include <iostream> -#include <algorithm> -#include <map> - -#ifdef DEBUG -#include <ctime> -#endif - -Game::p Game::create(ClientBase::p player_1, ClientBase::p player_2, ClientBase::p player_3, ClientBase::p player_4) { - Game::p p(new Game(player_1, player_2, player_3, player_4)); - p->start(); - return p; -} - -Game::~Game() { - std::cout << "Game destroyed." << std::endl; -} - -Game::Game(ClientBase::p player_1, ClientBase::p player_2, ClientBase::p player_3, ClientBase::p player_4) { - players[0].client = player_1; - players[1].client = player_2; - players[2].client = player_3; - players[3].client = player_4; -} - -void Game::handle_ready() { - if(--awaiting_players) { - return; - } - - std::cout << "All ready!" << std::endl; - - round_start(); -} - -void Game::start() { - std::cout << "Started a game with " - << players[0].client->nick() << ", " - << players[1].client->nick() << ", " - << players[2].client->nick() << " and " - << players[3].client->nick() << "." << std::endl; - - round_wind = 0; - round_num = 0; - - awaiting_players = 4; - - std::vector<std::string> pl; - - pl.push_back(players[0].client->nick()); - pl.push_back(players[1].client->nick()); - pl.push_back(players[2].client->nick()); - pl.push_back(players[3].client->nick()); - - players[0].client->game_start(boost::bind(&Game::handle_ready, shared_from_this()), pl); - - pl.erase(pl.begin()); - pl.push_back(players[0].client->nick()); - players[1].client->game_start(boost::bind(&Game::handle_ready, shared_from_this()), pl); - - pl.erase(pl.begin()); - pl.push_back(players[1].client->nick()); - players[2].client->game_start(boost::bind(&Game::handle_ready, shared_from_this()), pl); - - pl.erase(pl.begin()); - pl.push_back(players[2].client->nick()); - players[3].client->game_start(boost::bind(&Game::handle_ready, shared_from_this()), pl); -} - -void Game::round_start() { - std::cout << "Starting a new round." << std::endl; - - // Build a new wall. - wall.build(); - - // Clear previous dora and draw a new. - dora.clear(); - dora.push_back(wall.take_one()); - - kan_dora_pending = false; - - // Notify players of round start. - // TODO: Tell them where wall is broken. - players[0].round_start(-round_num); - players[1].round_start(-round_num + 1); - players[2].round_start(-round_num + 2); - players[3].round_start(-round_num + 3); - - // Draw hands. - for(int i = 0; i < 13; i++) { - players[0].draw(wall.take_one()); - players[1].draw(wall.take_one()); - players[2].draw(wall.take_one()); - players[3].draw(wall.take_one()); - } - - // Sort hands. - players[0].hand.sort(); - players[1].hand.sort(); - players[2].hand.sort(); - players[3].hand.sort(); - - // Give east an extra tile. - players[0].draw(wall.take_one()); - - current_player = 0; - - round_update_draw(); -} - -void Game::round_update_draw() { - // Get possible actions for current player. - Actions possible_actions = players[current_player].get_actions_draw(); - - // Construct and send state to each client. - PlayerNum player = 0; - do { - PlayerState state[4]; - - state[0] = players[player].get_state(); - state[1] = players[player + 1].get_state_filtered(); - state[2] = players[player + 2].get_state_filtered(); - state[3] = players[player + 3].get_state_filtered(); - - Actions a; - if(player == current_player) { - a = possible_actions; - } - - GameState gstate = {dora, current_player - player, round_wind, round_num, 0, 0}; - - players[player].client->round_state(state[0], state[1], state[2], state[3], gstate, a); - } while(++player); - - // Await action from client. - players[current_player].client->get_action(boost::bind(&Game::handle_action_draw, shared_from_this(), _1), possible_actions); -} - -void Game::round_update_discard() { - Tile discarded_tile = players[current_player].last_discard(); - - std::map<int, Actions> possible_actions; - - // Construct and send state to each client. - PlayerNum player = 0; - do { - PlayerState state[4]; - - state[0] = players[player].get_state(); - state[1] = players[player + 1].get_state_filtered(); - state[2] = players[player + 2].get_state_filtered(); - state[3] = players[player + 3].get_state_filtered(); - - Actions a; - if(player != current_player) { - if(a = players[player].get_actions_discard(discarded_tile, current_player - player)) { - possible_actions[player] = a; - } - } - - GameState gstate = {dora, current_player - player, round_wind, round_num, 0, 0}; - - players[player].client->round_state(state[0], state[1], state[2], state[3], gstate, a); - } while(++player); - - preceding_action = Action::Pass; - if(possible_actions.empty()) { - awaiting_players = 1; - handle_action_discard(Action::Pass, 0); - } else { - awaiting_players = possible_actions.size(); - for(std::map<int, Actions>::iterator it = possible_actions.begin(); it != possible_actions.end(); it++) { - players[it->first].client->get_action(boost::bind(&Game::handle_action_discard, shared_from_this(), _1, it->first), it->second); - } - } -} - -void Game::handle_action_draw(Action action) { - switch(action.type) { - case Action::Discard: { - players[current_player].discard(action.target_offset); - if(kan_dora_pending) { - kan_dora_pending = false; - dora.push_back(wall.take_one()); - } - round_update_discard(); - } break; - - case Action::Tsumo: { - players[current_player].declare_tsumo(); - round_end(Tsumo); - } break; - - case Action::Riichi: { - players[current_player].declare_riichi(); - round_update_draw(); - } break; - - case Action::Kan: { - if(action.target_type == Action::Index) { - players[current_player].make_kan(action.target_offset - 2); - dora.push_back(wall.take_one()); - } else { - players[current_player].make_kan_extend(action.target_offset); - kan_dora_pending = true; - } - players[current_player].draw(wall.take_one()); - round_update_draw(); - } break; - - case Action::Draw: - // Not implemented yet. - - // Will never occur on draw: - case Action::Pass: - case Action::Chi: - case Action::Pon: - case Action::Ron: - break; - } -} - -void Game::handle_action_discard(Action action, int player) { - switch(preceding_action.type) { - case Action::Pass: - - case Action::Chi: - if(action.type == Action::Chi) { - preceding_action = action; - preceding_action_owner = player; - break; - } - - case Action::Kan: - if(action.type == Action::Kan) { - preceding_action = action; - preceding_action_owner = player; - break; - } - - case Action::Pon: - if(action.type == Action::Pon) { - preceding_action = action; - preceding_action_owner = player; - break; - } - - // First ron. - if(action.type == Action::Ron) { - preceding_action = action; - preceding_action_owner = player; - break; - } - - // Multiple ron. - case Action::Ron: - if(action.type == Action::Ron && current_player - player > current_player - preceding_action_owner) { - preceding_action = action; - preceding_action_owner = player; - break; - } - break; - - // Will never occur on discard: - case Action::Discard: - case Action::Riichi: - case Action::Tsumo: - case Action::Draw: - break; - } - - if(--awaiting_players) { - return; - } - - switch(preceding_action.type) { - case Action::Pass: { - // Tile not claimed, next player draws. - - // Check if the wall has run out. - if(wall.remaining() <= 14) { - round_end(Draw); - break; - } - - players[++current_player].draw(wall.take_one()); - round_update_draw(); - } break; - - case Action::Chi: { - players[preceding_action_owner].make_chi(players[current_player].claim(), preceding_action.target_offset); - current_player = preceding_action_owner; - round_update_draw(); - } break; - - case Action::Pon: { - players[preceding_action_owner].make_pon(players[current_player].claim(), preceding_action.target_offset - 1, current_player - preceding_action_owner); - current_player = preceding_action_owner; - round_update_draw(); - } break; - - case Action::Kan: { - players[preceding_action_owner].make_kan(players[current_player].claim(), preceding_action.target_offset - 2, current_player - preceding_action_owner); - current_player = preceding_action_owner; - kan_dora_pending = true; - players[current_player].draw(wall.take_one()); - round_update_draw(); - } break; - - case Action::Ron: { - players[preceding_action_owner].declare_ron(players[current_player].claim()); - round_end(Ron); - } break; - - // Will never occur on discard: - case Action::Discard: - case Action::Riichi: - case Action::Tsumo: - case Action::Draw: - break; - } -} - -Tiles merge_hand_open(const Tiles& hand, const Sets& open) { - Tiles tiles = hand; - for(Sets::const_iterator it = open.begin(); it != open.end(); it++) { - tiles.insert(tiles.end(), it->tiles.begin(), it->tiles.end()); - } - return tiles; -} - -void Game::round_end(Endcondition end) { - - Message::RoundEnd::p msg[4] = make_shared<Message::RoundEnd>(); - - for(CyclicInt<4> count_player = 0; count_player < 4; count_player++) { - msg[count_player]->total_han = msg[count_player]->total_fu = msg[count_player]->won = msg[count_player]->score[count_player].won = 0; - for(int i = 0; i < 4; i++) { - msg[count_player]->score[count_player + i].score = players[count_player + i].get_state().score; - msg[count_player]->score[count_player + i].won = 0; - } - - switch(end) { - case Draw: - //msg->total_han = msg->total_fu = msg->won = 0; - break; - - case Tsumo: { - Player& player = players[current_player]; - - msg[count_player]->hand = merge_hand_open(player.hand, player.open); - - msg[count_player]->yakus = player.won_han; - - msg[count_player]->total_han = player.won_value.han(); - msg[count_player]->total_fu = player.won_value.fu_rounded(); - - if(current_player == round_num) { - msg[count_player]->won = 3 * player.won_value.tsumo_east(); - - for(int y = 0; y < 4; y++) { - msg[count_player]->score[current_player + y].won = -(msg[count_player]->won / 3); - } - msg[count_player]->score[count_player + current_player ].won = msg[count_player]->won; - - } else { - msg[count_player]->won = player.won_value.tsumo_east() + 2 * player.won_value.tsumo(); - - for(int y = 0; y < 4; y++) { - if(count_player + y == current_player) { - msg[count_player]->score[y].won = msg[count_player]->won; - } else if (count_player + y == round_num){ - msg[count_player]->score[y].won = -(player.won_value.tsumo_east()); - } else { - msg[count_player]->score[y].won = -(player.won_value.tsumo()); - } - } - } - - } break; - - case Ron: - for(int i = 0; i < 4; i++) { - if(players[current_player + i].won) { - Player& player = players[current_player + i]; - - msg[count_player]->hand = merge_hand_open(player.hand, player.open); - - msg[count_player]->yakus = player.won_han; - - msg[count_player]->total_han = player.won_value.han(); - msg[count_player]->total_fu = player.won_value.fu_rounded(); - - if(current_player + i == round_num) { - msg[count_player]->won = player.won_value.ron_east(); - msg[count_player]->score[current_player + i].won = player.won_value.ron_east(); - msg[count_player]->score[current_player].won = -(player.won_value.ron_east()); - - } else { - msg[count_player]->won = player.won_value.ron(); - msg[count_player]->score[current_player + i].won = player.won_value.ron(); - msg[count_player]->score[current_player].won = -(player.won_value.ron()); - } - - // TODO: Support multiple wins. - break; - } - } - break; - } - - //Send med score - msg[count_player]->game_end = false; - if(count_player == 3) break; - } - - round_num++; - - if(!round_num) { - round_wind++; - //Do a 4-round game for now - for(int i = 0; i < 4; ++i) { - msg[i]->game_end = true; - players[i].client->round_end(msg[i], 0); - } - game_end(); - } else { - awaiting_players = 4; - players[0].client->round_end(msg[0], boost::bind(&Game::handle_ready, shared_from_this())); - players[1].client->round_end(msg[1], boost::bind(&Game::handle_ready, shared_from_this())); - players[2].client->round_end(msg[2], boost::bind(&Game::handle_ready, shared_from_this())); - players[3].client->round_end(msg[3], boost::bind(&Game::handle_ready, shared_from_this())); - } - - // Ferdig? game_end() -} - -void Game::game_end() { - Message::GameEnd::p msg = make_shared<Message::GameEnd>(); - for(int i = 0; i < 4; i++) { - msg->scores[i].score = players[i].score; - msg->scores[i].won = players[i].score - 25000; - } - - awaiting_players = 4; - players[0].client->game_end(msg, boost::bind(&Game::handle_ready, shared_from_this())); - players[1].client->game_end(msg, boost::bind(&Game::handle_ready, shared_from_this())); - players[2].client->game_end(msg, boost::bind(&Game::handle_ready, shared_from_this())); - players[3].client->game_end(msg, boost::bind(&Game::handle_ready, shared_from_this())); - - -} |