圈圈叉叉/井字棋/TicTacToe——C/C++实现

无聊,写个小游戏,井字棋

思路:

棋盘表达:二维数组打印

棋盘状态:数组元素标识:未下棋,下O和下X。

棋手:加计数器,奇偶判断区分两棋手。

胜利判断:横竖斜,一方能先连起来,这个直接拿出数据来比一下。还有棋盘慢等情况。


来来来,V1.0诞生了

#include<iostream>
using namespace std;

typedef enum TicTacToeState{
TTTS_Default = 0,
TTTS_O = 1,
TTTS_X = 2,
}TTTS;

void Print(TTTS array[][3])
{
	for(int i = 0;i < 3;i++)
	{
		for(int j = 0;j < 3;j++)
		{
			if(array[i][j] == TTTS_Default)
				cout << "-";		
			else if(array[i][j] == TTTS_O)
				cout << "O";
			else
				cout << "X";
		}
		cout << endl;
	}

}
TTTS CheckWin(TTTS array[][3])
{
	for(int i = 0;i < 3;i++)
		if(array[i][0] == array[i][1] && 
			array[i][0] == array[i][2] &&
			array[i][0] != TTTS_Default)
			return array[i][0];
	for(int j = 0;j < 3;j++)
		if(array[0][j] == array[1][j] &&
			array[0][j]== array[2][j] && 
			array[0][j] != TTTS_Default)
			return array[0][j];
	if(array[0][0] == array[1][1] &&
		array[0][0] == array[2][2] &&
		array[0][0] != TTTS_Default)
		return array[0][0];
	if(array[0][2] == array[1][1] &&
		array[0][2] == array[2][0] &&
		array[0][2] != TTTS_Default)
		return array[0][2];

	return TTTS_Default;
}

int main()
{
	TTTS array[3][3] = {TTTS_Default};
	int index_x,index_y;
	int counter = 0;

	Print(array);

	while(cin >> index_x >> index_y)
	{
		if(! ((index_x >= 0 && index_x < 3)&&(index_y >= 0 && index_y < 3))
			 || (array[index_x][index_y] != TTTS_Default))
		{
			cout << "wrong position,please retry!" << endl;
			continue;
		}
		//随便约定个先手
		array[index_x][index_y] = counter % 2 ? TTTS_O : TTTS_X; 

		//打印棋盘
		Print(array);
		//如果win,就break
		if(TTTS_O == CheckWin(array))
		{
			cout  << "game over,O win!!!!!" << endl;
			break;
		}else if(TTTS_X == CheckWin(array))
		{
			cout  << "game over,O win!!!!!" << endl;
			break;
		}
		
		counter++;//识别O和X
		if(counter >= 9 )//总步数达到9,或者加个或运算,可以判断全盘是否还有TTTS_Default,懒的写了
		{
			cout << "game over,draw game!" << endl;
			break;
		}
	}

}








可优化的部分



程序的OO化:

整体还是C的风格,用类封装一下,用一个对象表达一盘棋。可以用工厂模式同时开很多盘棋。




包裹一层循环,使得draw game可以直接开始下一盘

(不过如果打算OO化,就不用了,加上构造和析构,每次新开一个就好了)




必输和必胜情况的提前判定:

考虑:

OXX

OO-

X-X

此时,O怎么下都赢不了,X怎么下都赢,可以做成提前判定输赢(向后推演两棋手的棋招和结局,这不就是阿尔法狗干的事么,他不就是向后推N步,算输赢么,并且,还要更高级,并不是穷举所有结局,而是有优化过程,可惜我连最简单的还玩不转,不能窥其门径)



包裹一层循环,使得draw game可以直接开始下一盘

(不过如果打算OO化,就不用了,加上构造和析构,每次新开一个就好了)


友好度:
使用坐标,而非数组下标,不过这都没卵用了,简单。
还可以显示个 轮到O或者轮到X下棋了。


可以考虑再弄个五子棋出来,感觉除了棋盘更大,主要的一点是计算胜利方法更麻烦了。

一个笨方法是遍历棋盘,每次碰到一个棋子,向右、向下、向右下三个方向判断,五个连续同色,胜利。

但是方法太蠢了,看看有没有其他方法,而且本例井字棋的方法也是挺蠢的,直接判断行、判断列、判断手动输入的斜线。本可以抽象化,不过它就三行,本来就简单,不想折腾了。





包裹一层循环,使得draw game可以直接开始下一盘

(不过如果打算OO化,就不用了,加上构造和析构,每次新开一个就好了)


猜你喜欢

转载自blog.csdn.net/huqinweI987/article/details/52793048