当前位置: 首页 > news >正文

三子棋(超详解+完整码源)

三子棋

    • 前言
    • 一,游戏规则
    • 二,所需文件
    • 三,创建菜单
    • 四,游戏核心内容实现
      • 1.棋盘初始化
      • 1.棋盘展示
      • 3.玩家下棋
      • 4.电脑下棋
      • 5.游戏胜负判断
      • 6.game()函数内部具体实现
    • 四,游戏运行实操

前言

C语言实现三子棋是对大家对数组,函数,循环与分支等内容的考察。通过本篇文章你将学会如何制作出三子棋,坚持一段时间的复习相信你肯定能够掌握三子棋**(文末附三子棋全部代码).**
在这里插入图片描述

一,游戏规则

设计游戏前先了解三子棋基本规则,以围绕规则用C语言实现

1、人机双方轮流在格子里落子棋子,先连成三棋一线者视为胜利

2、棋盘被摆满棋子仍未分出胜利,视为平局
在这里插入图片描述

二,所需文件

三子棋并不是一项容易的代码,需要我们进行分文件编写。
什么是分文件编写?

就是把我们的程序代码划分成多个文件,这样就不会把所有的代码都放在main.c里面,采用分模块的编程思想,进行功能划分,把每个功能不一样的单独放在一个c文件里,然后写头文件把它封装成可调用的一个函数,在主函数调用这个封装好的函数,编译的时候一起编译即可

好处:

a.功能责任划分
b.方便调试
c.主程序简洁

来让给我们看看具体操作如下:
头文件中创建game.h ----用来声明函数
源文件中创建game.c—函数具体实现 / test.c—主题流程
在这里插入图片描述

三,创建菜单

先创建一个菜单以展示进入退出游戏功能:

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

用do…while循环实现菜单使用,switch语句进行菜单选择

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

四,游戏核心内容实现

game()函数中实现整个游戏,先数组棋盘


char board[ROW][COL];

1.棋盘初始化

在game.h中定义行和列为3

#define ROW 3
#define COL 3

在game.h中声明初始化函数Initboard

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

在game.c中实现初始化函数,创造三行三列的空格

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

期盼初始化完成。

1.棋盘展示

初始化完棋盘需要将棋盘打印在键盘上
在game.文件中声明打印棋盘

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

在game.c文件中实现棋盘打印函数

void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){//先打印数据printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);//再打印分割行if(i<row-1)printf("---|---|---\n");}
}

棋盘打印完成

3.玩家下棋

在game.h声明玩家下棋函数

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

在game.h中实现玩家下棋函数。玩家所在下棋子不能出棋盘否则坐标非法重新下,所下棋子必须在无棋子格子中否则坐标备占有重新下,while实现玩家下错棋子重新下直到下正确退出循环

void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("玩家下棋\n");while (1){printf("请输入要下棋的坐标:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x-1][y-1] == ' ')//数组下标从0开始所以横纵坐标各减一{board[x - 1][y - 1] = '*';break;}else{printf("该坐标被占有,请输入其他坐标\n");}}else{printf("坐标非法,请重新输入\n");}}
}

玩家下棋完成。

4.电脑下棋

在game.h声明电脑下棋函数

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

在game.c文件中实现电脑下棋函数。电脑随机下棋需要随机坐标引头文件#include <stdlib.h>,随机数生成需要头文件#include <time.h>。将电脑所下棋控制在棋盘内然后判断是否下在空棋盘内否则重下,while实现玩家下错棋子重新下直到下正确退出循环

void Computermove(char board[ROW][COL], int row, int col)
{printf("电脑开始下棋>\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}

5.游戏胜负判断

在game.h中声明胜负判断函数。

//判断输赢
>char IsWin(char board[ROW], int row, int col);

在game.c中实现胜负判断函数。每次下棋结果共有四种1.玩家嬴2.电脑嬴3.平局4.继续游戏,
for循环实现行列三点成直线,if判断玩家或电脑三点成直线打印‘ * ’或‘ # ’

char IsWin(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][0] == board[i][0] && board[i][2] != ' ')//行连成线{return board[i][0];}}for(i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] == board[2][i] && board[0][i] != ' ')//列连成线{return board[i][0];}}if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == board[2][2] && board[0][0] != ' ')//斜方连成线{return board[0][0];}if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[0][2] == board[2][0] && board[1][1] != ' ')//斜方连成线{return board[1][1];}if (isFull(board, ROW, COL)){return 'Q';}return 'C';
}

嵌套平局函数在game.h中。若所有坐标被占满(坐标都不为空)平局函数返回真,判断胜负函数返回Q平局。若坐标有空,平局函数返回假,在判断胜负函数中返回C继续游戏

static isFull(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++){if (board[i][j] == ' ')return 0;}}return 1;
}

