> 文档中心 > 【C语言】C语言系列—五子棋的实现

【C语言】C语言系列—五子棋的实现


一个五子棋程序,可以分为四个部分,第一部分是头文件的创立,它可以让我们的函数很好的封装起来,其中有两个细节需要注意:一是在头文件中用define定义行和列,这样我们将来要对行和列进行改动的时候只用改define这一个地方。二是把stdio.h time.h 等头文件包含在game.h 这个头文件中,避免重复包含。

第二部分是test.c函数逻辑的实现,它包含了实现这个游戏所需要的基本逻辑,包括菜单的打印、棋盘的初始化、棋盘的打印、玩家和电脑下棋、游戏状态的判断。

第三部分是游戏相关函数的实现,前面是对游戏各个具体功能的阐述,后面是总的代码。

第四部分是游戏效果展示。 

第五部分:游戏总体实现代码 

第一部分:

头文件的内容--游戏相关函数的声明、符号的声明、头文件的包含

#pragma once//game.h  游戏相关函数的声明、符号的声明、头文件的包含//符号的声明#define ROW 5#define COL 5//头文件的包含#include#include#include//函数的声明//初始化棋盘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);//判断输赢//游戏状态:*:玩家赢//   #:电脑赢//   Q:平局//   C:游戏继续char IsWin(char board[ROW][COL], int row, int col);

第二部分--测绘游戏的逻辑  test.c  

#define _CRT_SECURE_NO_WARNINGS 1//test.c  测绘游戏的逻辑//game.c  游戏相关函数的实现//game.h  游戏相关函数的声明、符号的声明、头文件的包含#define _CRT_SECURE_NO_WARNINGS 1    //解决VS中scanf不安全问题#include"game.h"//自己创建的头文件用双引号void menu()     //菜单的实现{printf("1.play\n");printf("0.exit\n");}void game()     //游戏实现部分{//定义数组--存储数据char board[ROW][COL] = { 0 };//初始化棋盘InitBoard(board, ROW, COL);//打印棋盘DisplayBoard(board, ROW, COL);char ret;      //判断游戏状态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");elseprintf("平局\n");}int main(){int n = 0;srand((unsigned int)time(NULL));do {menu();printf("请选择:->");scanf("%d", &n);switch (n){case 1:game(); break;case 0:printf("退出游戏"); break;default:printf("选择错误,重新选择\n");}} while (n);return 0;}

第三部分--游戏相关函数的实现  game.c

1,棋盘初始化(实质是数组初始化)

//初始化棋盘void InitBoard(char board[ROW][COL], int row, int col){int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++)board[i][j] = ' ';      //将棋盘初始化为空格}}

2,打印棋盘

//打印棋盘void DisplayBoard(char board[ROW][COL], int row, int col){int i = 0, 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){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 m = 0, n = 0;printf("玩家走\n");while (1)//如果坐标违法就重新输入{printf("请输入坐标->:");scanf("%d%d", &m, &n);//判断坐标合法性if (m = 1 && n = 1){//判断坐标是否被占用if (board[m - 1][n - 1] == ' ')     //玩家不知道数组下标从零开始,输入是从(1 1)开始的,所以要减一{board[m - 1][n - 1] = '*';break;}elseprintf("坐标被占用,请重新输入\n");}elseprintf("坐标非法,请重新输入\n");}}

4,电脑下棋--要让电脑产生一个在数组范围内的随机坐标,要用到随机函数值产生函数rand(),同时为保证该值的随机性,需要为其设置一个种子,同时要判断坐标是否被占用。

//电脑下棋void ComputerMove(char board[ROW][COL], int row, int col){int m = 0, n = 0;printf("电脑走\n");while (1){m = rand() % row;n = rand() % col;//判断坐标是否被占用if (board[m][n] == ' '){board[m][n] = '#';break;}}}

5,判断游戏的状态--:*:玩家赢              

                                     #:电脑赢
                                     Q:平局
                                     C:游戏继续

//判断输赢char IsWin(char board[ROW][COL], int row, int col){int i = 0, j = 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][4] != ' ')return board[i][1];}for (i = 0; i < col; i++){if (board[0][i] == board[1][i]&& 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[4][i] != ' ')return board[1][i];}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[4][4] != ' ')return board[0][0];if (board[0][4] == board[1][1]&& board[1][1] == board[2][2]&& board[2][2] == board[3][3]&& board[3][3] == board[4][4]&& board[4][4] != ' ')return board[0][0];int ret = IsFull(board, row, col);if (ret)return 'Q';return 'C';}

6,判断游戏状态--判断棋盘是否下满

in//判断棋盘是否满了int IsFull(char board[ROW][COL], int row, int col){int i = 0, j = 0, flag = 1;for (i = 0; i < row; i++){for (j = 0; j < col; j++)if (board[i][j] == ' ')flag = 0;}return flag;}

7,game.c 的总体实现

