C语言实现三子棋(简单到我奶奶都会)

C语言实现三子棋

首先我们应该构思:

  • 游戏流程
  • 每个流程如何代码实现

游戏流程
在这里插入图片描述
我们先构造总体框架,在这里先自定一个menu菜单函数,和一个game游戏函数
至于函数主体我们后面再写

int main()
{
	menu();//打印菜单
	game();//进入游戏
}

开始界面
在这里我们就写menu函数的主题(一个简陋的界面,你也可以做任何你想的样式)

void menu()//打印开始界面
{
	printf("**********************************\n");
	printf("**** 1.开始游戏 ** 2.结束 *********\n");
	printf("**********************************\n");
}

打印完菜单后,正式进入game函数
game函数:

  1. 玩家选择开始游戏还是结束
  2. 初始化棋盘
  3. 让玩家和电脑依次落子
  4. 判断胜负

所以第一步,玩家选择开始游戏还是结束
这个很简单,不多赘述

int put;//定义一个整型变量记录玩家输入
scanf("%d",&put);
if(put==1)
{
  初始化棋盘开始游戏
}
else
{
  return 0;
}

第二步,初始化棋盘
首先写一个BoardPrint函数打印棋盘
我们想打印一个这样的棋盘

 * | * | * 
---|---|---
 * | * | *
---|---|---
 * | * | *

则它可以拆分为
1.

 * | * | *

1又可以拆分为两个(空格)*(空格)|和一个(空格)*(空格)
和2. ---|---|---
2又可以拆分为两个---|一个---

所以我们有规律的打印一行打印两个(空格)*(空格)| 一个(空格)*(空格),一行打印两个---| 一个---

void BoardPrint(char board[ROW][COL], int row, int col)//打印棋盘
{
	for (int i = 0; i < row; i++)
	{
		for (int n = 0;n<col; n++)
		{
			if (n == col - 1) /如果到了最后一列则不打印字符后的|
			{
				printf(" %c \n", board[i][n]);
			}
			else 
			{
                printf(" %c |",board[i][n]);
			}
		}
		if(i<row-1) /最后一行不打印---|---|---
		{
			for (int j = 0; j < col; j++)
		 {
			
			if (j == col - 1) /当打印到最后一列时,就不打印 | ,改为打印换行
			{
				printf("---\n");
			}
			else
			{
                printf("---|");
			}
		 } 
		}
	}
}

在这里我们自定一个函数,名为 initBoard

void initBoard(char board[ROW][COL], int row, int col)//初始化棋盘
{
	for (int i = 0; i < row; i++)//将二维数组所有值为空格
	{
		for (int n = 0; n < col; n++)
		{
			board[i][n] = ' ';
		}
	}
}

第三步,让玩家、电脑依次落子玩家的子为“ * ” ,电脑的子为“ # ”
我们先写玩家落子代码,自定一个函数,名为Player_Move

void Player_Move(char board[ROW][COL], int row, int col) /这里的ROW与COL用define定义为33
{
	int x, y; /定义一个x与y,记录玩家输入的坐标
	while (1) /写在循环内的原因是:如果输入有误,则让玩家重新输入
	{
		printf("请输入你想要落子的坐标:");
		scanf_s("%d%d",&x,&y);
		if (x > ROW || y > COL)  /如果玩家输入的坐标超过了棋盘大小,则打印超出棋盘
		{
			printf("超出棋盘");
		}
		else if (board[x-1][y-1] != ' ')  /如果玩家输入的坐标已经被占用,则打印以下内容
		{
			printf("该位置被占用");
		}
		else /如果上述错误都没有,则将玩家输入的坐标的数组值变为‘*’(一个星号)
		{
			board[x - 1][y - 1] = '*'; /
			break;
		}
	}
}

因为玩家所认为的坐标,例如(1,1)在数组里,应该是(0,0),所以我们记得在改变值的坐标写为board[x-1][y-1]。

接下来写电脑落子函数,名为Com_Move

void Com_Move(char board[ROW][COL], int row, int col)
{
	int x, y;
	while (1)
	{
    x = rand()%row;
	y = rand()%col;
	if(board[x][y]=' '&& board[x][y]!='*')/如果落子点为空格并且不为*则可以落子
	{
		board[x][y] = '#';
		break;
	}
	}
}

因为电脑生成的随机值我们规定了在0~2之间,所以就不用像之前一样x-1 y-1了。

第四步,判断胜负
这里我们自定两个函数,一个名为is_Win用来判断哪方胜,一个名为is_None用来判断是否平局

