diff options
-rw-r--r-- | server/player.cpp | 98 | ||||
-rw-r--r-- | server/player.h | 4 |
2 files changed, 102 insertions, 0 deletions
diff --git a/server/player.cpp b/server/player.cpp index 7c48a80..27c4b73 100644 --- a/server/player.cpp +++ b/server/player.cpp @@ -2,6 +2,9 @@ #include "hand.h" +#include <boost/assign/list_of.hpp> +using boost::assign::list_of; + void Player::round_start(int w) { // Reset contents. hand.clear(); @@ -431,5 +434,100 @@ void Player::declare_ron(Tile tile) { } void Player::declare_tsumo() { + List<Sets> hands = Hand::get_breakdowns(hand); + + Sets hand = hands.front(); + hand.insert(hand.end(), open.begin(), open.end()); + + Score score = calculate_score(hand, true); + + std::cout << "Tsumo: " << score.han() << " han, " << score.fu << " fu: " << score.tsumo_east() << "/" << score.tsumo() << "." << std::endl; +} + +Score Player::calculate_score(const Sets& hand, bool tsumo) { + Tiles yakuhai = list_of(Tile::Chun)(Tile::Hatsu)(Tile::Haku); // TODO: Add seat and prevalent wind. + Tiles dora; // TODO: Fill this. + Tiles uradora; // TODO: Fill this. + + Score score(0, 20, 0); // Always 20 fu for winning. + + // Check riichi. + if(riichi) { + score.yaku += 1; + // TODO: Check ippatsu. + } + + // Check menzen tsumo. + if(tsumo && !open) { + score.yaku += 1; + } + + bool possible_tanyao = true; + bool possible_toitoi = true; + + for(Sets::const_iterator set = hand.begin(); set != hand.end(); set++) { + switch(set->type) { + case Set::Pair: + // Check for pair-related fu. + score.fu += yakuhai.count(set->tiles.front()); + + break; + + case Set::Chi: + // Toitoi can't contain chi. + possible_toitoi = false; + break; + + case Set::Pon: + case Set::Kan: + // Calculate fu. + score.fu += 2 << (!set->open + !set->tiles.front().is_simple() + 2 * (set->type == Set::Kan)); + + // Check yakuhai. + score.yaku += yakuhai.count(set->tiles.front()); + + break; + } + + for(Tiles::const_iterator tile = set->tiles.begin(); tile != set->tiles.end(); tile++) { + // Check tanyao. + if(!tile->is_simple()) { + possible_tanyao = false; + } + + // Check dora. + score.dora += dora.count(*tile); + + // Check uradora. + score.dora += uradora.count(*tile); + + // Check akadora. + if(tile->red) { + score.dora += 1; + } + } + } + + // Check tanyao. + if(possible_tanyao) { + score.yaku += 1; + } + + // Check toitoi. + if(possible_toitoi) { + score.yaku += 2; + } + + // Check pinfu. + if(score.fu == 20 && !open) { + score.yaku += 1; + } + + // Check fu for ron. + if(!tsumo && !open) { + // 10 fu for ron. + score.fu += 10; + } + return score; } diff --git a/server/player.h b/server/player.h index cf98231..ea17926 100644 --- a/server/player.h +++ b/server/player.h @@ -2,6 +2,7 @@ #define PLAYER_H #include "client.h" +#include "score.h" #include "../common/set.h" #include "../common/cyclicint.h" @@ -100,6 +101,9 @@ class Player { //! Declare win on self-drawn tile. void declare_tsumo(); + + //! Calculate score for winning hand combination. + Score calculate_score(const Sets& hand, bool tsumo); }; #endif |