三子棋创作(c语言)

2023-11-11

我们写三子棋之前首先要思考一下三子棋的实现逻辑:

一、

1、游戏菜单,是选择开始游戏还是结束游戏

2、打印一个棋盘出来,并且进行棋盘的初始化(即没有旗子的棋盘)

3、玩家下棋(用*表示)

4、电脑下棋(用#表示)

5、判断胜负(电脑和玩家下完棋之后,均要判断)

二、具体操作步骤

1、首先我们要打印游戏的菜单界面部分

1表示开始游戏,0表示退出游戏;

void meau()
{
	printf("*****************************\n");
	printf("******  1.开始游戏  *********\n");
	printf("******  0.退出游戏  *********\n");
	printf("*****************************\n");
}

2、我们要创建一个主函数,

int main()
{
	test();
	return 0;
}

用 test() 函数表示我们要进入游戏部分;

3、我们要把test函数具体部分写出来,创建一个void类型的函数

void test()
{
	int input = 0;
	do
	{
		meau();//进入test部分,首先打印菜单
		printf("请输入:>");
		scanf_s("%d", &input);//输入1/0,是否开始游戏
	
		switch (input)
		{
		case 1:
			printf("游戏开始\n");//开始游戏
			game();//游戏开始后进入game函数部分
			break;//game执行完后跳出循环
		case 0:
			printf("退出游戏\n");
			break;//选择退出游戏,直接跳出循环
		default:
			printf("输入错误,请重新输入:>");
			break;

		}
	} while (input);//在我们输入数字的情况下,一直执行循环
}

4、选择开始游戏后,创建一个game()函数,并作为三子棋逻辑实现的主要部分;

void game()
{
    char board[ROW][COL] = { 0 };//创建一个数组,存放数据
	InitBoard(board, ROW, COL);//初始化棋盘为全空格
	DisplayBoard(board, ROW, COL);//打印棋盘
}

   1、初始化棋盘为全空格棋盘

void InitBoard(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] = ' ';//将空格放入期盼的每一个元素内
		}
	}
}

  2、打印出这个初始化的棋盘

void DisplayBoard(char board[3][3], 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");//某一行打完之后 ,换行
		}
	}
}

 3、我们运行一下目前的代码,会得到一个这样的棋盘

五、接着我们要写出玩家下棋的函数部分,玩家下完棋之后,电脑继续下棋,因此这是一个循环,因此我们的game()函数内部也就要写成下面这样

void game()
{
	char board[ROW][COL] = { 0 };//创建一个数组,存放数据
	InitBoard(board, ROW, COL);//初始化棋盘为全空格
	DisplayBoard(board, ROW, COL);//打印棋盘
	while (1)
	{
		printf("玩家下棋:>");
		Player_move(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);//再次打印棋盘

		printf("电脑下棋\n");
		Computer_move(board, ROW, COL);//电脑下棋
		DisplayBoard(board, ROW, COL);//再次打印棋盘
    }
}

 六、我们要写出玩家下棋的具体步骤:因为玩家并不知道电脑是从第0行开始执行的,因此我们要   将玩家输入的坐标(x,y)变成(x-1,y-1)作为电脑执行的命令;

void Player_move(char board[3][3], int row, int col)
{
	int x = 0;
	int y = 0;
	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] = '*';//如果没有被其他棋子占用,那么将代表玩家的*放入棋盘内部
		}
		else
		{
			printf("坐标已被占用,请重新输入!\n");//如果已经被其他棋子占用,那么重新输入
		}
	}
	else
	{
		printf("坐标非法,请重新输入!\n");
	}
}

七、玩家下完棋之后,电脑要接着下棋,因此,我们需要把大脑下棋的步骤写出来

void Computer_move(char board[3][3], int row, int col)
{
	int x = 0;
	int y = 0;
	x = rand() % row;//电脑随机生成一个数,取余之后的数字一定可用
	y = rand() % col;
	if (board[x][y] == ' ')//判断是否被占用
		board[x][y] = '#';//如果未被占用,那么将代表电脑的'#'放进去
}

    注意:由于我们需要随机生成一个数字,因此我们需要在我们的test()函数内部加上这样一行代     码srand((unsigned int)time(NULL)); ,我们的头文件中也需要再加上#include<stdlib.h>那么我们的test()将会变成下面这样

