三子棋(电脑非弱智版)

1. 游戏介绍


  三子棋是很简单的双人游戏,双方在3X3的棋盘上轮流落子,当一条直线上出现三颗连续且相同的棋子时即获胜。此程序让玩家先落子,电脑在棋盘上随机落子。游戏结束时显示胜负,玩家可以选择是否继续玩游戏。

2. 思路


  1. 游戏菜单,选择玩/不玩三子棋
  2. 打印棋盘
  3. 玩家落子
  4. 打印棋盘
  5. 电脑落子
  6. 打印棋盘
  7. 显示胜负
  8. 返回游戏菜单,选择玩/不玩

3. 具体步骤


1. 游戏菜单menu()

  弹出游戏菜单选择玩/不玩,选择不玩,退出;选择玩,进入游戏,游戏结束后,再次弹出让玩家选择。因为程序一开始就需要弹出,并且每次游戏结束后再次弹出,可用do while来实现。

void menu()
{
	printf("****************\n");
	printf("***  1.play  ***\n");
	printf("***  0.play  ***\n");
	printf("****************\n");
}
int main()
{
	int input = 0;
	srand(time(NULL));
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("游戏结束\n");
			break;
		default:
			printf("请重新选择\n");
			break;
		}
	} while (input);
	system("pause");
	return 0;
}
2. 游戏函数game()

  在这个函数中,需要实现游戏的运行,包括打印棋盘,玩家落子,打印棋盘,电脑落子,打印棋盘…同时每次落完子后需要判段游戏的胜负,如果分出胜负,显示;没有分出胜负继续。

2.1 打印棋盘
三子棋 三子棋
  为了方便理解同时给出了空棋盘(左)和落子后(右)的棋盘,落子后‘X’的左右两边是空隔,而‘X’存储在一个二维数组数中,在没有落子时,这个二维数组的内容显示在每个小方格的中央,在没落子时存储的是一个空格‘ ’,因此空棋盘就如左示。 用print()函数来实现打印棋盘。
void Print(char board[ROW][COL], int row, int col)//打印棋盘
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		for (j = 0; j < col; j++)
		{
			if (i < row - 1)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
	
}

  在打印棋盘之需要先创建一个board[3][3]的数组,刚开始是数组存储的内容为空格‘ ’,用Inic()函数实现。

void Inic(char board[ROW][COL], int row, int col)//给数组初始化空格
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}
2.2 玩家落子

  玩家落子其实就是选择数组中的一个数,然后把它所存储的‘ ’换成‘ X’,电脑落子也是一样只不过是换成‘ 0’。不过需要注意的是数组是从[0][0]开始的,而玩家在棋盘落子时选择的坐标从1 1开始,另外在玩家和电脑落子前需要判断,选择的坐标是否可以落子(如选择坐标外,或选的地方已经落过子了),在落子结束后判断游戏胜负。

void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)//这是一个死循环,选择的坐标可以落子则跳出循环。
	{
		printf("玩家走:>");
		scanf("%d%d", &x, &y);
		if (board[x-1][y-1] == ' ')
		{
			board[x-1][y-1] = 'X';
			break;
		}
		else
			printf("无法在此下子,请重新选择\n");
	}
}

  落子后需要打印棋盘,同时判断胜负。

2.3 电脑走

  这里电脑的走法是随机的,只要满足条件,在棋盘上随意落子。让电脑随机生成x和y,给定范围0-2;如果可以落子,修改‘ ’为‘0’然后跳出循环,否则进行下一次循环。 注意:

X,Y 需要放在while的里面,如果放在外面,一旦随机的位置不能落子,陷入死循环!另外在刚开时因为玩家只下了一次,电脑随机的位置大概率不会与玩家相同,可以落子,玩家再次落子,电脑可能生成的随机位置仍可以落子,但是一般两次后即陷入死循环,电脑不再落子。

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑走:>\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % ROW;
		y = rand() % COL;
		if (board[x][y] == ' ')
		{
			board[x][y] = '0';
			break;
		}
	}
}

  上面的方法电脑采用的是随机的走法,想要让游戏更有挑战可以采用下面的写法,以下电脑不再随机落子,而是在落子前进行判断,如果玩家已经有两子在一条直线,电脑选择堵,如果没有,电脑会选择较优的位置落子,电脑将会利于不败。

2.3.1 电脑落子优化

  让电脑选择更优位置落子,需要知道何为最优位置,这是对游戏玩法的理解,三字棋是一个简单的游戏,不论先落子还是后落子,只要走法正确 ,都可以利于不败。
  三子棋是一个3X3的棋盘,一共有九个位置可以选择,在这九个位置中哪些位置相对较好,为什么呢?

  1. 最中心的位置:可以与横竖斜共条线上的棋子组成三子棋。
  2. 四个角上的位置:可以与横竖斜共条线上的棋子组成三子棋。
  3. 每天边的中心位置:可以与横竖共条线上的棋子组成 三子棋。
           在明白这个道理后,可以让电脑落子时进行选择