6.game()函数内部具体实现

创建数组char board[ROW][COL];,调用初始化棋盘(Initboard(board, ROW, COL))和打印棋盘(Displayboard(board, ROW, COL))函数,while循环实现电脑和玩家相互下棋用ret接受胜负结果,如果不是继续游戏(C)则跳出循环。若结果为玩家(*)则玩家嬴,若结果为电脑(#)则电脑应,否则结果为平局。

void game()
{int ret = 0;char board[ROW][COL];Initboard(board, ROW, COL);Displayboard(board, ROW, COL);while (1){Playermove(board, ROW, COL);Displayboard(board, ROW, COL);ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}Computermove(board, ROW, COL);Displayboard(board, ROW, COL);ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}}if (ret == '*'){printf("玩家嬴\n");}else if (ret == '#'){printf("电脑嬴\n");}else{printf("平局\n");}
}

四,游戏运行实操

1.运行程序,出现菜单
在这里插入图片描述
1.选择1开始玩游戏,出现棋盘
在这里插入图片描述
2.输入下棋位置开始下棋:
在这里插入图片描述
3.棋子没有落在空位置,重新下棋
在这里插入图片描述
4出现三点成直线,获得胜利
在这里插入图片描述
5若棋盘下满,则平局
在这里插入图片描述
6.选择0,退出游戏
在这里插入图片描述

完整代码:

game.h

#pragma once#include <stdio.h>
#include <time.h>
#include <stdlib.h>#define ROW 3
#define COL 3//初始化棋盘
void Initboard(char board[ROW][COL], int row, int col);
//打印棋盘
void Displayboard(char board[ROW][COL], int row, int col);
//玩家下棋
void Playermove(char board[ROW][COL], int row, int col);
//电脑下棋
void Computermove(char board[ROW][COL], int row, int col);
//判断输赢
char IsWin(char board[ROW], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"void Initboard(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 Displayboard(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++){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)
{int x = 0;int y = 0;printf("玩家要下棋:\n");while (1){printf("请输入下棋位置:");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 Computermove(char board[ROW][COL], int row, int col)
{printf("电脑开始下棋>\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}
static isFull(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++){if (board[i][j] == ' ')return 0;}}return 1;
}
char IsWin(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][0] == board[i][0] && board[i][2] != ' '){return board[i][0];}}for(i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] == board[2][i] && board[0][i] != ' '){return board[i][0];}}if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == board[2][2] && board[0][0] != ' '){return board[0][0];}if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[0][2] == board[2][0] && board[1][1] != ' '){return board[1][1];}if (isFull(board, ROW, COL)){return 'Q';}return 'C';
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//创建菜单
void menu()
{printf("**********************\n");printf("******  1.play  ******\n");printf("******  0.exit  ******\n");printf("**********************\n");
}
//创建游戏
void game()
{int ret = 0;char board[ROW][COL];Initboard(board, ROW, COL);Displayboard(board, ROW, COL);while (1){Playermove(board, ROW, COL);Displayboard(board, ROW, COL);ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}Computermove(board, ROW, COL);Displayboard(board, ROW, COL);ret = IsWin(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();printf("请输入选项>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏>\n");break;default:printf("选择错误,重新选择>\n");break;}} while (input);return 0;
}

