目前為止學(xué)了分支,循環(huán),數(shù)組和函數(shù),現(xiàn)在利用這些知識(shí)來(lái)寫(xiě)一個(gè)三子棋小游戲來(lái)鞏固加深所學(xué)哈哈哈
目錄
這就是游戲的整個(gè)過(guò)程,接下來(lái)我將慢慢講解整個(gè)工程是如何實(shí)現(xiàn)的~
?
我創(chuàng)建了三個(gè)文件,先在game.c文件里放函數(shù)的實(shí)現(xiàn),然后在頭文件game.h中放這些函數(shù)的聲明,這樣在test.c文件中就可以直接引用頭文件game.c中的函數(shù)啦,這樣能保證主函數(shù)邏輯清晰,簡(jiǎn)單易懂。游戲的實(shí)現(xiàn)主要分這么幾個(gè)步驟:打印菜單,初始化棋盤(pán),打印棋盤(pán),玩家下棋,電腦下棋,判斷輸贏。
這個(gè)很簡(jiǎn)單,就不過(guò)多贅述啦,直接上代碼
void menu(){ printf("----------- 菜單 ------------/n"); printf("***********1、play************/n"); printf("***********0、exit************/n"); printf("------------------------------/n");}
?
這個(gè)我是創(chuàng)建了一個(gè)二維數(shù)組board[ROW][COL]來(lái)模擬一個(gè)ROW行,COL列的棋盤(pán),將數(shù)組的行和列定義為全局變量是為了方便改棋盤(pán)的大小。我最初是將這個(gè)二維數(shù)組全部初始化為空格。
void Init(char board[ROW][COL])//將棋盤(pán)初始化為空格{ int i = 0; int j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) board[i][j] = " "; }}
打印棋盤(pán)之前一定要將初始化后的棋盤(pán)進(jìn)行修飾哈,不然你就看不到你打印的棋盤(pán)啦,這樣還怎么玩游戲呢~
void DisplayBoard(char board[ROW][COL]){ int i = 0; int j = 0; for (j = 0; j < ROW; j++) { for (i = 0; i < COL; i++) { printf(" %c ",board[j][i]); if(i
下面就是這段代碼所對(duì)應(yīng)的棋盤(pán)啦
棋盤(pán)打印好之后相當(dāng)于準(zhǔn)備工作就做好了,接下來(lái)就是玩家與電腦的博弈啦。
首先是玩家下棋,“*”代表玩家,先由玩家輸入第幾行第幾列,落子之前,系統(tǒng)要先判斷該位置是否不被占用,輸入是否合法,只有都滿足才能落子,否則就要重新輸入,下面是代碼實(shí)現(xiàn):
void player_move(char board[ROW][COL]){ int i = 0; int j = 0; while (1) { scanf("%d %d", &i, &j); if (i >= 0 && i < ROW && j >= 0 && j < COL) { if (board[i][j] == " ") { board[i][j] = "*"; DisplayBoard(board); return; } else printf("該位置已被占用,請(qǐng)重新輸入! "); } else printf("輸入不合法,請(qǐng)重新輸入!"); }}
?
這里就不得不說(shuō)一下實(shí)現(xiàn)人工智能是真的有點(diǎn)難度,我最開(kāi)始寫(xiě)電腦落子的時(shí)候是直接利用srand()和rand()函數(shù)來(lái)隨機(jī)生成兩個(gè)數(shù)作為落子的坐標(biāo)的,后來(lái)發(fā)現(xiàn)寫(xiě)出來(lái)的游戲整個(gè)就一人工智障,然后稍稍改變了電腦下棋這一部分函數(shù),才讓電腦學(xué)會(huì)堵玩家的棋子,而不是只是單單隨便下了。電腦落子前我是先讓它判斷是否有某一行或某一列或?qū)蔷€上已經(jīng)有2個(gè)玩家落的棋子了,如果有,則直接將電腦的棋子落在相應(yīng)的位置上去堵玩家,如果沒(méi)有在去隨機(jī)生成2個(gè)數(shù)去確定自己的位置(我還沒(méi)有實(shí)現(xiàn)怎么讓電腦除了堵別人還有自己的走法),要不怎么說(shuō)人工智能難呢,我們還是來(lái)看看這部分是怎么實(shí)現(xiàn)的吧
void computer_move(char board[ROW][COL]){ while (1) { int i = 0; int j = 0; for (i = 0; i < ROW; i++)//判斷一行中是否有兩個(gè)相同的 { if (board[i][0] == " "&&board[i][1] == board[i][2] && board[i][1] !=" " || board[i][1] == " " && board[i][0] == board[i][2] && board[i][0] != " " || board[i][2] == " " && board[i][1] == board[i][0] && board[i][1] != " ") { for (j = 0; j < COL; j++) { if (board[i][j] == " ") { board[i][j] = "#"; DisplayBoard(board); return; } } } } for (i = 0; i < ROW; i++)//判斷一列中是否有兩個(gè)相同的 { if (board[0][i] == " "&&board[1][i] == board[2][i] && board[1][i]!=" " || board[1][i] == " " && board[0][i] == board[2][i] && board[0][i] != " " || board[2][i] == " " && board[0][i] == board[1][i] && board[0][i] != " ")//判斷列 { for (j = 0; j < COL; j++) { if (board[j][i] == " ") { board[j][i] = "#"; DisplayBoard(board); return; } } } } //判斷主對(duì)角線中是否有兩個(gè)相同的 if (board[1][1] != " " && board[2][2] == board[1][1] || board[0][0] != " " && board[0][0] == board[1][1] || board[2][2] != " " && board[0][0] == board[2][2]) { for (j= 0; j < ROW; j++) { if (board[j][j] == " ") { board[j][j] = "#"; DisplayBoard(board); return; } } } //判斷副對(duì)角線是否有兩個(gè)相同的 if (board[2][0] != " " && board[2][0] == board[0][2] || board[1][1] !=" " && board[1][1] == board[2][0] || board[1][1] !=" " && board[1][1] == board[0][2]) { for (j = 0; j < ROW; j++) { if (board[2 - j][j] == " ") { board[2 - j][j] = "#"; DisplayBoard(board); return; } } } //隨機(jī)下棋 int a = rand() % ROW; int b = rand() % COL; if (board[a][b] == " ") { board[a][b] = "#"; DisplayBoard(board); break; } }}
玩家下棋和電腦下棋是放在一個(gè)循環(huán)里面的,直到三子連線或棋盤(pán)被下滿嘛,接下來(lái)的一步就是判斷輸贏啦
這個(gè)主要就是用循環(huán)來(lái)寫(xiě),判斷一行或一列或?qū)蔷€上的字符都是同一個(gè)且不是空格就可以決出勝負(fù)啦,然后返回對(duì)應(yīng)的字符稍加判斷就可以知道誰(shuí)是贏家啦。當(dāng)然,如果棋盤(pán)滿了也就是沒(méi)有二位數(shù)組中空格且沒(méi)有三子連線就可以判為平局。看代碼:
int ful_board(char board[ROW][COL])//判斷棋盤(pán)是否滿{ 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 win(char board[ROW][COL])//判斷輸贏{ int i = 0; int j = 0; for (j = 0; j < COL; j++) { if (board[0][j] == board[1][j] && board[0][j] == board[2][j]&& board[0][j] != " ")//判斷列 return board[0][j]; } for (j = 0; j < COL; j++) { if (board[j][0] == board[j][1] && board[j][0] == board[j][2]&& board[j][0] != " ")//判斷行 return board[j][0]; } if (board[0][0] == board[1][1] && board[0][0]==board[2][2] && board[0][0] != " ") { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&& board[0][2] != " ") { return board[1][1]; } if (1 == ful_board(board)) return "P"; return 0;}
以上就是各個(gè)函數(shù)的具體實(shí)現(xiàn)了,我是把這些函數(shù)大都放在game.c中,然后在game.c中聲明它們,最后在test.c中測(cè)試時(shí)就可以直接引用頭文件game.c啦,接下來(lái)就讓我們來(lái)看看整個(gè)完整的代碼~~
#include#include#include void menu();//打印菜單#define ROW 3//全局變量,3行#define COL 3//3列void DisplayBoard(char board[ROW][COL]);//打印棋盤(pán)void Init(char board[ROW][COL]);//初始化棋盤(pán)void player_move(char board[ROW][COL]);//玩家下棋void computer_move(char board[ROW][COL]);//電腦下棋char win(char board[ROW][COL]);//判斷輸贏int ful_board(char board[ROW][COL]);//判斷棋盤(pán)是否滿
#define _CRT_SECURE_NO_WARNING#include"game.h"void menu(){ printf("----------- 菜單 ------------/n"); printf("***********1、play************/n"); printf("***********0、exit************/n"); printf("------------------------------/n");}void Init(char board[ROW][COL])//將棋盤(pán)初始化為空格{ int i = 0; int j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) board[i][j] = " "; }}void DisplayBoard(char board[ROW][COL])//打印棋盤(pán){ int i = 0; int j = 0; for (j = 0; j < ROW; j++) { for (i = 0; i < COL; i++) { printf(" %c ",board[j][i]); if(i= 0 && i < ROW && j >= 0 && j < COL) { if (board[i][j] == " ") { board[i][j] = "*"; DisplayBoard(board); return; } else printf("該位置已被占用,請(qǐng)重新輸入! "); } else printf("輸入不合法,請(qǐng)重新輸入!"); }}void computer_move(char board[ROW][COL])//電腦下棋{ while (1) { int i = 0; int j = 0; for (i = 0; i < ROW; i++)//判斷一行中是否有兩個(gè)相同的 { if (board[i][0] == " "&&board[i][1] == board[i][2] && board[i][1] !=" " || board[i][1] == " " && board[i][0] == board[i][2] && board[i][0] != " " || board[i][2] == " " && board[i][1] == board[i][0] && board[i][1] != " ") { for (j = 0; j < COL; j++) { if (board[i][j] == " ") { board[i][j] = "#"; DisplayBoard(board); return; } } } } for (i = 0; i < ROW; i++)//判斷一列中是否有兩個(gè)相同的 { if (board[0][i] == " "&&board[1][i] == board[2][i] && board[1][i]!=" " || board[1][i] == " " && board[0][i] == board[2][i] && board[0][i] != " " || board[2][i] == " " && board[0][i] == board[1][i] && board[0][i] != " ")//判斷列 { for (j = 0; j < COL; j++) { if (board[j][i] == " ") { board[j][i] = "#"; DisplayBoard(board); return; } } } } //判斷主對(duì)角線中是否有兩個(gè)相同的 if (board[1][1] != " " && board[2][2] == board[1][1] || board[0][0] != " " && board[0][0] == board[1][1] || board[2][2] != " " && board[0][0] == board[2][2]) { for (j= 0; j < ROW; j++) { if (board[j][j] == " ") { board[j][j] = "#"; DisplayBoard(board); return; } } } //判斷副對(duì)角線是否有兩個(gè)相同的 if (board[2][0] != " " && board[2][0] == board[0][2] || board[1][1] !=" " && board[1][1] == board[2][0] || board[1][1] !=" " && board[1][1] == board[0][2]) { for (j = 0; j < ROW; j++) { if (board[2 - j][j] == " ") { board[2 - j][j] = "#"; DisplayBoard(board); return; } } } //隨機(jī)下棋 int a = rand() % ROW; int b = rand() % COL; if (board[a][b] == " ") { board[a][b] = "#"; DisplayBoard(board); break; } }}int ful_board(char board[ROW][COL])//判斷棋盤(pán)是否滿{ 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 win(char board[ROW][COL])//判斷輸贏{ int i = 0; int j = 0; for (j = 0; j < COL; j++) { if (board[0][j] == board[1][j] && board[0][j] == board[2][j]&& board[0][j] != " ")//判斷列 return board[0][j]; } for (j = 0; j < COL; j++) { if (board[j][0] == board[j][1] && board[j][0] == board[j][2]&& board[j][0] != " ")//判斷行 return board[j][0]; } if (board[0][0] == board[1][1] && board[0][0]==board[2][2] && board[0][0] != " ") { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&& board[0][2] != " ") { return board[1][1]; } if (1 == ful_board(board)) return "P"; return 0;}
#define _CRT_SECURE_NO_WARNINGS #include"game.h"void game(){ char board[ROW][COL] = { 0 }; char ret = 0; srand((unsigned int)time(NULL));//設(shè)置隨機(jī)種子數(shù) Init(board);//初始化棋盤(pán) DisplayBoard(board);//裝飾棋盤(pán) while (1) { player_move(board);//玩家下棋 ret = win(board);//判斷勝負(fù) if (ret == "*") { printf("恭喜你,獲勝了!??!/n"); break; } if (ret == "P") { printf("平局!??!/n"); break; } computer_move(board);//電腦下棋 ret = win(board); if (ret == "#") { printf("很遺憾,你輸了?。?!/n"); break; } if (ret == "P") { printf("平局!??!"); break; } }}void test(){ int input = 0; do { menu(); scanf("%d", &input); switch (input) { case 1: printf("三子棋/n"); game(); break; case 0: printf("退出游戲/n"); break; default: printf("輸入不合法,請(qǐng)重新輸入!/n"); break; } } while (input);}int main(){ test(); return 0;}
?
到這里就結(jié)束啦,接下來(lái)我還會(huì)寫(xiě)一個(gè)掃雷的小游戲的哈哈哈,最后看完的小伙伴給個(gè)贊吧
?
?
?
?
?
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/123072.html
摘要:前言本篇文章記錄了用語(yǔ)言實(shí)現(xiàn)三子棋小游戲,主要目的是對(duì)之前語(yǔ)言知識(shí)學(xué)習(xí)的鞏固,聯(lián)系各個(gè)知識(shí),以及怎么樣實(shí)際使用各個(gè)知識(shí)。效果顯示函數(shù)當(dāng)玩家輸入時(shí),跳入到游戲的實(shí)現(xiàn)代碼之中。這里調(diào)用了函數(shù),實(shí)現(xiàn)代碼如下由于在這里強(qiáng)制轉(zhuǎn)化為正整數(shù)。 前言 本篇文章記錄了用C語(yǔ)言實(shí)現(xiàn)三子棋小游戲,主要目...
摘要:每成功排一次雷,我們都要展示雷盤(pán)當(dāng)場(chǎng)上剩下的格子數(shù)等于雷數(shù)時(shí),游戲勝利,玩家踩雷時(shí),游戲結(jié)束,所以我們這是一個(gè)判斷輸贏的函數(shù)。 前言:寫(xiě)完三子棋后,慢慢地熟悉了這種...
摘要:三子棋三子棋游戲介紹規(guī)則游戲設(shè)計(jì)思路代碼分析文件代碼分析。玩家下棋實(shí)現(xiàn)。三子棋是一種民間傳統(tǒng)游戲,又叫九宮棋圈圈叉叉一條龍井字棋等。落子后打印棋盤(pán)以顯示。假設(shè)平局時(shí)判定輸贏的函數(shù)返回后面代碼實(shí)現(xiàn)時(shí)詳細(xì)講。 ...
摘要:簡(jiǎn)單介紹了三子棋原理后接下來(lái)為大家講解分步目標(biāo)及代碼如何實(shí)現(xiàn)。電腦下棋我們實(shí)現(xiàn)了玩家和電腦的下棋后,我們需要編寫(xiě)一個(gè)函數(shù)來(lái)判斷雙方的輸贏。我們使用函數(shù)來(lái)實(shí)現(xiàn)這一目標(biāo)。 目錄 1.三子棋原理 2.分塊代碼實(shí)現(xiàn) 3.總結(jié) 1.首先向大家介紹一下三子棋的原理 首先我們需要有一個(gè)棋盤(pán),初始時(shí)棋...
摘要:三子棋目錄一問(wèn)題介紹三子棋,在民間又叫井字棋。因?yàn)槿藗冊(cè)谟瓮鏁r(shí)常常不畫(huà)棋盤(pán)的邊框,正如漢字中的井字,多稱為井字棋。 三子棋 目錄 一、問(wèn)題介紹 ? ? ? ? 三子棋,在民間又叫井字棋。因?yàn)槿藗冊(cè)谟瓮鏁r(shí)常常不畫(huà)棋盤(pán)的邊框,正如漢字中的井字,多稱為井字棋。 三子棋的游戲規(guī)則十分的簡(jiǎn)單: ...
閱讀 2661·2021-11-11 16:55
閱讀 1292·2021-09-22 15:25
閱讀 1809·2019-08-29 16:26
閱讀 994·2019-08-29 13:21
閱讀 2318·2019-08-23 16:19
閱讀 2806·2019-08-23 15:10
閱讀 790·2019-08-23 14:24
閱讀 1863·2019-08-23 13:48