c++ - 如果一个数字小于 "Max"数组中的相应数字,如何将其添加到数组中?

标签 c++ arrays algorithm comparison

所以这是我的问题。在我下面的程序中,在函数“SetBoardStartingConfig”的底部,我尝试通过随机生成数字来填充数组的前 4 行,检查我尝试放置它们的正方形是否为空 (0) , 并且如果添加棋子会使它超过数组“MaxPieces”中指定的最大值。如果它不会,理论上应该添加它 - 但它没有按我的预期工作,并给我带来了有趣的值(value)。总的来说,我继续重复这个函数 10 次,但它似乎总是会产生不同的错误 - 下面我也粘贴了一些我的结果。

注意:为了尝试这个,我已经注释掉了两种算法,它们之间用一点空格分隔。

旁注:我似乎总是在第一次运行程序时得到 FlagSide = 1(右侧)——关于如何解决这个问题有什么想法吗?

非常感谢大家的帮助:)。

#include <iostream>
#include <stdlib.h>
#include <string>

using namespace std;

int board[10][10];

int AIPieces[11];
int PlayerPieces[11];
int MaxPieces[11];
string PieceNames[11];

//insert stuff for maximum number of things

#define NullSpace -1  // Spaces that pieces can not move to
#define Flag -5
#define Bomb 1
#define EmptySpace 0 //Empty board spaces

void SetMaxPieces()
{
    MaxPieces[0] = 1;
    MaxPieces[Bomb] = 6;
    MaxPieces[2] = 8;
    MaxPieces[3] = 5;
    MaxPieces[4] = 4;
    MaxPieces[5] = 4;
    MaxPieces[6] = 4;
    MaxPieces[7] = 3;
    MaxPieces[8] = 2;
    MaxPieces[9] = 1;
    MaxPieces[10] = 1;
    MaxPieces[11] = 1; //Spy
}

void ResetAIPieces()
{
        for (int i = 0; i < 11; i++)
        AIPieces[i] = 0;
}

void SetPieceNames()
{
    PieceNames[0] = "Flags:";
    PieceNames[1] = "Bombs:";
    PieceNames[2] = "Twos:";
    PieceNames[3] = "Threes:";
    PieceNames[4] = "Fours:";
    PieceNames[5] = "Fives:";
    PieceNames[6] = "Sixes:";
    PieceNames[7] = "Sevens:";
    PieceNames[8] = "Eights:";
    PieceNames[9] = "Nines:";
    PieceNames[10] = "Tens:";
    PieceNames[11] = "Spies:";
}

void PrintBoard()
{   
    for (int i=0; i<10; i++)
    {
        for (int j=0; j<10; j++)
        {
            cout << board[i][j] << " ";
            if (board[i][j] >= 0)
            {
                cout << " ";
            }
        }
        cout << endl;
    }
}

void SetBoardStartingConfig()
{
    for (int i=0; i<10; i++)
    {
        for (int j=0; j<10; j++)
        {   
            board[i][j] = EmptySpace;
        }
    }
    //arrays work in [row] and [column].

    //below defines areas that the pieces can not move to.
    board[4][2] = NullSpace;
    board[4][3] = NullSpace;
    board[5][2] = NullSpace;
    board[5][3] = NullSpace;
    board[4][6] = NullSpace;
    board[4][7] = NullSpace;
    board[5][6] = NullSpace;
    board[5][7] = NullSpace;

    int FlagSide = rand() % 2;

    if (FlagSide == 0)
    {       
        board[0][0] = Flag;
        AIPieces[0]++;
        AIPieces[board[2][0] = Bomb]++;
        AIPieces[board[1][1] = Bomb]++;
        AIPieces[board[0][2] = Bomb]++;
        AIPieces[board[1][0] = rand() % 3 + 4]++;
        AIPieces[board[0][1] = rand() % 3 + 4]++;       
    }

    else if (FlagSide == 1)
    {
        board[0][9-0] = Flag;
        AIPieces[0]++;
        AIPieces[board[2][9-0] = Bomb]++;
        AIPieces[board[1][9-1] = Bomb]++;
        AIPieces[board[0][9-2] = Bomb]++;
        AIPieces[board[1][9-0] = rand() % 3 + 4]++;
        AIPieces[board[0][9-1] = rand() % 3 + 4]++; 
    }

    //for (int i =0; i < 4; i++)
    //      for (int j = 0; j < 10; j++)
    //      {
    //          if (board[i][j] == 0)
    //          {
    //              int Chosen = rand() % 10+1;
    //              if (AIPieces[Chosen] < MaxPieces[Chosen])
    //                  {
    //                  board[i][j] = Chosen;
    //                  AIPieces[Chosen]++;
    //              }
    //              else
    //                  break;
    //          }
    //          else
    //              break;


    //          //      if (AIPieces[0] < MaxPieces[0] || AIPieces[1] < MaxPieces[1] || AIPieces[2] < MaxPieces[2] || AIPieces[3] < MaxPieces[3] || AIPieces[4] < MaxPieces[4] || AIPieces[5] < MaxPieces[5] || AIPieces[5] < MaxPieces[5] || AIPieces[6] < MaxPieces[6] || AIPieces[7] < MaxPieces[7] || AIPieces[8] < MaxPieces[8] || AIPieces[9] < MaxPieces[9] || AIPieces[10] < MaxPieces[10] || AIPieces[11] < MaxPieces[11]) 
    //          //{
    //          //  AIPieces[board[i][j] = rand() % 10+1]++;        
    //          //}
    //      }
}

