C语言小游戏:三子棋(简单版)实现讲解

2023-10-28

目录

前言

打印菜单

初始化棋盘

打印棋盘

玩家下棋

电脑下棋(重难点)

判断输赢

组合函数来实现游戏

 源代码    


前言

        这是一篇实现一个简陋的C语言小游戏【三子棋】的讲解,后面要是有自己的想法的话可以自行为小游戏添加一点游戏项目。

最终实现的样式

              


打印菜单

        我们首先要打印一个游戏菜单来供玩家选择, 是开始游戏还是退出游戏,由于每局游戏开始前都会将菜单打印出来供玩家选择,,而且至少需要执行一次。所以我们将菜单放在do  whlie循环里面。后面的游戏代码也是同样的道理。

void menu(void)   //由于不需要返回值而且没有参数,所以返回类型和函数参数都是void
{
	printf("**********************\n");
	printf("***** 1、开始游戏 *****\n");          //可以根据自己的喜好来调格式
	printf("***** 0、退出游戏 *****\n");          //在屏幕中间效果可能会更好(我不会)
	printf("**********************\n");
}

初始化棋盘

        可以看到我们的棋盘在刚开始的时候是一个没有任何东西的,并且是有行和列来确定位置的,那我们就可以用一个二维字符数组来存放这个棋盘的内容,并且初始化为空格 ' '。


//这里是使用函数的形式来进行初始化,首先要在主函数里面创建一个二维的字符数组
void star_board(char board[ROW][COL],int row,int col)
{
	for (int i = 0; i < row; i++)          //两层的循环分别代表着行和列
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ' ';    //初始化为' '。
		}
	}

打印棋盘

        打印棋盘的原理和初始化棋盘的原理一样,都是两层循环。但是可以根据自己想要的效果来控制打印的格式。

void put_board(char board[ROW][COL],int row,int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)                    
				printf("|");                  //每列结束的时候打印 |来区分列
		}
		if (i < row - 1)
		{
			printf("\n");
			printf("------------");           //每行结束的时候打印——————来区分行
			printf("\n");
		}
		else
			printf("\n");

	}
}

玩家下棋

        玩家下棋的时候需要玩家自己输入坐标所以需要设置两个变量来模拟行(x)和列(y),并且将二维数组中对应的元素改成 ' * ',用来区分玩家、电脑还有没有下的地方。并在玩家输入错误的坐标的时候及时提醒玩家。


//小细节:形参ch是为了将数组中的元素改成自己想要的字符,这样就可以避免重复多次定义函数

void player_move(char board[ROW][COL], int row, int col, char ch)
{
	int x, y;
	printf("玩家下棋,请输入坐标:");
	do {
		scanf("%d%d", &x, &y);
		if (x - 1 > row || y - 1 > col)
		{
			printf("非法输入,请输入正确的坐标:");     //没有输入正确的坐标的时候给与正确的提示
			continue;
		}
		if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = ch;            //将数组中的元素改为ch
			break;
		}
		else
			printf("该坐标已经被占用,请重新输入坐标:");   //输入已经被下过的坐标的时候给与提示
	} while (1);
	
}

电脑下棋(重难点)

        这个是这个游戏的重难点。电脑下棋的时候既要下在棋盘内部,还要下在没有下过的地方,如果还要实现各种智能算法的话就更加复杂了。在这里我们只实现下棋(所以这个游戏的难度在于让计算机赢),算法就不做深入的研究,有兴趣的小伙伴可以自行研究。

        让电脑下棋的时候我们需要让电脑的棋子落在棋盘内,并且还要是没有下过的,这时候就需要使用随机数函数rand了,在使用rand之前我们需要使用srand来生成随机数的范围,在使用srand的时候我们又需要使用一个时间戳函数time【具体的函数内容可以点击函数来查看】

void computer_move(char board[ROW][COL], int row, int col, char ch)    //控制电脑的棋子样式
{
	printf("电脑下棋:\n");
	
	while (1)
	{
		int x = rand() % 3;        //使电脑的棋子落在棋盘内
		int y = rand() % 3;
		if (board[x][y] == ' ')        //判断棋盘有没有被下过
		{
			board[x][y] = ch;           //电脑下棋
			break;
		}
	}
}

