fork(1) download
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <random>
  5. #include <regex>
  6. #include <boost/lexical_cast.hpp>
  7. #include <boost/format.hpp>
  8. #include <boost/range/algorithm/stable_partition.hpp>
  9.  
  10. static constexpr char ErrorThatHandIsNotImplemented[] = "その手は実装されていません。";
  11.  
  12. enum class Hand
  13. {
  14. Rock = 0, // グー
  15. Scissors, // チョキ
  16. Paper, // パー
  17. First = Rock,
  18. Last = Paper
  19. };
  20.  
  21. std::ostream& operator<<(std::ostream& os, Hand hand)
  22. {
  23. switch (hand)
  24. {
  25. case Hand::Rock:
  26. os << "グー";
  27. break;
  28. case Hand::Scissors:
  29. os << "チョキ";
  30. break;
  31. case Hand::Paper:
  32. os << "パー";
  33. break;
  34. default:
  35. throw std::runtime_error(ErrorThatHandIsNotImplemented);
  36. }
  37.  
  38. return os;
  39. }
  40.  
  41. class Player
  42. {
  43. public:
  44. Player() = default;
  45. Player(const std::string& name, Hand hand);
  46.  
  47. std::string GetName() const;
  48.  
  49. Hand GetHand() const;
  50. void SetHand(Hand hand);
  51.  
  52. friend std::ostream& operator<<(std::ostream& os, const Player& player);
  53.  
  54. private:
  55. std::string name_;
  56. Hand hand_;
  57. };
  58.  
  59. Player::Player(const std::string& name, Hand hand)
  60. : name_(name), hand_(hand){ };
  61.  
  62. inline std::string Player::GetName() const
  63. {
  64. return name_;
  65. }
  66.  
  67. inline Hand Player::GetHand() const
  68. {
  69. return hand_;
  70. }
  71.  
  72. inline void Player::SetHand(Hand hand)
  73. {
  74. hand_ = hand;
  75. }
  76.  
  77. std::ostream& operator<<(std::ostream& os, const Player& player)
  78. {
  79. os << player.name_ << ": " << player.hand_;
  80. return os;
  81. }
  82.  
  83. std::size_t GetPlayerNumber()
  84. {
  85. std::size_t number = 0;
  86.  
  87. while (number == 0)
  88. {
  89. std::cout << "プレイヤーの人数を入力してください。: ";
  90.  
  91. std::string input;
  92. std::getline(std::cin, input);
  93. if (std::regex_match(input, std::regex("[\\d]+")))
  94. {
  95. number = boost::lexical_cast<std::size_t>(input);
  96. }
  97. }
  98.  
  99. return number;
  100. }
  101.  
  102. std::vector<Player> MakePlayers(std::size_t number)
  103. {
  104. std::vector<Player> players;
  105.  
  106. for (std::size_t i = 0; i < number; ++i)
  107. {
  108. // 最初はグー(初期値的な意味で)
  109. players.emplace_back((boost::format("プレイヤー%1%") % (i + 1)).str(), Hand::Rock);
  110. }
  111.  
  112. return players;
  113. }
  114.  
  115. void RemoveLosers(std::vector<Player>& players, Hand winners_hand)
  116. {
  117. auto pos = boost::stable_partition(players, [winners_hand](Player& player)
  118. {
  119. return player.GetHand() == winners_hand;
  120. });
  121.  
  122. players.erase(pos, std::end(players));
  123. };
  124.  
  125. void Janken(std::vector<Player>& players)
  126. {
  127. std::random_device seed_gen;
  128. std::mt19937 rand_engine(seed_gen());
  129. std::uniform_int_distribution<int> rand_dist(static_cast<int>(Hand::First), static_cast<int>(Hand::Last));
  130.  
  131. std::size_t round = 1;
  132.  
  133. // 最後の独りになるまで戦え……
  134. while (players.size() != 1)
  135. {
  136. std::cout << std::endl;
  137. std::cout << "第" << round << "回戦" << std::endl;
  138. ++round;
  139.  
  140. for (auto& player : players)
  141. {
  142. player.SetHand(static_cast<Hand>(rand_dist(rand_engine)));
  143. }
  144.  
  145. std::size_t rock_players_counter = 0;
  146. std::size_t scissors_players_counter = 0;
  147. std::size_t paper_players_counter = 0;
  148.  
  149. for (auto& player : players)
  150. {
  151. std::cout << player << std::endl;
  152.  
  153. switch (player.GetHand())
  154. {
  155. case Hand::Rock:
  156. ++rock_players_counter;
  157. break;
  158. case Hand::Scissors:
  159. ++scissors_players_counter;
  160. break;
  161. case Hand::Paper:
  162. ++paper_players_counter;
  163. break;
  164. default:
  165. throw std::runtime_error(ErrorThatHandIsNotImplemented);
  166. }
  167. }
  168.  
  169. if ((rock_players_counter == players.size()) ||
  170. (scissors_players_counter == players.size()) ||
  171. (paper_players_counter == players.size()))
  172. {
  173. // あいこ
  174. }
  175. else
  176. {
  177. if (rock_players_counter == 0)
  178. {
  179. // グーがいなければ、チョキのプレイヤーだけ生き残り
  180. RemoveLosers(players, Hand::Scissors);
  181. }
  182. else if (scissors_players_counter == 0)
  183. {
  184. // チョキがいなければ、パーのプレイヤーだけ生き残り
  185. RemoveLosers(players, Hand::Paper);
  186. }
  187. else if (paper_players_counter == 0)
  188. {
  189. // パーがいなければ、グーのプレイヤーだけ生き残り
  190. RemoveLosers(players, Hand::Rock);
  191. }
  192. else
  193. {
  194. // あいこ
  195. }
  196. }
  197. }
  198.  
  199. std::cout << std::endl;
  200. std::cout << "勝者: " << players[0].GetName() << std::endl;
  201. }
  202.  
  203. int main()
  204. {
  205. int result = 0;
  206.  
  207. try
  208. {
  209. std::size_t number = GetPlayerNumber();
  210.  
  211. std::vector<Player> players = MakePlayers(number);
  212.  
  213. Janken(players);
  214. }
  215. catch(const std::exception& ex)
  216. {
  217. std::cout << "ゲームを継続できません。" << std::endl;
  218. std::cout << ex.what() << std::endl;
  219.  
  220. result = 1;
  221. }
  222.  
  223. std::cout << "Enterキーを押すと終了します。" << std::endl;
  224. std::string ignore;
  225. std::getline(std::cin, ignore);
  226. return result;
  227. }
  228.  
