五子棋的历史背景:
五子棋起源于中国,是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。
五子棋容易上手,老少皆宜,而且趣味横生,引人入胜。它不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
不难看出,五子棋是我们中华民族发明的,我们必须了解他,作为程序员,我们更加要懂得如何把五子棋的代码给敲出来,我研究了一天了,调试了无数次,修改了无数错误,到最后运行成功的那一刹那,我就很开心,就想以博客的形式分享给大家!
一.设计过程步骤
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:努力进大厂的新青年