三子棋(C 语言)
目录
- 一、游戏设计的整体思路
- 二、各个步骤的代码实现
- 1. 菜单及循环选择的实现
- 2. 棋盘的初始化和显示
- 3. 轮流下棋及结果判断实现
- 4. 结果判断实现
- 三、所有代码
- 四、总结
一、游戏设计的整体思路
(1)提供一个菜单让玩家选择人机对战、玩家对战或者退出游戏,且一局结束以后还可以继续选择直到退出。
(2)使用一个 3*3 二维数组来表示一个棋盘,存放双方的落子情况并进行显示。且显示时使用一些符号进行分隔让棋盘更加合理。
(3)初始棋盘应为空,然后提示先手方下棋,要对先手方落子位置进行判断(是否合法,是否该位置已经落子),最后先手方下棋完毕后应检查棋局状态(获胜、平局或继续);同理后手方下棋。
(4)若平局或者任意一方获胜则结束对局,显示结果。
本次代码使用多文件形式,一共有三个文件,一个头文件包含各种声明,一个 .c 文件进行测试,一个 .c 文件实现函数功能。

二、各个步骤的代码实现
1. 菜单及循环选择的实现
(1)主函数代码的实现
// 头文件
#include <stdio.h>
#include "Tic_tac_toe.h"int main()
{// 所需变量int select = 0;// 选择do{// 菜单menu();// 选择scanf("%d", &select);// 判断switch (select){case 1 : // 人机对战PVE();break;case 2 :PVP(); // 玩家对战break;case 0 :printf("游戏结束!\n");break;}} while (select);return 0;
}
(2)头文件中的声明
// 菜单
void menu();
(3)函数实现
// 菜单
void menu()
{printf("**************************************\n");printf("********** 1. PVE **********\n");printf("********** 2. PVP **********\n");printf("********** 0. exit **********\n");printf("**************************************\n");
}
(4)运行效果如下

2. 棋盘的初始化和显示
棋盘的初始化和显示分别设计为两个函数 —— InitBoard()、PrintBoard()。首先,需要在主函数创建棋盘,且大小使用符号常量,方便替换。然后把棋盘的信息传入人机对战和玩家对战函数中,并在头文件和实现文件中进行相应的声明和定义。
(1)主函数创建棋盘
int main()
{// 所需变量int select = 0;char board[ROW][COL] = { 0 }; // 创建棋盘//...
}
(2)头文件进行相应声明
// 初始化棋盘
void InitBoard(char board[][COL], int row, int col);// 打印棋盘
void PrintBoard(char board[][COL], int row, int col);// 人机对战模式
void PVE(char board[][COL], int row, int col);// 玩家对战模式
void PVP(char board[][COL], int row, int col);
(3)实现文件进行定义
// 初始化棋盘
void InitBoard(char board[][COL], int row, int col)
{int i;for (i = 0; i < row; ++i){int j;for (j = 0; j < col; ++j)board[i][j] = ' ';}
}// 打印棋盘
void PrintBoard(char board[][COL], int row, int col)
{// 打印棋盘时,需要适当添加符号分隔int i;for (i = 0; i < row; ++i){int j;for (j = 0; j < col; ++j)printf(" ---");// 下一行printf("\n");for (j = 0; j < col; ++j)printf("| %c ", board[i][j]);// 补齐改行分隔printf("|");// 下一行printf("\n");}// 补齐最后一行分隔for (i = 0; i < col; ++i)printf(" ---");printf("\n");
}// 人机对战模式
void PVE(char board[][COL], int row, int col)
{printf("\n人机对战:\n");// 初始化棋盘InitBoard(board, row, col);// 显示棋盘PrintBoard(board, row, col);
}// 玩家对战模式
void PVP(char board[][COL], int row, int col)
{printf("\n玩家对战:\n");// 初始化棋盘InitBoard(board, row, col);// 显示棋盘PrintBoard(board, row, col);
}
运行效果如下:

