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