判断输赢

        在三子棋中游戏的输赢无非就是横竖撇捺上面连续三个棋子是一样的,所以我们只需要判断一下是否满足这个条件就可以了,如果是电脑赢了的话就返回电脑的棋子,如果是玩家赢了的话就返回玩家的棋子,如果是平局(也就是棋盘上面已经满了但是也没有三个练续的棋子)的时候,就返回&。

char is_win(char board[ROW][COL], int row, int col)
{
	int count = 0;
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == '*')
			return '*';
		if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == '#')
			return '#';
	}
	if ((board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*') || (board[0][2]     
    == '*' && board[1][1] == '*' && board[2][0] == '*'))
	{
		return '*';
	}
	if ((board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#') || (board[0][2] 
    == '#' && board[1][1] == '#' && board[2][0] == '#'))
	{
		return '#';
	}
	for (int i = 0; i < col; i++)
	{
		if (board[0][i] == '*' && board[1][i] == '*' && board[2][i] == '*')
			return '*';
		if (board[0][i] == '#' && board[1][i] == '#' && board[2][i] == '#')
			return '#';
	}
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				count++;
		}
	}
	if (count == 0)
	{
		printf("游戏平局!!");
		return '&';
	}	
}

组合函数来实现游戏

        在游戏的全部功能都由函数实现了之后,就只需要将函数组合在一起就可以将游戏实现了。

void game()
{
	char board[ROW][COL];
	star_board(board, ROW, COL);        //初始化棋盘
	put_board(board, ROW, COL);          //打印棋盘

	do {
		player_move(board, ROW, COL, '*');        //玩家下棋
		put_board(board, ROW, COL);               //打印棋盘
		if (is_win(board, ROW, COL) == '*')       //判断输赢
		{
			printf("玩家赢!!\n");
			break;
		}
		if (is_win(board, ROW, COL) == '&')       //判断是否平局
		{
			printf("游戏平局!!\n");
			break;
		}
		computer_move(board, ROW, COL, '#');      //电脑下棋
		put_board(board, ROW, COL);               //打印棋盘
		if (is_win(board, ROW, COL) == '#')       //判断输赢
		{
			printf("电脑赢!!\n");
			break;
		}
		if (is_win(board, ROW, COL) == '&')       //判断输赢
		{
			printf("游戏平局!!\n");
			break;
		}
	} while (1);
}

 源代码    

        如果在实现这个小游戏的时候有什么不懂的时候可以通过这个地址查看源代码三子棋小游戏: 三子棋的源代码

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

C语言小游戏:三子棋(简单版)实现讲解 的相关文章

