c语言——三子棋

基本框架

三个文件:

其中.cpp文件用于游戏具体函数设计,.h文件为游戏的函数声明,test.cpp文件用于测试游戏运行。

 需要用到的头文件:

#include <stdio.h>
#include <stdlib.h>//rand&srand
#include <time.h>//时间相关

框架运行

#include"game.h"
void menu()
{printf("*********************************\n");printf("********      1. play    ********\n");printf("********      0. exit    ********\n");printf("*********************************\n");
}
void game()
{}
int main()
{int input;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;
}

运行结果:

棋盘

棋盘是一个3*3的平面,可以用二维数组接收,编译器不支持变长数组,我们可以用define定义数组的下标(行和列),之后有大用。

#define COL 3
#define ROW 3

打印:

 为什么没有对齐呢?这是因为字符数组初始化为0等价于\0,而\0是不会显示出来的,所以,我们再添加一个初始化函数。

 初始化函数

因为游戏可以反复游玩,我们不妨设置一个初始化函数,将棋子置于初始状态('  '字符)。

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

可以发现这次棋盘很标准了,但有点刻意的风味,如果想要一个10*10的棋盘,又要重新设计吗?应对此种情况,我们试着改进棋盘。

棋盘改进

void display_board(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){//printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);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开始而不是从0开始是因为让玩家觉得合理。

void player_move(char board[ROW][COL], int row, int col)
{int x;int y;while (1){printf("请输入要下棋的坐标:>");scanf("%d %d", &x, &y);if (y <= col && x <= row){if (board[x-1][y-1] == ' '){board[x-1][y-1] = '*';break;}else{printf("该坐标被占用,请重新输入\n");}}else{printf("坐标非法,重新输入\n");}}
}

测试: 

 电脑下棋

需要用随机函数rand生成随机数和srand设置初始点使之电脑能随机在棋盘上下棋。

srand放在主函数里,循环体前,只需执行一次。 

void computer_move(char board[ROW][COL], int row, int col)
{while (1){int x = rand() % 3;//0~2int y = rand() % 3;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}

胜负评判

接着需要我们评判双方获胜条件,即三子连成一条线的情况。

这里我们直接无脑评判就行,如果三处相同且不为空格则说明一方胜利

char is_win(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] != ' '){return board[i][1];}}//列for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' '){return board[0][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];}//判断平局if (is_full(board, row, col) == 1){return 'Q';}//继续return 'C';
}

这里有个取巧的方法,可以直接用我们棋子所代表的字符作为返回值进行判断。

是否平局

平局需要单独判断,我们可以封装一个函数,遍历看棋盘是否已满就行了。

static 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;
}

这里的static是只对本文件可见,因为它只用于我们的胜负评判。

接下来我们对主函数的game函数再增添胜负评判,每次落子之后进行评判,根据对应的返回值输出相应的结果。

运行结果:

完整代码

