#include "hand.h" bool Hand::agari(const Tiles& tiles) { return basic_format(tiles); } bool Hand::basic_format(const Tiles& tiles, bool pair_eaten) { if(!tiles) { return true; // All tiles eaten. } if(!pair_eaten) { if(Tiles rest = eat_pair(tiles)) { if(basic_format(rest, true)) { return true; } } } if(tiles.size() < 3) { return false; } if(Tiles rest = eat_pon(tiles)) { if(basic_format(rest, pair_eaten)) { return true; } } if(Tiles rest = eat_chi(tiles)) { return basic_format(rest, pair_eaten); } return false; } Tiles Hand::eat_pair(Tiles tiles) { if(tiles[0] == tiles[1]) { tiles.erase(tiles.begin(), tiles.begin() + 2); return tiles; } return Tiles(); } Tiles Hand::eat_pon(Tiles tiles) { if(tiles[0] == tiles[2]) { tiles.erase(tiles.begin(), tiles.begin() + 3); return tiles; } return Tiles(); } Tiles Hand::eat_chi(Tiles tiles) { 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 Tiles(); } 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 tiles; } } return Tiles(); }