首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tic-Tac-Toe优化

Tic-Tac-Toe优化
EN

Code Review用户
提问于 2013-08-22 03:41:19
回答 2查看 1.2K关注 0票数 7

我已经为2名人类玩家制作了一个Tic-Tac-Toe程序(非AI).我将在稍后为计算机播放器实现AI。我是一个初级程序员,也是新的类,这是我在这个程序中实现的。我想知道这是如何优化的。

代码语言:javascript
复制
//the main class is all the way at the end

#include "stdafx.h"
#include <iostream>
#include <string>
#include <Windows.h>

//To Implement Color Mechanics
HANDLE hCon;
enum Color { DARKBLUE = 1, DARKGREEN, DARKTEAL, DARKRED, DARKPINK, DARKYELLOW, GRAY, DARKGRAY, BLUE, GREEN, TEAL, RED, PINK, YELLOW, WHITE };

void SetColor(Color c){
        if(hCon == NULL)
                hCon = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(hCon, c);
}

//As of now the program asks for player names but this functionality was added later on, but that disrupted some methods in the game class
//so i declared these global variables to keep the changes to a minimum
std::string player1, player2;


//its the game class, all the methods and the constructor are written right after  the class
class game{
public:
     game();
     int insert(int,char);
     int win();
     void win_display();
private: 
    char board[9];
    void color_conv(char);
    void Winner(int);
};



//constructor for the class game
game::game(){
    SetColor(DARKGREEN);
    std::cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Tic-Tac-Taoe~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<std::endl;
    std::cout<<"*By Default Player 1 is 'O' and Player 2 is 'X'\n";
    std::cout<<"*The choice of cells is mapped out in the following legend\n\n\n";
    std::cout<<" 1  | 2  | 3  \n____|____|____\n 4  | 5  | 6  \n____|____|____\n 7  | 8  | 9  \n    |    |    \n\n";
    std::cout<<"********************************************************************************\n\n\n";

    SetColor(WHITE);

    //This fills up the board array with '-' a filler character, also it looks good :)
    for(int k=0;k<9;k++){
        board[k]='-';
    }
}



//this function in game class is used to insert the right mark, i.e 'O' or 'X' , in the player's choice of position
//the return values are used in the main program to determine a valid choice 
//if there is an invalid choice the current player is given another choice until he makes a valid choice 
int game::insert(int choice, char mark){

    SetColor(WHITE);
    if(choice<=9 && board[choice-1]=='-'){
        board[choice-1]=mark;
        std::cout<<" "<<board[0]<<"  | "<<board[1]<<"  | "<<board[2]<<"  \n____|____|____\n "<<board[3]<<"  | "<<board[4]<<"  | "<<board[5]<<"  \n____|____|____\n "<<board[6]<<"  | "<<board[7]<<"  | "<<board[8]<<"  \n    |    |    \n\n";
        return 1;
    }
    else if(choice>9){
        SetColor(RED);
        std::cout<<"Valid choices are only 1 through 9....\n\n";
        SetColor(WHITE);
        return 0;
    }

    else if(board[choice-1]!='-'){
        SetColor(RED);
        std::cout<<"This choice was already taken....\n\n";
        SetColor(WHITE);
        return 0;
    }
}

//this funtion determines if there is a win 
//return values are 1 for win, 0 for loss, 2 for draw
int game::win(){

    //the conditions listed are for row1,row2,row3,col1,col2,col3,diagonal1 and diagonal2 respectively                                     
    if(   (board[0]==board[1] && board[1]==board[2] && board[0]!='-')
        ||(board[3]==board[4] && board[4]==board[5] && board[3]!='-')
        ||(board[6]==board[7] && board[7]==board[8] && board[6]!='-')
        ||(board[0]==board[3] && board[3]==board[6] && board[0]!='-')
        ||(board[1]==board[4] && board[4]==board[7] && board[1]!='-')
        ||(board[2]==board[5] && board[5]==board[8] && board[2]!='-')
        ||(board[0]==board[4] && board[4]==board[8] && board[0]!='-')
        ||(board[2]==board[4] && board[4]==board[6] && board[2]!='-')){

            return 1;
    }

    //condition for draw----> if its not a win and the board is full i.e. no '-' chars 
    while(true){
    for(int k=0;k<9;k++){
        //if there are any '-' chars then the game is not complete thus we return 0
        if(board[k]=='-'){
            return 0;
        }
    }
    return 2;
    }

    return 0; 
}

//changes the color of the input character
//this is implemented by the "win_display()" 
void game::color_conv(char c){
    SetColor(TEAL);
    std::cout<<c;
    SetColor(WHITE);
}

