前言
今天牛牛給大家分享的是c語言實(shí)現(xiàn)三子棋和五子棋游戲,初學(xué)者可能有些不理解的地方,記得私信提問哦,牛牛會一 一回答的。
一、游戲介紹
《三子棋》是一款益智小游戲,通常是在九宮格里面玩,所以也被稱為”九宮棋“或”井字棋“。
游戲規(guī)則也極其簡單,只要三子相連即可獲勝。
例如:

c語言實(shí)現(xiàn)效果圖:
三子棋:
五子棋:
二、游戲設(shè)計思路
分為三個模塊化實(shí)現(xiàn):
1.主函數(shù)測試區(qū)(test.c):用于打印菜單、實(shí)現(xiàn)調(diào)用游戲要使用的各種函數(shù)、退出游戲等功能。
重點(diǎn)在于其中的game函數(shù)()。
2.函數(shù)聲明區(qū)(game.h):用于各種庫函數(shù)、自定義函數(shù)的聲明。
3.函數(shù)實(shí)現(xiàn)區(qū)(game.c):用于各種函數(shù)功能的具體的實(shí)現(xiàn)。
1. 菜單界面選擇開始或者退出游戲。
2. 玩家選擇游戲類型:1.三子棋 2.五子棋
3. 玩家選擇棋盤大小。
4. 創(chuàng)建棋盤并初始化.打印棋盤。(打印初始化后的棋盤)。
5. 玩家落子(玩家輸入行列坐標(biāo)的方式來落子),'*’表示玩家落子。(注意坐標(biāo)合法性)
6. 打印棋盤(玩家落子后的棋盤)。
7. 判定勝負(fù)關(guān)系(輸,贏,和棋),'p’表示平局。.
8.電腦落子(隨機(jī)位置落子) ,'#’表示電腦落子。
9. 打印棋盤(電腦落子后的棋盤)
10.判定輸贏情況。
2.1 主函數(shù)測試區(qū)(test.c)基本構(gòu)成
2.11 創(chuàng)建游戲菜單
可用printf打印一個簡易菜單,讓玩家選擇。
//在主函數(shù)測試區(qū)(test.c)
void menu()
{
printf("*******************************************************************\n");
printf("************ * *************\n");
printf("****************** * *****************\n");
printf("************************ * ***********************\n");
printf("******************************* * ******************************\n");
printf("******** 1.玩游戲 * 2.退出游戲 *********\n");
printf("******************************* * ******************************\n");
printf("************************ * ***********************\n");
printf("****************** * *****************\n");
printf("************ * ************\n");
printf("*******************************************************************\n");
printf("請選擇:\n");
}
2.12 主測試區(qū)基本框架
通過switch語句來實(shí)現(xiàn)根據(jù)玩家選擇結(jié)果來調(diào)用game函數(shù)
int main()
{
int n = 0;//記錄玩家在菜單中的選擇
srand((unsigned int)time(NULL));//與前面介紹的猜數(shù)字游戲一樣,改變種子值來使得rand函數(shù)每次生成不同的隨機(jī)數(shù)列。用于后面的電腦下棋
do
{
menu();
scanf("%d", &n);//讓玩家在菜單中選擇
switch (n)
{
case 1://代表玩游戲
game();//這個是重點(diǎn)函數(shù)
printf("再來一局嗎?\n");//游戲結(jié)束后
printf("1.再來一局 2. 沒意思不玩了\n");
int again = 0;//存放玩家是否再玩的結(jié)果。
scanf("%d", &again);
if (again == 1)
{
break;
}
else
n = 2;//令n=2循環(huán)結(jié)束
break;
case 2:
printf("退出游戲");
break;
default:
printf("沒有這個選項哦。\n");//玩家不小心輸錯了
break;
}
} while (n - 2);//當(dāng)玩家選擇2時,代表不玩了
}
2.2 game函數(shù)的實(shí)現(xiàn)(在主函數(shù)測試區(qū)(test.c))
1. 玩家選擇游戲類型:1.三子棋 2.五子棋
2. 玩家選擇棋盤大小。
3. 創(chuàng)建棋盤并初始化.打印棋盤。(打印初始化后的棋盤)。
4. 玩家落子(玩家輸入行列坐標(biāo)的方式來落子),'*’表示玩家落子。(注意坐標(biāo)合法性)
5. 打印棋盤(玩家落子后的棋盤)。
6. 判定勝負(fù)關(guān)系(輸,贏,和棋),'p’表示平局。.
7.電腦落子(隨機(jī)位置落子) ,'#’表示電腦落子。
8. 打印棋盤(電腦落子后的棋盤)
9.判定輸贏情況。
2.21 棋盤的創(chuàng)建:
創(chuàng)建一個大小為15行15列的二維數(shù)組(可修改,不建議太大)用于存放棋子。
這里使用宏定義是為了方便改變棋盤的最大大小,下次需要修改的時候只需要修改這里就行,不需要每個函數(shù)都一 一去改。
//函數(shù)聲明區(qū)(game.h)
#define ROW 15//為了方便改變棋盤大小
#define COL 15
//game函數(shù)的實(shí)現(xiàn)(在主函數(shù)測試區(qū)(test.c))
void game()
{
printf("歡迎玩家進(jìn)入游戲:\n");
int gametype = 0;//游戲類型
int boardtype = 0;//棋盤大小的確定
again://玩家選擇錯誤后返回到此處
printf("請選擇游戲類型: 1.三子棋游戲(建議3*3的棋盤) 2.五子棋游戲\n");
scanf("%d", &gametype);//讓玩家選擇游戲類型
if (gametype != 1 && gametype != 2)//玩家選擇錯誤給出提示,并重新選擇
{
printf("選擇錯誤,牛牛還未開發(fā)此類型游戲。\n");
printf("請重新選擇:\n");
goto again;//跳轉(zhuǎn)到again語句處
}
printf("請選擇棋盤類型:n*n,你希望n的值為多少?(1<n<15)\n");
scanf("%d", &boardtype);//得到玩家想要的棋盤大小
if (gametype == 2 && boardtype < 5 || gametype == 1 && boardtype < 3)//避免選五子棋的棋盤小于5*5,和三子棋小于3*3的棋盤
{
printf("棋盤不符合要求:請重新選擇:\n");
goto again;//跳轉(zhuǎn)到again語句處
}
else if (boardtype > ROW)//選擇的棋盤最大不得超過15*15
{
printf("超出棋盤最大設(shè)置范圍(15*15):\n請重新選擇:\n");
goto again;//跳轉(zhuǎn)到again語句處
}
char board[ROW][COL] = { 0 };//定義一個2維數(shù)組,最大為15*15,用于存放棋子
char ret = 0;//設(shè)置判斷輸贏的返回值。
//打印數(shù)組的元素
init_board(board, ROW, COL);//初始化棋盤,使其值全為空格
print_board(board, boardtype, boardtype);//打印棋盤的外觀和內(nèi)容
while (1)//游戲開始
{
palyer(board, boardtype, boardtype);//玩家下棋
print_board(board, boardtype, boardtype);//打印棋盤
if (gametype == 1)//根據(jù)類型現(xiàn)在判斷輸贏的類型
{
ret = who_win3(board, boardtype, boardtype);//三子棋判斷輸贏
}
else
ret = who_win5(board, boardtype, boardtype);//五子棋判斷輸贏
if (ret != 'c')
{
break;
}
computer(board, boardtype, boardtype);//電腦下棋
print_board(board, boardtype, boardtype);//打印棋盤
if (gametype == 1)//根據(jù)類型現(xiàn)在判斷輸贏的類型
{
ret = who_win3(board, boardtype, boardtype);//三子棋判斷輸贏
}
else
ret = who_win5(board, boardtype, boardtype);//五子棋判斷輸贏
if (ret != 'c')
{
break;
}
}
if (ret == '*')
{
printf("玩家勝利\n");
}
else if (ret == '#')
{
printf("電腦勝利\n");
}
else
{
printf("平局\n");
}
}
補(bǔ)充知識:goto語句:用于跳轉(zhuǎn)到自己設(shè)定的語句處。
提示:雖然棋盤大小是用戶選擇,但其實(shí)并不是用戶選擇多大的棋盤就創(chuàng)建多大的棋盤,棋盤最大值已經(jīng)限定,只是在打印棋盤的時候,根據(jù)傳遞過去的參數(shù)要求打印棋盤的部分內(nèi)容。
例如:
玩家輸入:5,那么程序就只打印5×5的棋盤,但是棋盤的真實(shí)大小還是15×15,程序只是打印了其中的5行5列罷了(部分內(nèi)容)。
2.3函數(shù)實(shí)現(xiàn)區(qū)(game.c)
2.31 棋盤的初始化函數(shù)(init_board)
void init_board(char board[ROW][COL], int row, int col)//初始化棋盤
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';//初始化棋盤的內(nèi)容為全空格
}
}
}
2.32 棋盤的打印函數(shù)(print_board)
牛牛為了美觀,這里設(shè)計起來顯得有些繁瑣,但是牛牛會盡量解釋清楚的。
先看效果圖:

