三子棋游戲(基礎版)

我們用 C 語言代碼實現了一個簡單的控制臺版三子棋游戲,代碼分為三個部分,分別是頭文件game.h中定義的函數聲明以及兩個源文件game.ctest.cgame.c文件。

1.頭文件(game.h)部分

首先包含了<stdio.h>(用于標準輸入輸出操作,像printfscanf函數的使用)、<stdlib.h>(包含了如randsrand等函數,用于生成隨機數以及內存分配等相關操作)和<time.h>(獲取時間相關信息,用于初始化隨機數生成器)這幾個常用的標準庫頭文件。

接著通過#define定義了ROWCOL兩個宏常量,都賦值為 3,代表三子棋棋盤的行數和列數。

最后聲明了五個函數,這些函數分別用于初始化棋盤、打印棋盤、玩家下棋、電腦下棋以及判斷游戲的輸贏狀態,它們的具體實現在game.c文件中。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>#define ROW 3
#define COL 3//初始化棋盤
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盤
void DispalyBoard(char board[ROW][COL], int row, int col);//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);//電腦下棋
void ComputerMove(char board[ROW][COL], int row, int col);//'X'表示玩家獲勝
//'O'表示電腦獲勝
//'Q'表示平局
//'C'表示游戲未結束
char IsWin(char board[ROW][COL], int row, int col);

2.源文件(game.c)部分

(InitBoard函數)

這個函數的作用是初始化棋盤,通過兩層嵌套的for循環遍歷整個二維字符數組(即棋盤),將每個元素都設置為空字符' ',表示棋盤初始狀態下各個格子都是空白的,沒有棋子。

(DispalyBoard函數)

該函數用于在控制臺打印出三子棋棋盤的樣子。它通過兩層循環來實現,外層循環控制行數,內層循環在每行中先打印出每個格子對應的字符(棋子符號或者空白),并且在格子之間用|進行分隔,每一行數據打印完后,若不是最后一行,還會打印出一行分割線(由---|組成),這樣就能清晰地展示出棋盤的布局和當前棋子的放置情況。

(PlayerMove函數)

這個函數實現了玩家下棋的操作邏輯。首先提示玩家輸入下棋的坐標,然后通過while循環不斷接收玩家輸入的坐標,并進行合法性檢查:一是檢查坐標是否在棋盤的有效范圍內(1 到rowcol之間),二是檢查輸入坐標對應的格子是否為空(沒有被其他棋子占據),只有當坐標合法且對應格子為空時,才會將玩家的棋子(用'X'表示)放置到該格子中,隨后跳出循環;如果坐標不合法或者格子已被占用,則會相應地提示玩家重新輸入。

(ComputerMove函數)

該函數用于實現電腦下棋的操作邏輯。首先會提示 “電腦下棋:>”,然后通過while循環不斷生成隨機坐標(利用rand函數生成 0 到row - 1以及 0 到col - 1范圍內的隨機數作為棋盤的行列索引),接著檢查該隨機坐標對應的格子是否為空,如果為空,就將電腦的棋子(用'O'表示)放置到該格子中,然后跳出循環;這樣電腦就能隨機地在棋盤上的空白格子中放置棋子了。需要注意的是,這里使用rand函數前一般需要在main函數中通過srand((unsigned int)time(NULL));初始化隨機數生成器,以保證每次游戲電腦下棋的隨機性。

(IsFull函數)

這個函數用于判斷棋盤是否已滿,也就是判斷棋盤上是否還有空白的格子。通過兩層嵌套的for循環遍歷整個棋盤,如果發現有任意一個格子的值為' '(即空白),就返回 0,表示棋盤未滿;如果整個棋盤遍歷完都沒有發現空白格子,那就返回 1,表示棋盤已滿。

(IsWin函數)

此函數用于判斷游戲的輸贏狀態。它首先按照行、列、對角線的順序來檢查是否有一方的棋子連成了三子一線的情況:

在檢查行時,通過外層循環遍歷每一行,然后比較該行的三個格子的棋子是否相同且不為空白,如果滿足條件,就返回該行棋子對應的字符('X'或者'O'),表示該行對應的玩家或電腦獲勝。

檢查列的邏輯類似,通過內層循環遍歷每一列,比較每列三個格子的棋子情況來判斷是否有一方獲勝。

