0

私は楽しみのために取り組んでいる三目並べボードを持っていますが、問題に遭遇しました。基本的に、2 つの x、y 座標をランダムに生成し、それらを while ループで実行します。座標位置がマークされていない場合は、スポットをマークします。それ以外の場合は実行を継続し、新しい座標のペアを生成します。これは、関数が呼び出された最初の 4 回までは機能しているように見えますが、その後関数を使用すると制御不能になります。誰かが私を正しい方向に向けるだけでなく、論理がどこかで間違っているかどうかを教えてくれることを願っています. 建設的な批判は素晴らしい。

事前に感謝します。これが X の move 関数のコードです (O のコードはほぼ同じです)。

void Xmove(struct config *cp) {
    int ran1, ran2;
    srand((unsigned) time(NULL));
    ran1 = rand() % 3;
    ran2 = rand() % 3;

    if(cp->grid[1][1] == ' ') {
        cp->grid[1][1] = 'X';
        printGrid(cp);
        return;
    }

    while(ran1 == 1 && ran2 == 1) {
        ran1 = (rand() % 3);
        ran2 = (rand() % 3);
    }

    int looper = 1;

    while (looper) {
        if(cp->grid[ran1][ran2] != 'O' && cp->grid[ran1][ran2] != 'X') {
            cp->grid[ran1][ran2] = 'X';
            printGrid(cp);
            looper = 0;
        }

        ran1 = (rand() % 3);
        ran2 = (rand() % 3);
    }

}
4

2 に答える 2

1

無限ループとコードに関する元の質問に戻ります。空のスロットを見つけて埋めるという前提だけでループを中断させることはできません。利用可能なスロットが残っていない場合は、ループに入る必要さえありません。実際、塗りつぶすオープン タイルがない場合は、どちらの Move() 関数も呼び出すべきではなく、正直なところ、構成構造体のデクリメント カウンターとして維持する必要があります。

しかし、それはさておき、開いているタイルが残っていることの検出は、さまざまな方法で行うことができます。構成テーブルなどに他の変更を必要としないものを以下に示します。これは、実行可能なタイルのリストを作成し、そこからランダムなエントリを1 つ選択することで簡単に実行できます。以下は、中央のスロットが開いていることを最初に確認した後のすべてを置き換えます。

// build a table of open tiles
int ar[9] = {0};
int n=0,i=0,j=0;
for (i=0;i<3;++i)
  for (j=0;j<3;++j)
    if (cp->grid[i][j] != 'O' && cp->grid[i][j] != 'X')
      ar[n++] = i*3+j;

// now you have the list of available tiles 
//  in `ar[0..n-1]`. choose ONE via `rand()`
if (n > 0)
{
    n = ar[rand()%n];
    cp->grid[n/3][n%3] = 'X'; // or 'O'
}
于 2012-12-05T22:13:47.977 に答える
0

ランダムなループを完全に排除し、代わりに、移動が必要になるたびに、0 から 9 までの数字のランダムな順列を生成し、それを使用してボードを歩き、X または O を配置する場所を探します。必要に応じて。このようなもの:

    int randperm[9], i = 0;     

    /* fill the array randperm with the numbers 0 through 8 in 
     * order
     */
    for(i = 0; i != 9; i++)
        randperm[i] = i;

    /* Now mix the numbers up, so that the array ends up in
     * some "random" order: that is, generate a permutation
     * of the digits 0-8.
     */
    for(i = 8; i > 0; i--) 
    {
        int j = rand() % (i+1);
        int temp = randperm[j];
        randperm[j] = randperm[i];
        randperm[i] = temp;
    }

    /* Now try to find a spot. We will use our randperm array to
     * determine which cell to look at. Remember that the array
     * contains the numbers 0-8 in some random order.
     */
    for(i = 0; i != 9; i++)
    {       
        /* We split a number from 0-8 into two numbers (x and y), 
         * each from 0 to 2:
         *
         * 0 -> 0 0, 1 -> 1 0, 2 -> 2 0,
         * 3 -> 0 1, 4 -> 1 1, 5 -> 2 1,
         * 6 -> 0 2, 7 -> 1 2, 8 -> 2 2
         *
         * notice that (y * 3) + x = randperm[i]
         */
        int x = randperm[i] % 3;
        int y = randperm[i] / 3;


        /* check if the spot at grid[x][y] is available, if it is
         * take it and return. 
         */
    }

    /* If we get here there's no spot to put an X or an O... board is full */
于 2012-12-05T20:02:12.020 に答える