棋盤打印實(shí)現(xiàn)的分步講解:
分割行打印講解:(由于空格不能顯示,這里用口表示,棋子未輸入前用%c表示)
特殊:由于分割行總共有row+1行,所以我們可以先打印第一行,再循環(huán)打印后面的row行。
數(shù)據(jù)行打印講解:

行號和列標(biāo)的打印講解:
為了讓玩家更好的找到棋盤的對應(yīng)位置,我們可以打印行號和列標(biāo)來輔助。
只是苦了我們程序猿了,要加代碼來實(shí)現(xiàn)。
行號:可以在打印棋盤之前用for循環(huán)打印得到1到col之間的數(shù)字。
列標(biāo):則是每打印一行數(shù)據(jù)行,在前面加上行號。
打印棋盤函數(shù)代碼實(shí)現(xiàn):
//函數(shù)代碼實(shí)現(xiàn)區(qū)(game.c)
void print_board(char board[ROW][COL], int row, int col)//打印棋盤//建議參照棋盤的外觀查看代碼
{
int i = 0, j = 0;
printf(" ");//打印空格是為了對齊(因為下面的行號占用位置)
for (i = 1; i <= row; i++)//打印顯示在第一行的列標(biāo)
{
printf("%3d ",i);//因為一個數(shù)據(jù)行的格子占3個位置,所以我們這里用%3d占用三個位置的空間
}
printf("\n");//打印列標(biāo)后換行。
printf(" +");//先打印一個+,可以觀察棋盤外觀,將棋盤外觀拆分打印。//為了對齊加了一個空格,因為分割行前面沒有行號占用位置,只能補(bǔ)空格。
for (i = 0; i < row; i++)//打印第一行的分割線
{
printf("---+");//上圖講解了拆分過程。
}
printf("\n");//每次打印一行就要換行
for (i = 0; i < row; i++)
{
printf("%2d", i+1);//打印數(shù)據(jù)行前面的行號,%2d是因為當(dāng)行數(shù)>9的時候,兩位數(shù)會占用兩個位置,影響對齊。(細(xì)節(jié))
printf("|");//和上面一樣,先打印一個 | ,可以觀察棋盤外觀,將數(shù)據(jù)行拆分打印。
for (j = 0; j < col; j++)//打印一行中間的棋子和其它分割線
{
printf(" %c |", board[i][j]);//這里打印的是“空格”“棋子”“空格”“|”
}
printf("\n");//每次打印一行就要換行
//打印剩余的分割行
printf(" +");//先打印一個+,可以觀察棋盤外觀,將棋盤外觀拆分打印。//為了對齊加了一個空格
for (j = 0; j < col; j++)//打印一行外觀的分割線
{
printf("---+");//每次打印一行就要換行
}
printf("\n");
}
}
2.33 玩家下棋函數(shù)(palyer)
注意:此處的ROW(大寫)與row(小寫)大小不一定相同,ROW(大寫)是宏定義的15,而row(小寫)是由玩家選擇的。
void palyer(char board[ROW][COL], int row, int col)
{
int x = 0, y = 0;//定義x 和 y變量存儲棋子的坐標(biāo)
printf("請玩家下棋:\n");
while (1)
{
printf("請輸入行號和列標(biāo):(用空格隔開)\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= ROW && y >= 1 && y <= COL)//判斷坐標(biāo)是否合法,由于玩家并不是程序員,所以坐標(biāo)要正常從1開始
{
if (board[x - 1][y - 1] == ' ')//落子處為空格,表示此處還未被占用。x-1,y-1是因為2維數(shù)組的坐標(biāo)是從0開始的。
{
board[x - 1][y - 1] = '*';//玩家下棋為‘*’,將輸入的坐標(biāo)位置占據(jù)。
break;//表示落子成功,結(jié)束循環(huán),判斷輸贏后,輪到電腦下了
}
else//如果此處不是空格,則表示此處已經(jīng)有棋子了。
{
printf("該處已經(jīng)被占用了,請重新選擇\n");
}
}
else//如果坐標(biāo)不在1到row之間,則棋子超出合法范圍,
{
printf("該坐標(biāo)非法,已經(jīng)超過棋盤,無法識別\n");
printf("請重新選擇:\n");
}
}
}
2.33 電腦下棋函數(shù)(computer)
電腦下棋是隨機(jī)下棋,我們需要得到兩個隨機(jī)數(shù)作為電腦棋子的下標(biāo)。
void computer(char board[ROW][COL], int row, int col)//電腦下棋中
{
printf("電腦下棋中:\n");
while (1)
{
int x = rand() % row;//生成0到2的隨機(jī)數(shù)作為棋子下標(biāo)
int y = rand() % col;
if (board[x][y] == ' ')//找到棋盤中的空余位置進(jìn)行下棋
{
board[x][y] = '#';
break;
}
}
}
2.34 判斷是否平局函數(shù)(draw)
平局的判斷很簡單,當(dāng)棋盤上沒有空余棋子的時候,表示棋盤已經(jīng)滿了,并且沒有一方獲勝,則顯示平局。文章來源:http://www.zghlxwxcb.cn/news/detail-805370.html
int draw(char board[ROW][COL], int row, int col)//判斷平局
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;//如果還要一個空格,即表示棋盤還沒有滿
}
}
}
return 1;//棋盤滿了
}
2.35 三子棋的判斷輸贏函數(shù)(who_win3)