1 .判断玩家再落一子是否胜利,如果是,电脑在此落子,堵。
2 .中心位置可否落子?
3 .四个角可否落子?
4 .四条边的中心位置。
  电脑在每次落子前依次进行这样的判段,即可实现不败。代码如下:

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑走:>\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		for (x = 0; x <= 2; x++)//当玩家有两个子连成一条线时,堵!
		{
			for (y = 0; y <= 2; y++)
			{
				if (board[x][y] == ' ')
				{
					board[x][y] = 'X';
					if (IsWin(board, ROW, COL) == 'X')
					{
						board[x][y] = '0';//一旦落子,就直接跳出while循环,后面都一样
						return 0;
					}
					else
						board[x][y] = ' ';//还原
				}
			}
		}
		if (board[1][1] == ' ')//如果中间可以落子,在中间落子
		{
			board[1][1] = '0';
			return 0;
		}
		else //如果四个角可以落子,在四个角上落子。
		{
			for (x = 0; x <= 2; x+=2)
			{
				for (y = 0; y <= 2; y += 2)
				{
					if (board[x][y] == ' ')
					{
						board[x][y] = '0';
						return 0;
					}
				}
			}
			x = rand() % ROW;//四个边的中间随机落子,0—2
			y = rand() % COL;
			if (board[x][y] == ' ')
			{
				board[x][y] = '0';
			}
		}
	}
}
3 判断胜负

   判断胜负只会出现四种情况,用IsWin()函数来判断返回值类型为char,返回‘X’代表玩家赢,返回‘0’代表电脑赢,返回‘Q’代表平局,返回‘ ’代表继续。这里判断胜负的办法很愚蠢,即对每一条直线进行判断,横竖斜一共八条,如果相同,将直线上任意元素返回。如果没有分出胜负,接着判断是否为平局,即没有元素为‘ ’,若不是平均,继续。

char IsWin(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board [i][0]!= ' ')
			return board[i][0];
	}
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board [0][i]!= ' ')
			return board[0][i];
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
		return board[1][1];
	else if (IsFull(board, ROW, COL)==1)
		return 'Q';
	else
		return ' ';
}
int IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

4. 结果

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
三子是一种简单的类游戏,下面是一个简单的使用C语言编写的三子游戏程序: ``` #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 3 #define COL 3 void Menu() { printf("*****************************\n"); printf("**********三子游戏**********\n"); printf("*****************************\n"); } void Init(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } } void Display(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j != col - 1) { printf("|"); } } printf("\n"); if (i != row - 1) { printf("---|---|---\n"); } } } void PlayerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("请输入您要下的位置:"); scanf_s("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else { printf("该位置已经有子,请重新输入!\n"); } } else { printf("您输入的位置不合法,请重新输入!\n"); } } } void ComputerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } char IsWin(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][1] == board[i][2]) { return board[i][0]; } } for (i = 0; i < col; i++) { if (board[0][i] != ' ' && board[0][i] == board[1][i] && board[1][i] == board[2][i]) { return board[0][i]; } } if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2]) { return board[0][0]; } if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0]) { return board[0][2]; } if (IsFull(board, row, col)) { return 'Q'; } return 'C'; } int IsFull(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ') { return 0; } } } return 1; } void Game() { char board[ROW][COL] = { 0 }; char result = 0; srand((unsigned int)time(NULL)); Init(board, ROW, COL); Display(board, ROW, COL); while (1) { PlayerMove(board, ROW, COL); Display(board, ROW, COL); result = IsWin(board, ROW, COL); if (result != 'C') { break; } ComputerMove(board, ROW, COL); Display(board, ROW, COL); result = IsWin(board, ROW, COL); if (result != 'C') { break; } } if (result == '*') { printf("恭喜您,您赢了!\n"); } else if (result == '#') { printf("很遗憾,电脑赢了!\n"); } else { printf("平局!\n"); } } int main() { int input = 0; do { Menu(); printf("请选择:"); scanf_s("%d", &input); switch (input) { case 1: Game(); break; case 0: printf("退出游戏!\n"); break; default: printf("选择错误,请重新输入!\n"); break; } } while (input); return 0; } ``` 这个程序中,使用了一个二维数组来表示盘,其中'*'表示玩家下的子,'#'表示电脑下的子。程序中实现了玩家下电脑、判断胜负等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值