目錄
作為一家“創(chuàng)意+整合+營(yíng)銷(xiāo)”的成都網(wǎng)站建設(shè)機(jī)構(gòu),我們?cè)跇I(yè)內(nèi)良好的客戶(hù)口碑。成都創(chuàng)新互聯(lián)公司提供從前期的網(wǎng)站品牌分析策劃、網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、網(wǎng)站制作、創(chuàng)意表現(xiàn)、網(wǎng)頁(yè)制作、系統(tǒng)開(kāi)發(fā)以及后續(xù)網(wǎng)站營(yíng)銷(xiāo)運(yùn)營(yíng)等一系列服務(wù),幫助企業(yè)打造創(chuàng)新的互聯(lián)網(wǎng)品牌經(jīng)營(yíng)模式與有效的網(wǎng)絡(luò)營(yíng)銷(xiāo)方法,創(chuàng)造更大的價(jià)值。一、了解五子棋基本元素
二、了解五子棋下棋過(guò)程
三、重要功能設(shè)計(jì)
1、初始化棋子
2、初始化棋盤(pán)
3、判斷勝負(fù)
4、人機(jī)對(duì)戰(zhàn)隨機(jī)算法
5、判斷棋盤(pán)是否已滿(mǎn)
6、保存當(dāng)前棋局并退出游戲
7、復(fù)盤(pán)游戲
四、源代碼及運(yùn)行結(jié)果
五、總結(jié)
五子棋分黑白兩色,形狀為扁圓形。雙方進(jìn)行博弈時(shí)要將棋子下在棋盤(pán)的交叉點(diǎn)處。
棋子符號(hào)包括:
黑子:○? ? 白子:●
棋盤(pán)每一個(gè)位置分為三種狀態(tài),白子、黑子、空白??梢允褂煤甓x:
#define WHITE -1
#define BLACK 1
#define BLANK 0
(該實(shí)踐默認(rèn)在人機(jī)對(duì)戰(zhàn)時(shí),玩家執(zhí)黑棋,電腦執(zhí)白棋)
2、棋盤(pán)目前國(guó)際上使用的五子棋棋盤(pán)都是15×15,由橫縱交叉線(xiàn)形成了225個(gè)交叉點(diǎn)。
棋盤(pán)符號(hào)包括:
┌??? ┬??? ┐
├??? ┼??? ┤
└??? ┴??? ┘
棋盤(pán)大行數(shù)15,大列數(shù)15。可以使用宏定義:
#define MAX_ROW 15
#define MAX_COL 15
棋盤(pán)可以抽象為一個(gè)二維數(shù)組chessboard[MAX_ROW][MAX_COL],存儲(chǔ)棋子的下標(biāo)位置
二、了解五子棋下棋過(guò)程1、在菜單界面選擇對(duì)戰(zhàn)方式、進(jìn)行上一局或退出游戲
2、繪制棋盤(pán)、棋子
3、執(zhí)黑子的玩家先落子,然后雙方輪流落子
4、判斷勝負(fù)或平局
5、退出游戲
三、重要功能設(shè)計(jì) 1、初始化棋子void draw_chessman(int type, char *tableline) {
if (type == WHITE)
printf("●");
if (type == BLACK)
printf("○");
if (type == BLANK)
printf("%s", tableline);//此處傳入另一個(gè)參數(shù)tableline,是為了繪制棋盤(pán)更加方便
}
2、初始化棋盤(pán)觀察棋盤(pán)可以發(fā)現(xiàn),遍歷繪制棋盤(pán)需分成三種不同的情況,即第一行,最后一行,其余行
//棋盤(pán)可分為三部分,第一行,最后一行,中間行
//用i代表行,j代表列
void draw_chessboardn(int row, int col, int chessboard[][MAX_COL]) {
for (int i = 0; i< row ; i++) {
if (i == 0) {
for (int j = 0; j< col; j++) {
if (j == 0)
draw_chessman(chessboard[i][j], "┌ ");
else if (j == 14)
draw_chessman(chessboard[i][j], "┐");
else
draw_chessman(chessboard[i][j], "┬ ");
}
printf("\n");//第一行┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
} else if (i == 14) {
for (int j = 0; j< col; j++) {
if (j == 0)
draw_chessman(chessboard[i][j], "└ ");
else if (j == 14)
draw_chessman(chessboard[i][j], "┘ ");
else
draw_chessman(chessboard[i][j], "┴ ");
}
printf("\n");//最后一行└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘
} else {
for (int j = 0; j< col; j++) {
if (j == 0)
draw_chessman(chessboard[i][j], "├ ");
else if (j == 14)
draw_chessman(chessboard[i][j], "┤");
else
draw_chessman(chessboard[i][j], "┼ ");
}
printf("\n");//其他行├┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┤
}
}
}
3、判斷勝負(fù)五子棋連成五子即為勝,判斷輸贏須在一個(gè)棋子的上、下、左、右、右上、右下、左上、左上共八個(gè)方向遍歷是否有相連的五子。但可以發(fā)現(xiàn)上和下在一條線(xiàn)上,左和右在一條線(xiàn)上,依此類(lèi)推只需判斷四個(gè)方向,即橫、豎、左斜、右斜方向。
//返回當(dāng)前棋子的值,若值為1,代表黑棋勝,若值為-1,代表白棋勝
int is_win(int chessboard[][MAX_COL], int row, int col) {
int i, j;
for (i = 0; i< row; i++) {
for (j = 0; j< col; j++) {
if (chessboard[i][j] == BLANK)
continue;
// (-)橫著連成五子
if (j< col - 4)
if (chessboard[i][j] == chessboard[i][j + 1] && chessboard[i][j] ==
chessboard[i][j + 2]
&& chessboard[i][j] == chessboard[i][j + 3] && chessboard[i][j]
== chessboard[i][j + 4])
return chessboard[i][j];
// (|)豎著連成五子
if (i< row - 4)
if (chessboard[i][j] == chessboard[i + 1][j] && chessboard[i][j] ==
chessboard[i + 2][j]
&& chessboard[i][j] == chessboard[i + 3][j] && chessboard[i][j]
== chessboard[i + 4][j])
return chessboard[i][j];
// (\)左斜連成五子
if (i< row - 4 && j< col - 4)
if (chessboard[i][j] == chessboard[i + 1][j + 1] && chessboard[i][j] ==
chessboard[i + 2][j + 2]
&& chessboard[i][j] == chessboard[i + 3][j + 3] && chessboard[i]
[j] == chessboard[i + 4][j + 4])
return chessboard[i][j];
// (/)右斜連成五子
if (i< row - 4 && j >4)
if (chessboard[i][j] == chessboard[i + 1][j - 1] && chessboard[i][j] ==
chessboard[i + 2][j - 2]
&& chessboard[i][j] == chessboard[i + 3][j - 3] && chessboard[i]
[j] == chessboard[i + 4][j - 4])
return chessboard[i][j];
}
}
return BLANK;
}
4、人機(jī)對(duì)戰(zhàn)隨機(jī)算法利用產(chǎn)生隨機(jī)數(shù)的函數(shù)隨機(jī)產(chǎn)生隨機(jī)數(shù),用于表示棋子的行和列
int random_create_point(void) {
int point;
srand(time(NULL));
point = rand() % MAX_ROW;
return point;
}
5、判斷棋盤(pán)是否已滿(mǎn)遍歷數(shù)組,棋盤(pán)若下滿(mǎn)了棋子,則表示本次對(duì)弈為和棋
int is_full(int chessboard[][MAX_COL], int row, int col) {
int ret = 1;
for (int i = 0; i< row; i++) {
for (int j = 0; j< col; j++) {
if (chessboard[i][j] == BLANK) {
ret = 0;
break;
}
}
}
return ret;
}
6、保存當(dāng)前棋局并退出游戲void save_chess(int chessboard[][MAX_COL], int row, int col) {
int choice ;
FILE *fp;
printf("是否選擇結(jié)束游戲,并保存當(dāng)前棋局\n");
printf("*********1.存盤(pán)并退出***********\n");
printf("*********2.繼續(xù)游戲*************\n");
printf("請(qǐng)選擇 :");
while (1) {
scanf("%d", &choice);
if (choice >2||choice< 1) {
printf("輸入錯(cuò)誤,請(qǐng)重新選擇\n");
continue;
}
break;
}
if (choice == 1) {
if ( ( fp = fopen( "Save_chess.txt", "w" ) ) == NULL ) {
printf(" 保存失敗\n");
} else {
for (int i = 0; i< row; i++) {
for (int j = 0; j< col; j++) {
fprintf(fp, "%d", chessboard[i][j]);
}
}
fclose(fp);
printf("恭喜您,保存成功");
}
exit(0);
}
}
7、復(fù)盤(pán)游戲void replay_chess(void) {
int chessboard[MAX_ROW][MAX_COL] = {BLANK};
FILE *fp;
char ch;
if ((fp = fopen("Save_chess.txt", "w")) == NULL) {
printf("復(fù)盤(pán)失敗");
} else {
for (int i = 0; i< MAX_ROW; i++) {
for (int j = 0; j< MAX_COL; j++) {
fscanf(fp, "%d", chessboard[i][j]);
}
}
fclose(fp);
draw_chessboardn(MAX_ROW, MAX_COL, chessboard);
}
}
四、源代碼及運(yùn)行結(jié)果#include#include#define MAX_ROW 15
#define MAX_COL 15
#define WHITE -1
#define BLACK 1
#define BLANK 0
void draw_chessboardn(int row, int col, int chessboard[][MAX_COL]);
void draw_chessman(int type, char *tableline);
int random_create_point(void);
void draw_menu(void);
void person_person(void);
void person_computer_random(void);
int is_full(int chessboard[][MAX_COL], int row, int col);
int is_win(int chessboard[][MAX_COL], int row, int col);
void save_chess(int chessboard[][MAX_COL], int row, int col);
void replay_chess(void);
int ChooseArrow(int chessboard[][MAX_COL], int row, int col);
int main () {
int choice;
draw_menu();
while (1) {
scanf("%d", &choice);
switch (choice) {
case 1:
person_person();
break;
case 2:
person_computer_random();
break;
case 3:
replay_chess();
break;
case 4:
exit(0);
break;
default:
printf("輸入錯(cuò)誤,請(qǐng)重新選擇\n");
}
}
return 0;
}
//繪制棋盤(pán)
void draw_chessboardn(int row, int col, int chessboard[][MAX_COL]) {
for (int i = 0; i< row ; i++) {
if (i == 0) {
for (int j = 0; j< col; j++) {
if (j == 0)
draw_chessman(chessboard[i][j], "┌ ");
else if (j == 14)
draw_chessman(chessboard[i][j], "┐");
else
draw_chessman(chessboard[i][j], "┬ ");
}
printf("\n");
} else if (i == 14) {
for (int j = 0; j< col; j++) {
if (j == 0)
draw_chessman(chessboard[i][j], "└ ");
else if (j == 14)
draw_chessman(chessboard[i][j], "┘ ");
else
draw_chessman(chessboard[i][j], "┴ ");
}
printf("\n");
} else {
for (int j = 0; j< col; j++) {
if (j == 0)
draw_chessman(chessboard[i][j], "├ ");
else if (j == 14)
draw_chessman(chessboard[i][j], "┤");
else
draw_chessman(chessboard[i][j], "┼ ");
}
printf("\n");
}
}
}
//繪制棋子
void draw_chessman(int type, char *tableline) {
if (type == WHITE)
printf("●");
if (type == BLACK)
printf("○");
if (type == BLANK)
printf("%s", tableline);
}
//隨機(jī)算法獲取棋子的坐標(biāo)
int random_create_point(void) {
int point;
point = rand() % MAX_ROW;
return point;
}
//繪制主菜單
void draw_menu(void) {
printf("******************************\n");
printf("******* 歡迎使用五子棋 *******\n");
printf("*** 研發(fā)者:Hiya(a ***\n");
printf("*** 請(qǐng)選擇對(duì)戰(zhàn)方式 ***\n");
printf("* 1.人-人對(duì)戰(zhàn) *\n");
printf("* 2.人-機(jī)對(duì)戰(zhàn)(隨機(jī)算法) *\n");
printf("* 3.復(fù)盤(pán) *\n");
printf("* 4.退出 *\n");
printf("******************************\n");
printf("請(qǐng)選擇:");
}
//人人對(duì)戰(zhàn)
void person_person(void) {
int chessboard[MAX_ROW][MAX_COL] = {BLANK};
int i, j;
char key;
draw_chessboardn(MAX_ROW, MAX_COL, chessboard);
for (int step = 1; step<= MAX_ROW * MAX_COL; step++) { //黑子先行,然后雙方輪流下棋
if (step % 2 == 1) { //當(dāng)前步數(shù)為單數(shù),黑棋落子。
printf("請(qǐng)黑棋落子:");
while (1) {
scanf("%d %d", &i, &j);
if (chessboard[i][j] != BLANK) {
printf("該位置已有棋子,請(qǐng)重新輸入\n"); //棋子只能落在空白處
continue;
}
if (i >= MAX_ROW || j >= MAX_COL || i< 0 || j< 0) {
printf("輸入超出棋盤(pán)范圍,請(qǐng)重新輸入\n"); //棋子坐標(biāo)不可超出棋盤(pán)
continue;
}
break;
}
chessboard[i][j] = BLACK;
draw_chessboardn(MAX_ROW, MAX_COL, chessboard);
if (is_win(chessboard, MAX_ROW, MAX_COL) == BLACK) {
printf("黑棋勝");
exit(0);
}
save_chess(chessboard, MAX_ROW, MAX_COL);
} else if (step % 2 == 0) { //當(dāng)前步數(shù)為雙數(shù),則白棋落子
printf("請(qǐng)白棋落子:");
while (1) {
scanf("%d %d", &i, &j);
if (chessboard[i][j] != BLANK) {
printf("該位置已有棋子,請(qǐng)重新輸入\n"); //棋子只能落在空白處
continue;
}
if (i >= MAX_ROW || j >= MAX_COL || i< 0 || j< 0) {
printf("輸入超出棋盤(pán)范圍,請(qǐng)重新輸入\n"); //棋子坐標(biāo)不可超出棋盤(pán)
continue;
}
break;
}
chessboard[i][j] = WHITE;
draw_chessboardn(MAX_ROW, MAX_COL, chessboard);
if (is_win(chessboard, MAX_ROW, MAX_COL) == WHITE) {
printf("白棋勝");
exit(0);
}
save_chess(chessboard, MAX_ROW, MAX_COL);
}
}
if (is_full(chessboard, MAX_ROW, MAX_COL) == 1)
printf("棋盤(pán)已滿(mǎn)");
}
//判斷棋盤(pán)是否已滿(mǎn)
int is_full(int chessboard[][MAX_COL], int row, int col) {
int ret = 1;
for (int i = 0; i< row; i++) {
for (int j = 0; j< col; j++) {
if (chessboard[i][j] == BLANK) { //遍歷數(shù)組,當(dāng)有一個(gè)位置為空,則棋盤(pán)不滿(mǎn)
ret = 0;
break;
}
}
}
return ret;
}
//判斷勝負(fù)
int is_win(int chessboard[][MAX_COL], int row, int col) {
int i, j;
for (i = 0; i< row; i++) {
for (j = 0; j< col; j++) {
if (chessboard[i][j] == BLANK)
continue;
if (j< col - 4)
if (chessboard[i][j] == chessboard[i][j + 1] && chessboard[i][j] == chessboard[i][j + 2]
&& chessboard[i][j] == chessboard[i][j + 3] && chessboard[i][j] == chessboard[i][j + 4])
return chessboard[i][j];
if (i< row - 4)
if (chessboard[i][j] == chessboard[i + 1][j] && chessboard[i][j] == chessboard[i + 2][j]
&& chessboard[i][j] == chessboard[i + 3][j] && chessboard[i][j] == chessboard[i + 4][j])
return chessboard[i][j];
if (i< row - 4 && j< col - 4)
if (chessboard[i][j] == chessboard[i + 1][j + 1] && chessboard[i][j] == chessboard[i + 2][j + 2]
&& chessboard[i][j] == chessboard[i + 3][j + 3] && chessboard[i][j] == chessboard[i + 4][j + 4])
return chessboard[i][j];
if (i< row - 4 && j >4)
if (chessboard[i][j] == chessboard[i + 1][j - 1] && chessboard[i][j] == chessboard[i + 2][j - 2]
&& chessboard[i][j] == chessboard[i + 3][j - 3] && chessboard[i][j] == chessboard[i + 4][j - 4])
return chessboard[i][j];
}
}
return BLANK;
}
//人機(jī)對(duì)戰(zhàn)
void person_computer_random(void) {
int chessboard[MAX_ROW][MAX_COL] = {BLANK};
int i, j;
draw_chessboardn(MAX_ROW, MAX_COL, chessboard);
for (int step = 1; step<= MAX_ROW * MAX_COL; step++) {
if (step % 2 == 1) {
printf("請(qǐng)黑棋落子:");
while (1) {
scanf("%d %d", &i, &j);
if (chessboard[i][j] != BLANK) {
printf("該位置已有棋子,請(qǐng)重新輸入\n");
continue;
}
if (i >= MAX_ROW || j >= MAX_COL || i< 0 || j< 0) {
printf("輸入超出棋盤(pán)范圍,請(qǐng)重新輸入\n");
continue;
}
break;
}
chessboard[i][j] = BLACK;
draw_chessboardn(MAX_ROW, MAX_COL, chessboard);
if (is_win(chessboard, MAX_ROW, MAX_COL) == BLACK) {
printf("黑棋勝");
exit(0);
}
save_chess(chessboard, MAX_ROW, MAX_COL);
} else if (step % 2 == 0) {
while (1) {
i = random_create_point();
j = random_create_point();
if (chessboard[i][j] == BLANK)
break;
}
chessboard[i][j] = WHITE;
draw_chessboardn(MAX_ROW, MAX_COL, chessboard);
if (is_win(chessboard, MAX_ROW, MAX_COL) == WHITE) {
printf("白棋勝");
exit(0);
}
save_chess(chessboard, MAX_ROW, MAX_COL);
}
}
if (is_full(chessboard, MAX_ROW, MAX_COL) == 1)
printf("棋盤(pán)已滿(mǎn)");
}
//存盤(pán)
void save_chess(int chessboard[][MAX_COL], int row, int col) {
int choice ;
FILE *fp;
printf("是否選擇結(jié)束游戲,并保存當(dāng)前棋局\n");
printf("*********1.存盤(pán)并退出***********\n");
printf("*********2.繼續(xù)游戲*************\n");
printf("請(qǐng)選擇 :");
while (1) {
scanf("%d", &choice);
if (choice >2) {
printf("輸入錯(cuò)誤,請(qǐng)重新選擇\n");
continue;
}
break;
}
if (choice == 1) {
if ( ( fp = fopen( "Save_chess.txt", "w" ) ) == NULL ) {
printf(" 保存失敗\n");
} else {
for (int i = 0; i< row; i++) {
for (int j = 0; j< col; j++) {
fprintf(fp, "%d", chessboard[i][j]);
}
}
fclose(fp);
printf("恭喜您,保存成功");
}
exit(0);
}
}
//復(fù)盤(pán)
void replay_chess(void) {
int chessboard[MAX_ROW][MAX_COL] = {BLANK};
FILE *fp;
char ch;
if ((fp = fopen("Save_chess.txt", "w")) == NULL) {
printf("復(fù)盤(pán)失敗");
} else {
for (int i = 0; i< MAX_ROW; i++) {
for (int j = 0; j< MAX_COL; j++) {
fscanf(fp, "%d", chessboard[i][j]);
}
}
fclose(fp);
draw_chessboardn(MAX_ROW, MAX_COL, chessboard);
}
}
五、總結(jié)用C語(yǔ)言設(shè)計(jì)五子棋小游戲的過(guò)程中,充分利用了C當(dāng)中的數(shù)組和循環(huán)判斷的知識(shí),通過(guò)設(shè)計(jì)五子棋的實(shí)踐,更加深入的理解C。有錯(cuò)誤大家可以指出,共同進(jìn)步。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