本次三子棋学习告一段落,三子棋详解+完整代码,反复阅读,坚持打码,相信你在不久的将来就会拿下三子棋,以扩展更高级代码。期待下次作品与大家见面!!!

相关文章:

三子棋(超详解+完整码源)

三子棋 前言一&#xff0c;游戏规则二&#xff0c;所需文件三&#xff0c;创建菜单四&#xff0c;游戏核心内容实现1.棋盘初始化1.棋盘展示3.玩家下棋4.电脑下棋5.游戏胜负判断6.game&#xff08;&#xff09;函数内部具体实现 四&#xff0c;游戏运行实操 前言 C语言实现三子棋…...

【算法提高:动态规划】1.2 最长上升子序列模型(TODO:最长公共上升子序列)

文章目录 题目列表1017. 怪盗基德的滑翔翼1014. 登山482. 合唱队形1012. 友好城市&#xff08;⭐排序后 最长上升子序列模型&#xff09;1016. 最大上升子序列和1010. 拦截导弹解法1——最长递减子序列 贪心解法2——最长递减子序列 最长递增子序列&#xff08;⭐贪心结论&am…...

会不会好奇ai绘画生成器?ai创作的灵感从何而来?

在这个宁静的公园里&#xff0c;阳光透过树叶的缝隙洒在的地面上&#xff0c;微风轻拂着艺术家的发丝&#xff0c;带来一丝清凉。坐在长椅上的他&#xff0c;手中紧握着一支触控画笔&#xff0c;目光凝视着眼前的美景。旁边一台智能绘画助手正在悄悄发光&#xff0c;它似乎能够…...

【Ajax】笔记-JQuery发送请求与通用方法

Get请求 语法格式&#xff1a; $.get(url, [data], [callback], [type]) url:请求的 URL 地址。data:请求携带的参数。callback:载入成功时回调函数。type:设置返回内容格式&#xff0c;xml, html, script, json, text, _default。 准备三个按钮分别测试Get 、Post、通用型方…...

视频的音频提取怎么做?这样提取很简单

提取视频中的音频通常在需要从视频中独立使用音频或需要对音频进行编辑时使用。例如&#xff0c;当我们需要将音频上传到音乐流媒体平台或将其用于播客或其他音频项目时&#xff0c;就可能需要从视频中提取音频。问题是该怎么提取呢&#xff1f;教给大家几种简单的提取方法&…...

几百本常用计算机开发语言电子书链接

GitHub - XiangLinPro/IT_book: 本项目收藏这些年来看过或者听过的一些不错的常用的上千本书籍&#xff0c;没准你想找的书就在这里呢&#xff0c;包含了互联网行业大多数书籍和面试经验题目等等。有人工智能系列&#xff08;常用深度学习框架TensorFlow、pytorch、keras。NLP、…...

Docker Compose 解析:定义和管理多容器应用,从多角度探索其优势和应用场景

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…...

Linux系列---【CentOS 7通过MSTSC连接远程桌面】

安装对应的yum源 yum list lightdm xorgxrdp xrdp 可以看到这些软件都在epel中&#xff0c;如果没有的话&#xff0c;请先安装对应的yum源。命令如下&#xff1a; yum install -y epel-release 确认yum源没有问题之后&#xff0c;我们就可以进行安装了。 安装lightdm xorgxrdp…...

width: calc(~“100% - 267px“);动态css 调样式

