如果代码太长,很抱歉。我只是想详细描述一下我所面临的情况
我正在编写一个名为"战船"的游戏。下面的代码是一个更简单的版本,我确实消除了所有不必要的逻辑,因为我只想用幻数来说明问题。
这是我的结构和枚举
// the dimension of the 10 + 2 game grid for detection of the neighboring ship
// (its usage comes later in the game, not at this stage)
const int SIZE = 12;
// the number of warships
const int NBSHIP = 5;
string ships[NBSHIP] = {"Carrier", "Cruiser", "Destroyer", "Submarine", "Torpedo" };
// available warships and their size on the grid
enum Ship {
CARRIER=5,
CRUISER=4,
DESTROYER=3,
SUBMARINE=3,
TORPEDO=2,
NONE=0
};
// the different states that a grid cell can take and their display
enum State {
HIT='x',
SINK='#',
MISS='o',
UNSHOT='~'
};
// a grid cell
// the ship present on the space
// the state of the box
struct Cell {
Ship ship;
State state;
};
// the player with
// his name
// his score to determine who lost
// his game grid
struct Player {
string name;
int score;
Cell grid[SIZE][SIZE];
};
// the coordinates of the cell on the grid
// its column from 'A' to 'J'
// its line from 1 to 10
struct Coordinate {
char column;
int line;
};
// the placement of the ship on the grid
// its coordinates (E5)
// its direction 'H' horizontal or 'V' vertical from the coordinate
struct Placement {
Coordinate coordi;
char direction;
};
基本上,在游戏开始时,我必须为每个单元格初始化一个具有适当状态的网格(在本例中为UNSHOT和NONE(。然后我必须显示网格并开始放置船只奇怪的是,我必须使用";幻数";根据玩家的输入将飞船放置在正确的位置。但我甚至不知道我为什么需要它,也不知道如何摆脱它
幻数的使用出现在placeShip函数中。
void initializeGrid (Cell aGrid[][SIZE])
{
for (int i = 0; i < SIZE - 2; i++)
{
for (int j = 0; j < SIZE - 2; j++)
{
aGrid[i][j].ship = NONE;
aGrid[i][j].state = UNSHOT;
}
}
}
void displayGrid(Player aPlayer)
{
cout << endl;
cout << setw(10) << aPlayer.name << endl;
// Letter coordinates
char a = 'A';
cout << " ";
for (int i = 0; i < SIZE - 2 ; i++)
{
cout << " " << char (a+i);
}
cout << endl;
// Number coordinates
for (int i = 0; i < SIZE - 2; i++)
{
// Player
if(i + 1 >= 10) // To align the first column
cout << i + 1;
else
cout << " " << i + 1;
for (int j = 0; j < SIZE - 2; j++)
{
if (aPlayer.grid[i][j].ship) // Check if there are ships
cout << " " << (aPlayer.grid[i][j].ship);
else
cout << " " << char (aPlayer.grid[i][j].state);
}
cout << endl;
}
}
void placeShip(Cell aGrid[][SIZE], Placement aPlace, Ship aShip)
{
if (aPlace.direction == 'h' || aPlace.direction == 'H')
{
for (int i = 0; i < aShip; i++) // To change the value of a cell according to the size of the boat
{
// Utilization of magic number
aGrid[aPlace.coordi.line - 9][aPlace.coordi.column + i - 1].ship = aShip; // Horizontal so we don't change the line
}
}
else if (aPlace.direction == 'v' || aPlace.direction == 'V')
{
for (int i = 0; i < aShip; i++)
{
// Utilization of magic number
aGrid[aPlace.coordi.line + i - 9][aPlace.coordi.column - 1].ship = aShip; // Vertical so we don't change the column
}
}
}
void askPlayerToPlace(Player& aPlayer)
{
Ship battleships[NBSHIP] = { CARRIER, CRUISER, DESTROYER, SUBMARINE, TORPEDO};
for (int i = 0; i < NBSHIP; i++)
{
string stringPlace;
string stringShip = ships[i];
Ship aShip = battleships[i];
string inputDirection;
Coordinate coordi;
cout << "n" << aPlayer.name << ", time to place your carrier of length "
<< to_string(battleships[i])
<< " (" << ships[i] << ")n"
<< "Enter coordinates (i.e. B5): ";
cin >> stringPlace;
coordi = { stringPlace[0], int(stringPlace[1]) - 48 };
cout << "Direction: ";
cin >> inputDirection;
Placement aPlace = {
coordi,
inputDirection[0]
};
placeShip(aPlayer.grid, aPlace, aShip);
displayGrid(aPlayer);
}
}
int main()
{
Player aPlayer;
cout << "Player's name: ";
getline (cin, aPlayer.name);
initializeGrid(aPlayer.grid);
displayGrid(aPlayer);
askPlayerToPlace(aPlayer);
return 0;
}
这里奇怪的是我必须使用"幻数";根据玩家的输入将船只放置在正确的位置
如果这些是经常出现的数字,你应该为它们定义另一个常数,比如:
const int GRID_SIZE_MARGIN = 2;
并使用
void initializeGrid (Cell aGrid[][SIZE]) {
for (int i = 0; i < SIZE - GRID_SIZE_MARGIN; i++) {
for (int j = 0; j < SIZE - GRID_SIZE_MARGIN; j++) {
aGrid[i][j].ship = NONE;
aGrid[i][j].state = UNSHOT;
}
}
}
如果有其他数字出现在计算中,但无法合理命名,可以保留数值。我试着给你举一个例子:
根据弧度计算度数的公式是
deg = rad * 180° / π
对于π,我们有一个常数定义(PI
(,但180
是一个值得常数定义的幻数吗
我们应该如何命名它?HUNDREDEIGHTY_DEGREES
??
因此,去掉代码中出现的数字常量并不总是合理的。
但我甚至不知道为什么我需要它以及如何摆脱它。
这可能是任务的一部分。