C语言实践----五子棋(附源代码及思路讲解)-创新互联
目录
作为一家“创意+整合+营销”的成都网站建设机构,我们在业内良好的客户口碑。成都创新互联公司提供从前期的网站品牌分析策划、网站设计、成都网站建设、网站制作、创意表现、网页制作、系统开发以及后续网站营销运营等一系列服务,帮助企业打造创新的互联网品牌经营模式与有效的网络营销方法,创造更大的价值。一、了解五子棋基本元素
二、了解五子棋下棋过程
三、重要功能设计
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 * MAX_COL; step++) { //黑子先行,然后双方轮流下棋
if (step % 2 == 1) { //当前步数为单数,黑棋落子。
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] = 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 * MAX_COL; step++) {
if (step % 2 == 1) {
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] = 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。有错误大家可以指出,共同进步。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站名称:C语言实践----五子棋(附源代码及思路讲解)-创新互联
网页地址:http://scyanting.com/article/djcojh.html