.result-filtering {color: #8b8b8b;display: flex;// width: 82.6%;width: calc(~"100% - 267px");}...

Windows Server 2012 搭建网关服务器并端口转发

需求 使用 Windows server 作为Hyper-V 虚拟出许多虚拟机&#xff0c;基本上都分配了内网地址&#xff0c;现在需要这些虚拟机访问外网&#xff0c;或者外网直接访问这些虚拟机&#xff0c;必须配置一个网关服务器。我决定直接使用 Windows 的远程访问中的 NAT 服务来完成。 …...

基于linux下的高并发服务器开发(第三章)- 3.10 死锁

deadlock.c #include <stdio.h> #include <pthread.h> #include <unistd.h>// 全局变量&#xff0c;所有的线程都共享这一份资源。 int tickets 1000;// 创建一个互斥量 pthread_mutex_t mutex;void * sellticket(void * arg) {// 卖票while(1) {// 加锁pt…...

09.计算机网络——套接字编程

文章目录 网络字节序socket编程socket 常见APIsockaddr结构 UDP编程创建socket绑定socketsendto发送数据recvform接收数据关闭socket TCP编程创建socket绑定socketlisten监听套接字accept服务端接收连接套接字connect客户端连接套接字send发送数据recv接收数据关闭socket 工具n…...

Data Structure, Algorithm,and Applications in C++

在学习这本书进阶内容之前&#xff0c;我们可以跟着它的第一章部分再巩固和复习。本书由Sartaj Sahni撰写&#xff0c;由王立柱和刘志红翻译。全书通俗易懂&#xff0c;内容丰富&#xff0c;是巩固C内容的不二选择。希望本文对各位有所帮助。 目录 1.函数与参数 1.1.传值参数…...

Apipost使用教程

Apipost是一款集API调试、生成文档、Mock、测试于一体的协同工具。单个工具可以同时满足接口测试、生成/分享文档、Mock、流程测试等功能&#xff0c;还有超实用的多人多角色间实时协作的功能。将前端、后端、测试三种角色串联起来&#xff0c;从而实现工作流程无缝衔接、提高研…...

如何使用Python进行服务器管理和自动化操作?

使用Python进行服务器管理和自动化操作可以极大地简化和提高日常管理任务的效率。下面是一些常见的方法和工具&#xff1a; SSH库&#xff1a;使用Python的paramiko库可以通过SSH协议连接到服务器&#xff0c;执行命令、上传文件和下载文件等操作。 例如&#xff0c;使用para…...

Kafka-partition和消费者的关系

Kafka-partition 目录概述需求&#xff1a; 设计思路实现思路分析1.Kafka-partition2.消费者数量小于分区数量3. 拓展实现 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a…...

使用克拉默法则进行三点定圆(二维)

目录 1.二维圆2.python代码3.计算结果 本文由CSDN点云侠原创&#xff0c;爬虫网站请自重。 1.二维圆 已知不共线的三个点&#xff0c;设其坐标为 ( x 1 , y 1 ) (x_1,y_1) (x1​,y1​)、 ( x 2 , y 2 ) (x_2,y_2) (x2​,y2​)、 ( x 3 , y 3 ) (x_3,y_3) (x3​,y3​)&#xf…...

【Java】Java多线程编程基础

文章目录 1. 进程与线程1.1 进程与线程的基本认识1.1.1 进程&#xff08;Process&#xff09;1.1.2 线程&#xff08;Thread&#xff09; 1.2 为什么会有线程1.2.1 以看视频为例 2. 多线程实现2.1 Thread类实现多线程2.2 Runnable接口实现多线程2.3 Callable接口实现多线程2.3 …...

FFmpeg-4.2.4的去logo源码分析

1.源码 libavfilter/vf_delogo.c 2.源码分析 /** 去logo算法, 函数的参数解释如下: w: 输入图像的宽度 h: 输入图像的高度 logo_x: 标志区域左上角的x坐标 logo_y: 标志区域左上角的y坐标 logo_w: 标志的宽度 logo_h: 标志的高度 band: 处理区域周围的带宽大小 show: 是否在…...

深度学习(一)

目录 一、特征工程的作用 二、深度学习的应用 三、得分函数 四、损失函数 五、前向传播 六、反向传播 一、特征工程的作用 数据特征决定了模型的上限预处理和特征提取是最核心的算法与参数选择决定了如何逼近这个上限 二、深度学习的应用 无人驾驶人脸识别分辨率重构 深…...

Materials Studio8.0在CentOS7.9环境下的安装与配置指南

1. 环境准备与系统检查 在CentOS 7.9上安装Materials Studio 8.0之前&#xff0c;我们需要确保系统环境满足最低要求。我遇到过不少因为环境配置不当导致的安装失败案例&#xff0c;这里分享几个关键检查点&#xff1a; 首先检查主机名是否包含特殊字符。Materials Studio对主机…...

自媒体人的秘密武器:OpenClaw+nanobot自动生成视频字幕文件

自媒体人的秘密武器&#xff1a;OpenClawnanobot自动生成视频字幕文件 1. 为什么我们需要自动化字幕生成 作为一个长期在视频创作领域摸索的自媒体人&#xff0c;我深知字幕制作这个环节有多折磨人。曾经为了给一段10分钟的视频添加字幕&#xff0c;我需要反复暂停播放、手动…...

新手入门实战:从零复现简易情绪记录站,掌握Web开发基础

最近在自学前端开发&#xff0c;想找个简单又有趣的练手项目。发现情绪记录网站是个不错的切入点&#xff0c;既能练习基础技能&#xff0c;又能做出实用功能。今天就用InsCode(快马)平台复现了一个简易版&#xff0c;分享下实现过程和心得。 项目构思 这个"私密树洞"…...

AIGC时代,程序员会被取代吗?我的看法与行动建议

AIGC时代&#xff0c;程序员会被取代吗&#xff1f;我的看法与行动建议 随着AI生成内容&#xff08;AIGC&#xff09;技术的迅猛发展&#xff0c;许多人开始担忧&#xff1a;程序员这一职业是否会被AI取代&#xff1f;从代码生成工具GitHub Copilot到对话式编程助手ChatGPT&am…...

企业Exchange邮箱配置失败?可能是Autodiscover服务出了问题,教你用微软官方工具排查

企业Exchange邮箱自动配置故障深度排查指南 引言 当企业用户或IT管理员遇到Outlook无法自动配置Exchange邮箱的问题时&#xff0c;往往意味着Autodiscover服务出现了异常。作为Exchange生态系统的核心组件&#xff0c;Autodiscover服务负责在客户端与服务器之间建立初始连接通…...

时间切片:24小时

基于双层优化的电动汽车优化调度研究 代码主要做的是一个双层的电动汽车充放电行为优化问题&#xff0c;具体来讲&#xff0c;输电网上层优化将电动汽车与发电机、基本负荷协调&#xff0c;同时考虑风力发电&#xff0c;从而在时域内优化电动汽车的负荷周期。 然后&#xff0c;…...

QuickRecorder高效解决方案:从基础到进阶的macOS录屏全指南

QuickRecorder高效解决方案&#xff1a;从基础到进阶的macOS录屏全指南 【免费下载链接】QuickRecorder A lightweight screen recorder based on ScreenCapture Kit for macOS / 基于 ScreenCapture Kit 的轻量化多功能 macOS 录屏工具 项目地址: https://gitcode.com/GitHu…...

小红书数据采集自动化工具实战:突破反爬限制的零基础搭建指南

小红书数据采集自动化工具实战&#xff1a;突破反爬限制的零基础搭建指南 【免费下载链接】XiaohongshuSpider 小红书爬取 项目地址: https://gitcode.com/gh_mirrors/xia/XiaohongshuSpider 高效数据采集是内容分析与市场研究的基础&#xff0c;但面对小红书等平台的反…...

HarmonyOS 5 + UniApp 真机调试保姆级教程:从HBuilderX配置到ArkUI Inspector查错

HarmonyOS 5 UniApp 真机调试全流程实战指南 第一次在HarmonyOS设备上调试UniApp应用时&#xff0c;我盯着HBuilderX里那个灰色的"运行到鸿蒙设备"按钮整整半小时。设备明明连着USB线&#xff0c;开发者模式也开了&#xff0c;但工具就是识别不到我的MatePad Pro。…...

ES启动失败:深入解析No buffer space available错误及连接数优化策略

1. 当ES启动失败时发生了什么 第一次看到"No buffer space available"这个报错时&#xff0c;我也是一头雾水。那天凌晨三点&#xff0c;线上监控突然报警&#xff0c;ES集群集体罢工&#xff0c;整个搜索服务直接瘫痪。查看日志发现满屏都是"java.net.SocketE…...