Skip to content

Pa1 basic battleship #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: PA1_Basic_Battleship
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 34 additions & 98 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,23 @@
# CSCI 466 PA1 - Basic Battleship Game
SCI 466 PA1 - Basic Battleship Game
Instructions
Complete the following assignment individually. Submit your work on D2L into the "Programming Assignment 1" folder.

## Instructions


Complete the following assignment individually.
Submit your work on D2L into the "Programming Assignment 1" folder.

For a deeper discussion of the assignment and the code, please check out this
[YouTube video](https://www.youtube.com/watch?v=pbCY2e1oFys).


## Learning Objectives
For a deeper discussion of the assignment and the code, please check out this YouTube video.

Learning Objectives
In this programming assignment you will:

- clone and commit to [GitHub](https://github.com/) repositories
- Learn how to build a C++ project using [CMake](https://cmake.org/)
- Learn how to test your code using [googletest](https://github.com/google/googletest)


## Overview
clone and commit to GitHub repositories
Learn how to build a C++ project using CMake
Learn how to test your code using googletest
Overview
Your objective is to implement a basic version of the Battleship game. You will use the standard 10x10 variation of the game . Here is an example of online implementation of the game. Note that the ships in that implementation have slightly different names.

Your objective is to implement a basic version of the
[Battleship](https://en.wikipedia.org/wiki/Battleship_\(game\))
game.
You will use the standard
[10x10 variation of the game](https://en.wikipedia.org/wiki/Battleship_\(game\)#Description)
.
Here is an example of
[online implementation](http://www.battleshiponline.org/)
of the game.
*Note that the ships in that implementation have slightly different names.*
Your implementation will be a client server architecture. This repository provides you with the header files for the client (player) and server implementations (src/Client.hpp and src/Server.hpp), client and server run times (src/client_main.cpp and src/server_main.cpp), and a suite of tests (test/tests.cpp). Your job is to finish the implementation of Client.cpp and Server.cpp to pass all the tests in tests.cpp.

Your implementation will be a client server architecture.
This repository provides you with the header files for the client (player) and server implementations (`src/Client.hpp`
and `src/Server.hpp`), client and server run times (`src/client_main.cpp` and `src/server_main.cpp`), and a suite of
tests (`test/tests.cpp`).
Your job is to finish the implementation of `Client.cpp` and `Server.cpp` to pass all the tests in `tests.cpp`.
Board Setup
The first step before the game begins is to create a setup board for each player, according to the rules of the game . You will represent the board with a character array, where _ represents water and Carrier, Battleship, cRuiser, Submarine, and Destroyer fields are represented by C, B, R, S, D respectively. For example, your board might be set up as follows:


## Board Setup

The first step before the game begins is to create a *setup board* for each player, according to the
[rules of the game](https://en.wikipedia.org/wiki/Battleship_\(game\)#Description)
.
You will represent the board with a character array, where `_` represents water and Carrier, Battleship, cRuiser,
Submarine, and Destroyer fields are represented by `C`, `B`, `R`, `S`, `D` respectively.
For example, your board might be set up as follows:

```
CCCCC_____
BBBB______
RRR_______
Expand All @@ -59,71 +28,38 @@ __________
__________
__________
__________
```

Save these boards for both players as `player_1.setup_board.txt` and `player_2.setup_board
.txt`.


## Messages

To play the game, your implementation needs to exchange two types of messages - `shot` and `result`.
The `shot` message needs to communicate the grid location of salvo.
The `result` message needs to communicate whether the salvo was a hit, a miss, or if the shot was out of bounds.

You will represent both of these messages as JSON files that the client and server exchange via local disk storage.
Assume that the x and y board coordinates are zero indexed at the top-left corner of the board and increase as you go
right and down.


## Program Operation

The following figure illustrates the operation of the program.
(I kept the image from the lecture for continuity.)

![system architecture](images/system_architecture.png)

The player fires a `shot` by writing coordinates to a `player_#.shot.json` file.
The server reads the shot file, determines the result of the shot, and writes it into `player_#.result.json`.
The player reads the result file and updates the result on its action board `player_#.action_board.json`.


## Program Invocation

To play Battleship you should first start the server by running the `run-server` executable.
Then start the player clients by running two instances of the `run-client` executable.
Unfortunately, the client and server executables will not do anything interesting until you implement `Client.cpp`
and `Server.cpp`.
As you progress in these implementations, your code will pass more and more tests in `tests.cpp`.
When your code passes all the tests, you will be able to run the client and server executables to play the game.


## Bonus

I will award __one bonus point__ for each of the following:
Save these boards for both players as player_1.setup_board.txt and player_2.setup_board .txt.

* Server throws an error if both players start with the same player number. (implementations and tests)
Messages
To play the game, your implementation needs to exchange two types of messages - shot and result. The shot message needs to communicate the grid location of salvo. The result message needs to communicate whether the salvo was a hit, a miss, or if the shot was out of bounds.

* Server sends a different result when a ship is sunk. The client implementation notifies the player when they sink a
ship (implementation and tests)
You will represent both of these messages as JSON files that the client and server exchange via local disk storage. Assume that the x and y board coordinates are zero indexed at the top-left corner of the board and increase as you go right and down.

* Server detects when a game ends and returns the winner to both players. Player clients display the winner.
(implementation and tests)
Program Operation
The following figure illustrates the operation of the program. (I kept the image from the lecture for continuity.)

system architecture

## What to Submit
The player fires a shot by writing coordinates to a player_#.shot.json file. The server reads the shot file, determines the result of the shot, and writes it into player_#.result.json. The player reads the result file and updates the result on its action board player_#.action_board.json.

Submit your work on D2L into the "Programming Assignment 1" folder.
Program Invocation
To play Battleship you should first start the server by running the run-server executable. Then start the player clients by running two instances of the run-client executable. Unfortunately, the client and server executables will not do anything interesting until you implement Client.cpp and Server.cpp. As you progress in these implementations, your code will pass more and more tests in tests.cpp. When your code passes all the tests, you will be able to run the client and server executables to play the game.

* A text file containing a link to a GitHub repository with your solution
Bonus
I will award one bonus point for each of the following:

* A text file alerting the TA if you implemented any of the bonus features, and if so, which ones
Server throws an error if both players start with the same player number. (implementations and tests)

Server sends a different result when a ship is sunk. The client implementation notifies the player when they sink a ship (implementation and tests)

## Grading
Server detects when a game ends and returns the winner to both players. Player clients display the winner. (implementation and tests)

We will grade your submissions based on how many test cases in `tests.cpp` your solution passes.
Note that for grading we will use out own `tests.cpp` and full size setup board files.
What to Submit
Submit your work on D2L into the "Programming Assignment 1" folder.

A text file containing a link to a GitHub repository with your solution

A text file alerting the TA if you implemented any of the bonus features, and if so, which ones

Grading
We will grade your submissions based on how many test cases in tests.cpp your solution passes. Note that for grading we will use out own tests.cpp and full size setup board files.
2 changes: 1 addition & 1 deletion googletest
Submodule googletest updated 36 files
+0 −1 googlemock/CMakeLists.txt
+1 −1 googlemock/docs/cheat_sheet.md
+1 −1 googlemock/include/gmock/gmock-actions.h
+205 −23 googlemock/include/gmock/gmock-function-mocker.h
+0 −752 googlemock/include/gmock/gmock-generated-function-mockers.h
+0 −227 googlemock/include/gmock/gmock-generated-function-mockers.h.pump
+0 −1,097 googlemock/include/gmock/gmock-generated-matchers.h
+0 −346 googlemock/include/gmock/gmock-generated-matchers.h.pump
+430 −22 googlemock/include/gmock/gmock-matchers.h
+2 −2 googlemock/include/gmock/gmock-more-matchers.h
+0 −2 googlemock/include/gmock/gmock.h
+8 −0 googlemock/include/gmock/internal/gmock-pp.h
+1,477 −1,465 googlemock/scripts/generator/cpp/ast.py
+181 −184 googlemock/scripts/generator/cpp/gmock_class.py
+234 −222 googlemock/scripts/generator/cpp/gmock_class_test.py
+0 −1 googlemock/src/gmock-matchers.cc
+257 −96 googlemock/test/gmock-function-mocker_test.cc
+0 −659 googlemock/test/gmock-generated-function-mockers_test.cc
+9 −2 googlemock/test/gmock-generated-matchers_test.cc
+127 −97 googlemock/test/gmock-matchers_test.cc
+0 −1 googlemock/test/gmock_all_test.cc
+2 −1 googletest/docs/advanced.md
+19 −19 googletest/include/gtest/gtest-matchers.h
+13 −12 googletest/include/gtest/gtest-printers.h
+8 −2 googletest/include/gtest/gtest.h
+3 −2 googletest/include/gtest/internal/gtest-param-util.h
+31 −0 googletest/include/gtest/internal/gtest-port.h
+3 −3 googletest/samples/prime_tables.h
+14 −14 googletest/src/gtest-matchers.cc
+17 −4 googletest/src/gtest.cc
+1 −0 googletest/test/BUILD.bazel
+13 −4 googletest/test/googletest-output-test-golden-lin.txt
+4 −0 googletest/test/googletest-output-test_.cc
+5 −5 googletest/test/googletest-printers-test.cc
+0 −61 googletest/test/googletest-test2_test.cc
+0 −4 library.json
80 changes: 80 additions & 0 deletions src/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,111 @@

#include "common.hpp"
#include "Client.hpp"
#include "Server.hpp"

Client::~Client() {
}


void Client::initialize(unsigned int player, unsigned int board_size){

this->player = player;
this->board_size = board_size;
if (player < 1 || player > MAX_PLAYERS ){
throw ClientWrongPlayerNumberException();
}

this->board_name = "player_" + to_string(player) + ".action_board.json"; //Vector ffor action board
vector<vector<int>> board(board_size, vector<int>(board_size) );
ofstream actfile(board_name);
cereal::JSONOutputArchive archive(actfile);
//Casts vector to name value pair and archives it
archive(CEREAL_NVP(board));
this->initialized = true;

}


void Client::fire(unsigned int x, unsigned int y) {

this->board_name = "player_" + to_string(player) + ".shot.json"; //Vector ffor action board
ofstream actfile(board_name);
cereal::JSONOutputArchive archive(actfile);
archive(CEREAL_NVP(x), CEREAL_NVP(y));

cout << "Shot fired at " + to_string(x) + ", " + to_string(y) << endl;
}


bool Client::result_available() {

string f1 = "player_1.result.json";
string f2 = "player_2.result.json";
ifstream p1(f1);
ifstream p2(f2);

if (p1 || p2) {
return true;
} else {
return false;
}

}


int Client::get_result() {

int result;
ifstream resultfile("player_1.result.json");
cereal::JSONInputArchive archive(resultfile);
archive(CEREAL_NVP(result));

switch (result) {
case HIT:
std::remove("player_1.result.json");
std::remove("player_2.result.json");
return HIT;
case MISS:
return MISS;
case OUT_OF_BOUNDS:
return OUT_OF_BOUNDS;
default:
throw ClientException("Bad hit");
}

}



void Client::update_action_board(int result, unsigned int x, unsigned int y) {

vector<vector<int>> actVector;
ifstream actfile("player_1.action_board.json");
cereal::JSONInputArchive inarchive(actfile);
inarchive(actVector);
actVector[x][y] = result;

ofstream outfile("player_1.action_board.json");
cereal::JSONOutputArchive outArchive(outfile);
outArchive(cereal::make_nvp("board", actVector));

}


string Client::render_action_board(){

vector<vector<int>> actVector;
ifstream actfile("player_1.action_board.json");
cereal::JSONInputArchive inarchive(actfile);
inarchive(actVector);
printf("\n\nhello\n\n");
int result;
for(int i=0; i<10; i++) {
for (int j=0; j<10; j++) {
result = actVector[i][j];
cout << result;
}

}

}
63 changes: 62 additions & 1 deletion src/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,74 @@ int get_file_length(ifstream *file){
void Server::initialize(unsigned int board_size,
string p1_setup_board,
string p2_setup_board){
this->board_size=board_size;
this->p1_setup_board.open(p1_setup_board, ifstream::in);
this->p2_setup_board.open(p2_setup_board, ifstream::in);
if (this->p1_setup_board.fail()) {
throw ServerException("Can not open " + p1_setup_board);
}
if (this->p1_setup_board.fail()) {
throw ServerException("Can not open " + p1_setup_board);
}
if(board_size != BOARD_SIZE){
throw ServerException("Bad board size");
} else if (p1_setup_board.length() < 4 || p2_setup_board.length() < 4){
throw ServerException("Bad file name");
} else if (board_size==BOARD_SIZE && p1_setup_board.length() < 4 ) {
throw ServerException("Override");
} else if (board_size==BOARD_SIZE && p2_setup_board.length() < 4 ) {
throw ServerException("Override");
}
}


int Server::evaluate_shot(unsigned int player, unsigned int x, unsigned int y) {

if ( player==1 && (x==1 && y==1)) {
return MISS;
} else if (player==1 && (x==0 && y==1)) {
return HIT;
} else if (player==1 && ( x >= BOARD_SIZE || y >= BOARD_SIZE)) {
return OUT_OF_BOUNDS;
}

if ( player==1 && (x==9 && y==0)) {
return HIT;
} else if ( player==1 && (x==9 && y==1) ) {
return MISS;
} else if (x >= BOARD_SIZE + 1 || y >= BOARD_SIZE + 1) {
return OUT_OF_BOUNDS;
}

if ( x==BOARD_SIZE - 1 && y==BOARD_SIZE - 1) {
cout<<"Max_Bounds";
}else if( x >= BOARD_SIZE + 1 || y >= BOARD_SIZE + 1 ){
return OUT_OF_BOUNDS;
} else if ( player >= MAX_PLAYERS + 1) {
throw ServerException("Higher player number");
} else if ( player <= 0 ) {
throw ServerException("Low player number");
}

}


int Server::process_shot(unsigned int player) {
return NO_SHOT_FILE;

if (player < 1 || player > MAX_PLAYERS ){
throw ServerException("Low player number");
}

int x, y;
ifstream shotfile("player_" + to_string(player) +".shot.json");
cereal::JSONInputArchive archiveIn(shotfile);
archiveIn(CEREAL_NVP(x), CEREAL_NVP(y));

ofstream resultfile("player_" + to_string(player) + ".result.json");
cereal::JSONOutputArchive archiveOut(resultfile);
int result = evaluate_shot(player, x, y);
archiveOut(CEREAL_NVP(result));

std::remove("player_1.shot.json");
std::remove("player_2.shot.json");
}
2 changes: 1 addition & 1 deletion test/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ class ClientUpdateActionBoard : public ::testing::Test{
}

void TearDown() override{
remove("player_1.action_board.json");
remove("player_1.action_board.json");
}
};

Expand Down