//display mechanism for a win/draw situation
//this is implemented to selectively color the winning condition like row1, col1, etc
void game::win_display(){
    if((board[0]==board[1] && board[1]==board[2])){
        std::cout<<" ";
        color_conv(board[0]);
        std::cout<<"  | ";
        color_conv(board[1]);
        std::cout<<"  | ";
        color_conv(board[2]);
        std::cout<<"  \n____|____|____\n "<<board[3]<<"  | "<<board[4]<<"  | "<<board[5]<<"  \n____|____|____\n "<<board[6]<<"  | "<<board[7]<<"  | "<<board[8]<<"  \n    |    |    \n\n";
        Winner(0);
    }

    else if((board[3]==board[4] && board[4]==board[5])){
        std::cout<<" "<<board[0]<<"  | "<<board[1]<<"  | "<<board[2]<<"  \n____|____|____\n ";
        color_conv(board[3]);
        std::cout<<"  | ";
        color_conv(board[4]);
        std::cout<<"  | ";
        color_conv(board[5]);
        std::cout<<"  \n____|____|____\n "<<board[6]<<"  | "<<board[7]<<"  | "<<board[8]<<"  \n    |    |    \n\n";
        Winner(3);
    }

    else if((board[6]==board[7] && board[7]==board[8])){
        std::cout<<" "<<board[0]<<"  | "<<board[1]<<"  | "<<board[2]<<"  \n____|____|____\n "<<board[3]<<"  | "<<board[4]<<"  | "<<board[5]<<"  \n____|____|____\n ";
        color_conv(board[6]);
        std::cout<<"  | ";
        color_conv(board[7]);
        std::cout<<"  | ";
        color_conv(board[8]);
        std::cout<<"  \n    |    |    \n\n";
        Winner(6);
    }

    else if((board[0]==board[3] && board[3]==board[6])){
        std::cout<<" ";
        color_conv(board[0]);
        std::cout<<"  | "<<board[1]<<"  | "<<board[2]<<"  \n____|____|____\n ";
        color_conv(board[3]);
        std::cout<<"  | "<<board[4]<<"  | "<<board[5]<<"  \n____|____|____\n ";
        color_conv(board[6]);
        std::cout<<"  | "<<board[7]<<"  | "<<board[8]<<"  \n    |    |    \n\n";
        Winner(0);
    }

    else if((board[1]==board[4] && board[4]==board[7])){
        std::cout<<" "<<board[0]<<"  | ";
        color_conv(board[1]);
        std::cout<<"  | "<<board[2]<<"  \n____|____|____\n "<<board[3]<<"  | ";
        color_conv(board[4]);
        std::cout<<"  | "<<board[5]<<"  \n____|____|____\n "<<board[6]<<"  | ";
        color_conv(board[7]);
        std::cout<<"  | "<<board[8]<<"  \n    |    |    \n\n";
        Winner(1);
    }

    else if((board[2]==board[5] && board[5]==board[8])){
        std::cout<<" "<<board[0]<<"  | "<<board[1]<<"  | ";
        color_conv(board[2]);
        std::cout<<"  \n____|____|____\n "<<board[3]<<"  | "<<board[4]<<"  | ";
        color_conv(board[5]);
        std::cout<<"  \n____|____|____\n "<<board[6]<<"  | "<<board[7]<<"  | ";
        color_conv(board[8]);
        std::cout<<"  \n    |    |    \n\n";
        Winner(2);
    }

    else if((board[0]==board[4] && board[4]==board[8])){
        std::cout<<" ";
        color_conv(board[0]);
        std::cout<<"  | "<<board[1]<<"  | "<<board[2]<<"  \n____|____|____\n "<<board[3]<<"  | ";
        color_conv(board[4]);
        std::cout<<"  | "<<board[5]<<"  \n____|____|____\n "<<board[6]<<"  | "<<board[7]<<"  | ";
        color_conv(board[8]);
        std::cout<<"  \n    |    |    \n\n";
        Winner(0);
    }

    else if((board[2]==board[4] && board[4]==board[6])){
        std::cout<<" "<<board[0]<<"  | "<<board[1]<<"  | ";
        color_conv(board[2]);
        std::cout<<"  \n____|____|____\n "<<board[3]<<"  | ";
        color_conv(board[4]);
        std::cout<<"  | "<<board[5]<<"  \n____|____|____\n ";
        color_conv(board[6]);
        std::cout<<"  | "<<board[7]<<"  | "<<board[8]<<"  \n    |    |    \n\n";
        Winner(2);
    }
}

//again this function is implemented by "win_display()" to display which player won
void game::Winner(int k){
    if(board[k]=='O'){
            SetColor(YELLOW);
            std::cout<<player1<<" Won....\n";
            SetColor(WHITE);
        }
        else if(board[k]=='X'){
            SetColor(YELLOW);
            std::cout<<player2<<" Won....\n";
            SetColor(WHITE);
        }
}


