#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
//Define the board size
#define ROWS 10
#define COLS 10
//Define the ships
#define BABY_SHIP 'B'
#define SIMPLE_SHIP 'S'
#define RUGGED_SHIP 'R'
#define VALENCIA_SHIP 'V'
#define GIANT_SHIP 'G'
//Define the ship sizes
#define BABY_SHIP_SIZE 2
#define SIMPLE_SHIP_SIZE 3
#define RUGGED_SHIP_SIZE 3
#define VALENCIA_SHIP_SIZE 4
#define GIANT_SHIP_SIZE 5
//Define the ship struct
struct ship {
char type;
int size;
int hits;
int row;
int col;
int is_horizontal;
};
//Function prototypes
void initialize_board(int board[ROWS][COLS]);
void getBoard(int board[ROWS][COLS]);
void randomizeShips(int board[ROWS][COLS], struct ship* s);
int check_location_valid(int board[ROWS][COLS], struct ship* s);
void fire_missile(int board[ROWS][COLS], int row, int col, struct ship ships[]);
int check_ship_sunk(int board[ROWS][COLS], struct ship* s);
void print_ship_status(struct ship ships[]);
void save_game(int board[ROWS][COLS], struct ship ships[]);
void loadGame(int board[ROWS][COLS], struct ship ships[]);
int main()
{
// Seed the random number generator
srand(time(NULL));
int board[ROWS][COLS] = { 0 };
// Declare the array of ships
struct ship ships[5];
int check = 0;
// Define the ships
ships[0].type = BABY_SHIP;
ships[0].size = BABY_SHIP_SIZE;
ships[0].hits = 0;
ships[1].type = SIMPLE_SHIP;
ships[1].size = SIMPLE_SHIP_SIZE;
ships[1].hits = 0;
ships[2].type = RUGGED_SHIP;
ships[2].size = RUGGED_SHIP_SIZE;
ships[2].hits = 0;
ships[3].type = VALENCIA_SHIP;
ships[3].size = VALENCIA_SHIP_SIZE;
ships[3].hits = 0;
ships[4].type = GIANT_SHIP;
ships[4].size = GIANT_SHIP_SIZE;
ships[4].hits = 0;
// Initialize the board
initialize_board(board);
// Place the ships
for (int i = 0; i < 5; i++)
{
randomizeShips(board, &ships[i]);
}
// Print the board
getBoard(board);
// Start the game
int missiles = 0;
int ships_sunk = 0;
while (ships_sunk < 5)
{
// Get the row and column from the player
char row_c;
int col;
printf("Missiles Fired: %d\n", missiles);
printf("Enter row and column (ex. A5) or QQ to quit: ");
scanf(" %c%d", &row_c, &col);
// Check if the player wants to quit
if (row_c == 'Q' || row_c == 'q')
{
save_game(board, ships);
check++;
break;
}
// Convert the row to an int
int row = row_c - 'A';
// Fire the missile
fire_missile(board, row, col, ships);
// Increment the missile count
missiles++;
// Check to see if any ships have been sunk
for (int i = 0; i < 5; i++)
{
if (check_ship_sunk(board, &ships[i]))
{
ships_sunk++;
}
}
// Print the board
getBoard(board);
// Print ship status
print_ship_status(ships);
}
// Print the win message
if (check = 1)
{
printf("See you next time :)");
}
else
{
printf("You win! You sunk all the ships in %d missiles.\n", missiles);
}
return 0;
}
// Function implementations
// Initializes the board with all 0s
void initialize_board(int board[ROWS][COLS])
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
board[i][j] = 0;
}
}
}
// Prints the board to the console
void getBoard(int board[ROWS][COLS])
{
printf(" ");
// Print the column numbers
for (int i = 0; i < COLS; i++)
{
printf("%d ", i);
}
printf("\n");
// Print the board
for (int i = 0; i < ROWS; i++)
{
printf("%c ", 'A' + i);
for (int j = 0; j < COLS; j++)
{
if (board[i][j] == 0)
{
printf(". ");
}
else if (board[i][j] == BABY_SHIP || board[i][j] == SIMPLE_SHIP || board[i][j] == RUGGED_SHIP || board[i][j] == VALENCIA_SHIP || board[i][j] == GIANT_SHIP)
{
printf(". ");
}
else
{
printf("%c ", board[i][j]);
}
}
printf("\n");
}
}
// Places a ship on the board
void randomizeShips(int board[ROWS][COLS], struct ship* s)
{
// Generate a random row, column, and orientation
s->row = rand() % ROWS;
s->col = rand() % COLS;
s->is_horizontal = rand() % 2;
// Check to make sure the location is valid
while (!check_location_valid(board, s))
{
s->row = rand() % ROWS;
s->col = rand() % COLS;
s->is_horizontal = rand() % 2;
}
// Place the ship
for (int i = 0; i < s->size; i++)
{
if (s->is_horizontal == 0)
{
board[s->row][s->col + i] = s->type;
}
else
{
board[s->row + i][s->col] = s->type;
}
}
}
// Checks to make sure the location is valid
int check_location_valid(int board[ROWS][COLS], struct ship* s)
{
// Check to make sure the ship is inside the board
if (s->is_horizontal == 0 && (s->col + s->size) > COLS)
{
return 0;
}
if (s->is_horizontal == 1 && (s->row + s->size) > ROWS)
{
return 0;
}
// Check to make sure the ship is not overlapping another ship
for (int i = 0; i < s->size; i++)
{
if (s->is_horizontal == 0)
{
if (board[s->row][s->col + i] != 0)
{
return 0;
}
}
else
{
if (board[s->row + i][s->col] != 0)
{
return 0;
}
}
}
return 1;
}
// Fires a missile at the specified row and column
void fire_missile(int board[ROWS][COLS], int row, int col, struct ship ships[])
{
if (row < 0 || row >= ROWS || col < 0 || col >= COLS)
{
printf("Invalid location.\n");
printf("You missed that bad huh... dumbass.\n");
return;
}
if (board[row][col] == BABY_SHIP || board[row][col] == SIMPLE_SHIP || board[row][col] == RUGGED_SHIP || board[row][col] == VALENCIA_SHIP || board[row][col] == GIANT_SHIP)
{
printf("Hit!\n");
board[row][col] = 'H';
// Increment the hit count for the corresponding ship
for (int i = 0; i < 5; i++)
{
if (ships[i].type == board[row][col])
{
ships[i].hits++;
break;
}
}
}
if (board[row][col] == 'H' || board[row][col] == 'M')
{
printf("You already hit there idiot.\n");
}
else
{
printf("Miss!\n");
board[row][col] = 'M';
}
}
// Checks to see if a ship has been sunk
int check_ship_sunk(int board[ROWS][COLS], struct ship* s)
{
if (s->hits == s->size)
{
printf("You sunk the %c ship!\n", s->type);
for (int i = 0; i < s->size; i++)
{
if (s->is_horizontal == 0)
{
board[s->row][s->col + i] = s->type;
}
else
{
board[s->row + i][s->col] = s->type;
}
}
return 1;
}
else
{
return 0;
}
}
// Saves the game to a file
void save_game(int board[ROWS][COLS], struct ship ships[])
{
// Open the file for writing
FILE* f = fopen("battleship.txt", "w");
// Write the board to the file
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
fprintf(f, "%d ", board[i][j]);
}
fprintf(f, "\n");
}
// Close the file
fclose(f);
printf("Game saved to battleship.txt\n");
}
void loadGame(int board[ROWS][COLS], struct ship ships[])
{
FILE* file = fopen("battleship.txt", "rb");
if (file == NULL)
{
printf("Warning: Could not open file.\n");
return;
}
fread(board, sizeof(int) * ROWS * COLS, 1, file);
fread(ships, sizeof(struct ship), 5, file);
fclose(file);
} // ends loadGame
void print_ship_status(struct ship ships[])
{
printf("Ship Status:\n");
for (int i = 0; i < 5; i++)
{
printf("%c: %s\n", ships[i].type, ships[i].hits == ships[i].size ? "Sunk" : "Floating");
}
printf("\n");
}
在C写的战舰游戏.我有麻烦恢复游戏,以及使船舶实际沉没,并显示在标签上,它已经沉没.我还需要显示谁是“赢家”是通过显示以前的分数.另一个问题是,我必须改变字母的船舶字母,一旦它已被摧毁.图像显示的方向.没有全局变量或后藤.谢谢你提前:)。
1条答案
按热度按时间lfapxunr1#
在测试和调试你的代码时,我把注意力集中在那些看起来永远不会沉没的东西上。下面是你的代码的重构版本,它大约有99%是原来的。
为了直观地看到测试船只的位置,进行了修正和/或临时更改的地方使用vintage /* . . . */ comment方法进行了注解。以下是调整的关键部分。
随着这些位的变化,下面是一个样本的游戏测试运行。
我将在文件保存/恢复位上尊重其他人,但是给予这些重构的调整,看看它是否符合您的项目的精神。