IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言实现井字棋小游戏 -> 正文阅读

[C++知识库]C语言实现井字棋小游戏

C语言实现井字棋小游戏

前言

相信很多人都玩过井字棋,简单介绍一下游戏规则:
当行或列或斜对角出现三个相同棋子,那么使用该棋子的棋手获胜。那么今天我们利用C语言中的数组和循环的知识来实现一个简单的三子棋小游戏。这里我们可以分文件写,这样更加清晰明了。
那么我们大概可以分为几个步骤:
1. 打开vs2019
2. 新建项目
3. 写入代码
4. 运行,大功告成

在这里插入图片描述
1.写一个简易的菜单
2.初始化并打印出棋盘
3.玩家或者电脑下棋
4.判断输赢

本次项目大致可以分为三个文件:
1.game.c(函数的实现)
2.game.h(函数声明,头文件)
3.主程序.c

一、写一个简易的菜单

在主程序中写出一个建议的菜单

void menu()
{
	printf("请选择:\n");
	printf("***************************\n");
	printf("***1.play         2.exit***\n");
	printf("***************************\n");
}

当我们选择1时就进入游戏,如果选择2则退出游戏。

int main()
{
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
 		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏");
			break;
		default:
			printf("输入错误,请重新输入");
		}
	} while (input != 2);
	return 0;
}

这里的game()函数即是游戏整体的实现


二、初始化并打印出棋盘

void game()
{
	char board[ROW][COL] = { 0 };
	initialize(board, ROW, COL);//初始化棋盘
	display(board, ROW, COL);//打印棋盘
}

在game.h头文件中声明头文件中定义ROW、COL为3,声明出这两个函数,并包含所需头文件

#define ROW 3
#define COL 3
#include<stdio.h>
void initialize(char board[ROW][COL], int row, int col);
void display(char board[ROW][COL], int row, int col);

那么再实现这两个函数

1. 先进行初始化棋盘,将棋盘中的每个数值初始化为空白

在game.c中实现代码,代码如下(示例):

void initialize(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. 打印出棋盘,并且中间要留下棋子(数组)的位置

在game.c中实现代码,代码如下(示例):

void display(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(i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}	
			}
			printf("\n");
		}
	}
}

效果图
1.这里棋盘的打印可以分为三行,三列。
2.在第一行中打印出棋盘内容(数组内容)和分隔符’ | ‘,换行。
3.打印分割用的’—’,三列打印三次即可,再打印出分隔 符’|’。(演示效果图连在一起了)。
4.利用循环,依次打印出第二行,第三行的内容。


三、玩家或者电脑下棋

1. 玩家下棋(并打印)

在game()函数中调用,代码如下(示例):

void game()
{
	char board[ROW][COL] = { 0 };
	initialize(board, ROW, COL);//初始化棋盘
	display(board, ROW, COL);//打印棋盘
	playermove(board, ROW, COL);//玩家移动
	display(board, ROW, COL);//打印
}

在game.h头文件中声明,代码如下(示例):

#define ROW 3
#define COL 3
void initialize(char board[ROW][COL], int row, int col);
void display(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col);

在game.c中实现代码,代码如下(示例):

void playermove(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x, y = 0;
		printf("请输入您要下的位置");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (board[x-1][y-1] == ' ')
			{
				board[x-1][y-1] = '*';
				break;
			}
			else
			{
				printf("该位置已有棋子,请重新输入\n");
			}
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
}

作为游戏的设计者当然知道数组下标是从0开始的,但是玩家不知道啊,所以让玩家输入一个大于零小于三的数字,并在玩家所输入的数字基础上减1即可。
当玩家移动后让电脑移动:

2. 电脑下棋(并打印)

在game()函数中调用,代码如下(示例):

void game()
{
	char board[ROW][COL] = { 0 };
	initialize(board, ROW, COL);//初始化棋盘
	display(board, ROW, COL);//打印棋盘
	playermove(board, ROW, COL);//玩家移动
	display(board, ROW, COL);//打印
	pcmove(board, ROW, COL);//电脑走
	display(board, ROW, COL);//打印
}

在game.h头文件中声明,代码如下(示例):

#define ROW 3
#define COL 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void initialize(char board[ROW][COL], int row, int col);
void display(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col);
void pcmove(char board[ROW][COL], int row, int col);

在game.c中实现代码,代码如下(示例):

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

这里还是定义数组的下标为x,y。并使用循环判断数组位置是否为空白,下完棋子使用break终止循环。与玩家不同的是x,y是随机值,那么在C语言中的随机值是用rand函数,并且取余之后的值的范围,是根据模谁来判断的,在C语言中时间就是一个随机数。要在主程序中进行初始化并且要在头文件中包含<stdlib.h>和<time.h>文件,同时电脑也要下在空白处。

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		scanf("%d", &input);
 		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏");
			break;
		default:
			printf("输入错误,请重新输入");
		}
	} while (input != 2);
	return 0;
}
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void initialize(char board[ROW][COL], int row, int col);
void display(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col);
void pcmove(char board[ROW][COL], int row, int col);

这里将头文件一并写在geme.h的头文件中,那么在其他文件中直接#include"game.h"即可。

很明显的,我们下棋不可能只下一次就结束了,那么我们可以对playermove和pcmove使用一个循环,然后在循环中,判断输赢平局之类的,用以跳出整个循环。
在game()函数中实现代码,代码如下(示例):

