【C语言/入门游戏】三子棋及改良思路

知识提要(自主编写游戏所需要的知识):

1.函数的基本实现;

2.二维数组;

好的,话不多说让我们来看今天的分享

目录

三子棋

1.初始界面实现

2.棋盘的创建及初始化棋盘

3.棋盘的打印

3.先后手的实现

4.玩家行动

5.电脑行动

6.胜负判定

7.全局展示

8.改良思路


三子棋

效果图:

1.初始界面实现

老规矩,先创建三个文件,分别为test.c(用于测试游戏以及运行游戏),game.c(用于实现游戏内函数)以及game.h(声明game.c中的函数和共同需要的数据)

先在game.h中引用你所需要的文件和必要的定义

#pragma once
# define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define ROW 3//棋盘的行
#define COL 3//棋盘的列

下面就要创建初始界面了

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//后文有函数会用到,不理解这个函数的,可以跳转到我猜字游戏那篇文章
	
   //这里用do while循环保证菜单至少被打开一次
    do
	{
		menu();
		
		printf("请选择>:");
		
		scanf("%d", &input);
		
		
		switch (input)
		{
		case 1:
			printf("游玩愉快\n");
			game();
			break;
		case 0:
			printf("已退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
            break;
		}
	} while (input);//如果选择0,会判定为假,跳出循环,结束游戏;选择其他则不会,保证游戏可以重复游玩
	return 0;
}

 menu():

void menu()
{
	printf("************************\n");
	printf("*******  1. play  ******\n");
	printf("*******  0. exit  ******\n");
	printf("************************\n");
}

2.棋盘的创建及初始化棋盘

首先要创建game()这个函数,然后先创建一个二维数组作为棋盘,同时我们需要将棋盘初始化。

void game()
{
    char arr[ROW][COL];
	//初始化棋盘
	intialize(arr,ROW,COL);

}

现在我们来写将棋盘初始化的函数intialize,这里我们用循环可以简单写成

void intialize(char board[ROW][COL] ,int row,int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}

}

3.棋盘的打印

初始化棋盘后,我们需要将棋盘展示出来,打印效果如下

为了实现效果,这里我们也需要一个函数来实现,我们将其命名为print

void Print(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)//在除最后一列的其他列打印|
				printf("|");
		}
		printf("\n");//换行
		if (j = col - 1)//打印---分割行
		{
			int k = 0;
			if (i < row - 1)//在最后一行不打印分割行
			{
				for (k = 0; k < col; k++)
				{
					printf("---");
					if (k < col - 1)
						printf("|");
				}
			}
		}
		printf("\n");
	}
	

}

只需将ROW,COL定义换成其他数就可以打印各种棋盘。如果棋盘过大,则需要标明行列号,此处暂不演示,具体实现见下一篇扫雷文章。

3.先后手的实现

为了使玩家和电脑都可以先手,我们用一个Dice的类似于骰子的函数实现

int Dice()
{
	return rand() % 2;//返回0或1

}

在game()中接收,并判定

int ret = Dice();
if (ret == 1)//返回为1,玩家先走
	{
			Playermove(arr, ROW, COL);
			Computermove(arr, ROW, COL);
			
		
	}
	else//返回为0,电脑先走
	{
		
			Computermove(arr, ROW, COL);
			Playermove(arr, ROW, COL);
			
		
	}

4.玩家行动

现在到了本游戏的重点,玩家行动,这里我们用o来代表玩家的棋子

玩家下棋代表用o将棋盘中的空格替代

void Playermove(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	
	printf("玩家走>:示例(输入:1 1)\n");
	while (1)//防止输入错误以及非法占用
	{
		printf("请输入坐标>:");
		scanf("%d%d", &i, &j);

		if (i <= row && j <= col&&i>=1&&j>=1)//防止输入的数字超过最大访问范围
		{
			if (board[i-1][j-1] == ' ')//如果该位置为空格,才能下
			{
				board[i-1][j-1] = 'o';//玩家眼中的坐标是从1开始的,而C语言中是从0开始,所以要减1
				break;
			}
			else
				printf("该棋位已被占用,请重新输入\n");
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}

	}

5.电脑行动

我们先不讨论如何让电脑有智商,这个放在文章结尾讨论。我们先设置一个随机的电脑

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] = 'x';
			break;

		}
	}
}

6.胜负判定

这里我们需要列举全部的游戏情况

胜利:横行三子,竖行三子,对角线三子

平局:棋盘已被占满且无胜利情况

继续:棋盘未占满且没有胜利情况

我们规定

如果玩家胜利,返回'o'

如果电脑胜利,返回'x'

如果平局,返回'E'

如果继续,返回'C

用于在test.c中判定胜负

每一方行动完后,都要判定胜负

int even(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;
}

char win(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//judge row
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
			return board[i][1];//直接返回其中的字符,方便后续判定
	}
	//judge col
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
			return board[1][i];
	}
	//judge dia
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
		return board[1][1];
	//judge even
	if (even(board, row, col)==1)//在上述胜利条件都没满足的情况下,才判断是否平局
		return 'E';
	return 'C';
}

7.全局展示

现在大体的游戏函数写得差不多了,可以将填充到game.h和test.c中了

记得要使用game.c中的函数,一定要在game.h中声明,并且引用game.h

game.h

#pragma once
# define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define ROW 3
#define COL 3


void intialize(char board[ROW][COL], int row, int col);

void Print(char board[ROW][COL], int row, int col);

int Dice();