void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));//时间轴随机生成一个数字
	do
	{
		meau();
		printf("请输入:>");
		scanf_s("%d", &input);
	
		switch (input)
		{
		case 1:
			printf("游戏开始\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入:>");
			break;

		}
	} while (input);
}

 八、无论是玩家还是电脑下完棋之后都要进行判断胜负,因此我们要分析一下如何写出判断胜负  的代码,我们写一个w_win()函数来判断,游戏无非三种情况,1、玩家胜利,2、电脑胜利,           3、平局

char w_win(char board[3][3], 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][1];
	}
	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];
	}
        //判断对角线
	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];
	//判断平局
	int x = 0;
	for (x = 0; x < row; x++)
	{
		int y = 0;
		for (y = 0; y< col; y++)
		{
			if (board[x][y] != ' ')
				return 'c';
		}
	}
	
}

   九、我们在game()函数内部创建一个char 类型的ret来接收w_win()函数所返回的值, 如果返       回的是'*',那么玩家胜利,如果返回的是'#',那么电脑胜利,如果返回的是'c',那么平局。因此             我们需要在game()函数内部变成下面这样

void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };//创建一个数组,存放数据
	InitBoard(board, ROW, COL);//初始化棋盘为全空格
	DisplayBoard(board, ROW, COL);//打印棋盘
	while (1)
	{
		printf("玩家下棋:>");
		Player_move(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);//再次打印棋盘
		ret = is_win(board, ROW, COL);//判断输赢

		printf("电脑下棋\n");
		Computer_move(board, ROW, COL);//电脑下棋
		DisplayBoard(board, ROW, COL);//再次打印棋盘
		ret = is_win(board, ROW, COL);//判断输赢


		if (ret == '*')
		{
			printf("玩家赢了,游戏结束!\n");
			break;
		}
		if (ret == '#')
		{
			printf("电脑赢了,游戏结束!\n");
			break;
		}
		if (ret == 'q')
		{
			printf("平局!\n");
		}
		if (ret == 'c')
		{
			printf("游戏继续!\n");
		}
	}
}

 总结:为了方便我们观看,因此我们可以创建一个game.h的头文件来进行函数声明,并可以使用  宏定义#define来改变我们的行和列

#pragma once

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

void InitBoard(char board[3][3],int row,int col);//初始化棋盘
void DisplayBoard(char board[3][3],int row,int col);//打印棋盘
void Player_move(char board[3][3], int row,int col);//玩家下棋
void Computer_move(char board[3][3], int row, int col);//电脑下棋
char is_win(char board[3][3], int row, int col);//判断输赢

最后,下面是三子棋的完整代码,如有错误,请私聊我并指正。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include "game.h"


void InitBoard(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] = ' ';
		}
	}
}