void game()
{
	char board[ROW][COL] = { 0 };
	initialize(board, ROW, COL);//初始化棋盘
	display(board, ROW, COL);//打印棋盘
	while (1)
	{
		playermove(board, ROW, COL);//玩家移动
		display(board, ROW, COL);//打印
		pcmove(board, ROW, COL);//电脑走
		display(board, ROW, COL);//打印
	}
}

至此,大概的游戏模块已经实现完毕,万事俱备。最后再写一个用以判断的函数即可

四、判断输赢

在game()函数中调用,代码如下(示例):

定义一个字符变量char ret= whowin(board, ROW, COL)。用于接收whowin函数的返回值
如果返回值为‘*’,玩家获胜,返回值’#'电脑获胜。(不会真有人输给电脑吧)。

每下完一个棋,都要进行判断输赢,当不满足获胜或平局条件则返回字符’C’,循环继续,当满足获胜或平局条件,则返回其他字符,循环终止,进行判断是谁赢了,或者平局。

void game()
{
	char board[ROW][COL] = { 0 };
	initialize(board, ROW, COL);//初始化棋盘
	display(board, ROW, COL);//打印棋盘
	char ret = 0;
	while (1)
	{
		playermove(board, ROW, COL);//玩家移动
		display(board, ROW, COL);//打印
		ret = whowin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		pcmove(board, ROW, COL);//电脑走
		display(board, ROW, COL);//打印
		ret = whowin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
		if (ret == '*')
		{
			printf("玩家获胜\n");
		}
		else if (ret == '#')
		{
			printf("电脑获胜\n");
		}
		else
		{
			printf("平局\n");
		}
}

在game.h头文件中声明,代码如下(示例):

用于判断输赢的函数声明返回值类型为char型,返回该行中已经获胜的数组元素。

#define ROW 3
#define COL 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void initialize(char board[ROW][COL], int row, int col);
void display(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col);
void pcmove(char board[ROW][COL], int row, int col);
int is_full(char board[ROW][COL], int row, int col);
char whowin(char board[ROW][COL], int row, int col);



在game.c中实现代码,代码如下(示例):

返回值类型为int 型的is_full函数判断棋盘是否为满格,如果是满格则返回1,如果不是返回0。
并且在whowin函数中接收值

int is_full(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++)
		{
			if (board[i][j]==' ')
				return 0;//没满
		}
	}
	return 1;//满了
}
char whowin(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][1] != ' ')
		{
			return board[i][0];
		}
	}
	//判断列
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j]&&board[j][1] != ' ')
		{
			return board[0][j];
		}
	}
	//斜对角
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
		return board[1][1];

	if (1 == is_full(board, ROW, COL))
	{
		return 'Q';
	}
	return 'C';
}

在代码中使用循环遍历数组:分别判断行列对角线的判断,并返回该行中其中一个元素即可。
在用if语句判断if_full函数数组元素是否满格,如果is_full函数返回值为1,则满格则返回Q,不是就返回C。且作为判断的中间值board[i][1]或者board[j][1]不能为空白,否则判断为平局。如果去掉这一判断条件,判断到第二行时,全部为’ ‘(空格字符),返回’ '(空格字符),判断平局。

总结

提示:这里对代码进行总结:

game.h文件

#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 3
#define COL 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void initialize(char board[ROW][COL], int row, int col);
void display(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col);
void pcmove(char board[ROW][COL], int row, int col);
int is_full(char board[ROW][COL], int row, int col);
char whowin(char board[ROW][COL], int row, int col);

game.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void initialize(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;
	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(i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}	
			}
			printf("\n");
		}
	}
}

void playermove(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x, y = 0;
		printf("请输入您要下的位置");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (board[x-1][y-1] == ' ')
			{
				board[x-1][y-1] = '*';
				break;
			}
			else
			{
				printf("该位置已有棋子,请重新输入\n");
			}
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
}

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

int is_full(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++)
		{
			if (board[i][j]==' ')
				return 0;//没满
		}
	}
	return 1;//满了
}
char whowin(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][1] != ' ')
		{
			return board[i][0];
		}
	}
	//判断列
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j]&&board[j][1] != ' ')
		{
			return board[0][j];
		}
	}
	//斜对角
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
		return board[1][1];
	if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
		return board[1][1];

	if (1 == is_full(board, ROW, COL))
	{
		return 'Q';
	}
	return 'C';
}



主程序.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
	printf("请选择:\n");
	printf("***************************\n");
	printf("***1.play         2.exit***\n");
	printf("***************************\n");
}

void game()
{
	char board[ROW][COL] = { 0 };
	initialize(board, ROW, COL);//初始化棋盘
	display(board, ROW, COL);//打印棋盘
	char ret = 0;
	while (1)
	{
		playermove(board, ROW, COL);//玩家移动
		display(board, ROW, COL);//打印
		ret = whowin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		pcmove(board, ROW, COL);//电脑走
		display(board, ROW, COL);//打印
		ret = whowin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
		if (ret == '*')
		{
			printf("玩家获胜\n");
		}
		else if (ret == '#')
		{
			printf("电脑获胜\n");
		}
		else
		{
			printf("平局\n");
		}
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		scanf("%d", &input);
 		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏");
			break;
		default:
			printf("输入错误,请重新输入");
		}
	} while (input != 2);
	return 0;
}

那么这么一个非常简单的三子棋小游戏就完成了。
比心!
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-29 11:27:16  更:2021-07-29 11:27:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/29 4:35:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码