Advertisement
azakharov93

tom_and_jerry_game

Dec 3rd, 2022
363
0
Never
2
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.61 KB | Gaming | 0 0
  1. #include <cmath>
  2. #include <fstream>
  3. #include <iostream>
  4. #include <string>
  5. #include <vector>
  6.  
  7. using Time = double;
  8.  
  9. // Represents one of three possible game results
  10. enum GameResult {
  11.   TomWins = 0,
  12.   JerryWins = 1,
  13.   GameIsNotComplete = 2
  14. };
  15.  
  16.  
  17. // Represents the point in the 2D space
  18. struct Position {
  19.   double x{ 0. };
  20.   double y{ 0. };
  21. };
  22.  
  23. // Represents the vector in 2D space
  24. struct Vector {
  25.   double x{ 0. };
  26.   double y{ 0. };
  27.  
  28.   // Take absolute value of vector
  29.   double abs() const {
  30.     return std::sqrt(x * x + y * y);
  31.   }
  32.  
  33.   // Normalization of vector (used to calculate direction of movement)
  34.   void normalize()
  35.   {
  36.     const double norm = abs();
  37.     x /= norm;
  38.     y /= norm;
  39.   }
  40. };
  41.  
  42. // Constants
  43. const double Pi{ 3.14159265358979323846 };
  44. const Time DefaultTimeStep{ 0.01 };
  45. const Position BurrowPosition{ 0., 0. };
  46.  
  47. /*
  48.  * @brief             Checks if two points are close to each other, basing on the distance between them
  49.  *
  50.  * @param[in] first   First point
  51.  * @param[in] second  Second point
  52.  *
  53.  * @return            True, if two points are close, false otherwise
  54.  */
  55. bool isCloseEnough(Position first, Position second) {
  56.   const double DistanceThreshold{ 0.01 };
  57.  
  58.   Vector difference;
  59.   difference.x = first.x - second.x;
  60.   difference.y = first.y - second.y;
  61.  
  62.   return difference.abs() < DistanceThreshold;
  63. };
  64.  
  65. /*
  66.  * @brief                   Calculates the velocity, using 2 steps: calculate direction of movement, and multiply on the velocity amplitude
  67.  *
  68.  * @param[in] from          Point from which to calculate direction
  69.  * @param[in] to            Point to which to calculate direction
  70.  * @param[in] amplitude     Velocity amplitude, ie sqrt(vx * vx + vy * vy)
  71.  *
  72.  */
  73. Vector calculateVelocityToDirection(const Position from, const Position to, const double amplitude)
  74. {
  75.   Vector velocity;
  76.  
  77.   Vector direction;
  78.   direction.x = to.x - from.x;
  79.   direction.y = to.y - from.y;
  80.   direction.normalize();
  81.  
  82.   velocity.x = direction.x * amplitude;
  83.   velocity.y = direction.y * amplitude;
  84.  
  85.   return velocity;
  86. }
  87.  
  88. /*
  89.  * @brief                           Reads the initial input from the *.txt file
  90.  *
  91.  * @param[in] file_name             File name (should be in the same folder as main.cpp)
  92.  * @param[in] start_position        Position from which to start (note - argument, is a reference)
  93.  * @param[in] velocity_amplitude    Velocity amplitude (note - argument, is a reference)
  94.  *
  95.  */
  96. void readInputDataFromFile(const std::string& file_name, Position& start_position, double& velocity_amplitude)
  97. {
  98.   std::ifstream input(file_name);
  99.  
  100.   if (input.is_open()) {
  101.     input >> start_position.x;
  102.     if (start_position.x < 0.)
  103.       throw std::exception("Starting X position should be greater than zero!");
  104.  
  105.     input >> start_position.y;
  106.     if (start_position.y < 0.)
  107.       throw std::exception("Starting Y position should be greater than zero!");
  108.  
  109.     input >> velocity_amplitude;
  110.     if (velocity_amplitude <= 0.)
  111.       throw std::exception("Velocity amplitude should be greater than zero!");
  112.   }
  113.   else
  114.   {
  115.     std::string message = "Could not open file! Probably you set the wrong file name: ";
  116.     message += file_name;
  117.     throw std::exception(message.c_str());
  118.   }
  119. }
  120.  
  121. // !!! OPTIONAL FUNCTION ONLY FOR VISUALIZATION !!! YOU COULD REMOVE IT WITH THE CORRESPONDING CODE IN main() FUNCTION
  122.  void printData(const std::vector<Position>& sun_path, const std::vector<Position>& earth_path)
  123. {
  124.    std::ofstream out("pathway.csv");
  125.    out << "cat_x" << "," << "cat_y" << "," << "mouse_x" << "," << "mouse_y" << '\n';
  126.    for (int id = 0; id < sun_path.size(); ++id)
  127.      out << sun_path[id].x << "," << sun_path[id].y << "," << earth_path[id].x << "," << earth_path[id].y << '\n';
  128. }
  129.  
  130. struct Mouse {
  131.   Position current_position;
  132.   Vector velocity;
  133.   // All steps that have been made by the mouse
  134.   std::vector<Position> pathway;
  135.  
  136.   // Initialize the initial position of mouse and it's velocity amplitude
  137.   void init(const std::string& file_name) {
  138.     double velocity_amplitude{ 0. };
  139.     readInputDataFromFile(file_name, current_position, velocity_amplitude);
  140.  
  141.     velocity = calculateVelocityToDirection(current_position, BurrowPosition, velocity_amplitude);
  142.   }
  143.  
  144.   void updatePosition(const Time dt) {
  145.     current_position.x += velocity.x * dt;
  146.     current_position.y += velocity.y * dt;
  147.  
  148.     pathway.push_back(current_position);
  149.   }
  150.  
  151.   bool isInTheBurrow(const Position burrow_position) const {
  152.     return isCloseEnough(burrow_position, current_position);
  153.   }
  154. };
  155.  
  156. struct Cat {
  157.   Position current_position;
  158.   double velocity_amplitude;
  159.   // All steps that have been made by the cat
  160.   std::vector<Position> pathway;
  161.  
  162.   void init(const std::string& file_name) {
  163.     readInputDataFromFile(file_name, current_position, velocity_amplitude);
  164.   }
  165.  
  166.   void updatePosition(const Position mouse_position, const Time dt) {
  167.     // Each time we update the velocity direction for the cat, because at each time step, mouse has changed it's own position
  168.     const Vector velocity = calculateVelocityToDirection(current_position, mouse_position, velocity_amplitude);
  169.  
  170.     current_position.x += velocity.x * dt;
  171.     current_position.y += velocity.y * dt;
  172.  
  173.     pathway.push_back(current_position);
  174.   }
  175.  
  176.   bool isCatchJerry(const Position jerry_position) const {
  177.     return isCloseEnough(jerry_position, current_position);
  178.   }
  179. };
  180.  
  181. // Game representation: while time is not over update positions of mouse and cat and check if some of them has won
  182. GameResult playGame(Mouse &jerry, Cat &tom, Time max_game_time) {
  183.   Time current_game_time{ 0. };
  184.  
  185.   while (current_game_time < max_game_time) {
  186.     jerry.updatePosition(DefaultTimeStep);
  187.     tom.updatePosition(jerry.current_position, DefaultTimeStep);
  188.  
  189.     if (jerry.isInTheBurrow(BurrowPosition)) {
  190.       return GameResult::JerryWins;
  191.     }
  192.  
  193.     if (tom.isCatchJerry(jerry.current_position)) {
  194.       return GameResult::TomWins;
  195.     }
  196.  
  197.     current_game_time += DefaultTimeStep;
  198.   }
  199.  
  200.   return GameResult::GameIsNotComplete;
  201. }
  202.  
  203.  
  204. int main() {
  205.   Mouse jerry;
  206.   Cat tom;
  207.  
  208.  
  209.   // Step 1. Read initial data about tom & jerry
  210.   try {
  211.     jerry.init("jerry_input.txt");
  212.     tom.init("tom_input.txt");
  213.   }
  214.   catch (const std::exception& error) {
  215.     // In case there is an error in input data - print error to console and close task
  216.     std::cout << "Error! Incorrect input data: " << error.what() << std::endl;
  217.     std::cout << "Please change input and restart the game!" << std::endl;
  218.  
  219.     return 0;
  220.   }
  221.  
  222.   // Step 2. Set up the maximum game time
  223.   Time max_time_to_play{ 0. };
  224.   std::cout << "Input max time to play: ";
  225.   std::cin >> max_time_to_play;
  226.  
  227.   try {
  228.     std::cout << "Let the game begin..." << std::endl;
  229.  
  230.     // Step 3. Play the game
  231.     const GameResult result = playGame(jerry, tom, max_time_to_play);
  232.  
  233.     // Step 4. Print the result of the game
  234.     switch (result) {
  235.     case GameResult::JerryWins:
  236.       std::cout << "Jerry is in the burrow. Tom, sorry for you :)" << std::endl;
  237.       break;
  238.  
  239.     case GameResult::TomWins:
  240.       std::cout << "Tom caught Jerry. Jerry, sorry for you :)" << std::endl;
  241.       break;
  242.  
  243.     case GameResult::GameIsNotComplete:
  244.       std::cout << "There is not enough time to complete the game with such input conditions" << std::endl;
  245.     }
  246.   }
  247.   catch (const std::exception& error) {
  248.     // In case there is an error during the game - print error to console and close task
  249.     std::cout << "Error! Unexpected behaviour during the game: " << error.what() << std::endl;
  250.   }
  251.  
  252.  
  253.   // Optional code for visualization
  254.   printData(tom.pathway, jerry.pathway);
  255.  
  256.  
  257.   return 0;
  258. }
  259.  
