Tic-Tac-Toe没有人工智能

时间:2015-11-17 10:17:59

标签: c tic-tac-toe

我正在为UNI做作业,我做了Tic-Tac-Toe而没有玩家做出任何决定,这些动作都是随机选择的。因此,如果矩阵上的字符是' '它意味着它是免费的,而如果它是' X'或者' O'它应该产生另一个举动。这是代码(语言C):

if (playerTurn == 1){
    playerSymb = 'X';
}
else if (playerTurn == 2){
    playerSymb = 'O';
}

if (matrix[rand1][rand2] == ' '){
    matrix[rand1][rand2] = playerSymb;
} else if(matrix[rand1][rand2] == 'X' || matrix[rand1][rand2] == 'O'){
    do{
        randAlt1 = MINRND + rand()%(MAXRND - MINRND +1);
        randAlt2 = MINRND + rand()%(MAXRND - MINRND +1);
    }while (matrix[randAlt1][randAlt2] != 'X' && matrix[randAlt1][randAlt2] != 'O');
    matrix[randAlt1][randAlt2] = playerSymb;
}

我没有复制整个代码,因为它根本没有完成,我只需要帮助解决这个问题。但是如果我尝试运行它,可以覆盖符号,就像我有一个' X'在matrix[1][2],它可能是一个' O'经过一些转弯。那么我怎样才能让动作不被覆盖呢? (抱歉英语不好)。

2 个答案:

答案 0 :(得分:2)

只要输入正确的条件:

while (matrix[randAlt1][randAlt2] == 'X' || matrix[randAlt1][randAlt2] == 'O')

(即,如果此单元格不为空,请再试一次)

此外,您可以轻松简化代码而不会丢失任何内容:

randAlt1 = rand1;
randAlt2 = rand2;
while (matrix[randAlt1][randAlt2] != ' ') {
    randAlt1 = MINRND + rand()%(MAXRND - MINRND +1);
    randAlt2 = MINRND + rand()%(MAXRND - MINRND +1);
}
matrix[randAlt1][randAlt2] = (playerTurn == 1) ? 'X' : 'O';

最好添加循环保护以防止无限循环(或为此情况添加特殊检查):

randAlt1 = rand1;
randAlt2 = rand2;
int nbAttempts = 0;
while (matrix[randAlt1][randAlt2] != ' ' && nbAttempts < 100) {
    randAlt1 = MINRND + rand()%(MAXRND - MINRND +1);
    randAlt2 = MINRND + rand()%(MAXRND - MINRND +1);
    nbAttempts++;
}
if (matrix[randAlt1][randAlt2] != ' ') {
    // show error message and stop the game
}
matrix[randAlt1][randAlt2] = (playerTurn == 1) ? 'X' : 'O';

答案 1 :(得分:1)

您选择一个任意位置,然后测试它是否空闲 - 可能是多次。但你也可以选择一些自由职位然后找到它。

首先设置转弯计数器

int   turnNo = 0;

然后为替换动作制作一个循环,选择9-turnNo个未使用位置中的一个,找到它,标记带有玩家标记并测试该移动是否为三行:

while(turnNo < 9)
{
    char  currPlayerMark = ...choose 'X' or 'O';

    int   freePos = 9 - turnNo;
    int   currPos = rand() % freePos;  // 0 .. freePos-1

    for(x=0; x<3; x++)
    {
        for(y=0; y<3; y++)
        {
            if(matrix[x][y] == ' ')  // a free position
                if(--currPos < 0)    // the sought one
                    break;           // break the inner loop
        }
        if(currPos < 0)
            break;                   // break the outer loop
    }

    matrix[x][y] = currPlayerMark;

    if(test_for_win_position(x,y))
    {
         message_a_win_of_player(currPlayerMark);
         break;  // turnNo < 9 here
    }

    turnNo ++;
}

最后测试循环是否以'win'结束:

if(turnNo == 9)
    message_its_a_draw(); // no-one wins

测试胜利位置的功能可能如下所示:

int test_for_win_position(int x, int y)
{
    char mark = matrix[x][y];

    // check a column
    if(matrix[x][0] == mark && matrix[x][1] == mark && matrix[x][2] == mark)
        return 1;

    // check a row
    if(matrix[0][y] == mark && matrix[1][y] == mark && matrix[2][y] == mark)
        return 1;

    // check one diagonal
    if(x==y)
        if(matrix[0][0] == mark && matrix[1][1] == mark && matrix[2][2] == mark)
            return 1;

    // check another diagonal
    if(x+y==2)
        if(matrix[0][2] == mark && matrix[1][1] == mark && matrix[2][0] == mark)
            return 1;

    // current player has not won (yet)
    return 0;
}