void Playermove(char board[ROW][COL], int row, int col);

void Computermove(char board[ROW][COL], int row, int col);

char win(char board[ROW][COL], int row, int col);//如果玩家胜利,返回o;如果电脑胜,返回x;平局,返回E;继续返回C

test.c

# define _CRT_SECURE_NO_WARNINGS

#include "game.h"

void menu()
{
	printf("************************\n");
	printf("*******  1. play  ******\n");
	printf("*******  0. exit  ******\n");
	printf("************************\n");
}

void game()
{
	char arr[ROW][COL];
	//初始化棋盘
	intialize(arr,ROW,COL);
	Print(arr,ROW,COL);
	int ret = Dice();
	char Win = 0;
	if (ret == 1)
	{
		while (1)
		{
			Playermove(arr, ROW, COL);
			Print(arr, ROW, COL);
			Win = win(arr, ROW, COL);
			if (Win !='C')
				break;
			
			Computermove(arr, ROW, COL);
			Print(arr, ROW, COL);
			Win = win(arr, ROW, COL);
			if (Win != 'C')
				break;
		}
	}
	else
	{
		while (1)
		{
			Computermove(arr, ROW, COL);
			Print(arr, ROW, COL);
			Win = win(arr, ROW, COL);
			if (Win != 'C')
				break;
			
			Playermove(arr, ROW, COL);
			Print(arr, ROW, COL);
			Win = win(arr, ROW, COL);
			if (Win != 'C')
				break;

		}
	}
 
	if (Win == 'o')
		printf("恭喜,玩家胜利\n");
	else if (Win == 'x')
		printf("电脑赢了,别灰心\n");
	else if (Win == 'E')
		printf("平局,再来一把吧\n");
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		
		printf("请选择>:");
		
		scanf("%d", &input);
		
		
		switch (input)
		{
		case 1:
			printf("游玩愉快\n");
			game();
			break;
		case 0:
			printf("已退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
		}
	} while (input);
	return 0;
}

8.改良思路

while (1)
	{
		if (board[1][1] == 'o')// 防守为上
		{
			if (board[1][2] == 'o' && board[1][0] == ' ')
			{
				board[1][0] == 'x';
				break;
			}
			else if (board[1][0] == 'o' && board[1][2] == ' ')
			{
				board[1][2] == 'x';
				break;
			}
			else if (board[0][1] == 'o' && board[2][1] == ' ')
			{
				board[2][1] == 'x';
				break;
			}
			else if (board[2][1] == 'o' && board[0][1] == ' ')
			{
				board[0][1] == 'x';
				break;
			}
		    else if (board[2][2] == 'o' && board[0][0] == ' ')
			{
				board[0][0] == 'x';
				break;

			}
			else if (board[0][0] == 'o' && board[2][2] == ' ')
			{
				board[0][1] == 'x';
				break;

			}
			else if (board[0][2] == 'o' && board[2][0] == ' ')
			{
				board[2][0] == 'x';
				break;

			}
			else if (board[2][0] == 'o' && board[0][2] == ' ')
			{
				board[0][2] == 'x';
				break;

			}

		}
		/*int i = 0;*/

		//for (i = 0; i < row - 1; i++)//竖行防守
		//{
		//	int j = 0;
		//	for (j = 0; j < col ; j++)
		//	{
		//		if (board[i][j] == 'o' && board[i + 1][j] == 'o')
		//		{
		//			if (i == 0 && board[i + 2][j] = ' ')
		//			{
		//				board[i + 2][j] = 'x';

		//			}
		//			else if (i == 1 && board[i - 1][j] = ' ')
		//			{
		//				board[i - 1][j] = 'x';
		//			}
		//		}

		//	}

		//}

		if (board[1][1] == ' ')//抢中间位置
		{
			board[1][1] == 'x';
			break;
		}
		if (board[1][1] == 'x')//当有子在中间时的走法
		{
			if ( board[1][2] == 'x'&& board[1][0] == ' ')
			{
					board[1][0] == 'x';
					break;
			}
			else if (board[1][0] == 'x' && board[1][2] == ' ')
			{
				board[1][2] == 'x';
				break;
			}
			else if(board[0][1] == 'x' && board[2][1] == ' ')
			{
				board[2][1] == 'x';
				break;
			}
			else if (board[2][1] == 'x' && board[0][1] == ' ')
			{
				board[0][1] == 'x';
				break;
			
			}
			else if (board[2][2] == 'x' && board[0][0] == ' ')
			{
				board[0][0] == 'x';
				break;

			}
			else if (board[0][0] == 'x' && board[2][2] == ' ')
			{
				board[0][1] == 'x';
				break;

			}
			else if (board[0][2] == 'x' && board[2][0] == ' ')
			{
				board[2][0] == 'x';
				break;

			}
			else if (board[2][0] == 'x' && board[0][2] == ' ')
			{
				board[0][2] == 'x';
				break;

			}

		}
		
		}
	}

上面的是一些如何提升电脑智商的代码,其中要考虑的问题比较多,而且代码执行顺序也要加以斟酌,大家可以把我这几段代码当参考,还有进攻等问题我还没有写出来,所以直接套用是不行的。

以上就是本次的分享内容了,喜欢我的分享的话,别忘了点赞加关注哟!

如果你对我的文章有任何看法,欢迎在下方评论留言或者私信我鸭!

我是白晨,我们下次分享见!!

猜你喜欢

转载自blog.csdn.net/baichendada/article/details/120630743