Advertisement
Cinestra

Rabbits 2

Feb 9th, 2023
1,018
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.38 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 poison;
  62.     bool 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.     poison = 0;
  176.     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 (poison == 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 (poison == 1)
  215.         slow_counter != slow_counter;
  216.  
  217.     if (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.         poison++;
  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;  // This implementation compiles, but is incorrect.
  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.     int i = 0;
  522.  
  523.     while (i < m_nRabbits)
  524.     {
  525.         Rabbit* pointer_rabbit = m_rabbits[i];
  526.         pointer_rabbit->move();
  527.  
  528.         if (pointer_rabbit->isDead())
  529.         {
  530.             delete pointer_rabbit;
  531.             m_rabbits[i] = m_rabbits[m_nRabbits - 1];
  532.             m_nRabbits--;
  533.             continue;
  534.         }
  535.  
  536.         if (m_player->row() == pointer_rabbit->row() && m_player->col() == pointer_rabbit->col())
  537.         {
  538.             m_player->setDead();
  539.         }
  540.  
  541.         i++;
  542.     }
  543.  
  544.     m_turns++;
  545. }
  546.  
  547. bool Arena::isPosInBounds(int r, int c) const
  548. {
  549.     return (r >= 1 && r <= m_rows && c >= 1 && c <= m_cols);
  550. }
  551.  
  552. void Arena::checkPos(int r, int c, string functionName) const
  553. {
  554.     if (!isPosInBounds(r, c))
  555.     {
  556.         cout << "***** " << "Invalid arena position (" << r << ","
  557.             << c << ") in call to " << functionName << endl;
  558.         exit(1);
  559.     }
  560. }
  561.  
  562. ///////////////////////////////////////////////////////////////////////////
  563. //  Game implementation
  564. ///////////////////////////////////////////////////////////////////////////
  565.  
  566. Game::Game(int rows, int cols, int nRabbits)
  567. {
  568.     if (nRabbits < 0)
  569.     {
  570.         cout << "***** Cannot create Game with negative number of rabbits!" << endl;
  571.         exit(1);
  572.     }
  573.     if (nRabbits > MAXRABBITS)
  574.     {
  575.         cout << "***** Trying to create Game with " << nRabbits
  576.             << " rabbits; only " << MAXRABBITS << " are allowed!" << endl;
  577.         exit(1);
  578.     }
  579.     int nEmpty = rows * cols - nRabbits - 1;  // 1 for Player
  580.     if (nEmpty < 0)
  581.     {
  582.         cout << "***** Game created with a " << rows << " by "
  583.             << cols << " arena, which is too small too hold a player and "
  584.             << nRabbits << " rabbits!" << endl;
  585.         exit(1);
  586.     }
  587.  
  588.     // Create arena
  589.     m_arena = new Arena(rows, cols);
  590.  
  591.     // Add player
  592.     int rPlayer;
  593.     int cPlayer;
  594.     do
  595.     {
  596.         rPlayer = randInt(1, rows);
  597.         cPlayer = randInt(1, cols);
  598.     } while (m_arena->getCellStatus(rPlayer, cPlayer) != EMPTY);
  599.     m_arena->addPlayer(rPlayer, cPlayer);
  600.  
  601.     // Populate with rabbits
  602.     while (nRabbits > 0)
  603.     {
  604.         int r = randInt(1, rows);
  605.         int c = randInt(1, cols);
  606.         if (r == rPlayer && c == cPlayer)
  607.             continue;
  608.         m_arena->addRabbit(r, c);
  609.         nRabbits--;
  610.     }
  611. }
  612.  
  613. Game::~Game()
  614. {
  615.     delete m_arena;
  616. }
  617.  
  618. string Game::takePlayerTurn()
  619. {
  620.     for (;;)
  621.     {
  622.         cout << "Your move (n/e/s/w/c or nothing): ";
  623.         string playerMove;
  624.         getline(cin, playerMove);
  625.  
  626.         Player* player = m_arena->player();
  627.         int dir;
  628.  
  629.         if (playerMove.size() == 0)
  630.         {
  631.             if (recommendMove(*m_arena, player->row(), player->col(), dir))
  632.                 return player->move(dir);
  633.             else
  634.                 return player->dropPoisonedCarrot();
  635.         }
  636.         else if (playerMove.size() == 1)
  637.         {
  638.             if (tolower(playerMove[0]) == 'c')
  639.                 return player->dropPoisonedCarrot();
  640.             else if (decodeDirection(playerMove[0], dir))
  641.                 return player->move(dir);
  642.         }
  643.         cout << "Player move must be nothing, or 1 character n/e/s/w/c." << endl;
  644.     }
  645. }
  646.  
  647. void Game::play()
  648. {
  649.     m_arena->display("");
  650.     Player* player = m_arena->player();
  651.     if (player == nullptr)
  652.         return;
  653.     while (!player->isDead() && m_arena->rabbitCount() > 0)
  654.     {
  655.         string msg = takePlayerTurn();
  656.         m_arena->display(msg);
  657.         if (player->isDead())
  658.             break;
  659.         m_arena->moveRabbits();
  660.         m_arena->display(msg);
  661.     }
  662.     if (player->isDead())
  663.         cout << "You lose." << endl;
  664.     else
  665.         cout << "You win." << endl;
  666. }
  667.  
  668. ///////////////////////////////////////////////////////////////////////////
  669. //  Auxiliary function implementation
  670. ///////////////////////////////////////////////////////////////////////////
  671.  
  672.   // Return a uniformly distributed random int from lowest to highest, inclusive
  673. int randInt(int lowest, int highest)
  674. {
  675.     if (highest < lowest)
  676.         swap(highest, lowest);
  677.     static random_device rd;
  678.     static default_random_engine generator(rd());
  679.     uniform_int_distribution<> distro(lowest, highest);
  680.     return distro(generator);
  681. }
  682.  
  683. bool decodeDirection(char ch, int& dir)
  684. {
  685.     switch (tolower(ch))
  686.     {
  687.     default:  return false;
  688.     case 'n': dir = NORTH; break;
  689.     case 'e': dir = EAST;  break;
  690.     case 's': dir = SOUTH; break;
  691.     case 'w': dir = WEST;  break;
  692.     }
  693.     return true;
  694. }
  695.  
  696. // Return false without changing anything if moving one step from (r,c)
  697. // in the indicated direction would run off the edge of the arena.
  698. // Otherwise, update r and c to the position resulting from the move and
  699. // return true.
  700. bool attemptMove(const Arena& a, int dir, int& r, int& c)
  701. {
  702.     // TODO:  Implement this function
  703.     // Delete the following line and replace it with the correct code.
  704.  
  705.     // To move up, you need to subtract rows. The first row is at the top. The last row is at the bottom.
  706.     // To move right, you need to add cols. The first col is at the left. The last row is at the right.
  707.  
  708.     // Check if it's trying to move within bounds, if it is then return false. If not then move accordingly.
  709.  
  710.     if (dir == NORTH) {
  711.         if (r <= 1) return false;
  712.         else r--;
  713.     }
  714.  
  715.     else if (dir == EAST) {
  716.         if (c >= a.cols()) return false;
  717.         else c++;
  718.     }
  719.  
  720.     else if (dir == WEST) {
  721.         if (c <= 1) return false;
  722.         else c--;
  723.     }
  724.  
  725.     else if (dir == SOUTH) {
  726.         if (r >= a.rows()) return false;
  727.         else r++;
  728.     }
  729.  
  730.     return true;
  731. }
  732.  
  733. // Recommend a move for a player at (r,c):  A false return means the
  734. // recommendation is that the player should drop a poisoned carrot and
  735. // not move; otherwise, this function sets bestDir to the recommended
  736. // direction to move and returns true.
  737. bool recommendMove(const Arena& a, int r, int c, int& bestDir)
  738. {
  739.     // TODO:  Implement this function
  740.     // Delete the following line and replace it with your code.
  741.  
  742.     int idle_risk = assessRisk(a, r, c);
  743.  
  744.     if (idle_risk == 0)
  745.         return false;
  746.    
  747.     int least_risk = idle_risk;
  748.  
  749.     int north_risk = assessRisk(a, r - 1, c);
  750.     int south_risk = assessRisk(a, r + 1, c);
  751.     int west_risk = assessRisk(a, r, c - 1);
  752.     int east_risk = assessRisk(a, r, c + 1);
  753.  
  754.     if (north_risk < least_risk && r != 1) {
  755.         least_risk = north_risk;
  756.         bestDir = NORTH;
  757.     }
  758.     if (south_risk < least_risk && r != a.rows()) {
  759.         least_risk = south_risk;
  760.         bestDir = SOUTH;
  761.     }
  762.     if (west_risk < least_risk && c!=1) {
  763.         least_risk = west_risk;
  764.         bestDir = WEST;
  765.     }
  766.     if (east_risk < least_risk && c!=a.cols()) {
  767.         least_risk = east_risk;
  768.         bestDir = EAST;
  769.     }
  770.  
  771.     // Now let's check if least risk is different from idle risk
  772.     // If it is different, then we would recommend moving
  773.     if (idle_risk != least_risk)
  774.     {
  775.         return true;
  776.     }
  777.  
  778.     // If it isn't different, simply return false.
  779.     return false;
  780.  
  781.     // Your replacement implementation should do something intelligent.
  782.     // You don't have to be any smarter than the following, although
  783.     // you can if you want to be:  If staying put runs the risk of a
  784.     // rabbit possibly moving onto the player's location when the rabbits
  785.     // move, yet moving in a particular direction puts the player in a
  786.     // position that is safe when the rabbits move, then the chosen
  787.     // action is to move to a safer location.  Similarly, if staying put
  788.     // is safe, but moving in certain directions puts the player in
  789.     // danger of dying when the rabbits move, then the chosen action should
  790.     // not be to move in one of the dangerous directions; instead, the player
  791.     // should stay put or move to another safe position.  In general, a
  792.     // position that may be moved to by many rabbits is more dangerous than
  793.     // one that may be moved to by few.
  794.     //
  795.     // Unless you want to, you do not have to take into account that a
  796.     // rabbit might be poisoned and thus sometimes less dangerous than one
  797.     // that is not.  That requires a more sophisticated analysis that
  798.     // we're not asking you to do.
  799. }
  800.  
  801. int assessRisk(const Arena& a, int row, int col)
  802. {
  803.  
  804.     int risk = 0;
  805.  
  806.     if (a.numberOfRabbitsAt(row, col) > 0)
  807.     {
  808.         risk += 99;
  809.         return risk;
  810.         // Do not move here lmao
  811.     }
  812.  
  813.     else
  814.     {
  815.         risk += a.numberOfRabbitsAt(row - 1, col); // Rabbits above indicated location
  816.         risk += a.numberOfRabbitsAt(row + 1, col); // Rabbits below indicated location
  817.         risk += a.numberOfRabbitsAt(row, col - 1); // Rabbits left of indicated location
  818.         risk += a.numberOfRabbitsAt(row, col + 1); //Rabbits right of indicated location
  819.  
  820.         return risk;
  821.     }
  822. }
  823.  
  824. ///////////////////////////////////////////////////////////////////////////
  825. // main()
  826. ///////////////////////////////////////////////////////////////////////////
  827.  
  828. int main()
  829. {
  830.     // Create a game
  831.     // Use this instead to create a mini-game:   Game g(3, 5, 2);
  832.     Game g(10, 12, 10);
  833.  
  834.     // Play the game
  835.     g.play();
  836. }
  837.  
  838. ///////////////////////////////////////////////////////////////////////////
  839. //  clearScreen implementation
  840. ///////////////////////////////////////////////////////////////////////////
  841.  
  842. // DO NOT MODIFY OR REMOVE ANYTHING BETWEEN HERE AND THE END OF THE FILE!!!
  843. // THE CODE IS SUITABLE FOR VISUAL C++, XCODE, AND g++/g31 UNDER LINUX.
  844.  
  845. // Note to Xcode users:  clearScreen() will just write a newline instead
  846. // of clearing the window if you launch your program from within Xcode.
  847. // That's acceptable.  (The Xcode output window doesn't have the capability
  848. // of being cleared.)
  849.  
  850. #ifdef _WIN32
  851.  
  852. #include <windows.h>
  853.  
  854. void clearScreen()
  855. {
  856.     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  857.     CONSOLE_SCREEN_BUFFER_INFO csbi;
  858.     GetConsoleScreenBufferInfo(hConsole, &csbi);
  859.     DWORD dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
  860.     COORD upperLeft = { 0, 0 };
  861.     DWORD dwCharsWritten;
  862.     FillConsoleOutputCharacter(hConsole, TCHAR(' '), dwConSize, upperLeft,
  863.         &dwCharsWritten);
  864.     SetConsoleCursorPosition(hConsole, upperLeft);
  865. }
  866.  
  867. #else  // not _WIN32
  868.  
  869. #include <iostream>
  870. #include <cstring>
  871. #include <cstdlib>
  872. using namespace std;
  873.  
  874. void clearScreen()  // will just write a newline in an Xcode output window
  875. {
  876.     static const char* term = getenv("TERM");
  877.     if (term == nullptr || strcmp(term, "dumb") == 0)
  878.         cout << endl;
  879.     else
  880.     {
  881.         static const char* ESC_SEQ = "\x1B[";  // ANSI Terminal esc seq:  ESC [
  882.         cout << ESC_SEQ << "2J" << ESC_SEQ << "H" << flush;
  883.     }
  884. }
  885.  
  886. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement