summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2010-12-11 07:18:01 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2010-12-11 07:18:01 +0100
commit2d45eeee80586ae21d4aeae5b19f08d722e2cc7d (patch)
tree1aeea4f93220af13d3635dea66694e8618cff81e
parentfc4b974402a47f99ee08f5fe5520e2755c7b1dd7 (diff)
Added Player::calculate_score().
-rw-r--r--server/player.cpp98
-rw-r--r--server/player.h4
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