0

我有一个 tic tac toe board ,我正在为好玩而工作,但我遇到了一个问题。基本上我随机生成两个 x,y 坐标,然后通过 while 循环运行它们。如果坐标位置没有被标记,那么它会标记点。否则它将继续运行并生成一对新坐标。这似乎在调用该函数的前四次有效,但随后对该函数的任何使用都会导致它失控。希望有人能指出我正确的方向,并告诉我某处的逻辑是否不正确。建设性的批评很棒。

在此先感谢,这是 X 的移动功能的代码(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() 函数,老实说,它应该作为配置结构的递减计数器来维护。

但除此之外,可以通过多种方式检测剩余的开放瓷砖。下面介绍的一个不需要对配置表等进行其他修改。您可以通过构建一个可行的图块列表并从中选择一个随机条目来轻松完成操作以下内容将替换您最初检查中心插槽是否打开后的所有内容。

// 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 回答