有什么好的逻辑可以用来阻止计算机将 O 放在 Tic-Tac-Toe 中的现有 X 上

Is there any good logic I can use to stop computer from placing O on a existing X in Tic-Tac-Toe

我在学习 C++ 时创建了一个 Tic-Tac-Toe 游戏作为我的第一个项目。我还没有看过任何自己尝试创建井字游戏的视频,我不知道程序员用来制作这个游戏的真正逻辑。但是从我自己的角度来看,我设法让我的游戏运行良好并且几乎完成了 80%。

所有获胜的可能性都很好,但问题是我们只有 9 次机会,在比赛中 CPU 放置了一个 'O' 玩家已经在他之前的输入中放置了一个'X'。我已经停止 CPUCPU 的当前输入上执行此操作,但我无法停止 CPU 将 'O' 放置在玩家较旧的输入 'X' 上。

为了便于大家理解,我使用了有意义的变量名称并在我的代码中添加了注释。 谢谢

此代码在这里很抱歉没有完整代码,但没有我的代码我无法解释。

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

char board[3][7]; 


void display(){
    int rows, columns;
//********************For Player***********************
    int n=9;
    while(n-- > 0)
    {
    int x,y;
    cin>>x;
    x = (x == 1) ? 0 : x;
    x = (x == 2) ? 1 : x;
    x = (x == 3) ? 2 : x;
    cin>>y;
    y = (y == 3) ? 5 : y;
    y = (y == 0) ? 1 : y;
    y = (y == 2) ? 3 : y;


        for ( rows = 0 ; rows < 3 ; rows++ ){
        for ( columns = 1 ; columns < 7 ; columns = columns+2 ){

            board[ x ][ y ] = 'X';
        }
    }

        for ( rows = 0 ; rows < 3 ; rows++ )
        {
            for ( columns = 0 ; columns < 7 ; columns++ )
            {
            cout<< board[rows][columns] ; 
            }
            cout<<"\n";
        }
        cout<<"\n";


//***********************For CPU****************************

    srand(time(NULL));
    int randX = (rand() % 3) + 1;

    //To check randX and player x should not be same
    while(randX==x){
        randX = (rand() % 3) + 1;
    }

    randX = (randX == 1) ? 0 : randX;
    randX = (randX == 2) ? 1 : randX;
    randX = (randX == 3) ? 2 : randX;


    int randY = (rand() % 3) + 1;
    //To check randY and player y should not be same
    while(randY==y){
        randY = (rand() % 3) + 1;
    }
    randY = (randY == 3) ? 5 : randY;
    randY = (randY == 0) ? 1 : randY;
    randY = (randY == 2) ? 3 : randY;


    for ( rows = 0 ; rows < 3 ; rows++ ){
        for ( columns = 1 ; columns < 7 ; columns = columns+2 ){

            board[ randX ][ randY ] = 'O';
        }
    }

        for ( rows = 0 ; rows < 3 ; rows++ )
        {
            for ( columns = 0 ; columns < 7 ; columns++ )
            {
            cout<< board[rows][columns] ; 
            }
            cout<<"\n";
        }

/*Check Winning*/
   // All Column Winning Cases
    if((board[0][1]=='X') && (board[1][1]=='X') && (board[2][1]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[0][3]=='X') && (board[1][3]=='X') && (board[2][3]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[0][5]=='X') && (board[1][5]=='X') && (board[2][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }

   // All Row Winning Cases
    else if((board[0][1]=='X') && (board[0][3]=='X') && (board[0][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[1][1]=='X') && (board[1][3]=='X') && (board[1][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[2][1]=='X') && (board[2][3]=='X') && (board[2][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }

   // All Diagnal Winning Cases
    else if((board[0][1]=='X') && (board[1][3]=='X') && (board[2][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[0][5]=='X') && (board[1][3]=='X') && (board[2][1]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else
        continue;
    }

}/*End of function display()*/

void drawBoard()
{

    int rows, columns;


    for ( rows = 0 ; rows < 3 ; rows++ ){
        for ( columns = 0 ; columns < 7 ; columns=columns+2 ){ // to fill every second elemnt of the array .. just increment the counter by 2

            board[ rows ][ columns ] = '|';
        }
    }

    for ( rows = 0 ; rows < 3 ; rows++ ){
        for ( columns = 1 ; columns < 7 ; columns = columns+2 ){

            board[ rows ][ columns ] = ' ';
        }
    }

    for ( rows = 0 ; rows < 3 ; rows++ )
        {
            for ( columns = 0 ; columns < 7 ; columns++ )
            {
            cout<< board[rows][columns] ; 
            }
            cout<<"\n";
        }
    display();


}/* end function drawboard */

int main()
{
    drawBoard();
    return 0;
}

这是一个从您的代码派生的工作示例。要查看的重要位是 numberPlacesRemaing 和 cpuPlays。第一个函数计算剩余可用位置的数量。然后 cpu 选择一个介于 1 和剩余数字之间的数字。使用数字播放,它按顺序遍历所有可用空间,然后选择要播放的值,同时跳过已经放置的空间。我留下了基本的调试语句,但注释掉了。您可以取消注释并查看输出,其中将详细说明此方法的工作原理。

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

char board[3][7]; 

int numberPlacesRemaining()
{
    //cout<<"numberPlacesRemaining\n";
    int numberPlacesRemaining = 9;
    for ( int rows = 0 ; rows < 3 ; rows++ ){
        for ( int columns = 1 ; columns < 7 ; columns = columns+2 ){
            //cout<<"numberPlacesRemaining: board["<<rows<<"]["<<columns<<"] = "<<board[rows][columns]<<'\n';
            if( board[rows][columns] != ' ' ){
                //cout<<"numberPlacesRemaining: numberPlacesRemaining = "<<numberPlacesRemaining<<'\n';
                numberPlacesRemaining--;
            }
        }
    }
    return numberPlacesRemaining;
}

void cpuPlays(int toPlay)
{
    //cout<<"cpuPlays:\n";
    //cout<<"cpuPlays: toPlay = "<<toPlay<<'\n';
    for ( int rows = 0 ; rows < 3 ; rows++ ){
        for ( int columns = 1 ; columns < 7 ; columns = columns+2 ){
            //cout<<"cpuPlays: board["<<rows<<"]["<<columns<<"] = "<<board[rows][columns]<<'\n';
            if( board[rows][columns] == ' ' ){
                //cout<<"cpuPlays: counts toPlay = "<<toPlay<<'\n';
                --toPlay;
            }
            if(toPlay == 0)
            {
                board[rows][columns] = 'O';
                //cout<<"cpuPlays: make play board["<<rows<<"]["<<columns<<"] = "<<board[rows][columns]<<"\n\n";
                return;
            }
        }
    }
}

void display(){
    int rows, columns;
//********************For Player***********************
    int n=9;
    while(n-- > 0) {
        int x,y;
        cin>>x;
        x = (x == 1) ? 0 : x;
        x = (x == 2) ? 1 : x;
        x = (x == 3) ? 2 : x;
        cin>>y;
        y = (y == 3) ? 5 : y;
        y = (y == 0) ? 1 : y;
        y = (y == 2) ? 3 : y;

        for ( rows = 0 ; rows < 3 ; rows++ ){
            for ( columns = 1 ; columns < 7 ; columns = columns+2 ){
                board[ x ][ y ] = 'X';
            }
        }

        for ( rows = 0 ; rows < 3 ; rows++ )
        {
            for ( columns = 0 ; columns < 7 ; columns++ )
            {
                cout<< board[rows][columns] ; 
            }
            cout<<"\n";
        }
        cout<<"\n";


//***********************For CPU****************************
    srand(time(NULL));
    int remaning = numberPlacesRemaining();
    cout<<"remaing = " << remaning << '\n';
    int randX = (rand() % remaning) + 1;

    //To check randX and player x should not be same
    cpuPlays(randX);

    for ( rows = 0 ; rows < 3 ; rows++ )
    {
        for ( columns = 0 ; columns < 7 ; columns++ )
        {
            cout<< board[rows][columns] ; 
        }
        cout<<"\n";
    }

/*Check Winning*/
   // All Column Winning Cases
    if((board[0][1]=='X') && (board[1][1]=='X') && (board[2][1]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[0][3]=='X') && (board[1][3]=='X') && (board[2][3]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[0][5]=='X') && (board[1][5]=='X') && (board[2][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }

   // All Row Winning Cases
    else if((board[0][1]=='X') && (board[0][3]=='X') && (board[0][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[1][1]=='X') && (board[1][3]=='X') && (board[1][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[2][1]=='X') && (board[2][3]=='X') && (board[2][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }

   // All Diagnal Winning Cases
    else if((board[0][1]=='X') && (board[1][3]=='X') && (board[2][5]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else if((board[0][5]=='X') && (board[1][3]=='X') && (board[2][1]=='X')){
        cout<<"You won the game"<<endl;
        break;
        }
    else
        continue;
    }

}/*End of function display()*/

void drawBoard()
{
    int rows, columns;

    for ( rows = 0 ; rows < 3 ; rows++ ){
        for ( columns = 0 ; columns < 7 ; columns=columns+2 ){ // to fill every second elemnt of the array .. just increment the counter by 2
            board[ rows ][ columns ] = '|';
        }
    }

    for ( rows = 0 ; rows < 3 ; rows++ ){
        for ( columns = 1 ; columns < 7 ; columns = columns+2 ){
            board[ rows ][ columns ] = ' ';
        }
    }

    for ( rows = 0 ; rows < 3 ; rows++ ) {
        for ( columns = 0 ; columns < 7 ; columns++ ) {
            cout<< board[rows][columns] ; 
        }
        cout<<"\n";
    }
    display();


}/* end function drawboard */

int main()
{
    drawBoard();
    return 0;
}

第二版 -- 更加模块化,并结合了与问题相关的评论中的所有想法。

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

char board[3][3] = {{' ', ' ', ' '},{' ', ' ', ' '},{' ', ' ', ' '}};

int numberPlacesRemaining()
{
    int numberPlacesRemaining = 9;
    for ( int rows = 0 ; rows < 3 ; rows++ ){
        for ( int columns = 0 ; columns < 3 ; columns++ ){
            if( board[rows][columns] != ' ' ){
                numberPlacesRemaining--;
            }
        }
    }
    return numberPlacesRemaining;
}

void toPlay(int row, int column, char player){
    board[row][column] = player;
}

void toPlay(int play, char player){
    for ( int rows = 0 ; rows < 3 ; rows++ ){
        for ( int columns = 0 ; columns < 3 ; columns++ ){
            if( board[rows][columns] == ' ' ){
                --play;
            }
            if(play == 0)
            {
                board[rows][columns] = player;
                return;
            }
        }
    }
}

void cpuPlays()
{
    srand(time(NULL));
    int remaning = numberPlacesRemaining();
    int choice = (rand() % remaning) + 1;
    cout << "cpu plays" << std::endl;
    toPlay(choice,'O');
}

void drawBoard()
{
    for( int row = 0 ; row < 3 ; row++ )
    {
        cout << '|' << board[row][0] << '|' << board[row][1] << '|' << board[row][2] << '|' << '\n';
    }
}

bool hasAlreadyBeenPlayed(int row, int column)
{
    return board[row][column] != ' ';
}

void playerPlays()
{
    cout<<"Your Move\n";

    int x = 0;
    int y = 0;
    do{
        cout<<"Position down? ";
        do{
            cin>>x;
            if( x < 1 || x > 3 )
            {
                cout<<"Plese pick a number between 1 and 3. ";
                x = 0;
            }
        } while(x==0);

        cout<<"Position across? ";
        do {
            cin>>y;
            if( y < 1 || y > 3 )
            {
                cout<<"Plese pick a number between 1 and 3. ";
                y = 0;
            }
        } while(y==0);

        x--;y--;
        if(hasAlreadyBeenPlayed(x,y))
        {
            cout<<"Sorry, but that location has alreayd benn played. Please try agian.\n";
        }
    } while(hasAlreadyBeenPlayed(x,y));
    toPlay(x,y,'X');
}

char whoWonAcross() {
    for(int row = 0; row < 3; row++){
        if( board[row][0] != ' '){
            if( board[row][0] == board[row][1] && board[row][0] == board[row][2] ){
                return board[row][0];
            }
        }
    }
    return ' ';
}
char whoWonUpwards() {
    for(int column = 0; column < 3; column++){
        if( board[0][column] != ' '){
            if( board[0][column] == board[1][column] && board[0][column] == board[2][column] ){
                return board[0][column];
            }
        }
    }
    return ' ';
}
char whoWonDiagonal() {
    if( board[1][1] != ' '){
        if( board[1][1] == board[0][0] && board[1][1] == board[2][2] ){
            return board[1][1]; 
        }
        if ( board[1][1] == board[0][2] && board[1][1] == board[2][0] ){
            return board[1][1]; 
        }
    }
    return ' ';
}


char whoWon()
{
    char result = whoWonAcross();
    if( result != ' ' ) return result;

    result = whoWonUpwards();
    if( result != ' ' ) return result;

    result = whoWonDiagonal();
    if( result != ' ' ) return result;

    return ' ';
}

bool gameOver()
{
    char who = whoWon();
    if( who == ' ') {
        if( numberPlacesRemaining() == 0 ){
            cout << "Draw game!";
            return true;
        }
        return false;
    }

    cout << "Congratulations to " << who << " for such an excelent game." << std::endl;
    return true;
}

void display(){
    for(drawBoard();;){
        playerPlays();
        drawBoard();
        if(gameOver() ){
            break;
        }
        cpuPlays();
        drawBoard();
        if(gameOver() ){
            break;
        }
    }
}

int main()
{
    display();
    return 0;
}