Advertisement
Comments
  • azakharov93
    1 year
    # text 0.14 KB | 0 0
    1. In the same folder, near main.cpp file should be 2 files with input data:
    2.  
    3. jerry_input.txt
    4. 2.0
    5. 2.0
    6. 1.0
    7.  
    8. tom_input.txt
    9. 0.0
    10. 1.0
    11. 0.5
    12.  
  • azakharov93
    1 year (edited)
    # Python 0.71 KB | 0 0
    1. # How to print the pathway for tom and jerry
    2. import pandas as pd
    3. import matplotlib.pyplot as plt
    4.  
    5. jerry_path = r"D:\other\tom_and_jerry\tom_and_jerry\pathway.csv"
    6.  
    7. if __name__ == '__main__':
    8.     df =pd.read_csv(jerry_path)
    9.  
    10.     x_max = df[['cat_x', 'mouse_x']].max(axis=0).max()
    11.     y_max = df[['cat_y', 'mouse_y']].max(axis=0).max()
    12.  
    13.     ax = df.plot(x="cat_x", y="cat_y", color='C3', label='Tom')
    14.     df.plot(x="mouse_x", y="mouse_y", color='C0', label='Jerry', ax=ax)
    15.  
    16.     plt.xlabel('X-coordinate')
    17.     plt.ylabel('Y-coordinate')
    18.     plt.xlim([0, 1.2 * x_max])
    19.     plt.ylim([0, 1.2 * y_max])
    20.     plt.grid(True)
    21.     plt.title('Pathway of Tom & Jerry')
    22.     plt.show()
    23.     # plt.savefig("some_title.png")
Add Comment
Please, Sign In to add comment
Advertisement