diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json deleted file mode 100644 index f8b4888565caadc7510be75682268d6c18edd6de..0000000000000000000000000000000000000000 --- 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 Binary files a/.vs/slnx.sqlite and /dev/null differ diff --git a/5_praktikum/battleship.cpp b/5_praktikum/battleship.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7cdae64faf57fea28af0d5e58ba590a9e8169f47 --- /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 0000000000000000000000000000000000000000..991651a4dc0f8edab210ec47fff7755b46f2d97e --- /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 0000000000000000000000000000000000000000..be65b15b9dc20ad3ecaaa6beb4dde7fd95b62546 --- /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 0000000000000000000000000000000000000000..fa5cc43cdf387578ef0826b26202d0b9145290be --- /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 0000000000000000000000000000000000000000..1636b43d93f060682e5cf1b888df8185da648d1e --- /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 0000000000000000000000000000000000000000..273b74419d025b8db7c5397ddfc1d87a7a27856f --- /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 0000000000000000000000000000000000000000..dfb2b24ec2f8f67dbae4d3cf088ae35d96702b29 --- /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 0000000000000000000000000000000000000000..ed426610eca0ab1084c491d04024456510f1a67d --- /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 0000000000000000000000000000000000000000..157e94497b21287bc3562aa4431fcdd9fe31d98e --- /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 0000000000000000000000000000000000000000..b822d27dbc4393be9bbb34ada56e5d0dda3a27bd --- /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 0000000000000000000000000000000000000000..58e3860568275eef9a09b7ae98e1ef69098177a8 --- /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 0000000000000000000000000000000000000000..624d6a07ab4239f5cfbb04d26c89b35fe623b552 --- /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 15d74f5ffbb5a3623656958125d6af9aa81a1db2..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# work - -abc