int main()
{
    SetMaxPieces();
    SetPieceNames();

    int loop = 0;

    do
    {
        SetBoardStartingConfig();
        PrintBoard();
        cout << endl; 

        for (int i = 0; i < 11; i++)
        {
                cout << PieceNames[i] << AIPieces[i] << endl;
        }
            cout << endl;

        ResetAIPieces();

        loop++;

    } while (loop <= 10);

    system("PAUSE");

}

我的结果(每次我使用第一种算法运行时它们似乎都一样)

1  10  5  9  0  0  0  1  5  -5
3  5  6  6  2  8  2  2  1  6
6  3  8  7  2  5  3  4  3  1
3  2  7  0  0  0  0  0  0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:4
Twos:5
Threes:5
Fours:1
Fives:4
Sixes:4
Sevens:2
Eights:2
Nines:1
Tens:1

2  9  10  3  8  0  0  1  4  -5
6  5  4  2  3  4  4  5  1  6
2  2  0  0  0  0  0  0  0  1
0  0  0  0  0  0  0  0  0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:3
Twos:4
Threes:2
Fours:4
Fives:2
Sixes:2
Sevens:0
Eights:1
Nines:1
Tens:1

8  8  10  4  2  0  0  1  5  -5
9  7  6  1  3  0  0  0  1  6
7  1  3  5  0  0  0  0  0  1
7  6  1  0  0  0  0  0  0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:6
Twos:1
Threes:2
Fours:1
Fives:2
Sixes:3
Sevens:3
Eights:2
Nines:1
Tens:1

-5 4  1  0  0  0  0  0  0  0
6  1  0  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0  0  0
2  4  9  10  4  5  5  7  1  7
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:4
Twos:1
Threes:0
Fours:3
Fives:2
Sixes:1
Sevens:2
Eights:0
Nines:1
Tens:1

-5 5  1  0  0  0  0  0  0  0
6  1  0  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0  0  0
5  10  7  4  8  9  0  0  0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:3
Twos:0
Threes:0
Fours:1
Fives:2
Sixes:1
Sevens:1
Eights:1
Nines:1
Tens:1

-5 6  1  0  0  0  0  0  0  0
4  1  0  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0  0  0
4  6  10  9  5  1  8  7  4  7
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:4
Twos:0
Threes:0
Fours:3
Fives:1
Sixes:2
Sevens:2
Eights:1
Nines:1
Tens:1

3  1  10  8  4  8  3  1  6  -5
7  1  2  7  6  0  0  0  1  6
6  5  2  3  1  0  0  0  0  1
2  5  7  0  0  0  0  0  0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:6
Twos:3
Threes:3
Fours:1
Fives:2
Sixes:4
Sevens:3
Eights:2
Nines:0
Tens:1

8  8  0  0  0  0  0  1  5  -5
4  4  6  10  0  0  0  0  1  6
9  2  0  0  0  0  0  0  0  1
3  7  7  1  4  0  0  0  0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:4
Twos:1
Threes:1
Fours:3
Fives:1
Sixes:2
Sevens:2
Eights:2
Nines:1
Tens:1