對于對角線,分別檢查兩條對角線上的格子棋子是否相同且不為空白來確定是否有一方獲勝。

如果經過上述檢查都沒有發現有一方獲勝,那么接著調用IsFull函數來判斷棋盤是否已滿,如果已滿則返回'Q',表示平局;如果棋盤未滿,則返回'C',表示游戲還未結束,需要繼續進行。

#include"game.h"void InitBoard(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 DispalyBoard(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++){printf(" %c ", board[i][j]);if (j < col - 1)printf("|");}printf("\n");//打印分割信息if (i < row - 1){int j = 0;for (j = 0;j < col;j++){printf("---");if (j < col - 1)printf("|");}printf("\n");}}
}void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("玩家下棋:>\n");while (1){printf("請輸入坐標:>");scanf("%d %d", &x, &y);//坐標范圍合法判度if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = 'X';break;}else{printf("坐標被占用,請選擇其他位置\n");}}else{printf("坐標非法,請重新輸入\n");}}
}void ComputerMove(char board[ROW][COL], int row, int col)
{printf("電腦下棋:>\n");int x = 0;int y = 0;while (1){x = rand() % row;//0~2y = rand() % col;//0~2if (board[x][y] == ' '){board[x][y] = 'O';break;}}}//判斷棋盤狀態,返回值含義://'X'表示玩家獲勝//'O'表示電腦獲勝//'Q'表示平局//'C'表示游戲未結束//滿了就返回1
//不滿就返回0
int IsFull(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++){if (board[i][j] == ' '){return 0;}}}return 1;
}char IsWin(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][1] != ' '){return board[i][1];}}//列int j = 0;for (j = 0;j< col;j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j]!= ' '){return board[1][j];}}//對角線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 (IsFull(board, row, col)){return 'Q';}//游戲繼續return 'C';}

2.源文件(test.c)部分

(menu函數)

這個函數很簡單,就是在控制臺打印出游戲的菜單,顯示了兩個選項,分別是1.play用于開始游戲和0.exit用于退出游戲,使玩家能清晰地看到可操作的選擇。

(game函數)

game函數實現了一局三子棋游戲的完整流程。首先定義了一個字符變量ret用于記錄游戲的輸贏狀態,以及一個二維字符數組board來表示棋盤,接著調用InitBoard函數初始化棋盤,并通過DispalyBoard函數顯示初始棋盤。然后進入一個while循環,在循環中先讓玩家下棋(調用PlayerMove函數),之后調用IsWin函數判斷此時游戲是否有輸贏結果,如果游戲未結束(返回值為'C'),則顯示當前棋盤狀態(再次調用DispalyBoard函數),接著讓電腦下棋(調用ComputerMove函數),同樣再判斷游戲輸贏情況,如此反復,直到游戲有了輸贏或者平局的結果(IsWin函數返回值不為'C'),最后根據ret的值輸出相應的游戲結果(玩家贏、電腦贏或者平局),并再次顯示棋盤。

(main函數)

main函數是整個程序的入口點。首先通過srand((unsigned int)time(NULL));初始化隨機數生成器,確保電腦下棋的隨機性。然后進入一個do-while循環,在循環中先調用menu函數顯示游戲菜單,接著讓用戶輸入選擇,根據用戶輸入的不同選項(通過switch語句判斷),如果輸入1則調用game函數開始一局游戲,如果輸入0則退出游戲,其他輸入則提示選擇錯誤,循環繼續,直到用戶選擇退出游戲為止,最后返回 0 表示程序正常結束。