char who_win3(char board[ROW][COL], int row, int col)//三子棋判斷輸贏
{
int i = 0, j = 0;
for (i = 0; i < row; i++)//判斷每行,所以i要取0到row(不包含row)
{
for (j = 0; j + 2 < col; j++)
{
if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j] != ' ')
//判斷每行是否有相連的3個元素,并且不是空格
{
return board[i][j];
}
}
}
for (j = 0; j < col; j++)//判斷每列
{
for (i = 0; i + 2 < row; i++)
{
if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j] && board[i][j] != ' ')
//判斷每列是否有相連的3個元素,并且不是空格
{
return board[i][j];
}
}
}
for (i = 0; i + 2 < row; i++)//判斷主對角線和主對角線平行的線
{
for (j = 0; j + 2 < col; j++)
{
if (board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] && board[i][j] != ' ')//判斷主對角線和主對角線平行的線是否有三個相連,且不是空格
return board[i][j];
}
}
for (i = 2; i < row; i++)//判斷反對角線和與反對角線平行的線
{
for (j = 0; j + 2 < col; j++)
{
if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] && board[i][j] != ' ')//判斷反對角線和反對角線平行的線是否有三個相連,且不是空格
return board[i][j];
}
}
if (1 == draw(board, ROW, COL))
{
return 'p';
}
else
return 'c';
}
2.36 五子棋的判斷輸贏函數(shù)(who_win5)
char who_win5(char board[ROW][COL], int row, int col)//五子棋判斷輸贏
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)//判斷每行
{
for (j = 0; j + 4 < col; j++)
{
if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] == board[i][j + 3] && board[i][j + 3] == board[i][j + 4] && board[i][j] != ' ')/判斷每一行的是否有五個相連的元素,并且不是空格
return board[i][j];
}
}
for (j = 0; j < row; j++)//判斷每列
{
for (i = 0; i + 4 < row; i++)
{
if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j] && board[i + 2][j] == board[i + 3][j] && board[i + 3][j] == board[i + 4][j] && board[i][j] != ' ')//判斷每一列的是否有五個相連的元素,并且不是空格
return board[i][j];
}
}
for (i = 0; i + 4 < row; i++)//判斷主對角線和主對角線平行的線
{
for (j = 0; j + 4 < col; j++)
{
if (board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] && board[i + 2][j + 2] == board[i + 3][j + 3] && board[i + 3][j + 3] == board[i + 4][j + 4] && board[i][j] != ' ')//判斷主對角線和反對角線平行的線是否有五個相連,且不是空格
return board[i][j];
}
}
for (i = 4; i < row; i++)//判斷反對角線和與反對角線平行的線
{
for (j = 0; j + 4 < col; j++)
{
if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] && board[i - 2][j + 2] == board[i - 3][j + 3] && board[i - 3][j + 3] == board[i - 4][j + 4] && board[i][j] != ' ')//判斷反對角線和反對角線平行的線是否有五個相連,且不是空格
return board[i][j];
}
}
if (1 == draw(board, ROW, COL))
{
return 'p';
}
else
return 'c';
}
三、游戲總代碼
3.1.主函數(shù)測試區(qū)(test.c):
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("*******************************************************************\n");
printf("************ * *************\n");
printf("****************** * *****************\n");
printf("************************ * ***********************\n");
printf("******************************* * ******************************\n");
printf("******** 1.玩游戲 * 2.退出游戲 *********\n");
printf("******************************* * ******************************\n");
printf("************************ * ***********************\n");
printf("****************** * *****************\n");
printf("************ * ************\n");
printf("*******************************************************************\n");
printf("請選擇:\n");
}
void game()
{
printf("歡迎玩家進(jìn)入游戲:\n");
int gametype = 0;//游戲類型
int boardtype = 0;//棋盤大小的確定
again:
printf("請選擇游戲類型: 1.三子棋游戲(建議3*3的棋盤) 2.五子棋游戲\n");
scanf("%d", &gametype);//讓玩家選擇游戲類型
if (gametype != 1 && gametype != 2)
{
printf("選擇錯誤,牛牛還未開發(fā)此類型游戲。\n");
printf("請重新選擇:\n");
goto again;
}
printf("請選擇棋盤類型:n*n,你希望n的值為多少?(1<n<15)\n");
scanf("%d", &boardtype);
if (gametype == 2 && boardtype < 5 || gametype == 1 && boardtype < 3)//避免選五子棋的棋盤小于5*5,和三子棋小于3*3的棋盤
{
printf("棋盤不符合要求:請重新選擇:\n");
goto again;
}
else if (boardtype > ROW)//選擇的棋盤最大不得超過15*15
{
printf("超出棋盤最大設(shè)置范圍(15*15):\n請重新選擇:\n");
goto again;
}
char board[ROW][COL] = { 0 };//定義一個2維數(shù)組,最大為15*15,用于存放棋子
char ret = 0;//設(shè)置判斷輸贏的返回值。
//打印數(shù)組的元素
init_board(board, ROW, COL);//初始化棋盤,使其值全為空格
print_board(board, boardtype, boardtype);//打印棋盤的外觀和內(nèi)容
while (1)//游戲開始
{
palyer(board, boardtype, boardtype);//玩家下棋
print_board(board, boardtype, boardtype);//打印棋盤
if (gametype == 1)//根據(jù)類型現(xiàn)在判斷輸贏的類型
{
ret = who_win3(board, boardtype, boardtype);//三子棋判斷輸贏
}
else
ret = who_win5(board, boardtype, boardtype);//五子棋判斷輸贏
if (ret != 'c')
{
break;
}
computer(board, boardtype, boardtype);//電腦下棋
print_board(board, boardtype, boardtype);//打印棋盤
if (gametype == 1)//根據(jù)類型現(xiàn)在判斷輸贏的類型
{
ret = who_win3(board, boardtype, boardtype);//三子棋判斷輸贏
}
else
ret = who_win5(board, boardtype, boardtype);//五子棋判斷輸贏
if (ret != 'c')
{
break;
}
}
if (ret == '*')
{
printf("玩家勝利\n");
}
else if (ret == '#')
{
printf("電腦勝利\n");
}
else
{
printf("平局\n");
}
}
int main()
{
int n = 0;//記錄玩家在菜單中的選擇
srand((unsigned int)time(NULL));//與前面介紹的猜數(shù)字游戲一樣,改變種子值來使得rand函數(shù)每次生成不同的隨機(jī)數(shù)列。
do
{
menu();
scanf("%d", &n);//讓玩家在菜單中選擇
switch (n)
{
case 1://代表玩游戲
game();
printf("再來一局嗎?\n");
printf("1.再來一局 2. 沒意思不玩了\n");
int again = 0;//存放玩家是否再玩的結(jié)果。
scanf("%d", &again);
if (again == 1)
{
break;
}
else
n = 2;//令n=2循環(huán)結(jié)束
break;
case 2:
printf("退出游戲");
break;
default:
printf("沒有這個選項哦。\n");//玩家不小心輸錯了
break;
}
} while (n - 2);//當(dāng)玩家選擇2時,代表不玩了
}
3.2.函數(shù)聲明區(qū)(game.h):
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 15//為了方便改變棋盤大小
#define COL 15
void init_board(char board[ROW][COL], int row, int col);//初始化棋盤
void print_board(char board[ROW][COL], int row, int col);//打印棋盤
void palyer(char board[ROW][COL], int row, int col);//玩家下棋
void computer(char board[ROW][COL], int row, int col);//電腦下棋
char who_win3(char board[ROW][COL], int row, int col);//判斷三子棋輸贏
char who_win5(char board[ROW][COL], int row, int col);//判斷五子棋輸贏
3.3.函數(shù)實(shí)現(xiàn)區(qū)(game.c):
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void init_board(char board[ROW][COL], int row, int col)//初始化棋盤
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';//初始化棋盤的內(nèi)容為全空格
}
}
}
void print_board(char board[ROW][COL], int row, int col)//打印棋盤//建議參照棋盤的外觀
{
int i = 0, j = 0;
printf(" ");//為了對齊
for (i = 1; i <= row; i++)//打印顯示在第一行的列標(biāo)
{
printf("%3d ",i);//因為一個格子3個位置
}
printf("\n");
printf(" +");//先打印一個+,可以觀察棋盤外觀,將棋盤外觀拆分打印。//為了對齊加了一個空格
for (i = 0; i < row; i++)//打印一行外觀的分割線
{
printf("---+");
}
printf("\n");//每次打印一行就要換行
for (i = 0; i < row; i++)
{
printf("%2d", i+1);
printf("|");//和上面一樣,先打印一個 | ,可以觀察棋盤外觀,將棋盤外觀拆分打印。
for (j = 0; j < col; j++)//打印一行中間的棋子和其它分割線
{
printf(" %c |", board[i][j]);//這里打印的是“空格”“棋子”“空格”“|”
}
printf("\n");//每次打印一行就要換行
printf(" +");//先打印一個+,可以觀察棋盤外觀,將棋盤外觀拆分打印。//為了對齊加了一個空格
for (j = 0; j < col; j++)//打印一行外觀的分割線
{
printf("---+");//每次打印一行就要換行
}
printf("\n");
}
}
void palyer(char board[ROW][COL], int row, int col)
{
int x = 0, y = 0;//定義x 和 y變量存儲棋子的坐標(biāo)
printf("請玩家下棋:\n");
while (1)
{
printf("請輸入行號和列標(biāo):(用空格隔開)\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= ROW && y >= 1 && y <= COL)//判斷坐標(biāo)是否合法,由于玩家并不是程序員,所以坐標(biāo)要正常從1開始
{
if (board[x - 1][y - 1] == ' ')//落子處為空格,表示此處還未被占用。
{
board[x - 1][y - 1] = '*';//玩家下棋為‘*’,將輸入的坐標(biāo)位置占據(jù)。
break;//表示落子成功,結(jié)束循環(huán),輪到電腦下了
}
else//如果此處不是空格,則表示此處已經(jīng)有棋子了。
{
printf("該處已經(jīng)被占用了,請重新選擇\n");
}
}
else//如果坐標(biāo)不在1到3之間,則棋子超出合法范圍,
{
printf("該坐標(biāo)非法,已經(jīng)超過棋盤,無法識別\n");
printf("請重新選擇:\n");
}
}
}
void computer(char board[ROW][COL], int row, int col)//電腦下棋中
{
printf("電腦下棋中:\n");
while (1)
{
int x = rand() % row;//生成0到2的隨機(jī)數(shù)作為棋子下標(biāo)
int y = rand() % col;
if (board[x][y] == ' ')//找到棋盤中的空余位置進(jìn)行下棋
{
board[x][y] = '#';
break;
}
}
}
int draw(char board[ROW][COL], int row, int col)//判斷平局
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
char who_win3(char board[ROW][COL], int row, int col)//三子棋判斷輸贏
{
int i = 0, j = 0;
for (i = 0; i < row; i++)//判斷每行,所以i要取0到row(不包含row)
{
for (j = 0; j + 2 < col; j++)
{
if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j] != ' ')
//判斷每行是否有相連的3個元素,并且不是空格
{
return board[i][j];
}
}
}
for (j = 0; j < col; j++)//判斷每列
{
for (i = 0; i + 2 < row; i++)
{
if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j] && board[i][j] != ' ')
//判斷每列是否有相連的3個元素,并且不是空格
{
return board[i][j];
}
}
}
for (i = 0; i + 2 < row; i++)//判斷主對角線和主對角線平行的線
{
for (j = 0; j + 2 < col; j++)
{
if (board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] && board[i][j] != ' ')
return board[i][j];
}
}
for (i = 2; i < row; i++)//判斷反對角線和與反對角線平行的線
{
for (j = 0; j + 2 < col; j++)
{
if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] && board[i][j] != ' ')
return board[i][j];
}
}
if (1 == draw(board, ROW, COL))
{
return 'p';
}
else
return 'c';
}
char who_win5(char board[ROW][COL], int row, int col)//五子棋判斷輸贏
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)//判斷每行
{
for (j = 0; j + 4 < col; j++)
{
if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] == board[i][j + 3] && board[i][j + 3] == board[i][j + 4] && board[i][j] != ' ')
return board[i][j];
}
}
for (j = 0; j < row; j++)//判斷每列
{
for (i = 0; i + 4 < row; i++)
{
if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j] && board[i + 2][j] == board[i + 3][j] && board[i + 3][j] == board[i + 4][j] && board[i][j] != ' ')
return board[i][j];
}
}
for (i = 0; i + 4 < row; i++)//判斷主對角線和主對角線平行的線
{
for (j = 0; j + 4 < col; j++)
{
if (board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] && board[i + 2][j + 2] == board[i + 3][j + 3] && board[i + 3][j + 3] == board[i + 4][j + 4] && board[i][j] != ' ')
return board[i][j];
}
}
for (i = 4; i < row; i++)//判斷反對角線和與反對角線平行的線
{
for (j = 0; j + 4 < col; j++)
{
if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] && board[i - 2][j + 2] == board[i - 3][j + 3] && board[i - 3][j + 3] == board[i - 4][j + 4] && board[i][j] != ' ')
return board[i][j];
}
}
if (1 == draw(board, ROW, COL))
{
return 'p';
}
else
return 'c';
}
結(jié)語
怎樣可以讓電腦變得更加聰明呢?怎樣實(shí)現(xiàn)n子棋的玩法而不是限制了三子棋和五子棋的玩法呢?判斷輸贏能否有更簡單的方法?這些都需要更加聰明的牛牛才能實(shí)現(xiàn),現(xiàn)在牛牛的能力有限,還在成長當(dāng)中。希望看了這篇文章對大家有幫助。歡迎小伙伴們私信提意見和提問哦!今天牛牛的小游戲就分享到這里了。
最后,小伙伴們的點(diǎn)贊就是給牛牛最大的支持,能不能給牛牛來一個一鍵三連呢?謝謝支持。文章來源地址http://www.zghlxwxcb.cn/news/detail-805370.html
到了這里,關(guān)于趣味益智小游戲 三子棋+五子棋 優(yōu)化版(可任意選擇棋盤大小)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!