// main function
int main(){
    int choice,i=1,turn_check;
    int check=0;
    game current_game;

    SetColor(DARKPINK);
    std::cout<<"Enter the 1st Player's Name....\n\n";
    std::getline(std::cin,player1);
    std::cout<<"Enter the 2nd Player's Name....\n\n";
    std::getline(std::cin,player2);
    SetColor(WHITE);

    //to play turn wise I implemented an odd\even check
    //as such when a valid choice is not made by the player, which we will know from the return value of game::insert()
    //the counter i is set decremented by 1 to give the current player another chance
    while(check==0){
    //player 1's turn
    if(i%2!=0){
    std::cout<<player1<<": Enter Your Choice...."<<std::endl;
    std::cin>>choice;
    turn_check=current_game.insert(choice,'O');
    }

    //check if the game is won
    check=current_game.win();

    //player 2's turn
    if(i%2==0){
    std::cout<<player2<<": Enter Your Choice...."<<std::endl;
    std::cin>>choice;
    turn_check=current_game.insert(choice,'X');
    }
    //check if the game is won
    check=current_game.win();

    //increment i for the next player's turn
    i++;

    //if player has not made a valid chance give the player another chance
    if(turn_check==0){
        i--;
    }
    }

    //at this point check=1 or 2 i.e. game is won or draw the following conditional statement check for this and displays appropriate message
    if(check==1){
    current_game.win_display();
    }

    else {
        SetColor(PINK);
        std::cout<<"The Game is a Draw!!!\n";
        SetColor(WHITE);
    }

    return 0;
}

//The End
EN

回答 2

Code Review用户

发布于 2013-08-22 20:11:11

一个简单的‘AI’的伪代码:

代码语言:javascript
复制
// If there is a winning move
//    Take it.
// Otherwise, if there is a blocking move (opponent has 2 in a row with open square)
//    Take it.
// Otherwise, take one of these spots, if it is available, in this order:
//    Middle, Middle.
//    Any corner. //  <-- this can be randomized for different games.
//    Any middle edge. //  <-- same as above.

角边和中间边可以随机决定,这样玩家就可以通过多样化来获得更多的乐趣。

另外,为了让'AI‘变得更聪明、更简单,您可以使用上面的伪代码,这样就有机会(随机)从不同的’层‘中选择一个动作。'AI‘将更聪明,因为它有更广泛的选择,但愚蠢,因为他们不工作,也。

票数 3
EN

Code Review用户

发布于 2013-08-22 19:45:47

  • insert()win()不需要返回类似于int的内容,所以它们都可以是void。另一方面,对于insert(),您有另一个返回选项:bool。如果插入成功,则返回true。如果失败,返回false。我应该指出,这完全是在有条件的情况下进行的,这并不能使您的代码异常安全。不过,我不会在这里谈这个的。insert()返回bool的例子,用于您的代码::插入(int选择,char标记){ if ( <= 9& board选择-1 == '-') { // do执行条件返回为真;}否则,如果(选择> 9) { // do为假条件返回false;}否则,如果(board选择-1 != '-') { //为FALSE条件执行其他操作,则返回false;}对于win(),您有不同的选项:
    1. 只在调用时测试条件(作为bool)
    2. 返回一个“布尔枚举”,并在调用时进行测试。

让我们看看这两个选项:在调用//玩游戏时进行测试.如果(赢()){ //做}{ //做别的}它甚至连抽签都不包括,对吧?让我们尝试“布尔枚举”:首先,声明enum://您可以将其放入类中或名称空间//在本例中您不需要分配这些数字//为了说明结果{ LOSE=0,WIN=1,DRAW=2 },无论如何我已经这样做了;接下来,设置函数:结果游戏::WIN(){如果在这里(/* WIN条件这里* //做一些东西返回WIN);}否则,如果(/*丢失条件在这里*/) { //执行一些内容返回丢失;} another //绘制条件{ //执行一些物质返回绘制;}}这里请注意,我使用的是else而不是另一个if else。这是因为函数在技术上仍然不能满足任何这些条件,因此它将无法返回任何东西。而且,由于这显然不是一个void函数(返回并不重要),这将是不好的。如果您的编译器被设置为报告警告,那么如果被违反,它会告诉您这一点。最后,在调用时测试这一点:如果(win() == WIN) { // == } else (win() == LOSE) { // ==} else如果(win() == huh ){ // ==}看起来更好看,嗯?试试这两种选择,看看你更喜欢哪一种。而且,是的,您是对的;应该重命名win()。你可以把它命名为outcome()

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/30060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档