C++ 新手第一個練手小游戲:井字棋

1. 引言

介于身邊有特別多沒有學習過編程,或者有一定C語言、python或是Java基礎的但是沒有接觸過C++的新手朋友,我想可以通過一個很簡單的小項目作為挑戰,幫助大家入門C++。

今天,我們將挑戰一個對新手來說稍微復雜一點,但非常適合新手的經典小游戲——**井字棋 **!通過這個項目,你將學習到 C++ 中更重要的概念,讓你的編程能力再上一個臺階!

這個項目將帶你:

  • 深入理解函數: 如何定義、調用函數,以及參數傳遞(包括引用傳遞)。
  • 掌握二維數據結構: 使用 std::vector 來模擬棋盤。
  • 設計更復雜的程序邏輯: 判斷輸贏、平局等游戲狀態。
  • 提升代碼組織能力: 將不同功能封裝到獨立的函數中。

如何學習
在編寫的過程中可能會遇到之前沒有接觸過的知識點,這時候不要只是跟著案例敲,一個優秀的程序員應該理解自己所寫的代碼,而不是一味地對著抄,或是復制粘貼。對于不懂的代碼:

  • 使用AI工具(例如deepseek)解讀
  • 查閱相關手冊或博客文章

準備好了嗎?讓我們開始這場新的編程冒險吧!

2. 項目概覽:井字棋游戲

游戲規則:

  1. 井字棋在 3x3 的棋盤上進行。
  2. 兩名玩家輪流落子,一個用 ‘X’,一個用 ‘O’。
  3. 玩家選擇一個空位進行落子(通常通過輸入行和列的數字)。
  4. 第一個在橫線、豎線或對角線上連成三個自己的棋子的玩家獲勝。
  5. 如果棋盤填滿,但沒有人獲勝,則游戲平局。

游戲界面示例(命令行):

 1 | 2 | 3
---+---+---4 | 5 | 6
---+---+---7 | 8 | 9玩家 X 的回合。請輸入你的選擇 (1-9):

3. 環境準備

你需要:

  1. 一個 C++ 編譯器: GCC (MinGW)、MSVC (Visual Studio)、Clang 等。(如果不知道什么是編譯器記得先簡單了解一下)
  2. 一個代碼編輯器或 IDE: VS Code、Visual Studio、CLion 等。(推薦:Visual Studio)

VisualStudio2022使用教程與安裝
確保你的環境能夠編譯和運行 C++ 程序。

4. 逐步實現:井字棋游戲

我們將把游戲的不同功能拆分成獨立的函數,這樣代碼會更清晰、更容易維護。

4.1 核心數據結構:棋盤

井字棋棋盤是一個 3x3 的網格。在 C++ 中,我們可以使用二維 std::vector 來表示它。std::vector 是 C++ 標準庫提供的動態數組,比 C 風格數組更安全、更靈活。

#include <iostream> // 用于輸入輸出
#include <vector>   // 用于 std::vector
#include <limits>   // 用于 std::numeric_limits (處理輸入錯誤)// 為了方便,我們在這里使用整個 std 命名空間
using namespace std;// 定義棋盤
// vector<vector<char>> 表示一個二維字符向量
// 初始時,每個格子都用 ' ' (空格) 表示空位
vector<vector<char>> board = {{' ', ' ', ' '},{' ', ' ', ' '},{' ', ' ', ' '}
};// 當前玩家 ('X' 或 'O')
char currentPlayer = 'X';// 游戲是否結束
bool gameOver = false;int main() {// 游戲主邏輯將在這里實現return 0;
}
4.2 函數一:顯示棋盤 displayBoard()

這個函數負責將當前的棋盤狀態打印到控制臺,讓玩家看到。

// 函數:顯示棋盤
void displayBoard() {system("cls"); // Windows 清屏命令,Linux/macOS 可以用 system("clear");// 或者注釋掉,不清屏也行cout << "--- 井字棋 ---" << endl;cout << "-------------" << endl;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {cout << " " << board[i][j]; // 打印棋子if (j < 2) {cout << " |"; // 打印列分隔符}}cout << endl;if (i < 2) {cout << "---+---+---" << endl; // 打印行分隔符}}cout << "-------------" << endl;
}
4.3 函數二:玩家落子 playerMove()

