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