Advertisement
Guest User

Chutes & Ladders

a guest
Jan 21st, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.43 KB | None | 0 0
  1. // compile with "g++ -std=c++11 game.cpp"
  2. #include <utility>
  3. #include <vector>
  4. #include <string>
  5. #include <random>
  6. #include <map>
  7. #include <iostream>
  8. #include <functional>
  9. #include <cstdlib>
  10.  
  11. class Player
  12. {
  13.   public:
  14.     Player(const std::string &name) : name(name), location(0), encounteredChutes(0), encounteredLadders(0) {}
  15.  
  16.     std::string getName() const
  17.     {
  18.         return name;
  19.     }
  20.  
  21.     int getLocation() const
  22.     {
  23.         return location;
  24.     }
  25.  
  26.     void setLocation(int newLocation)
  27.     {
  28.         location = newLocation;
  29.     }
  30.  
  31.     int getEncounteredLadders() const
  32.     {
  33.         return encounteredLadders;
  34.     }
  35.  
  36.     void incEncounteredLadders()
  37.     {
  38.         encounteredLadders++;
  39.     }
  40.  
  41.     int getEncounteredChutes() const
  42.     {
  43.         return encounteredChutes;
  44.     }
  45.  
  46.     void incEncounteredChutes()
  47.     {
  48.         encounteredChutes++;
  49.     }
  50.  
  51.   private:
  52.     std::string name;
  53.     int location;
  54.     int encounteredLadders;
  55.     int encounteredChutes;
  56. };
  57.  
  58. class Game
  59. {
  60.   public:
  61.     Game()
  62.     {
  63.         // 不知道要不要随机设置ladders 和 chutes?
  64.         ladders = std::vector<std::pair<int, int>>{
  65.             {1, 3},
  66.             {8, 11},
  67.             {20, 33},
  68.             {33, 44},
  69.             {55, 88},
  70.             {70, 90},
  71.         };
  72.         chutes = std::vector<std::pair<int, int>>{
  73.             {10, 4},
  74.             {30, 21},
  75.             {66, 53},
  76.             {80, 71},
  77.             {89, 67},
  78.         };
  79.     }
  80.  
  81.     // 原文是“requires a player name and location”, 但是我感觉得接收一个player才行。。不然没法记录ladder/chutes的历史(把历史信息包成tuple作为返回值返回的话有点坑)
  82.     void turn(Player &player)
  83.     {
  84.         std::string playerName = player.getName();
  85.         int curLocation = player.getLocation();
  86.  
  87.         int spinNum = spin();
  88.         int newLocation = curLocation + spinNum;
  89.  
  90.         // If a player is on square 95 or higher, then a spin which takes them past 100 must be ignored
  91.         // 直接按原文翻译是这样, 不知道要不要考虑95以上有chute的情况。。。
  92.         if (newLocation > 100)
  93.         {
  94.             std::cout << playerName << " remains at " << curLocation << " after spin as " << spinNum << "\n";
  95.             return;
  96.         }
  97.  
  98.         std::cout << playerName << " moved:" << curLocation << "==>" << newLocation << " after spin as " << spinNum << "\n";
  99.         newLocation = handleLadders(player, newLocation);
  100.         newLocation = handleChutes(player, newLocation);
  101.         player.setLocation(newLocation);
  102.     }
  103.  
  104.     bool winner(Player &player)
  105.     {
  106.         int curLocation = player.getLocation();
  107.         if (curLocation < 100)
  108.         {
  109.             return false;
  110.         }
  111.  
  112.         std::cout << player.getName()
  113.                   << " is the winner! He/She encountered "
  114.                   << player.getEncounteredLadders()
  115.                   << " ladders and "
  116.                   << player.getEncounteredChutes()
  117.                   << " chutes \n";
  118.         return true;
  119.     }
  120.  
  121.   private:
  122.     int spin()
  123.     {
  124.         auto gen = std::mt19937{std::random_device{}()};
  125.         std::uniform_int_distribution<std::mt19937::result_type> dist{1, 6};
  126.         return dist(gen);
  127.     }
  128.  
  129.     int handleLadders(Player &player, int curLocation)
  130.     {
  131.         for (auto &ladder : ladders)
  132.         {
  133.             if (ladder.first == curLocation)
  134.             {
  135.                 player.incEncounteredLadders();
  136.                 std::cout << player.getName() << " climbed up an ladder:" << ladder.first << "==>" << ladder.second << "\n";
  137.                 return handleLadders(player, ladder.second);
  138.             }
  139.         }
  140.         return curLocation;
  141.     }
  142.  
  143.     int handleChutes(Player &player, int curLocation)
  144.     {
  145.         for (auto &chute : chutes)
  146.         {
  147.             if (chute.first == curLocation)
  148.             {
  149.                 player.incEncounteredChutes();
  150.                 std::cout << player.getName() << " fall through an chute:" << chute.first << "==>" << chute.second << "\n";
  151.                 return handleChutes(player, chute.second);
  152.             }
  153.         }
  154.         return curLocation;
  155.     }
  156.  
  157.   private:
  158.     std::vector<std::pair<int, int>> ladders;
  159.     std::vector<std::pair<int, int>> chutes;
  160. };
  161.  
  162. int main(int argc, char **argv)
  163. {
  164.     std::cout << "Please enter number of players [2-6]:";
  165.     int numberOfPlayers;
  166.     std::cin >> numberOfPlayers;
  167.     if (numberOfPlayers < 2 || numberOfPlayers > 6)
  168.     {
  169.         std::cerr << "number of players must be within [2-6]! You entered:" << numberOfPlayers << "\n";
  170.         return 1;
  171.     }
  172.  
  173.     std::vector<Player> players;
  174.     for (int i = 1; i != numberOfPlayers + 1; ++i)
  175.     {
  176.         std::cout << "Please enter name of player " << i << ":";
  177.         std::string playerName;
  178.         std::cin >> playerName;
  179.         players.emplace_back(playerName);
  180.     }
  181.  
  182.     auto gen = std::mt19937{std::random_device{}()};
  183.     std::uniform_int_distribution<std::mt19937::result_type> dist{0, std::mt19937::result_type(players.size()) - 1};
  184.     int nextPlayerIndex = dist(gen);
  185.  
  186.     Game game = Game{};
  187.     bool gameEnded = false;
  188.  
  189.     while (!gameEnded)
  190.     {
  191.         auto &player = players[nextPlayerIndex];
  192.         nextPlayerIndex = (nextPlayerIndex + 1) % players.size();
  193.  
  194.         game.turn(player);
  195.         if ((gameEnded = game.winner(player)))
  196.         {
  197.             break;
  198.         }
  199.     }
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement