栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言实现三子棋,和我一起泡杯咖啡,敲起来吧!

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言实现三子棋,和我一起泡杯咖啡,敲起来吧!

手把手教你写出三子棋(让你深入了解二维数组) 1.创建项目

我们自己在自己的编译器上创建一个三子棋项目,创建完毕后分别创建test.c,用来测试运行代码,game.h,用来引用所需要的头文件和所需函数的声明,game.c,用来定义game.h中的函数。以后我们写这种代码较长的函数较多的项目,都应该养成分文件的习惯,代码看起来也很分明。

2.在test.c文件中引头文件和写主函数
#include"game.h"//因为在game.h中引用头文件,为了方便,我们在test.c和game.c都加上,表示用了game.h里                 //面的头文件和game.h里面的函数

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

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择 >:n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("欢迎下次再玩!n");
			break;
		default:
			printf("输入错误,请重新输入!n");
			break;
		}
	} while (input);
	return 0;
}

我们首先需要打印一个菜单让玩家选择,玩家可能玩一次还想再玩一次,所以我们让它至少执行一次,用do while循环,然后循环里面用分支语句来分别跳转玩家的选择。

3.在test.c文件写开始玩游戏代码
void game()
{
	char board[ROW][COL] = { 0 };//创建一个二维数组棋盘
	init_board(board, ROW, COL);//初始化棋盘
	display_board(board, ROW, COL);//打印棋盘让玩家看到
}

我们需要将棋盘打印成这种形状:

我们将二维数组棋盘初始化为3行3列的,但是为了让代码灵活起来,我们选择用宏定义,将行定义为ROW,列定义为COL:于是在game.h文件里面:

#define ROW 3
#define COL 3
4.初始化棋盘

现在game.h文件里面声明初始化棋盘的函数并引用头文件:

#include

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);

接下来转到game.c文件中写函数的定义:

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

这里已经将3*3个格子的元素全部初始化为空格。而为什么要初始化为空格不为0,原因是空格占一个字符,0占两个,打印出来会对不齐。

5.打印棋盘

在game.h文件里面声明打印棋盘的函数:

//打印棋盘
void display_board(char board[ROW][COL], int row, int col);

接下来转到game.c文件中写函数的定义:

void display_board(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);//要把格子打印在中央
			if(j
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("n");
		}
	}
}

然后我们就成功的打印出了上面图中我们需要的棋盘,当然,也可以把ROW和COL定义的3改为4,就会打印出4*4的棋盘了。

6.开始下棋

我们要实现玩家下一步棋,电脑下一步棋,直到有一方赢,所以就是一直循环到有人赢,循环里面,玩家走一步,打印给玩家看,电脑走一步,打印给玩家看,先给死循环,判断条件我们下面再说

void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);
	while (1)
	{
		player_move(board, ROW, COL);//玩家下棋
		display_board(board, ROW, COL);//打印棋盘
		computer_move(board, ROW, COL);//电脑下棋
		display_board(board, ROW, COL);//打印棋盘
	}
}

在game.h中声明玩家下棋和电脑下棋的函数:

//玩家下棋
void player_move(char board[ROW][COL], int row, int col);

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);

在game.c文件中定义这两个函数:

//玩家下棋:
//这里我们把玩家下的子定义为*
void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下:n");
	//判断下棋合法
	int x = 0, y = 0;
	while (1)
	{
		scanf("%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 computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑下:n");
	int x = 0, y = 0;
	while (1)
	{
		x = rand() % row;//产生一个0到2的随机数
		y = rand() % col;//产生一个0到2的随机数
        //判断坐标合法即可下子
		if (x >= 0 && x <= row - 1 && y >= 0 && y <= col - 1 && board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
        //这里给电脑下的不需要提示坐标是否合法,玩家的才需要。电脑下了子直接跳出就行了。
	}
}

我们在电脑下棋那的x和y要产生随机数,所以我们需要写一个时间种子,在game.h里面引用时间函数的头文件和srand函数的头文件:

#include
#include

我们srand函数只需要调用一次,所以我们在main()函数里面调用一次即可:

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//就是这。
	do
	{
		menu();
		printf("请选择 >:n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("欢迎下次再玩!n");
			break;
		default:
			printf("输入错误,请重新输入!n");
			break;
		}
	} while (input);
	return 0;
}
7.判断谁赢

我们以返回的棋子来判断谁赢或者平局,需要每下一步就判断一次:

我们这里返回*就是玩家赢,返回#就是电脑赢,返回Q就是平局,返回C,就是继续游戏

void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);
	while (1)
	{
		player_move(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
		computer_move(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
	{
		printf("玩家赢!n");
	}
	else if (ret == '#')
	{
		printf("电脑赢!n");
	}
	else if (ret == 'Q')
	{
		printf("平局!n");
	}
}

在game.h文件中写函数的声明:

//判断谁赢
char is_win(char board[ROW][COL], int row, int col);

在game.c中写函数的定义:

我用了标签flag来判断,使得判断灵活了起来,无论的4*4的还是其它数的,都可以判断

int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;//横线判断:
	for (i = 0; i < row; i++)
	{
		int flag1 = 1;
		for (j = 0; j < col-1; j++)
		{
			if (board[i][j] != board[i][j + 1] || board[i][j+1] == ' ')
			{
				flag1 = 0;
				break;
			}
		}
		if (flag1 == 1)
		{
			return board[i][j];
		}
	}
    //竖直判断:
	for (i = 0; i < col; i++)
	{
		int flag2 = 1;
		for (j = 0; j < row - 1; j++)
		{
			if (board[j][i] != board[j + 1][i]|| board[j+1][i] == ' ')
			{
				flag2 = 0;
				break;
			}
		}
		if (flag2 == 1)
		{
			return board[j][i];
		}
	}
    //从左到右斜线判断:
	int flag3 = 1;
	for (i = 0; i < row-1; i++)
	{
		if (board[i][i] != board[i + 1][i + 1] || board[i+1][i+1] == ' ')
		{
			flag3 = 0;
			break;
		}
	}
	if (flag3 == 1)
	{
		return board[i][i];
	}
	//从右到左斜线判断:
	int flag4 = 1;
	for (i = 0, j = col - 1; i < row, j>0; i++, j--)
	{
		if (board[i][j] != board[i + 1][j - 1] || board[i+1][j-1] == ' ')
		{
			flag4 = 0;
			break;
		}
	}
	if (flag4 == 1)
	{
		return board[i][j];
	}
	int ret = is_full(board, ROW, COL);//判断是否为平局
	if (ret == 1)
	{
        //返回平局
		return 'Q';
	}
    //以上的都不是,就返回继续游戏
		return 'C';
	}
8.总结

写到这里,恭喜你!你已经把三子棋的代码完成了!

放出最后代码的样子:

test.c文件:

//三子棋
#include "game1.h"

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

void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);
	while (1)
	{
		player_move(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
		computer_move(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
	{
		printf("玩家赢!n");
	}
	else if (ret == '#')
	{
		printf("电脑赢!n");
	}
	else if (ret == 'Q')
	{
		printf("平局!n");
	}
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择 >:n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("欢迎下次再玩!n");
			break;
		default:
			printf("输入错误,请重新输入!n");
			break;
		}
	} while (input);
	return 0;
}

game.h文件:

#pragma once
#define ROW 3
#define COL 3
#include
#include
#include

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);

//打印棋盘
void display_board(char board[ROW][COL], int row, int col);

//玩家下棋
void player_move(char board[ROW][COL], int row, int col);

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);

//判断谁赢
char is_win(char board[ROW][COL], int row, int col);

game.c文件:

#include "game1.h"


//初始化棋盘
void init_board(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}


void display_board(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if(j
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("n");
		}
	}
}

void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下:n");
	//判断下棋合法
	int x = 0, y = 0;
	while (1)
	{
		scanf("%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 computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑下:n");
	int x = 0, y = 0;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (x >= 0 && x <= row - 1 && y >= 0 && y <= col - 1 && board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		int flag1 = 1;
		for (j = 0; j < col-1; j++)
		{
			if (board[i][j] != board[i][j + 1] || board[i][j+1] == ' ')
			{
				flag1 = 0;
				break;
			}
		}
		if (flag1 == 1)
		{
			return board[i][j];
		}
	}
	for (i = 0; i < col; i++)
	{
		int flag2 = 1;
		for (j = 0; j < row - 1; j++)
		{
			if (board[j][i] != board[j + 1][i]|| board[j+1][i] == ' ')
			{
				flag2 = 0;
				break;
			}
		}
		if (flag2 == 1)
		{
			return board[j][i];
		}
	}
	int flag3 = 1;
	for (i = 0; i < row-1; i++)
	{
		if (board[i][i] != board[i + 1][i + 1] || board[i+1][i+1] == ' ')
		{
			flag3 = 0;
			break;
		}
	}
	if (flag3 == 1)
	{
		return board[i][i];
	}

	int flag4 = 1;
	for (i = 0, j = col - 1; i < row, j>0; i++, j--)
	{
		if (board[i][j] != board[i + 1][j - 1] || board[i+1][j-1] == ' ')
		{
			flag4 = 0;
			break;
		}
	}
	if (flag4 == 1)
	{
		return board[i][j];
	}
	int ret = is_full(board, ROW, COL);
	if (ret == 1)
	{
		return 'Q';
	}
		return 'C';
	}

写的不好,欢迎批评指正!你的每一句建议,都对我很重要!希望我们都可以一起进步!

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1037337.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号