Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*Eric Schmid
- Zach Williams
- 12/4/10
- COP 3223H
- Final Project
- Battleship Game*/
- #include <stdio.h>
- #include <time.h>
- #define LENGTH 10
- #define WIDTH 10
- struct ship{
- char name[20];
- int size;
- };
- int PlayerShipCheck(char array[][WIDTH], struct ship *s);
- int CompShipCheck(char array[][WIDTH], struct ship *s);
- void PrintGrid(char array[][WIDTH]);
- void AssignCompGrid(char array[][WIDTH], struct ship *s);
- int CompIntersectCheck(char array[][WIDTH], int n1, int n2, struct ship *s);
- int CharToInt(char letter);
- char IntToChar(int num);
- void AssignPlayerGrid(char array[][WIDTH], struct ship *s);
- int PlayerIntersectCheck(char array[][WIDTH], int coord1, int coord2, int coord3, int coord4);
- void FileInterface(int winner);
- int main(){
- //Establish random # generator, integers needed for whole of program, and the grids for use
- srand(time(0));
- int i, j, choice=1, check;
- char Comp_hide_grid[LENGTH][WIDTH], Comp_view_grid[LENGTH][WIDTH], Player_view_grid[LENGTH][WIDTH];
- //Player_view grid shows player ships, Comp_view_grid shows hits and misses, Comp_hide_grid stores computer's ships
- //Set up each of the struct ship types
- struct ship Aircraft_Carrier;
- strcpy(Aircraft_Carrier.name, "Aircraft Carrier");
- Aircraft_Carrier.size = 5;
- struct ship Battleship;
- strcpy(Battleship.name, "Battleship");
- Battleship.size = 4;
- struct ship Cruiser;
- strcpy(Cruiser.name, "Cruiser");
- Cruiser.size = 3;
- struct ship Submarine;
- strcpy(Submarine.name, "Submarine");
- Submarine.size = 3;
- struct ship Destroyer;
- strcpy(Destroyer.name, "Destroyer");
- Destroyer.size = 2;
- struct ship Hit;
- strcpy(Hit.name, "X");
- Hit.size = 1;
- struct ship Miss;
- strcpy(Miss.name, "O");
- Miss.size = 1;
- printf("Welcome to Battleship!\n\n");
- //Use a do-while loop to cycle through gameplay at least once
- do{
- //Set all the grids to have the emnpty value, a '~' for our case
- for(i=0; i<10; i++){
- for(j=0; j<10; j++){
- Comp_hide_grid[i][j] = '~';
- Comp_view_grid[i][j] = '~';
- Player_view_grid[i][j] = '~';
- }
- }
- //Call custom function for randomly assigning each of the ships on the computer's grid
- AssignCompGrid(Comp_hide_grid, &Aircraft_Carrier);
- AssignCompGrid(Comp_hide_grid, &Battleship);
- AssignCompGrid(Comp_hide_grid, &Cruiser);
- AssignCompGrid(Comp_hide_grid, &Submarine);
- AssignCompGrid(Comp_hide_grid, &Destroyer);
- //Call custom function to prompt the user for ship placement coordinates
- AssignPlayerGrid(Player_view_grid, &Aircraft_Carrier);
- AssignPlayerGrid(Player_view_grid, &Battleship);
- AssignPlayerGrid(Player_view_grid, &Cruiser);
- AssignPlayerGrid(Player_view_grid, &Submarine);
- AssignPlayerGrid(Player_view_grid, &Destroyer);
- //Print out player's game board
- printf("Your game board:\n");
- PrintGrid(Player_view_grid);
- check=1;
- //Give user option to 'cheat'; if they want Easy, print the Computer's game board
- char ans[5];
- while(check){
- printf("Would you like to play on Easy or Hard? \n");
- scanf("%s", ans);
- if(strcmp(ans, "Easy") == 0){
- printf("Computer's game board:\n");
- PrintGrid(Comp_hide_grid);
- check = 0;
- }
- //If the user does not input 'Easy' or 'Hard'
- else if(strcmp(ans, "Hard")!= 0){
- printf("Not a valid answer, try again.\n");
- }
- else{
- check = 0;
- }
- }
- //Establish variables for use in the gameplay
- printf("\nGAME ON!\n\n");
- int turn=1, play=1, coord2, compcoord1, compcoord2, winner;
- //Initialize variables used in ship check to 0
- int a1=0, b1=0, c1=0, d1=0, s1=0, a2=0, b2=0, c2=0, d2=0, s2=0;
- char coord1, temp[3], coord1char;
- while(play){ //As long as the program stays within this loop, the game is not over; gameplay continues
- if(turn){ //Determines the turns; if turn=1 it's the player's turn, turn=0 is the computer's
- //Player goes first; prompt player for coordinate input
- printf("Your turn: \n");
- printf("Enter the target coordinates: \n");
- scanf("%s", temp);
- //Parse the inputted data into the two separate coordinates
- coord1 = temp[0];
- coord2 = temp[1]-'0';
- //Call custom function to convert char input into int value
- coord1 = CharToInt(coord1);
- check=1;
- //If check=1, spot is occupied by a hit or miss; continue to reprompt player for coordinates; else move on
- while(check){
- if(Comp_view_grid[coord1][coord2] == Hit.name[0] || Comp_view_grid[coord1][coord2] == Miss.name[0]){
- printf("You have already shot there. Enter a different target.\n");
- scanf("%s", temp);
- coord1 = temp[0];
- coord2 = temp[1]-'0';
- coord1 = CharToInt(coord1);
- }
- else{
- check = 0;
- }
- }
- //Conditions for a hit; if inputted coordinate coorresponds to a value that isn't ~ on assigned CPU coordinates
- if(Comp_hide_grid[coord1][coord2] != '~'){
- printf("Direct hit!\n");
- //To make sure same spot isn't fired upon twice, change values in both CPU grids
- Comp_hide_grid[coord1][coord2] = '~';//change to ~
- Comp_view_grid[coord1][coord2] = Hit.name[0];//change to X
- }
- //Otherwise, the grid value is ~ and it's a miss, change view grid to O
- else{
- printf("Miss!\n");
- Comp_view_grid[coord1][coord2] = Miss.name[0];
- }
- //Call custom functions to check which computer ships still survive
- if(a1==0){
- a1 = CompShipCheck(Comp_hide_grid, &Aircraft_Carrier);
- }
- if(b1==0){
- b1 = CompShipCheck(Comp_hide_grid, &Battleship);
- }
- if(c1==0){
- c1 = CompShipCheck(Comp_hide_grid, &Cruiser);
- }
- if(d1==0){
- d1 = CompShipCheck(Comp_hide_grid, &Destroyer);
- }
- if(s1==0){
- s1 = CompShipCheck(Comp_hide_grid, &Submarine);
- }
- //Game over condition; all computer ships are sunk, victory for the player
- if(a1==1 && b1==1 && c1==1 && d1==1 && s1==1){
- printf("YOU WIN!\n");
- printf("\n");
- printf("Your board: \n");
- PrintGrid(Player_view_grid);
- printf("Shots taken: (O-miss, X-hit) \n");
- PrintGrid(Comp_view_grid);
- //Initialize variable for use in FileInterface
- winner = 1;
- break;
- }
- printf("\n");
- //Change turns
- turn=0;
- }
- else{ //Now the computer plays
- printf("Computer's turn: \n");
- sleep(750); //Pause the program for .75 seconds to simulate the computer 'thinking'
- //Generate random number 0-9 for target coordinates
- coord1=rand()%10;
- coord2=rand()%10;
- //Convert int to char for printing to screen
- coord1char=IntToChar(coord1);
- check=1;
- //Loop to check if generating coordinate has already been fired upon
- while(check){
- if(Player_view_grid[coord1][coord2] == Hit.name[0] || Player_view_grid[coord1][coord2] == Miss.name[0]){
- coord1=rand()%10;
- coord2=rand()%10;
- }
- else{
- check = 0;
- }
- }
- printf("The computer fired at point %c%d. \n", coord1char, coord2);
- //Check if hit on player's grid, change corredsponding value to X on view grid
- if(Player_view_grid[coord1][coord2] != '~'){
- printf("Direct hit!\n");
- Player_view_grid[coord1][coord2] = Hit.name[0];
- }
- //Otherwise, it's a miss and change corresponding value to O on view grid
- else{
- printf("Miss!\n");
- Player_view_grid[coord1][coord2] = Miss.name[0];
- }
- //Call custom functions to check which player ships still survive
- if(a2==0){
- a2 = PlayerShipCheck(Player_view_grid, &Aircraft_Carrier);
- }
- if(b2==0){
- b2 = PlayerShipCheck(Player_view_grid, &Battleship);
- }
- if(c2==0){
- c2 = PlayerShipCheck(Player_view_grid, &Cruiser);
- }
- if(d2==0){
- d2 = PlayerShipCheck(Player_view_grid, &Destroyer);
- }
- if(s2==0){
- s2 = PlayerShipCheck(Player_view_grid, &Submarine);
- }
- //Game over condition; all player ships are sunk, victory for the computer
- if(a2==1 && b2==1 && c2==1 && d2==1 && s2==1){
- printf("YOU LOSE!\n");
- winner = 0;
- printf("\n");
- printf("Your board: \n");
- PrintGrid(Player_view_grid);
- printf("Shots taken: (O-miss, X-hit) \n");
- PrintGrid(Comp_view_grid);
- break;
- }
- //Change turns back to player
- turn = 1;
- printf("\n");
- //Print game boards; NOTE: you may want to maximize the screen, the game boards take up a lot of space
- printf("Your board: \n");
- PrintGrid(Player_view_grid);
- printf("Shots taken: (O-miss, X-hit) \n");
- PrintGrid(Comp_view_grid);
- }
- }
- //Call custom function to update records by writing to text file
- FileInterface(winner);
- check=1;
- //Prompt user if they wish to play again
- while(check){
- printf("\nWould you like to play again (Yes or No)?\n");
- scanf("%s", ans);
- if(strcmp(ans,"No")== 0){
- choice = 0;
- check = 0;
- }
- //If they don't input 'Yes' or 'No, reprompt
- else if(strcmp(ans,"Yes")!=0){
- printf("Not a valid answer, try again.\n");
- }
- else{
- check = 0;
- }
- }
- //If choice == 1, return to beginning of do-while, otherwise end game
- }while(choice);
- printf("Thanks for playing!\n");
- system("PAUSE");
- return 0;
- }
- //Function for assigning the computer's ships, takes in Computer's grid and each different ship type
- //Assigns the first letter of the ship name at the specific locations in the char grid
- void AssignCompGrid(char array[][WIDTH], struct ship *s){
- //Delcare variables for use
- int i, n1, n2, align, check=1;
- //Generates starting positions, checks to make sure no possible intersections
- while(check){
- n1=rand()%10;
- n2=rand()%10;
- //Call custom function for checking intersections; if it returns 0, go back and generate new start coordinates
- if(CompIntersectCheck(array, n1, n2, s)){
- check = 0;
- }
- }
- align = rand()%2; //Align randomly orients the ships; if 1 then ship is horizontal, if 0 it is vertical
- //If the ship's starting point is too far to the right and bottom (lower right corner of the grid)
- if(n1+((s->size)-1)>9 && n2+((s->size)-1)>9){
- for(i=0; i<(s->size); i++){
- if(align){ //If the ship is horizontal, increment up
- array[n1][n2-i] = s->name[0];
- }
- else{ //If vertical, increment left
- array[n1-i][n2] = s->name[0];
- }
- }
- }
- //If the ship's starting point is only too close to the bottom
- else if(n1+((s->size)-1)>9){
- for(i=0; i<(s->size); i++){
- array[n1][n2+i] = s->name[0]; //Increment right
- }
- }
- //If the ship's starting point is only too close to the right
- else if(n2+((s->size)-1)>9){
- for(i=0; i<(s->size); i++){
- array[n1+i][n2] = s->name[0]; //Increment down
- }
- }
- //If there are no issues of running off the board, align the ship horizontal if align=1
- else if(align==1){
- for(i=0; i<(s->size); i++){
- array[n1][n2+i] = s->name[0];
- }
- }
- //Otherwise, align=0 and the ship is aligned vertically
- else if(align==0){
- for(i=0; i<(s->size); i++){
- array[n1+i][n2] = s->name[0];
- }
- }
- }
- //Function that checks for ship intersections on the computer grid
- int CompIntersectCheck(char array[][WIDTH], int n1, int n2, struct ship *s){
- int i, check=1;
- //Checks from start point and goes in all four directions as far as the ship size dictates
- for(i=0; i<((s->size)); i++){
- if(array[n1][n2+i] != '~'||array[n1][n2-i]!='~'||array[n1+i][n2] != '~' || array[n1-i][n2]!= '~'){
- check=0;//If non-~ values are found, return 0
- break;
- }
- }
- //If all values were ~, nothing intersects and function returns 1
- return check;
- }
- //Function for assigning the player's ships on the grid, takes in grid and each of the different ship types
- void AssignPlayerGrid(char array[][WIDTH], struct ship *s){
- int i, j=0, coord2, coord4, swap;
- char coord1, coord3, temp1[3], temp2[3];
- //Loop used to keep reprompting user if errors are made in entering coordinates
- while(j==0){
- //Prompts user for start and end coordinates, reads them in as strings
- printf("Please enter the beginning and ending coordinates of your %s: \n", (s->name));
- scanf("%s %s", temp1, temp2);
- //Parses each coordinate into two separate values
- coord1 = temp1[0];
- coord2 = temp1[1]-'0';//converts numerical char into int value
- coord3 = temp2[0];
- coord4 = temp2[1]-'0';
- //Calls custom function for converting char to int
- coord1 = CharToInt(coord1);
- coord3 = CharToInt(coord3);
- //Calls custom function for checking intersections
- if(PlayerIntersectCheck(array, coord1, coord2, coord3, coord4)){
- printf("You already have a ship in that area.\n");
- }
- //By default, the coordinates are interpreted right to left, up to down
- //If the user enters coordinates in 'backwards', swap values
- else{
- if(coord1>coord3){
- swap = coord1;
- coord1 = coord3;
- coord3 = swap;
- }
- if(coord2>coord4){
- swap = coord2;
- coord2 = coord4;
- coord4 = swap;
- }
- //For horizontal ship
- if(coord1==coord3){
- if((coord4-coord2) !=((s->size)-1)) //If the length of inputted coordinates does not match ship size
- printf("You have entered invalid coordinates. \n");
- else{ //Valid coordinates entered
- for(i=0; i<=(coord4-coord2); i++){
- array[coord1][coord2+i] = s->name[0];
- j=1;
- }
- }
- }
- //For vertical ship
- else if(coord2==coord4){
- if((coord3-coord1) != ((s->size)-1)){ //Again, if length does not match ship size
- printf("You have entered invalid coordinates.\n");
- }
- else{ //Valid cooraintes entered
- for(i=0; i<=(coord3-coord1); i++){
- array[coord1+i][coord2] = s->name[0];
- j=1;
- }
- }
- }
- else{ //In cases of inputting coordinates diagonally
- printf("You have entered invalid coordinates.\n");
- }
- }
- }
- }
- //Function that checks for ship intersections on the player grid
- int PlayerIntersectCheck(char array[][WIDTH], int coord1, int coord2, int coord3, int coord4){
- int i, check=0;
- //If ship is aligned horizontally
- if(coord1==coord3){
- for(i=0; i<=(coord4-coord2);i++){
- if(array[coord1][coord2+i]!='~'){ //If any value along horizontal within size is not ~, a ship is already there
- check=1;
- break;
- }
- }
- }
- //If ship is aligned vertically
- else if(coord2==coord4){
- for(i=0;i<=(coord3-coord1);i++){
- if(array[coord1+i][coord2]!='~'){ //If any value along horizontal within size is not ~, a ship is already there
- check=1;
- break;
- }
- }
- }
- return check;
- }
- //Function that prints out desired grid
- void PrintGrid(char array[][WIDTH]){
- int i, j;
- printf(" ");
- //Print out 0-9 across the top
- for(i=0; i<10; i++){
- printf("%d ", i);
- }
- //Print dashes to separate top numbers from board
- printf("\n ");
- for(i=0;i<19; i++){
- printf("-");
- }
- //Print out rows, with each row starting with a corresponding A-J
- printf("\n");
- for(i=0; i<10; i++){
- printf("%c|", IntToChar(i));
- for(j=0; j<10; j++){
- printf("%c ", array[i][j]);
- }
- printf("\n");
- }
- }
- //Converts char A-J to int value of 0-9 by casting char to ASCII value
- int CharToInt(char letter){
- int num;
- num = (int)letter-65;
- return num;
- }
- //Converts int 0-9 to char A-J by added 65 to int value and casting to char
- char IntToChar(int num){
- char letter;
- letter = (char)(num+65);
- return letter;
- }
- //Runs a check to see if a given ship is still present on computer's grid
- int CompShipCheck(char array[][WIDTH], struct ship *s){
- int i,j, check=1;
- for(i=0; i<10; i++){
- for(j=0; j<10; j++){
- if(array[i][j]==s->name[0]){ //If the first char of a ship name is anywhere on the grid, the ship is still there
- return 0;
- }
- else{
- check = 1;
- }
- }
- }
- //Otherwise, player has sunk the computer's ship
- if(check = 1){
- printf("You have sunk the computer's %s.\n", s->name);
- return 1;
- }
- }
- //Runs a check to see if a given ship is still present on the player's grid
- int PlayerShipCheck(char array[][WIDTH], struct ship *s){
- int i,j, check=1;
- for(i=0; i<10; i++){
- for(j=0; j<10; j++){
- if(array[i][j]==s->name[0]){ //If the first char of a ship name is anywhere on the grid, the ship is still there
- return 0;
- }
- else{
- check = 1;
- }
- }
- }
- //Otherwise, computer has sunk the player's ship
- if(check = 1){
- printf("The computer has sunk your %s.\n", s->name);
- return 1;
- }
- }
- //Function that accesses a file to keep a running record of human vs. computer wins
- void FileInterface(int winner){
- //Initialize file pointer and variables for score
- FILE *statFile;
- int playerscore, compscore;
- //Open the file and read in the current scores
- statFile = fopen("winner.in", "r");
- fscanf(statFile, "%*s %d", &playerscore);
- fscanf(statFile, "%*s %d", &compscore);
- //If winner=1, the human won the game, increment their score
- if(winner){
- playerscore++;
- }
- //Else winner=0, the computer won; increment computer score
- else{
- compscore++;
- }
- fclose(statFile);
- //Write the new results into the file
- fopen("winner.in", "w");
- fprintf(statFile, "Player %d\n", playerscore);
- fprintf(statFile, "Computer %d", compscore);
- fclose(statFile);
- printf("\nThe current score is Player-%d, Computer-%d.\n", playerscore, compscore);
- }
Add Comment
Please, Sign In to add comment