-5 4  1  0  0  0  0  0  0  0
6  1  0  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0  0  0
6  1  10  5  8  9  4  6  2  3
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:4
Twos:1
Threes:1
Fours:2
Fives:1
Sixes:3
Sevens:0
Eights:1
Nines:1
Tens:1

-5 6  1  0  0  0  0  0  0  0
5  1  0  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0  0  0
5  1  7  2  9  10  0  0  0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:4
Twos:1
Threes:0
Fours:0
Fives:2
Sixes:1
Sevens:1
Eights:0
Nines:1
Tens:1

-5 4  1  0  0  0  0  0  0  0
5  1  0  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0  0  0
4  10  9  0  0  0  0  0  0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  -1 -1 0  0  -1 -1 0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0
0  0  0  0  0  0  0  0  0  0

Flags:1
Bombs:3
Twos:0
Threes:0
Fours:2
Fives:1
Sixes:0
Sevens:0
Eights:0
Nines:1
Tens:1

Press any key to continue . . .

最佳答案

我不太清楚您期望发生什么或正在发生什么,您应该尝试解释为什么您得到的是错误的,这样人们就不必花很长时间来分析代码和结果。第一个算法有效而第二个算法无效吗?还是两者都错了?无论如何,下面的更改将使程序更容易推理。

您的变量和函数命名有点不合常规。更常见的是变量和函数以小写字母开头,类以大写字母开头。您的程序看起来好像一切都非常重要。

为什么在这里使用宏?

#define NullSpace -1  // Spaces that pieces can not move to
#define Flag -5
#define Bomb 1
#define EmptySpace 0 //Empty board spaces

In general, macros suck, especially if you don't name them to avoid clashing with other names. The inventor of C++ recommends using ALL_CAPS for macros. Better still, don't use them:

const int NullSpace = -1;  // Spaces that pieces can not move to
const int Flag -5;
const int Bomb 1;
const int EmptySpace 0; //Empty board spaces

This is a very tedious way to set arrays:

void SetMaxPieces()
{
    MaxPieces[0] = 1;
    MaxPieces[Bomb] = 6;
    MaxPieces[2] = 8;
...
    MaxPieces[10] = 1;
    MaxPieces[11] = 1; //Spy
}

Just initialize the array when you define it:

int MaxPieces[11] = {
    1, 6, 8, 5, 4, 4, 4, 3, 2, 1, 1, 1
};
string PieceNames[11] = {
  "Flags:", "Bombs:", "Twos:", "Threes:", "Fours:", "Fives:", "Sixes:",
  "Sevens:", "Eights:", "Nines:", "Tens:", "Spies:"
};

But wait! Now the compiler refuses to compile the program:

game.cc:13:1: error: too many initializers for ‘int [11]’
game.cc:17:1: error: too many initializers for ‘std::string [11] {aka std::basic_string [11]}’

You are setting twelve values in an array of eleven! The compiler didn't complain when you did MaxPieces[11] (but maybe should have done) but it definitely won't let you initialize an array with too many values. Are your arrays supposed have twelve elements? Or are you just filling them wrong?

As a commenter pointed out, you must seed rand() or the pseudo-random number generator always starts in the same initial state and produces the exact same sequence of "random" numbers.

Why are you using do-while in main? do-while is only useful in a few situations, when the condition can't be tested initially (or for some clever hacks to make its block scope act as a single statement in evil macros). In your case the condition is initially true (loop is less than 10) so just use a for or while loop. I would prefer a for because your loop variable doesn't need to exist after the for so you can initialize it there:

for (int loop = 0; loop <= 10; ++loop)
{
    SetBoardStartingConfig();
    PrintBoard();
    cout << '\n';

    for (int i = 0; i < 11; i++)
    {
            cout << PieceNames[i] << AIPieces[i] << '\n';
    }
    cout << '\n';

    ResetAIPieces();
}
cout << flush;

使用 endl每次你想要换行都是不必要的,endl添加换行符 刷新流,这不需要在每一行都完成。上面的代码在循环后只执行一次。

现在是第一个算法:

for (int i =0; i < 4; i++)
    for (int j = 0; j < 10; j++)
    {
        if (board[i][j] == 0)
        {
            int Chosen = rand() % 10+1;
            if (AIPieces[Chosen] < MaxPieces[Chosen])
                {
                board[i][j] = Chosen;
                AIPieces[Chosen]++;
            }
            else
                break;
        }
        else
            break;

周边第一for大括号也有助于提高可读性。这也有助于编写 rand()%10 + 1而不是上面的间距,这样运算符的优先级就更明显了,目前看起来你的意思是 rand() % 11因为您已将加法操作数分组。

不应该检查 board[i][j] == 0board[i][j] == EmptySpace ?否则,拥有该常量有什么意义?

你真的想要break那里?这是否意味着一旦找到非空方格或用完特定种类的棋子就停止填充一行?如果break应该在那里,他们去哪里进行第二个算法?您的代码无法推理,部分原因是所有重要的逻辑都被注释掉了(这不是阅读代码的有用方法!)并且缩进不一致。

您的第二个算法是完全不可读的,您的屏幕是否足够宽以在不换行的情况下看到该行?即使您这样做,阅读起来也会更容易。

第二个算法是否检查 board[i][j] == EmptySpace ?它似乎没有,但也许这只是你的格式。

此外,所有这些评论使得在实现之间切换以比较结果变得很尴尬。如果你这样做:

    for (int i =0; i < 4; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            if (board[i][j] == EmptySpace)
            {
#if 0
                int Chosen = rand()%10 +1;

                if (AIPieces[Chosen] < MaxPieces[Chosen])
                {
                    board[i][j] = Chosen;
                    AIPieces[Chosen]++;
                }
                else
                    break;
#else
                if (AIPieces[0] < MaxPieces[0]
                        || AIPieces[1] < MaxPieces[1]
                        || AIPieces[2] < MaxPieces[2]
                        || AIPieces[3] < MaxPieces[3]
                        || AIPieces[4] < MaxPieces[4]
                        || AIPieces[5] < MaxPieces[5]
                        || AIPieces[5] < MaxPieces[5]
                        || AIPieces[6] < MaxPieces[6]
                        || AIPieces[7] < MaxPieces[7]
                        || AIPieces[8] < MaxPieces[8]
                        || AIPieces[9] < MaxPieces[9]
                        || AIPieces[10] < MaxPieces[10]
                        || AIPieces[11] < MaxPieces[11]) 
                {
                    AIPieces[board[i][j] = rand() % 10+1]++;        
                }
#endif
            }
            else
                break;
        }
    }

那么你只需要改变一个字符(将 #if 0 改为 #if 1 )就可以在它们之间切换。

现在我可以正确地看到第二个算法,很明显,如果 any 棋子仍然存在,您将放置一个棋子,但这可能会放置一个您已经用完的棋子。例如如果AIPieces[1] < MaxPieces[1]但是AIPieces[2] == MaxPieces[2]条件为真,但如果 rand()%10 + 1返回 2 你放了一 block 你不允许放的东西。这意味着您放置了太多某些类型的棋子。

我认为 Scott 有一个更好的主意,将 block 的放置分离到一个函数中,这将使该循环很多更易于阅读:

for (int i =0; i < 4; i++)
    for (int j = 0; j < 10; j++)
        AddPiece(rand() % 3 + 4, 1, 0);

现在你可以写AddPiece2并将调用更改为尝试不同的实现。比较这两种算法可以帮助找出问题所在。

关于c++ - 如果一个数字小于 "Max"数组中的相应数字,如何将其添加到数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11167747/

相关文章:

c++ - 为什么要调用复制构造函数来构造一个空的 unique_ptr vector ?

java - 创建一个方法数组以供调用

php - 具有自定义索引 PHP 的 Foreach

ruby-on-rails - 将项目成对地分发到容器中 - Rails

c++ - 在 Windows Mobile 上使用 native 代码读取文件时出错

c++ - Boost 程序选项 - 解析命令行时崩溃

c++ - opencv2 可以使用 cmake 构建但不能在 CLion "build"功能中构建?

java - 我的方法没有给我正确的数组维度?

java - 插入排序 - 如何接受输入并打印排序后的数组

c++ - 更新 std::set 以仅保留最小值