0

これが私の問題です。以下のプログラムでは、関数「SetBoardStartingConfig」の下部に向かって、ランダムに数値を生成して配列の最初の4行を埋めようとし、配置しようとしている正方形が空(0)かどうかを確認します。 、およびピースを追加すると、配列「MaxPieces」で指定された最大値を超える場合。そうでない場合は、理論的には追加する必要がありますが、意図したとおりに機能せず、興味深い値が表示されます。主に、この関数を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 . . .
4

2 に答える 2

2

あなたが何を期待しているのか、何が起こっているのかはよくわかりません。なぜ間違っているのかを説明してみてください。そうすれば、人々はコードと結果の分析に何年も費やす必要がなくなります。最初のアルゴリズムは機能しており、2 番目のアルゴリズムは機能していませんか? それとも両方とも間違っていますか?以下の変更により、プログラムの推論がとにかく簡単になります。

変数と関数の命名は少し型破りです。変数と関数は小文字で始まり、クラスは大文字で始まるのが一般的です。あなたのプログラムは、すべてが非常に重要であるかのように見えます。

なぜここでマクロを使用しているのですか?

#define NullSpace -1 // ピースが移動できないスペース
#define フラグ -5
#define ボム 1
#define EmptySpace 0 //空のボード スペース

一般に、マクロは最悪です。他の名前との衝突を避けるためにマクロに名前を付けない場合は特にそうです。C++ の発明者は、マクロに ALL_CAPS を使用することを推奨しています。さらに良いことに、それらを使用しないでください。

const int NullSpace = -1; // ピースが移動できないスペース
const int フラグ -5;
const int 爆弾 1;
const int EmptySpace 0; //空のボード スペース

これは、配列を設定するための非常に面倒な方法です。

ボイド SetMaxPieces()
{
    MaxPieces[0] = 1;
    MaxPieces[爆弾] = 6;
    最大ピース[2] = 8;
...
    MaxPieces[10] = 1;
    MaxPieces[11] = 1; //スパイ
}

配列を定義するときに配列を初期化するだけです:

int MaxPieces[11] = {
    1、6、8、5、4、4、4、3、2、1、1、1
};
文字列 PieceNames[11] = {
  「フラグ:」、「爆弾:」、「2:」、「3:」、「4:」、「5:」、「6:」、
  「セブンズ:」、「エイト:​​」、「ナイン:」、「テンズ:」、「スパイ:」
};

ちょっと待って!これで、コンパイラはプログラムのコンパイルを拒否します:

game.cc:13:1: エラー: 'int [11]' の初期化子が多すぎます
game.cc:17:1: エラー: 'std::string [11] {aka std::basic_string [11]}' の初期化子が多すぎます

11 個の配列に 12 個の値を設定しています! あなたがそうしたときにコンパイラは文句を言いませんでしたMaxPieces[11](しかし、おそらくそうすべきでした)が、あまりにも多くの値で配列を初期化することは間違いありません。あなたの配列には12個の要素があると思われますか? それとも、それらを間違って埋めていますか?

コメンターが指摘したように、シードする必要があります。そうrand()しないと、疑似乱数ジェネレーターが常に同じ初期状態で開始され、まったく同じシーケンスの「乱数」が生成されます。

なぜあなたはで使用do-whileしていmainますか? do-while条件を最初にテストできない場合 (または、ブロック スコープを悪意のあるマクロで単一のステートメントとして機能させるための巧妙なハック) など、いくつかの状況でのみ役立ちます。あなたの場合、条件は最初は真です(loop10未満です)ので、fororwhileループを使用してください。forループ変数は後に存在する必要がないため、forそこで初期化できるため、私はを好むでしょう:

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、2 番目のアルゴリズムはどこに行くのでしょうか? 部分的には、すべての重要なロジックがコメントアウトされているため (これはコードを読むのに役立つ方法ではありません!)、一貫性のないインデントが原因で、コードを推論することは不可能です。

2 番目のアルゴリズムは完全に判読できません。折り返さずにその行を表示するのに十分な幅の画面がありますか? 分解しても読みやすいでしょう。

2 番目のアルゴリズムはチェックし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次に、1文字を変更するだけで( に変更#if 1)、それらを切り替えることができます。

これで、2 番目のアルゴリズムが正しく表示されました。ピースが残っている場合はピースを配置することは明らかです、それによって不足しているピースが配置される可能性があります。たとえば、条件が true であるが、2 を返す場合AIPieces[1] < MaxPieces[1]は、配置できない駒を置きます。これは、いくつかの種類のピースを配置しすぎることを意味します。AIPieces[2] == MaxPieces[2]rand()%10 + 1

スコットは、ピースの配置を関数に分離するという、より良いアイデアを持っていると思います。これにより、そのループがはるかに読みやすくなります。

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

AddPiece2これで、その呼び出しを作成および変更して、さまざまな実装を試すことができます。2 つのアルゴリズムを比較すると、どこが間違っているかを見つけるのに役立ちます。

于 2012-06-23T09:42:23.300 に答える
1

質問をよく理解しているのかわかりません。しかし、それに答えようとしています。このようなものがあなたが求めているもののようです:

AIPiecesをインクリメントする代わりに、最初にボードに何かがないことと、MaxPiecesがまだ使用されていないことを確認する必要があります。

  AIPieces[board[1][0] = rand() % 3 + 4]++;

したがって、これを行う関数を試してください。

void AddPiece(int pieceType, int locationX, int locationY)
{
    if( board[locationX][locationY] != 0 )
         return; // board already has something here, so don't add.

    if( AIPieces[pieceType] >= MaxPieces[pieceType] )
        return; // Can't add as all of these pieces have already been used.

    board[locationX][locationY] = pieceType;
    AIPieces[pieceType]++;
}

そして、元の行の代わりに、次のような関数を呼び出します。

AddPiece(rand() % 3 + 4, 1, 0);

2番目のアルゴリズムは機能しません。これは、ピースを追加しようとすると、追加しようとしているピースのタイプをチェックするだけでなく、ifステートメントが使用されているピースのタイプをチェックするためです。

于 2012-06-23T08:14:08.173 に答える