Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cmath>
- #include <fstream>
- #include <iostream>
- #include <string>
- #include <vector>
- using Time = double;
- // Represents one of three possible game results
- enum GameResult {
- TomWins = 0,
- JerryWins = 1,
- GameIsNotComplete = 2
- };
- // Represents the point in the 2D space
- struct Position {
- double x{ 0. };
- double y{ 0. };
- };
- // Represents the vector in 2D space
- struct Vector {
- double x{ 0. };
- double y{ 0. };
- // Take absolute value of vector
- double abs() const {
- return std::sqrt(x * x + y * y);
- }
- // Normalization of vector (used to calculate direction of movement)
- void normalize()
- {
- const double norm = abs();
- x /= norm;
- y /= norm;
- }
- };
- // Constants
- const double Pi{ 3.14159265358979323846 };
- const Time DefaultTimeStep{ 0.01 };
- const Position BurrowPosition{ 0., 0. };
- /*
- * @brief Checks if two points are close to each other, basing on the distance between them
- *
- * @param[in] first First point
- * @param[in] second Second point
- *
- * @return True, if two points are close, false otherwise
- */
- bool isCloseEnough(Position first, Position second) {
- const double DistanceThreshold{ 0.01 };
- Vector difference;
- difference.x = first.x - second.x;
- difference.y = first.y - second.y;
- return difference.abs() < DistanceThreshold;
- };
- /*
- * @brief Calculates the velocity, using 2 steps: calculate direction of movement, and multiply on the velocity amplitude
- *
- * @param[in] from Point from which to calculate direction
- * @param[in] to Point to which to calculate direction
- * @param[in] amplitude Velocity amplitude, ie sqrt(vx * vx + vy * vy)
- *
- */
- Vector calculateVelocityToDirection(const Position from, const Position to, const double amplitude)
- {
- Vector velocity;
- Vector direction;
- direction.x = to.x - from.x;
- direction.y = to.y - from.y;
- direction.normalize();
- velocity.x = direction.x * amplitude;
- velocity.y = direction.y * amplitude;
- return velocity;
- }
- /*
- * @brief Reads the initial input from the *.txt file
- *
- * @param[in] file_name File name (should be in the same folder as main.cpp)
- * @param[in] start_position Position from which to start (note - argument, is a reference)
- * @param[in] velocity_amplitude Velocity amplitude (note - argument, is a reference)
- *
- */
- void readInputDataFromFile(const std::string& file_name, Position& start_position, double& velocity_amplitude)
- {
- std::ifstream input(file_name);
- if (input.is_open()) {
- input >> start_position.x;
- if (start_position.x < 0.)
- throw std::exception("Starting X position should be greater than zero!");
- input >> start_position.y;
- if (start_position.y < 0.)
- throw std::exception("Starting Y position should be greater than zero!");
- input >> velocity_amplitude;
- if (velocity_amplitude <= 0.)
- throw std::exception("Velocity amplitude should be greater than zero!");
- }
- else
- {
- std::string message = "Could not open file! Probably you set the wrong file name: ";
- message += file_name;
- throw std::exception(message.c_str());
- }
- }
- // !!! OPTIONAL FUNCTION ONLY FOR VISUALIZATION !!! YOU COULD REMOVE IT WITH THE CORRESPONDING CODE IN main() FUNCTION
- void printData(const std::vector<Position>& sun_path, const std::vector<Position>& earth_path)
- {
- std::ofstream out("pathway.csv");
- out << "cat_x" << "," << "cat_y" << "," << "mouse_x" << "," << "mouse_y" << '\n';
- for (int id = 0; id < sun_path.size(); ++id)
- out << sun_path[id].x << "," << sun_path[id].y << "," << earth_path[id].x << "," << earth_path[id].y << '\n';
- }
- struct Mouse {
- Position current_position;
- Vector velocity;
- // All steps that have been made by the mouse
- std::vector<Position> pathway;
- // Initialize the initial position of mouse and it's velocity amplitude
- void init(const std::string& file_name) {
- double velocity_amplitude{ 0. };
- readInputDataFromFile(file_name, current_position, velocity_amplitude);
- velocity = calculateVelocityToDirection(current_position, BurrowPosition, velocity_amplitude);
- }
- void updatePosition(const Time dt) {
- current_position.x += velocity.x * dt;
- current_position.y += velocity.y * dt;
- pathway.push_back(current_position);
- }
- bool isInTheBurrow(const Position burrow_position) const {
- return isCloseEnough(burrow_position, current_position);
- }
- };
- struct Cat {
- Position current_position;
- double velocity_amplitude;
- // All steps that have been made by the cat
- std::vector<Position> pathway;
- void init(const std::string& file_name) {
- readInputDataFromFile(file_name, current_position, velocity_amplitude);
- }
- void updatePosition(const Position mouse_position, const Time dt) {
- // Each time we update the velocity direction for the cat, because at each time step, mouse has changed it's own position
- const Vector velocity = calculateVelocityToDirection(current_position, mouse_position, velocity_amplitude);
- current_position.x += velocity.x * dt;
- current_position.y += velocity.y * dt;
- pathway.push_back(current_position);
- }
- bool isCatchJerry(const Position jerry_position) const {
- return isCloseEnough(jerry_position, current_position);
- }
- };
- // Game representation: while time is not over update positions of mouse and cat and check if some of them has won
- GameResult playGame(Mouse &jerry, Cat &tom, Time max_game_time) {
- Time current_game_time{ 0. };
- while (current_game_time < max_game_time) {
- jerry.updatePosition(DefaultTimeStep);
- tom.updatePosition(jerry.current_position, DefaultTimeStep);
- if (jerry.isInTheBurrow(BurrowPosition)) {
- return GameResult::JerryWins;
- }
- if (tom.isCatchJerry(jerry.current_position)) {
- return GameResult::TomWins;
- }
- current_game_time += DefaultTimeStep;
- }
- return GameResult::GameIsNotComplete;
- }
- int main() {
- Mouse jerry;
- Cat tom;
- // Step 1. Read initial data about tom & jerry
- try {
- jerry.init("jerry_input.txt");
- tom.init("tom_input.txt");
- }
- catch (const std::exception& error) {
- // In case there is an error in input data - print error to console and close task
- std::cout << "Error! Incorrect input data: " << error.what() << std::endl;
- std::cout << "Please change input and restart the game!" << std::endl;
- return 0;
- }
- // Step 2. Set up the maximum game time
- Time max_time_to_play{ 0. };
- std::cout << "Input max time to play: ";
- std::cin >> max_time_to_play;
- try {
- std::cout << "Let the game begin..." << std::endl;
- // Step 3. Play the game
- const GameResult result = playGame(jerry, tom, max_time_to_play);
- // Step 4. Print the result of the game
- switch (result) {
- case GameResult::JerryWins:
- std::cout << "Jerry is in the burrow. Tom, sorry for you :)" << std::endl;
- break;
- case GameResult::TomWins:
- std::cout << "Tom caught Jerry. Jerry, sorry for you :)" << std::endl;
- break;
- case GameResult::GameIsNotComplete:
- std::cout << "There is not enough time to complete the game with such input conditions" << std::endl;
- }
- }
- catch (const std::exception& error) {
- // In case there is an error during the game - print error to console and close task
- std::cout << "Error! Unexpected behaviour during the game: " << error.what() << std::endl;
- }
- // Optional code for visualization
- printData(tom.pathway, jerry.pathway);
- return 0;
- }
Advertisement
Comments
-
- In the same folder, near main.cpp file should be 2 files with input data:
- jerry_input.txt
- 2.0
- 2.0
- 1.0
- tom_input.txt
- 0.0
- 1.0
- 0.5
-
- # How to print the pathway for tom and jerry
- import pandas as pd
- import matplotlib.pyplot as plt
- jerry_path = r"D:\other\tom_and_jerry\tom_and_jerry\pathway.csv"
- if __name__ == '__main__':
- df =pd.read_csv(jerry_path)
- x_max = df[['cat_x', 'mouse_x']].max(axis=0).max()
- y_max = df[['cat_y', 'mouse_y']].max(axis=0).max()
- ax = df.plot(x="cat_x", y="cat_y", color='C3', label='Tom')
- df.plot(x="mouse_x", y="mouse_y", color='C0', label='Jerry', ax=ax)
- plt.xlabel('X-coordinate')
- plt.ylabel('Y-coordinate')
- plt.xlim([0, 1.2 * x_max])
- plt.ylim([0, 1.2 * y_max])
- plt.grid(True)
- plt.title('Pathway of Tom & Jerry')
- plt.show()
- # plt.savefig("some_title.png")
Add Comment
Please, Sign In to add comment
Advertisement