diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6502eb1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,55 @@
+# Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf
+
+.idea/*
+cmake-build-debug/*
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..59fb7e4
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "cereal"]
+ path = cereal
+ url = git@github.com:USCiLab/cereal.git
+[submodule "googletest"]
+ path = googletest
+ url = git@github.com:google/googletest.git
+[submodule "dtl"]
+ path = dtl
+ url = git@github.com:cubicdaiya/dtl.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..996cc90
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.6)
+
+project(Battleship)
+enable_language(ASM_NASM)
+
+set(CMAKE_CXX_STANDARD 14)
+
+add_subdirectory(googletest)
+
+add_subdirectory(src)
+
+add_subdirectory(test)
+
+
+
diff --git a/README.md b/README.md
index 0d7ba70..8f04e76 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,79 @@
-CSCI_366_Programming_Assignments
+# CSCI 466 PA2 - Bit Board Storage
+
+## Instructions
+
+
+Complete the following assignment individually.
+Submit your work on D2L into the "Programming Assignment 2" folder.
+
+
+## Learning Objectives
+
+In this programming assignment you will:
+
+- Implement a class to store the setup board as bits. The core functionality of your class will be implemented in the
+ Netwide Assembler (NASM).
+
+
+## Overview
+
+Your objective is to extend your basic implementation of the
+[Battleship](https://en.wikipedia.org/wiki/Battleship_\(game\))
+game to store the player setup boards in two dimensional bit arrays.
+The core of the idea is that the `Server` reads in the player setup boards and instead of referencing the file to
+ evaluate each shot, it saves the board in internal memory.
+You might wonder why not store the board in a two dimensional vector?
+Well, since all we want to store is whether a ship is present in a given position, using a vector, even just of bytes, still uses 8 bits for every ship position.
+We want to get this down to one bit.
+Of course you could use something like an array of [bitsets](http://www.cplusplus.com/reference/bitset/bitset/), but
+ you can save even more memory by implementing a two dimensional bit storage yourself in assembly.
+For very large data sets, or on very memory-constrained devices, every bit counts!
+
+To complete this assignment you will extend your current implementation of Battleship.
+I have added some functions that you'll need to implement, but most of your `Server` code should carry over.
+Your `Client` code will remain unchanged.
+I have also added a few tests to check the new functionality, while keeping all the old tests in tact.
+So, if you have those working, great!
+If not, you can earn back some points by getting your code to pass the tests you missed in PA1.
+
+
+## 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:
+
+* Server sends a different result when a ship is sunk. The client implementation notifies the player when they sink a
+ ship (implementation and tests).
+ This will require you to store more than 1 bit in the setup board array - you will also need to store ship type.
+
+
+## What to Submit
+
+Submit your work on D2L into the "Programming Assignment 2" folder.
+
+* A text file containing a link to a GitHub repository with your solution for the base assignment.
+Please not that your repository should be private, so that other students cannot see your solutions.
+You can create an unlimited number of private repositories by upgrading your github account to the pro version for
+ free using the [academic discount](https://help.github.com/en/github/teaching-and-learning-with-github-education/applying-for-an-educator-or-researcher-discount) with your school email.
+In order for us to be able to see your solution, please add github users `cooperstrahan` and `mwittie` as
+ collaborators through repository settings.
+
+* If you implement the bonus solution, please submit a YouTube video of your implementation.
+Be sure to show the tests you have written as well as your assembly code.
+
+
+## Grading
+
+We will grade your submissions based on how many test cases in `tests.cpp` your solution passes.
+
+
+
diff --git a/cereal b/cereal
new file mode 160000
index 0000000..a5a3095
--- /dev/null
+++ b/cereal
@@ -0,0 +1 @@
+Subproject commit a5a30953125e70b115a28dd76b64adf3c97cc883
diff --git a/dtl b/dtl
new file mode 160000
index 0000000..6b030d6
--- /dev/null
+++ b/dtl
@@ -0,0 +1 @@
+Subproject commit 6b030d6397909e7658cf785f369f647f40c046c1
diff --git a/googletest b/googletest
new file mode 160000
index 0000000..8b4817e
--- /dev/null
+++ b/googletest
@@ -0,0 +1 @@
+Subproject commit 8b4817e3df3746a20502a84580f661ac448821be
diff --git a/images/system_architecture.png b/images/system_architecture.png
new file mode 100644
index 0000000..d187f89
Binary files /dev/null and b/images/system_architecture.png differ
diff --git a/player_1.setup_board.txt b/player_1.setup_board.txt
new file mode 100644
index 0000000..64e30ab
--- /dev/null
+++ b/player_1.setup_board.txt
@@ -0,0 +1,10 @@
+CCCCC_____
+BBBB______
+RRR_______
+SSS_______
+D_________
+D_________
+__________
+__________
+__________
+__________
diff --git a/player_2.setup_board.txt b/player_2.setup_board.txt
new file mode 100644
index 0000000..45285e5
--- /dev/null
+++ b/player_2.setup_board.txt
@@ -0,0 +1,10 @@
+C________D
+C_________
+C_________
+C_________
+CBBBB_____
+_______RRR
+_________S
+_________S
+_________S
+D_________
diff --git a/src/BitArray2D.asm b/src/BitArray2D.asm
new file mode 100644
index 0000000..c1d3cb9
--- /dev/null
+++ b/src/BitArray2D.asm
@@ -0,0 +1,38 @@
+
+ global set_bit_elem
+ global get_bit_elem
+ section .text
+
+set_bit_elem:
+ push rbp ; save the base pointer on the stack (at rsp+8)
+ mov rbp, rsp ; set up the rbp for the bottom of this frame
+
+ ; rdi contains array pointer
+ ; rsi contains row width
+ ; rdx contains row
+ ; rcx contains col
+
+ ; add your code here
+
+ mov rsp, rbp ; restore stack pointer to before we pushed parameters onto the stack
+ pop rbp ; remove rbp from the stack to restore rsp to initial value
+ ret ; return value in rax
+
+
+
+
+get_bit_elem:
+ push rbp ; save the base pointer on the stack (at rsp+8)
+ mov rbp, rsp ; set up the rbp for the bottom of this frame
+
+ ; rdi contains array pointer
+ ; rsi contains row width
+ ; rdx contains row
+ ; rcx contains col
+
+ ; add your code here - for now returning 0
+ mov rax, 0
+
+ mov rsp, rbp ; restore stack pointer to before we pushed parameters onto the stack
+ pop rbp ; remove rbp from the stack to restore rsp to initial value
+ ret ; return value in rax
diff --git a/src/BitArray2D.cpp b/src/BitArray2D.cpp
new file mode 100644
index 0000000..984f7a6
--- /dev/null
+++ b/src/BitArray2D.cpp
@@ -0,0 +1,44 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+#include "BitArray2D.hpp"
+
+BitArray2D::BitArray2D(unsigned int rows, unsigned int columns) {
+
+}
+
+
+BitArray2D::~BitArray2D() {
+
+}
+
+
+bool BitArray2D::get(unsigned int row, unsigned int column){
+ // check array bounds
+
+ // get the element
+ return get_bit_elem(array, columns, row, column);
+}
+
+
+
+void BitArray2D::set(unsigned int row, unsigned int column){
+ // check array bounds
+
+ // set the element
+ set_bit_elem(array, columns, row, column);
+}
diff --git a/src/BitArray2D.hpp b/src/BitArray2D.hpp
new file mode 100644
index 0000000..1efc7c0
--- /dev/null
+++ b/src/BitArray2D.hpp
@@ -0,0 +1,110 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+
+
+#include
+#include
+
+#ifndef BATTLESHIP_BITARRAY2D_HPP
+#define BATTLESHIP_BITARRAY2D_HPP
+
+using namespace std;
+
+class BitArray2DException: public exception
+{
+private:
+ char *cstr;
+
+public:
+ BitArray2DException(string message){
+ cstr = new char[message.size() + 1];
+ message.copy(cstr, message.size() + 1);
+ cstr[message.size()] = '\0';
+ }
+
+ ~BitArray2DException(){
+ delete cstr;
+ }
+
+ virtual const char* what() const throw(){
+ return cstr;
+ }
+};
+
+
+/**
+ * Sets a bit in a two dimensional bit array
+ * @param array - pointer to a bit array
+ * @param row_width - the number of bits in a row of the two dimensional array
+ * @param row - row index (0 indexed)
+ * @param col - column index (0 indexed)
+ */
+extern "C" void set_bit_elem(char *array, unsigned int row_width, unsigned int row, unsigned int col);
+
+/**
+ * Gets a bit in a two dimensional bit array
+ * @param array - pointer to a bit array
+ * @param row_width - the number of bits in a row of the two dimensional array
+ * @param row - row index (0 indexed)
+ * @param col - column index (0 indexed)
+ * @return a boolean containing the bit at [row][column]
+ */
+extern "C" bool get_bit_elem(char *array, unsigned int row_width, unsigned int row, unsigned int col);
+
+
+class BitArray2D {
+private:
+ /**
+ * The 'char' types does not mean that each bit is stored as a character - we just need the pointer
+ * to have some type since there is no type for bit.
+ */
+ char* array = nullptr;
+
+ unsigned int rows;
+ unsigned int columns;
+
+public:
+ /**
+ * Sets up the array to store rows * columns bits
+ * @param rows - number of rows
+ * @param columns - number of columns
+ */
+ BitArray2D(unsigned int rows, unsigned int columns);
+
+ /**
+ * Deallocate memory used for array
+ */
+ ~BitArray2D();
+
+ /**
+ * Get bit at row and column
+ * @param row
+ * @param column
+ * @return bit at row and column as bool
+ */
+ bool get(unsigned int row, unsigned int column);
+
+ /**
+ * Set bit to true at row and column
+ * @param row
+ * @param column
+ */
+ void set(unsigned int row, unsigned int column);
+};
+
+
+#endif //BATTLESHIP_BIT_ARRAY_HPP
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..409d93e
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,19 @@
+#copy the board files into runtime directory
+configure_file(${PROJECT_SOURCE_DIR}/player_1.setup_board.txt ${PROJECT_SOURCE_DIR}/cmake-build-debug/src/player_1.setup_board.txt COPYONLY)
+configure_file(${PROJECT_SOURCE_DIR}/player_2.setup_board.txt ${PROJECT_SOURCE_DIR}/cmake-build-debug/src/player_2.setup_board.txt COPYONLY)
+
+# convert player setup boards to unix line endings
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/src/player_1.setup_board.txt)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/src/player_2.setup_board.txt)
+
+include_directories(${PROJECT_SOURCE_DIR}/cereal/include)
+
+set_source_files_properties(BitArray2D.asm PROPERTIES COMPILE_FLAGS "-g -Fdwarf")
+
+add_library(SERVER Server.cpp Server.hpp BitArray2D.cpp BitArray2D.hpp BitArray2D.asm)
+
+add_library(CLIENT Client.cpp Client.hpp)
+
+add_executable(run_server server_main.cpp Server.cpp BitArray2D.cpp BitArray2D.hpp BitArray2D.asm)
+
+add_executable(run_client client_main.cpp Client.cpp BitArray2D.cpp BitArray2D.hpp BitArray2D.asm)
diff --git a/src/Client.cpp b/src/Client.cpp
new file mode 100644
index 0000000..0b2835e
--- /dev/null
+++ b/src/Client.cpp
@@ -0,0 +1,46 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "common.hpp"
+#include "Client.hpp"
+
+Client::~Client() {
+}
+
+
+void Client::initialize(unsigned int player, unsigned int board_size){
+}
+
+
+void Client::fire(unsigned int x, unsigned int y) {
+}
+
+
+bool Client::result_available() {
+}
+
+
+int Client::get_result() {
+}
+
+
+
+void Client::update_action_board(int result, unsigned int x, unsigned int y) {
+}
+
+
+string Client::render_action_board(){
+}
\ No newline at end of file
diff --git a/src/Client.hpp b/src/Client.hpp
new file mode 100644
index 0000000..5777ebd
--- /dev/null
+++ b/src/Client.hpp
@@ -0,0 +1,110 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+class ClientWrongPlayerNumberException: public exception{
+public:
+ virtual const char* what() const throw(){
+ return "Player number our of bounds.";
+ }
+};
+
+class ClientException: public exception
+{
+private:
+ char *cstr;
+
+public:
+ ClientException(string message){
+ cstr = new char[message.size() + 1];
+ message.copy(cstr, message.size() + 1);
+ cstr[message.size()] = '\0';
+ }
+
+ ~ClientException(){
+ delete cstr;
+ }
+
+ virtual const char* what() const throw(){
+ return cstr;
+ }
+};
+
+class Client {
+private:
+ unsigned int player;
+ string board_name;
+public:
+ unsigned int board_size;
+ bool initialized = false;
+
+public:
+ /**
+ * Destructor to remove the action board created in initialize()
+ */
+ ~Client();
+
+ /**
+ * Performs the initialization functions that normally would be in a constructor, but needs to be a separate
+ * function for googletest so clients may be initialized in the SetUp() function.
+ * Creates player_#.action_board.json.
+ * @param player - the id of the player
+ * @param board_size - the square size of the action board
+ */
+ void initialize(unsigned int player, unsigned int board_size);
+
+ /**
+ * Fires a shot on the coordinate target and creates a player_#.shot.json file
+ * @param x - coordinate
+ * @param y - coordinate
+ */
+ void fire(unsigned int x, unsigned int y);
+
+ /**
+ * Checks if a result file is available for
+ * @return true if result is available, false otherwise
+ */
+ bool result_available();
+
+ /**
+ * Gets the result from the player_#.result.json
+ * @return the result as either HIT, MISS, or OUT_OF_BOUNDS
+ */
+ int get_result();
+
+ /**
+ * Updates the internal representation of player_#.action_board.json on the result of a shot.
+ * @param result - the result returned from the server
+ * @param x - coordinate
+ * @param y - coordinate
+ */
+ void update_action_board(int result, unsigned int x, unsigned int y);
+
+ /**
+ * Formats a string representing player_#.action_board.json as ASCII
+ * @return ASCII representation of the action board
+ */
+ string render_action_board();
+
+};
+
+
diff --git a/src/Server.cpp b/src/Server.cpp
new file mode 100644
index 0000000..6429ab7
--- /dev/null
+++ b/src/Server.cpp
@@ -0,0 +1,51 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+
+#include "common.hpp"
+#include "Server.hpp"
+
+
+/**
+ * Calculate the length of a file (helper function)
+ *
+ * @param file - the file whose length we want to query
+ * @return length of the file in bytes
+ */
+int get_file_length(ifstream *file){
+}
+
+
+void Server::initialize(unsigned int board_size,
+ string p1_setup_board,
+ string p2_setup_board){
+}
+
+
+Server::~Server() {
+}
+
+
+BitArray2D *Server::scan_setup_board(string setup_board_name){
+}
+
+int Server::evaluate_shot(unsigned int player, unsigned int x, unsigned int y) {
+}
+
+
+int Server::process_shot(unsigned int player) {
+ return NO_SHOT_FILE;
+}
\ No newline at end of file
diff --git a/src/Server.hpp b/src/Server.hpp
new file mode 100644
index 0000000..91d8e12
--- /dev/null
+++ b/src/Server.hpp
@@ -0,0 +1,116 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "BitArray2D.hpp"
+
+#define SHOT_FILE_PROCESSED 0
+#define NO_SHOT_FILE 1
+
+#define SHIPS "CBRSD" //Carrier, Battleship, cRuiser, Submarine, and Destroyer
+
+using namespace std;
+
+
+class ServerException: public exception
+{
+private:
+ char *cstr;
+
+public:
+ ServerException(string message){
+ cstr = new char[message.size() + 1];
+ message.copy(cstr, message.size() + 1);
+ cstr[message.size()] = '\0';
+ }
+
+ ~ServerException(){
+ delete cstr;
+ }
+
+ virtual const char* what() const throw(){
+ return cstr;
+ }
+};
+
+class Server{
+public:
+ unsigned int board_size;
+
+private:
+
+ BitArray2D *p1_setup_board = nullptr;
+ BitArray2D *p2_setup_board = nullptr;
+
+ /**
+ * Sets up a BitArray2D pointer with bits filled in based on a setup_board_name
+ * @param setup_board_name - the name of the setup board file
+ * @return an internally allocated pointer to a BitArray2D object
+ */
+ BitArray2D *scan_setup_board(string setup_board_name);
+
+public:
+ /**
+ * Performs Server initialization
+ *
+ * Need to do initialization outside of the constructor, so that the object may be initialized inside the
+ * googletest SetUp() method.
+ * The method opens player setup boards containing ship positions and checks the size of boards compared to
+ * board_size parameter.
+ * @param board_size - the size of a square board
+ * @param p1_setup_board - file name of player 1's board
+ * @param p2_setup_board - file name of player 2's board
+ */
+ void initialize(unsigned int board_size,
+ string p1_setup_board,
+ string p2_setup_board);
+
+ /**
+ * Checks the coordinates of a shot against setup board of player
+ *
+ * Check that player number within bounds, checks that shot coordinates within bounds, determines if the shot
+ * results in a HIT, or a MISS.
+ * @param player - player number
+ * @param x - coordinate
+ * @param y - coordinate
+ * @return returns shot result as either HIT, MISS, or OUT_OF_BOUNDS
+ */
+ int evaluate_shot(unsigned int player, unsigned int x, unsigned int y);
+
+ /**
+ * Processes a shot issued by player
+ *
+ * Gets the shot from player, extracts coordinates, passes the information of evaluate_shot, and writes the result
+ * into player_#.result.json.
+ * @param player - player number
+ * @return returns SHOT_PROCESSED, or NO_SHOT_FILE if nothing to process
+ */
+ int process_shot(unsigned int player);
+
+ /**
+ * Deallocates Server memory
+ */
+ ~Server();
+};
diff --git a/src/client_main.cpp b/src/client_main.cpp
new file mode 100644
index 0000000..153c464
--- /dev/null
+++ b/src/client_main.cpp
@@ -0,0 +1,70 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+
+#include "common.hpp"
+#include "Client.hpp"
+
+#include
+#include
+
+int main()
+{
+ printf("Starting Battleship client\n");
+
+ // initialize the client with a correct player number
+ Client c;
+ while(! c.initialized){
+ try{
+ cout << "Enter player number: ";
+ int player;
+ cin >> player;
+ c.initialize(player, BOARD_SIZE);
+ } catch (ClientWrongPlayerNumberException& e){
+ cout << e.what() << '\n';
+ }
+
+ }
+
+ // keep firing and updating the action board with results from the server
+ unsigned int x, y;
+ while(true){
+ // get coordinates
+ cout << "Enter fire x position: ";
+ cin >> x;
+ cout << "Enter fire y position: ";
+ cin >> y;
+
+ // fire and get result
+ c.fire(x, y);
+ while(! c.result_available()) {
+ cout << "Waiting for result" << endl;
+ this_thread::sleep_for(std::chrono::milliseconds(2000));
+ }
+ int result = c.get_result();
+ printf("Shot at (%d, %d) result %d\n", x, y, result);
+ if(result == OUT_OF_BOUNDS){
+ cout << "Entered coordinates are out of bounds" << "\n";
+ continue;
+ }
+
+ // update the action board
+ c.update_action_board(result, x, y);
+ cout << c.render_action_board();
+ }
+
+ return 0;
+}
diff --git a/src/common.hpp b/src/common.hpp
new file mode 100644
index 0000000..2c05682
--- /dev/null
+++ b/src/common.hpp
@@ -0,0 +1,27 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#ifndef BATTLESHIP_COMMON_H
+#define BATTLESHIP_COMMON_H
+
+#define MAX_PLAYERS 2
+#define HIT 1
+#define MISS -1
+#define OUT_OF_BOUNDS 0
+
+#define BOARD_SIZE 10
+
+#endif //BATTLESHIP_COMMON_H
diff --git a/src/server_main.cpp b/src/server_main.cpp
new file mode 100644
index 0000000..121643a
--- /dev/null
+++ b/src/server_main.cpp
@@ -0,0 +1,44 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "common.hpp"
+#include "Server.hpp"
+
+#include
+#include
+
+
+int main(){
+ cout << "Starting Battleship server" << endl;
+
+ Server s;
+ s.initialize(BOARD_SIZE, "player_1.setup_board.txt", "player_2.setup_board.txt");
+
+ // run the server process in a loop
+ while(true){
+ while(s.process_shot(1) == NO_SHOT_FILE) {
+ cout << "Waiting for shot from player 1" << endl;
+ this_thread::sleep_for(std::chrono::milliseconds(2000));
+ }
+ cout << "Processed shot from player 1" << endl;
+ while(s.process_shot(2) == NO_SHOT_FILE) {
+ cout << "Waiting for shot from player 2" << endl;
+ this_thread::sleep_for(std::chrono::milliseconds(2000));
+ }
+ cout << "Processed shot from player 2" << endl;
+ }
+
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..7323c9b
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,41 @@
+#copy the board files into runtime directory
+configure_file(${PROJECT_SOURCE_DIR}/player_1.setup_board.txt ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/player_1.setup_board.txt COPYONLY)
+configure_file(${PROJECT_SOURCE_DIR}/player_2.setup_board.txt ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/player_2.setup_board.txt COPYONLY)
+
+# copy test action boards into runtime directory
+configure_file(${PROJECT_SOURCE_DIR}/test/correct_start_action_board.json
+ ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_start_action_board.json
+ COPYONLY)
+configure_file(${PROJECT_SOURCE_DIR}/test/correct_fire_message.json
+ ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_fire_message.json
+ COPYONLY)
+configure_file(${PROJECT_SOURCE_DIR}/test/correct_hit_action_board.json
+ ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_hit_action_board.json
+ COPYONLY)
+configure_file(${PROJECT_SOURCE_DIR}/test/correct_miss_action_board.json
+ ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_miss_action_board.json
+ COPYONLY)
+configure_file(${PROJECT_SOURCE_DIR}/test/correct_hit_result.json
+ ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_hit_result.json
+ COPYONLY)
+configure_file(${PROJECT_SOURCE_DIR}/test/correct_miss_result.json
+ ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_miss_result.json
+ COPYONLY)
+configure_file(${PROJECT_SOURCE_DIR}/test/correct_out_of_bounds_result.json
+ ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_out_of_bounds_result.json
+ COPYONLY)
+
+# convert boards to unix line endings
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/player_1.setup_board.txt)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/player_2.setup_board.txt)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_start_action_board.json)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_fire_message.json)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_hit_action_board.json)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_miss_action_board.json)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_hit_result.json)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_miss_result.json)
+execute_process(COMMAND dos2unix ${PROJECT_SOURCE_DIR}/cmake-build-debug/test/correct_out_of_bounds_result.json)
+
+add_executable(battleship_tests tests.cpp)
+include_directories(${PROJECT_SOURCE_DIR}/dtl/dtl ${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/cereal/include)
+target_link_libraries(battleship_tests SERVER CLIENT gtest gmock_main)
\ No newline at end of file
diff --git a/test/correct_fire_message.json b/test/correct_fire_message.json
new file mode 100644
index 0000000..b1ecb78
--- /dev/null
+++ b/test/correct_fire_message.json
@@ -0,0 +1,4 @@
+{
+ "x": 0,
+ "y": 1
+}
\ No newline at end of file
diff --git a/test/correct_hit_action_board.json b/test/correct_hit_action_board.json
new file mode 100644
index 0000000..84172a1
--- /dev/null
+++ b/test/correct_hit_action_board.json
@@ -0,0 +1,124 @@
+{
+ "board": [
+ [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/test/correct_hit_result.json b/test/correct_hit_result.json
new file mode 100644
index 0000000..688ec1f
--- /dev/null
+++ b/test/correct_hit_result.json
@@ -0,0 +1,3 @@
+{
+ "result": 1
+}
\ No newline at end of file
diff --git a/test/correct_miss_action_board.json b/test/correct_miss_action_board.json
new file mode 100644
index 0000000..67f68a0
--- /dev/null
+++ b/test/correct_miss_action_board.json
@@ -0,0 +1,124 @@
+{
+ "board": [
+ [
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/test/correct_miss_result.json b/test/correct_miss_result.json
new file mode 100644
index 0000000..ca4f6be
--- /dev/null
+++ b/test/correct_miss_result.json
@@ -0,0 +1,3 @@
+{
+ "result": -1
+}
\ No newline at end of file
diff --git a/test/correct_out_of_bounds_result.json b/test/correct_out_of_bounds_result.json
new file mode 100644
index 0000000..48777f7
--- /dev/null
+++ b/test/correct_out_of_bounds_result.json
@@ -0,0 +1,3 @@
+{
+ "result": 0
+}
\ No newline at end of file
diff --git a/test/correct_result_message.json b/test/correct_result_message.json
new file mode 100644
index 0000000..688ec1f
--- /dev/null
+++ b/test/correct_result_message.json
@@ -0,0 +1,3 @@
+{
+ "result": 1
+}
\ No newline at end of file
diff --git a/test/correct_start_action_board.json b/test/correct_start_action_board.json
new file mode 100644
index 0000000..a6c495c
--- /dev/null
+++ b/test/correct_start_action_board.json
@@ -0,0 +1,124 @@
+{
+ "board": [
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/test/tests.cpp b/test/tests.cpp
new file mode 100644
index 0000000..b9190e7
--- /dev/null
+++ b/test/tests.cpp
@@ -0,0 +1,424 @@
+// Battleship game assignment for MSU CSCI 366
+// Copyright (C) 2020 Mike P. Wittie
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+
+#include
+#include
+#include
+
+#include "common.hpp"
+#include "Server.hpp"
+#include "Client.hpp"
+
+
+
+/**
+ * Compute the diff distance between two files using the dtl library
+ * @param file1 - name of the first file
+ * @param file2 - name of the second file
+ * @return distance between the contents of two files
+ */
+#include // a library for diffing strings
+long get_diff_dist(string file1, string file2){
+ // load the file contents
+ ifstream ifstr1(file1);
+ string file1_S((std::istreambuf_iterator(ifstr1)),
+ std::istreambuf_iterator());
+ ifstr1.close();
+ ifstream ifstr2(file2);
+ string file2_S((std::istreambuf_iterator(ifstr2)),
+ std::istreambuf_iterator());
+ ifstr2.close();
+
+ // compute the distance between correct and constructed boards
+ dtl::Diff d(file1_S, file2_S);
+ d.onOnlyEditDistance();
+ d.compose();
+
+ return d.getEditDistance();
+}
+
+
+TEST(BitArray2DCreate, Correct_1by1){
+ BitArray2D *array;
+ ASSERT_NO_THROW(array = new BitArray2D(1,1));
+}
+
+TEST(BitArray2DCreate, Correct_10by10){
+ BitArray2D *array;
+ ASSERT_NO_THROW(array = new BitArray2D(10,10));
+}
+
+TEST(BitArray2DCreate, Incorrect){
+ BitArray2D *array;
+ ASSERT_ANY_THROW(array = new BitArray2D(0,0));
+}
+
+
+
+
+class BitArray2DSetGet : public ::testing::Test{
+protected:
+ BitArray2D *array;
+
+ void SetUp() override {
+ array = new BitArray2D(10, 10);
+ };
+
+ void TearDown() override{
+ delete array;
+ }
+
+};
+
+TEST_F(BitArray2DSetGet, Zero){
+ int row=0, col=0;
+ array->set(row, col);
+ ASSERT_EQ(1, array->get(row,col));
+}
+
+TEST_F(BitArray2DSetGet, One){
+ int row=0, col=1;
+ array->set(row, col);
+ ASSERT_EQ(1, array->get(row,col));
+}
+
+TEST_F(BitArray2DSetGet, Seven){
+ int row=0, col=7;
+ array->set(row, col);
+ ASSERT_EQ(1, array->get(row,col));
+}
+
+TEST_F(BitArray2DSetGet, Eight){
+ int row=0, col=8;
+ array->set(row, col);
+ ASSERT_EQ(1, array->get(row,col));
+}
+
+TEST_F(BitArray2DSetGet, Nine){
+ int row=0, col=9;
+ array->set(row, col);
+ ASSERT_EQ(1, array->get(row,col));
+}
+
+TEST_F(BitArray2DSetGet, Ten){
+ int row=9, col=1;
+ array->set(row, col);
+ ASSERT_EQ(1, array->get(row,col));
+}
+
+TEST_F(BitArray2DSetGet, Hundred){
+ int row=9, col=9;
+ array->set(row, col);
+ ASSERT_EQ(1, array->get(row,col));
+}
+
+TEST_F(BitArray2DSetGet, Get_Out_Of_Bounds_High){
+ ASSERT_ANY_THROW(array->get(BOARD_SIZE, BOARD_SIZE));
+}
+
+TEST_F(BitArray2DSetGet, Get_Out_Of_Bounds_Low){
+ ASSERT_ANY_THROW(array->get(-1, -1));
+}
+
+TEST_F(BitArray2DSetGet, Set_Out_Of_Bounds_High){
+ ASSERT_ANY_THROW(array->set(BOARD_SIZE, BOARD_SIZE));
+}
+
+TEST_F(BitArray2DSetGet, Set_Out_Of_Bounds_Low){
+ ASSERT_ANY_THROW(array->set(-1, -1));
+}
+
+class ServerInitialize : public ::testing::Test{
+protected:
+ Server srv;
+};
+
+TEST_F(ServerInitialize, Correct_Board_Size){
+ ASSERT_NO_THROW(srv.initialize(BOARD_SIZE, "player_1.setup_board.txt", "player_2.setup_board.txt"));
+}
+
+TEST_F(ServerInitialize, Wrong_Board_Size){
+ ASSERT_ANY_THROW(srv.initialize(BOARD_SIZE-1, "player_1.setup_board.txt", "player_2.setup_board.txt"));
+}
+
+TEST_F(ServerInitialize, Bad_File_Name){
+ ASSERT_ANY_THROW(srv.initialize(BOARD_SIZE, "", ""));
+}
+
+
+class ServerEvaluateShot : public ::testing::Test{
+protected:
+ Server srv;
+ void SetUp() override{
+ srv.initialize(BOARD_SIZE, "player_1.setup_board.txt", "player_2.setup_board.txt");
+ }
+};
+
+TEST_F(ServerEvaluateShot, Hit_Detected){
+ ASSERT_EQ(HIT, srv.evaluate_shot(1,9,0));
+}
+
+TEST_F(ServerEvaluateShot, Miss_Detected){
+ ASSERT_EQ(MISS, srv.evaluate_shot(1,9,1));
+}
+
+TEST_F(ServerEvaluateShot, Out_Of_Bounds_X_High){
+ ASSERT_EQ(OUT_OF_BOUNDS, srv.evaluate_shot(1,srv.board_size+1,1));
+}
+
+TEST_F(ServerEvaluateShot, Out_Of_Bounds_X_Low){
+ ASSERT_EQ(OUT_OF_BOUNDS, srv.evaluate_shot(1,-1,1));
+}
+
+TEST_F(ServerEvaluateShot, Out_Of_Bounds_Y_High){
+ ASSERT_EQ(OUT_OF_BOUNDS, srv.evaluate_shot(1,1,srv.board_size+1));
+}
+
+TEST_F(ServerEvaluateShot, Out_Of_Bounds_Y_Low){
+ ASSERT_EQ(OUT_OF_BOUNDS, srv.evaluate_shot(1,1,-1));
+}
+
+TEST_F(ServerEvaluateShot, Max_In_Bounds){
+ ASSERT_NO_THROW(srv.evaluate_shot(1,srv.board_size-1,srv.board_size-1));
+}
+
+TEST_F(ServerEvaluateShot, Bad_Player_Number_Low){
+ ASSERT_ANY_THROW(srv.evaluate_shot(0,0,0));
+}
+
+TEST_F(ServerEvaluateShot, Bad_Player_Number_High){
+ ASSERT_ANY_THROW(srv.evaluate_shot(MAX_PLAYERS+1,0,0));
+}
+
+
+class ServerProcessShot : public ::testing::Test{
+protected:
+ Server srv;
+
+ void set_up_shot(unsigned int x, unsigned int y){
+ string coords = "{\"x\": "+to_string(x)+",\"y\": "+to_string(y)+"}";
+ ofstream shot_file("player_1.shot.json");
+ shot_file << coords;
+ shot_file.close();
+ }
+
+ void SetUp() override{
+ srv.initialize(BOARD_SIZE, "player_1.setup_board.txt", "player_2.setup_board.txt");
+ }
+
+ void TearDown() override{
+ remove("player_1.shot.json");
+ remove("player_1.result.json");
+ }
+};
+
+
+TEST_F(ServerProcessShot, Hit_Detected){
+ set_up_shot(0, 1);
+ srv.process_shot(1);
+ ASSERT_EQ(0, get_diff_dist("correct_hit_result.json", "player_1.result.json"));
+}
+
+TEST_F(ServerProcessShot, Miss_Detected){
+ set_up_shot(1, 1);
+ srv.process_shot(1);
+ ASSERT_EQ(0, get_diff_dist("correct_miss_result.json", "player_1.result.json"));
+}
+
+TEST_F(ServerProcessShot, Out_Of_Bounds_X){
+ set_up_shot(srv.board_size, 0);
+ srv.process_shot(1);
+ ASSERT_EQ(0, get_diff_dist("correct_out_of_bounds_result.json", "player_1.result.json"));
+}
+
+TEST_F(ServerProcessShot, Out_Of_Bounds_Y){
+ set_up_shot(0, srv.board_size);
+ srv.process_shot(1);
+ ASSERT_EQ(0, get_diff_dist("correct_out_of_bounds_result.json", "player_1.result.json"));
+}
+
+TEST_F(ServerProcessShot, Max_In_Bounds){
+ set_up_shot(srv.board_size-1, srv.board_size-1);
+ ASSERT_NO_THROW(srv.process_shot(1));
+}
+
+TEST_F(ServerProcessShot, Bad_Player_Number_Low){
+ set_up_shot(0, 0);
+ ASSERT_ANY_THROW(srv.process_shot(0));
+}
+
+TEST_F(ServerProcessShot, Bad_Player_Number_Low_High){
+ set_up_shot(0, 0);
+ ASSERT_ANY_THROW(srv.process_shot(MAX_PLAYERS+1));
+}
+
+TEST_F(ServerProcessShot, Cleanup){
+ set_up_shot(0,0);
+ srv.process_shot(1);
+ ifstream f("player_1.shot.json");
+ ASSERT_FALSE(f.good());
+}
+
+
+class ClientInitialize : public ::testing::Test{
+protected:
+ Client client;
+
+ void SetUp() override{
+ client.initialize(1, BOARD_SIZE);
+ }
+
+ void TearDown() override{
+ remove("player_1.action_board.json");
+ }
+};
+
+TEST_F(ClientInitialize, Creates_Action_Board){
+ ASSERT_EQ(0, get_diff_dist("player_1.action_board.json", "correct_start_action_board.json"));
+}
+
+
+class ClientFire : public ::testing::Test{
+protected:
+ Client client;
+
+ void SetUp() override{
+ client.initialize(1, BOARD_SIZE);
+ }
+
+ void TearDown() override{
+ remove("player_1.shot.json");
+ }
+};
+
+TEST_F(ClientFire, Creates_Fire_Message){
+ client.fire(0,1);
+ ASSERT_EQ(0, get_diff_dist("player_1.shot.json", "correct_fire_message.json"));
+}
+
+
+class ClientResultAvailable : public ::testing::Test{
+protected:
+ Client client;
+
+ void set_up_result(int result){
+ string result_str = "{\n"
+ " \"result\": "+to_string(result)+"\n"
+ "}";
+ ofstream result_file("player_1.result.json");
+ result_file << result_str;
+ result_file.close();
+ }
+
+ void SetUp() override{
+ client.initialize(1, BOARD_SIZE);
+ }
+
+ void TearDown() override{
+ remove("player_1.result.json");
+ }
+};
+
+TEST_F(ClientResultAvailable, NoResultFile){
+ ASSERT_FALSE(client.result_available());
+}
+
+TEST_F(ClientResultAvailable, GoodFile){
+ set_up_result(HIT);
+ ASSERT_TRUE(client.result_available());
+}
+
+
+class ClientGetResult : public ::testing::Test{
+protected:
+ Client client;
+
+ void set_up_result(int result){
+ string result_str = "{\n"
+ " \"result\": "+to_string(result)+"\n"
+ "}";
+ ofstream result_file("player_1.result.json");
+ result_file << result_str;
+ result_file.close();
+ }
+
+ void SetUp() override{
+ client.initialize(1, BOARD_SIZE);
+ }
+
+ void TearDown() override{
+ remove("player_1.result.json");
+ }
+};
+
+TEST_F(ClientGetResult, Return_Hit){
+ set_up_result(HIT);
+ ASSERT_EQ(HIT, client.get_result());
+}
+
+TEST_F(ClientGetResult, Return_Miss){
+ set_up_result(MISS);
+ ASSERT_EQ(MISS, client.get_result());
+}
+
+TEST_F(ClientGetResult, Return_Out_Of_Bounds){
+ set_up_result(OUT_OF_BOUNDS);
+ ASSERT_EQ(OUT_OF_BOUNDS, client.get_result());
+}
+
+TEST_F(ClientGetResult, Catch_Bad_Result){
+ set_up_result(999);
+ ASSERT_ANY_THROW(client.get_result());
+}
+
+TEST_F(ClientGetResult, Cleanup){
+ set_up_result(HIT);
+ client.get_result();
+ ifstream f("player_1.result.json");
+ ASSERT_FALSE(f.good());
+}
+
+
+class ClientUpdateActionBoard : public ::testing::Test{
+protected:
+ Client client;
+
+ void SetUp() override{
+ client.initialize(1, BOARD_SIZE);
+ }
+
+ void TearDown() override{
+ remove("player_1.action_board.json");
+ }
+};
+
+TEST_F(ClientUpdateActionBoard, Record_Hit){
+ client.update_action_board(HIT, 0, 0);
+ ASSERT_EQ(0, get_diff_dist("player_1.action_board.json", "correct_hit_action_board.json"));
+}
+
+TEST_F(ClientUpdateActionBoard, Record_Miss){
+ client.update_action_board(MISS, 0, 0);
+
+ ASSERT_EQ(0, get_diff_dist("player_1.action_board.json", "correct_miss_action_board.json"));
+}
+
+
+