【小朋友的三子棋】
三子棋游戏
文章目录
前言
今天向大家分享用c语言来实现三子棋,至于为啥说是小朋友的三子棋,相信大家看完后就会有答案了。
一 游戏说明
我们会创建三个分文件来实现该游戏:text.c && game.c &&game.h
text.c:实现游戏的整体思路
game.c:游戏内部函数的实现
game.h:游戏内部函数的定义
二 实现步骤
1.用text函数实现菜单打印
void menu()
{
printf("*****************************\n");
printf("*****1:玩游戏 0:退出游戏*****\n");
printf("*****************************\n");}
void text()
{
int intput = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入:>");
scanf("%d", &intput);//scanf函数一定要放在循环语句中
switch (intput)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (intput);
}
int main()
{
text();
return 0;
}
这样我们便得到了一个菜单,玩家可以选择是否玩游戏
2.初始化棋盘以及打印棋盘
char board [ROW][COL] = {0};
Initboard(board,ROW,COL);//初始化棋盘
playboard(board,ROW,COL);//打印棋盘
具体的代码实现:
void Initboard(char board[ROW][COL], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void playboard(char board[ROW][COL], int row, int col)
{
int i ;
int j ;
for (i = 0; i < row; i++)
{
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");
}
}
}
棋盘初始化是为了让board中的每一个元素都初始化为' ',打印棋盘时值得注意的是为了让棋盘更加的美观,每一行最后一个'|'不打印,最后一个分割行不打印,用的是if语句实现的,具体的可以参考我写的代码。
3 玩家和电脑下棋
//玩家下棋
playermove(board, ROW, COL);
playboard(board, ROW, COL);
//电脑下棋
computermove(board, ROW, COL);
playboard(board, ROW, COL);
玩家和电脑下棋后还要打印棋盘,方便玩家进行下一步
4 玩家移动和电脑移动
void playermove(char board[ROW][COL], int row, int col)
{
int x = 0, y = 0;
printf("玩家下棋;>\n");
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;//用break语句跳出循环,防止一直输入坐标
}
else
printf("该坐标被占用\n");
}
else
printf("输入错误,请重新输入:>");
}
}
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;
}
}
}
玩家落棋是用playermove函数实现的,其中玩家每一次成功落棋后都要用break跳出循环,以防一直输入坐标。电脑落棋是用computermove函数实现的,其中随机数的设计用到了时间戳,这里便不在多说。
5 判断输赢
我们可以知道三子棋只要有一方三个数连在一起时就获胜,无论是横向纵向还是斜向,那么我们该如何判断有三个数连在一起呢?
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[0][0];
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[2][0] != ' ')
return board[2][0];
if (1 == IsFull(board, ROW, COL))
return 'Q';
return 'C';
}
上面的横三行 竖三列 斜向都很好理解,关键是后面的'Q','C'怎么理解?
我们这样来看:
游戏的结果有下面这几种情况
- 玩家赢
- 电脑赢
- 平局
- 继续游戏
IsWin函数实现后会返回一个值,为了让代码更加简单,我们不妨假设玩家赢了返回'*'.电脑赢了返回'$',平局就返回'Q',继续游戏就返回'C'
有了这个理解我们就可以写代码了
while (1)
{
//玩家下棋
playermove(board, ROW, COL);
playboard(board, ROW, COL);
//判断玩家的输赢
ret=IsWin(board,ROW,COL);
if (ret != 'C')
break;
//电脑下棋
computermove(board, ROW, COL);
playboard(board, ROW, COL);
//判断电脑的输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
printf("玩家赢\n");
else if (ret == '$')
printf("电脑赢\n");
else
printf("平局\n");
}
IsWin函数函数中的IsFull函数又是什么鬼呢?
是这样的:当棋盘已经被下满了的时候IsFull函数就返回1,否则就返回0。
//返回1表示棋盘满了
//返回0表示棋盘没满
int IsFull(char board[ROW][COL],int row,int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;//没有满
}
}
return 1;//满了
这样我们就完成了这个小游戏
三 代码实现
在text.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"
void game()
{
char board [ROW][COL] = {0};
Initboard(board,ROW,COL);//初始化棋盘
playboard(board,ROW,COL);//打印棋盘
char ret = 0;
while (1)
{
//玩家下棋
playermove(board, ROW, COL);
playboard(board, ROW, COL);
//判断玩家的输赢
ret=IsWin(board,ROW,COL);
if (ret != 'C')
break;
//电脑下棋
computermove(board, ROW, COL);
playboard(board, ROW, COL);
//判断电脑的输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
printf("玩家赢\n");
else if (ret == '$')
printf("电脑赢\n");
else
printf("平局\n");
}
void menu()
{
printf("*****************************\n");
printf("*****1:玩游戏 0:退出游戏*****\n");
printf("*****************************\n");}
void text()
{
int intput = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入:>");
scanf("%d", &intput);//scanf函数一定要放在循环语句中
switch (intput)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (intput);
}
int main()
{
text();
return 0;
}
在game.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Initboard(char board[ROW][COL], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void playboard(char board[ROW][COL], int row, int col)
{
int i ;
int j ;
for (i = 0; i < row; i++)
{
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");
}
}
}
void playermove(char board[ROW][COL], int row, int col)
{
int x = 0, y = 0;
printf("玩家下棋;>\n");
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;//用break语句跳出循环,防止一直输入坐标
}
else
printf("该坐标被占用\n");
}
else
printf("输入错误,请重新输入:>");
}
}
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;
}
}
}
//返回1表示棋盘满了
//返回0表示棋盘没满
int IsFull(char board[ROW][COL],int row,int col)
{
int i = 0, 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;
//判断横三行
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[0][0];
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[2][0] != ' ')
return board[2][0];
if (1 == IsFull(board, ROW, COL))
return 'Q';
return 'C';
}
在game.h:
#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 playboard(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);
四 结果演示
当然还有其它结果,你们快去试试吧!
至于为啥这个叫做小朋友的三子棋,我相信你们一定也有了答案了吧
因为这个电脑真的有点“蠢”,可以拿去骗骗小孩子
哈哈 今天的分享就到这里了,我们下次再见
拜拜~~
相关文章
- 进程?线程?小朋友你是否有很多问号?
- 小朋友排队--第五届蓝桥杯
- 【洛谷3852】小朋友(弦图)
- 【BZOJ3625/CF438E】小朋友和二叉树(多项式求逆,多项式开方)
- 【华为OD机试真题 python】小朋友排队-2 【2022 Q4 | 100分】
- HarmonyOS开发竟如此简单,九岁小朋友也能轻松上手
- 《Haskell趣学指南》—— 第1章,第1.2节小朋友的第一个函数
- [第五届蓝桥杯省赛C++B组]小朋友排队
- 华为OD机试 - 找出同班小朋友(JavaScript) | 机试题+算法思路+考点+代码解析 【2023】
- 华为OD机试 -小朋友排队(JavaScript) | 机试题+算法思路+考点+代码解析 【2023】
- 华为OD机试 - 找出同班小朋友(Python) | 机试题+算法思路+考点+代码解析 【2023】
- 2022&2023华为OD机试 - 小朋友排队(Python)
- 华为OD机试 -寻找身高相近的小朋友(Java) | 机试题+算法思路+考点+代码解析 【2023】
- HarmonyOS开发竟如此简单,九岁小朋友也能轻松上手
- 小朋友学Linux<一>基础篇
- 好看又好用的头戴蓝牙耳机,小朋友更喜欢,趣倍BTH16体验
- 好玩有趣彩色小画板,小朋友的好玩伴,米家液晶小黑板多彩版体验
- 从零学Java(7)之数据类型,小AD竟然solo不过小朋友