//game.c
#include "game.h"
void display_board(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){//printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);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");}}printf("\n");
}
void init_board(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 player_move(char board[ROW][COL], int row, int col)
{int x;int y;while (1){printf("请输入要下棋的坐标:>");scanf("%d %d", &x, &y);if (y <= col && x <= row){if (board[x-1][y-1] == ' '){board[x-1][y-1] = '*';break;}else{printf("该坐标被占用,请重新输入\n");}}else{printf("坐标非法,重新输入\n");}}
}
void computer_move(char board[ROW][COL], int row, int col)
{while (1){int x = rand() % 3;int y = rand() % 3;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}static 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 is_win(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] != ' '){return board[i][1];}}//列for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' '){return board[0][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];}//判断平局if (is_full(board, row, col) == 1){return 'Q';}//继续return 'C';
}
//.h
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3
#define COL 3//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);
//打印棋盘
void display_board(char board[ROW][COL], int row, int col);
//玩家下棋
void player_move(char board[ROW][COL], int row, int col);
//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);
//判断游戏状态
char is_win(char board[ROW][COL], int row, int col);
//test.c
#include"game.h"
void menu()
{printf("*********************************\n");printf("********      1. play    ********\n");printf("********      0. exit    ********\n");printf("*********************************\n");
}
void game()
{char board[ROW][COL] = { 0 };init_board(board, ROW, COL);display_board(board, ROW, COL);char ret;while (1){player_move(board, ROW, COL);display_board(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')break;computer_move(board, ROW, COL);display_board(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')break;}if (ret == 'Q'){printf("平局\n");}if (ret == '*'){printf("玩家胜\n");}if (ret == '#'){printf("电脑胜\n");}
}
int main()
{int input;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/30796.shtml

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

相关文章

[oeasy]python0083_[趣味拓展]字体样式_正常_加亮_变暗_控制序列

字体样式 回忆上次内容 上次了解了 一个新的转义模式 \033 逃逸控制字符 esc esc 让输出 退出 标准输出流进行 控制信息的设置 可以 清屏也可以 设置光标输出的位置 还能做什么呢&#xff1f; 可以 设置 字符的颜色吗&#xff1f;&#xff1f;&#xff1f;&#x1f914; 查…

利用Simulink Test进行模型单元测试 - 1

1.搭建用于测试的简单模型 随手搭建了一个demo模型MilTestModel&#xff0c;模型中不带参数 2.创建测试框架 1.模型空白处右击 测试框架 > 为‘MilTestModel’创建 菜单 2.在创建测试框架对话框中&#xff0c;点击OK&#xff0c;对应的测试框架MilTestMode_Harness1就自动…

C语言--联合体-共用体

有时候同一个内存空间存放类型不同&#xff0c;不同类型的变量共享一块空间 像结构体&#xff0c;但是有区别 1、 结构体元素有各自单独空间&#xff0c; 共用体元素共享空间&#xff0c;空间大小由最大类型确定 同一块空间&#xff0c;有时候存放char类型、有时候存放int型&am…

计算机体系中的不同的缓存存储层级说明

分级说明 L1缓存的标准延迟是4个周期。这意味着&#xff0c;当CPU请求数据时&#xff0c;L1缓存需要4个时钟周期来将数据传输给CPU。 L2缓存的标准延迟是12个周期。相对于L1缓存&#xff0c;L2缓存的容量更大&#xff0c;但其读取速度更慢&#xff0c;需要更多的时钟周期来传输…

第五次作业 运维高级 构建 LVS-DR 集群和配置nginx负载均衡

1、基于 CentOS 7 构建 LVS-DR 群集。 LVS-DR模式工作原理 首先&#xff0c;来自客户端计算机CIP的请求被发送到Director的VIP。然后Director使用相同的VIP目的IP地址将请求发送到集群节点或真实服务器。然后&#xff0c;集群某个节点将回复该数据包&#xff0c;并将该数据包…

leetcode357- 2812. 找出最安全路径

这个题比较经典&#xff0c;可以用多个算法来求解&#xff0c;分别给出各个算法的求解方法&#xff0c;主要是分为第一部分的多源BFS求每个位置的距离和第二部分求(0,0)到(n-1,n-1)的最短路径&#xff08;可以用多种方法求&#xff09; 目录 多源BFS求最短路径枚举安全系数判断…

Android Jetpack

Jetpack 是一个由多个库组成的套件&#xff0c;可帮助开发者遵循最佳实践、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码&#xff0c;让开发者可将精力集中于真正重要的编码工作。 1.基础组件 &#xff08;1&#xff09;AppCompat&#xff1a;使得支持较低…

sklearn垃圾邮件分类

在Python中&#xff0c;可以使用机器学习算法来进行垃圾邮件分类。下面是一个简单的示例&#xff0c;使用朴素贝叶斯算法进行垃圾邮件分类&#xff1a; import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.model_selection impor…

Qt画波浪球(小费力)

画流动波浪 #ifndef WIDGET3_H #define WIDGET3_H#include <QWidget> #include <QtMath> class widget3 : public QWidget {Q_OBJECT public:explicit widget3(QWidget *parent nullptr);void set_value(int v){valuev;}int get_value(){return value;} protecte…

C++特有__attribute__的so动态库

这是一段 C 代码&#xff0c;其中使用了 GCC 编译器的一些特殊语法。 extern "C"&#xff1a;这是 C 中的语法&#xff0c;用于指定一个函数或变量应该按照 C 语言的约定进行编译和链接。在 C 中&#xff0c;函数和变量的名称会根据其作用域和命名空间进行修饰&…

el-date-picker设置默认当前日期

HTMl部分&#xff1a; <el-form-item label"拍摄时间&#xff1a;"><el-date-pickerv-model"searchData.filmingTimeRange"type"daterange"align"right"unlink-panelsrange-separator"至"start-placeholder"…

vue中vuex的五个属性和基本用法,另加js-cookie的使用

VueX 是一个专门为 Vue.js 应用设计的状态管理构架&#xff0c;统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。 Vuex有五个核心概念&#xff1a; state, getters, mutations, actions, modules。 1. state&#xff1a; vuex的基本数据&…

【Linux】-- 进程间通信

目录 一、进程间通信介绍 二、管道 1.什么是管道&#xff08;pipe&#xff09; 2.重定向和管道 &#xff08;1&#xff09;为什么要有管道的存在 &#xff08;2&#xff09;重定向和管道的区别 3.匿名管道 &#xff08;1&#xff09;匿名管道原理 &#xff08;2&…

SpringCloud实用篇5——elasticsearch基础

目录 1.初识elasticsearch1.1 了解ES1.1.1 elasticsearch的作用1.1.2 ELK技术栈1.1.3 elasticsearch和lucene1.1.4 总结 1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排 1.3 es的一些概念1.3.1 文档和字段1.3.2 索引和映射1.3.3 mysql与elasticsearch 1.4 部署单点…

C# ListBox自动滚动方法

1、方法1&#xff1a;添加记录后&#xff0c;选择最后一条记录&#xff0c;让滚动条滚动到底部&#xff0c;再自动取消 listBox1.Items.Add(t ":a good day"); listBox1.SelectedIndex listBox1.Items.Count - 1; listBox1.SelectedIndex -1; //是否取消选中行…

直播招聘小程序解决方案

项目开发愿景 介绍工作拿佣金&#xff0c;Boss直播现真身。做为直播招聘的新平台&#xff0c;让求职和招聘变得更简单&#xff01;企业发布招聘视频&#xff0c;展现公司环境与实力&#xff0c;开通会员可以直播招聘、在线面试功能&#xff1b;求职者刷视频可以刷到工作…

信息安全:访问控制技术原理与应用.

信息安全&#xff1a;访问控制技术原理与应用. 访问控制是网络信息系统的基本安全机制。访问控制是指对资源对象的访问者授权、控制的方法及运行机制。访问者又称为主体&#xff0c;可以是用户、进程、应用程序等&#xff1b;而资源对象又称为客体&#xff0c;即被访问的对象&…

react中hooks分享

一. HOOKS是什么 在计算机程序设计中&#xff0c;钩子一词涵盖了一系列技术&#xff0c;这些技术用来通过拦截函数调用、消息或在软件组件之间传递的事件来改变或增加操作系统、应用程序或其他软件组件的行为。处理这些被截获的函数调用、事件或消息的代码称为“hook”。 在r…

C++核心编程:C++中的引用

C中的引用 引用的基本语法 作用&#xff1a;给变量起别名 语法&#xff1a;数据类型 & 别名 原名 //比如给一个int变量a命名一个别名 b int &b a;b 20; cout<< a << endl;//a 20引用的注意事项 引用必须初始化 int &b;//错误的引用在初始化后&…

Wav2Lip实践

1. 安装 1.1 安装 conda以指定python版本运行环境 下载&#xff1a;Index of /https://repo.anaconda.com/archive/index.html 1.2 如按旧项目基于python3.6版本对话&#xff0c;会有很多包找不到的情况&#xff0c;经摸索后以python3.9构建成功&#xff0c; conda instal…