随机推荐

  • linux下库文件的制作和链接、动态加载流程

    很长时间没有回过头总结下unix下c相关的知识了 重新捡起来好好品味一下 砸 真香 在学习库的制作之前 我们先简单写一个多文件的例子 编写一个 h 和 c的文件 如下所示 mymath h ifndef MYMATH H define MY
  • 【Protobuf速成指南】enum类型的使用

    文章目录 2 1枚举类型 一 如何定义枚举类型 二 语法规范 三 重定义问题 四 enum类型相关函数 五 Contact 2 1 改写 六 总结 2 1枚举类型 本系列文章将通过对通讯录项目的不断完善 带大家由浅入深的学习Protobuf
  • Python爬取上交所年报并下载

    批量下载上交所年报及相关细节处理 一 使用工具 Python3 6 Pycharm 二 准备工作 import json import requests import re import datetime import csv f open
  • 常量表达式(const expression)

    常量表达式是指值不会改变并且在编译过程中就能得到计算结果的表达式 问 int staff size 27 const int sz get size 是不是常量表达式 答 int staff size 27 staff size 不是常量表
  • Pygame详解(十一):Rect 对象

    class pygame Rect Rect 是用于存储矩形坐标的 Pygame 对象 Rect left top width height gt Rect Rect left top width height gt Rect Rect o
  • Java堆内存是线程共享的吗?

    Java堆内存是线程共享的吗 看似简单却暗藏玄机 本文来源 敖丙 阅读文章前请先对Java运行时数据区有一定了解 可参考 JVM运行时数据区初识 Java堆内存是线程共享的吗 Java对象的内存分配过程是如何保证线程安全的 什么是TLAB
  • 【单片机毕业设计】【mcuclub-dz-044】基于STM32的智能泳池的设计与实现

    最近设计了一个项目基于STM32的智能泳池的设计与实现 与大家分享一下 一 基本介绍 项目编号 mcuclub dz 044 项目名 基于单片机的泳池的设计 单片机类型 STM32F103C8T6 具体功能 1 通过防水式DS18B20测量
  • 利用python编写自动化格式文档并打包成exe

    开发环境 开发思路 选择一个配置文件 txt格式 生成文件格式 txt格式 开发思路 读取配置文件信息 生成固定格式的文本文件 具体固定格式可根据自身需求生成 代码 import os file name reg set txt numbu
  • python处理网页弹窗,用于处理弹出式浏览器窗口的Python webdriver

    切换到弹出窗口至少有两个不同的原因 很多人都知道 当弹出窗口出现时 你需要同时使用driver switch to window window handle 这样你就可以在弹出窗口中找到元素 在弹出窗口关闭后 你就可以在主窗口中找到元素 只
  • 学习笔记-架构的演进之分布式架构-服务发现-2月day19

    文章目录 服务发现 Service Discovery 服务发现要解决注册 维护和发现三大功能问题 服务的注册 Service Registration 服务的维护 Service Maintaining 服务的发现 Service Dis
  • JDK1.8安装和环境搭建步骤

    JDK1 8安装步骤 1 安装文件 首先打开JDK的安装包 选择公共JRE 下载的路径可以根据自己的选择更改 我选择的是D盘 接着默认下一步 直到安装出现到下图 为了方便后期的使用 此处的jre安装建议和JDK文件同级 2 环境变量配置 1
  • C#初级需要掌握的知识点

    俗话说 温故而知新 可以为师矣 为师就拉倒吧 还是巩固巩固自己的地基吧 今天想要记录的就是C 语法中的基础部分 这一篇就先记录一下知识点的序列吧 然后接下来再根据这个序列来一步步的完成复习 1 C 和 Net框架的概念和运行原理 2 C 程
  • 万字长文人脸识别深度研究:发展与市场、市场研究、流程及主要技术、行业应用、产品落地和个人看法

    来源 知乎 软件定义世界 作者 放飞人夜 一 发展与市场 1 人脸识别的理解 人脸识别 Face Recognition 是一种依据人的面部特征 如统计或几何特征等 自动进行身份识别的一种生物识别技术 又称为面像识别 人像识别 相貌识别 面
  • Python十大装B语法

    Python 是一种代表简单思想的语言 其语法相对简单 很容易上手 不过 如果就此小视 Python 语法的精妙和深邃 那就大错特错了 本文精心筛选了最能展现 Python 语法之精妙的十个知识点 并附上详细的实例代码 如能在实战中融会贯通
  • mac jdk下载 https://www.oracle.com/java/technologies/downloads/archive/

    Java Archive Oracle MAC 系统安装 JDK 及环境变量配置 蜗牛的博客 CSDN博客
  • 给明年依然年轻的我们:欲望、外界、标签、天才、时间、人生目标、现实、后悔、和经历

    原文链接 http blog sina com cn s blog 6e8e05ac0100wu4h html 今天是22岁的最后一天 几个月前 我从沃顿商学院毕业 用文凭上 最高荣誉毕业 的标签安抚了已经年过半百的老妈 然后转头辞去了毕业
  • vue3 中使用tsx&插槽的使用

    app tsx文件 import defineComponent ref from vue import setPermissionsVisible from shared export default defineComponent se
  • 度量学习:使用多类N对损失改进深度度量学习

    度量学习系列 Author 码科智能 使用多类N对损失改进深度度量学习 度量学习是ReID任务中常用的方式之一 今天来看下一篇关于如何改进度量学习的论文 来自2016年NeurIPS上的一篇论文 被引用超过900次 论文 Improved
  • [C++] volatile 关键字

    C C 中的 volatile 关键字是一种类型修饰符 用它声明的类型变量表示可以被某些编译器未知的因素更改 比如 操作系统 硬件或者其它线程等 遇到这个关键字声明的变量 编译器对访问该变量的代码就不再进行优化 从而可以提供对特殊地址的稳定
  • C语言小游戏:三子棋(简单版)实现讲解

    目录 前言 打印菜单 初始化棋盘 打印棋盘 玩家下棋 电脑下棋 重难点 判断输赢 组合函数来实现游戏 源代码 前言 这是一篇实现一个简陋的C语言小游戏 三子棋 的讲解 后面要是有自己的想法的话可以自行为小游戏添加一点游戏项目 最终实现的样式