首页 > 其他分享 >三子棋小游戏

三子棋小游戏

时间:2023-01-18 12:31:26浏览次数:42  
标签:int 三子 小游戏 board printf row COL ROW

今天实现一个三子棋小游戏,虽然小,但是“麻雀虽小,五脏俱全”,通过三子棋游戏,我们来学习如何模块化地写代码。

首先,我们创建一个game.h头文件,再创建一个game.c和test.c源文件。

//头文件用来放各种函数的声明,以及引用库里的头文件;game.h用来写各个函数的内容;test.c用来将各个函数模块连接起来

#define _CRT_SECURE_NO_WARNINGS 1
#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 ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
char IsWin(char board[ROW][COL], int row, int col);

 //头文件(上图)

然后,开始在test.c中写代码。我们希望玩家在一开始的时候可以看到游戏的一个界面,并且决定自己玩还是不玩游戏,所以这里我们用一个do while循环,先让玩家看到界面,再选择自己玩不玩,并且如果想,可以一直玩下去:

void menu()
{
printf("***************************\n");
printf("*********三 子 棋**********\n");
printf("*********1.开始游戏********\n");
printf("*********0.退出游戏********\n");
printf("***************************\n");
}

//menu

int main()
{
int input = 0;
srand((unsigned int)time(NULL));//后面电脑随机生成坐标要用到rand函数
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;
}

这里我们把input作为while的条件,输入1开始游戏,0退出游戏。

接下来,我们就要开始写游戏的内容了也就是game函数。

下棋嘛,肯定要有棋盘,所以创建一个3*3的二维数组,元素全部是空格,就定义为board函数吧,在头文件里面声明一下,再在game.c里面写:

void InitBoard(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++)
{
board[i][j] = ' ';//空格不仅占位了,而且又看不见;0虽然看不见,但是不能占位
}
}
//memset(&board[0][0], ' ', row* col * sizeof(board[0][0]));
}

//也可以用memset函数

创建好了数组,但是什么都看不到,我们要加上一些条条框框,所以定义DisplayBoard函数:

void DisplayBoard(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++)
{
printf(" %c ", board[i][j]);
if(j<col-1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
}
printf("\n");
}
}

接下来就可以看到棋盘了:

三子棋小游戏_i++

棋盘做好了,就可以下棋了,你下一步,打印一下棋盘,电脑下一步,再打印一下棋盘,你再下一步,打印一下棋盘,电脑下一步......我们发现这里要用到循环,并且,下完之后,我们最好都去判断一下输赢:

void game()
{
//创建一个3*3的二维数组
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);
//电脑下棋
ComputerMove(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
}

这就是大概的流程,以及各自的函数;

首先,玩家下棋:

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 >= 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");
}
}
}

在玩家的眼中,大多是认为第一行第一列就是1 1,而不是0 0,所以我们就要按照玩家的习惯去写,下完了打印一下棋盘,

接着电脑下棋,这里就是个小游戏,不是什么人机大战,所以不会写的电脑很厉害,当然现在我也写不出来那种类似于人工智能的代码,所以就rand取随机数就好了(srand函数写外面,一次游戏调用一次就行了):

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] = '#';
break;
}
}
}

三子棋小游戏_i++_02

电脑的话坐标就直接从0开始到2结束就好了,省的麻烦,接着打印棋盘;

现在还有最后一个模块:判断输赢,也就是IsWin函数:

//判断输赢
//玩家赢 —— '*'
//电脑赢 —— '#'
//平局 —— 'Q'
//继续 —— 'C'
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][0] != ' ')
{
return board[i][0];
}
}
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
//判断是否是平局
if (IsFull(board, row, col))
return 'Q';
//游戏继续
return 'C';
}
int IsFull(char board[ROW][COL], int row, int  col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (i = 0; i < col; i++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}

我们一开始在头文件里面用define定义了常量ROW和COL,是为了以后可以快速的改变棋盘的大小,但是在判断输赢中又把我们的棋盘限制住了,但是呢,无论如何还是满足了作为“三”子棋的条件,以后学的更多了之后可以再改进改进。

这里IsWin函数中玩家和电脑赢返回的‘*’ ‘#‘正好是玩家和电脑输入的’*’ ‘#’,灵活地运用了函数的返回值:

void game()
{
//创建一个3*3的二维数组
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board,ROW,COL);
//显示棋盘
DisplayBoard(board,ROW,COL);
char ret = 0;
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 if (ret == 'Q')
printf("平局!\n");
}

而且把判断输赢放在循环外面,平局的判断放在里面,也减少了代码的重复;三子棋小游戏_#include_03

三子棋小游戏_#include_04

这样,我们的三子棋小游戏就写好了,思路不算复杂,主要还是认识并了解代码的模块化,毕竟这么写下来也有个300多行代码,如果还像以前做题目一样全部写在一个源文件里面,就太麻烦了。



最后,源码附上:

game.h :

#define _CRT_SECURE_NO_WARNINGS 1
#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 ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
char IsWin(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;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
board[i][j] = ' ';//空格不仅占位了,而且又看不见;0虽然看不见,但是不能占位
}
}
//memset(&board[0][0], ' ', row* col * sizeof(board[0][0]));
}

//void DisplayBoard(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++)
// {
// printf("%c ", board[i][j]);
// }
// printf("\n");
// }
//}//什么都看不到

//void DisplayBoard(char board[ROW][COL], int row, int col)
//{
// int i = 0;
// int j = 0;
// for (i = 0; i < row; i++)
// {
// printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
// if (i < row - 1)
// printf("---|---|---\n");
// }
//}//列数卡死了

void DisplayBoard(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++)
{
printf(" %c ", board[i][j]);
if(j<col-1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
}
printf("\n");
}
}

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 >= 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");
}
}
}

//电脑随机下棋
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] = '#';
break;
}
}
}

int IsFull(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (i = 0; i < col; i++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}

//判断输赢
//玩家赢 —— '*'
//电脑赢 —— '#'
//平局 —— 'Q'
//继续 —— 'C'
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][0] != ' ')
{
return board[i][0];
}
}
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
//判断是否是平局
if (IsFull(board, row, col))
return 'Q';
//游戏继续
return 'C';
}

test.c :

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

void menu()
{
printf("***************************\n");
printf("*********三 子 棋**********\n");
printf("*********1.开始游戏********\n");
printf("*********0.退出游戏********\n");
printf("***************************\n");
}

void game()
{
//创建一个3*3的二维数组
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board,ROW,COL);
//显示棋盘
DisplayBoard(board,ROW,COL);
char ret = 0;
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 if (ret == 'Q')
printf("平局!\n");
}

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;
}

标签:int,三子,小游戏,board,printf,row,COL,ROW
From: https://blog.51cto.com/u_15928027/6019198

相关文章

  • 【补档】15 Jan 2293. 极大极小游戏(每日一题)
    15Jan2293.极大极小游戏给你一个下标从0开始的整数数组nums,其长度是2的幂。对nums执行下述算法:设n等于nums的长度,如果n==1,终止算法过程。否则,创建......
  • 用Three.js写h5小游戏-3d飞机大战
    用Three.js写h5小游戏-飞机大战​​博主的话​​​​运行图片​​​​目录路径!​​index.html​​博主的话Three.js是js的一个3D引擎,比较复杂。比如光是Three.js就附带了10......
  • 适合编程初学者的开源项目:小游戏2048(安卓Compose版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。2048游戏规则一共16个单元格,初始时由2或者4构成。1、手指向一个方向滑动,所有格子会向那个方向运动。2......
  • 2293. 极大极小游戏
    2293.极大极小游戏给你一个下标从0开始的整数数组nums,其长度是2的幂。对nums执行下述算法:设n等于nums的长度,如果n==1,终止算法过程。否则,创建一个......
  • 【点击即用】自制的一款情侣小游戏
    开发前提学了3个月的编程,始终停留在书本阶段,并没有开发出产品。所以最近借鉴大神们的源码,加上自己的改动,做了一款在线小游戏(结合使用环境,主要照顾手机移动端,所以电脑端的体......
  • golang实现的一个小游戏–猜数字
    随机生成一个数字,输入一个数字看是否匹对,匹配则结速,反之提示是大了还是小了,代码如下:packagemainimport("bufio""fmt""math/rand""os""strconv""time")var......
  • 适合编程初学者的开源项目:小游戏2048(鸿蒙ArkTS版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。2048游戏规则一共16个单元格,初始时由2或者4构成。1、手指向一个方向滑动,所有格子会向那个方向运动。2......
  • java猜数小游戏
    问题:程序自动生成一个1~100之间的随机数字,使用程序猜出这个数字是多少:Random可以随机生成一个随机数使用方法:导包创建对象Randomr=newRandom();//只有r是变......
  • 前端使用canvas实现贪吃蛇小游戏
    贪吃蛇是一款益智小游戏,通过点击上下左右四个按键控制蛇头移动。设计思路主要是设计蛇的身体和移动方法。将蛇的身体设置成一个数组,数组里存放蛇身每一节的xy坐标。游......
  • c语言实现三子棋
    前言:在此之前我们学习了循环,函数,数组等相关知识,我们来写一个小游戏练练手概述:代码大致分为三部分程序主函数,函数,声明函数(这一点我们在通讯录项目是就介绍过了,将代码分为三部......