这里胜负怎么判断呢,我们可以发现有以下几种情况
在这里插入图片描述竖着三个,横着三个
![![在这里插入图片描述](https://img-blog.csdnimg.cn/276a78848e374a88bcf8371f88ba5886.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbHpoTm94,size_18,color_FFFFFF,t_70,g_se,x_16](https://img-blog.csdnimg.cn/5acef0b880ab432e8cff21b0a306b12b.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbHpoTm94,size_14,color_FFFFFF,t_70,g_se,x_16主对角线,副对角线各一个
所以代码如下

char is_Win(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&& board[i][1]!='0') /行的情况
		{
			return board[i][1];/返回三个值中的一个,*或者#
		}
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != '0')/列的情况
		{
			return board[1][i];
		}
		if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != '0')/副对角线的情况
		{
			return board[1][1];
		}
		if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != '0')主对角线的情况
		{
			return board[1][1];
		}
		if (is_none(board, ROW, COL) == 1)/进入平局函数
	    {
		return 'p';
	    }
    }
}

is_none(char board[ROW][COL], int row, int col)
{
	for (int i = 0;i < row; i++)/遍历数组,如果遇到一个空格就返回0,如果一个空格都没有就跳出for循环返回1
	{
		for (int n = 0; n < col; n++)
		{
			if (board[i][n] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

综上,我们整合所有的代码

#include <stdio.h>
#include "game.h"
#include <stdlib.h>
#include <time.h>

int main()/主函数
{
	srand(time(NULL));
	menu();
	game();
}

void menu()//打印开始界面
{
	printf("**********************************\n");
	printf("**** 1.开始游戏 ** 2.结束 ********\n");
	printf("**********************************\n");
}

void game()
{
	char board[ROW][COL] = { 0 };
	int put;
	scanf_s("%d", &put);
	if(put==1)
	{ 
		int ret=0;
		initBoard(board,ROW,COL);/初始化棋盘
		BoardPrint(board, ROW, COL);/打印棋盘
		while (1)
		{
			Player_Move(board, ROW, COL);/玩家落一次子
			BoardPrint(board, ROW, COL);/棋盘打印依次
			ret = is_Win(board, ROW, COL);/判断有没有人赢了
			if (ret == '#')
			{
				printf("电脑赢");
				break;
			}
			else if (ret == '*')
			{
				printf("玩家赢");
				break;
			}
			else if (ret == 'p')
			{
				printf("平局");
				break;
			}
			Com_Move(board, ROW, COL);/电脑落一次子
			printf("电脑下\n");
			BoardPrint(board, ROW, COL);/再打印一次棋盘
			ret = is_Win(board, ROW, COL);/再判断一次有没有人赢了
			if ( ret == '#')
			{
				printf("电脑赢");
				break;
			}
			else if ( ret == '*')
			{
				printf("玩家赢");
				break;
			}
			else if (ret == 'p')
			{
				printf("平局");
				break;
			}
		}
	}
	else if (put == 2) /如果输入2就结束游戏
	{
		return 0;
	}
}
void initBoard(char board[ROW][COL], int row, int col)//初始化棋盘
{
	for (int i = 0; i < row; i++)
	{
		for (int n = 0; n < col; n++)
		{
			board[i][n] = ' ';
		}
	}
}

void BoardPrint(char board[ROW][COL], int row, int col)//打印棋盘
{
	for (int i = 0; i < row; i++)
	{
		for (int n = 0;n<col; n++)
		{
			if (n == col - 1)
			{
				printf(" %c \n", board[i][n]);
			}
			else
			{
                printf(" %c |",board[i][n]);
			}
		}
		if(i<row-1)//最后一行不打印---|---|---
		{
			for (int j = 0; j < col; j++)
		 {
			
			if (j == col - 1)//当打印到最后一列时,就不打印 | ,改为打印换行
			{
				printf("---\n");
			}
			else
			{
                printf("---|");
			}
		 } 
		}
	}
}
void Player_Move(char board[ROW][COL], int row, int col)
{
	int x, y;
	
	while (1)
	{
		printf("请输入你想要落子的坐标:");
		scanf_s("%d%d",&x,&y);
		if (x > ROW || y > COL)
		{
			printf("超出棋盘");
		}
		else if (board[x-1][y-1] != ' ')
		{
			printf("该位置被占用");
		}
		else
		{
			board[x - 1][y - 1] = '*';
			break;
		}
	}
}
void Com_Move(char board[ROW][COL], int row, int col)
{
	int x, y;
	while (1)
	{
    x = rand()%row;
	y = rand()%col;
	if(board[x][y]=' '&& board[x][y]!='*')
	{
		board[x][y] = '#';
		break;
	}
	}
}

char is_Win(char board[ROW][COL], int row, int col)//版本一
{
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&& board[i][1]!='0')
		{
			return board[i][1];
		}
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != '0')
		{
			return board[1][i];
		}
		if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != '0')
		{
			return board[1][1];
		}
		if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != '0')
		{
			return board[1][1];
		}
		if (is_none(board, ROW, COL) == 1)
	    {
		return 'p';
	    }
    }
}

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

运行结果:在这里插入图片描述

所以你学会了吗

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值