C语言实现三子棋
C语言实现三子棋
来自菜鸡的第一次写博客
菜鸡自学C语言----学到数组这里,课堂有一节练习----三子棋 这不就是小时玩过的井字棋?
本菜鸡用最简单的C语言编程来实现这个三子棋游戏
菜鸡
**设计电脑与玩家作为下棋的两方,用键盘输入坐标的形式作为玩家的游戏操作 **
1.效果图
程序总的构架:

1.test.c --->> 测试游戏的逻辑
2.game.h --->> 关于游戏相关的函数声明,符号声明,头文件包含
3.game.c --->> 游戏相关函数的实现
我们只要输入坐标就可以和电脑对弈了.
电脑的棋子用#代替,玩家的棋子用*代替。

2.打印菜单
可以根据自己的爱好设计各种风格的菜单,自己赏心悦目,让自己游戏界面更加美观以及游戏体验更佳.
void menu()
{
printf("\n");
printf("******************************************\n");
printf("******* 欢迎来到三子棋游戏 *********\n");
printf("************ 1. play ***************\n");
printf("************ 0. exit ***************\n");
printf("******************************************\n");
}
3.初始化棋盘
ROW,COL分别表示棋盘的宽度和高度(既是棋盘的x和y坐标,也是数组的行和列)
一开始把棋盘初始化为' '(空格).
//初始化棋盘
//把数组每个元素初始化成空格
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] = ' ';//初始化成空格
}
}
}
4.打印棋盘
打印棋盘,棋盘由符号加数组元素组成,用符号把棋盘的框架打印下来
//打印棋盘
//打印数组元素及棋盘的框架
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ",board[i][j]);
if (col - 1 > j )
{
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
//printf("---|---|---\n");
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1 )
{
printf("|");
}
}
}
printf("\n");
}
}
5.下棋
可以使用判断语句让用户选择是先下还是后下,选完后再进行下棋.
首先我给出电脑下棋的逻辑,我是利用srand()函数和rand函数产生随机值让电脑在棋盘有空的位置上随机下棋.用一个循环判断就可以实现。也可以设计电脑让其更"聪明",能够判断玩家已经下好的棋,并能做出阻止(我没有做这一步,如果有兴趣的话,可以自己研究研究🧐)
电脑下棋
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑走:>\n");
while (1)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
玩家下棋
从键盘上输入下棋坐标,判断坐标正好是棋盘上空的地方,则成功下棋,若在棋盘上但非空位置,提示玩家该坐标已经被占用,要重新输入,若不在棋盘上,提示玩家该坐标非法,要重新输入。
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走:>\n");
while (1)
{
printf("请选择坐标(x,y):>");
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("坐标非法,请重新输入");
}
}
}
6.判断输赢
游戏进行会有4种状态
- 玩家赢 -->返回'*'
- 电脑赢 -->返回'#'
- 平局 -->返回'Q'
- 游戏继续 -->返回'C'
双方谁能3颗棋子先连成一条线,就是赢家
下面有个判断输赢我写了个5子棋的判断输赢代码
//判断输赢
char IsWim(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 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[0][2] == board[1][1] & board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
// 横线上五子连成一线,赢家产生
//for (i = 0; i < row; i++)
//{
// for (j = 0; j < col - 4; j++)
// {
// if (board[i][j] == board[i][j + 1]
// && board[i][j + 1] == board[i][j + 2]
// && board[i][j + 2] == board[i][j + 3]
// && board[i][j + 3] == board[i][j + 4]
// && board[i][j] != ' ')
// {
// return board[i][j];
// }
// }
//}
// 竖线上五子连成一线,赢家产生
//for (j = 0; j < col; j++)
//{
// for (i = 0; i < row - 4; i++)
// {
// if (board[i][j] == board[i + 1][j]
// && board[i + 1][j] == board[i + 2][j]
// && board[i + 2][j] == board[i + 3][j]
// && board[i + 3][j] == board[i + 4][j]
// && board[i][j] != ' ')
// {
// return board[i][j];
// }
// }
//}
// 斜线上五子连成一线,赢家产生
//for (i = 0; i < row - 4; i++)
//{
// if (board[i][i] == board[i + 1][i + 1]
// && board[i + 1][i + 1] == board[i + 2][i + 2]
// && board[i + 2][i + 2] == board[i + 3][i + 3]
// && board[i + 3][i + 3] == board[i + 4][i + 4]
// && board[i][i] != ' ')
// {
// return board[i][i];
// }
// if (board[i][i + 4] == board[i + 1][i + 3]
// && board[i + 1][i + 3] == board[i + 2][i + 2]
// && board[i + 2][i + 2] == board[i + 3][i + 1]
// && board[i + 3][i + 1] == board[i + 4][i]
// && board[i][i + 4] != ' ')
// {
// return board[i][i + 4];
// }
//}
//判断平局
//如果棋盘满了返回1 反之0
int ret = isFull(board, ROW, COL);
if (1 == ret)
{
return 'Q';
}
else
{
return 'C';
}
}
7.判断平局
//判断棋盘满了否
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;//棋盘满了
}
8.游戏执行
以上就是我们要实现三子棋的模块,要想把这些模块整合起来运行,就需要一个游戏执行函数来调用这些模块,定义个game()函数实现,代码如下:
//三子棋游戏运行逻辑
void game()
{
//存储数据 - 二维数组
//char board[3][3];//3*3的棋盘 后期如果需要更大的棋盘需要改大 修改数据太多工程量大 不适合
//棋盘是游戏的属性
char board[ROW][COL];
//初始化棋盘 - 初始化为空格
//初始化棋盘函数属于游戏模块 -->game.h
//不初始化出现随机值影响外观
InitBoard(board,ROW,COL);
//打印棋盘
//本质上是打印数组的内容
DisplayBoard(board,ROW,COL);
//在游戏进行的过程
//1.玩家赢了 *
//2.电脑赢了 #
//3.平局 Q
//4.游戏继续 C
//char IsWin 用来判断游戏的状态
char ret = 0;//接受游戏状态
while (1)
{
//玩家先下棋
PlayerMove(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//判断用户输赢
ret = IsWin(board,ROW,COL);
if ('C' != ret)
{
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//判断电脑输赢
ret = IsWin(board, ROW, COL);
if ('C' != ret)
{
break;
}
}
if ('*' == ret)
{
printf("玩家赢了!\n");
}
else if ('#' == ret)
{
printf("电脑赢了\n");
}
else
{
printf("平局!\n");
}
DisplayBoard(board, ROW, COL);
}
9.头文件
在头文件 game.h 中声明各种函数、符号、头文件包含.
//头文件的包含
#include <stdio.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);
//在游戏进行的过程
//1.玩家赢了 *
//2.电脑赢了 #
//3.平局 Q
//4.游戏继续 C
//char IsWin 用来判断游戏的状态
char IsWin(char board[ROW][COL], int row, int col);
10.测试
可以将棋盘x和y轴更改多个值进行测试,以确保代码的稳定性.
int main()
{
int input = 0;//定义用户的选择变量
//生成随机值 srand()函数只会调用一次
srand((unsigned int)time(NULL));
do
{
menu();//打印简易的菜单
printf("请选择:>");
scanf("%d", &input);//接受用户输入的选择
switch (input)
{
case 1:
game();
//printf("三子棋游戏\n");
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
附:game.c的源码
#include "game.h"
//重复了
//#include <stdio.h>
//“printf”未定义
//初始化棋盘
//数组的每一元素初始化成空格
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] = ' ';
}
}
}
//打印棋盘
//打印数组元素
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++)
{
printf(" %c ",board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1)
{
//printf("---|---|---\n");
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
//函数不够完善 一旦改了行与列这个棋盘会出现问题 行没有问题但是列少了
// 只适用3*3棋盘
//void DispalyBoard(char board[ROW][COL], int row, int col)
//{
// int i = 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 ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑走:>\n");
while (1)
{
//随机生成电脑下棋的坐标
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//玩家走
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");
}
}
}
//判断输赢
char IsWim(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 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[0][2] == board[1][1] & board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
// 横线上五子连成一线,赢家产生
//for (i = 0; i < row; i++)
//{
// for (j = 0; j < col - 4; j++)
// {
// if (board[i][j] == board[i][j + 1]
// && board[i][j + 1] == board[i][j + 2]
// && board[i][j + 2] == board[i][j + 3]
// && board[i][j + 3] == board[i][j + 4]
// && board[i][j] != ' ')
// {
// return board[i][j];
// }
// }
//}
// 竖线上五子连成一线,赢家产生
//for (j = 0; j < col; j++)
//{
// for (i = 0; i < row - 4; i++)
// {
// if (board[i][j] == board[i + 1][j]
// && board[i + 1][j] == board[i + 2][j]
// && board[i + 2][j] == board[i + 3][j]
// && board[i + 3][j] == board[i + 4][j]
// && board[i][j] != ' ')
// {
// return board[i][j];
// }
// }
//}
// 斜线上五子连成一线,赢家产生
//for (i = 0; i < row - 4; i++)
//{
// if (board[i][i] == board[i + 1][i + 1]
// && board[i + 1][i + 1] == board[i + 2][i + 2]
// && board[i + 2][i + 2] == board[i + 3][i + 3]
// && board[i + 3][i + 3] == board[i + 4][i + 4]
// && board[i][i] != ' ')
// {
// return board[i][i];
// }
// if (board[i][i + 4] == board[i + 1][i + 3]
// && board[i + 1][i + 3] == board[i + 2][i + 2]
// && board[i + 2][i + 2] == board[i + 3][i + 1]
// && board[i + 3][i + 1] == board[i + 4][i]
// && board[i][i + 4] != ' ')
// {
// return board[i][i + 4];
// }
//}
//判断平局
//如果棋盘满了返回1 反之0
int ret = isFull(board, ROW, COL);
if (1 == ret)
{
return 'Q';
}
else
{
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 (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;//棋盘没满
}
}
}
return 1;//棋盘满了
}
C语言实现三子棋本菜鸡以及写完了,有些缺漏或没写好的请各位大佬请教请教,小生也是第一次写博客,有些写不好的还请勿怪。感谢各位的收看.谢谢大家!


浙公网安备 33010602011771号