三子棋游戏的实现
三子棋游戏是一个常见的游戏,我们今天来用C语言实现一下这个游戏.
- 首先先打印一个菜单,供玩家选择,1代表玩游戏,0代表退出
void menu() { printf("***************************************\n"); printf("**** 1.play 0.exit ****\n"); printf("***************************************\n"); }
- 我们来看主函数部分,先做个do…while循环,把菜单放进循环,循环条件为input,只要input不为0,即不退出游戏,玩家都可以重新输入继续玩:
int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请输入:\n"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("选择错误,请重新选择!\n"); break; } } while (input); return 0; }
- 游戏的整个算法实现部分
(1)创建一个二维数组来存放棋盘信息;
(2)在game.h头文件引用ROW(行),COL(列),方便修改行和列;
(3)InitBoard()函数用来初始化数组,即初始化棋盘;
(4)DisplayBoard()函数用来打印棋盘;
(5)PlayerMove()函数实现玩家下棋的操作;
(6)ComputerMove()函数实现电脑下棋的操作;
(7)Iswin()函数用来接收具体情况的返回值,不同的返回值用来判断玩家胜还是电脑胜还是平局还是游戏继续;
每个函数都是把数组(棋盘)和行和列传进去,因为要用这个数组和它的行和列进行具体的操作;
void game() { char ret = 0; char board[ROW][COL] = {0}; InitBoard(board, ROW, COL); DisplayBoard(board,ROW,COL); //下棋 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"); }
- InitBoard()函数
初始化数组,将数组里面全部初始化为空格,方便下面打印棋盘和显示给玩家看:
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] = ' '; } } }
- DisplayBoard()函数
打印棋盘,首先我们知道棋盘像一个’ # ‘一样,我们可以将棋盘分为五个部分,首先printf(" %c ", board[i][j]),打印一个格子的空格,然后有打印’ | ‘的每次循环比前面的少一次,因为继续打印会出到棋盘外面;打印分割行使用的是’ — ',然后两次循环就可以打印出棋盘了;
void DisplayBoard(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++) { //1.打印一行的数据 printf(" %c ", board[i][j]); if (j < col - 1) printf("|"); } printf("\n"); //2.打印分割行 if (i < row - 1) { for (j = 0; j < col; j++) { printf("---"); if (j < col - 1) printf("|"); } printf("\n"); } } }
打印出来的棋盘如下:
- PlayerMove()函数
实现玩家下棋的具体操作,首先让玩家输入一个坐标,在玩家的角度坐标是多少就是多少,但是在数组的角度,坐标是从0开始的,所以玩家输入的坐标总比数组实际的坐标大1,所以判断坐标应该以玩家的为准,如board[x - 1][y - 1] == ’ ‘,判断玩家输入的坐标是否被占用,若没被占用就输入’ * ',否则提示玩家,代码如下:
void PlayerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("请输入坐标:\n"); scanf("%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"); } }
- ComputerMove()函数
实现电脑下棋的具体操作,首先定义两个变量x,y,为电脑输入的坐标,而这两个值需要生成两个随机数,这里使用rand()函数生成,而使用rand()函数需要用srand()函数生成一个为伪随机数生成器种子,具体使用方法在主函数,放在主函数是因为防止在game()函数里面过于频繁使用,以至于生成的随机值过于相近;rand()函数生成的随机数模3,取余数只能是0,1,2,即可生成随机坐标,代码如下:
void ComputerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("电脑走:\n"); while (1) { x = rand() % 3; //随机数模3,取余数只能是0,1,2 y = rand() % 3; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } }
- Iswin()函数
用来接收具体情况的返回值,用来判断输赢,因为判断输赢的情况有四种,玩家赢,电脑赢,平局或者游戏继续,所以我们设定4种返回值接收;Iswin()函数应该返回4种状态:玩家赢返回 ’ * ’ ,电脑赢返回 ’ # ’ ,和局返回 ’ Q ',游戏继续返回 ’ C ';这里还调用了Isfull函数用来判断数组是否满了,满了返回1,不满返回0.
先判断玩家或者电脑赢的情况,分为横三行,竖三列和两个对角线,具体是三个符号连续相等即可,且不可以等于空格,返回类型直接返回符号,返回’ * ‘是玩家赢,返回’ # '是电脑赢,在主函数接收;判断平局和游戏继续也是在主函数接收.
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][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[1][i] != ' ') { return board[1][i]; } } //两个对角 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') return board[1][1]; if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ') return board[1][1]; //判断是否和局 if (1 == IsFull(board,ROW,COL)) { return 'Q'; } return 'C'; }
IsFull()函数的实现
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; }
上面就是整个三子棋游戏实现的过程,同时还有游戏的头文件,里面包括函数的声明和常用头文件的引用:
#pragma once #define ROW 3 #define COL 3 #include <stdio.h> #include <stdlib.h> #include <time.h> //函数声明 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);