這個函數負責接收玩家的輸入,并更新棋盤。它需要處理用戶輸入、檢查輸入是否合法(是否在范圍內、是否為空位)。

// 函數:玩家落子
// 參數 board 用引用傳遞 (&),這樣函數內部對 board 的修改會直接反映到外部的 board 變量
void playerMove(vector<vector<char>>& currentBoard, char player) {int choice;int row, col;while (true) {cout << "玩家 " << player << " 的回合。請輸入你的選擇 (1-9): ";cin >> choice;// 檢查輸入是否為數字,以及是否在有效范圍內if (cin.fail() || choice < 1 || choice > 9) {cout << "無效輸入!請輸入 1 到 9 之間的數字。" << endl;cin.clear(); // 清除錯誤標志// 忽略輸入緩沖區中剩余的字符,直到換行符cin.ignore(numeric_limits<streamsize>::max(), '\n');continue; // 繼續循環,要求重新輸入}// 將 1-9 的選擇轉換為二維數組的行和列row = (choice - 1) / 3;col = (choice - 1) % 3;// 檢查選擇的格子是否為空if (currentBoard[row][col] == ' ') {currentBoard[row][col] = player; // 落子break; // 輸入合法,跳出循環} else {cout << "這個位置已經被占用了!請選擇其他位置。" << endl;}}
}

新知識點:

  • 引用傳遞 (&): playerMove(vector<vector<char>>& currentBoard, char player) 中的 & 符號表示 currentBoard 是一個引用。這意味著函數內部對 currentBoard 的修改,會直接影響到 main 函數中傳入的 board 變量,而不是它的一個副本。這對于需要修改外部變量的函數非常有用。
  • cin.fail()cin.clear() 用于處理非數字輸入錯誤。cin.fail() 檢查輸入流是否處于錯誤狀態,cin.clear() 清除錯誤標志,cin.ignore() 丟棄錯誤輸入。
  • numeric_limits<streamsize>::max() 表示流的最大尺寸,配合 cin.ignore 丟棄所有剩余輸入。
4.4 函數三:檢查勝利 checkWin()

這個函數判斷當前棋盤上是否有玩家獲勝。

// 函數:檢查是否有玩家獲勝
// 參數 currentBoard 用常量引用傳遞 (const &),表示函數只讀取 board 的內容,不修改它
bool checkWin(const vector<vector<char>>& currentBoard, char player) {// 檢查行for (int i = 0; i < 3; ++i) {if (currentBoard[i][0] == player && currentBoard[i][1] == player && currentBoard[i][2] == player) {return true;}}// 檢查列for (int j = 0; j < 3; ++j) {if (currentBoard[0][j] == player && currentBoard[1][j] == player && currentBoard[2][j] == player) {return true;}}// 檢查主對角線if (currentBoard[0][0] == player && currentBoard[1][1] == player && currentBoard[2][2] == player) {return true;}// 檢查副對角線if (currentBoard[0][2] == player && currentBoard[1][1] == player && currentBoard[2][0] == player) {return true;}return false; // 沒有獲勝
}

新知識點:

  • 常量引用 (const &): checkWin(const vector<vector<char>>& currentBoard, char player) 中的 const & 表示 currentBoard 是一個引用,但函數內部不能修改 currentBoard 的內容。這是一種很好的編程習慣,既避免了不必要的拷貝,又保證了數據的安全性。
  • bool 返回值: 函數返回 truefalse,表示是否獲勝。
4.5 函數四:檢查平局 checkDraw()

這個函數判斷棋盤是否已滿,且沒有玩家獲勝。

// 函數:檢查是否平局
bool checkDraw(const vector<vector<char>>& currentBoard) {for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {if (currentBoard[i][j] == ' ') {return false; // 還有空位,不是平局}}}return true; // 沒有空位,是平局
}
4.6 游戲主邏輯 main()

現在,我們將所有函數組合起來,構建游戲的主循環。

int main() {cout << "-----------------------------------" << endl;cout << "         歡迎來到井字棋!        " << endl;cout << "-----------------------------------" << endl;// 游戲主循環while (!gameOver) {displayBoard(); // 顯示棋盤// 玩家落子playerMove(board, currentPlayer);// 檢查勝利if (checkWin(board, currentPlayer)) {displayBoard(); // 勝利后再次顯示最終棋盤cout << "恭喜玩家 " << currentPlayer << " 獲勝!" << endl;gameOver = true; // 游戲結束}// 檢查平局(只有在沒有勝利者的情況下才檢查平局)else if (checkDraw(board)) {displayBoard(); // 平局后顯示最終棋盤cout << "游戲平局!" << endl;gameOver = true; // 游戲結束}// 切換玩家else {currentPlayer = (currentPlayer == 'X') ? 'O' : 'X'; // 三元運算符:如果當前是X,則切換到O,否則切換到X}}cout << "游戲結束!感謝游玩!" << endl;return 0;
}

5. 完整代碼

現在,將所有代碼片段組合起來,你的 main.cpp 文件應該長這樣:

#include <iostream> // 用于標準輸入輸出
#include <vector>   // 用于 std::vector
#include <limits>   // 用于 std::numeric_limits (處理輸入錯誤)
#include <string>   // 用于 std::string (如果需要)
// #include <windows.h> // 如果使用 system("cls") 且在 Windows 環境下// 為了方便,我們在這里使用整個 std 命名空間
using namespace std;// 定義棋盤 (全局變量,簡化示例)
vector<vector<char>> board = {{' ', ' ', ' '},{' ', ' ', ' '},{' ', ' ', ' '}
};// 當前玩家 ('X' 或 'O')
char currentPlayer = 'X';// 游戲是否結束
bool gameOver = false;// --- 函數聲明 (良好的編程習慣,先聲明再定義) ---
void displayBoard();
void playerMove(vector<vector<char>>& currentBoard, char player);
bool checkWin(const vector<vector<char>>& currentBoard, char player);
bool checkDraw(const vector<vector<char>>& currentBoard);// --- 函數定義 ---// 函數:顯示棋盤
void displayBoard() {// Windows 清屏命令,Linux/macOS 可以用 system("clear");// 如果不想清屏,可以注釋掉這行// system("cls"); cout << "\n--- 井字棋 ---" << endl;cout << "-------------" << endl;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {cout << " " << board[i][j]; // 打印棋子if (j < 2) {cout << " |"; // 打印列分隔符}}cout << endl;if (i < 2) {cout << "---+---+---" << endl; // 打印行分隔符}}cout << "-------------" << endl;
}// 函數:玩家落子
void playerMove(vector<vector<char>>& currentBoard, char player) {int choice;int row, col;while (true) {cout << "玩家 " << player << " 的回合。請輸入你的選擇 (1-9): ";cin >> choice;// 檢查輸入是否為數字,以及是否在有效范圍內if (cin.fail() || choice < 1 || choice > 9) {cout << "無效輸入!請輸入 1 到 9 之間的數字。" << endl;cin.clear(); // 清除錯誤標志// 忽略輸入緩沖區中剩余的字符,直到換行符cin.ignore(numeric_limits<streamsize>::max(), '\n');continue; // 繼續循環,要求重新輸入}// 將 1-9 的選擇轉換為二維數組的行和列// 1 -> (0,0), 2 -> (0,1), 3 -> (0,2)// 4 -> (1,0), 5 -> (1,1), 6 -> (1,2)// 7 -> (2,0), 8 -> (2,1), 9 -> (2,2)row = (choice - 1) / 3;col = (choice - 1) % 3;// 檢查選擇的格子是否為空if (currentBoard[row][col] == ' ') {currentBoard[row][col] = player; // 落子break; // 輸入合法,跳出循環} else {cout << "這個位置已經被占用了!請選擇其他位置。" << endl;}}
}// 函數:檢查是否有玩家獲勝
bool checkWin(const vector<vector<char>>& currentBoard, char player) {// 檢查行for (int i = 0; i < 3; ++i) {if (currentBoard[i][0] == player && currentBoard[i][1] == player && currentBoard[i][2] == player) {return true;}}// 檢查列for (int j = 0; j < 3; ++j) {if (currentBoard[0][j] == player && currentBoard[1][j] == player && currentBoard[2][j] == player) {return true;}}// 檢查主對角線 (左上到右下)if (currentBoard[0][0] == player && currentBoard[1][1] == player && currentBoard[2][2] == player) {return true;}// 檢查副對角線 (右上到左下)if (currentBoard[0][2] == player && currentBoard[1][1] == player && currentBoard[2][0] == player) {return true;}return false; // 沒有獲勝
}// 函數:檢查是否平局
bool checkDraw(const vector<vector<char>>& currentBoard) {for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {if (currentBoard[i][j] == ' ') {return false; // 還有空位,不是平局}}}return true; // 沒有空位,是平局
}int main() {cout << "-----------------------------------" << endl;cout << "         歡迎來到井字棋!        " << endl;cout << "-----------------------------------" << endl;// 游戲主循環while (!gameOver) {displayBoard(); // 顯示棋盤// 玩家落子playerMove(board, currentPlayer);// 檢查勝利if (checkWin(board, currentPlayer)) {displayBoard(); // 勝利后再次顯示最終棋盤cout << "恭喜玩家 " << currentPlayer << " 獲勝!" << endl;gameOver = true; // 游戲結束}// 檢查平局(只有在沒有勝利者的情況下才檢查平局)else if (checkDraw(board)) {displayBoard(); // 平局后顯示最終棋盤cout << "游戲平局!" << endl;gameOver = true; // 游戲結束}// 切換玩家else {// 三元運算符:如果當前是X,則切換到O,否則切換到XcurrentPlayer = (currentPlayer == 'X') ? 'O' : 'X';}}cout << "游戲結束!感謝游玩!" << endl;return 0; // 程序正常退出
}

6. 編譯和運行你的游戲

6.1 使用命令行編譯 (以 GCC 為例)
  1. 打開你的命令行工具(Windows 下可以是 Git Bash、CMD、PowerShell,macOS/Linux 下是 Terminal)。

  2. 使用 cd 命令進入你存放 main.cpp 的文件夾。

    cd path/to/your/TicTacToeGame
    
  3. 編譯 main.cpp

    g++ main.cpp -o tictactoe
    
    • g++ 是 C++ 編譯器的命令。
    • main.cpp 是你的源文件。
    • -o tictactoe 指定編譯生成的可執行文件名為 tictactoe (Windows 下會自動添加 .exe 后綴)。
  4. 運行你的游戲:

    ./tictactoe  # Linux/macOS
    tictactoe.exe # Windows
    
6.2 使用 IDE 編譯和運行

如果你使用 Visual Studio、VS Code 或其他 IDE,通常可以直接點擊“運行”或“構建并運行”按鈕,IDE 會自動幫你完成編譯和運行的步驟。

7. 運行效果示例

-----------------------------------歡迎來到井字棋!        
-------------------------------------- 井字棋 ---
-------------|   |  
---+---+---|   |  
---+---+---|   |  
-------------
玩家 X 的回合。請輸入你的選擇 (1-9): 5--- 井字棋 ---
-------------|   |  
---+---+---| X |  
---+---+---|   |  
-------------
玩家 O 的回合。請輸入你的選擇 (1-9): 1--- 井字棋 ---
-------------O |   |  
---+---+---| X |  
---+---+---|   |  
-------------
玩家 X 的回合。請輸入你的選擇 (1-9): 9--- 井字棋 ---
-------------O |   |  
---+---+---| X |  
---+---+---|   | X
-------------
玩家 O 的回合。請輸入你的選擇 (1-9): 2--- 井字棋 ---
-------------O | O |  
---+---+---| X |  
---+---+---|   | X
-------------
玩家 X 的回合。請輸入你的選擇 (1-9): 8--- 井字棋 ---
-------------O | O |  
---+---+---| X |  
---+---+---| X | X
-------------
玩家 O 的回合。請輸入你的選擇 (1-9): 3--- 井字棋 ---
-------------O | O | O
---+---+---| X |  
---+---+---| X | X
-------------
恭喜玩家 O 獲勝!
游戲結束!感謝游玩!

8. 知識點回顧與進階

通過這個井字棋項目,我們學習并實踐了以下 C++ 核心概念:

  • std::vector 使用 vector<vector<char>> 來表示二維棋盤,這是 C++ 中處理動態數組和多維數據的重要方式。
  • 函數(Function): 將程序拆分成 displayBoardplayerMovecheckWincheckDraw 等獨立函數,提高了代碼的模塊化、可讀性和可維護性。
  • 函數參數傳遞:
    • 值傳遞: 默認方式,傳遞參數的副本。
    • 引用傳遞 (&): 允許函數修改外部變量(如 playerMove 修改 board),避免不必要的拷貝。
    • 常量引用 (const &): 允許函數高效地讀取外部變量,但不允許修改(如 checkWincheckDraw 讀取 board),兼顧效率和安全性。
  • bool 類型與邏輯判斷: checkWincheckDraw 函數返回 bool 值,用于控制游戲流程。
  • 健壯的輸入處理: 使用 cin.fail()cin.clear()cin.ignore() 來處理非數字輸入和輸入緩沖區問題,使程序更穩定。
  • 三元運算符 (? :): 簡潔地實現玩家切換 currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';

進階挑戰:自己嘗試完成

  1. 重置游戲: 在游戲結束后,詢問玩家是否“再玩一次”,如果選擇是,則重置棋盤和玩家狀態。
  2. 人機對戰 (AI): 實現一個簡單的電腦玩家。
    • 初級 AI: 隨機選擇一個空位落子。
    • 中級 AI: 優先選擇能贏的位置,其次選擇能阻止對手贏的位置。
  3. 統計分數: 記錄玩家 X 和玩家 O 的勝場次數。
  4. 優化棋盤顯示: 可以考慮用數字 1-9 來表示每個格子,方便玩家輸入。
  5. 結構體/類封裝: 將棋盤、當前玩家、游戲狀態等數據封裝到一個 Game 結構體或類中,進一步提升代碼的面向對象特性。

9. 總結:C++ 進階的里程碑!

恭喜你!你已經成功完成了你的第一個 C++ 進階小游戲項目——井字棋!這標志著你對 C++ 的理解又深入了一步。

通過這個項目,你不僅掌握了 std::vector、函數的運用、引用傳遞等重要概念,更重要的是,你學會了如何將一個相對復雜的程序拆解成更小、更易于管理的部分,這是軟件開發中非常重要的能力。

C++ 的學習是一個循序漸進的過程。多動手,多思考,多嘗試,你就能不斷突破,駕馭這門強大的語言,創造出更多精彩的作品!


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96349.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96349.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96349.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

透射TEM 新手入門:快速掌握核心技能

目錄 簡介? 一、TEM 基本知識 1. 核心原理&#xff08;理解圖像本質&#xff09;? 2. 關鍵結構與成像模式&#xff08;對應圖像類型&#xff09;? 二、TEM 數據處理 1. 預處理&#xff08;通用步驟&#xff09;? 2. 衍射花樣&#xff08;SAED&#xff09;處理&#x…

day075-MySQL數據庫服務安裝部署與基礎服務管理命令

文章目錄0. 老男孩思想-老男孩名言警句1. 數據庫服務安裝部署1.1 下載安裝包1.2 系統環境準備1.2.1 關閉防火墻1.2.2 關閉selinux1.2.3 安裝依賴軟件1.2.4 卸載沖突軟件1.3 安裝程序1.3.1 上傳軟件包1.3.2 配置環境變量1.3.3 創建數據庫存儲數據目錄1.3.4 創建數據庫程序管理用…

Qt二維碼生成器項目開發教程 - 從零開始構建專業級QR碼生成工具

Qt二維碼生成器項目開發教程 - 從零開始構建專業級QR碼生成工具 項目概述 本項目是一個基于Qt框架開發的專業級二維碼生成器&#xff0c;集成了開源的qrencode庫&#xff0c;提供完整的QR碼生成、預覽、保存和分享功能。項目采用C語言開發&#xff0c;使用Qt的信號槽機制實現…

LLaVA-3D,Video-3D LLM,VG-LLM,SPAR論文解讀

目錄 一、LLaVA-3D 1、概述 2、方法 3、訓練過程 4、實驗 二、Video-3D LLM 1、概述 2、方法 3、訓練過程 4、實驗 三、SPAR 1、概述 2、方法 4、實驗 四、VG-LLM 1、概述 2、方法 3、方法 4、實驗 一、LLaVA-3D 1、概述 空間關系不足&#xff1a;傳…

Spring兩個核心IoCDI(二)

DI&#xff08;依賴注入&#xff09;就是從IoC容器中獲取對象并賦值給某個屬性&#xff0c;這就是依賴注入的過程。 關于依賴注入有3種方式&#xff1a; 1、屬性注入 2、構造方法注入 3、setter注入 目錄 1、屬性注入 2、 構造方法注入 3、Setter方法注入 4、3種注入方式優…

廣東省省考備考(第八十三天8.21)——言語、判斷推理(強化訓練)

言語理解與表達 錯題解析 文段開篇介紹足夠的執法權限對于基層治理高效運行的重要性&#xff0c;接著從兩方面進行論證&#xff0c;介紹權限不足和權限過度下放對基層治理的負面影響&#xff0c;最后通過“因此”進行總結&#xff0c;強調一方面要完善執法目錄動態調整機制和制…

字符串與算法題詳解:最長回文子串、IP 地址轉換、字符串排序、蛇形矩陣與字符串加密

字符串與算法題詳解&#xff1a;最長回文子串、IP 地址轉換、字符串排序、蛇形矩陣與字符串加密 前言 在編程題訓練中&#xff0c;字符串相關的題目非常常見。本文將結合幾個典型的例題&#xff0c;詳細解析它們的解題思路和實現方式&#xff0c;幫助初學者循序漸進地掌握常用技…

從協同設計到綠色制造:工業云渲染的價值閉環

在智能制造、建筑工程、能源電力、船舶海工等工業場景中&#xff0c;3D可視化已從傳統的桌面端逐步向Web端遷移&#xff0c;Web 3D憑借其跨平臺、輕量化、實時交互等特性&#xff0c;已成為企業構建數字孿生、實現遠程協作、推動云端交付的重要工具。這場技術變革不僅改變了工業…

算法第五十一天:圖論part02(第十一章)

1.島嶼數量 99. 島嶼數量 &#x1f31f; 思路總結 — DFS 版 1?? 問題本質 給定一個二維矩陣 grid&#xff0c;1 表示陸地&#xff0c;0 表示水 統計島嶼數量&#xff0c;每個島嶼由上下左右相鄰的陸地組成 本質是 在二維網格中找連通塊 的問題。 2?? 核心思路 遍歷矩陣…

杰里708n tws api 簡介

/** 通過搜索碼搜索tws設備*/int tws_api_search_sibling_by_code();/**打開可發現, 可連接&#xff0c;可被手機和tws搜索到*/int tws_api_wait_pair_by_code(u16 code, const char *name, int timeout_ms);int tws_api_wait_pair_by_ble(u16 code, const char *name, int tim…

高調光比 LED 恒流驅動芯片方案詳解AP5165B:36V/1A

AP5165B 是深圳市世微半導體有限公司推出的一款高性能、連續電流模式的降壓型&#xff08;Buck&#xff09;LED 恒流驅動芯片。該芯片適用于輸入電壓高于 LED 電壓的應用場景&#xff0c;可驅動單顆或多顆串聯的 LED&#xff0c;輸出電流最高可達 1A&#xff0c;廣泛用于非隔離…

【從零構建企業級線程池管理系統:Python并發編程實戰指南】

從零構建企業級線程池管理系統&#xff1a;Python并發編程實戰指南 技術博客 | 深入探索Python并發編程、Web開發與現代軟件架構設計的完整實踐 &#x1f680; 項目背景 在當今高并發的互聯網時代&#xff0c;線程池作為并發編程的核心組件&#xff0c;其管理和監控能力直接影…

飛牛系統總是死機,安裝個工具查看一下日志

崩潰轉儲 (kernel crash dump)如果你懷疑是內核 panic&#xff0c;可以開啟 kdump 或 kernel crash dump。 安裝&#xff1a;sudo apt install kdump-tools # Debian/Ubuntu sudo systemctl enable kdump 下次死機時&#xff0c;系統會把內存 dump 到 /var/crash 里。sudo syst…

2025年AI Agent技術深度解析:原理、應用與未來趨勢

一、引言隨著人工智能技術的飛速發展&#xff0c;AI Agent&#xff08;智能體&#xff09;作為人工智能領域的重要分支&#xff0c;正逐漸成為推動各行業智能化轉型的關鍵力量。AI Agent具備自主感知、決策和執行能力&#xff0c;能夠在復雜環境中完成特定任務&#xff0c;為人…

linux內核 - 內存分配機制介紹

在linux內核中&#xff0c;下面這張圖說明了系統中存在一個可以滿足各種內存請求的分配機制。根據你需要內存的用途&#xff0c;你可以選擇最接近你目標的分配方式。最底層、最基礎的分配器是 頁分配器&#xff08;page allocator&#xff09;&#xff0c;它以頁為單位分配內存…

PyTorch生成式人工智能——ACGAN詳解與實現

PyTorch生成式人工智能——ACGAN詳解與實現0. 前言1. ACGAN 簡介1.1 ACGAN 技術原理1.2 ACGAN 核心思想1.3 損失函數2. 模型訓練流程3. 使用 PyTorch 構建 ACGAN3.1 數據處理3.2 模型構建3.3 模型訓練3.4 模型測試相關鏈接0. 前言 在生成對抗網絡 (Generative Adversarial Net…

Python + 淘寶 API 開發:自動化采集商品數據的完整流程?

在電商數據分析、競品監控和市場調研等場景中&#xff0c;高效采集淘寶商品數據是關鍵環節。本文將詳細介紹如何利用 Python 結合 API&#xff0c;構建一套自動化的商品數據采集系統&#xff0c;涵蓋從 API 申請到數據存儲的完整流程&#xff0c;并提供可直接運行的代碼實現。?…

2025.8.21總結

工作一年多了&#xff0c;在這期間&#xff0c;確實也有不少壓力&#xff0c;但每當工作有壓力的時候&#xff0c;最后面都會解決。好像每次遇到解決不了的事情&#xff0c;都有同事給我兜底。這種壓力&#xff0c;確實會加速一個人的成長。這種狼性文化&#xff0c;這種環境&a…

VS2022 - C#程序簡單打包操作

文章目錄VS2022 - C#程序簡單打包操作概述筆記實驗過程新建工程讓依賴的運行時程序安裝包在安裝時運行(如果發現運行時不能每次都安裝程序&#xff0c;就不要做這步)關于”運行時安裝程序無法每次都安裝成功“的應對知識點嘗試打包舊工程bug修復從需求屬性中&#xff0c;可以原…

在JAVA中如何給Main方法傳參?

一、在IDEA中進行傳參&#xff1a;先創建一個類&#xff1a;MainTestimport java.util.Arrays;public class MainTest {public static void main(String[] args) {System.out.println(args.length);System.out.println(Arrays.toString(args));} }1.IDEA ---> 在運行的按鈕上…