Success #stdin #stdout 0s 3604KB
stdin
5
stdout
プレイヤーの人数を入力してください。: 
第1回戦
プレイヤー1: パー
プレイヤー2: チョキ
プレイヤー3: グー
プレイヤー4: パー
プレイヤー5: グー

第2回戦
プレイヤー1: グー
プレイヤー2: パー
プレイヤー3: チョキ
プレイヤー4: グー
プレイヤー5: パー

第3回戦
プレイヤー1: パー
プレイヤー2: グー
プレイヤー3: チョキ
プレイヤー4: グー
プレイヤー5: グー

第4回戦
プレイヤー1: チョキ
プレイヤー2: パー
プレイヤー3: グー
プレイヤー4: パー
プレイヤー5: パー

第5回戦
プレイヤー1: チョキ
プレイヤー2: パー
プレイヤー3: グー
プレイヤー4: パー
プレイヤー5: グー

第6回戦
プレイヤー1: チョキ
プレイヤー2: グー
プレイヤー3: パー
プレイヤー4: グー
プレイヤー5: チョキ

第7回戦
プレイヤー1: グー
プレイヤー2: チョキ
プレイヤー3: グー
プレイヤー4: パー
プレイヤー5: パー

第8回戦
プレイヤー1: パー
プレイヤー2: グー
プレイヤー3: パー
プレイヤー4: チョキ
プレイヤー5: グー

第9回戦
プレイヤー1: チョキ
プレイヤー2: チョキ
プレイヤー3: グー
プレイヤー4: チョキ
プレイヤー5: パー

第10回戦
プレイヤー1: グー
プレイヤー2: チョキ
プレイヤー3: グー
プレイヤー4: グー
プレイヤー5: パー

第11回戦
プレイヤー1: パー
プレイヤー2: チョキ
プレイヤー3: チョキ
プレイヤー4: チョキ
プレイヤー5: グー

第12回戦
プレイヤー1: グー
プレイヤー2: パー
プレイヤー3: チョキ
プレイヤー4: パー
プレイヤー5: グー

第13回戦
プレイヤー1: チョキ
プレイヤー2: グー
プレイヤー3: グー
プレイヤー4: パー
プレイヤー5: グー

第14回戦
プレイヤー1: パー
プレイヤー2: パー
プレイヤー3: チョキ
プレイヤー4: チョキ
プレイヤー5: パー

第15回戦
プレイヤー3: グー
プレイヤー4: パー

勝者: プレイヤー4
Enterキーを押すと終了します。