C语言写三子棋,冲冲冲!

三子棋

当我们学习了数组之后,我们就可以利用所学的知识来写一个三子棋的小游戏。
首先我们将建立两个.c文件和一个.h文件,以便代码逻辑清晰和方便修改,如下图,
在这里插入图片描述

首先在tic-tac-toe.c文件中建立大概的逻辑关系链,如下图:

#define  _CRT_SECURE_NO_WARNINGS	
#include  "game.h"
void menu()
{
    
    
	printf("***********************\n");
	printf("******  1.play  *******\n");
	printf("******  0.exit  *******\n");
	printf("***********************\n");
}//打印菜单
int main()
{
    
    
	int input;
	srand((unsigned int)time(NULL));//设置一个随机数起点,为电脑随机下棋做准备
	do
	{
    
    
		menu();
		printf("Please input 1/0\n");
		scanf("%d",&input);
		switch (input)
		{
    
    
		case 1:
				game();//游戏主函数
				break;
		case 0:
			printf("Exitgame\n");
			break;
		default:
			printf("Input error,please input again\n");
			break;
		}
	} while (input);
}

这个游戏的主要思想是利用数组来储存棋子,然后遍历打印。
因为需要重复游玩,所以放进do while 循环中,且while的判别条件中0为假,非0为真,所以只有input=0时才能退出游戏。
那我们再来看一下game.h中所引用的函数名及其大概的作用

#define  _CRT_SECURE_NO_WARNINGS	
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3

void init(int arr[ROW][COL], int row, int col);//初始化数组
void printborad(int arr[ROW][COL], int row, int col);//打印棋盘和棋子
void playermove(int arr[ROW][COL], int row, int col);//玩家移动
void computermove(int arr[ROW][COL], int row, int col);//电脑移动
int checkwin(int arr[ROW][COL], int row, int col);//检查游戏是否结束
void game();//游戏主函数

最后我们再来看一下这个工程中最为重要的game.c的实现。

void game()
{
    
    
	int arr[ROW][COL];
	int num = 0;
	init(arr, ROW, COL);//初始化棋子
	printborad(arr, ROW, COL);//打印棋盘和棋子
	do
	{
    
    
		playermove(arr, ROW, COL);//玩家移动
		computermove(arr, ROW, COL);//电脑移动
		num = checkwin(arr, ROW, COL);//检查是否完成游戏
	} while (num == 0);
	switch (num)
	{
    
    
	case 1:
		printf("You win\n");
		printborad(arr, ROW, COL);
		break;
	case 2:
		printf("You lose\n");
		printborad(arr, ROW, COL);
		break;
	case 3:
		printf("it ends in a draw\n");
		printborad(arr, ROW, COL);

	}

}

那我们就一步一步来,首先是初始化函数init()

void init(int arr[ROW][COL], int row, int col)
{
    
    
	int i = 0;
	for (; i < ROW; i++)
	{
    
    
		int j = 0;
		for (; j < COL; j++)
		{
    
    
			arr[i][j] = ' ';
		}
	}
}//遍历数组来初始化数组

初始化之后,就开始打印棋盘和空棋子print()

void printborad(int arr[ROW][COL], int row, int col)
{
    
    
	int i = 0;
	int j = 0;
	for (; i < row; i++)
	{
    
    
		for (j = 0; j < col; j++)
		{
    
    
			printf(" %c ", arr[i][j]);
			if (j != col - 1)
				printf("|");//以“ %c |”为一组,但是最后一组的“|”不打印
		}
		printf("\n");
		if (i != row - 1)
			printf("-----------\n");//最后一组的分割线不打印
	}

}

结果如下图
在这里插入图片描述
打印之后开始由playermove储存玩家的棋子,棋子是“ * ”,然后用printborad函数打印出来让玩家看到

void playermove(int arr[ROW][COL], int row, int col)
{
    
    
	printf("Player move,please input your coordinate\n");
	int x, y;
	printf("Please input : ");
	scanf("%d%d", &x, &y);
	arr[x - 1][y - 1] = '*';//考虑到玩家会将数组的第一个元素看成[1][1],所以写成x-1,y-1
	printborad(arr, ROW, COL);
}

同理,用computermove函数储存电脑随机下的棋子

void computermove(int arr[ROW][COL], int row, int col)
{
    
    
	int x, y;
	printf("Computer move :\n");
	while (1)
	{
    
    
		x = rand() % row;
		y = rand() % col;
		//产生随机数x,y
		if (arr[x][y] == ' ')
		{
    
    
			arr[x][y] = '#';
			break;
		}
	}
	printborad(arr, ROW, COL);

}

最后进行比较难的检查函数
在这里插入图片描述
检查函数主要分为五部分
第一部分,检查每行是否满足

int checkwin(int arr[ROW][COL], int row, int col)
{
    
    
	int win = 3;//3可以先初始化为平局需要的数字,然后再根据下面的判断条件来修改
	int ret = 2;
	int i = 0;
	for (; i < ROW; i++)
	{
    
    
		if (arr[i][0] == arr[i][1] && arr[i][0] == arr[i][2] && arr[i][0] != ' ')
		{
    
    
			if (arr[i][0] == '*')
			{
    
    
				return win = 1;//玩家赢
			}
			else
				return win = 2;//电脑赢
		}
	}//检查每一行是否满足赢得条件

第二部分,检查每一列是否满足

for (i = 0; i < COL; i++)
	{
    
    
		if (arr[0][i] == arr[1][i] && arr[0][i] == arr[2][i] && arr[0][i] != ' ')
		{
    
    
			if (arr[0][i] == '*')
			{
    
    
				return win = 1;//玩家赢
			}
			else
				return win = 2;//电脑赢
		}
	}//检查每一列是否满足

第三部分,检查斜向上的那列是否满足

for (i = 0; i<ROW - 1 ; i++)
	{
    
    

		if (arr[i][i] == arr[i + 1][i + 1])
		{
    
    
			ret = 1;
		}

	}
	if (arr[0][0]==' ')
	{
    
    
		ret = 0;
	}
	if (1== ret)
	{
    
    
		if (arr[i][i] == '*')
			return win = 1;
		else if (arr[i][i] == '#')
			return win = 2;
	}
	//检查斜向上的那列是否满足

第四部分,检查斜向下的那列是否满足

int j = 0;
	for (i = ROW - 1, j = 0; i >= 1 &&j <COL - 1; i--, j++)
	{
    
    

		if (arr[i][j] != arr[i - 1][j + 1])
		{
    
    
			ret = 1;
			break;
		}

	}
	if (arr[ROW][0] == ' ')
	{
    
    
		ret = 0;
	}
	if (2 == ret)
	{
    
    
		if (arr[ROW/2][COL/2] == '*')
			return win = 1;
		else if (arr[ROW/2][COL/2] == '#')
			return win = 2;
	}
	//检查斜向下的那列是否满足

第五部分,检查是否需要继续游戏,即我没赢,电脑也没赢

for (i = 0; i < ROW; i++)
	{
    
    
		for (j = 0; j < COL; j++)
		{
    
    
			if (arr[i][j] == ' ');
			return win = 0;
		}
	}
	//检查是否需要继续游戏,即上面的代码都不满足,因为上面每个判断代码都含有return,如果满足,就到不了这段代码。所以数组中只要含有" ",就继续游戏
	return win;

到这,三子棋的代码就完成啦!希望对看到文章的你有帮助。一起加油吧!最后附上一张三子棋的运行图
在这里插入图片描述

在这里插入图片描述
拜拜!

猜你喜欢

转载自blog.csdn.net/weixin_51306225/article/details/113118415