五子棋(N子棋)
运用简单的C语言知识完成入门小游戏——五子棋(也可以是N子棋),N子棋即N子连续的棋子横竖或斜连城一线,便可胜利。要实现此游戏主要是以下几点:1.建立棋盘,2.电脑走和玩家(即我们)走,3.判断输赢。
首先,我们来建立棋盘,所建立的棋盘如下图所示:
棋盘在C语言中可以以二维数组的方式存储,我们把上图棋盘分解来看,首先横着看,第一行就是空格字符(棋子)空格和一条竖线这样几组组成,所以利用for循环在数组第一行上存着‘ ’“%c”\’ \’和‘|’ ,竖着看是由几组‘—’和‘|’组成的,也是利用for循环实现的。上图我们所建的是五行五列的棋盘,而N子棋需要的是N行N列,若要实现我们只需在.h的头文件里将行列设置成宏定义形式的就行了,如下图所示:
所以建立棋盘的代码如下所示:
void SetupBoard(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { int j = 0; 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"); } } }
然后,我们来编写让电脑和玩家下棋的代码,所谓下棋即在我们建立的二维数组board[ ][ ]内存放棋子,而电脑下的时候我们只需要把数组board[x][y]中的坐标x和y设置成随机数就行了。不管是玩家存放棋子还是电脑存放棋子的时候我们都要考虑到我们接下来所存放的位置是不是合法(是否在棋盘内)和我们所存放的位置是否已经被占用了。代码如下所示:
电脑下的时候:
void ComputerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("电脑走=>\n"); while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == \' \') { board[x][y] = \'x\'; break; } } }
我们下的时候,我们只需输入想要下的位置的坐标即可:
void PlayerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("玩家走=>\n"); while (1) { printf("请输入坐标=>"); scanf("%d%d", &x, &y); if (x >= 0 && x < row && y >= 0 && y <= col) { if (board[x][y] == \' \') { board[x][y] = \'0\'; break; } else { printf("该坐标被占用,请重新输入!\n"); } } else { printf("坐标不存在,请重新输入!\n"); } } }
最后要解决的问题就是判断输赢了,判断的时候我们要从横着竖着和斜着这三方面考虑,所以我们需要在建立一个一维数组数组大小为N(N子成龙),一维数组分三次使用,分别来存放棋盘上横着的竖着的和斜着的棋子,这样我们只需每次遍历一维数组看看里面所有的值是否都相等。
当然下棋不止有输赢,还有可能平局,而所谓平局就是棋盘已经满了,没有地方可以下了(二维数组已满,无法在存放值了),这时候我们只需编写一个函数来判断棋盘是否已满即可,而这个函数的思想就是遍历整个二维数组看看有没有值为空的位置了,函数代码块如下:
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; int j = 0; int q = 0; char a[100] = { \'0\' }; int count = 0; for (i = 0; i < row; i++) { count = 0; for (j = 0; j < col; j++) { a[j] = board[i][j]; } for (q = 0; q <CH; q++) { if (a[q] == a[q + 1]) count++; else break; } if (count == row-1) { return board[i][0]; } } count = 0; for (j = 0; j < col; j++) { count = 0; for (i = 0; i < row; i++) { a[i] = board[i][j]; } for (q = 0; q <CH; q++) { if (a[q] == a[q + 1]) count++; else break; } if (count == (col-1)) { return board[0][j]; } } count = 0; for (i = 0; i < row; i++) { a[i] = board[i][i]; } for (j = 0; j < col - 1; j++) { if (a[j] == a[j + 1]) { count++; } else break; } if (count == (row - 1)) return board[0][0]; count = 0; for (i = 0; i < row; i++) { a[i] = board[i][row - 1 - i]; } for (j = 0;j < col - 1; j++) { if (a[j] == a[j + 1]) { count++; } else break; } if (count == (row - 1)) return board[0][row - 1]; if (IsFull(board, row, col)) { return \'T\'; } else return \' \'; }
考虑完以上三个问题,一个游戏基本就可以完成了。完整代码如下:
game.h #include <stdio.h> #include <time.h> #include <stdlib.h> #define ROW 5 #define COL 5 #define CH 5 //N子棋,CH个棋子成龙 void InitBoard(char board[ROW][COL], int row, int col); // 棋盘初始化 void SetupBoard(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); //判断输赢或平局 void PlayerMove(char board[ROW][COL], int row, int col); //玩家下棋 int IsFull(char board[ROW][COL], int row, int col); //判断棋盘是否满了 game.c #define _CRT_SECURE_NO_WARNINGS 1 #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 (j = 0; j < col; j++) { board[i][j] = \' \'; } } } void SetupBoard(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { int j = 0; 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"); } } } void ComputerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("电脑走=>\n"); while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == \' \') { board[x][y] = \'x\'; break; } } } void PlayerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("玩家走=>\n"); while (1) { printf("请输入坐标=>"); scanf("%d%d", &x, &y); if (x >= 0 && x < row && y >= 0 && y <= col) { if (board[x][y] == \' \') { board[x][y] = \'0\'; break; } else { printf("该坐标被占用,请重新输入!\n"); } } else { printf("坐标不存在,请重新输入!\n"); } } } char IsWin(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; int q = 0; char a[100] = { \'0\' }; int count = 0; for (i = 0; i < row; i++) { count = 0; for (j = 0; j < col; j++) { a[j] = board[i][j]; } for (q = 0; q <CH; q++) { if (a[q] == a[q + 1]) count++; else break; } if (count == row-1) { return board[i][0]; } } count = 0; for (j = 0; j < col; j++) { count = 0; for (i = 0; i < row; i++) { a[i] = board[i][j]; } for (q = 0; q <CH; q++) { if (a[q] == a[q + 1]) count++; else break; } if (count == (col-1)) { return board[0][j]; } } count = 0; for (i = 0; i < row; i++) { a[i] = board[i][i]; } for (j = 0; j < col - 1; j++) { if (a[j] == a[j + 1]) { count++; } else break; } if (count == (row - 1)) return board[0][0]; count = 0; for (i = 0; i < row; i++) { a[i] = board[i][row - 1 - i]; } for (j = 0;j < col - 1; j++) { if (a[j] == a[j + 1]) { count++; } else break; } if (count == (row - 1)) return board[0][row - 1]; if (IsFull(board, row, col)) { return \'T\'; } else return \' \'; } 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; } test.c #define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void menu() { printf("--------N子棋游戏-------\n"); printf("---------1.play---------\n"); printf("---------0.exit---------\n"); printf("------------------------\n"); } void game() { char board[ROW][COL] = { 0 }; char ret = 0; InitBoard(board, ROW, COL);//初始化棋盘 SetupBoard(board, ROW, COL);//建造棋盘 while (1) { ComputerMove(board, ROW, COL);//电脑走 ret = IsWin(board, ROW, COL);//判断输赢 if (ret != \' \') break; SetupBoard(board, ROW, COL); PlayerMove(board, ROW, COL);//玩家走 ret = IsWin(board, ROW, COL);//判断输赢 if (ret != \' \') break; SetupBoard(board, ROW, COL); } if (ret == \'x\') { printf("电脑赢!\n"); } if (ret == \'0\') { printf("恭喜你赢了!\n"); } else if (ret == \'T\') { printf("平局!\n"); } } int main() { int put = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请选择(0或1)=>"); scanf("%d", &put); switch (put) { case 1: game(); break; case 0: printf("退出游戏!\n"); break; default: printf("请输入0或1!输入错误,请重新输入!\n"); break; } } while (put); return 0; }
代码实现结果如下: