C++开发五子棋游戏案例详解

在这里插入图片描述

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:Java案例分享专栏
✨特色专栏:国学周更-心性养成之路
🥭本文内容:基于贝叶斯决策的 CAD 程序设计方案

文章目录

    • 1、游戏概念和设计
    • 2、游戏引擎选择
    • 3、游戏逻辑编写
    • 4、图形和音频处理
    • 5、用户界面设计
    • 6、游戏测试和调试
    • 7、游戏优化和性能调整
    • 8、发布和分发
    • 9、游戏更新和维护

在这里插入图片描述

1、游戏概念和设计

  五子棋是一种古老的策略棋类游戏,通常在 15x15 的棋盘上进行。游戏的规则非常简单:两名玩家轮流在棋盘的交叉点上落子,先连成五子的一方获胜。在游戏设计阶段,需要确定以下核心玩法:

  • 游戏规则:明确定义落子规则、胜负判定规则、禁手规则(如果有的话)等。
  • 界面设计:包括棋盘的布局、棋子的样式、玩家信息显示、计时器等。
  • AI对战:设计并实现一个智能的对战系统,使玩家可以与电脑进行对战。
  • 玩家对战:提供玩家之间的对战模式,可以通过局域网或在线进行对战。
  • 视觉风格:确定游戏的整体视觉风格,包括棋盘背景、棋子样式、界面按钮等。
  • 音效:选择合适的音效来增强游戏的氛围,例如落子音效、胜利音效等。
  • 用户交互:设计良好的用户交互方式,包括落子操作、悔棋功能、重新开始游戏等。

  以上是游戏设计的核心方面,详细的设计需要根据目标玩家群体、游戏平台等因素进行调整和完善。在设计过程中,还需要考虑如何提升游戏的趣味性、可玩性和吸引力,以及如何平衡游戏的难度和挑战性。

2、游戏引擎选择

  对于开发简单的2D游戏,如五子棋,选择轻量级的游戏引擎是非常合适的。SFML(Simple and Fast Multimedia Library)和SDL(Simple DirectMedia Layer)都是优秀的选择。

  SFML 是一个现代的多媒体库,提供了简单易用的接口,包括图形渲染、窗口管理、音频播放和输入处理等功能。它使用 C++ 编写,易于学习和使用,适合用于快速开发小型游戏。SFML 的文档和社区支持也非常完善,对于初学者来说是一个很好的选择。

  SDL 是另一个流行的跨平台多媒体库,同样提供了图形渲染、窗口管理、音频播放和输入处理等功能。它同样使用 C++ 编写,被广泛应用于游戏开发领域。SDL 也有丰富的文档和活跃的社区,可以帮助开发者快速上手并解决问题。

  这两个引擎都可以满足五子棋游戏开发的需求,选择哪个取决于开发者的个人偏好和经验。它们都提供了良好的图形渲染支持,可以轻松实现棋盘绘制、棋子落子效果等。同时,它们也提供了方便的输入处理功能,可以处理玩家的鼠标点击或触摸操作。

3、游戏逻辑编写

在C++中编写五子棋游戏的逻辑代码需要考虑以下几个关键点:

  • 棋盘数据结构:可以使用二维数组来表示棋盘,记录每个交叉点的状态(空、黑子、白子)。
  • 用户输入处理:通过输入获取玩家落子的位置,然后更新棋盘状态。
  • 游戏状态管理:需要管理游戏的进行状态,包括当前轮到哪个玩家落子、游戏是否结束等。
  • 落子逻辑:根据玩家输入的位置,在棋盘上落子,并更新棋盘状态。
  • 胜负判断:编写算法来判断是否有玩家连成了五子,从而决定游戏的胜负。

代码示例:

#include <iostream>
#include <vector>

using namespace std;

const int BOARD_SIZE = 15;
const char EMPTY = '-';
const char PLAYER1 = 'X';
const char PLAYER2 = 'O';

vector<vector<char>> board(BOARD_SIZE, vector<char>(BOARD_SIZE, EMPTY));

void printBoard() {
    for (int i = 0; i < BOARD_SIZE; i++) {
        for (int j = 0; j < BOARD_SIZE; j++) {
            cout << board[i][j] << " ";
        }
        cout << endl;
    }
}

bool isValidMove(int row, int col) {
    if (row < 0 || row >= BOARD_SIZE || col < 0 || col >= BOARD_SIZE) {
        return false;
    }
    if (board[row][col] != EMPTY) {
        return false;
    }
    return true;
}

bool isWinningMove(int row, int col, char player) {
    int count = 0;

    // 水平方向
    for (int i = max(0, col - 4); i <= min(col + 4, BOARD_SIZE - 1); i++) {
        if (board[row][i] == player) {
            count++;
            if (count == 5) {
                return true;
            }
        } else {
            count = 0;
        }
    }

    // 垂直方向
    count = 0;
    for (int i = max(0, row - 4); i <= min(row + 4, BOARD_SIZE - 1); i++) {
        if (board[i][col] == player) {
            count++;
            if (count == 5) {
                return true;
            }
        } else {
            count = 0;
        }
    }

    // 左上到右下斜线
    count = 0;
    int startRow = row - min(row, col);
    int startCol = col - min(row, col);
    for (int i = 0; i < min(BOARD_SIZE - startRow, BOARD_SIZE - startCol); i++) {
        if (board[startRow + i][startCol + i] == player) {
            count++;
            if (count == 5) {
                return true;
            }
        } else {
            count = 0;
        }
    }

    // 右上到左下斜线
    count = 0;
    startRow = row + min(BOARD_SIZE - 1 - row, col);
    startCol = col - min(BOARD_SIZE - 1 - row, col);
    for (int i = 0; i < min(startRow + 1, BOARD_SIZE - startCol); i++) {
        if (board[startRow - i][startCol + i] == player) {
            count++;
            if (count == 5) {
                return true;
            }
        } else {
            count = 0;
        }
    }

    return false;
}

void playGame() {
    int row, col;
    char currentPlayer = PLAYER1;

    while (true) {
        cout << "当前棋盘状态:" << endl;
        printBoard();

        cout << "玩家 " << currentPlayer << ",请输入你的下棋位置(行 列):";
        cin >> row >> col;

        if (isValidMove(row, col)) {
            board[row][col] = currentPlayer;
            if (isWinningMove(row, col, currentPlayer)) {
                cout << "玩家 " << currentPlayer << " 获胜!" << endl;
                break;
            }
            currentPlayer = (currentPlayer == PLAYER1) ? PLAYER2 : PLAYER1;
        } else {
            cout << "无效的下棋位置,请重新输入!" << endl;
        }
    }
}

int main() {
    cout << "欢迎来到五子棋游戏!" << endl;
    playGame();
    return 0;
}

4、图形和音频处理

  使用图形库(如SFML)可以方便地处理游戏的图形渲染,绘制棋盘、棋子和界面元素。下面是一个简单的示例代码,展示了如何使用SFML来渲染五子棋游戏的棋盘和棋子:

#include <SFML/Graphics.hpp>

const int BOARD_SIZE = 15;
const int CELL_SIZE = 40;

int main() {
    sf::RenderWindow window(sf::VideoMode(BOARD_SIZE * CELL_SIZE, BOARD_SIZE * CELL_SIZE), "Gobang Game");

    sf::RectangleShape board(sf::Vector2f(BOARD_SIZE * CELL_SIZE, BOARD_SIZE * CELL_SIZE));
    board.setFillColor(sf::Color(222, 184, 135));

    sf::CircleShape piece(CELL_SIZE / 2 - 2);
    piece.setOutlineThickness(2);

    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
        }

        window.clear();

        window.draw(board);

        // 绘制棋子
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (/* 棋盘上该位置有棋子 */) {
                    piece.setFillColor(/* 棋子颜色 */);
                    piece.setPosition(i * CELL_SIZE + 2, j * CELL_SIZE + 2);
                    window.draw(piece);
                }
            }
        }

        window.display();
    }

    return 0;
}

  对于音频处理,可以使用相应的音频库来播放游戏音效。SFML 本身也提供了音频模块,可以方便地加载和播放音频文件。下面是一个简单的示例代码,展示了如何使用SFML的音频模块来播放音效:

#include <SFML/Audio.hpp>

int main() {
    sf::SoundBuffer buffer;
    if (!buffer.loadFromFile("sound.wav")) {
        // 加载音频文件失败
        return -1;
    }

    sf::Sound sound;
    sound.setBuffer(buffer);
    sound.play();

    // 游戏逻辑代码

    return 0;
}

  以上示例代码只是简单的演示了如何使用SFML进行图形渲染和音频处理,实际开发中可以根据需要进行更加复杂的图形和音频处理,例如添加动画效果、调整音量等。同时,还可以使用其他图形库和音频库来实现游戏的图形和音频处理,根据个人偏好和需求进行选择。

5、用户界面设计

  设计游戏的用户界面需要考虑主菜单、游戏界面和游戏设置等部分。通过图形库(如SFML)可以实现用户界面的绘制和交互。下面是一个简单的示例代码,展示了如何使用SFML来设计五子棋游戏的用户界面:

#include <SFML/Graphics.hpp>

int main() {
    sf::RenderWindow window(sf::VideoMode(800, 600), "Gobang Game");

    // 主菜单界面
    bool inMainMenu = true;
    sf::Font font;
    font.loadFromFile("arial.ttf");
    sf::Text title("Gobang Game", font, 50);
    title.setPosition(300, 100);
    sf::Text startButton("Start Game", font, 30);
    startButton.setPosition(350, 200);
    sf::Text exitButton("Exit", font, 30);
    exitButton.setPosition(380, 250);

    // 游戏界面
    bool inGame = false;
    // ... 游戏界面的绘制和交互代码 ...

    // 游戏设置界面
    bool inSettings = false;
    // ... 游戏设置界面的绘制和交互代码 ...

    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }

            if (inMainMenu) {
                // 处理主菜单界面交互
                if (event.type == sf::Event::MouseButtonPressed) {
                    // 检查鼠标点击位置,处理开始游戏和退出游戏的逻辑
                }
            } else if (inGame) {
                // 处理游戏界面交互
                // ... 游戏界面的交互代码 ...
            } else if (inSettings) {
                // 处理游戏设置界面交互
                // ... 游戏设置界面的交互代码 ...
            }
        }

        window.clear();

        if (inMainMenu) {
            // 绘制主菜单界面
            window.draw(title);
            window.draw(startButton);
            window.draw(exitButton);
        } else if (inGame) {
            // 绘制游戏界面
            // ... 游戏界面的绘制代码 ...
        } else if (inSettings) {
            // 绘制游戏设置界面
            // ... 游戏设置界面的绘制代码 ...
        }

        window.display();
    }

    return 0;
}

  以上示例代码展示了如何使用SFML来设计游戏的用户界面,包括主菜单、游戏界面和游戏设置界面。实际开发中,可以根据需求添加更多的交互元素和美化界面的效果,以提升游戏的用户体验。

6、游戏测试和调试

  进行游戏的测试和调试是确保游戏稳定性和可玩性的重要步骤。测试包括功能测试、兼容性测试和性能测试等,以确保游戏在不同平台上都能正常运行。

  • 功能测试:功能测试是验证游戏的各项功能是否按照设计要求正常工作。包括落子逻辑、胜负判断、悔棋功能、重新开始游戏等。在功能测试中,需要测试所有可能的游戏情况,包括正常情况和边界情况,以确保游戏的功能完备和稳定。

  • 兼容性测试:兼容性测试是验证游戏在不同平台和设备上的兼容性。包括不同操作系统(如Windows、macOS、Linux)、不同分辨率的屏幕、不同输入设备(如鼠标、触摸屏)等。通过兼容性测试,可以确保游戏在各种环境下都能正常运行和显示良好的效果。

  • 性能测试:性能测试是验证游戏在各种情况下的性能表现,包括帧率稳定性、内存占用、CPU占用等。通过性能测试,可以发现游戏在特定情况下可能出现的性能问题,并进行优化和调整。

  在测试过程中,需要使用各种测试工具和设备,包括调试器、性能分析工具、不同操作系统的设备等。同时,也需要进行用户体验测试,邀请真实玩家参与游戏测试,收集他们的反馈意见,以改进游戏的可玩性和用户体验。

7、游戏优化和性能调整

  游戏优化是确保游戏在各种平台上能够以流畅的方式运行,并且减少资源占用的重要步骤。优化包括代码优化、图形渲染优化、内存管理优化等。

  • 代码优化:代码优化是通过改进算法、减少不必要的计算、避免内存泄漏等方式来提高游戏的性能。这可能涉及到对游戏逻辑和数据结构的重新设计,以减少不必要的计算和内存占用。同时,还可以通过并行化处理、减少函数调用等方式来提高代码的执行效率。

  • 图形渲染优化:图形渲染是游戏性能的重要组成部分。通过减少不必要的绘制操作、使用合适的图形渲染技术(如批量渲染)、优化纹理和模型的加载等方式来提高图形渲染的效率。同时,还可以考虑使用低多边形模型、减少纹理大小等方式来降低图形渲染的资源占用。

  • 内存管理优化:合理的内存管理可以减少游戏的内存占用,提高游戏的性能。通过使用对象池、减少内存碎片、及时释放不再需要的资源等方式来优化内存管理。同时,还可以考虑使用内存映射和延迟加载等技术来降低内存占用。

  除了以上的优化方式,还可以考虑使用硬件加速、多线程优化、数据压缩等技术来提高游戏的性能和流畅度。在进行优化时,需要根据具体的情况进行分析和调整,以确保优化的效果和稳定性。

  在进行优化时,需要使用性能分析工具来评估游戏的性能瓶颈,并根据评估结果进行有针对性的优化。同时,也需要进行持续的测试和验证,以确保优化的效果和稳定性。通过不断的优化和调整,可以提高游戏的性能和用户体验,使游戏在各种平台上都能够以流畅的方式运行。

8、发布和分发

对于发布和分发游戏,需要进行以下步骤:

  • 打包游戏:将游戏打包为可执行文件或安装包。对于PC平台,可以打包为.exe文件或安装包;对于移动设备,可以打包为.apk(Android)或.ipa(iOS)文件。

  • 符合平台要求:确保游戏符合各个平台的发布要求。不同平台有不同的审核标准和要求,需要确保游戏内容、图标、描述等都符合平台的规定。同时,还需要确保游戏在不同设备上的适配性和稳定性。

  • 发布到应用商店:将游戏提交到各个平台的应用商店,如Steam(PC)、App Store(iOS)、Google Play(Android)等。在提交时需要填写相关的游戏信息、截图、描述等,并遵守应用商店的审核流程和规定。

  • 营销推广:发布游戏后,进行相关的营销推广工作,包括游戏宣传、社交媒体推广、媒体报道等,以吸引玩家关注并下载游戏。

  • 更新和维护:发布后需要持续进行游戏的更新和维护工作,包括修复bug、添加新内容、改进用户体验等,以保持游戏的品质和吸引力。

  在发布和分发游戏时,需要注意不同平台的特点和规定,确保游戏能够顺利通过审核并在各个平台上获得良好的展示和推广。同时,也需要关注玩家的反馈和意见,不断改进游戏,提高用户满意度。

9、游戏更新和维护

  游戏更新和维护是确保游戏持续吸引玩家的重要环节。根据用户反馈和需求,开发团队可以收集玩家意见和建议,然后评估并确定哪些功能需要更新或修复。这可能涉及添加新的游戏内容、改进游戏性能、修复bug或优化用户体验。持续改进游戏可以增加玩家的参与度,并确保游戏保持竞争力和吸引力。更新和维护也需要注意平衡,以避免对游戏整体稳定性和玩家体验造成负面影响。


  码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MSYS2+GCC 安装与应用保姆手册

msys2 提供可在Windows下使用 GCC 编译器&#xff1b;并且&#xff0c;借助 Linux 包管理功能&#xff0c;可轻松下载丰富的可在Windows下直接使用的 C/C 开发包&#xff0c;包括编译好的二进制包。 网络库asio、准标准库boost、zip解压缩、json格式处理、引擎 SDL……十八般兵…

图片美化SDK解决方案,赋能H5与小程序极致体验

无论是社交媒体分享、电商产品展示&#xff0c;还是个人日常生活的记录&#xff0c;一张经过精心美化的图片总能瞬间吸引眼球&#xff0c;传递出更加丰富和动人的信息。如何在不增加应用体积、不牺牲用户体验的前提下&#xff0c;为H5页面和小程序提供媲美原生APP的图片美化功能…

前端高频面试题2024/9/22(偏项目问题--通用后台管理系统)

文章目录 一.前端项目概述1.系统登录注册模块1.对注册的密码进行加密 &#xff08;使用加密中间件bcrypt.js&#xff09;2.登录成功后返回token3.前端登录页面有用到弹性布局&#xff0c;ref和reactive4.登录头像&#xff1a;文件上传 2.系统设置模块2.系统首页模块&#xff08…

Unity 从零开始的框架搭建1-2 事件的发布-订阅-取消的小优化及调用对象方法总结[半干货]

该文章专栏是向QFrameWork作者凉鞋老师学习总结得来&#xff0c;吃水不忘打井人&#xff0c;不胜感激 Unity 从零开始的框架搭建1-1 unity中对象调用的三种方式的优缺点分析【干货】-CSDN博客 原来 其实就是对上一节的事件发布订阅类的小优化&#xff0c;原来是这样子的 p…

【SEO】什么是SEO?

什么是SEO&#xff08;搜索引擎优化&#xff09;&#xff1f;为什么SEO对于⼀个⽹站⾄关重要&#xff1f; SEO 全称是搜索引擎优化&#xff08;Search Engine Optimization&#xff09; 因为我们目前开发的网址&#xff0c;需要人看到&#xff0c;除了通过宣传营销的方式展现…

计算机毕业设计 校内跑腿业务系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Qt操作主/从视图及XML——实例:汽车管理系统

目录 1. 主界面布局2.连接数据库3.主/从视图应用 1. 主界面布局 先创建一个QMainwindow&#xff0c;不带设计界面 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QGroupBox> #include <QTableView> #include <QListWidg…

【环境搭建】MAC M1安装ElasticSearch

STEP1 官网下载ES Download Elasticsearch | Elastic&#xff0c;下载mac m1对应版本的es STEP2 进入bin文件夹&#xff0c;执行./elasticSearch 浏览器输入 127.0.0.1:9200 STEP 3 下载对应Kibana版本&#xff0c;Download Kibana Free | Get Started Now | Elastic 出现报错…

Linux驱动开发(速记版)--单总线

第124章 单总线简介 124.1 单总线概述 单总线是一种串行通信协议&#xff0c;由Dallas Semiconductor开发&#xff0c;特点是用一根信号线实现双向数据传输和时钟同步&#xff0c;节省IO口且结构简单。 它广泛应用于传感器、存储器等。 硬件包括信号线、上拉电阻、设备和处理器…

高亚科技助力优巨新材,打造高效数字化研发项目管理平台

近日&#xff0c;中国企业管理软件资深服务商高亚科技与广东优巨先进新材料股份有限公司&#xff08;以下简称“优巨新材”&#xff09;正式签署合作协议&#xff0c;共同推进产品研发管理数字化升级。此次合作的主要目标是通过8Manage PM项目管理系统&#xff0c;提升优巨新材…

现货黄金价格走势图策略分析 先看“势”

在现货黄金投资市场&#xff0c;对金价走势图的趋势进行分析&#xff0c;是投资者做出明智决策的关键步骤。通过有效的趋势分析&#xff0c;投资者可以更好地预测市场的走向&#xff0c;从而制定相应的交易策略。本文将详细介绍如何分析金价的趋势&#xff0c;并探讨这种分析方…

QStandardItemModel的role

QStandardItemModel定义了一些标准的角色&#xff0c;而QAbstractItemModel允许自定义角色。以下是一些常见的数据角色&#xff1a;1. **Qt::DisplayRole**&#xff1a;这是最基本的角色&#xff0c;用于显示在视图中的文本。当一个单元格被绘制时&#xff0c;通常会查询这个角…

鸿蒙next开发者第一课02.DevEcoStudio的使用-习题

【习题】DevEco Studio的使用 通过/及格分80/ 满分100 判断题 1. 如果代码中涉及到一些网络、数据库、传感器等功能的开发&#xff0c;均可使用预览器进行预览。F 正确(True)错误(False) 预览器不能进行传感器等特殊功能的开发,需要使用真机开发 2. module.json5文件中的…

【大模型理论篇】精简循环序列模型(minGRU/minLSTM)性能堪比Transformer以及对循环神经网络的回顾

1. 语言模型之精简RNN结构 近期关注到&#xff0c;Yoshua Bengio发布了一篇论文《Were RNNs All We Needed?》&#xff0c;提出简化版RNN&#xff08;minLSTM和minGRU&#xff09;。该工作的初始缘由&#xff1a;Transformer 在序列长度方面的扩展性限制重新引发了对可在训练期…

消费者Rebalance机制

优质博文&#xff1a;IT-BLOG-CN 一、消费者Rebalance机制 在Apache Kafka中&#xff0c;消费者组 Consumer Group会在以下几种情况下发生重新平衡Rebalance&#xff1a; 【1】消费者加入或离开消费者组&#xff1a; 当一个新的消费者加入消费者组或一个现有的消费者离开消费…

若依项目搭建(黑马经验)

欢迎你搜索和了解到若依&#xff0c;这个项目是从黑马课程的一个实践&#xff0c;更多的项目经历和平台搭建期待着我们的共同学习&#xff01; 关于若依 若依是一套全部开源的快速开发平台&#xff0c;毫无保留给个人及企业免费使用。 前端采用Vue、Element UI。后端采用Sprin…

使用Pytorch+Numpy+Matplotlib实现手写字体分类和图像显示

文章目录 1.引用2.内置图片数据集加载3.处理为batch类型4.设置运行设备5.查看数据6.绘图查看数据图片(1)不显示图片标签(2)打印图片标签(3)图片显示标签 7.定义卷积函数8.卷积实例化、损失函数、优化器9.训练和测试损失、正确率(1)训练(2)测试(3)循环(4)损失和正确率曲线(5)输出…

Spark_累加器

分布式共享只写变量 实现原理&#xff1a;  累加器用来把Executor端变量信息聚合到Driver端&#xff0c;在Driver程序中定义的变量&#xff0c;在Executor端的每个Task都会得到这个变量的一份新的副本&#xff0c;每个task更新这些副本的值后&#xff0c;传回Driver端进行mer…

执行node.js获取本机Ip命令,报:Error: Cannot find module ‘ip‘错误

Error: Cannot find module ip是由于没有改模块的依赖包&#xff0c;需要进行安装&#xff0c;以管理员的身份打开命令行&#xff0c;执行npm install ip 获取当前电脑的ip地址 方法一&#xff1a; const ip require("ip")/*** 1:获取当前电脑的ip地址*/ console.…

PPT技巧:保护PPT文件的方法有哪些?

PPT文件制作好之后保证文件不出错应该是很重要的&#xff0c;毕竟是要拿出去展示的&#xff0c;今天分享PPT加密方法给大家。希望能够帮助大家保护好自己的PPT文件。 打开密码 如果想要其他人需要输入正确的密码才能够打开文件查看并编辑&#xff0c;我们可以给PPT文件设置打…