C语言实践

您所在的位置:网站首页 五子棋快速获胜方法 C语言实践

C语言实践

2024-07-10 12:30| 来源: 网络整理| 查看: 265

目录

一、了解五子棋基本元素

二、了解五子棋下棋过程

三、重要功能设计

1、初始化棋子

2、初始化棋盘

3、判断胜负

4、人机对战随机算法

5、判断棋盘是否已满

6、保存当前棋局并退出游戏

7、复盘游戏

四、源代码及运行结果

 五、总结

一、了解五子棋基本元素 1、棋子

五子棋分黑白两色,形状为扁圆形。双方进行博弈时要将棋子下在棋盘的交叉点处。

棋子符号包括:

黑子:○    白子:●

棋盘每一个位置分为三种状态,白子、黑子、空白。可以使用宏定义:

#define WHITE -1

#define BLACK 1

#define BLANK 0

(该实践默认在人机对战时,玩家执黑棋,电脑执白棋)

2、棋盘

目前国际上使用的五子棋棋盘都是15×15,由横纵交叉线形成了225个交叉点。

棋盘符号包括:

┌    ┬    ┐

├    ┼    ┤

└    ┴    ┘

棋盘最大行数15,最大列数15。可以使用宏定义:

#define MAX_ROW 15

#define MAX_COL 15

棋盘可以抽象为一个二维数组chessboard[MAX_ROW][MAX_COL],存储棋子的下标位置

二、了解五子棋下棋过程

1、在菜单界面选择对战方式、进行上一局或退出游戏

2、绘制棋盘、棋子

3、执黑子的玩家先落子,然后双方轮流落子

4、判断胜负或平局

5、退出游戏

三、重要功能设计 1、初始化棋子 void draw_chessman(int type, char *tableline) { if (type == WHITE) printf("●"); if (type == BLACK) printf("○"); if (type == BLANK) printf("%s", tableline);//此处传入另一个参数tableline,是为了绘制棋盘更加方便 } 2、初始化棋盘

观察棋盘可以发现,遍历绘制棋盘需分成三种不同的情况,即第一行,最后一行,其余行

//棋盘可分为三部分,第一行,最后一行,中间行 //用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、判断胜负

五子棋连成五子即为胜,判断输赢须在一个棋子的上、下、左、右、右上、右下、左上、左上共八个方向遍历是否有相连的五子。但可以发现上和下在一条线上,左和右在一条线上,依此类推只需判断四个方向,即横、竖、左斜、右斜方向。

//返回当前棋子的值,若值为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、人机对战随机算法

利用产生随机数的函数随机产生随机数,用于表示棋子的行和列

int random_create_point(void) { int point; srand(time(NULL)); point = rand() % MAX_ROW; return point; } 5、判断棋盘是否已满

遍历数组,棋盘若下满了棋子,则表示本次对弈为和棋

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、保存当前棋局并退出游戏 void save_chess(int chessboard[][MAX_COL], int row, int col) { int choice ; FILE *fp; printf("是否选择结束游戏,并保存当前棋局\n"); printf("*********1.存盘并退出***********\n"); printf("*********2.继续游戏*************\n"); printf("请选择 :"); while (1) { scanf("%d", &choice); if (choice > 2||choice < 1) { printf("输入错误,请重新选择\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、复盘游戏 void replay_chess(void) { int chessboard[MAX_ROW][MAX_COL] = {BLANK}; FILE *fp; char ch; if ((fp = fopen("Save_chess.txt", "w")) == NULL) { printf("复盘失败"); } 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); } } 四、源代码及运行结果 #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("输入错误,请重新选择\n"); } } return 0; } //绘制棋盘 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); } //随机算法获取棋子的坐标 int random_create_point(void) { int point; point = rand() % MAX_ROW; return point; } //绘制主菜单 void draw_menu(void) { printf("******************************\n"); printf("******* 欢迎使用五子棋 *******\n"); printf("*** 研发者:Hiya(a ***\n"); printf("*** 请选择对战方式 ***\n"); printf("* 1.人-人对战 *\n"); printf("* 2.人-机对战(随机算法) *\n"); printf("* 3.复盘 *\n"); printf("* 4.退出 *\n"); printf("******************************\n"); printf("请选择:"); } //人人对战 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 || j >= MAX_COL || i < 0 || j < 0) { printf("输入超出棋盘范围,请重新输入\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) { //当前步数为双数,则白棋落子 printf("请白棋落子:"); while (1) { scanf("%d %d", &i, &j); if (chessboard[i][j] != BLANK) { printf("该位置已有棋子,请重新输入\n"); //棋子只能落在空白处 continue; } if (i >= MAX_ROW || j >= MAX_COL || i < 0 || j < 0) { printf("输入超出棋盘范围,请重新输入\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("棋盘已满"); } //判断棋盘是否已满 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; } //判断胜负 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; } //人机对战 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 || j >= MAX_COL || i < 0 || j < 0) { printf("输入超出棋盘范围,请重新输入\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("棋盘已满"); } //存盘 void save_chess(int chessboard[][MAX_COL], int row, int col) { int choice ; FILE *fp; printf("是否选择结束游戏,并保存当前棋局\n"); printf("*********1.存盘并退出***********\n"); printf("*********2.继续游戏*************\n"); printf("请选择 :"); while (1) { scanf("%d", &choice); if (choice > 2) { printf("输入错误,请重新选择\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); } } //复盘 void replay_chess(void) { int chessboard[MAX_ROW][MAX_COL] = {BLANK}; FILE *fp; char ch; if ((fp = fopen("Save_chess.txt", "w")) == NULL) { printf("复盘失败"); } 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); } }

 五、总结

用C语言设计五子棋小游戏的过程中,充分利用了C当中的数组和循环判断的知识,通过设计五子棋的实践,更加深入的理解C。有错误大家可以指出,共同进步。

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3