From df76b5d7726617b89ca7c5e43cbd8ed12e4847eb Mon Sep 17 00:00:00 2001 From: stlekelle <leopold.keller@stud.h-da.de> Date: Mon, 24 Jan 2022 11:23:25 +0100 Subject: [PATCH] commit --- .vs/ProjectSettings.json | 3 - .vs/slnx.sqlite | Bin 90112 -> 0 bytes 5_praktikum/battleship.cpp | 1 + 5_praktikum/battleship.h | 86 +++++++++++++++ 5_praktikum/gameboard.cpp | 216 +++++++++++++++++++++++++++++++++++++ 5_praktikum/gameboard.h | 189 ++++++++++++++++++++++++++++++++ 5_praktikum/main.cpp | 12 +++ 5_praktikum/p5-ref.pro | 19 ++++ 5_praktikum/part.cpp | 1 + 5_praktikum/part.h | 91 ++++++++++++++++ 5_praktikum/player.cpp | 1 + 5_praktikum/player.h | 99 +++++++++++++++++ 5_praktikum/ship.cpp | 44 ++++++++ 5_praktikum/ship.h | 142 ++++++++++++++++++++++++ README.md | 3 - 15 files changed, 901 insertions(+), 6 deletions(-) delete mode 100644 .vs/ProjectSettings.json delete mode 100644 .vs/slnx.sqlite create mode 100644 5_praktikum/battleship.cpp create mode 100644 5_praktikum/battleship.h create mode 100644 5_praktikum/gameboard.cpp create mode 100644 5_praktikum/gameboard.h create mode 100644 5_praktikum/main.cpp create mode 100644 5_praktikum/p5-ref.pro create mode 100644 5_praktikum/part.cpp create mode 100644 5_praktikum/part.h create mode 100644 5_praktikum/player.cpp create mode 100644 5_praktikum/player.h create mode 100644 5_praktikum/ship.cpp create mode 100644 5_praktikum/ship.h delete mode 100644 README.md diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json deleted file mode 100644 index f8b4888..0000000 --- a/.vs/ProjectSettings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "CurrentProjectSetting": null -} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100644 index 69b706d1f4401fe49e5e1b80d3ae8452367abe25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90112 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%0DE(vP1oYT>c?R z6EKZ{-|%=sloh#Igzj2!&_kL<=u&J191IFih)x2I11Urgc+F-H7DyrO49*<rmZS4o zp^kxO5OiszEP^gYURHs)8Ij6~Xo=vA14Q8->f-~+is)@BbVuW;*$|q^X%To9gRF^F zaPq`#2Kpoxm-r_Yrxul^rXZKR(AJ`Yi>sSss85JOa%mAb$Cki~X<jbPd}elWLutlF zd2lufPAw_P%u7c~SWpobXcR&-08|u79XJ_*oBI$WaAjJ}046qZZEeO#aLOqz%*iZC zjW13uEKSWzPDSG~LoJ1*8#GCcyu{p8o#NC&%|>@dc5!KG#->!TnNYVuDJB#%qM@Ql zNe(JPx0Du^m{Xb>tALg|!HG)~-2Z3jW8nAW>Er&!?ayJzUc+{r#fNzzLm!R0hj@%_ z6A)n+)z#(b4lm10EeEyL0}@Lzz%^iIYB4$=8qQ&!uHg#katevXyj<a)Asz}ruFj!B z!Jc8Rm}(q@p`9a8{t9;Wadi$+0Ht~4*0yJgf@83PQ(|!{s;G_vt_%!P?+i)z5G7#u zS9+%CD1eFy6zP%-1-Br7UkqCjIXBeL)87xlg}4&I2e~{z4~z3qmAD1#LEM7fd)S?e zVFcLuH8l$AG3p96H3|WGaD62iXx>8Th4`;DCkHtyL8=1~YCQe?T!R$6{5}0JLIR}H zEm#3L4BUeCuz153**%~_2NvwST$;RGkZ@CQ3)a)pL34L8JYn#1;d3l8js#hN!)=&x z#LE@#;Tq(s01riES1Wi1gB!Aq8p7=2(VC2nk>KJIVYo|TNg~c(5UMgUXik9^rKplP z%>b9LkO37`9iW01Ap#5LSk0CSA#ek>QyW|=B9wrfipmp(x(HIvB6V><N|B06R9)ni zm<TiAPDNC)&<YEY6v^mFK|5-otVm8h3u`PR`;LY^DMU3uxE&A5@E8>bG{|raus|!D z5Z4IQfuoSbqV&`f48uZwd~g`#oS#>cT0x8sP{+YYkX=097-iG}+*%GwO-n5TRrK+2 z7AQSnwz}ccBG9CXky+p>up5OnyTJ9tYDB}?5C_C+HW~>Ka<ofoL26z~VqOVE52XDJ zVnZq;xRJty9gWo}f{sSh6|31M&Cf1wY|Pk=G+Kfh(pa1)0CgTlc87ZaYo3S8VrE<- zda=-K3Gc>Y%U{^@JuF8;tflIZC3<*Lw<JP%hn#{49^9Z9L<uc$TM<;gfiM{*Bo*BS zYDL5<z>60gg$E5w8~Df*>bMj*h%_5j_}E7$KfrT3NJR_!qy?w}0jXM02ir#{KVUN) zC>aL(xF{q55w$rHLk^%$(&*#|mWd?TyvE3z{21N;k7qbyRBAK?MnhmU1V%$(Gz3ON zU^E0qLtr!nMnhmU1V%$(Gz5l82#ogshe<?^dSf&MMnhmU1V%$(Gz3ONU^E0qLtr!n zMnhmU1V%$(Gz9R30BHR`g8&`{qf(<GFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O zqaiRF0z*CoM(6*Bd=!p)U^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1PF!z E0NG@G761SM diff --git a/5_praktikum/battleship.cpp b/5_praktikum/battleship.cpp new file mode 100644 index 0000000..7cdae64 --- /dev/null +++ b/5_praktikum/battleship.cpp @@ -0,0 +1 @@ +#include "battleship.h" diff --git a/5_praktikum/battleship.h b/5_praktikum/battleship.h new file mode 100644 index 0000000..991651a --- /dev/null +++ b/5_praktikum/battleship.h @@ -0,0 +1,86 @@ +/** + * \file + * \date 08.12.2019 + * \author Michael Roth + * This is the header file for the \ref Battleship class, which is the main + * class for the game. + * This class holds two \ref Player objects as well as their corresponding \ref + * GameBoard objects. + */ + +#ifndef BATTLESHIP_H +#define BATTLESHIP_H +#include "gameboard.h" +#include "player.h" + +#include <string> +using std::string; + +#include <array> +using std::array; + +/** + * @brief The Battleship class + * + * This is the main class of the game. An object is constructed by supplying two + * player names. One game round is then started by simply calling the \ref play + * function. + * + * The Players and their boards are stored in Arrays to make the implementation + * of the game logic easier. + * + * **Note:** If you find that confusing, you are welcome the change the Arrays + * into something else, or have two attributes per player. + */ +class Battleship +{ + public: + /** + * @brief Battleship constructor + * @param[in] player1Name Name of the first player + * @param[in] player2Name Name of the second player + */ + Battleship(const string& player1Name, const string& player2Name); + + /** + * @brief Play one game of Battleships! + * + * This functions shall do the following: + * + * - Initialize both players game boards: + * - The ships shall be placed at randomized locations + * - The 'cheat sheets' shall be empty + * - This can easily be achieved by creating new \ref GameBoard objects + * and storing them in \ref m_boards, overwriting the old boards which may be + * there already + * + * Then, do the following in a loop: + * 1. Determine the active Player either by random coin toss or first player + * always gets to start + * 2. Print both the game board and the 'cheat sheet' for the active player + * 3. Ask the active player a location she wants to shoot at + * 4. Call the \ref GameBoard::hit function for that location on the + * **inactive** Player's board + * 5. Inform the active player if she hit something and make the correct + * mark on the cheat sheet + * 6. Switch the players, e.g. active player becomes inactive and inactive + * Player becomes active + * 7. Repeat Steps 1 to 6 until one player has lost + * 8. Exit the function + * + */ + void play(); + + private: + /** + * @brief Array containing the two \ref Player objects + */ + array<Player, 2> m_players; + + /** + * @brief Array containing the two \ref GameBoard objects, one for each player + */ + array<GameBoard, 2> m_boards; +}; + +#endif // BATTLESHIP_H diff --git a/5_praktikum/gameboard.cpp b/5_praktikum/gameboard.cpp new file mode 100644 index 0000000..be65b15 --- /dev/null +++ b/5_praktikum/gameboard.cpp @@ -0,0 +1,216 @@ +#include "gameboard.h" +#include <iostream> +#include <iomanip> +#include <random> +using namespace std; +using std::array; +GameBoard::GameBoard(){ + for(int i=0; i<10;i++){ + for(int j=0; j<10;j++) + m_enemyBoard[i][j]='.'; + } +} +void GameBoard::printBoard() +{ + +for (int jt= 0; jt<= m_enemyBoard.size(); jt++){ + + +} + + for (int it = 0; it < 10; it++) + { + for (int kt = 0; kt < 10; kt++) + { + if (m_enemyBoard[it][kt] == *".") + cout << "."; + if (m_enemyBoard[it][kt] == *"X") + cout << "X"; + if (m_enemyBoard[it][kt] == *"o") + cout << "o"; + if (it == 9) + cout << "\n"; + } + } + cout << "\n\n"; + +} +void GameBoard::randomPlaceShips(){ +random_device rnd_device; +mt19937 mersenne_engine{ rnd_device() }; +uniform_int_distribution<int> dist{ 0, 9 }; +uniform_int_distribution<int> dist2{ 0, 3 }; + auto gen = [&dist, &mersenne_engine]() { + return dist(mersenne_engine); + }; + auto gen2 = [&dist2, &mersenne_engine]() { + return dist2(mersenne_engine); + }; +int finalx; +int finaly; +Direction finaldir; + +//Dreadnought +while(true){ +int x=gen(); +int y=gen(); +int direction=gen2(); +Direction dir; +if(direction==0) dir=Direction::north; else if(direction==1)dir=Direction::east; else if(direction==2) dir=Direction::south; else if(direction==3) dir=Direction::west; +if(dir==Direction::north && y-4 >=0 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x][y-1]=='.' && m_enemyBoard[x][y-2]=='.' && m_enemyBoard[x][y-3]=='.' && m_enemyBoard[x][y-4]=='.'){ m_ships[0] = Ship(x,y,5,Direction::north); break; finalx=x;finaly=y; finaldir=dir;} +if(dir==Direction::west && x-4 >=0 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x-1][y] == '.' && m_enemyBoard[x-2][y] == '.' && m_enemyBoard[x-3][y] == '.' && m_enemyBoard[x-4][y] == '.'){ m_ships[0] = Ship(x,y,5,Direction::west); break; finalx=x;finaly=y; finaldir=dir;} +if(dir==Direction::east && x+4 <=9 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x+1][y] == '.' && m_enemyBoard[x+2][y] == '.' && m_enemyBoard[x+3][y] == '.' && m_enemyBoard[x+4][y] == '.'){ m_ships[0] = Ship(x,y,5,Direction::east); break; finalx=x;finaly=y; finaldir=dir;} +if(dir==Direction::south && y+4 <=9 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x][y+1] == '.' && m_enemyBoard[x][y+2] == '.' && m_enemyBoard[x][y+3] == '.' && m_enemyBoard[x][y+4] == '.'){ m_ships[0] = Ship(x,y,5,Direction::south); break; finalx=x;finaly=y; finaldir=dir;} +} +for(int i=0; i<5; i++){ + m_enemyBoard[finalx][finaly]= '1'; + if(finaldir==Direction::north) finaly--; + if(finaldir==Direction::south) finaly++; + if(finaldir==Direction::east) finalx++; + if(finaldir==Direction::west) finalx--; +} + +//Cruisers +for(int i=2; i<=3;i++){ + while(true){ + int x=gen(); + int y=gen(); + int direction=gen2(); + Direction dir; +if(direction==0) dir=Direction::north; else if(direction==1)dir=Direction::east; else if(direction==2) dir=Direction::south; else if(direction==3) dir=Direction::west; +if(dir==Direction::north && y-3 >=0 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x][y-1]=='.' && m_enemyBoard[x][y-2]=='.' && m_enemyBoard[x][y-3]=='.'){ m_ships[i] = Ship(x,y,4,Direction::north); +for(int j=0; j<4; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break; +if(dir==Direction::west && x-3 >=0 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x-1][y] == '.' && m_enemyBoard[x-2][y] == '.' && m_enemyBoard[x-3][y] == '.'){ m_ships[i] = Ship(x,y,4,Direction::west); +for(int j=0; j<4; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} +if(dir==Direction::east && x+3 <=9 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x+1][y] == '.' && m_enemyBoard[x+2][y] == '.' && m_enemyBoard[x+3][y] == '.'){ m_ships[i] = Ship(x,y,4,Direction::east); +for(int j=0; j<4; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} +if(dir==Direction::south && y+3 <=9 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x][y+1] == '.' && m_enemyBoard[x][y+2] == '.' && m_enemyBoard[x][y+3] == '.' ){ m_ships[i] = Ship(x,y,4,Direction::south); +for(int j=0; j<4; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} + } + } + } + + //Destroyers +for(int i=4; i<=6;i++){ + while(true){ + int x=gen(); + int y=gen(); + int direction=gen2(); + Direction dir; +if(direction==0) dir=Direction::north; else if(direction==1)dir=Direction::east; else if(direction==2) dir=Direction::south; else if(direction==3) dir=Direction::west; +if(dir==Direction::north && y-2 >=0 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x][y-1]=='.' && m_enemyBoard[x][y-2]=='.'){ m_ships[i] = Ship(x,y,3,Direction::north); +for(int j=0; j<3; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break; +if(dir==Direction::west && x-2 >=0 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x-1][y] == '.' && m_enemyBoard[x-2][y] == '.'){ m_ships[i] = Ship(x,y,3,Direction::west); +for(int j=0; j<3; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} +if(dir==Direction::east && x+2 <=9 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x+1][y] == '.' && m_enemyBoard[x+2][y] == '.'){ m_ships[i] = Ship(x,y,3,Direction::east); +for(int j=0; j<3; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} +if(dir==Direction::south && y+2 <=9 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x][y+1] == '.' && m_enemyBoard[x][y+2] == '.'){ m_ships[i] = Ship(x,y,3,Direction::south); +for(int j=0; j<3; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} + } + } + } + //Submarines +for(int i=7; i<=10;i++){ + while(true){ + int x=gen(); + int y=gen(); + int direction=gen2(); + Direction dir; +if(direction==0) dir=Direction::north; else if(direction==1)dir=Direction::east; else if(direction==2) dir=Direction::south; else if(direction==3) dir=Direction::west; +if(dir==Direction::north && y-1 >=0 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x][y-1]=='.'){ m_ships[i] = Ship(x,y,2,Direction::north); +for(int j=0; j<3; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break; +if(dir==Direction::west && x-1 >=0 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x-1][y] == '.'){ m_ships[i] = Ship(x,y,2,Direction::west); +for(int j=0; j<3; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} +if(dir==Direction::east && x+1 <=9 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x+1][y] == '.'){ m_ships[i] = Ship(x,y,2,Direction::east); +for(int j=0; j<3; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} +if(dir==Direction::south && y+1 <=9 && m_enemyBoard[x][y] == '.' && m_enemyBoard[x][y+1] == '.'){ m_ships[i] = Ship(x,y,2,Direction::south); +for(int j=0; j<3; j++){ + m_enemyBoard[x][y]= (char)i; + if(dir==Direction::north) y--; + if(dir==Direction::south) y++; + if(dir==Direction::east) x++; + if(dir==Direction::west) x--; + } + break;} + } + } + } + +} \ No newline at end of file diff --git a/5_praktikum/gameboard.h b/5_praktikum/gameboard.h new file mode 100644 index 0000000..fa5cc43 --- /dev/null +++ b/5_praktikum/gameboard.h @@ -0,0 +1,189 @@ +/** + * \file + * \date 08.12.2019 + * \author Michael Roth + * This is the header file for the \ref GameBoard class which represents the + * game board(s) for a single player. + */ + +#ifndef GAMEBOARD_H +#define GAMEBOARD_H +#include "ship.h" + +#include <array> +using std::array; + +/** + * @brief The GameBoard class + * + * This class contains everything that a single player needs in order to play. + * First of all, this class contains an array of one's own ships. Furthermore it + * contains a map of locations where Player A has tried to hit ships from Player + * B. + * + * The primary functions of this board are \ref hit which represents + * a shot from the enemy. The \ref hit function handles the shot and returns + * true if any ship was actually hit by that shot. The other important function + * is \ref mark which is used to mark positions where the player tried to hit + * enemy ships. + * + * Every Player needs one instance of this in order to: + * + * - Have a registry where her own ships are located + * - Have an idea where she has already tried to hit her enemy's ships + * + * Note that while the enemy board is represented as a two dimensional array of + * `char` values, the own registry exists simply as `vector` of \ref Ship + * objects. + * + * Also, this class has the neccessary functions functions to print both of + * those boards. + * + * Note that Battleships is played on a 10 x 10 board, with valid rows and + * columns ranging from 0 to 9. + */ +class GameBoard +{ + public: + /** + * @brief GameBoard constructor + * + * This shall initialize the enemy board (attribute \ref m_enemyBoard) with + * dot characters '.'. The player's ships can either be placed here also, or + * later by calling \ref randomPlaceShips. + * + * + */ + GameBoard(); + + /** + * @brief Prints the player's board. + * + * This function prints the player's board to the console screen. You are + * relatively free to be creative here, but make sure that all ships are + * displayed properly. + * + * Some suggestions are: + * + * - A location containing water is represented by printing '.' + * - A location containing an intact (e.g. undamaged) ship part is + * represented by its ship number (e.g. the ships index in the array) + * - A location containing a damaged ship part of an **unsunken ship** is + * represented by an 'X' + * - A location containing a part of a sunken ship is represented by an 'S' + * + * You can, as mentioned before, use other characters, but those four types of + * locations should be distinguishable from another. + */ + void printBoard(); + + /** + * @brief Prints the 'cheat sheet', containing markings where this player has + * hit or missed. + * + * When trying to hit the other player's ships, it does not make sense to + * shoot the same location more than once. In order to 'memorize' those + * locations, the two-dimensional array is used. In there, the characters have + * the following meanings: + * + * - '.' represents a location which has not yet beens shot + * - 'X' represents a hit ship at that locations + * - 'O' represents a shot into open water + * + * As with \ref printBoard you are free to change the characters if you fancy + * something else. + */ + void printEnemyBoard(); + + /** + * @brief The enemy player's shot on our board + * @param[in] row The row where we are being shot + * @param[in] col The column where we are being shot + * @return True if the shot hit any of our ships, false otherwise. + * + * This function is called when the enemy is trying to hit any of our ships. + * Generally a shot is directed at a specific location denoted by `row` and + * `col`. + * + * If there is a ship part at that location, that part shall be damaged by + * that shot. + * + * \see Part::setDamaged + * \see printBoard + */ + bool hit(int row, int col); + + /** + * @brief Mark locations on the enemy board where we already shot at + * @param[in] row The row where we shot + * @param[in] col The column where we shot + * @param[in] wasHit True if the shot was a hit (e.g. we hit a ship) + * + * This function shall make a mark on the 'cheat sheet'. The mark shall be + * different depending on if we hit something there. + * + * \see hit + * \see printEnemyBoard + */ + void mark(int row, int col, bool wasHit); + + /** + * @brief Randomly place ships. + * + * This function randomly places ships on the board, e.g. it populates the + * \ref m_ships vector. + * + * The following ships shall be placed: + * - 1 'Dreadnought' with 5 parts + * - 2 'Cruisers' with 4 parts + * - 3 'Destroyers' with 3 parts + * - 4 'Submarines' with 2 parts + * + * The ships shall be placed so that: + * - No ships intersect each other + * - No ship has parts outside the playing area + * - When this is called for both players, the resulting placements shall be + * different + * + */ + void randomPlaceShips(); + + /** + * @brief Test if all ships are sunk + * @return True if all ships on this board are sunk + * + * This function is used to determine if the player hast lost the game. As a + * reminder: The player has lost the game when she has no floating ship left. + */ + bool allShipsSunk(); + + private: + /** + * @brief The player's ships + * + * This is collection of the player's ships. Since there are always 10 ships + * on the board, we can use a simple `std::array`. + */ + array<Ship, 10> m_ships; + + /** + * @brief The 'cheat sheet' + * + * This is a two-dimensional Array of `char` values. What this means is that + * we use an `std::array<char, 10>` to represent a row. Then, a collection of + * 10 of such rows finally is a grid, our two-dimensional structure. + * + * So the datatype for this is `array< array<char, 10>, 10 >`. + * + */ + array<array<char, 10>, 10> m_enemyBoard; + + + + + +}; + + + +#endif // GAMEBOARD_H diff --git a/5_praktikum/main.cpp b/5_praktikum/main.cpp new file mode 100644 index 0000000..1636b43 --- /dev/null +++ b/5_praktikum/main.cpp @@ -0,0 +1,12 @@ +#include <iostream> +using std::cin; +using std::cout; +using std::endl; + +#include "battleship.h" + +int main() +{ + + return 0; +} diff --git a/5_praktikum/p5-ref.pro b/5_praktikum/p5-ref.pro new file mode 100644 index 0000000..273b744 --- /dev/null +++ b/5_praktikum/p5-ref.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +CONFIG += console c++11 +CONFIG -= app_bundle +CONFIG -= qt + +SOURCES += \ + battleship.cpp \ + gameboard.cpp \ + main.cpp \ + part.cpp \ + player.cpp \ + ship.cpp + +HEADERS += \ + battleship.h \ + gameboard.h \ + part.h \ + player.h \ + ship.h diff --git a/5_praktikum/part.cpp b/5_praktikum/part.cpp new file mode 100644 index 0000000..dfb2b24 --- /dev/null +++ b/5_praktikum/part.cpp @@ -0,0 +1 @@ +#include "part.h" diff --git a/5_praktikum/part.h b/5_praktikum/part.h new file mode 100644 index 0000000..ed42661 --- /dev/null +++ b/5_praktikum/part.h @@ -0,0 +1,91 @@ +/** + * \file + * \date 08.12.2019 + * \author Michael Roth + * This is the header file for the \ref Part class. + * The \ref Part class is used to represent on piece (or part) + * of a \ref Ship for the \ref Battleship game + */ + +#ifndef PART_H +#define PART_H + +/** + * @brief The Part class represents a part of a \ref Ship in the context of the + * \ref Battleship game. + * + * One object of Part is located at a specific * position denoted by row and + * column. Multiple Part objects make up one object of \ref Ship, as a matter of + * fact there is a composition association between those two. + * + * A ship's part has a status which indicates wether it is damaged or not. + * A part of a ship does neither 'know' to which ship it belongs neither if that + * ship is already sunk or not. + * + */ +class Part +{ + public: + /** + * @brief Part constructor + * @param[in] row The grid row on which this part is to be placed + * @param[in] col The grid column on which this part is to be placed + * + * This is supposed to be the only Part constructor. The values for \ref m_row + * and \ref m_col shall be assigned from `row` and `col` respectively. + * The status \ref m_status shall be initialized with 0. indicating 'no + * damage'. + */ + Part(int row, int col); + + /** + * @brief Returns wether or not this part is damaged + * @return True if damaged, False if undamaged + * + * Note that there is no extra status for a sunken \ref Ship. + * By definition, a ship is sunk when all parts were hit, e.g. are damaged. + */ + bool isDamaged() const; + + /** + * @brief Sets the status of this part to a valued representing 'damaged'. + * + * The attribute \ref m_status is supposed to be 0 if there is no damage, + * and 1 if this part was damaged. + * This method shall thereby set \ref m_status to 1. + */ + void setDamaged(); + + /** + * @brief Returns the row with which this part was constructed + * @return The row with which this part was constructed + */ + int getRow() const; + + /** + * @brief Returns the column with which this part was constructed + * @return The column with which this part was constructed + */ + int getCol() const; + + private: + /** + * @brief The row where this part is located on the grid. + */ + int m_row; + + /** + * @brief The column where this part is located on the grid. + */ + int m_col; + + /** + * @brief Status of the part as integer value + * + * 0 means 'No Damage' + * 1 means 'Damaged' + */ + int m_status; +}; + +#endif // PART_H diff --git a/5_praktikum/player.cpp b/5_praktikum/player.cpp new file mode 100644 index 0000000..157e944 --- /dev/null +++ b/5_praktikum/player.cpp @@ -0,0 +1 @@ +#include "player.h" diff --git a/5_praktikum/player.h b/5_praktikum/player.h new file mode 100644 index 0000000..b822d27 --- /dev/null +++ b/5_praktikum/player.h @@ -0,0 +1,99 @@ +/** + * \file + * \date 08.12.2019 + * \author Michael Roth + * This is the header file for the \ref Player class. + * This class is used for storing player Names and some sort of highscore table. + * + */ + +#ifndef PLAYER_H +#define PLAYER_H + +#include <string> +using std::string; + +/** + * @brief The Player class represents a single player for the \ref Battleship + * game. + * + * Objects of this class store + * - The player's name + * - How many games where won + * - How many games where lost + */ +class Player +{ + public: + /** + * @brief Player constructor. + * @param[in] playerName The player's name. + * + * The attribute \ref m_playerName shall be initialized with the + * `playerName` parameter. + * + * The attributes \ref m_gamesWon and \ref m_gamesLost + * shall be initialized with 0. + */ + Player(const string& playerName); + + /** + * @brief Get games won. + * @return The number of games which were won by this player. + */ + int getGamesWon() const; + + /** + * @brief Get games lost. + * @return The number of games which were lost by this player. + */ + int getGamesLost() const; + + + /** + * @brief Get games played. + * @return The total number of games this player has played. + * + * \see getGamesWon + * \see getGamesLost + */ + int getGamesPlayed() const; + + /** + * @brief Add another won game. + * + * This shall increase the number of won games by 1. + */ + void addGameWon(); + + /** + * @brief Add another lost game. + * + * This shall increase the number of lost games by 1 + */ + void addGameLost(); + + /** + * @brief Get the player's name + * @return The player's name + */ + string getName(); + + private: + /** + * @brief Number of games won. + */ + int m_gamesWon; + + /** + * @brief Number of games lost. + */ + int m_gamesLost; + + /** + * @brief The player's name. + */ + string m_playerName; +}; + +#endif // PLAYER_H diff --git a/5_praktikum/ship.cpp b/5_praktikum/ship.cpp new file mode 100644 index 0000000..58e3860 --- /dev/null +++ b/5_praktikum/ship.cpp @@ -0,0 +1,44 @@ +#include "ship.h" +#include <stdexcept> + +bool Ship::hasPartIn(int row, int col) +{ + for (int it = 0; it < Ship().m_parts.size() - 1; it++) + { + if (m_parts.at(it).getCol() == row && m_parts.at(it).getCol() == col) + { + return true; + } + } + return false; +} +Part &Ship::getPartIn(int row, int col) +{ + for (int it = 0; it < Ship().m_parts.size() - 1; it++) + { + if (m_parts.at(it).getCol() == row && m_parts.at(it).getCol() == col) + { + return m_parts.at(it); + } + } + throw std::invalid_argument("no Part at given Place!"); +} + +bool Ship::isDamaged() +{ + for (int it = 0; it < Ship().m_parts.size() - 1; it++) + { + if (m_parts.at(it).isDamaged() == true) + return true; + } + return false; +} +bool Ship::isSunk() +{ + for (int it = 0; it < Ship().m_parts.size() - 1; it++) + { + if (m_parts.at(it).isDamaged() == false) + return false; + } + return true; +} \ No newline at end of file diff --git a/5_praktikum/ship.h b/5_praktikum/ship.h new file mode 100644 index 0000000..624d6a0 --- /dev/null +++ b/5_praktikum/ship.h @@ -0,0 +1,142 @@ +/** + * \file + * \date 08.12.2019 + * \author Michael Roth + * This is the header file for the \ref Ship class. + * A Ship is, in this context, a composite collection of \ref Part objects, + * where the part objects make up the ship. + */ + +#ifndef SHIP_H +#define SHIP_H +#include <vector> +using std::vector; + +#include "part.h" + +/** + * @brief The Direction enum, indicating in which direction a ship is pointed + */ +enum class Direction +{ + north, + east, + south, + west +}; + +/** + * @brief The Ship class, a collection of \ref Part objects. + * + * This class represents a ship for the \ref Battleship game. A ship is made up + * of at parts, e.g. \ref Part objects which are stored using a vector. + * + * Ships of multiple sizes are represented by having different amount of parts: + * + * - The 'Dreadnought' has 5 parts + * - A 'Cruiser' has 4 parts + * - A 'Destroyer' has 3 parts + * - A 'Submarine' has 2 parts + * + */ +class Ship +{ + public: + /** + * @brief Ship Standard constructor + * + * Should do nothing. This is just needed in order for the std::array in \ref + * GameBoard to work. + */ + Ship(); + + /** + * @brief Ship constructor + * @param[in] row The row where the aft part of the ship shall be placed + * @param[in] col The column where the aft part of the ship shall be placed + * @param[in] lengthOfShip Which length the ship shall have (usually 2 to 5) + * @param[in] direction Which direction the ship should point to with: + * - 0 meaning up + * - 1 meaning right + * - 2 meaning down + * - 3 meaning left + * @throws std::invalid_argument if either the direction if the ship is an + * invalid value **or** if parts of the ship would be placed outside of the + * 10x10 grid. + * + * This constructs a ship with the given parameters. The aft section of the + * ship is always placed at the given row and column. From there on, + * (lengthOfShip - 1) number of parts are placed in the given direction. + * + * If, for example, a ship shall be constructed at `row = 3` and `col = 2`, + * a length of 3 and `direction = 1` this means the following part objects are + * created: + * - Part at 3 / 2 + * - Part at 3 / 3 + * - Part at 3 / 4 + * + */ + Ship(int row, int col, int lengthOfShip, Direction direction); + + /** + * @brief Evaluates if this ship extends to the given row and col + * @param[in] row Row which is to be checked + * @param[in] col Column which is to be checked + * @return True if ship extends to the field row/col, false otherwise. + * + * This function is used to determine wether or not a ship is present in the + * given row and col. This is easily answered by iterating over the ship's + * parts and checking if any of those are located on this position. + * + * \see getPartIn + */ + bool hasPartIn(int row, int col); + + /** + * @brief Returns the ship's part which is in the given row and col + * @param[in] row Row of the Part + * @param[in] col Column of the Part + * @return Reference to the ship part at the given location. + * @throws std::invalid_argument if there is no such part at the given + * position. + * + * It is advised to only use this function if you are sure that the given + * position really contains a part of this ship, e.g. calling \ref hasPartIn + * first. + * + * \see hasPartIn + */ + Part& getPartIn(int row, int col); + + /** + * @brief Returns wether or not the ship is damaged. + * @return True if the ship is damaged. + * + * A ship is considered to be damaged of there is at least on of it's parts + * damaged. If **all** of the parts are damaged, the ship is considered to be + * sunk, but this also counts as damaged. + * + * \see isSunk + */ + bool isDamaged(); + + /** + * @brief Returns wether or not the ship is sunk. + * @return True if the ship is sunk. + * + * A ship is considered to be sunk if **all** of it's parts are damaged. + * + * \see isDamaged + */ + bool isSunk(); + + private: + /** + * @brief The ship's parts + * + * This vector stores the \ref Part objects which make up the ship. + */ + vector<Part> m_parts; +}; + +#endif // SHIP_H diff --git a/README.md b/README.md deleted file mode 100644 index 15d74f5..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# work - -abc -- GitLab