阅读量:0
一.自定义头文件(game.h)
放入源文件需要用到的标准库头文件和函数的声明
ROW 和COL为棋盘的行和列,三子棋嘛,肯定为3啦
#pragma once #include<stdio.h> #include<String.h> #include<stdlib.h> #include<time.h> #define ROW 3 #define COL 3 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 ComputerBoard(char board[ROW][COL], int row, int col); char IsWin(char board[ROW][COL], int row, int col);
二.源文件(test.c和game.c)
1.test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void menu() { printf("***********************************\n"); printf("************1.开始游戏*************\n"); printf("************0.退出游戏*************\n"); printf("***********************************\n"); } void game() { char board[ROW][COL] = {0}; InitBoard(board,ROW,COL);//初始化棋盘 DisplayBoard(board, ROW, COL);//显示棋盘 while (1) { PlayerMove(board, ROW, COL);//玩家输入坐标 DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况 if (IsWin(board, ROW, COL) != 'C') {//满了或者有一方赢了就break break; } ComputerBoard(board, ROW, COL);//人机输入坐标 DisplayBoard(board, ROW, COL);//再显示一边棋盘当前的情况 if (IsWin(board, ROW, COL) != 'C') {//人机输入坐标后再判断一下满没满或者双方有没有赢的,满足就break break; } } if (IsWin(board, ROW, COL) == '*') { printf("玩家赢\n"); } else if (IsWin(board, ROW, COL) == '#') { printf("电脑玩家赢\n"); } else if (IsWin(board, ROW, COL) == 'D') { printf("平局\n"); } } int main() { int input=0; srand((unsigned int)time(NULL)); do { menu(); printf("请输入:"); scanf("%d", &input); switch(input){ case 1: printf("进入游戏\n"); game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入:\n"); } } while (input); return 0; }
(1)void game()解释
1.先创建一个游戏面板二维数组
字符型的
char board[ROW][COL] = {0};
2.初始化棋盘
InitBoard(board,ROW,COL);
3.显示棋盘
在真正开始游戏之前肯定得先给玩家看一下棋盘滴啦
DisplayBoard(board, ROW, COL);//显示棋盘
4.while()循环
在玩家输入坐标之后
判断一下棋盘是否满了或者有一方赢了就break
同理,人机输入坐标后也是如此
(每次执行IsWin都会返回一个字符)
while (1) { PlayerMove(board, ROW, COL);//玩家输入坐标 DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况 if (IsWin(board, ROW, COL) != 'C') { break; } ComputerBoard(board, ROW, COL);//人机输入坐标 DisplayBoard(board, ROW, COL);//再显示一边棋盘当前的情况 if (IsWin(board, ROW, COL) != 'C') { break; } }
注意:符号' C '说明没满并且没有一方赢
5.判赢
在while()循环出来后,肯定是有一方赢了或者满了
如果返回的符号为‘ * ’则玩家赢
如果返回的符号为‘ # ’则人机(电脑玩家)赢
如果返回的符号为‘ D ’则平局
具体可以看一下下文的IsWin函数具体实现,有注解
if (IsWin(board, ROW, COL) == '*') { printf("玩家赢\n"); } else if (IsWin(board, ROW, COL) == '#') { printf("电脑玩家赢\n"); } else if (IsWin(board, ROW, COL) == 'D') { printf("平局\n"); }
2.game.c
(1)初始化棋盘(InitBoard)
void InitBoard(char board[ROW][COL], int row, int col) { //InitBoard(board,ROW,COL);//初始化棋盘 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { board[i][j] = ' '; } } /*或者直接写这一行代码也可以memset(&board[0][0], ' ', row * col * sizeof(board[0][0]));*/ }
(2)显示棋盘(DisplayBoard)
void DisplayBoard(char board[ROW][COL], int row, int col) { //DisplayBoard(board, ROW, COL);//显示棋盘 for (int i = 0; i < row; i++) { if (i < 2) { printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]); printf("---|---|---\n"); } else { printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]); } } }
效果如图:
(3)玩家输入坐标(PlayerMove)
玩家的棋子是' * '号
void PlayerMove(char board[ROW][COL], int row, int col) { //PlayerMove(board, ROW, COL);//玩家输入坐标 int x, y; printf("玩家下棋:>\n"); printf("请输入棋子的坐标:"); scanf("%d %d", &x, &y); while (1) { if (x <= 0 && x >= 4 && y <= 0 && y >= 4) { printf("坐标非法,请重新输入\n"); } else if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else { printf("坐标已经被占用,请重新输入坐标\n"); break; } } }
效果如图:
(4)人机下棋(ComputerBoard)
人机的棋子是' # '号
void ComputerBoard(char board[ROW][COL], int row, int col) { //ComputerBoard(board, ROW, COL);//人机输入坐标 //DisplayBoard(board, ROW, COL);//然后显示一边棋盘当前的情况 printf("电脑下棋:>\n"); int x, y; while (1) { x = rand() % row;//模上一个3之后得到的数的范围肯定为0~2 y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } }
效果如图:
可以看到我们在输入坐标后紧跟着人机也输入了坐标
(5)判定双方是否赢了(IsWin)
char IsWin(char board[ROW][COL], int row, int col) { //IsWin(board, ROW, COL) 判定双方是否赢了 //判断行是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了 for (int i = 0; i < row; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&&board[i][2]!=' ') { return board[i][0];//返回 } } //判断列是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了 for (int j = 0; j < col; j++) { if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ') { return board[0][j];//返回 } } //判断两对角线是否相等(注意不为空),相等的话就返回其对应的棋子,再下定论谁赢了 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ') { return board[0][0];//返回 } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ') { return board[0][2];//返回 } //判断是否满了,返回不同的字符执行不同的效果 if (IsFull(board, ROW, COL)) { return 'D';//返回 } else { return 'C';//返回 } }
大致效果:
(6)判满(对应(5)中的函数IsFull())
注意该函数写在IsWin()函数的上边,否则加上声明
int IsFull(char board[ROW][COL], int row, int col) { //IsFull(board, ROW, COL)判满 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (board[i][j] == ' ') { return 0;//返回0说明没满,if(0)相当于false } } } return 1;//相当于true }
一键三连哦,感谢大家的阅读!