我已经为2名人类玩家制作了一个Tic-Tac-Toe程序(非AI).我将在稍后为计算机播放器实现AI。我是一个初级程序员,也是新的类,这是我在这个程序中实现的。我想知道这是如何优化的。
//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发布于 2013-08-22 20:11:11
一个简单的‘AI’的伪代码:
// 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‘将更聪明,因为它有更广泛的选择,但愚蠢,因为他们不工作,也。
发布于 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(),您有不同的选项:bool)让我们看看这两个选项:在调用//玩游戏时进行测试.如果(赢()){ //做}{ //做别的}它甚至连抽签都不包括,对吧?让我们尝试“布尔枚举”:首先,声明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()。
https://codereview.stackexchange.com/questions/30060
复制相似问题