/** * @file * @author [Carlos Rafael](https://github.com/CarlosZoft) * @author [Herick Lima](https://github.com/hericklima22) * @brief [naval_battle](https://en.wikipedia.org/wiki/Battleship_(game)) * implementation in C using only the stdio.h for Standard Input and Output. * @details Naval battle is a game, to be played by two people. It consists of * knocking down the enemy ship, through shots , when hit the ship is * revealed with the respective number of its size. Example: size 3 = 3 3 3 on * the board. * To play - boats over size 1, need direction; V -> vertical and H -> * horizontal. Example Input 1 A H -> line 1, column A, direction H * (Horizontal). */ #include /// for Standard Input Output /** * @brief Function validEntryLineColumn * Responsible for validating entries, for positioning boats * @param line matrix row * @param column matrix column * @returns if the row and column are valid */ int validEntryLineColumn(int line, char column) { if ((line >= 1 && line <= 10) && (column >= 65 && column <= 74)) { return 1; } return 0; } /** * @brief Function validatePosition * Responsible for checking if the position can receive the boat. * @param mat board * @param boat boat * @param line matrix row * @param column matrix column * @returns if the position is valid */ int validatePosition(int mat[10][10], int boat, int line, int column, char guide) { int cont = 0; int i, j; if (line < 0 || line > 9 || column < 0 || column > 9 || (guide != 'H' && guide != 'V') || boat < 1 || boat > 3) { return 0; } if (guide == 'H') { if ((10 - column) < boat) { return 0; } else { for (j = column; j < (column + boat); j++) { if (mat[line][j] == 0) { cont++; } } } } if (guide == 'V') { if ((10 - line) < boat) { return 0; } else { for (i = line; i < (line + boat); i++) { if (mat[i][column] == 0) { cont++; } } } } if (cont == boat) { return 1; } return 0; } /** * @brief Function canShoot * Responsible to verify that it is a valid position to shoot * @param mat board * @param line matrix row * @param column matrix column * @returns if the position is valid for shooting */ int canShoot(int mat[10][10], int line, int column) { if (mat[line][column] == -2 || mat[line][column] == 10 || mat[line][column] == 20 || mat[line][column] == 30 || mat[line][column] == 50) { return 0; } return 1; } /** * @brief Function positionBoat * Responsible for placing the boats on the board, according to the size. * @param mat board * @param boat boat */ void positionBoat(int mat[10][10], int boat) { int line, j; char column, guide; if (boat == 1) { scanf("%d %c", &line, &column); while (validEntryLineColumn(line, column) != 1 || validatePosition(mat, boat, (line - 1), (column - 65), 'H') != 1) { printf("Position unavailable!\n"); scanf("%d %c", &line, &column); } } else { scanf("%d %c %c", &line, &column, &guide); while (validEntryLineColumn(line, column) == 0 || validatePosition(mat, boat, (line - 1), (column - 65), guide) == 0) { printf("Position unavailable!\n"); scanf("%d %c %c", &line, &column, &guide); } } int aux = column - 'A'; line -= 1; if (boat == 1) { for (j = aux; j < (aux + boat); j++) { mat[line][j] = boat; } for (int a = line - 1; a < (line + boat + 1); a++) { for (int b = aux - 1; b < (aux + boat + 1); b++) { if (a >= 0 && a <= 9 && b >= 0 && b <= 9) { if (mat[a][b] != boat) { mat[a][b] = -1; } } } } } if (guide == 'H') { for (j = aux; j < (aux + boat); j++) { mat[line][j] = boat; } if (boat == 3) { for (int a = line - 1; a < (line + boat - 1); a++) { for (int b = aux - 1; b < (aux + boat + 1); b++) { if (a >= 0 && a <= 9 && b >= 0 && b <= 9) { if (mat[a][b] != boat) { mat[a][b] = -1; } } } } } else { for (int a = line - 1; a < (line + boat); a++) { for (int b = aux - 1; b < (aux + boat + 1); b++) { if (a >= 0 && a <= 9 && b >= 0 && b <= 9) { if (mat[a][b] != boat) { mat[a][b] = -1; } } } } } } if (guide == 'V') { for (j = line; j < (line + boat); j++) { mat[j][aux] = boat; } if (boat == 3) { for (int a = line - 1; a < (line + boat + 1); a++) { for (int b = aux - 1; b < (aux + boat - 1); b++) { if (a >= 0 && a <= 9 && b >= 0 && b <= 9) { if (mat[a][b] != boat) { mat[a][b] = -1; } } } } } else { for (int a = line - 1; a < (line + boat + 1); a++) { for (int b = aux - 1; b < (aux + boat); b++) { if (a >= 0 && a <= 9 && b >= 0 && b <= 9) { if (mat[a][b] != boat) { mat[a][b] = -1; } } } } } } } /** * @brief Function printMessage * Responsible for printing the auxiliary message * @param msg msg with board */ void printMessage(char *msg) { printf("************************\n"); printf("*\n"); printf("* %s\n", msg); printf("*\n"); printf("************************\n"); } /** * @brief Function printMessageScore * Responsible for printing the score messages * @param pts1 player 1 score * @param pts2 player 2 score */ void printMessageScore(int pts1, int pts2) { printf("************************\n"); printf("*\n"); printf("* Player'S SCORE 1: %02d\n", pts1); printf("* Player'S SCORE 2: %02d\n", pts2); printf("*\n"); printf("************************\n"); } /** * @brief Function printTable * Responsible for printing the board * @param logic return of the logical matrix * @param stage game step * @returns char for visual matrix */ char printTable(int logic, int stage) { if (stage == 0) { if (logic == 0) { return '.'; } else if (logic == -1) { return '*'; } else if (logic == 1) { return '1'; } else if (logic == 2) { return '2'; } else { return '3'; } } else { if (logic == 0 || logic == -1 || logic == 1 || logic == 2 || logic == 3) { return '.'; } else if (logic == -2) { return 'x'; } else if (logic == 10 || logic == 20 || logic == 30) { return 'N'; } else { return 'A'; } } } /** * @brief Function printsTray * Responsible for printing the visual board for the user * @param mat Matrix * @param stage game step */ void printsTray(int mat[10][10], int stage) { int logic; char imp; printf(" "); for (int i = 65; i < 75; i++) { printf("%c", i); if (i < 74) { printf(" "); } } printf("\n"); for (int i = 0; i < 12; i++) { if (i > 0 && i < 11) { printf("%02d ", i); } else { printf(" "); } for (int j = 0; j < 12; j++) { if ((i > 0 && i < 11) && (j > 0 && j < 11)) { logic = mat[i - 1][j - 1]; imp = printTable(logic, stage); printf("%c", imp); } else { printf("#"); } if (j < 11) { printf(" "); } } printf("\n"); } } /** * @brief Function shoot * Responsible for saying if he hit a boat * @param mat board * @param line matrix row * @param column matrix column */ void shoot(int mat[10][10], int line, int column) { if (mat[line][column] == 0 || mat[line][column] == -1) { mat[line][column] = -2; } else if (mat[line][column] == 1) { mat[line][column] = 10; } else if (mat[line][column] == 2) { mat[line][column] = 20; } else if (mat[line][column] == 3) { mat[line][column] = 30; } } /** * @brief Function calculateScore * Responsible for calculating the score obtained during the game * @param mat board * @param line matrix row * @param column matrix column * @returns resulting score */ int calculateScore(int mat[10][10], int line, int column) { int c = 0, b = 0, e = 0, d = 0; if (mat[line][column] == 10) { mat[line][column] = 50; return 2; } else if (mat[line][column] == 20) { if (mat[line + 1][column] == 20) { b = 1; } if (mat[line - 1][column] == 20) { c = 1; } if (mat[line][column + 1] == 20) { d = 1; } if (mat[line][column - 1] == 20) { e = 1; } if (b == 1) { if (mat[line + 1][column] == 20) { mat[line][column] = 50; mat[line + 1][column] = 50; return 4; } else { return 0; } } if (c == 1) { if (mat[line - 1][column] == 20) { mat[line][column] = 50; mat[line - 1][column] = 50; return 4; } else { return 0; } } if (d == 1) { if (mat[line][column + 1] == 20) { mat[line][column] = 50; mat[line][column + 1] = 50; return 4; } else { return 0; } } if (e == 1) { if (mat[line][column - 1] == 20) { mat[line][column] = 50; mat[line][column - 1] = 50; return 4; } else { return 0; } } } else if (mat[line][column] == 30) { if (mat[line + 1][column] == 30) { b = 1; } if (mat[line - 1][column] == 30) { c = 1; } if (mat[line][column + 1] == 30) { d = 1; } if (mat[line][column - 1] == 30) { e = 1; } if (b == 1 && c == 1) { if (mat[line + 1][column] == 30 && mat[line - 1][column] == 30) { mat[line][column] = 50; mat[line + 1][column] = 50; mat[line - 1][column] = 50; return 7; } else { return 0; } } else if (d == 1 && e == 1) { if (mat[line][column + 1] == 30 && mat[line][column - 1] == 30) { mat[line][column] = 50; mat[line][column - 1] = 50; mat[line][column + 1] = 50; return 7; } else { return 0; } } else if (d == 1) { if (mat[line][column + 1] == 30 && mat[line][column + 2] == 30) { mat[line][column] = 50; mat[line][column + 1] = 50; mat[line][column + 2] = 50; return 7; } else { return 0; } } else if (e == 1) { if (mat[line][column - 1] == 30 && mat[line][column - 2] == 30) { mat[line][column] = 50; mat[line][column - 1] = 50; mat[line][column - 2] = 50; return 7; } else { return 0; } } else if (c == 1) { if (mat[line - 1][column] == 30 && mat[line - 2][column] == 30) { mat[line][column] = 50; mat[line - 1][column] = 50; mat[line - 2][column] = 50; return 7; } else { return 0; } } else if (b == 1) { if (mat[line + 1][column] == 30 && mat[line + 2][column] == 30) { mat[line][column] = 50; mat[line + 1][column] = 50; mat[line + 2][column] = 50; return 7; } else { return 0; } } } return 0; } /** * @brief Function printPositioning * Responsible for printing messages for positioning boats on the board; of * player 1 and 2 * @param Player number representing the Player * @param boat number that represents the boat * @param nm which message to print */ void printPositioning(int Player, int boat, int nm) { if (Player == 1) { char msg1[60] = "Player 1 - Position the size boat 1 (1/6)"; char msg2[60] = "Player 1 - Position the size boat 1 (2/6)"; char msg3[60] = "Player 1 - Position the size boat 1 (3/6)"; char msg4[60] = "Player 1 - Position the size boat 1 (4/6)"; char msg5[60] = "Player 1 - Position the size boat 1 (5/6)"; char msg6[60] = "Player 1 - Position the size boat 1 (6/6)"; char msg7[60] = "Player 1 - Position the size boat 2 (1/4)"; char msg8[60] = "Player 1 - Position the size boat 2 (2/4)"; char msg9[60] = "Player 1 - Position the size boat 2 (3/4)"; char msg10[60] = "Player 1 - Position the size boat 2 (4/4)"; char msg11[60] = "Player 1 - Position the size boat 3 (1/2)"; char msg12[60] = "Player 1 - Position the size boat 3 (2/2)"; if (boat == 1) { if (nm == 1) { printMessage(msg1); } else if (nm == 2) { printMessage(msg2); } else if (nm == 3) { printMessage(msg3); } else if (nm == 4) { printMessage(msg4); } else if (nm == 5) { printMessage(msg5); } else if (nm == 6) { printMessage(msg6); } } else if (boat == 2) { if (nm == 1) { printMessage(msg7); } else if (nm == 2) { printMessage(msg8); } else if (nm == 3) { printMessage(msg9); } else if (nm == 4) { printMessage(msg10); } } else if (boat == 3) { if (nm == 1) { printMessage(msg11); } if (nm == 2) { printMessage(msg12); } } } if (Player == 2) { char msg1[60] = "Player 2 - Position the size boat 1 (1/6)"; char msg2[60] = "Player 2 - Position the size boat 1 (2/6)"; char msg3[60] = "Player 2 - Position the size boat 1 (3/6)"; char msg4[60] = "Player 2 - Position the size boat 1 (4/6)"; char msg5[60] = "Player 2 - Position the size boat 1 (5/6)"; char msg6[60] = "Player 2 - Position the size boat 1 (6/6)"; char msg7[60] = "Player 2 - Position the size boat 2 (1/4)"; char msg8[60] = "Player 2 - Position the size boat 2 (2/4)"; char msg9[60] = "Player 2 - Position the size boat 2 (3/4)"; char msg10[60] = "Player 2 - Position the size boat 2 (4/4)"; char msg11[60] = "Player 2 - Position the size boat 3 (1/2)"; char msg12[60] = "Player 2 - Position the size boat 3 (2/2)"; if (boat == 1) { if (nm == 1) { printMessage(msg1); } else if (nm == 2) { printMessage(msg2); } else if (nm == 3) { printMessage(msg3); } else if (nm == 4) { printMessage(msg4); } else if (nm == 5) { printMessage(msg5); } else if (nm == 6) { printMessage(msg6); } } else if (boat == 2) { if (nm == 1) { printMessage(msg7); } else if (nm == 2) { printMessage(msg8); } else if (nm == 3) { printMessage(msg9); } else if (nm == 4) { printMessage(msg10); } } else if (boat == 3) { if (nm == 1) { printMessage(msg11); } else if (nm == 2) { printMessage(msg12); } } } } /** * @brief Main function * @returns 0 on exit */ int main() { int Player1[10][10]; int Player2[10][10]; int plays = 1; int pts1 = 0, pts2 = 0, a1 = 0, a2 = 0; int line, col = 0, lin = 0; char column; // filling matrix with 0 for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { Player1[i][j] = 0; Player2[i][j] = 0; } } // positioning boats for (int i = 1; i <= 2; i++) { for (int j = 1; j <= 6; j++) { if (i == 1) { printPositioning(i, 1, j); printsTray(Player1, 0); positionBoat(Player1, 1); } else if (i == 2) { printPositioning(i, 1, j); printsTray(Player2, 0); positionBoat(Player2, 1); } } for (int j = 1; j <= 4; j++) { if (i == 1) { printPositioning(i, 2, j); printsTray(Player1, 0); positionBoat(Player1, 2); } else if (i == 2) { printPositioning(i, 2, j); printsTray(Player2, 0); positionBoat(Player2, 2); } } for (int j = 1; j <= 2; j++) { if (i == 1) { printPositioning(i, 3, j); printsTray(Player1, 0); positionBoat(Player1, 3); } else if (i == 2) { printPositioning(i, 3, j); printsTray(Player2, 0); positionBoat(Player2, 3); } } } // starting the game while (plays <= 40) { if (plays % 2 != 0) { printMessageScore(pts1, pts2); printMessage("Player 1's turn"); printsTray(Player2, 1); scanf("%d %c", &line, &column); while (validEntryLineColumn(line, column) != 1 || canShoot(Player2, line - 1, column - 65) != 1) { line = 0; column = 'a'; printf("Position unavailable!\n"); scanf("%d %c", &line, &column); } lin = line - 1; col = column - 65; shoot(Player2, lin, col); a1 = pts1; pts1 += calculateScore(Player2, lin, col); if (a1 != pts1) { printMessage("Player 1 DROPPED A BOAT!"); } } else { printMessageScore(pts1, pts2); printMessage("Player 2's turn"); printsTray(Player1, 1); scanf("%d %c", &line, &column); while (validEntryLineColumn(line, column) != 1 || canShoot(Player1, line - 1, column - 65) != 1) { printf("Position unavailable!\n"); scanf("%d %c", &line, &column); } lin = line - 1; col = column - 65; shoot(Player1, lin, col); a2 = pts2; pts2 += calculateScore(Player1, lin, col); if (a2 != pts2) { printMessage("Player 2 DROPPED A BOAT!"); } } plays++; } /** * the one with the most points wins, or the one who knocks down all boats * first. */ printMessage("END GAME\n"); printMessageScore(pts1, pts2); return 0; }