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

三子棋

    • 前言
    • 一,游戏规则
    • 二,所需文件
    • 三,创建菜单
    • 四,游戏核心内容实现
      • 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;
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12133.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8.10 PowerBI系列之DAX函数专题-TopN中实现动态指标

需求 实现 建立一个辅助表供切片器选择 2 建立条件判断度量值top_measure swich(true(),selectedvalue(table[tope_type])"按数量top",sum(order_2[产品数量]),selectedvalue(table[tope_type])"按金额top",sum(order_2[订单金额]),selectedvalue(table…

本地部署中文LLaMA模型实战教程,民间羊驼模型

羊驼实战系列索引 博文1:本地部署中文LLaMA模型实战教程,民间羊驼模型(本博客) 博文2:本地训练中文LLaMA模型实战教程,民间羊驼模型 博文3:精调训练中文LLaMA模型实战教程,民间羊驼模型 简介 LLaMA大部分是英文语料训练的,讲中文能力很弱。如果我们想微调训练自己的…

aop实现方式及基本使用

aop实现方式 aspectj 编译器增强&#xff0c;直接修改源码可以不借助Spring实现 也没有用代理对象 &#xff08;ajc编译器&#xff09; aop 的原理并非代理一种, 编译器也能玩出花样&#xff08;直接修改源码&#xff09; 运行时需要在 VM options 里加入 -javaagent:D:/envir…

贪心算法总结及其leetcode题目N道

1 我为什么要写这个总结 1.1 字节笔试题 小明在玩一场通关游戏&#xff0c;初始血量为1&#xff0c;关卡有怪兽或者有血包&#xff08;正数就是血包可回血数&#xff0c;负数说明是怪兽的伤害值&#xff09;&#xff0c;当捡到血包时会加血量&#xff0c;碰到怪兽时会掉血&am…

4种方法实现输入框按回车自动刷新页面

系列文章目录 文章目录 系列文章目录前言一、使用原生 JavaScript二、使用 Vue.js三、使用 jQuery四、 使用 React五、 注意事项总结前言 在 Web 开发中,有时我们希望用户在输入框中按下回车键时能够自动刷新页面,以便触发某些操作或更新数据。本文将介绍4种方法来实现这一功…

Matlab的SimuLink对FS32K144编程--内部数据存储Flash

​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ 前言 Flah擦写是由寿命的&#xff0c;应当减免无效的擦写&#xff0c;如数据值不变不进行擦写 1、新建工程完成后&#xff0c;拖出Flash的存储控制初始化…

ROS 2 — 托管(生命周期)节点简介

一、说明 这篇文章是关于理解ROS 2中托管&#xff08;生命周期&#xff09;节点的概念。我们描述了概念性的想法以及我们为什么需要它。所以让我们开始吧&#xff01; 二、托管式节点 — 什么和为什么&#xff1f; 为了理解托管式节点&#xff0c;让我们从一个简单的问题陈述开…

Python并发程序

大贤者福尔的在计算机方面的研究也取得了极大的成绩,他的研究主要集中在并行计算方面,通过锁机制保障程序的并行执行。为此,他设计了一个非常简单的原型系统,系统中程序最多不超过100条语句,分为以下几种类型: var = another_var or constant(变量赋值) var += another_…

串口通讯接口类型:TTL、RS232和RS485(电平标准)

串口通讯接口类型&#xff1a;TTL、RS232和RS485 在串口通信中&#xff0c;常用的接口类型包括TTL、RS-232和RS-485&#xff0c;TTL、RS-232、RS422、RS-485是指的电平标准(电信号)。 通信协议规定了数据传输的规则和格式&#xff0c;包括数据的起始位、停止位、数据位数、校…

内网穿透远程查看内网监控摄像头

内网穿透远程查看内网监控摄像头 在现代社会中&#xff0c;大家总是奔波于家和公司之间。大部分时间用于工作中&#xff0c;也就很难及时知晓家中的动态情况&#xff0c;对于家中有老人、小孩或宠物的&#xff08;甚至对居住环境安全不放心的&#xff09;&#xff0c;这已然是…

Retrospectives on the Embodied AI Workshop(嵌入式人工智能研讨会回顾) 论文阅读

论文信息 题目&#xff1a;Retrospectives on the Embodied AI Workshop 作者&#xff1a;Matt Deitke, Dhruv Batra, Yonatan Bisk 来源&#xff1a;arXiv 论文地址&#xff1a;https://arxiv.org/pdf/2210.06849 Abstract 我们的分析重点关注 CVPR Embodied AI Workshop 上…

JiaYu说:如何做好IT类的技术面试?

IT类的技术面试 面试IT公司的小技巧IT技术面试常见的问题嵌入式技术面试嵌入式技术面试常见的问题嵌入式软件/硬件面试题 JiaYu归属嵌入式行业&#xff0c;所以这里只是以普通程序员的角度去分析技术面试的技巧 当然&#xff0c;也对嵌入式技术面试做了小总结&#xff0c;友友们…

vite / nuxt3 项目使用define配置/自定义,可以使用process.env.xxx获取的环境变量

每日鸡汤&#xff1a;每个你想要学习的瞬间&#xff0c;都是未来的你向自己求救 首先可以看一下我的这篇文章了解一下关于 process.env 的环境变量。 对于vite项目&#xff0c;在我们初始化项目之后&#xff0c;在浏览器中打印 process.env&#xff0c;只有 NODE_ENV这个变量&…

【组内工作】木马回联

文章目录 C2服务器安装和运行方法CrossC2运行方法sliver运行方法empire安装方法DeimosC2安装教程TrevorC2安装教程&#xff1a; C2服务器的流量特征CrossC21. 心跳包2. 命令3. ja3/ja3s Sliver1. http2. https empirehttphttps DeimosC2https TrevorC2 C2服务器安装和运行方法 …

Python - 嵌入式数据库Sqlite3的基本使用

SQLite是一种轻量级的嵌入式关系型数据库管理系统&#xff0c;而Python标准库中提供了与SQLite交互的模块&#xff0c;sqlite3。下面是一个Python 3中使用sqlite3模块的详细示例与解析。 import sqlite3 # 创建或连接数据库 conn sqlite3.connect(example.db) # 创建一个…

iperf3 编译安装及网讯WX1860千兆网口测试

iperf3 编译安装及网讯1860千兆网口测试 编译安装 安装包下载地址:https://github.com/esnet/iperf/archive/refs/tags/3.8.tar.gz 将安装包iperf-3.8.tar.gz拷贝测试系统盘桌面,使用如下命令进行编译安装: tar zxvf iperf-3.8.tar.gz cd iperf-3.8 ./configure make s…

48,排序算法merge

功能描述&#xff1a; 两个容器元素合并&#xff0c;并储存到另一容器中 函数原型&#xff1a; merge(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest); //容器元素合并&#xff0c;并存储到另一个容器中 //注意&#xff1a;两个容器必须是有序的…

vue : 无法加载文件 C:\Users\jianfei\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。...

背景 在新电脑上配置vue环境 PS E:\CODE_PROJ\myvue\vue23\P61_使用脚手架\vue_test> npm install -g vue/cli npm WARN deprecated source-map-url0.4.1: See https://github.com/lydell/source-map-url#deprecated npm WARN deprecated urix0.1.0: Please see https://git…

Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用

Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用 1. 什么是PhysicsRaycaster组件&#xff1f; PhysicsRaycaster是Unity UGUI中的一个组件&#xff0c;用于在UI元素上进行物理射线检测。它可以检测鼠标或触摸事件是否发生在UI元素上&#xff0c;并将事件传递给…

【btoa()方法在linux系统中,出现报错】

问题1&#xff1a;为什么在linux系统中&#xff0c;var sendEncoded btoa(deviceData);这里会出现下面的报错&#xff1f; UnhandledPromiseRejectionWarning: ReferenceError: btoa is not defined 分析如下&#xff1a;在Linux系统中&#xff0c;Node.js默认情况下不支持b…