用C語言實(shí)現(xiàn)井字棋游戲代碼
前言
我們都玩過或見過這樣一種簡單地下棋游戲,兩位玩家在一個(gè)井字形狀的棋盤上,用‘*’和‘#’來下棋,獲勝條件是橫豎斜任意一列三子成列。那如何在C語言怎么寫一個(gè)簡單地黑框框里運(yùn)行的井字棋呢,我們在接下來開始從0實(shí)施這一工程。
首先得確定程序?qū)崿F(xiàn)的功能
在寫代碼時(shí)列出需求方便我們后面實(shí)現(xiàn)它們。
菜單界面棋盤打印
棋子存儲(chǔ)采用二維數(shù)組。
因?yàn)橛螒蚴强梢赃x擇玩完一局接著再來一局的重復(fù)進(jìn)行,不退出游戲數(shù)組里的數(shù)據(jù)就會(huì)帶到下一輪,所以每下完重開一局就需要初始化棋盤,這個(gè)特別簡單,可以用循環(huán)往數(shù)組里寫入空格,在這就不贅述了。玩家下棋電腦下棋(智障下棋版,毫無智能)判斷輸贏
判斷輸贏算是這個(gè)項(xiàng)目里的一個(gè)難點(diǎn),有很多方式,這里用了最簡單粗暴的辦法,寫兩個(gè)for循環(huán)判斷橫豎是否相同且不為空,和兩個(gè)if判斷兩條斜邊,并返回里面的內(nèi)容,‘ * ’ 玩家贏,‘ # ’ 電腦贏,但是這樣也有弊端,導(dǎo)致了這串代碼參數(shù)寫死了,只能判斷三乘三內(nèi)的三個(gè)橫豎列是否相連。
直接上代碼:
頭文件
#pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 3//定義棋盤長寬為 3 #define COL 3 void menu(); void game(); void Initboard(char board[ROW][COL], int row, int col);//初始化棋盤 棋子位置都為空格 void DisplayBoard(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);//電腦下棋 int IsWin(char board[ROW][COL], int row, int col);//判斷輸贏
在寫程序時(shí),盡量讓代碼分工獨(dú)立,不定死其中之后可以預(yù)測到能改變的參數(shù),如棋盤長寬值,方便之后對(duì)代碼優(yōu)化改造與二次使用(比如說之前寫過的函數(shù)代碼,盡量使其獨(dú)立的實(shí)現(xiàn)某一單一功能(高內(nèi)聚低耦合),再之后有相同需求時(shí)可以直接使用)
1. 菜單界面
void menu() {//打印菜單界面 printf("*********************************\n"); printf("********** 1.play **********\n"); printf("********** 0.exit **********\n"); printf("*********************************\n"); }
void game() { //游戲過程 char board[ROW][COL];//創(chuàng)建棋盤數(shù)組 Initboard(board, ROW, COL);//初始化棋盤 棋子位置都為空格 DisplayBoard(board, ROW, COL);//打印棋盤 //下棋 char ret = 0; while (1) { PlayerMove(board, ROW, COL);//玩家下棋 DisplayBoard(board, ROW, COL);//打印棋盤 ret = IsWin(board, ROW, COL);//判斷輸贏 if (ret != 'C') { break; } ComputerMove(board, ROW, COL);//電腦下棋 DisplayBoard(board, ROW, COL);//打印棋盤 ret = IsWin(board, ROW, COL);//判斷輸贏 if (ret != 'C') { break; } } if (ret == '*') { printf("玩家贏\n"); } else if (ret == '#') { printf("電腦贏\n"); } else { printf("平局\n"); } }//我們在這里判斷輸贏函數(shù)返回四種狀態(tài) //返回‘C'繼續(xù)下棋循環(huán),返回‘*'玩家贏,返回‘#'電腦贏,返回‘P'平局 //平局判定還需要判斷棋盤是否下滿,后面說。
int main() { char input = 0;//定義菜單選擇值 do { menu();//打印菜單 printf("請(qǐng)選擇>"); scanf("%c", &input);//獲取選擇值 switch(input) { case '1'://開始游戲 printf("三子棋\n"); getchar();//清除緩存區(qū) game();//游戲過程 break; case '0'://退出游戲 getchar(); printf("退出游戲\n"); break; default://輸入其他東西時(shí) getchar(); printf("輸入錯(cuò)誤\n"); break; } } while (input!='0');//非0數(shù)字為真 0為假 return 0; }
2. 棋盤打印
void DisplayBoard(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) { for (j = 0; j < col; j++) { printf("---"); if (j < col - 1) { printf("|"); } } printf("\n"); } } }
打印出來效果
| | --|--|-- --|--|-- | |
3. 玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)//玩家下棋 { printf("玩家走:>\n"); int x = 0; int y = 0; while (1) { printf("請(qǐng)輸入坐標(biāo)>:");//玩家輸入1~ROW;1~COL對(duì)應(yīng)數(shù)組底標(biāo)row-1;col-1 scanf("%d %d", &x, &y); getchar(); if (((x >= 1) && (x <= row)) && ((y >= 1) && (y <= col))) { if (board[x-1][y-1]==' ') { board[x - 1][y - 1] = '*'; break; } else { printf("該位置已有棋子,請(qǐng)重新輸入\n"); } } else { printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n"); } } }
4. 電腦下棋(智障下棋版,毫無智能)
void ComputerMove(char board[ROW][COL], int row, int col)//電腦下棋 { printf("電腦走:>\n"); int x = 0; int y = 0; srand((unsigned int)time(NULL)); while (1) { //電腦隨機(jī)生成坐標(biāo) x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } else { //該位置已有棋子,重新生成 } } }
這是最簡易版本的隨機(jī)下棋,言外之意就是電腦沒有智商隨機(jī)下棋,后續(xù)還可以改進(jìn)。
5. 判斷輸贏
int 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][2]!=' ')) { return board[i][0]; } } //判斷列 for (i = 0; i < row; i++) { if ((board[0][i] == board[1][i]) && (board[1][i] == board[2][i]) && (board[2][i] != ' ')) { return board[0][i]; } } //判斷對(duì)角線 if ((board[0][0] == board[1][1]) && (board[1][1] == board[2][2]) && (board[2][2] != ' ')) { return board[1][1]; } if ((board[0][2] == board[1][1]) && (board[1][1] == board[2][0]) && (board[2][0] != ' ')) { return board[1][1]; } if (IsFull(board, row, col))//如果棋盤滿了還未分出勝負(fù),那么久平局 { return 'P'; } return 'C'; }
這里還需要一個(gè)判斷棋盤是否滿了的函數(shù)
int IsFull(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++) { if (board[i][j] == ' ') return 0; } } return 1; }
搞定
目前我們搞定了所有的功能,編譯運(yùn)行一下:
總結(jié)
到此這篇關(guān)于用C語言實(shí)現(xiàn)井字棋游戲代碼的文章就介紹到這了,更多相關(guān)C語言井字棋內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
OpenCV c++滑動(dòng)條的創(chuàng)建和使用代碼
滾動(dòng)條(Trackbar)在OpenCV中是非常方便的交互工具,它依附于特定的窗口而存在,下面這篇文章主要給大家介紹了關(guān)于OpenCV?c++滑動(dòng)條的創(chuàng)建和使用的相關(guān)資料,需要的朋友可以參考下2023-06-06CreateCompatibleDC()函數(shù)案例詳解
這篇文章主要介紹了CreateCompatibleDC()函數(shù)案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08Qt實(shí)現(xiàn)界面滑動(dòng)切換效果的思路詳解
這篇文章主要介紹了Qt實(shí)現(xiàn)界面滑動(dòng)切換效果,主要包括設(shè)計(jì)思路及主要函數(shù)講解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07win10環(huán)境下vscode Linux C++開發(fā)代碼自動(dòng)提示配置(基于WSL)
這篇文章主要介紹了win10環(huán)境下vscode Linux C++開發(fā)代碼自動(dòng)提示配置(基于WSL),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05詳解Visual Studio 2019(VS2019) 基本操作
這篇文章主要介紹了詳解Visual Studio 2019(VS2019) 基本操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03基于QT實(shí)現(xiàn)自定義溫度計(jì)的示例代碼
QT原生控件沒有實(shí)現(xiàn)如儀表盤或者溫度計(jì)的控件,只好自己實(shí)現(xiàn),所以本文為大家介紹了如何利用qt實(shí)現(xiàn)自定義溫度/濕度控件,感興趣的小伙伴可以了解下2023-11-11