#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define NUMROWS 10
#define NUMCOLS 10
int checkBoard(char**);
void printBoard(char**);
void copyBoard(char**, char**);
void playerMove(char**);
int* serverMove(char**);
int* checkForHits(char**, int, int);
char* placeDestroyer();
char* placeSub();
char* placePatrol();
char** makeOcean();
void freeOcean(char **ocean);
int checker();
int coord1;
int coord2;
char coord1a;
int direction;
int size;
int main () {
/*char **ocean =
{
{' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', ' '},
{'1', '-', '-', '-', '-', '-', '-', '-', '-', '1'},
{'2', '-', '-', '-', '-', '-', '-', '-', '-', '2'},
{'3', '-', '-', '-', '-', '-', '-', '-', '-', '3'},
{'4', '-', '-', '-', '-', '-', '-', '-', '-', '4'},
{'5', '-', '-', '-', '-', '-', '-', '-', '-', '5'},
{'6', '-', '-', '-', '-', '-', '-', '-', '-', '6'},
{'7', '-', '-', '-', '-', '-', '-', '-', '-', '7'},
{'8', '-', '-', '-', '-', '-', '-', '-', '-', '8'},
{' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', ' '}
};*/
char **ocean = makeOcean();
printBoard(ocean);
char **ocean2 = makeOcean();
int bstatus;
//bstatus = checkBoard(ocean);
//printf("\nStatus: %i\n", bstatus);
int col;
int row;
int i;
int test = 0;
srand(time(NULL));
//placing Destroyer
do
{
placeDestroyer();
test = checker(ocean);
col = coord1a - 'A' + 1;
row = coord2;
if (test == 1)
{
for (i = 0; i < size; i++)
{
ocean[row][col] = 'D';
if (direction == 1)
row--;
if (direction == 2)
col++;
if (direction == 3)
row++;
if (direction == 4)
col--;
}
}
}while (test == 0);
test = 0;
//placing Sub
do
{
placeSub();
test = checker(ocean);
col = coord1a - 'A' + 1;
row = coord2;
if (test == 1)
{
for (i = 0; i < size; i++)
{
ocean[row][col] = 'S';
if (direction == 1)
row--;
if (direction == 2)
col++;
if (direction == 3)
row++;
if (direction == 4)
col--;
}
}
}while (test == 0);
test = 0;
//placing Patrol
do
{
placePatrol();
test = checker(ocean);
col = coord1a - 'A' + 1;
row = coord2;
if (test == 1)
{
for (i = 0; i < size; i++)
{
ocean[row][col] = 'P';
if (direction == 1)
row--;
if (direction == 2)
col++;
if (direction == 3)
row++;
if (direction == 4)
col--;
}
}
}while (test == 0);
printBoard(ocean);
copyBoard(ocean2,ocean);
printBoard(ocean2);
printf("\n");
//the following is horrible code, really, since this should be done in the function playerMove, but
//I'm too lazy to error check and make it work at the moment -- logically it's fine for now
//int row, col;
/*int incorrect;
do
{
incorrect = 0;
int *move = playerMove(ocean);
row = move[0];
col = move[1];
incorrect = move[2];
}while(incorrect == -1);
if(incorrect == 0)
ocean[row][col] = 'X';
else if(incorrect == 1)
ocean[row][col] = 'O';
*/
for(;;)
{
playerMove(ocean);
printBoard(ocean);
}
bstatus = checkBoard(ocean);
printf("\nStatus: %i\n", bstatus);
printBoard(ocean);
freeOcean(ocean);
freeOcean(ocean2);
exit(1);
}
void freeOcean(char **ocean)
{
int i;
for (i = 0; i < NUMROWS; i++){
free(ocean[i]);
}
free(ocean);
}
char** makeOcean()
{
char** anOcean;
int i, j;
anOcean = (char**) malloc(NUMROWS*sizeof(char*));
for (i = 0; i < NUMROWS; i++)
anOcean[i] = (char*) malloc(NUMCOLS*sizeof(char));
//fill with values
for(i = 0; i < NUMROWS; i++)
{
if(i == 0 || i == NUMROWS -1)
{
anOcean[i][0] = '-';
anOcean[i][1] = 'A';
anOcean[i][2] = 'B';
anOcean[i][3] = 'C';
anOcean[i][4] = 'D';
anOcean[i][5] = 'E';
anOcean[i][6] = 'F';
anOcean[i][7] = 'G';
anOcean[i][8] = 'H';
anOcean[i][9] = '-';
}
else
{
anOcean[i][0] = '1' + i - 1;
anOcean[i][1] = '-';
anOcean[i][2] = '-';
anOcean[i][3] = '-';
anOcean[i][4] = '-';
anOcean[i][5] = '-';
anOcean[i][6] = '-';
anOcean[i][7] = '-';
anOcean[i][8] = '-';
anOcean[i][9] = '1' + i - 1;
}
}
return anOcean;
}
void copyBoard(char **copy, char **original)
{
int i, j;
for(i = 0; i < NUMROWS; i++)
{
for(j =0; j < NUMCOLS; j++)
{
copy[i][j] = original[i][j];
}
}
}
void printBoard(char **ocean)
{
int i, j;
for(i = 0; i < NUMROWS; i++)
{
for(j =0; j < NUMCOLS; j++)
{
printf("%c ",ocean[i][j]);
}
printf("\n");
}
}
//check for a cleared board
/*
1 - player wins
0 - nobody wins, game is on
*/
int checkBoard(char **ocean)
{
//simple idea: scan through the board array and look for ship symbols.
//if no more ship symbols exist on a board, that board is done and the other player wins
int i, j;
//boolean for checking for end of game
int end;
end = 1;
for (i = 1; i < NUMROWS-1 && end; i++)
{
for(j = 1; j < NUMCOLS-1 && end; j++)
{
if(ocean[i][j] == 'D' || ocean[i][j] == 'S' || ocean[i][j] == 'P')
end = 0;
}
}
return end;
}
//returns an array of move locations at the moment because...I want it to return
//the updated board but am too lazy to make that work with c, due to not liking pointers at the moment
/*
-1 - bad move, tried to bomb an X or an O
0 - correct move but missed, mark the X back in main
1 - correct move that hit, mark the O back in main
*/
void playerMove(char **ocean)
{
char buffer[3];
//buffer[2] = ' ';
printf("Missile Co-ordinate: ");
scanf("%s",&buffer);
buffer[0] = toupper(buffer[0]);
//make sure they didn't use the extra buffer slot
if(buffer[2] != NULL)
{
printf("You entered in 3 characters rather than 2! Shoot again.\n");
//call the function again
playerMove(ocean);
}
//no need to +1 to get rid of the top due to array indexing
int row = atoi(&buffer[1]);
//doesn't rely on array indexing, pure subtraction of ascii values, so need to +1
int col = buffer[0] - 'A' + 1;
//logic goes here
char square;
square = ocean[row][col];
int maxCol = 'H' - 'A' +1;
int maxRow = 8;
if(row > maxRow || row < 1 || col < 1 || col > maxCol)
{
printf("You tried to shoot your missile off the board! Shoot again.\n");
playerMove(ocean);
}
switch(square)
{
case 'X':
case 'O':
//not a correct move, try again
printf("You have already bombed here; please bomb elsewhere.\n");
playerMove(ocean);
break;
case 'D':
case 'P':
case 'S':
//hit
printf("Hit! You hit an enemy ship!\n");
ocean[row][col] = 'O';
break;
case '-':
//miss
printf("Miss. Your missile hit nothing but water and maybe some aquatic wildlife. Congrats.\n");
ocean[row][col] = 'X';
break;
default:
break;
}
}
//serverMove - AI function for firing missiles
int* serverMove(char **ocean)
{
//simple idea: scan through the board array and look for 'O'.
//try to hit around the 'O' to sink a ship
/*
1. Found a O
2. Check the directions around it
2a. Found another O around it
3. Try to find another O in the direction
2b. Did not find another O around it
3. Try a random direction
4. Check if the random direction has an 'X'
5. If it did, go back to 3, if not return the co-ords
*/
int i, j;
int k, l;
//boolean for checking for end of logic
int end;
end = 1;
//up - 1
//right - 2
//down - 3
//left - 4
int dir;
for (i = 1; i < NUMROWS-1 && end; i++)
{
for(j = 1; j < NUMCOLS-1 && end; j++)
{
//something was already hit
if(ocean[i][j] == 'O')
{
//check for more hits around it to get a direction heading
if(j < NUMCOLS-2 && ocean[i][j+1] == 'O')
{
//Right
dir = 1;
k = 1;
while((checkForHits(ocean, i, j+k) == 1) && ocean[i][j+k+1] != 'X')
k++;
end = 0;
}
else if(j > 1 && ocean[i][j-1] == 'O')
{
//Left
dir = 4;
end = 0;
}
else if(i < NUMROWS-2 && ocean[i+1][j] == 'O')
{
//Down
dir = 3;
end = 0;
}
else if(i > 1 && ocean[i-1][j] == 'O')
{
//Up
dir = 1;
end = 0;
}
else
{
/*no other hits around it, so go in a random direction */
dir = rand() % 4;
}
}
}
}
if(!end)
{
}
else
{
/*shoot somewhere random that is not 'X'
probably its own function so I can loop the selection based on some error
code for hitting 'X' again */
// or a do while...
}
return 0;
}
int* checkForHits(char **ocean, int i, int j)
{
if(ocean[i][j] == 'O')
return 1;
return 0;
}
char* placeDestroyer ()
{
char letters [8] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
int bound = 8;
size = 4;
coord1 = rand() % bound;
coord2 = 1 + rand() % bound;
coord1a = letters[coord1];
direction = 1 + rand() % size;
char results [4] = {coord1a, coord2, direction, size};
return results;
}
char* placeSub ()
{
char letters [8] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
int bound = 8;
size = 3;
coord1 = rand() % bound;
coord2 = 1 + rand() % bound;
coord1a = letters[coord1];
direction = 1 + rand() % size;
char results [4] = {coord1a, coord2, direction, size};
return results;
}
char* placePatrol ()
{
char letters [8] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
int bound = 8;
size = 2;
coord1 = rand() % bound;
coord2 = 1 + rand() % bound;
coord1a = letters[coord1];
direction = 1 + rand() % size;
char results [4] = {coord1a, coord2, direction, size};
return results;
}
int checker (char **ocean)
{
int sizeCompare = size;
int testRight = 'I' - coord1a;
int testLeft = coord1a - 'A' + 1;
int testDown = 9 - coord2;
int i;
if (direction == 1)
{
if (coord2 < sizeCompare)
return 0;
}
if (direction == 2)
{
if (testRight < sizeCompare)
return 0;
}
if (direction == 3)
{
if (testDown < sizeCompare)
return 0;
}
if (direction == 4)
{
if (testLeft < sizeCompare)
return 0;
}
int col = coord1a - 'A' + 1;
int row = coord2;
for (i = 0; i < size; i++)
{
if(ocean[row][col] != '-')
{
return 0;
}
else
{
if (direction == 1)
row--;
if (direction == 2)
col++;
if (direction == 3)
row++;
if (direction == 4)
col--;
}
}
return 1;
}
/*
//rough outline of gameflow
int gametime()
{
while()
{
p2ocean = playerOneMove(p2ocean);
if(checkBoard(p2ocean))
{
//send out end of game message, victory, etc.
break; //or put a variable up top of loop and set it here and
//check it at all points after here
}
p1ocean = playerTwoMove(p1ocean);
if(checKBoard(p1ocean))
{
//send out end of game message, victory, etc.
break; //or put a variable up top of loop and set it here and
//check it at all points after here
}
}
}
*/