Advertisement
Cinestra

Rabbits 3

Feb 9th, 2023
1,079
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.63 KB | None | 0 0
  1. // rabbits.cpp
  2.  
  3. // Portions you are to complete are marked with a TODO: comment.
  4. // We've provided some incorrect return statements (so indicated) just
  5. // to allow this skeleton program to compile and run, albeit incorrectly.
  6. // The first thing you probably want to do is implement the utterly trivial
  7. // functions (marked TRIVIAL).  Then get Arena::display going.  That gives
  8. // you more flexibility in the order you tackle the rest of the functionality.
  9. // As you finish implementing each TODO: item, remove its TODO: comment.
  10.  
  11. #include <iostream>
  12. #include <string>
  13. #include <random>
  14. #include <utility>
  15. #include <cstdlib>
  16. #include <cctype>
  17. using namespace std;
  18.  
  19. ///////////////////////////////////////////////////////////////////////////
  20. // Manifest constants
  21. ///////////////////////////////////////////////////////////////////////////
  22.  
  23. const int MAXROWS = 20;               // max number of rows in the arena
  24. const int MAXCOLS = 25;               // max number of columns in the arena
  25. const int MAXRABBITS = 100;           // max number of rabbits allowed
  26.  
  27. const int NORTH = 0;
  28. const int EAST = 1;
  29. const int SOUTH = 2;
  30. const int WEST = 3;
  31. const int NUMDIRS = 4;
  32.  
  33. const int EMPTY = 0;
  34. const int HAS_POISON = 1;
  35.  
  36. ///////////////////////////////////////////////////////////////////////////
  37. // Type definitions
  38. ///////////////////////////////////////////////////////////////////////////
  39.  
  40. class Arena;  // This is needed to let the compiler know that Arena is a
  41. // type name, since it's mentioned in the Rabbit declaration.
  42.  
  43. class Rabbit
  44. {
  45. public:
  46.     // Constructor
  47.     Rabbit(Arena* ap, int r, int c);
  48.  
  49.     // Accessors
  50.     int  row() const;
  51.     int  col() const;
  52.     bool isDead() const;
  53.  
  54.     // Mutators
  55.     void move();
  56.  
  57. private:
  58.     Arena* m_arena;
  59.     int    m_row;
  60.     int    m_col;
  61.     int m_poison_count;
  62.     bool m_slow_counter;
  63.     // TODO: You'll probably find that a rabbit object needs additional
  64.     // data members to support your implementation of the behavior affected
  65.     // by poisoned carrots.
  66. };
  67.  
  68. class Player
  69. {
  70. public:
  71.     // Constructor
  72.     Player(Arena* ap, int r, int c);
  73.  
  74.     // Accessors
  75.     int  row() const;
  76.     int  col() const;
  77.     bool isDead() const;
  78.  
  79.     // Mutators
  80.     string dropPoisonedCarrot();
  81.     string move(int dir);
  82.     void   setDead();
  83.  
  84. private:
  85.     Arena* m_arena;
  86.     int    m_row;
  87.     int    m_col;
  88.     bool   m_dead;
  89. };
  90.  
  91. class Arena
  92. {
  93. public:
  94.     // Constructor/destructor
  95.     Arena(int nRows, int nCols);
  96.     ~Arena();
  97.  
  98.     // Accessors
  99.     int     rows() const;
  100.     int     cols() const;
  101.     Player* player() const;
  102.     int     rabbitCount() const;
  103.     int     getCellStatus(int r, int c) const;
  104.     int     numberOfRabbitsAt(int r, int c) const;
  105.     void    display(string msg) const;
  106.  
  107.     // Mutators
  108.     void setCellStatus(int r, int c, int status);
  109.     bool addRabbit(int r, int c);
  110.     bool addPlayer(int r, int c);
  111.     void moveRabbits();
  112.  
  113. private:
  114.     int     m_grid[MAXROWS][MAXCOLS];
  115.     int     m_rows;
  116.     int     m_cols;
  117.     Player* m_player;
  118.     Rabbit* m_rabbits[MAXRABBITS];
  119.     int     m_nRabbits;
  120.     int     m_turns;
  121.  
  122.     // Helper functions
  123.     void checkPos(int r, int c, string functionName) const;
  124.     bool isPosInBounds(int r, int c) const;
  125. };
  126.  
  127. class Game
  128. {
  129. public:
  130.     // Constructor/destructor
  131.     Game(int rows, int cols, int nRabbits);
  132.     ~Game();
  133.  
  134.     // Mutators
  135.     void play();
  136.  
  137. private:
  138.     Arena* m_arena;
  139.  
  140.     // Helper functions
  141.     string takePlayerTurn();
  142. };
  143.  
  144. ///////////////////////////////////////////////////////////////////////////
  145. //  Auxiliary function declarations
  146. ///////////////////////////////////////////////////////////////////////////
  147.  
  148. int randInt(int lowest, int highest);
  149. bool decodeDirection(char ch, int& dir);
  150. bool attemptMove(const Arena& a, int dir, int& r, int& c);
  151. bool recommendMove(const Arena& a, int r, int c, int& bestDir);
  152. int assessRisk(const Arena& a, int row, int c);
  153. void clearScreen();
  154.  
  155. ///////////////////////////////////////////////////////////////////////////
  156. //  Rabbit implementation
  157. ///////////////////////////////////////////////////////////////////////////
  158.  
  159. Rabbit::Rabbit(Arena* ap, int r, int c)
  160. {
  161.     if (ap == nullptr)
  162.     {
  163.         cout << "***** A rabbit must be created in some Arena!" << endl;
  164.         exit(1);
  165.     }
  166.     if (r < 1 || r > ap->rows() || c < 1 || c > ap->cols())
  167.     {
  168.         cout << "***** Rabbit created with invalid coordinates (" << r << ","
  169.             << c << ")!" << endl;
  170.         exit(1);
  171.     }
  172.     m_arena = ap;
  173.     m_row = r;
  174.     m_col = c;
  175.     m_poison_count = 0;
  176.     m_slow_counter = 0;
  177. }
  178.  
  179. int Rabbit::row() const
  180. {
  181.     return m_row;
  182. }
  183.  
  184. int Rabbit::col() const
  185. {
  186.     return m_col;
  187. }
  188.  
  189. bool Rabbit::isDead() const
  190. {
  191.     // TODO: Return whether the Rabbit is dead
  192.  
  193.     if (m_poison_count == 2) {
  194.         return true;
  195.     }
  196.  
  197.     else {
  198.         return false;
  199.     }
  200. }
  201.  
  202. void Rabbit::move()
  203. {
  204.     // TODO:
  205.     //   Return without moving if the rabbit has eaten one poisoned
  206.     //   carrot (so is supposed to move only every other turn) and
  207.     //   this is a turn it does not move.
  208.  
  209.     //   Otherwise, attempt to move in a random direction; if can't
  210.     //   move, don't move.  If it lands on a poisoned carrot, eat the
  211.     //   carrot and remove it from the game (so it is no longer on that
  212.     //   grid point).
  213.  
  214.     if (m_poison_count == 1)
  215.         m_slow_counter = !m_slow_counter;
  216.  
  217.     if (m_slow_counter)
  218.         return;
  219.    
  220.     int random_direction = randInt(0, 3);
  221.  
  222.     attemptMove(*m_arena, random_direction, m_row, m_col);
  223.  
  224.     if (m_arena->getCellStatus(m_row, m_col) == HAS_POISON) {
  225.         m_arena->setCellStatus(m_row, m_col, EMPTY);
  226.         m_poison_count++;
  227.     }
  228. }
  229.  
  230. ///////////////////////////////////////////////////////////////////////////
  231. //  Player implementation
  232. ///////////////////////////////////////////////////////////////////////////
  233.  
  234. Player::Player(Arena* ap, int r, int c)
  235. {
  236.     if (ap == nullptr)
  237.     {
  238.         cout << "***** The player must be created in some Arena!" << endl;
  239.         exit(1);
  240.     }
  241.     if (r < 1 || r > ap->rows() || c < 1 || c > ap->cols())
  242.     {
  243.         cout << "**** Player created with invalid coordinates (" << r
  244.             << "," << c << ")!" << endl;
  245.         exit(1);
  246.     }
  247.     m_arena = ap;
  248.     m_row = r;
  249.     m_col = c;
  250.     m_dead = false;
  251. }
  252.  
  253. int Player::row() const
  254. {
  255.     return m_row;
  256. }
  257.  
  258. int Player::col() const
  259. {
  260.     return m_col;
  261. }
  262.  
  263. string Player::dropPoisonedCarrot()
  264. {
  265.     if (m_arena->getCellStatus(m_row, m_col) == HAS_POISON)
  266.         return "There's already a poisoned carrot at this spot.";
  267.     m_arena->setCellStatus(m_row, m_col, HAS_POISON);
  268.     return "A poisoned carrot has been dropped.";
  269. }
  270.  
  271. string Player::move(int dir)
  272. {
  273.     // TODO:  Attempt to move the player one step in the indicated
  274.     //        direction.  If this fails,
  275.     //        return "Player couldn't move; player stands."
  276.     //        A player who moves onto a rabbit, and this
  277.     //        returns "Player walked into a rabbit and died."
  278.     //        Otherwise, return one of "Player moved north.",
  279.     //        "Player moved east.", "Player moved south.", or
  280.     //        "Player moved west."
  281.  
  282.     if (attemptMove(*m_arena, dir, m_row, m_col))
  283.     {
  284.         if (m_arena->numberOfRabbitsAt(m_row, m_col) > 0)
  285.         {
  286.             setDead();
  287.             return "Player walked into a rabbit and died";
  288.         }
  289.  
  290.         if (dir == NORTH)
  291.             return "Player moved north. ";
  292.         else if (dir == EAST)
  293.             return "Player moved east. ";
  294.         else if (dir == WEST)
  295.             return "Player moved west. ";
  296.         else if (dir == SOUTH)
  297.             return "Player moved south. ";
  298.     }
  299.  
  300.     return "Player couldn't move; player stands.";
  301.  
  302. }
  303.  
  304. bool Player::isDead() const
  305. {
  306.     // TODO: Return whether the Player is dead
  307.     // Delete the following line and replace it with the correct code.
  308.     return m_dead;  // This implementation compiles, but is incorrect.
  309. }
  310.  
  311. void Player::setDead()
  312. {
  313.     m_dead = true;
  314. }
  315.  
  316. ///////////////////////////////////////////////////////////////////////////
  317. //  Arena implementation
  318. ///////////////////////////////////////////////////////////////////////////
  319.  
  320. Arena::Arena(int nRows, int nCols)
  321. {
  322.     if (nRows <= 0 || nCols <= 0 || nRows > MAXROWS || nCols > MAXCOLS)
  323.     {
  324.         cout << "***** Arena created with invalid size " << nRows << " by "
  325.             << nCols << "!" << endl;
  326.         exit(1);
  327.     }
  328.     m_rows = nRows;
  329.     m_cols = nCols;
  330.     m_player = nullptr;
  331.     m_nRabbits = 0;
  332.     m_turns = 0;
  333.     for (int r = 1; r <= m_rows; r++)
  334.         for (int c = 1; c <= m_cols; c++)
  335.             setCellStatus(r, c, EMPTY);
  336. }
  337.  
  338. Arena::~Arena()
  339. {
  340.     // TODO:  Deallocate the player and all remaining dynamically allocated
  341.     //        rabbits.
  342.  
  343.     delete m_player;
  344.  
  345.     for (int i = 0; i < m_nRabbits; i++)
  346.     {
  347.         delete m_rabbits[i];
  348.     }
  349.     // Delete each entry in the array of pointers to Rabbits
  350. }
  351.  
  352. int Arena::rows() const
  353. {
  354.     // TODO: TRIVIAL:  Return the number of rows in the arena
  355.     // Delete the following line and replace it with the correct code.
  356.     return m_rows;
  357. }
  358.  
  359. int Arena::cols() const
  360. {
  361.     // TODO: TRIVIAL:  Return the number of columns in the arena
  362.     // Delete the following line and replace it with the correct code.
  363.     return m_cols;
  364. }
  365.  
  366. Player* Arena::player() const
  367. {
  368.     return m_player;
  369. }
  370.  
  371. int Arena::rabbitCount() const
  372. {
  373.     // TODO: TRIVIAL:  Return the number of rabbits in the arena
  374.     // Delete the following line and replace it with the correct code.
  375.     return m_nRabbits;
  376.  
  377. }
  378.  
  379. int Arena::getCellStatus(int r, int c) const
  380. {
  381.     checkPos(r, c, "Arena::getCellStatus");
  382.     return m_grid[r - 1][c - 1];
  383. }
  384.  
  385. int Arena::numberOfRabbitsAt(int r, int c) const
  386. {
  387.     // TODO:  Return the number of rabbits at row r, column c
  388.     // Delete the following line and replace it with the correct code.
  389.  
  390.     int count = 0;
  391.  
  392.     for (int i = 0; i < m_nRabbits; i++)
  393.     {
  394.         if ((m_rabbits[i]->row() == r && m_rabbits[i]->col() == c))
  395.             count++;
  396.     }
  397.  
  398.     return count;
  399. }
  400.  
  401. void Arena::display(string msg) const
  402. {
  403.     char displayGrid[MAXROWS][MAXCOLS];
  404.     int r, c;
  405.  
  406.     // Fill displayGrid with dots (empty) and stars (poisoned carrots)
  407.     for (r = 1; r <= rows(); r++)
  408.         for (c = 1; c <= cols(); c++)
  409.             displayGrid[r - 1][c - 1] = (getCellStatus(r, c) == EMPTY ? '.' : '*');
  410.     // c = (a>b) ? a : b mean that if the expression being evaluated is true then a is returned whereas if it is false then b is returned
  411.  
  412.     // Indicate each rabbit's position
  413.     // TODO:  If one rabbit is at some grid point, set the displayGrid char
  414.     //        to 'R'.  If it's 2 though 8, set it to '2' through '8'.
  415.     //        For 9 or more, set it to '9'.
  416.  
  417.     for (r = 1; r <= rows(); r++)
  418.     {
  419.         for (c = 1; c <= cols(); c++)
  420.         {
  421.             int rabbit_count = numberOfRabbitsAt(r, c);
  422.  
  423.             if (rabbit_count == 1)
  424.                 displayGrid[r - 1][c - 1] = 'R';
  425.  
  426.             else if (rabbit_count >= 2 && rabbit_count < 9)
  427.                 displayGrid[r - 1][c - 1] = '0' + rabbit_count;
  428.                 // Trying to only print out rabbit_count will give out an ASCII character of the number
  429.  
  430.             else if (rabbit_count >= 9)
  431.                 displayGrid[r - 1][c - 1] = '9';
  432.         }
  433.     }
  434.  
  435.  
  436.     // Indicate the player's position
  437.     if (m_player != nullptr)
  438.         displayGrid[m_player->row() - 1][m_player->col() - 1] = (m_player->isDead() ? 'X' : '@');
  439.  
  440.     // Draw the grid
  441.     clearScreen();
  442.     for (r = 1; r <= rows(); r++)
  443.     {
  444.         for (c = 1; c <= cols(); c++)
  445.             cout << displayGrid[r - 1][c - 1];
  446.         cout << endl;
  447.     }
  448.     cout << endl;
  449.  
  450.     // Write message, rabbit, and player info
  451.     if (msg != "")
  452.         cout << msg << endl;
  453.     cout << "There are " << rabbitCount() << " rabbits remaining." << endl;
  454.     if (m_player == nullptr)
  455.         cout << "There is no player!" << endl;
  456.     else if (m_player->isDead())
  457.         cout << "The player is dead." << endl;
  458.     cout << m_turns << " turns have been taken." << endl;
  459. }
  460.  
  461. void Arena::setCellStatus(int r, int c, int status)
  462. {
  463.     checkPos(r, c, "Arena::setCellStatus");
  464.     m_grid[r - 1][c - 1] = status;
  465. }
  466.  
  467. bool Arena::addRabbit(int r, int c)
  468. {
  469.     if (!isPosInBounds(r, c))
  470.         return false;
  471.  
  472.     // Don't add a rabbit on a spot with a poisoned carrot
  473.     if (getCellStatus(r, c) != EMPTY)
  474.         return false;
  475.  
  476.     // Don't add a rabbit on a spot with a player
  477.     if (m_player != nullptr && m_player->row() == r && m_player->col() == c)
  478.         return false;
  479.  
  480.     // If there are MAXRABBITS existing rabbits, return false.  Otherwise,
  481.     // dynamically allocate a new rabbit at coordinates (r,c).  Save the
  482.     // pointer to newly allocated rabbit and return true.
  483.  
  484.     // TODO:  Implement this.
  485.  
  486.     if (rabbitCount() == MAXRABBITS)
  487.         return false;
  488.  
  489.     else
  490.     {
  491.         m_rabbits[m_nRabbits++] = new Rabbit(this, r, c);
  492.         return true;
  493.     }
  494. }
  495.  
  496. bool Arena::addPlayer(int r, int c)
  497. {
  498.     if (!isPosInBounds(r, c))
  499.         return false;
  500.  
  501.     // Don't add a player if one already exists
  502.     if (m_player != nullptr)
  503.         return false;
  504.  
  505.     // Don't add a player on a spot with a rabbit
  506.     if (numberOfRabbitsAt(r, c) > 0)
  507.         return false;
  508.  
  509.     m_player = new Player(this, r, c);
  510.     return true;
  511. }
  512.  
  513. void Arena::moveRabbits()
  514. {
  515.     // Move all rabbits
  516.     // TODO:  Move each rabbit.  Mark the player as dead if necessary.
  517.     //        Deallocate any dead dynamically allocated rabbit.
  518.  
  519.     // Another turn has been taken
  520.  
  521.     for (int i = 0; i < m_nRabbits; i++)
  522.     {
  523.         Rabbit* pointer_rabbit = m_rabbits[i];
  524.         // m_rabbits[(variable)] is an array of pointers to rabbits
  525.         // Create a pointer that will be able to manipulate a given rabbit
  526.  
  527.         pointer_rabbit->move();
  528.         // Now that the rabbit has moved, let's either see if it is dead or if it kills the player
  529.  
  530.         if (pointer_rabbit->isDead())
  531.         {
  532.             delete pointer_rabbit;
  533.             m_rabbits[i] = m_rabbits[m_nRabbits - 1];
  534.             m_nRabbits--;
  535.             i--;
  536.             continue;
  537.         }
  538.  
  539.         if (m_player->row() == pointer_rabbit->row() && m_player->col() == pointer_rabbit->col())
  540.         {
  541.             m_player->setDead();
  542.         }
  543.     }
  544.  
  545.     m_turns++;
  546. }
  547.  
  548. bool Arena::isPosInBounds(int r, int c) const
  549. {
  550.     return (r >= 1 && r <= m_rows && c >= 1 && c <= m_cols);
  551. }
  552.  
  553. void Arena::checkPos(int r, int c, string functionName) const
  554. {
  555.     if (!isPosInBounds(r, c))
  556.     {
  557.         cout << "***** " << "Invalid arena position (" << r << ","
  558.             << c << ") in call to " << functionName << endl;
  559.         exit(1);
  560.     }
  561. }
  562.  
  563. ///////////////////////////////////////////////////////////////////////////
  564. //  Game implementation
  565. ///////////////////////////////////////////////////////////////////////////
  566.  
  567. Game::Game(int rows, int cols, int nRabbits)
  568. {
  569.     if (nRabbits < 0)
  570.     {
  571.         cout << "***** Cannot create Game with negative number of rabbits!" << endl;
  572.         exit(1);
  573.     }
  574.     if (nRabbits > MAXRABBITS)
  575.     {
  576.         cout << "***** Trying to create Game with " << nRabbits
  577.             << " rabbits; only " << MAXRABBITS << " are allowed!" << endl;
  578.         exit(1);
  579.     }
  580.     int nEmpty = rows * cols - nRabbits - 1;  // 1 for Player
  581.     if (nEmpty < 0)
  582.     {
  583.         cout << "***** Game created with a " << rows << " by "
  584.             << cols << " arena, which is too small too hold a player and "
  585.             << nRabbits << " rabbits!" << endl;
  586.         exit(1);
  587.     }
  588.  
  589.     // Create arena
  590.     m_arena = new Arena(rows, cols);
  591.  
  592.     // Add player
  593.     int rPlayer;
  594.     int cPlayer;
  595.     do
  596.     {
  597.         rPlayer = randInt(1, rows);
  598.         cPlayer = randInt(1, cols);
  599.     } while (m_arena->getCellStatus(rPlayer, cPlayer) != EMPTY);
  600.     m_arena->addPlayer(rPlayer, cPlayer);
  601.  
  602.     // Populate with rabbits
  603.     while (nRabbits > 0)
  604.     {
  605.         int r = randInt(1, rows);
  606.         int c = randInt(1, cols);
  607.         if (r == rPlayer && c == cPlayer)
  608.             continue;
  609.         m_arena->addRabbit(r, c);
  610.         nRabbits--;
  611.     }
  612. }
  613.  
  614. Game::~Game()
  615. {
  616.     delete m_arena;
  617. }
  618.  
  619. string Game::takePlayerTurn()
  620. {
  621.     for (;;)
  622.     {
  623.         cout << "Your move (n/e/s/w/c or nothing): ";
  624.         string playerMove;
  625.         getline(cin, playerMove);
  626.  
  627.         Player* player = m_arena->player();
  628.         int dir;
  629.  
  630.         if (playerMove.size() == 0)
  631.         {
  632.             if (recommendMove(*m_arena, player->row(), player->col(), dir))
  633.                 return player->move(dir);
  634.             else
  635.                 return player->dropPoisonedCarrot();
  636.         }
  637.         else if (playerMove.size() == 1)
  638.         {
  639.             if (tolower(playerMove[0]) == 'c')
  640.                 return player->dropPoisonedCarrot();
  641.             else if (decodeDirection(playerMove[0], dir))
  642.                 return player->move(dir);
  643.         }
  644.         cout << "Player move must be nothing, or 1 character n/e/s/w/c." << endl;
  645.     }
  646. }
  647.  
  648. void Game::play()
  649. {
  650.     m_arena->display("");
  651.     Player* player = m_arena->player();
  652.     if (player == nullptr)
  653.         return;
  654.     while (!player->isDead() && m_arena->rabbitCount() > 0)
  655.     {
  656.         string msg = takePlayerTurn();
  657.         m_arena->display(msg);
  658.         if (player->isDead())
  659.             break;
  660.         m_arena->moveRabbits();
  661.         m_arena->display(msg);
  662.     }
  663.     if (player->isDead())
  664.         cout << "You lose." << endl;
  665.     else
  666.         cout << "You win." << endl;
  667. }
  668.  
  669. ///////////////////////////////////////////////////////////////////////////
  670. //  Auxiliary function implementation
  671. ///////////////////////////////////////////////////////////////////////////
  672.  
  673.   // Return a uniformly distributed random int from lowest to highest, inclusive
  674. int randInt(int lowest, int highest)
  675. {
  676.     if (highest < lowest)
  677.         swap(highest, lowest);
  678.     static random_device rd;
  679.     static default_random_engine generator(rd());
  680.     uniform_int_distribution<> distro(lowest, highest);
  681.     return distro(generator);
  682. }
  683.  
  684. bool decodeDirection(char ch, int& dir)
  685. {
  686.     switch (tolower(ch))
  687.     {
  688.     default:  return false;
  689.     case 'n': dir = NORTH; break;
  690.     case 'e': dir = EAST;  break;
  691.     case 's': dir = SOUTH; break;
  692.     case 'w': dir = WEST;  break;
  693.     }
  694.     return true;
  695. }
  696.  
  697. // Return false without changing anything if moving one step from (r,c)
  698. // in the indicated direction would run off the edge of the arena.
  699. // Otherwise, update r and c to the position resulting from the move and
  700. // return true.
  701. bool attemptMove(const Arena& a, int dir, int& r, int& c)
  702. {
  703.     // TODO:  Implement this function
  704.     // Delete the following line and replace it with the correct code.
  705.  
  706.     // To move up, you need to subtract rows. The first row is at the top. The last row is at the bottom.
  707.     // To move right, you need to add cols. The first col is at the left. The last row is at the right.
  708.  
  709.     // Check if it's trying to move within bounds, if it is then return false. If not then move accordingly.
  710.  
  711.     if (dir == NORTH) {
  712.         if (r <= 1) return false;
  713.         else r--;
  714.     }
  715.  
  716.     else if (dir == EAST) {
  717.         if (c >= a.cols()) return false;
  718.         else c++;
  719.     }
  720.  
  721.     else if (dir == WEST) {
  722.         if (c <= 1) return false;
  723.         else c--;
  724.     }
  725.  
  726.     else if (dir == SOUTH) {
  727.         if (r >= a.rows()) return false;
  728.         else r++;
  729.     }
  730.  
  731.     return true;
  732. }
  733.  
  734. // Recommend a move for a player at (r,c):  A false return means the
  735. // recommendation is that the player should drop a poisoned carrot and
  736. // not move; otherwise, this function sets bestDir to the recommended
  737. // direction to move and returns true.
  738. bool recommendMove(const Arena& a, int r, int c, int& bestDir)
  739. {
  740.     // TODO:  Implement this function
  741.     // Delete the following line and replace it with your code.
  742.  
  743.     int idle_risk = assessRisk(a, r, c);
  744.  
  745.     if (idle_risk == 0)
  746.         return false;
  747.    
  748.     int least_risk = idle_risk;
  749.  
  750.     int north_risk = assessRisk(a, r - 1, c);
  751.     int south_risk = assessRisk(a, r + 1, c);
  752.     int west_risk = assessRisk(a, r, c - 1);
  753.     int east_risk = assessRisk(a, r, c + 1);
  754.  
  755.     if (north_risk < least_risk && r != 1) {
  756.         least_risk = north_risk;
  757.         bestDir = NORTH;
  758.     }
  759.     if (south_risk < least_risk && r != a.rows()) {
  760.         least_risk = south_risk;
  761.         bestDir = SOUTH;
  762.     }
  763.     if (west_risk < least_risk && c!=1) {
  764.         least_risk = west_risk;
  765.         bestDir = WEST;
  766.     }
  767.     if (east_risk < least_risk && c!=a.cols()) {
  768.         least_risk = east_risk;
  769.         bestDir = EAST;
  770.     }
  771.  
  772.     // Now let's check if least risk is different from idle risk
  773.     // If it is different, then we would recommend moving
  774.     if (idle_risk != least_risk)
  775.     {
  776.         return true;
  777.     }
  778.  
  779.     // If it isn't different, simply return false.
  780.     return false;
  781.  
  782.     // Your replacement implementation should do something intelligent.
  783.     // You don't have to be any smarter than the following, although
  784.     // you can if you want to be:  If staying put runs the risk of a
  785.     // rabbit possibly moving onto the player's location when the rabbits
  786.     // move, yet moving in a particular direction puts the player in a
  787.     // position that is safe when the rabbits move, then the chosen
  788.     // action is to move to a safer location.  Similarly, if staying put
  789.     // is safe, but moving in certain directions puts the player in
  790.     // danger of dying when the rabbits move, then the chosen action should
  791.     // not be to move in one of the dangerous directions; instead, the player
  792.     // should stay put or move to another safe position.  In general, a
  793.     // position that may be moved to by many rabbits is more dangerous than
  794.     // one that may be moved to by few.
  795.     //
  796.     // Unless you want to, you do not have to take into account that a
  797.     // rabbit might be poisoned and thus sometimes less dangerous than one
  798.     // that is not.  That requires a more sophisticated analysis that
  799.     // we're not asking you to do.
  800. }
  801.  
  802. int assessRisk(const Arena& a, int row, int col)
  803. {
  804.  
  805.     int risk = 0;
  806.  
  807.     if (a.numberOfRabbitsAt(row, col) > 0)
  808.     {
  809.         risk += MAXRABBITS;
  810.         return risk;
  811.         // Do not move here lmao
  812.     }
  813.  
  814.     else
  815.     {
  816.         risk += a.numberOfRabbitsAt(row - 1, col); // Rabbits above indicated location
  817.         risk += a.numberOfRabbitsAt(row + 1, col); // Rabbits below indicated location
  818.         risk += a.numberOfRabbitsAt(row, col - 1); // Rabbits left of indicated location
  819.         risk += a.numberOfRabbitsAt(row, col + 1); //Rabbits right of indicated location
  820.  
  821.         return risk;
  822.     }
  823. }
  824.  
  825. ///////////////////////////////////////////////////////////////////////////
  826. // main()
  827. ///////////////////////////////////////////////////////////////////////////
  828.  
  829. int main()
  830. {
  831.     // Create a game
  832.     // Use this instead to create a mini-game:   Game g(3, 5, 2);
  833.     Game g(10, 12, 40);
  834.  
  835.     // Play the game
  836.     g.play();
  837. }
  838.  
  839. ///////////////////////////////////////////////////////////////////////////
  840. //  clearScreen implementation
  841. ///////////////////////////////////////////////////////////////////////////
  842.  
  843. // DO NOT MODIFY OR REMOVE ANYTHING BETWEEN HERE AND THE END OF THE FILE!!!
  844. // THE CODE IS SUITABLE FOR VISUAL C++, XCODE, AND g++/g31 UNDER LINUX.
  845.  
  846. // Note to Xcode users:  clearScreen() will just write a newline instead
  847. // of clearing the window if you launch your program from within Xcode.
  848. // That's acceptable.  (The Xcode output window doesn't have the capability
  849. // of being cleared.)
  850.  
  851. #ifdef _WIN32
  852.  
  853. #include <windows.h>
  854.  
  855. void clearScreen()
  856. {
  857.     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  858.     CONSOLE_SCREEN_BUFFER_INFO csbi;
  859.     GetConsoleScreenBufferInfo(hConsole, &csbi);
  860.     DWORD dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
  861.     COORD upperLeft = { 0, 0 };
  862.     DWORD dwCharsWritten;
  863.     FillConsoleOutputCharacter(hConsole, TCHAR(' '), dwConSize, upperLeft,
  864.         &dwCharsWritten);
  865.     SetConsoleCursorPosition(hConsole, upperLeft);
  866. }
  867.  
  868. #else  // not _WIN32
  869.  
  870. #include <iostream>
  871. #include <cstring>
  872. #include <cstdlib>
  873. using namespace std;
  874.  
  875. void clearScreen()  // will just write a newline in an Xcode output window
  876. {
  877.     static const char* term = getenv("TERM");
  878.     if (term == nullptr || strcmp(term, "dumb") == 0)
  879.         cout << endl;
  880.     else
  881.     {
  882.         static const char* ESC_SEQ = "\x1B[";  // ANSI Terminal esc seq:  ESC [
  883.         cout << ESC_SEQ << "2J" << ESC_SEQ << "H" << flush;
  884.     }
  885. }
  886.  
  887. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement