前言,打印游戏菜单等固定格式不再赘述,如有疑问,请查看最后相关代码也欢迎大家评论中与我一起讨论~~~这里重点讲三子棋实现逻辑过程
注:因为实现此逻辑过程使用的函数较多,这里我们将准备三个文件:
1.game.h(头文件:定义所需常量,函数声明主要是这两种等等)
2.game.c(函数实现)
3.test.c(测试源文件)
目录
1.准备一个二维数组存储三子棋数据(横坐标x,纵坐标y,值)
2.初始化棋盘(将二维数组数据初始化为空格)
3.打印棋盘(分为数据行和分隔行)
4.开始玩游戏
4.1输入位置坐标合法性
4.2随机生成坐标
4.3判断输赢
1.准备一个二维数组存储三子棋数据(横坐标x,纵坐标y,值)
? ?因为横坐标和纵坐标值不确定,所以把它定义在game.h中方便使用和后期修改
//将三子棋数据存放于二维数组中
char chessData[ROW][COL] = {0};
?2.初始化棋盘(将二维数组数据初始化为空格)
? ? 首先在game.h头文件中声明,然后在game.c文件中实现,最后在test.c中调用(两个.c源文件记得引用game.h头文件哦!!!#include "game.h")
//初始化三子棋(game.h头文件中)
void InitChess(char chessData[ROW][COL],int row, int col);
//对三子棋数据进行初始化为空格,保证输出格式规范
void InitChess(char chessData[ROW][COL], int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
chessData[i][j] = ' ';
}
}
}
//1.初始化三子棋
InitChess(chessData, ROW, COL);
? 为什么要初始化为空格呢?因为我们想要实现的棋盘是这样子的:
方便打印我们将三子棋数据初始化为' '。?
3.打印棋盘(分为数据行和分隔行)
? ?首先是数据行(紫色框框),再然后是分隔行(蓝色框框),所以我们每一行打完要进行换行
? ?实现如下:
//打印三子棋盘
void printChess(char chessData[ROW][COL], int row, int col);
void printChess(char chessData[ROW][COL], int row, int col) {
//一是数据行,二是分隔行
for (int i = 0; i < row; i++) {
//打印数据行
for (int j = 0; j < col; j++) {
printf(" %c ", chessData[i][j]);
if (j < col - 1) printf("|"); //避免多打印一列|
}
printf("\n");
//打印分隔行
if (i < row - 1) { //避免多打印一行分隔行
for (int k = 0; k < col; k++) {
printf("---");
if(k < col-1) printf("|");
}
}
printf("\n");
}
}
//2.打印三子棋盘
printChess(chessData, ROW, COL);
?准备棋盘结束.........
4.开始玩游戏
4.1输入位置坐标合法性
? ? ?玩家输入:接收键盘输入坐标,并判断坐标合理性(x>=1且x<=最大行,y>=1且y<=最大列)
? ? ?进一步若该坐标位置未被占用,则为'*',且循环结束,否则提示玩家继续输入
//玩家输入
void player_move(char chessData[ROW][COL], int row, int col);
//玩家输入
void player_move(char chessData[ROW][COL], int row, int col) {
int x = 0, y = 0;
while (1) {
printf("请玩家输入坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (chessData[x-1][y-1] == ' ') {
chessData[x-1][y-1] = '*';
break;
}
else {
printf("该位置被占用,请重新输入\n");
}
}
else {
printf("该坐标错误,请重新输入\n");
}
}
}
4.2随机生成坐标
? ? ?玩家输入后电脑输入,这个过程直到判断输赢完毕才可结束(玩家输入后电脑输入)
? ? ?随机生成x,y会用到srand()函数(随机数生成器,保证数据合理性)和rand(),对应包含头文件为<stdlib.h>,<time.h>,具体使用请查看cplusplus.com - The C++ Resources Network
//电脑输入
void computer_move(char chessData[ROW][COL], int row, int col);
在进入模式选择前调用srand()函数保证玩家一开始进行游戏,随机数变默默进行生成准备
//电脑生成坐标
void computer_move(char chessData[ROW][COL], int row, int col) {
int x = 0, y = 0;
printf("电脑输入:>\n");
while (1) {
x = rand() % row;
y = rand() % col;
if (chessData[x][y] == ' ') {
chessData[x][y] = '#';
break;
}
}
}
? ? ? ? ? 开始测试玩游戏后会发现我们会无限循环输入坐标并且电脑也会无限生成坐标,所以必须有循环终止条件.
4.3判断输赢
? ? ? ? ? 循环终止条件有三种,第一种是玩家赢了(*),第二种是电脑赢了(#),第三种是平局(Q),不然则游戏继续。这里我们准备一个result来进行比较char result = 'R';默认是游戏继续。
? ? ? ? ? 这里三子棋赢的方式可以分为四种:行成三,列成三,左对角线成三,右对角线成三。如下几张图所示:
总之就是四种,不同颜色的线分别代表一种
平局就要单独判断棋盘是否已满
//判断输赢
char is_win(char chessData[ROW][COL], int row, int col);
//判断棋盘是否满
int isFull(char chessData[ROW][COL], int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (chessData[i][j] == ' ') {
return 0;
}
}
}
return 1;
}
//判断输赢
char is_win(char chessData[ROW][COL], int row, int col) {
//竖成三
for (int i = 0; i < row; i++) {
if (chessData[0][i] == chessData[1][i] && chessData[1][i] == chessData[2][i] && chessData[0][i] != ' ') {
//printf("i");
return chessData[0][i];
}
}
//横成三
for (int j = 0; j < col; j++) {
if (chessData[j][0] == chessData[j][1] && chessData[j][1] == chessData[j][2] && chessData[j][0] != ' ') {
//printf("j");
return chessData[0][j];
}
}
//左对角线
if (chessData[0][0] == chessData[1][1] && chessData[1][1] == chessData[2][2] && chessData[0][0] != ' ') {
//printf("left");
return chessData[0][0];
}
//右对角线
if (chessData[0][2] == chessData[1][1] && chessData[1][1] == chessData[2][0] && chessData[0][2] != ' ') {
//printf("right");
return chessData[0][2];
}
if (isFull(chessData,row,col)) {
return 'Q';
}
return 'R';
}
最后调用:
//开始玩游戏
while (1) {
//1.玩家输入
player_move(chessData, ROW, COL);
//判断输赢
result = is_win(chessData, ROW, COL);
//printf("result=%c", result);
if (result != 'R') break;
printChess(chessData, ROW, COL);
//2.电脑输入
computer_move(chessData, ROW, COL);
result = is_win(chessData, ROW, COL);
if (result != 'R') break;
printChess(chessData, ROW, COL);
}
if (result == '*') {
printf("玩家胜利!!!\n");
printChess(chessData, ROW, COL);
}else if (result == '#') {
printf("电脑胜利!!!\n");
printChess(chessData, ROW, COL);
}else if (result == 'Q') {
printf("平局了!!!\n");
printChess(chessData, ROW, COL);
}
我的思路到此结束~接下来是我的全部代码细数奉上~~~
game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
//初始化三子棋
void InitChess(char chessData[ROW][COL],int row, int col);
//打印三子棋盘
void printChess(char chessData[ROW][COL], int row, int col);
//玩家输入
void player_move(char chessData[ROW][COL], int row, int col);
//电脑输入
void computer_move(char chessData[ROW][COL], int row, int col);
//判断输赢
char is_win(char chessData[ROW][COL], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//对三子棋数据进行初始化为空格,保证输出格式规范
void InitChess(char chessData[ROW][COL], int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
chessData[i][j] = ' ';
}
}
}
void printChess(char chessData[ROW][COL], int row, int col) {
//一是数据行,二是分隔行
for (int i = 0; i < row; i++) {
//打印数据行
for (int j = 0; j < col; j++) {
printf(" %c ", chessData[i][j]);
if (j < col - 1) printf("|");
}
printf("\n");
//打印分隔行
if (i < row - 1) {
for (int k = 0; k < col; k++) {
printf("---");
if(k < col-1) printf("|");
}
}
printf("\n");
}
}
//玩家输入
void player_move(char chessData[ROW][COL], int row, int col) {
int x = 0, y = 0;
while (1) {
printf("请玩家输入坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (chessData[x-1][y-1] == ' ') {
chessData[x-1][y-1] = '*';
break;
}
else {
printf("该位置被占用,请重新输入\n");
}
}
else {
printf("该坐标错误,请重新输入\n");
}
}
}
//电脑生成坐标
void computer_move(char chessData[ROW][COL], int row, int col) {
int x = 0, y = 0;
printf("电脑输入:>\n");
while (1) {
x = rand() % row;
y = rand() % col;
if (chessData[x][y] == ' ') {
chessData[x][y] = '#';
break;
}
}
}
//判断棋盘是否满
int isFull(char chessData[ROW][COL], int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (chessData[i][j] == ' ') {
return 0;
}
}
}
return 1;
}
//判断输赢
char is_win(char chessData[ROW][COL], int row, int col) {
//竖成三
for (int i = 0; i < row; i++) {
if (chessData[0][i] == chessData[1][i] && chessData[1][i] == chessData[2][i] && chessData[0][i] != ' ') {
//printf("i");
return chessData[0][i];
}
}
//横成三
for (int j = 0; j < col; j++) {
if (chessData[j][0] == chessData[j][1] && chessData[j][1] == chessData[j][2] && chessData[j][0] != ' ') {
//printf("j");
return chessData[0][j];
}
}
//左对角线
if (chessData[0][0] == chessData[1][1] && chessData[1][1] == chessData[2][2] && chessData[0][0] != ' ') {
//printf("left");
return chessData[0][0];
}
//右对角线
if (chessData[0][2] == chessData[1][1] && chessData[1][1] == chessData[2][0] && chessData[0][2] != ' ') {
//printf("right");
return chessData[0][2];
}
if (isFull(chessData,row,col)) {
return 'Q';
}
return 'R';
}
?test.c
#include "game.h"
void menu() {
printf("********************************************\n");
printf("************ 欢迎开启三子棋游戏 ************\n");
printf("************ 1. begin ************\n");
printf("************ 0. exit ************\n");
}
void game() {
//将三子棋数据存放于二维数组中
char chessData[ROW][COL] = {0};
char result = 'R';
//准备工作
//1.初始化三子棋
InitChess(chessData, ROW, COL);
//2.打印三子棋盘
printChess(chessData, ROW, COL);
//开始玩游戏
while (1) {
//1.玩家输入
player_move(chessData, ROW, COL);
//判断输赢
result = is_win(chessData, ROW, COL);
//printf("result=%c", result);
if (result != 'R') break;
printChess(chessData, ROW, COL);
//2.电脑输入
computer_move(chessData, ROW, COL);
result = is_win(chessData, ROW, COL);
if (result != 'R') break;
printChess(chessData, ROW, COL);
}
if (result == '*') {
printf("玩家胜利!!!\n");
printChess(chessData, ROW, COL);
}else if (result == '#') {
printf("电脑胜利!!!\n");
printChess(chessData, ROW, COL);
}else if (result == 'Q') {
printf("平局了!!!\n");
printChess(chessData, ROW, COL);
}
}
int main() {
int input = 0;
srand((unsigned int)time(NULL));
do {
//打印菜单栏
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("已退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
?嘿嘿,具体三子棋实现过程到此结束~~~
|