簡體   English   中英

(C++) 我必須使用幻數來顯示數組中正確 position 中的值。 我怎樣才能擺脫它?

[英](C++) I have to use magic numbers to display values in the correct position in an array. How can I get rid of it?

對不起,如果代碼太長。 我只是想詳細描述一下我所面臨的情況

我正在編寫一個名為 Battle Ship 的游戲。 下面的代碼是一個更簡單的版本,我確實消除了所有不必要的邏輯,因為我只想用幻數來說明問題。

這是我的結構和枚舉

// 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)使用適當的 state 初始化一個網格。 然后我必須顯示網格並開始放置船只。 這里奇怪的是我必須根據玩家的輸入使用“幻數”將船只放置在正確的 position 中 但我什至不知道為什么我需要它以及如何擺脫它。

幻數的使用出現在船 function 中

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;
}

這里奇怪的是我必須根據玩家的輸入使用“幻數”將船只放置在正確的 position 中。

如果這些是經常出現的數字,您應該為這些定義另一個常量,例如:

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 ??

因此,擺脫出現在代碼中的數字常量並不總是合理的。


但我什至不知道為什么我需要它以及如何擺脫它。

這可能是任務的一部分,要找出答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM