diff --git a/.idea/deep_miner.iml b/.idea/deep_miner.iml new file mode 100644 index 0000000..4c94235 --- /dev/null +++ b/.idea/deep_miner.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..8d0e15e --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,345 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b76fe5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..dff62e8 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..8306744 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..245fb9c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 4.2) +project(deep_miner) + +set(CMAKE_CXX_STANDARD 14) + +include_directories(include) + +add_executable(deep_miner + include/BaseRobot.h + include/Robot.h + include/SortBot.h + include/World.h + src/BaseRobot.cpp + src/SortBot.cpp + src/World.cpp) diff --git a/include/DigDeepBot.h b/include/DigDeepBot.h new file mode 100644 index 0000000..6db7097 --- /dev/null +++ b/include/DigDeepBot.h @@ -0,0 +1,11 @@ +#pragma once +#include "../include/BaseRobot.h" + +#include +class World; + +class DigDeepBot : public BaseRobot { + public: + DigDeepBot ( const int startX, const int startY ); + int mine ( World& world ) override; +}; diff --git a/include/Game.h b/include/Game.h new file mode 100644 index 0000000..e712428 --- /dev/null +++ b/include/Game.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#include "World.h" +#include "Robot.h" + + +class Game { + public: + Game (); + void run (); + + private: + World world_; + std::unique_ptr< Robot > player_; + std::unique_ptr < Robot > computer_; + bool autoMode_ = false; + int lastThreshold_ = 0; + + void setup (); + void play ( Robot& robot, bool isPlayer ); + void checkRearrange ( Robot& robot ); + void applyEffects ( Robot& robot, int effect ); + bool isGameOver() const; + void printScores() const; + void printResult() const; + + std::unique_ptr < Robot > createRobot ( int choice, int x, int y ) const; + +}; diff --git a/include/RandomBot.h b/include/RandomBot.h new file mode 100644 index 0000000..39370e4 --- /dev/null +++ b/include/RandomBot.h @@ -0,0 +1,12 @@ +#pragma once + +#include "BaseRobot.h" + +class World; + +class RandomBot : public BaseRobot { +/* A robot that digs at a random depth */ + public: + RandomBot ( const int startX, const int startY ); + int mine ( World& world ) override; +}; diff --git a/src/DigDeepBot.cpp b/src/DigDeepBot.cpp new file mode 100644 index 0000000..42571d0 --- /dev/null +++ b/src/DigDeepBot.cpp @@ -0,0 +1,21 @@ +#include "../include/DigDeepBot.h" +#include "../include/World.h" + +DigDeepBot::DigDeepBot ( const int startX, const int startY ) : +BaseRobot( "DigDeepBot", startX, startY) {} + +int DigDeepBot::mine ( World& world ) { + int total = 0; + int grabbed = 0; + + for ( int z = world.getSizeZ() - 1; z >= 0 && grabbed < 3; --z ) { + int v = world.getValue ( x_, y_, z ); + if ( v > 0 ) { + total += v; + world.setValue ( x_, y_, z, 0 ); + ++grabbed; + } + } + score_ += total; + return total; +} diff --git a/src/Game.cpp b/src/Game.cpp new file mode 100644 index 0000000..b2f9385 --- /dev/null +++ b/src/Game.cpp @@ -0,0 +1,101 @@ +#include "../include/Game.h" +#include "../include/SortBot.h" +#include "../include/DigDeepBot.h" +#include "../include/RandomBot.h" +#include +#include + +int validateInput ( const std::string& prompt, int min, int max ); + +Game::Game() : world_ ( 5, 5, 10 ) {} + +void Game::run () { + std::cout << "=== DEEP MINER ===/n/n"; + setup(); + world_.display (); + + int round = 1; + while ( !isGameOver() ) { + std::cout << "\n--- Round " << round ++ << " ---\n"; + + // human player + std::cout << "[Player: " << player_->getName () << "]\n"; + play ( *player_, true ); + + // computer + std::cout << "[Computer: " << computer_->getName() << "]\n"; + play ( *computer_, false ); + + world_.display(); + printScores(); + } + printResult(); +} + +void Game::setup () { + autoMode_ = ( validateInput("Mode - 1: Player vs. Computer 2: Computer vs. Computer: ", 1, 2) == 2 ); + + std::cout << "\nRobots: \n" + << " 1 = SortBot (sorts column and mines highest value)\n" + << " 2 = DigDeepBot (grabs the top 3 values)]\n" + << " 3 = RandomBot (grabs a random Number of values)\n"; + + player_ = createRobot ( validateInput( + "Your robot: ", 1, 3), 0, 0 ); + computer_ = createRobot ( validateInput( + "Computer robot: ", 1, 3 ), world_.getSizeX() - 1, world_.getSizeY() - 1 ); +} + +std::unique_ptr < Robot > Game::createRobot ( int choice, int x, int y ) const { + switch ( choice ) { + case 1: + return std::make_unique < SortBot > ( x, y ); + case 2 : + return std::make_unique < DigDeepBot > ( x, y ); + case 3 : + return std::make_unique < RandomBot > ( x, y ); + default: + return std::make_unique < SortBot > ( x, y ); + } +} + +bool Game::isGameOver () const { + for ( int x = 0; x < world_.getSizeX (); ++x ) { + for ( int y = 0; y < world_.getSizeY(); ++y ){ + if ( world_.getSurfaceLevel( x, y) >= 0 ) + return false; + } + } + return true; +} + +void Game::printScores() const { + std::cout << "Score: " + << player_->getName () << " = " << player_->getScore() << " | " + << computer_->getName() << " = " << computer_->getScore() << "\n"; +} + +void Game::printResult() const { + std::cout << "=== GAME OVER ===\n"; + printScores(); + int scorePlayer = player_->getScore(), scoreComputer = computer_->getScore(); + if ( scorePlayer > scoreComputer ) + std::cout << player_->getName() << " WINS!\n"; + else if ( scoreComputer > scorePlayer ) + std::cout << computer_->getName() << " WINS!\n"; + else + std::cout << "DRAW!\n"; +} + +int getValidatedInput(const std::string& prompt, int min, int max) { + int val; + while (true) { + std::cout << prompt; + if (std::cin >> val && val >= min && val <= max) + return val; + std::cin.clear(); + std::cin.ignore(std::numeric_limits::max(), '\n'); + std::cout << " Invalid. Enter a number between " + << min << " and " << max << ": "; + } +}