3. 轮流下棋及结果判断实现
这里假设人机对战时,玩家使用符号 ‘#’,机器人使用符号 ‘*’;玩家对战时,一号玩家使用符号 ‘#’,二号玩家使用符号 ‘*’。玩家下棋和机器人下棋分别使用两个函数 —— PMove() 和 EMove()。PMove() 函数需要使用一个额外的变量判断是 1 号玩家下棋,还是 2 号玩家下棋。
判断结果函数 is_win() 需要判断每行是否相同、每列是否相同,倘若其中有一个实现,则有一方获胜,倘若没有则需要使用函数 is_full() 判断棋盘是否已满,若满则平局,否则继续。is_full() 函数也可以直接实现在 is_win() 函数内部。
(1)头文件函数声明
// 玩家下棋
void PMove(char board[][COL], int row, int col, int who);// 机器人下棋
void EMove(char board[][COL], int row, int col);// 判断是否获胜
void is_win(char board[][COL], int row, int col);
(2)实现文件函数定义
// 玩家下棋
void PMove(char board[][COL], int row, int col, char who)
{// 所需变量int x, y;do{// 输入坐标printf("玩家下棋(输入坐标中间用空格隔开):\n");scanf("%d %d", &x, &y);// 判断合法性if ((x < 0 || x > row || y < 0 || y > col) || board[x - 1][y - 1] != ' '){printf("坐标非法,请重新输入!\n");}else{board[x - 1][y - 1] = who;break;}} while (1);
}// 机器人下棋
void EMove(char board[][COL], int row, int col)
{// 机器人是随机下棋的,这里就要获取随机数了// 需要包含头文件 stdlib.h 和 time.h // 设置随机数种子srand((unsigned)time(0));printf("电脑下棋:\n");while (1){int x = rand() % row; // 0 - row - 1int y = rand() % col; // 0 - col - 1if (board[x][y] == ' '){board[x][y] = '*';break;}}
}// 判断是否获胜
char is_win(char board[][COL], int row, int col)
{// 判断每行int r = 1;int i;for (i = 0; i < row; ++i){// 重置判断符号r = 1;// 若首字符为空则下一行if (board[i][0] == ' ')continue;// 判断改行int j;for (j = 1; j < col; ++j){r *= (board[i][j - 1] == board[i][j]);// 判断if (!r)break;}if (r)return board[i][0];}// 判断每列int c = 1;int j;for (j = 0; j < col; ++j){// 重置判断符号c = 1;// 首字符为空则下一列if (board[0][j] == ' ')continue;// 判断该列int i;for (i = 1; i < row; ++i){c *= (board[i - 1][j] == board[i][j]);// 判断if (!c)break;}if (c)return board[0][j];}// 判断对角线int d = 1;if (board[0][0] != ' '){for (i = 1; i < row; ++i){d *= (board[i - 1][i - 1] == board[i][i]);// 判断if (!d)break;}if (d)return board[0][0];}if (board[0][col] != ' '){d = 1;for (i = 1; i < row; ++i){d *= (board[i - 1][col - i + 1] == board[i][col - i]);// 判断if (!d)break;}if (d)return board[0][col];}// 判断棋盘是否已满int full = 1;for (i = 0; i < row; ++i){for (j = 0; j < col; ++j){if (board[i][j] == ' '){// 未满return 'C';}}}// 已满return 'D';}
上述代码中 is_win() 函数中所使用的是通用判断方法,即使改变了符号常量 ROW 和 COL 的值也可以是判断。(如果实在理解不了,可以只当 3*3 的特殊情况来实现判断,当然,也可能是我的代码写的不好)。
(3)程序运行结果:
这里值展示人机对战的三种结果:
玩家获胜:

电脑获胜:

平均:

4. 结果判断实现
该代码直接放在了函数 PMove() 和函数 EMove() 中,也可以单独写一个函数。
(1)实现文件函数定义
// 人机对战模式
void PVE(char board[][COL], int row, int col)
{printf("\n人机对战:\n");// 初始化棋盘InitBoard(board, row, col);// 显示棋盘PrintBoard(board, row, col);// 开始下棋int ret = 0;do{// 玩家下棋PMove(board, row, col, '#');// 显示棋盘PrintBoard(board, row, col);// 判断ret = is_win(board, row, col);if (ret != 'C')break;// 机器人下棋EMove(board, row, col);// 显示棋盘PrintBoard(board, row, col);// 判断ret = is_win(board, row, col);if (ret != 'C')break;} while (1);// 判断最终结果if (ret == '#')printf("玩家获胜!\n");else if (ret == '*')printf("电脑获胜!\n");elseprintf("平局!\n");
}// 玩家对战模式
void PVP(char board[][COL], int row, int col)
{printf("\n玩家对战:\n");// 初始化棋盘InitBoard(board, row, col);// 显示棋盘PrintBoard(board, row, col);// 开始下棋int ret = 0;do{// 玩家 1 号下棋PMove(board, row, col, '#');// 显示棋盘PrintBoard(board, col, row);// 判断ret = is_win(board, row, col);if (ret != 'C')break;// 玩家 2 号下棋PMove(board, row, col, '*');// 显示棋盘PrintBoard(board, col, row);// 判断ret = is_win(board, row, col);if (ret != 'C')break;} while (1);// 判断最终结果if (ret == '#')printf("玩家 1 号获胜!\n");else if (ret == '*')printf("玩家 2 号获胜!\n");elseprintf("平局!\n");
}
(2)演示结果
在上一次演示结果中已经体现。
三、所有代码
分三个文件,分别是头文件 Tic_tac_toe.h,测试文件 test.c,和函数实现文件 Tic_tac_toe.c。
(1)Tic_tac_toe.h
// 常量声明
#define ROW 3
#define COL 3// 函数声明// 菜单
void menu();// 初始化棋盘
void InitBoard(char board[][COL], int row, int col);// 打印棋盘
void PrintBoard(char board[][COL], int row, int col);// 玩家下棋
void PMove(char board[][COL], int row, int col, char who);// 机器人下棋
void EMove(char board[][COL], int row, int col);// 判断是否获胜
char is_win(char board[][COL], int row, int col);// 人机对战模式
void PVE(char board[][COL], int row, int col);// 玩家对战模式
void PVP(char board[][COL], int row, int col);
(2)test.c
// 头文件
#include <stdio.h>
#include "Tic_tac_toe.h"int main()
{// 所需变量int select = 0;char board[ROW][COL] = { 0 };// 选择do{// 菜单menu();// 选择scanf("%d", &select);// 判断switch (select){case 1 : // 人机对战PVE(board, ROW, COL);break;case 2 :PVP(board, ROW, COL); // 玩家对战break;case 0 :printf("游戏结束!\n");break;default :printf("选择错误请重新选择!\n");break;}} while (select);return 0;
}
(3)Tic_tac_toe.c
// 头文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "Tic_tac_toe.h"// 函数定义// 菜单
void menu()
{printf("**************************************\n");printf("********** 1. PVE **********\n");printf("********** 2. PVP **********\n");printf("********** 0. exit **********\n");printf("**************************************\n");
}// 初始化棋盘
void InitBoard(char board[][COL], int row, int col)
{int i;for (i = 0; i < row; ++i){int j;for (j = 0; j < col; ++j)board[i][j] = ' ';}
}// 打印棋盘
void PrintBoard(char board[][COL], int row, int col)
{// 打印棋盘时,需要适当添加符号分隔int i;for (i = 0; i < row; ++i){int j;for (j = 0; j < col; ++j)printf(" ---");// 下一行printf("\n");for (j = 0; j < col; ++j)printf("| %c ", board[i][j]);// 补齐改行分隔printf("|");// 下一行printf("\n");}// 补齐最后一行分隔for (i = 0; i < col; ++i)printf(" ---");printf("\n");
}// 玩家下棋
void PMove(char board[][COL], int row, int col, char who)
{// 所需变量int x, y;do{// 输入坐标printf("玩家下棋(输入坐标中间用空格隔开):\n");scanf("%d %d", &x, &y);// 判断合法性if ((x < 0 || x > row || y < 0 || y > col) || board[x - 1][y - 1] != ' '){printf("坐标非法,请重新输入!\n");}else{board[x - 1][y - 1] = who;break;}} while (1);
}// 机器人下棋
void EMove(char board[][COL], int row, int col)
{// 机器人是随机下棋的,这里就要获取随机数了// 需要包含头文件 stdlib.h 和 time.h // 设置随机数种子srand((unsigned)time(0));printf("电脑下棋:\n");while (1){int x = rand() % row; // 0 - row - 1int y = rand() % col; // 0 - col - 1if (board[x][y] == ' '){board[x][y] = '*';break;}}
}// 判断是否获胜
char is_win(char board[][COL], int row, int col)
{// 判断每行int r = 1;int i;for (i = 0; i < row; ++i){// 重置判断符号r = 1;// 若首字符为空则下一行if (board[i][0] == ' ')continue;// 判断改行int j;for (j = 1; j < col; ++j){r *= (board[i][j - 1] == board[i][j]);// 判断if (!r)break;}if (r)return board[i][0];}// 判断每列int c = 1;int j;for (j = 0; j < col; ++j){// 重置判断符号c = 1;// 首字符为空则下一列if (board[0][j] == ' ')continue;// 判断该列int i;for (i = 1; i < row; ++i){c *= (board[i - 1][j] == board[i][j]);// 判断if (!c)break;}if (c)return board[0][j];}// 判断对角线int d = 1;if (board[0][0] != ' '){for (i = 1; i < row; ++i){d *= (board[i - 1][i - 1] == board[i][i]);// 判断if (!d)break;}if (d)return board[0][0];}if (board[0][col] != ' '){d = 1;for (i = 1; i < row; ++i){d *= (board[i - 1][col - i + 1] == board[i][col - i]);// 判断if (!d)break;}if (d)return board[0][col];}// 判断棋盘是否已满int full = 1;for (i = 0; i < row; ++i){for (j = 0; j < col; ++j){if (board[i][j] == ' '){// 未满return 'C';}}}// 已满return 'D';}// 人机对战模式
void PVE(char board[][COL], int row, int col)
{printf("\n人机对战:\n");// 初始化棋盘InitBoard(board, row, col);// 显示棋盘PrintBoard(board, row, col);// 开始下棋int ret = 0;do{// 玩家下棋PMove(board, row, col, '#');// 显示棋盘PrintBoard(board, row, col);// 判断ret = is_win(board, row, col);if (ret != 'C')break;// 机器人下棋EMove(board, row, col);// 显示棋盘PrintBoard(board, row, col);// 判断ret = is_win(board, row, col);if (ret != 'C')break;} while (1);// 判断最终结果if (ret == '#')printf("玩家获胜!\n");else if (ret == '*')printf("电脑获胜!\n");elseprintf("平局!\n");
}// 玩家对战模式
void PVP(char board[][COL], int row, int col)
{printf("\n玩家对战:\n");// 初始化棋盘InitBoard(board, row, col);// 显示棋盘PrintBoard(board, row, col);// 开始下棋int ret = 0;do{// 玩家 1 号下棋PMove(board, row, col, '#');// 显示棋盘PrintBoard(board, col, row);// 判断ret = is_win(board, row, col);if (ret != 'C')break;// 玩家 2 号下棋PMove(board, row, col, '*');// 显示棋盘PrintBoard(board, col, row);// 判断ret = is_win(board, row, col);if (ret != 'C')break;} while (1);// 判断最终结果if (ret == '#')printf("玩家 1 号获胜!\n");else if (ret == '*')printf("玩家 2 号获胜!\n");elseprintf("平局!\n");
}
四、总结
本次三子棋的代码编写总体来说还可以,基本上都实现了上述功能,其中的某些代码本人均是根据符号常量来编写的,也就是即使符号常量改变,本代码依旧可以实现。当然,本人水平有限,有的地方看不懂可能是本人代码写的太烂,这里先道个歉。
当然代码还有很多可以提升的地方,比如优化棋盘,可以使用鼠标来下棋,提升电脑的水平等。
相关文章:
三子棋(C 语言)
目录 一、游戏设计的整体思路二、各个步骤的代码实现1. 菜单及循环选择的实现2. 棋盘的初始化和显示3. 轮流下棋及结果判断实现4. 结果判断实现 三、所有代码四、总结 一、游戏设计的整体思路 (1)提供一个菜单让玩家选择人机对战、玩家对战或者退出游戏…...
HWS赛题 入门 MIPS Pwn-Mplogin(MIPS_shellcode)
解题所涉知识点: 泄露或修改内存数据: 堆地址:栈地址:栈上数据的连带输出(Stack Leak) && Stack溢出覆盖内存libc地址:BSS段地址: 劫持程序执行流程:[[MIPS_ROP]] 获得shell或flag&am…...
纯血鸿蒙启动公测,爱加密鸿蒙加固平台发布,助力鸿蒙应用安全运营!
鸿蒙系统打破了移动操作系统两极格局,实现操作系统核心技术的自主可控、安全可靠,在神州大地上掀起一波科技革新的浪潮,HarmonyOS NEXT成为大型企业必须要布局的应用系统之一。 HarmonyOS NEXT于10月8日正式开启公测,距离面向全体…...
MySQL中 truncate、drop和delete的区别
MySQL中 truncate、drop和delete区别 truncate 执行速度快,删除所有数据,但是保留表结构不记录日志事务不安全,不能回滚可重置自增主键计数器 drop 执行速度较快,删除整张表数据和结构不记录日志事务不安全,不能回…...
什么开放式耳机值得买?开放式耳机推荐排行榜!
长时间佩戴传统入耳式耳机有时可能会影响耳道健康,鉴于此,转而选择不入耳设计的开放式耳机就成了不少人的新倾向,它们有助于减少细菌滋生和耳道闷热的烦恼。为了帮助大家找到合适的选项,下面我将列举一些市面上口碑不错的开放式耳…...
Apache Doris的分区与分桶详解
目录 第一章 Doris介绍和分区分桶作用 1.1 Doris背景介绍 1.2 分区与分桶的意义 第二章 原理解析 2.1 分区机制 2.1.1 定义 2.1.2 类型 2.1.3 工作原理 2.2 分桶机制 2.2.1 概念 2.2.2 实现方式 2.2.3 与分区的关系 第三章 手动分区与自动分区对比 3.1 手动分区 …...
docker详解介绍+基础操作 (二)info详解
1 docker相关信息和优化配置 1)查看docker版本详解 rootzz:~# docker version Client: Docker Engine - CommunityVersion: 27.3.1API version: 1.47Go version: go1.22.7Git commit: ce12230Built: Fri Sep 20 11:40:…...
C0023.在Clion中创建控件,对控件进行提升为自定义控件的步骤
新建Ui界面文件 修改新生成的ui文件头文件 关闭之前打开的ui文件,如上图Qt Designer中打开的,然后修改新生成的ui文件对应的头文件,改成自己需要的控件类即可。 提升控件为自定义类 将如下头文件中的类名和头文件名输入到提升窗口中&#…...
探索 C# 常用第三方库与框架
在 C# 开发中,第三方库和框架极大地提高了开发效率和代码质量。通过这些库,开发者可以快速处理 JSON 数据、简化对象映射、记录日志、以及高效地与数据库交互。本文将介绍四个常用的 C# 第三方库:Newtonsoft.Json、AutoMapper、NLog/Serilog …...
NodeJS GRPC简单的例子
1. 定义 .proto 文件 首先,创建一个 .proto 文件,定义服务和消息: syntax "proto3";package helloworld;service Greeter {rpc SayHello (HelloRequest) returns (HelloReply) {}rpc SayHelloAgain (HelloRequest) returns (Hel…...
无人机之三维航迹规划篇
一、基本原理 飞行环境建模:在三维航迹规划中,首先需要对飞行环境进行建模。这包括对地形、障碍物、气象等因素进行准确的测量和分析,以获得可行的飞行路径。 飞行任务需求分析:根据无人机的任务需求,确定航迹规划的…...
风格迁移-StyTr 2 : Image Style Transfer with Transformers
风格迁移-StyTr 2 : Image Style Transfer with Transformers 论文链接:Image Style Transfer with Transformers 源码链接:StyTR-2 文章目录 风格迁移-StyTr 2 : Image Style Transfer with TransformersStyTR架构图图像内容编码器内容感知位置编码&…...
上百种【基于YOLOv8/v10/v11的目标检测系统】目录(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型)
待更新(持续更新),早关注,不迷路............................................................................... 目标检测系统操作说明【用户使用指南】(pythonpyside6界面系统源码可训练的数据集也完成的训练模型ÿ…...
记录搜罗到的Matlab 对散点进行椭圆拟合
需要基于一些散点拟合椭圆估计并计算出椭圆的参数和周长,搜罗到直接上代码 (1)有用的椭圆拟合及参数计算函数 function W fitellipse(x,y) % 构造矩阵 D [x.*x, x.*y, y.*y, x, y,ones(size(x))]; S D*D; G zeros(6); G(1,3) 2; G(3,1)…...
分享我最近使用《柬埔寨语翻译通》App的体验,不会说高棉语也能去柬埔寨旅游,畅通无阻!
最近,我尝试了一款名为《柬埔寨语翻译通》的应用程序,它旨在帮助用户进行中文和高棉语之间的翻译。以下是我使用这款应用的一些体验和感受。 双向翻译功能:我首先测试了它的翻译功能。《柬埔寨语翻译通》能够将中文翻译成高棉语,反…...
文本语义检索系统的搭建过程,涵盖了召回、排序以及Milvus召回系统、短视频推荐等相关内容
大家好,我是微学AI,今天给大家介绍一下本文详细介绍了文本语义检索系统的搭建过程,涵盖了召回、排序以及Milvus召回系统的相关内容。通过使用PyTorch框架,我们提供了样例代码,以帮助读者更好地理解和实践。该系统具有广…...
redis在项目中运用(基础)
mysql学完命令之后,学过jdbc。 redis也要使用Java连接redis数据库 1.Jedis 2.RedisTemplate[重点] 1、Jedis【了解】 jedis是redis的java版本的客户端实现,jedis中提供了针对redis命令的操作 1.1导入jar文件 Maven方式 <dependency><group…...
libaom 源码分析系列:svc_encoder_rtc.cc 文件
源码函数关系 文件功能:实现 AV1 svc 编码的 RTC 功能 demo文件位置:libaom/examples/svc_encoder_rtc.cc文件内函数关系图: 结构体 AppInput:svc_encoder_rtc.cc 所属 demo 的结构体,作为从命令行接受参数的结构体;AvxVideoWriter:输出视频写入结构体;aom_codec_enc_c…...
MySQL备份和还原,用mysqldump、mysql和source命令来完成
MySQL备份和还原,都是利用mysqldump、mysql和source命令来完成的。 mysqldump命令使用方法 1运行 | cmd |利用 cd C:\Program Files\MySQL\MySQL Server 9.0\bin”命令进入bin文件夹 2输入命令 mysqldump -h127.0.0.1 -P3306 -uroot -pQWERTY zssjkcf>d:123.sql mysqldump -…...
MySQL Server、HeidiSQL(MySQL 数据库工具)
目录 一、MySQL Server (一)官网下载 (二)安装与配置 二、HeidiSQL软件 (一)安装 1. 官网下载 2. 打开 3. 使用 (1)打开服务 (2)新增数据库 ÿ…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
