summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/game.cpp67
-rw-r--r--server/game.h8
2 files changed, 74 insertions, 1 deletions
diff --git a/server/game.cpp b/server/game.cpp
index 268439f..65d5cf2 100644
--- a/server/game.cpp
+++ b/server/game.cpp
@@ -324,6 +324,10 @@ Actions Game::Player::get_actions_draw() {
// Check if player can force a draw.
// Check if player can tsumo.
+ if(can_tsumo()) {
+ possible_actions.push_back(Action(Action::Tsumo));
+ }
+
// Check if player can declare a concealed kan or extend an open pon. List all possibilities.
if(!riichi) {
@@ -369,6 +373,9 @@ Actions Game::Player::get_actions_discard(Tile tile, PlayerNum discarder) {
}
// Check if tile can be ron-ed.
+ if(can_ron(tile)) {
+ possible_actions.push_back(Action(Action::Ron));
+ }
// If any action is possible, add option to pass.
if(possible_actions) {
@@ -442,6 +449,66 @@ bool Game::Player::can_kan(Tile tile, int target) {
return false;
}
+//! Recursive function that eats away sets from a hand to determine if it's valid or not.
+bool complete_hand(Tiles tiles, bool pair_eaten = false) {
+ if(!tiles) {
+ return true; // All tiles eaten.
+ }
+
+ if(tiles[0] == tiles[1]) {
+ if(!pair_eaten) {
+ // We can eat a pair of tiles.
+ Tiles t = tiles;
+ t.erase(t.begin(), t.begin() + 2);
+ if(complete_hand(t, true)) {
+ return true;
+ }
+ }
+
+ if(tiles[1] == tiles[2]) {
+ // We can eat a pon of tiles.
+ Tiles t = tiles;
+ t.erase(t.begin(), t.begin() + 3);
+ if(complete_hand(t, pair_eaten)) {
+ return true;
+ }
+ }
+ }
+
+ Tile::Set set = tiles[0].get_set();
+ int num = tiles[0].get_num();
+
+ if(set == Tile::Honor || num > 7) {
+ // Can't be chi-ed.
+ return false;
+ }
+
+ Tiles::iterator it1 = std::find(tiles.begin(), tiles.end(), Tile(set, num + 1));
+ if(it1 != tiles.end()) {
+ Tiles::iterator it2 = std::find(tiles.begin(), tiles.end(), Tile(set, num + 2));
+ if(it2 != tiles.end()) {
+ // We can eat a chi of tiles.
+ tiles.erase(it2);
+ tiles.erase(it1);
+ tiles.erase(tiles.begin());
+ return complete_hand(tiles, pair_eaten);
+ }
+ }
+
+ return false;
+}
+
+bool Game::Player::can_tsumo() {
+ return complete_hand(hand);
+}
+
+bool Game::Player::can_ron(Tile tile) {
+ Tiles tiles = hand;
+ tiles.push_back(tile);
+ tiles.sort();
+ return complete_hand(tiles);
+}
+
void Game::Player::draw(Tile tile) {
hand.push_back(tile);
}
diff --git a/server/game.h b/server/game.h
index 5613751..8bf89e8 100644
--- a/server/game.h
+++ b/server/game.h
@@ -59,9 +59,15 @@ class Game : public boost::enable_shared_from_this<Game> {
//! Check if it's possible to make a concealed kan or extend an open kan.
Targets can_kan();
- // Check if tile can be called to kan target.
+ //! Check if tile can be called to kan target.
bool can_kan(Tile tile, int target);
+ //! Check if hand is complete.
+ bool can_tsumo();
+
+ //! Check if tile can be called to complete hand.
+ bool can_ron(Tile tile);
+
//! Draw tile.
void draw(Tile tile);