void DisplayBoard(char board[3][3], 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 Player_move(char board[3][3], int row, int col)
{
	int x = 0;
	int y = 0;
	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] = '*';
		}
		else
		{
			printf("坐标已被占用,请重新输入!\n");
		}
	}
	else
	{
		printf("坐标非法,请重新输入!\n");
	}
}
void Computer_move(char board[3][3], int row, int col)
{
	int x = 0;
	int y = 0;
	x = rand() % row;
	y = rand() % col;
	if (board[x][y] == ' ')
		board[x][y] = '#';
}
char is_win(char board[3][3], 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][1];
	}
	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];
	}
	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];
	//判断平局
	int x = 0;
	for (x = 0; x < row; x++)
	{
		int y = 0;
		for (y = 0; y< col; y++)
		{
			if (board[x][y] != ' ')
				return 'c';
		}
	}
	
}
void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };//创建一个数组,存放数据
	InitBoard(board, ROW, COL);//初始化棋盘为全空格
	DisplayBoard(board, ROW, COL);//打印棋盘
	while (1)
	{
		printf("玩家下棋:>");
		Player_move(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);//再次打印棋盘
		ret = is_win(board, ROW, COL);//判断输赢

		printf("电脑下棋\n");
		Computer_move(board, ROW, COL);//电脑下棋
		DisplayBoard(board, ROW, COL);//再次打印棋盘
		ret = is_win(board, ROW, COL);//判断输赢


		if (ret == '*')
		{
			printf("玩家赢了,游戏结束!\n");
			break;
		}
		if (ret == '#')
		{
			printf("电脑赢了,游戏结束!\n");
			break;
		}
		if (ret == 'q')
		{
			printf("平局!\n");
		}
		if (ret == 'c')
		{
			printf("游戏继续!\n");
		}
	}
}
void meau()
{
	printf("*****************************\n");
	printf("******  1.开始游戏  *********\n");
	printf("******  0.退出游戏  *********\n");
	printf("*****************************\n");
}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		meau();
		printf("请输入:>");
		scanf_s("%d", &input);
	
		switch (input)
		{
		case 1:
			printf("游戏开始\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入:>");
			break;

		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三子棋创作(c语言) 的相关文章

  • vue获取浏览器的指纹码

    前言 获取浏览器的指纹码 操作步骤 1 vue安装插件 1 使用CDN在线获取 https cdnjs com libraries fingerprintjs2 2 使用bowerinstall命令进行安装 bowerinstall fin
  • ElasticSearch 常用命令大全

    作者 十余年工作经验 跨域学习者 从事过全栈研发 项目经理等工作 一个爱折腾的程序员 1 获取索引列表 GET cat indices format json index 索引名称 可使用通配符 2 别名操作 GET alias 20 PO

随机推荐

  • kali linux扫描sql注入,Kali Linux系统利用DVWA靶场进测试SQL注入漏洞:

    手工盲注 手工盲注分为基于布尔的盲注 基于时间的盲注以及基于报错的盲注 手工盲注步骤 1 判断是否存在注入 注入是字符型还是数字型 2 猜解当前数据库名 3 猜解数据库中表名 4 猜解表中的字段名 5 猜解数据 Low安全级别源代码 if
  • full join 和full outer join_带你了解数据库中JOIN的用法

    前言 欢迎关注公众号 Coder编程 获取最新原创技术文章和相关免费学习资料 随时随地学习技术知识 本章主要介绍数据库中Join的的用法 也是我们在使用数据库时非常基础的一个知识点 本次会介绍数据库中的 inner join left jo
  • 30天自制操作系统学习-第10天

    1 内存管理 续 我们第一件事依旧是整理我们的bootpack c主文件 发现它在已长达200多行 我们分离出部分到memoy c函数中 并且对内存管理采用向上取整的策略 对部分零散的内存得以利用 新加的memory c 内存管理 incl
  • ESP8266-WIFI模块AT固件烧录

    目录 设备 AT固件烧录步骤 Step1 打开并启动软件 Step2 配置相关文件 Step3 配置结束 完成烧录 注意事项 文件资料 设备 1 烧录器一个 2 ESP8266 01S WIFI模块一个 AT固件烧录步骤 Step1 打开并
  • jmap 和jstack使用

    jmap jmap是JDK提供的一个可以生成Java虚拟机的堆转储快照dump文件的命令行工具 1 查看整个JVM内存状态 jmap heap pid 2 查看JVM堆中对象详细占用情况 jmap histo pid 3 导出整个JVM 中
  • 疯狂的程序员(绝影)

    这是CSDN上连载的小说 很有趣 刚开始学习计算机的那段历史 读起来是那样的熟悉 我也是从那种激动的过程中走过来的 发现有激情来能做成事情 这是最伟大的动力 读读这本书 回忆一下自己的当年 1 汇编代码 平时用的特别少 但是不是应该仔细的研
  • easy excel date 类型解析报错_最新Pandas.read_excel()全参数详解(案例实操,如何利用python导入excel)...

    pandas read excel 的作用 将Excel文件读取到pandas DataFrame中 支持从本地文件系统或URL读取的xls xlsx xlsm xlsb和odf文件扩展名 支持读取单一sheet或几个sheet 以下是该函
  • 【数据集】Python爬取某国内所有航班记录

    一 分析数据集 我们需要获取航班的数据集合 dcity acity airlineName flightNumber airportName departureDate arrivalDate punctualityRate price 航
  • 一言以蔽之

    其上申韩者 其下必佛老 这句的意思是 统治者如果采用法家式的高压态势治理国家 那么民众就只能从道家和佛家里寻找心理安慰了 也就是道家和佛家为专制权力之下的人提供了一种虚假的逃避方式 菜根谭 作者糅合了儒家的中庸 道家的无为 释家的出世和自身
  • BEPS生态过程模型简介和使用

    一 BEPS模型发展简介 二 BEPS模型代码和参数简介 代码链接 link 模型运行 待更新
  • 在vue项目中设置网站图标

    怎么在我们的Vue项目中设置自定义的网站图标 首先我们需要先制作个ico图标 大小为32 32的 放到static文件夹下 附制作网站 我们把制作好的ico图片改名为 favicon ico 注 必须改名 放到我们项目中的static文件夹
  • softmax分类器 python实现

    转自 http blog csdn net wds2006sdo article details 53699778 utm source itdadao utm medium referral 算法 算法参考的是Andrew 的课件与这篇文
  • Android中获取View宽高方法

    今天遇到一个问题 就是view获取宽度 高度都为0的问题 其实这个大家都遇到过 这里转载别人的 大家好共同学习 本文转载于 http www jianshu com p f56c92e29dea Android开发中经常需要获取控件的宽高
  • FileZilla的下载与安装

    FileZilla的下载与安装 为什么要使用FileZilla进行文件互传呢 Windows下 FileZilla客户端下载与安装 1 FileZilla的下载 1 FileZilla的安装 1 双击运行安装包 点击 i agree 2 n
  • Shader中的一些专业用语的解释

    Shader中的一些专业用语的解释 此文章收录于我主页顶置的 Unity Shader入门精要文章目录 点击即可跳转 一 什么是OPenGL DirectX 简单的来说 就是图像应用编程的接口 这些接口用语渲染二维和三维的图形 架起了上层应
  • 【毕业设计】基于单片机的桌面炫酷律动灯条 -物联网 嵌入式 单片机

    文章目录 0 前言 1 简介 2 主要器件 3 实现效果 4 设计原理 5 部分核心代码 6 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹告诉
  • 公办幼儿园教师要涨工资了???

    终于盼到这一天了 已在市区公办园上班3年多却一直没有编制的季馨 听说从明年开始要涨工资了 高兴坏了 记者从日前召开的全市学前教育工作会议上获悉 从2012年起 确保市区公办幼儿园中具有国家教师资格的聘用教师最低工资水平不得低于当地最低工资标
  • 蓝桥杯 问题 1083: Hello, world!(C/C++ vector实现)

    问题 1083 Hello world 时间限制 1Sec 内存限制 64MB 提交 944 解决 476 题目描述 This is the first problem for test Since all we know the ASCI
  • 《一周搞定模电》—功率放大器

    系列文章目录 文章目录 系列文章目录 前言 一 功率放大电路三极管的工作模式 二 功率放大器内部结构 前言 功率放大器指一种以输出较大功率为目的的放大电路 特点 输出电压大 输出电流大 放大电路的输出电阻与负载匹配 电压放大器和功率放大器的
  • 三子棋创作(c语言)

    我们写三子棋之前首先要思考一下三子棋的实现逻辑 一 1 游戏菜单 是选择开始游戏还是结束游戏 2 打印一个棋盘出来 并且进行棋盘的初始化 即没有旗子的棋盘 3 玩家下棋 用 表示 4 电脑下棋 用 表示 5 判断胜负 电脑和玩家下完棋之后