Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

In this assignment I must write an object-oriented implementation of the battles

ID: 3556813 • Letter: I

Question

In this assignment I must write an object-oriented implementation of the battleship board game.

The game is played on a board consisting of 100 cells arranged as a 10x10 square. Ten ships are
placed on the board. There are four kinds of ships. Each ship occupies a number of cells that
depends on the size of the ship. The ship types are

1) Aircraft carrier, size=5
2) Battleship, size=4
3) Cruiser, size=3
4) Destroyer, size=2

A ship occupies contiguous cells arranged as a rectangle of width=1 and height=size, or
width=size and height=1, i.e. the orientation of the rectangle can be horizontal or vertical. Ships
cannot overlap and cannot touch each other (either sideways or diagonally).

The following figure shows a valid arrangement of ships on the board.

http://gyazo.com/405014bc8d525c0e46ba017417bf15dc

The goal of this assignment is to implement classes representing ships.

The class Ship is an abstract base class from which four classes are derived:
AircraftCarrier, BattleShip, Cruiser and Destroyer. The header file is given below.

--------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------

My task is to write the implementation file Ship.cpp containing the implementation of all classes. I am not
allowed to modify the file Ship.h.

My class implementation file Ship.cpp should compile without warning using the command

$ g++ -Wall c Ship.cpp

I am also given a program testShip.cpp and a Makefile (listed below)
These two files should not be modified. The testShip.cpp program tests the functionality of
the Ship class. I should be able to build the executable testShip using the command

$ make

-------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------

testShip executable is used with provided input/outputs an can be ignored here as they are no provided.

Specification of the Ship Class
We describe here the detailed specification of the Ship class. The location of a ship is stored in
two pairs of integer variables (x1,y1) and (x2,y2) which specify the coordinates of the cells
located at both ends of the ship on the cell grid. The class includes a variable used to store the
current "level" of the ship (stored in the protected variable lev). The level will be used to keep
track of the number of times the ship has been hit during the game. When the ship is created, the
level is equal to the size of the ship. During the course of the game (later assignment) it will
be decreased by one every time the ship is hit.

Study carefully the file Ship.h. Some members are public, some protected and some private.
Some members are virtual. Make sure you understand why. Study the file testShip.cpp in
order to understand how the classes will be used.




Public members

virtual const char *name(void)
This function should return the name of the class instance as a C string, i.e.
AircraftCarrier, BattleShip, Cruiser or Destroyer.

virtual int size(void)
This function should return the size of the ship according to the sizes in the table given above.

int getX(int i)
This function returns the x coordinate of the ith cell of the ship. The value of i is in [0,size-1]
where size is the size of the ship. getX(0) should return x1 and getX(size( )-1) should
return x2. It is assumed that the argument i is valid i.e. it is in [0, size-1].

int getY(int i)
Same as getX but for the y coordinate.

void print(void)
This function prints information about the location of the ship by showing the cells occupied by
the ship. It should use the following format:

<name> from (<x1>,<y1>) to (<x2>,<y2>)


For example:

AircraftCarrier from (0,0) to (0,4)

bool includes(int x, int y)
This function should return true if the cell (x,y) is occupied by the ship, and false otherwise.

int level(void)
This function should return the current value of the protected variable lev

void decreaseLevel(void)
This function should decrease the variable lev by one. If the value of lev is zero, the value
should be unchanged (i.e. lev should not become negative)

static Ship *makeShip(char ch, int x1, int y1, int x2, int y2)
This function is a "ship factory". It is used to generate instances of ships. It creates an instance of
the appropriate kind of ship (specified by the character ch, with values 'A', 'B', 'C', 'D') at
the given position using the operator new, and returns a pointer to the instance. If the character
ch is not one of the allowed letters, the function should throw an invalid_argument
exception.





protected members

void setPos(int x1, int y1, int x2, int y2)
This function is used to set the values of the private variables x1,y1,x2,y2. It should check the
validity of the combination (x1,y1) and (x2,y2) using the checkConfig function and throw an
invalid_argument exception if the combination is invalid.