#include"game.h"void menu()
{printf("****************************************\n");printf("************    1.play    **************\n");printf("************    0.exit    **************\n");printf("****************************************\n");
}void game()
{char ret = 0;char board[ROW][COL] = { 0 };//初始化棋盤的函數InitBoard(board, ROW, COL);DispalyBoard(board, ROW, COL);//下棋while (1){PlayerMove(board, ROW, COL);//判斷輸贏ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}//顯示棋盤DispalyBoard(board, ROW, COL);ComputerMove(board, ROW, COL);//判斷輸贏ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}//顯示棋盤DispalyBoard(board, ROW, COL);}if (ret == 'X'){printf("玩家贏了\n");}else if (ret == 'O'){printf("電腦贏了\n");}else{printf("平局\n");}DispalyBoard(board, ROW, COL);} int main()
{srand((unsigned int)time(NULL));//設置隨機數生成起點的int input = 0;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.pswp.cn/web/63759.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/63759.shtml
英文地址,請注明出處:http://en.pswp.cn/web/63759.shtml

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

相關文章

使用Chat-LangChain模塊創建一個與用戶交流的機器人

當然&#xff01;要使用Chat-LangChain模塊創建一個與用戶交流的機器人&#xff0c;你需要安裝并配置一些Python庫。以下是一個基本的步驟指南和示例代碼&#xff0c;幫助你快速上手。 安裝依賴庫 首先&#xff0c;你需要安裝langchain庫&#xff0c;它是一個高級框架&#x…

嵌入式驅動開發詳解20(IIO驅動架構)

文章目錄 前言IIO子系統簡介主要結構體主要API函數 IIO子系統實現SPI框架IIO框架IIO通道詳解通道結構體分析通道命名分析icm20608設備通道實現 讀取函數寫入函數 測試測試效果命令行讀取應用程序讀取 后續參考文獻 前言 IIO 全稱是 Industrial I/O&#xff0c;翻譯過來就是工業…

Linux 網絡維護相關命令簡介

目錄 零. 概要一. ping二. ip命令2.1 ip address2.2 ip route2.3 ip neighbour 三. traceroute四. DNS查詢4.1 nslookup4.2 dig 五. ss 查看網絡連接狀態 零. 概要 ?在Linux系統中有2套用于網絡管理的工具集 net-tools 早期網絡管理的主要工具集&#xff0c;缺乏對 IPv6、網…

Jenkins持續集成部署——jenkins安裝

前言 Jenkins 是一個開源的自動化服務器&#xff0c;主要用于持續集成&#xff08;CI&#xff09;和持續交付&#xff08;CD&#xff09;。它為軟件開發團隊提供了一個易于使用的平臺來自動化構建、測試和部署應用程序的過程。 Jenkins 主要功能 1. 持續集成 (CI) 自動構建…

PYG - Cora數據集加載 (自動加載+手動實現)

本文從Cora的例子來展示PYG如何加載圖數據集。 Cora 是一個小型的有標注的圖數據集&#xff0c;包含以下內容&#xff1a; data.x&#xff1a;2708 個節點&#xff08;即 2708 篇論文&#xff09;&#xff0c;每個節點有 1433 個特征&#xff0c;形狀為 (2708, 1433)。data.ed…

《 火星人 》

題目描述 人類終于登上了火星的土地并且見到了神秘的火星人。人類和火星人都無法理解對方的語言&#xff0c;但是我們的科學家發明了一種用數字交流的方法。這種交流方法是這樣的&#xff0c;首先&#xff0c;火星人把一個非常大的數字告訴人類科學家&#xff0c;科學家破解這…

機器學習基礎算法 (二)-邏輯回歸

python 環境的配置參考 從零開始&#xff1a;Python 環境搭建與工具配置 邏輯回歸是一種用于解決二分類問題的機器學習算法&#xff0c;它可以預測輸入數據屬于某個類別的概率。本文將詳細介紹邏輯回歸的原理、Python 實現、模型評估和調優&#xff0c;并結合垃圾郵件分類案例進…

BiTCN-BiGRU基于雙向時間卷積網絡結合雙向門控循環單元的數據多特征分類預測(多輸入單輸出)

Matlab實現BiTCN-BiGRU基于雙向時間卷積網絡結合雙向門控循環單元的數據多特征分類預測&#xff08;多輸入單輸出&#xff09; 目錄 Matlab實現BiTCN-BiGRU基于雙向時間卷積網絡結合雙向門控循環單元的數據多特征分類預測&#xff08;多輸入單輸出&#xff09;分類效果基本描述…

云備份項目--工具類編寫

4. 文件工具類的設計 4.1 整體的類 該類實現對文件進行操作 FileUtil.hpp如下 /* 該類實現對文件進行操作 */ #pragma once #include <iostream> #include <string> #include <fstream> #include <vector> #include <sys/types.h> #include …

51c大模型~合集94

我自己的原文哦~ https://blog.51cto.com/whaosoft/12897659 #D(R,O) Grasp 重塑跨智能體靈巧手抓取&#xff0c;NUS邵林團隊提出全新交互式表征&#xff0c;斬獲CoRL Workshop最佳機器人論文獎 本文的作者均來自新加坡國立大學 LinS Lab。本文的共同第一作者為上海交通大…

【大學英語】英語范文十八篇,書信,議論文,材料分析

關注作者了解更多 我的其他CSDN專欄 過程控制系統 工程測試技術 虛擬儀器技術 可編程控制器 工業現場總線 數字圖像處理 智能控制 傳感器技術 嵌入式系統 復變函數與積分變換 單片機原理 線性代數 大學物理 熱工與工程流體力學 數字信號處理 光電融合集成電路…

一起學Git【第一節:Git的安裝】

Git是什么&#xff1f; Git是什么&#xff1f;相信大家點擊進來已經有了初步的認識&#xff0c;這里就簡單的進行介紹。 Git是一個開源的分布式版本控制系統&#xff0c;由Linus Torvalds創建&#xff0c;用于有效、高速地處理從小到大的項目版本管理。Git是目前世界上最流行…

消息隊列 Kafka 架構組件及其特性

Kafka 人們通常有時會將 Kafka 中的 Topic 比作隊列&#xff1b; 在 Kafka 中&#xff0c;數據是以主題&#xff08;Topic&#xff09;的形式組織的&#xff0c;每個 Topic 可以被分為多個分區&#xff08;Partition&#xff09;。每個 Partition 是一個有序的、不可變的消息…

《Mycat核心技術》第06章:Mycat問題處理總結

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章匯總&#xff1a;https://binghe.gitcode.host/md/all/all.html 星球項目地址&#xff1a;https://binghe.gitcode.host/md/zsxq/introduce.html 沉淀&#xff0c…

【day11】面向對象編程進階(繼承)

概述 本文深入探討面向對象編程的核心概念&#xff0c;包括繼承、方法重寫、this和super關鍵字的使用&#xff0c;以及抽象類和方法的定義與實現。通過本文的學習&#xff0c;你將能夠&#xff1a; 理解繼承的優勢。掌握繼承的使用方法。了解繼承后成員變量和成員方法的訪問特…

隨手記:小程序兼容后臺的wangEditor富文本配置鏈接

場景&#xff1a; 在后臺配置wangEditor富文本&#xff0c;可以文字配置鏈接&#xff0c;圖片配置鏈接&#xff0c;產生的json格式為&#xff1a; 例子&#xff1a; <h1><a href"https://uniapp.dcloud.net.cn/" target"_blank"><span sty…

6.8 Newman自動化運行Postman測試集

歡迎大家訂閱【軟件測試】 專欄&#xff0c;開啟你的軟件測試學習之旅&#xff01; 文章目錄 1 安裝Node.js2 安裝Newman3 使用Newman運行Postman測試集3.1 導出Postman集合3.2 使用Newman運行集合3.3 Newman常用參數3.4 Newman報告格式 4 使用定時任務自動化執行腳本4.1 編寫B…

工具環境 | 工具準備

搭建一套驗證環境需要的工具如下&#xff1a; 虛擬機&#xff1a;推薦virtualbox ubuntu VM好用&#xff0c;但是免費的好像木有了&#xff0c;ubuntu界面版更加容易上手。 網上找安裝教程即可&#xff0c;注意實現文件共享、復制粘貼等功能。 EDA&#xff1a;VCS Veridi 工…

計算機網絡之王道考研讀書筆記-2

第 2 章 物理層 2.1 通信基礎 2.1.1 基本概念 1.數據、信號與碼元 通信的目的是傳輸信息。數據是指傳送信息的實體。信號則是數據的電氣或電磁表現&#xff0c;是數據在傳輸過程中的存在形式。碼元是數字通信中數字信號的計量單位&#xff0c;這個時長內的信號稱為 k 進制碼…

ROS2學習配套C++知識

第3章 訂閱和發布——話題通信探索 3.3.1 發布速度控制海龜畫圓 std::bind cstd::bind綁定成員函數時&#xff0c;需要加上作用域以及取址符號 因為不會將成員函數隱式的轉換成指針&#xff0c;因此需要加&符號&#xff1b; 后面的第一個參數必須跟具體對象&#xff0c;c…