QT-五子棋游戏

QT-五子棋游戏

  • 一、演示效果
  • 二、核心代码
  • 三、下载链接


一、演示效果

请添加图片描述

二、核心代码

#include "GameModel.h"
#include <time.h>
#include <stdlib.h>GameModel::GameModel(){}void GameModel::startGame(GameType type){gameType = type;//初始化棋盤gameMapVec.clear();for(int i=0;i<BOARD_GRAD_SIZE;i++){std::vector<int> lineBoard;for(int j=0;j<BOARD_GRAD_SIZE;j++){lineBoard.push_back(0);}gameMapVec.push_back(lineBoard);}//如果是AI模式,需要初始化評分數組if(gameType == AI){scoreMapVec.clear();for(int i=0;i<BOARD_GRAD_SIZE;i++){std::vector<int> lineScores;for(int j=0;j<BOARD_GRAD_SIZE;j++){lineScores.push_back(0);}scoreMapVec.push_back(lineScores);}}//輪到黑方下棋為true,反之playerFlag = true;
}void GameModel::actionByPerson(int row, int col){updateGameMap(row,col);
}
void GameModel::updateGameMap(int row, int col){if(playerFlag){gameMapVec[row][col] = 1;}else{gameMapVec[row][col] = -1;}//換手playerFlag = !playerFlag;
}bool GameModel::isWin(int row,int col){/*判斷下棋點的水平、垂直、左斜、右斜方中* 有沒有5子相連的情況,如有則贏*/for(int i=0;i<5;i++){//先判斷水平方向是否有5子相連if(row>0 && row<BOARD_GRAD_SIZE &&col-i>0 && col-i+4<BOARD_GRAD_SIZE &&gameMapVec[row][col-i] == gameMapVec[row][col-i+1] &&gameMapVec[row][col-i] == gameMapVec[row][col-i+2] &&gameMapVec[row][col-i] == gameMapVec[row][col-i+3] &&gameMapVec[row][col-i] == gameMapVec[row][col-i+4]){return true;}//先判斷垂直方向是否有5子相連if(row-i>0 && row-i+4<BOARD_GRAD_SIZE &&col>0 && col<BOARD_GRAD_SIZE &&gameMapVec[row-i][col] == gameMapVec[row-i+1][col] &&gameMapVec[row-i][col] == gameMapVec[row-i+2][col] &&gameMapVec[row-i][col] == gameMapVec[row-i+3][col] &&gameMapVec[row-i][col] == gameMapVec[row-i+4][col]){return true;}//先判斷"/"方向是否有5子相連,左下->右上if(row-i>0 && row-i+4<BOARD_GRAD_SIZE &&col+i-4>0 && col+i<BOARD_GRAD_SIZE &&gameMapVec[row-i][col+i] == gameMapVec[row-i+1][col+i-1] &&gameMapVec[row-i][col+i] == gameMapVec[row-i+2][col+i-2] &&gameMapVec[row-i][col+i] == gameMapVec[row-i+3][col+i-3] &&gameMapVec[row-i][col+i] == gameMapVec[row-i+4][col+i-4]){return true;}//先判斷"\"方向是否有5子相連,右下->左上if(row-i>0 && row-i+4<BOARD_GRAD_SIZE &&col-i>0 && col-i+4<BOARD_GRAD_SIZE &&gameMapVec[row-i][col-i] == gameMapVec[row-i+1][col-i+1] &&gameMapVec[row-i][col-i] == gameMapVec[row-i+2][col-i+2] &&gameMapVec[row-i][col-i] == gameMapVec[row-i+3][col-i+3] &&gameMapVec[row-i][col-i] == gameMapVec[row-i+4][col-i+4]){return true;}}return false;
}//計算每格分數函數
void GameModel::calculateScore(){//統計玩家或者電腦連成的子int personNum = 0; //玩家連成子的個數int botNum = 0;   //AI連成子的個數int emptyNum = 0;   //各方向空白位的個數//清空評分數組scoreMapVec.clear();for(int i=0;i<BOARD_GRAD_SIZE;i++){std::vector<int> lineScores;for(int j=0;j<BOARD_GRAD_SIZE;j++){lineScores.push_back(0);}scoreMapVec.push_back(lineScores);}//計分/*計分個人理解:* 遍歷每一個格子,判斷哪些是空白的點(即為0的點),以該點為中心,判斷周圍的八個點向外延伸的四格裡,* 有多少個是黑子、白子、空白,以此作為依據來評分。下方算法是以守為主,所以守的分數>攻的分數*/for(int row=0;row<BOARD_GRAD_SIZE;row++){for(int col=0;col<BOARD_GRAD_SIZE;col++){//空白點才算if(row>0 && col>0 && gameMapVec[row][col]==0){//遍歷周圍8個方向for(int y=-1;y<=1;y++){for(int x=-1;x<=1;x++){//重置personNum = 0;botNum = 0;emptyNum = 0;//原坐標不算if(!(y==0 && x==0)){//每個方向延伸4個子//對玩家黑子評分(正反兩個方向)for(int i=1;i<=4;i++){if(row+i*y>0 && row+i*y<BOARD_GRAD_SIZE &&col+i*x>0 && col+i*x<BOARD_GRAD_SIZE &&gameMapVec[row+i*y][col+i*x]==1){ //真人玩家的子personNum++;}else if(row+i*y>0 && row+i*y<BOARD_GRAD_SIZE &&col+i*x>0 && col+i*x<BOARD_GRAD_SIZE &&gameMapVec[row+i*y][col+i*x]==0){ //空白位emptyNum++;break;}else{ //出邊界,或有白子break;}}for(int i=1;i<=4;i++){if(row-i*y>0 && row-i*y<BOARD_GRAD_SIZE &&col-i*x>0 && col-i*x<BOARD_GRAD_SIZE &&gameMapVec[row-i*y][col-i*x]==1){ //真人玩家的子personNum++;}else if(row-i*y>0 && row-i*y<BOARD_GRAD_SIZE &&col-i*x>0 && col-i*x<BOARD_GRAD_SIZE &&gameMapVec[row-i*y][col-i*x]==0){ //空白位emptyNum++;break;}else{ //出邊界,或有白子break;}}if(personNum == 1){                 //殺2scoreMapVec[row][col]+=10;}else if(personNum == 2){           //殺3if(emptyNum == 1)scoreMapVec[row][col]+=30;else if(emptyNum == 2)scoreMapVec[row][col]+=40;}else if(personNum == 3){           //殺4//量變空位不一樣,優先級不一樣if(emptyNum == 1)scoreMapVec[row][col]+=60;else if(emptyNum == 2)scoreMapVec[row][col]+=110;}else if(personNum == 4){           //殺5scoreMapVec[row][col]+=10100;}//進行一次清空emptyNum = 0;//對AI白子評分for(int i=1;i<=4;i++){if(row+i*y>0 && row+i*y<BOARD_GRAD_SIZE &&col+i*x>0 && col+i*x<BOARD_GRAD_SIZE &&gameMapVec[row+i*y][col+i*x]==-1){ //AI的子botNum++;}else if(row+i*y>0 && row+i*y<BOARD_GRAD_SIZE &&col+i*x>0 && col+i*x<BOARD_GRAD_SIZE &&gameMapVec[row+i*y][col+i*x]==0){ //空白位emptyNum++;break;}else{ //出邊界break;}}for(int i=1;i<=4;i++){if(row-i*y>0 && row-i*y<BOARD_GRAD_SIZE &&col-i*x>0 && col-i*x<BOARD_GRAD_SIZE &&gameMapVec[row-i*y][col-i*x]==-1){ //AI的子botNum++;}else if(row-i*y>0 && row-i*y<BOARD_GRAD_SIZE &&col-i*x>0 && col-i*x<BOARD_GRAD_SIZE &&gameMapVec[row-i*y][col-i*x]==0){ //空白位emptyNum++;break;}else{ //出邊界break;}}if(botNum == 0){scoreMapVec[row][col]+=5;  //活1}else if(botNum == 1){scoreMapVec[row][col]+=10; //活2}else if(botNum == 2){         //活3if(emptyNum == 1)scoreMapVec[row][col]+=25;else if(emptyNum == 2)scoreMapVec[row][col]+=50;}else if(botNum == 3){         //活4if(emptyNum == 1)scoreMapVec[row][col]+=55;else if(emptyNum == 2)scoreMapVec[row][col]+=100;}else if(botNum >= 4){         //活5scoreMapVec[row][col]+=20000;}}}}}}}}
//AI執行下棋
void GameModel::actionByAI(int &clickRow,int &clickCol){//計算評分calculateScore();//從評分中找出最大分數的位置int maxScore = 0;std::vector<std::pair<int,int>> maxPoints;for(int row = 1;row<BOARD_GRAD_SIZE;row++){for(int col = 1;col<BOARD_GRAD_SIZE;col++){//前提是這個坐標是空的if(gameMapVec[row][col] == 0){if(scoreMapVec[row][col]>maxScore){     //找最大數和坐標maxPoints.clear();maxScore = scoreMapVec[row][col];maxPoints.push_back(std::make_pair(row,col));}else if(scoreMapVec[row][col] == maxScore){   //如果有多個最大值就將他們存儲起來,在後面的代碼隨機抽1個maxPoints.push_back(std::make_pair(row,col));}}}}//隨機落子,如果有多個點的話srand((unsigned)time(0));int index = rand()%maxPoints.size();std::pair<int,int> pointPair = maxPoints.at(index);clickRow = pointPair.first;clickCol = pointPair.second;updateGameMap(clickRow,clickCol);
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QMouseEvent>
#include <math.h>
#include <QMessageBox>
#include <QTimer>
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->setFixedSize(MARGIN*2+BLOCK_SIZE*BOARD_GRAD_SIZE,MARGIN*2+BLOCK_SIZE*BOARD_GRAD_SIZE);initGame();}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::paintEvent(QPaintEvent* event){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing); //設置抗鋸齒for(int i=0;i<BOARD_GRAD_SIZE+1;i++){//從左到右,第(i+1)條豎線painter.drawLine(MARGIN+BLOCK_SIZE*i,MARGIN,MARGIN+BLOCK_SIZE*i,this->height()-MARGIN);//從上到下,第(i+1)條橫線painter.drawLine(MARGIN,MARGIN+BLOCK_SIZE*i,this->width()-MARGIN,MARGIN+BLOCK_SIZE*i);}//繪製選中點QBrush brush;brush.setStyle(Qt::SolidPattern);//繪製落子標記(防止鼠標出框越界)if(clickPosRow>0 && clickPosRow<BOARD_GRAD_SIZE &&clickPosCol>0 && clickPosCol<BOARD_GRAD_SIZE &&game->gameMapVec[clickPosRow][clickPosCol]==0){if(game->playerFlag){brush.setColor(Qt::black);}else{brush.setColor(Qt::white);}painter.setBrush(brush);painter.drawRect(MARGIN+BLOCK_SIZE*clickPosCol-MARK_SIZE/2,MARGIN+BLOCK_SIZE*clickPosRow-MARK_SIZE/2,MARK_SIZE,MARK_SIZE);}for(int i=0;i<BOARD_GRAD_SIZE;i++){for(int j=0;j<BOARD_GRAD_SIZE;j++){if(game->gameMapVec[i][j]==1){brush.setColor(Qt::black);painter.setBrush(brush);painter.drawEllipse(MARGIN+BLOCK_SIZE*j-CHESS_RADIUS,MARGIN+BLOCK_SIZE*i-CHESS_RADIUS,CHESS_RADIUS*2,CHESS_RADIUS*2);}else if(game->gameMapVec[i][j]==-1){brush.setColor(Qt::white);painter.setBrush(brush);painter.drawEllipse(MARGIN+BLOCK_SIZE*j-CHESS_RADIUS,MARGIN+BLOCK_SIZE*i-CHESS_RADIUS,CHESS_RADIUS*2,CHESS_RADIUS*2);}}}//判斷輸嬴if(clickPosCol>0 && clickPosCol<BOARD_GRAD_SIZE &&clickPosRow>0 && clickPosRow<BOARD_GRAD_SIZE &&(game->gameMapVec[clickPosRow][clickPosCol]==1||game->gameMapVec[clickPosRow][clickPosCol]==-1)){  //代碼解析:game->gameMapVec[clickPosRow][clickPosCol]==1||game->gameMapVec[clickPosRow][clickPosCol]==-1,防止因為5個0(空白)相連也被判勝利if(game->isWin(clickPosRow,clickPosCol) && game->gameStatus == PLAYING){game->gameStatus = WIN;QString str;str = game->gameMapVec[clickPosRow][clickPosCol]==1?u8"黑棋":u8"白棋";QMessageBox::StandardButton btnValue = QMessageBox::information(this,u8"五子棋嬴家",str+u8"勝利");if(btnValue == QMessageBox::Ok){game->startGame(game_type);game->gameStatus = PLAYING;}}}
}
//初始化遊戲
void MainWindow::initGame(){game = new GameModel();QMessageBox::StandardButton select = QMessageBox::question(this,u8"選擇遊戲模式",u8"YES[玩家VS電腦]  NO[玩家VS玩家]");if(select == QMessageBox::Yes){game_type = AI;}else {game_type = MAN;}game->gameStatus = PLAYING;game->startGame(game_type);update();
}void MainWindow::mouseMoveEvent(QMouseEvent* event){//通過鼠標的hover確定落子的標記int x = event->x();int y = event->y();//棋盤邊緣不能落子if(x>=MARGIN+BLOCK_SIZE/2&&x<this->width()-MARGIN-BLOCK_SIZE/2&&y>=MARGIN+BLOCK_SIZE/2&&y<this->height()-MARGIN-BLOCK_SIZE/2){//獲取最近的左上角的點int col = (x-MARGIN)/BLOCK_SIZE;int row = (y-MARGIN)/BLOCK_SIZE;int leftTopPosX = MARGIN+BLOCK_SIZE*col;int leftTopPosY = MARGIN+BLOCK_SIZE*row;//根據距離算出合適的點擊位置,一共四個點,根據半徑距離選最近的clickPosRow = -1; //初始化最終值clickPosCol = -1;int len = 0;  //計算完後取整就可以了selectPos = false;//確定一個誤差在範圍內的點,且只可能確定一個出來//len:與左上角的點的距離len = sqrt((x-leftTopPosX)*(x-leftTopPosX)+(y-leftTopPosY)*(y-leftTopPosY));if(len<POS_OFFSET){clickPosRow = row;clickPosCol = col;if(game->gameMapVec[clickPosRow][clickPosCol]==0){selectPos = true;}}//len:與右上角的點的距離len = sqrt((x-leftTopPosX-BLOCK_SIZE)*(x-leftTopPosX-BLOCK_SIZE)+(y-leftTopPosY)*(y-leftTopPosY));if(len<POS_OFFSET){clickPosRow = row;clickPosCol = col+1;if(game->gameMapVec[clickPosRow][clickPosCol]==0){selectPos = true;}}//len:與左下角的點的距離len = sqrt((x-leftTopPosX)*(x-leftTopPosX)+(y-leftTopPosY-BLOCK_SIZE)*(y-leftTopPosY-BLOCK_SIZE));if(len<POS_OFFSET){clickPosRow = row+1;clickPosCol = col;if(game->gameMapVec[clickPosRow][clickPosCol]==0){selectPos = true;}}//len:與右下角的點的距離len = sqrt((x-leftTopPosX-BLOCK_SIZE)*(x-leftTopPosX-BLOCK_SIZE)+(y-leftTopPosY-BLOCK_SIZE)*(y-leftTopPosY-BLOCK_SIZE));if(len<POS_OFFSET){clickPosRow = row+1;clickPosCol = col+1;if(game->gameMapVec[clickPosRow][clickPosCol]==0){selectPos = true;}}}//存了坐標後也要重繪update();
}void MainWindow::mouseReleaseEvent(QMouseEvent* event){if(selectPos == false){return;}else{selectPos = false;}//由人來下棋chessOneByPerson();if(game_type == AI){ //人機模式//AI 下棋QTimer::singleShot(AI_THINK_TIME,this,SLOT(chessOneByAI()));}
}void MainWindow::chessOneByPerson(){if(clickPosRow!=-1 && clickPosCol!=-1 && game->gameMapVec[clickPosRow][clickPosCol]==0){//在遊戲的數據模型中落子game->actionByPerson(clickPosRow,clickPosCol);//播放落子音效//重繪update();}
}void MainWindow::chessOneByAI(){game->actionByAI(clickPosRow,clickPosCol);update();
}

三、下载链接

https://download.csdn.net/download/u013083044/89656663

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

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

相关文章

如何备份电脑数据到U盘?防止数据丢失从备份开始

在数字化时代&#xff0c;数据备份已经成为我们日常生活中不可或缺的一部分。电脑中的数据&#xff0c;无论是工作文件、学习资料&#xff0c;还是珍贵的照片和视频&#xff0c;都是我们生活中重要的资产。为了防止数据丢失&#xff0c;将数据备份到U盘是一个简单且实用的方法。…

【IEEE独立出版】第三届人工智能、物联网和云计算技术国际会议(AIoTC 2024,9月13-15)

第三届人工智能、物联网与云计算技术国际会议(AIoTC 2024)将于2024年9月13日-15日在中国武汉举行。 本次会议由华中师范大学伍伦贡联合研究院与南京大学联合主办、江苏省大数据区块链与智能信息专委会承办、江苏省概率统计学会、江苏省应用统计学会、Sir Forum、南京理工大学、…

《重温JavaScript五子棋小游戏》

目录 全部运行代码&#xff1a;五子棋游戏的基本步骤&#xff1a;代码剖析&#xff1a;1. 初始化游戏界面2. 管理游戏状态3. 玩家交互4. 电脑AI5. 胜负判定6. 游戏控制 本文通过实现一个基本的五子棋游戏&#xff0c;展示了如何使用HTML、CSS和JavaScript来构建一个简单的交互式…

GIS应用水平考试一级真题和答案分享~

2012年-2018年完整真题和答案 GIS应用水平考试资料分享https://docs.qq.com/doc/DRmxxaVhpbGJXSGho?u5295a88d71d8480d971da4e3334ee913

ES高级查询Query DSL查询详解、term术语级别查询、全文检索、highlight高亮

文章目录 ES高级查询Query DSLmatch_all返回源数据_source返回指定条数size分页查询from&size指定字段排序sort 术语级别查询term query术语查询terms query多术语查询range query范围查询exists queryids queryprefix query前缀查询wildcard query通配符查询fuzzy query模…

可视化大屏-实现自动滚动

一、背景&#xff1a;可视化大屏通常需要用到自动滚动的效果&#xff0c;本文主要采用的是vue-seamless-scroll组件来实现&#xff08;可参考官方文档&#xff09; 二、实现效果&#xff1a; 自动滚动 三、代码实现&#xff1a; 解题思路&#xff1a; 1.先安装依赖包 npm inst…

亲测解决Verifying shim SBAT data failed: Security Policy Violation

在小虎用u盘安装ubuntu系统的时候&#xff0c;笔记本出现了这个问题&#xff0c;解决方法是管关闭security boot。 解决方法 利用F2\F10\F12进入Bios设置&#xff0c;关闭security boot即可。 Use F2 to enter the bios security settings, close it. 参考 Verifying shim…

基于YOLOv8的船舶目标检测与分割(ONNX模型)

项目背景 需求分析&#xff1a;在海洋监控、港口管理、海事安全等领域&#xff0c;自动化的船只检测与分割技术对于提高效率和安全性至关重要。技术选型&#xff1a;YOLOv8是YOLO系列的一个较新版本&#xff0c;以其速度快、准确率高而著称。使用ONNX&#xff08;Open Neural …

亲测好用,吐血整理 ChatGPT 3.5/4.0 新手使用手册~ 【2024年8月 更新】

废话不多说&#xff0c;直接分享正文~ 以下是小编为大家搜集到的最新的ChatGPT国内站&#xff0c;各有优缺点。 1、AI Plus&#xff08;稳定使用&#xff09; 推荐指数&#xff1a;⭐⭐⭐⭐⭐ yixiaai.com 该网站已经稳定运营了1年多了。2023年3月份第一批上线的网…

产品经理原型设计工具 Axure 的使用

原型设计工具 Axure 中文学习网&#xff1a;https://www.axure.com.cn/ 1、安装 2023年Axure RP9最新安装、汉化教程&#xff08;附带安装包下载&#xff09; 2、基本使用 Axure rp9入门图文教程——基操及介绍&#xff08;看完就能上手&#xff0c;人人都是产品经理&#x…

Thymeleaf+Bootstrap封装分页组件

效果 代码 templates/components/pagination.html <!doctype html> <html lang"zh-CN" xmlns:th"http://www.thymeleaf.org"> <body> <div class"d-flex justify-content-between align-items-center mb-3" th:fragment&…

【C++】string类:模拟实现(适合新手的手撕string)

上次介绍了标准库里的string类以及常用接口&#xff1a;【C】String类&#xff1a;标准库介绍-CSDN博客 本次就来亲自动手来模拟实现下 目录 一.基本结构 二.构造函数&#xff08;constructor&#xff09; 1.构造函数 2.拷贝构造 3.c_str() 三.析构函数&#xff08;destr…

linux PXE批量网络装机及Kickstart无人值守安装

目录 一、PXE基本概述 1.1 什么是PXE 1.2 PXE批量部署的优点 1.3 PXE部署的前置条件 二、部署PXE远程安装服务器 2.1 安装并启动TFTP服务 2.2 安装并启动DHCP服务 2.3 准备linux内核、初始化镜像文件 2.4 准备PXE引导程序 2.5 安装FTP服务&#xff0c;准备CentOS 7 安…

Solidworks 创建工程图纸,工程图纸不显示解决

当完成三维零件&#xff0c;制作工程图纸时&#xff0c;发现右侧“工程图图纸”不显示了&#xff0c;不能像以前那样方便的拖拽了。如下图&#xff1a; 解决办法&#xff1a; 步骤1:点击这 ...&#xff0c;打开需要的三维图文件&#xff0c;如“公头主体” 步骤2&#xff1a;…

VisualStudio|开发环境相关技巧及问题

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 本节继续学习VisualStudio相关内容&#xff0c;以前学习都是以能用为主&#xff0c;没有系统的学习&#xff0c;接下来会系统的学习相关内容&#xff0c; 以下为学习笔记。 01 第三方dll调用 ①&#xff1a;如果第三…

希尔排序

希尔排序是直接排序的优化版本。 希尔排序是将庞大的数据进行分组&#xff0c;通过定义一个gap值&#xff0c;将数组里面间隔为这个gap值的元素分在一个小组里面&#xff0c;把每个小组通过插入排序的方式分别排成有序 在一组组排成有序的这个过程中&#xff0c;原来无序的数…

快速上手体验MyPerf4J监控springboot应用(docker版快速开始-本地版)

使用MyPerf4J监控springboot应用 快速启动influxdb时序数据库日志收集器telegrafgrafana可视化界面安装最终效果 项目地址 项目简介: 一个针对高并发、低延迟应用设计的高性能 Java 性能监控和统计工具。 价值 快速定位性能瓶颈快速定位故障原因 快速启动 监控本地应用 idea配…

M8020A J-BERT 高性能比特误码率测试仪

M8020A 比特误码率测试仪 J-BERT M8020A 高性能 BERT 产品综述 Keysight J-BERT M8020A 高性能比特误码率测试仪能够快速、准确地表征传输速率高达 16 或 32 Gb/s 的单通道和多通道器件中的接收机。 M8020A 综合了更广泛的功能&#xff0c;可以简化您的测试系统。 自动对信…

qiankun微前端

qiankun微前端 主项目1、安装qiankun2、main.js引入注册 二、子项目1、安装sh-winter/vite-plugin-qiankun2、main.js配置3、vite.config.js配置 三、问题解决四、一键启动 主项目 1、安装qiankun npm i qiankun -S2、main.js引入注册 import { createApp } from vue import…

健身房管理系统--论文pf

TOC springboot542健身房管理系统--论文pf 第1章 绪论 1.1选题动因 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着电脑和笔记本的广泛…