赞
踩
目录
五子棋不必多介绍了,大家小时候都玩过哈。
我们要通过程序实现这个小游戏,大体上的构思得有:
游戏流程:运行游戏>>打印棋盘>>下棋>>判断输赢
由此,我们声明如下函数、棋盘数组和回合数 (用于双人下棋时下不同棋子的判断)。
将这些都放在我创建的头文件game.h中方便其他文件使用:
- #include <stdio.h>
- #include <Windows.h>
-
- int map[19][19];//棋盘
- int flag;//回合数
-
- //初始化棋盘
- void init();
-
- //游戏菜单
- void menuView();
-
- //打印棋盘
- void gameView_ShowMap();
-
- //玩家下棋
- int playerMove(int x, int y);
-
- //判断输赢
- int isWin(int x, int y);
-
- //判断输赢
- void winView();
先进行游戏下棋,后进行判断输赢,比较符合do—while的特点。
- int main()
- {
- int input = 0;
- do
- {
- menuView();
- printf("请选择:");
- scanf("%d", &input);
- switch (input) {
- case 1:
- gameView();
- break;
- case 0:
- printf("退出游戏\n");
- break;
- default:
- printf("输入错误,请重新选择.\n");
- break;
- }
- } while (input);
- return 0;
- }
在此之前先将各种功能函数进行实现,最后将它们放入gameView整合。
- void init() {
- for (int i = 0; i < 19; i++) {
- for (int j = 0; j < 19; j++) {
- map[i][j] = 0;
- }
- }
- flag = 0;
- }
- void menuView() {
- printf("*************************\n");
- printf("***** 1. play ******\n");
- printf("***** 0. exit ******\n");
- printf("*************************\n");
- }
这里我选择设计了棋盘格和横纵坐标,我们可以根据需要自行设计。
- void gameView_ShowMap() {
- int i, j;
- printf(" ");
- for (i = 0; i < 19; i++) {//打印横坐标
- printf("%3d ",i);
- }
- printf("\n ");
- for (i = 0; i < 19; i++) {
- printf("+---");
- }
- printf("+\n");
-
- for (i = 0; i < 19; i++) {
-
- printf("%2d |", i);//每行输出前都先打印纵坐标
-
- for (j = 0; j < 19; j++) {
- printf(" %d ", map[i][j]);//打印棋子
- if (j < 18)
- printf("|");
- }
- printf("|\n");
-
- if(i<18)
- printf(" |");
- if(i==18)
- printf(" +");
- for (j = 0; j < 19; j++) {
- printf("---");
- if (j < 18)
- printf("+");
- }
- printf("+\n");
- }
- }
效果如下:
- int playerMove(int x, int y) {
- if (x >= 0 && x < 19 && y >= 0 && y < 19) {
- if (map[x][y] == 0) {
- if (flag % 2 == 0)
- map[x][y] = 1;//下黑子
- else
- map[x][y] = 2;//下白子
- //落子成功
- return 1;
- }
- else {
- //该位置已有棋子
- return 0;
- }
- }
- else {
- //坐标不合法
- return -1;
- }
- }
- int isWin(int x, int y) {
- int i, j;
- for (i = 0; i < 19; i++) {
- for (j = 0; j < 19; j++) {
- if (map[i][j] == 0) {
- continue;
- }
-
- //横着连成五子
- if (j < 15)
- if (map[i][j] == map[i][j + 1] && map[i][j] == map[i][j + 2]
- && map[i][j] == map[i][j + 3] && map[i][j] == map[i][j + 4])
- return map[i][j];
-
- //竖着连成五子
- if (i < 15)
- if (map[i][j] == map[i + 1][j] && map[i][j] == map[i + 2][j]
- && map[i][j] == map[i + 3][j] && map[i][j] == map[i + 4][j])
- return map[i][j];
-
- //左斜着连成五子-> " \ "
- if (i < 15 && j < 15)
- if (map[i][j] == map[i + 1][j + 1] && map[i][j] == map[i + 2][j + 2]
- && map[i][j] == map[i + 3][j + 3] && map[i][j] == map[i + 4][j + 4])
- return map[i][j];
-
- //右斜着连成五子-> " / "
- if (i < 15 && j > 4)
- if (map[i][j] == map[i + 1][j - 1] && map[i][j] == map[i + 2][j - 2]
- && map[i][j] == map[i + 3][j - 3] && map[i][j] == map[i + 4][j - 4])
- return map[i][j];
-
-
- }
- }
- return 0;
- }
i < 15
用于确保在检查垂直和左斜方向的连续五子时,起始位置 (i, j)
之后至少还有4个位置。因为五子连成一线需要五个连续的位置,所以确保从当前位置开始往下检查的时候不会超出数组的边界。
j < 15
用于确保在检查水平和左斜方向的连续五子时,起始位置 (i, j)
之后至少还有4个位置。同样,这是为了确保从当前位置开始往右检查的时候不会超出数组的边界。
j > 4
用于确保在检查右斜方向的连续五子时,起始位置 (i, j)
之前至少还有4个位置。这是为了确保从当前位置开始往左检查的时候不会超出数组的边界。
- void gameView()
- {
- init();
- int x = 0, y = 0;
- int ret = 0;//辅助判断坐标是否合法
- while (1) {
- gameView_ShowMap();
-
- printf("请输入要下棋的坐标:");
- scanf("%d %d", &x, &y);
-
- if (playerMove(x, y) == 0) {
- printf("\n!!!该坐标已被占用!!!\n");
- Sleep(2000);
- continue;
- }
- else if (playerMove(x, y) == -1) {
- printf("\n!!!请输入合法坐标!!!\n");
- Sleep(2000);
- continue;
- }
- else {
- flag++;//切换回合
- }
-
- if (isWin(x, y) == 0) {
- continue;
- }
-
- else if (isWin(x, y) == 1) {
- printf("黑子获胜\n");
- break;
- }
-
- else if (isWin(x, y) == 2) {
- printf("白子获胜\n");
- break;
- }
- }
-
- }
想要实现人机下棋可以看看我这篇文章《三子棋》 ,里面实现了人机下棋,读者可以自行模仿改进,实现其功能的重要函数可以在这篇文章中学习 rand&srand函数 。
- #include <stdio.h>
- #include <Windows.h>
- int map[19][19];//棋盘
- int flag;//回合数
-
- //初始化
- void init();
-
- //游戏菜单
- void menuView();
-
- //打印棋盘
- void gameView_ShowMap();
-
- //玩家下棋
- int playerMove(int x, int y);
-
- //判断输赢
- int isWin(int x, int y);
- #define _CRT_SECURE_NO_WARNINGS 1
- #include "game.h"
-
-
- void init() {
- for (int i = 0; i < 19; i++) {
- for (int j = 0; j < 19; j++) {
- map[i][j] = 0;
- }
- }
- flag = 1;
- }
-
-
- int isWin(int x, int y) {
- int i, j;
- for (i = 0; i < 19; i++) {
- for (j = 0; j < 19; j++) {
- if (map[i][j] == 0) {
- continue;
- }
-
- //横着连成五子
- if (j < 15)
- if (map[i][j] == map[i][j + 1] && map[i][j] == map[i][j + 2]
- && map[i][j] == map[i][j + 3] && map[i][j] == map[i][j + 4])
- return map[i][j];
-
- //竖着连成五子
- if (i < 15)
- if (map[i][j] == map[i + 1][j] && map[i][j] == map[i + 2][j]
- && map[i][j] == map[i + 3][j] && map[i][j] == map[i + 4][j])
- return map[i][j];
-
- //左斜着连成五子-> " \ "
- if (i < 15 && j < 15)
- if (map[i][j] == map[i + 1][j + 1] && map[i][j] == map[i + 2][j + 2]
- && map[i][j] == map[i + 3][j + 3] && map[i][j] == map[i + 4][j + 4])
- return map[i][j];
-
- //右斜着连成五子-> " / "
- if (i < 15 && j > 4)
- if (map[i][j] == map[i + 1][j - 1] && map[i][j] == map[i + 2][j - 2]
- && map[i][j] == map[i + 3][j - 3] && map[i][j] == map[i + 4][j - 4])
- return map[i][j];
-
-
- }
- }
- return 0;
- }
-
-
- int playerMove(int x, int y) {
- if (x >= 0 && x < 19 && y >= 0 && y < 19) {
- if (map[x][y] == 0) {
- if (flag % 2 == 0)
- map[x][y] = 1;//下黑子
- else
- map[x][y] = 2;//下白子
- //落子成功
- return 1;
- }
- else {
- //该位置已有棋子
- return 0;
- }
- }
- else {
- //坐标不合法
- return -1;
- }
- }
-
-
- void menuView() {
- printf("*************************\n");
- printf("***** 1. play ******\n");
- printf("***** 0. exit ******\n");
- printf("*************************\n");
- }
-
-
- void gameView_ShowMap() {
- int i, j;
- printf(" ");
- for (i = 0; i < 19; i++) {//打印横坐标
- printf("%3d ",i);
- }
- printf("\n ");
- for (i = 0; i < 19; i++) {
- printf("+---");
- }
- printf("+\n");
-
- for (i = 0; i < 19; i++) {
-
- printf("%2d |", i);//每行输出前先都打印纵坐标
-
- for (j = 0; j < 19; j++) {
- printf(" %d ", map[i][j]);
- if (j < 18)
- printf("|");
- }
- printf("|\n");
-
- if(i<18)
- printf(" |");
- if(i==18)
- printf(" +");
- for (j = 0; j < 19; j++) {
- printf("---");
- if (j < 18)
- printf("+");
- }
- printf("+\n");
- }
- }
- #define _CRT_SECURE_NO_WARNINGS 1
- #include "game.h"
-
- void gameView()
- {
- init();
- int x = 0, y = 0;
- int ret = 0;//辅助判断坐标是否合法
- while (1) {
- gameView_ShowMap();
-
- printf("请输入要下棋的坐标:");
- scanf("%d %d", &x, &y);
-
- if (playerMove(x, y) == 0) {
- printf("\n!!!该坐标已被占用!!!\n");
- Sleep(2000);
- continue;
- }
- else if (playerMove(x, y) == -1) {
- printf("\n!!!请输入合法坐标!!!\n");
- Sleep(2000);
- continue;
- }
- else {
- flag++;//切换回合
- }
-
- if (isWin(x, y) == 0) {
- continue;
- }
-
- else if (isWin(x, y) == 1) {
- printf("黑子获胜\n");
- break;
- }
-
- else if (isWin(x, y) == 2) {
- printf("白子获胜\n");
- break;
- }
- }
-
- }
-
- int main()
- {
- int input = 0;
- do
- {
- menuView();
- printf("请选择:");
- scanf("%d", &input);
- switch (input) {
- case 1:
- gameView();
- break;
- case 0:
- printf("退出游戏\n");
- break;
- default:
- printf("输入错误,请重新选择.\n");
- break;
- }
- } while (input);
- return 0;
- }
此代码可以替换int main主函数,用于测试函数功能是否正确,可以减少自行下棋测试时间
成功运行输出如下:
- int main()
- {
- int testflag = 0;
- //init测试代码
-
- init();
- if (flag != 0) {
- printf("init()错误");
- exit(0);
- }
- for (int i = 0; i < 19; i++) {
- for (int j = 0; j < 19; j++) {
- if (map[i][j]) {
- printf("init()错误");
- exit(0);
- }
- }
- }
- printf("init()测试成功\n");
- testflag++;
-
-
- //playerMove测试代码
-
- int result = 1;
- result &= playerMove(2, 2);
- result &= playerMove(2, 3);
- result &= playerMove(2, 4);
- result &= playerMove(2, 5);
- if (result != 1 || (map[2][2] && map[2][3] && map[2][4] && map[2][5]) != 1) {
- printf("playerMove()错误");
- exit(0);
- }
- flag = 1;
- result &= playerMove(2, 5);
- if (result != 0 || map[2][5] != 1) {
- printf("playerMove()错误");
- exit(0);
- }
- printf("playerMove()测试成功\n");
- testflag++;
-
-
- //isWin测试代码
-
- playerMove(2, 1);
- if (isWin(2, 1)) {
- printf("isWin()错误");
- exit(0);
- }
- playerMove(1, 0);
- playerMove(3, 2);
- playerMove(4, 3);
- playerMove(5, 4);
- if (isWin(1, 0) != 2) {
- printf("isWin()错误");
- exit(0);
- }
- printf("isWin()测试成功\n");
- testflag++;
-
-
- if (testflag == 3) {
- printf("service代码测试成功\n");
- }
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。