#define _CRT_SECURE_NO_WARNINGS 1//game.c  游戏相关函数的实现#include"game.h"//初始化棋盘void InitBoard(char board[ROW][COL], int row, int col){int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++)board[i][j] = ' ';      //将棋盘初始化为空格}}//打印棋盘void DisplayBoard(char board[ROW][COL], int row, int col){int i = 0, 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){for (j = 0; j < col; j++)  //打印横线和竖线{printf("---");if (j :");scanf("%d%d", &m, &n);//判断坐标合法性if (m = 1 && n = 1){//判断坐标是否被占用if (board[m - 1][n - 1] == ' ')     //玩家不知道数组下标从零开始,输入是从(1 1)开始的,所以要减一{board[m - 1][n - 1] = '*';break;}elseprintf("坐标被占用,请重新输入\n");}elseprintf("坐标非法,请重新输入\n");}}//电脑下棋void ComputerMove(char board[ROW][COL], int row, int col){int m = 0, n = 0;printf("电脑走\n");while (1){m = rand() % row;n = rand() % col;//判断坐标是否被占用if (board[m][n] == ' '){board[m][n] = '#';break;}}}//判断棋盘是否满了int IsFull(char board[ROW][COL], int row, int col){int i = 0, j = 0, flag = 1;for (i = 0; i < row; i++){for (j = 0; j < col; j++)if (board[i][j] == ' ')flag = 0;}return flag;}//判断输赢char IsWin(char board[ROW][COL], int row, int col){int i = 0, j = 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][4] != ' ')return board[i][1];}for (i = 0; i < col; i++){if (board[0][i] == board[1][i]&& 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[4][i] != ' ')return board[1][i];}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[4][4] != ' ')return board[0][0];if (board[0][4] == board[1][1]&& board[1][1] == board[2][2]&& board[2][2] == board[3][3]&& board[3][3] == board[4][4]&& board[4][4] != ' ')return board[0][0];int ret = IsFull(board, row, col);if (ret)return 'Q';return 'C';}

第四部分--游戏效果

1,菜单的效果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pWy5Luj56CB55qE6aKc,size_20,color_FFFFFF,t_70,g_se,x_16

2,初始化棋盘的效果

911012b94d6546b59148f178781961a1.png

 3,游戏进行的效果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pWy5Luj56CB55qE6aKc,size_8,color_FFFFFF,t_70,g_se,x_16

4,游戏结束的效果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pWy5Luj56CB55qE6aKc,size_8,color_FFFFFF,t_70,g_se,x_16

第五部分:游戏总体实现代码。

game.h

#pragma once//game.h  游戏相关函数的声明、符号的声明、头文件的包含//符号的声明#define ROW 5#define COL 5//头文件的包含#include#include#include//函数的声明//初始化棋盘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);//判断输赢//游戏状态:*:玩家赢//   #:电脑赢//   Q:平局//   C:游戏继续char IsWin(char board[ROW][COL], int row, int col);

 test.c

#define _CRT_SECURE_NO_WARNINGS 1//test.c  测绘游戏的逻辑//game.c  游戏相关函数的实现//game.h  游戏相关函数的声明、符号的声明、头文件的包含#define _CRT_SECURE_NO_WARNINGS 1    //解决VS中scanf不安全问题#include"game.h"//自己创建的头文件用双引号void menu()     //菜单的实现{printf("1.play\n");printf("0.exit\n");}void game()     //游戏实现部分{//定义数组--存储数据char board[ROW][COL] = { 0 };//初始化棋盘InitBoard(board, ROW, COL);//打印棋盘DisplayBoard(board, ROW, COL);char ret;      //判断游戏状态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");elseprintf("平局\n");}int main(){int n = 0;srand((unsigned int)time(NULL));do {menu();printf("请选择:->");scanf("%d", &n);switch (n){case 1:game(); break;case 0:printf("退出游戏"); break;default:printf("选择错误,重新选择\n");}} while (n);return 0;}

 game.c

#define _CRT_SECURE_NO_WARNINGS 1//game.c  游戏相关函数的实现#include"game.h"//初始化棋盘void InitBoard(char board[ROW][COL], int row, int col){int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++)board[i][j] = ' ';      //将棋盘初始化为空格}}//打印棋盘void DisplayBoard(char board[ROW][COL], int row, int col){int i = 0, 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){for (j = 0; j < col; j++)  //打印横线和竖线{printf("---");if (j :");scanf("%d%d", &m, &n);//判断坐标合法性if (m = 1 && n = 1){//判断坐标是否被占用if (board[m - 1][n - 1] == ' ')     //玩家不知道数组下标从零开始,输入是从(1 1)开始的,所以要减一{board[m - 1][n - 1] = '*';break;}elseprintf("坐标被占用,请重新输入\n");}elseprintf("坐标非法,请重新输入\n");}}//电脑下棋void ComputerMove(char board[ROW][COL], int row, int col){int m = 0, n = 0;printf("电脑走\n");while (1){m = rand() % row;n = rand() % col;//判断坐标是否被占用if (board[m][n] == ' '){board[m][n] = '#';break;}}}//判断棋盘是否满了int IsFull(char board[ROW][COL], int row, int col){int i = 0, j = 0, flag = 1;for (i = 0; i < row; i++){for (j = 0; j < col; j++)if (board[i][j] == ' ')flag = 0;}return flag;}//判断输赢char IsWin(char board[ROW][COL], int row, int col){int i = 0, j = 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][4] != ' ')return board[i][1];}for (i = 0; i < col; i++){if (board[0][i] == board[1][i]&& 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[4][i] != ' ')return board[1][i];}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[4][4] != ' ')return board[0][0];if (board[0][4] == board[1][1]&& board[1][1] == board[2][2]&& board[2][2] == board[3][3]&& board[3][3] == board[4][4]&& board[4][4] != ' ')return board[0][0];int ret = IsFull(board, row, col);if (ret)return 'Q';return 'C';}