int lev
This variable stores the current level of the ship.

private members

bool checkConfig(int x1, int y1, int x2, int y2)
This function checks that the combination (x1,y1) (x2,y2) is valid, i.e. the two cells (x1,y1) and
(x2,y2) are either on the same row or on the same column. It also checks if the distance between
the two cells is compatible with the size of the current instance of ship calling the function. For
example, the pair (2,3) (2,5) is valid for a Cruiser since it includes a total of three cells. The
function should return true if the configuration is valid and false otherwise. Hint: use the
size() member function to get the correct size.

int x1,y1,x2,y2
The coordinates of the cells located at both ends of the ship. The ship occupies these cells and all
cells located in between.


Implementation Advice
Use the function setPos in the constructors of the derived classes.

Any help would be greatly appreciated!

Thank you.

Explanation / Answer

NOTE : I wrote mine(took ideas from somewhere else also), it shouldnt be a problem for anybody whatsoever.

To keep it simple, I would use <bitset>. See first example below. You say you need to use structures and a dynamic array. To me, it's a bit unnatural to use structs for this, but certainly possible. A good side-effect of this solution is pretty nice notation for addressing each element of the 2D array: board.row[i].col[j].

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <bitset>
#include <vector>

using namespace std;

const size_t rows = 5;
const size_t cols = 8;
const size_t N = 16;
unsigned random(double min, double max);

int main(int argc, char *argv[]) {
vector< bitset<cols> > board(rows);
vector< bitset<cols> >::iterator i;
time_t t;
srand((unsigned)time(&t));
size_t x,y,j;

// randomize
for (size_t n = 0; n < N; n++) {
while (board[ x=random(0,rows-1) ][ y=random(0,cols-1) ] == 1);
board[x][y] = 1;
}

// display
for (i = board.begin(); i != board.end(); i++) {
for (j = 0; j < i->size(); j++) {
cout << (*i)[j] << " ";
}
cout << endl;
}
return 0;
}

unsigned random(double rangeMin, double rangeMax) {
assert(rangeMin <= rangeMax);
double maxN = rangeMax - rangeMin + 1;
return static_cast<unsigned>
(((rand() / (double)RAND_MAX) * maxN) + rangeMin);
}

#if 0

Sample output:

0 1 0 0 1 1 0 0
0 0 1 1 0 0 0 1
0 0 1 0 1 1 0 0
1 0 1 0 1 1 1 0
0 1 0 0 1 0 0 0

#endif


#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>

using namespace std;

const size_t rows = 5;
const size_t cols = 8;
const size_t N = 10;
unsigned random(double min, double max);

typedef struct {
unsigned char *col;
} row_t;

typedef struct {
row_t *row;
} board_t;

int main(int argc, char *argv[]) {
board_t board;
time_t t;
srand((unsigned)time(&t));
size_t x,y;

// allocate and initialize
board.row = new row_t[rows];
for (size_t i = 0; i < rows; i++) {
board.row[i].col = new unsigned char[cols];
memset(board.row[i].col,0,cols);
}

// randomize
for (size_t n = 0; n < N; n++) {
while (board.row[ x=random(0,rows-1) ].col[ y=random(0,cols-1) ] == 1);
board.row[x].col[y] = 1;
}

// display
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
cout << static_cast<int>(board.row[i].col[j]) << " ";
}
cout << endl;
}

// free
for (size_t i = 0; i < rows; i++) {
delete [] board.row[i].col;
}
delete board.row;

return 0;
}

unsigned random(double rangeMin, double rangeMax) {
assert(rangeMin <= rangeMax);
double maxN = rangeMax - rangeMin + 1;
return static_cast<unsigned>
(((rand() / (double)RAND_MAX) * maxN) + rangeMin);
}

#if 0

Sample output:

1 0 0 0 1 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 1 1 0 0
1 0 0 0 0 0 1 1
0 0 1 0 0 0 1 0

#endif

Please Rate

Thank You