五子棋的历史背景:
五子棋起源于中国,是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。
五子棋容易上手,老少皆宜,而且趣味横生,引人入胜。它不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
不难看出,五子棋是我们中华民族发明的,我们必须了解他,作为程序员,我们更加要懂得如何把五子棋的代码给敲出来,我研究了一天了,调试了无数次,修改了无数错误,到最后运行成功的那一刹那,我就很开心,就想以博客的形式分享给大家!
一.设计过程步骤
ps:整个五子棋一共有三个文件,200多行代码,不复杂,多琢磨,很好懂,分为text.c,game.h,game.c文件,在最后会给出完整代码。
1.初始化二维数组
为了数组里面存放的每个数是我们想初始化的,我们初始化一个二维数组(方阵的格式,即 n*n)用来存放棋子,里面的元素可以按照我们的意愿来初始化;在此代码中将数组中每个元素初始化为一个空格。
#define ROW 5
#define COL 5
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
}
2.构造一个棋盘
在初始化一个数组后的基础上我们来构造一个棋盘,使得整个代码的结构更加清晰,可读性高。
#define ROW 5
#define COL 5
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for(j=0;j<col;j++)
{
printf(" %c ", board[i][j]);//注意:%c的左右是有两个空格的
if (j < col -1)//最后一列不打印|,也就是打印4个|,只是为了美观,不加也行,见下图
printf("|");
}
printf("\n");
if (i < row - 1)//最后一行不进行打印---和|,见下图
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)//和上面一样,见下图
printf("|");
}
printf("\n");
}
}
}
3.玩家走法
//玩家
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走:>");
while (1)
{
printf("请输入下棋的坐标\n");
scanf_s("%d %d", &x, &y);
//判断坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//下棋
//坐标是否被占用
if (' ' == board[x - 1][y - 1]) //等号量变也可以调换,我这样写要是出错那编译器会提示错误,如果换过来的话那就不会提示错误了,这样找bug可能会很难受
//如果是空格的话,这个位置就是空的,可以下棋
{
board[x - 1][y - 1] ='*';
break;
}
else
{
printf("坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法,请重新选择\n");
}
}
}
4.电脑随机下棋
//电脑
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑走:>\n");
while (1)
{
int x = rand() % ROW;//rand是根据系统的情况来自动生成一个随机数
int y = rand() % COL;
//判断占用
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
5.判断是否能分出胜负
//判断游戏是否有输赢
char IsWin(char board[ROW][COL], int row, int col)
{
int i = 0;
//判断五行每行五个元素是否相等
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] == board[i][3]
&& board[i][3] == board[i][4] && board[i][1] != ' ')
{
return board[i][1];
}
}
//判断五列每一列的元素是否相等
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] == board[3][i]
&& board[3][i] == board[4][i] && board[1][i] != ' ')
{
return board[i][1];
}
}
//判断\对角线元素是否相等
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]&&
board[2][2] == board[3][3]&&board[3][3] == board[4][4] && board[1][1]!=' ')
{
return board[1][1];
}
//判断/对角线元素是否相等
if ( board[4][0]== board[3][1] && board[3][1] == board[2][2]&&
board[2][2] == board[1][3] &&board[1][3] == board[0][4] && board[1][1]!=' ')
{
return board[1][1];
}
6.判断是否平局
int IsFull(char board[ROW][COL], int row, int 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;
}
//判断平局
//如果棋盘满了则返回1,不满返回0
int ret = IsFull(board, row, col);
if (ret == 1)
{
return 'Q';
}
return 'C';
以下是game.h文件的代码
#pragma once
//头文件的包含
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//符号定义
#define ROW 5
#define COL 5
//函数声明
//初始化棋盘的
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘的函数
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);
以下是text.c文件的代码
#include"game.h"
void menu()
{
printf("*******************************\n");
printf("********* 1.play ************\n");
printf("********* 0.exit ************\n");
printf("*******************************\n");
}
void game()
{
//储存数据--二维数组
char board[ROW][COL];
//初始化棋盘为空格
InitBoard(board, ROW, COL);
//打印棋盘--本质打印数组的内容
DisplayBoard(board,ROW,COL);
char ret = 0;
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判断玩家是否赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
break;
//电脑下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret =! 'C')
break;
}
if (ret == '*')
printf("玩家胜利\n");
else if (ret == '#')
printf("电脑胜利\n");
else
printf("平局\n");
DisplayBoard(board, ROW, COL);
}
int main()
{
srand((unsigned int) time(NULL));
int input = 0;
do
{
menu();
printf("请选择:>");
scanf_s("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
二.完整代码:
game.h文件
#pragma once
//头文件的包含
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//符号定义
#define ROW 5
#define COL 5
//函数声明
//初始化棋盘的
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘的函数
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);
game.c文件
#include"game.h"
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
}
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for(j=0;j<col;j++)
{
printf(" %c ", board[i][j]);
if (j < col -1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
//printf("---|---|---\n");
}
}
//玩家
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走:>");
while (1)
{
printf("请输入下棋的坐标\n");
scanf_s("%d %d", &x, &y);
//判断坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//下棋
//坐标是否被占用
if (' ' == board[x - 1][y - 1])
{
board[x - 1][y - 1] ='*';
break;
}
else
{
printf("坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法,请重新选择\n");
}
}
}
//电脑
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑走:>\n");
while (1)
{
int x = rand() % ROW;
int y = rand() % COL;
//判断占用
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int IsFull(char board[ROW][COL], int row, int 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 IsWin(char board[ROW][COL], int row, int col)
{
int i = 0;
//判断五行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] == board[i][3]
&& board[i][3] == board[i][4] && board[i][1] != ' ')
{
return board[i][1];
}
}
//判断五列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] == board[3][i]
&& board[3][i] == board[4][i] && board[1][i] != ' ')
{
return board[i][1];
}
}
//判断\对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]&& board[2][2] == board[3][3]
&&board[3][3] == board[4][4] && board[1][1]!=' ')
{
return board[1][1];
}
//判断/对角线
if ( board[4][0]== board[3][1] && board[3][1] == board[2][2]&& board[2][2] == board[1][3]
&&board[1][3] == board[0][4] && board[1][1]!=' ')
{
return board[1][1];
}
//判断平局
//如果棋盘满了则返回1,不满返回0
int ret = IsFull(board, row, col);
if (ret == 1)
{
return 'Q';
}
return 'C';
}
以下是text.c文件:
#include"game.h"
void menu()
{
printf("*******************************\n");
printf("********* 1.play ************\n");
printf("********* 0.exit ************\n");
printf("*******************************\n");
}
void game()
{
//储存数据--二维数组
char board[ROW][COL];
//初始化棋盘为空格
InitBoard(board, ROW, COL);
//打印棋盘--本质打印数组的内容
DisplayBoard(board,ROW,COL);
char ret = 0;
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判断玩家是否赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
break;
//电脑下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret =! 'C')
break;
}
if (ret == '*')
printf("玩家胜利\n");
else if (ret == '#')
printf("电脑胜利\n");
else
printf("平局\n");
DisplayBoard(board, ROW, COL);
}
int main()
{
srand((unsigned int) time(NULL));
int input = 0;
do
{
menu();
printf("请选择:>");
scanf_s("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
最后,大家有问题可以指出来,关个注,点个赞,评个论,我们一起进步!
2023.02.09
From:努力进大厂的新青年