三子棋小游戏

天啦噜,在电脑上也可以玩的三子棋小游戏(含优化)

三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。

准备工作

我将游戏的骨架放到test.c中
把相关游戏的实现放到game.c中
相关思路如图
在这里插入图片描述
三子棋游戏思路:
1、至少玩一次,可以玩多次,运用do…while循环
2、进入游戏后先打印菜单
3、提示用户输入,根据输入值来确定选择的游戏进程(1代表玩游戏,2代表退出,其他需要重新输入并选择)

我们需要知道三子棋的一些信息:

  1. 三子棋形状
    在这里插入图片描述
    打印出的棋盘:
    在这里插入图片描述
  2. 游戏规则:只要将自己的三个棋子走成一条线,对方就算输了。
    所以获胜·有三种情况:1、横排三子 2、竖排三子 3、对角线三子

三子棋游戏实现具体思路:
1.我们要记录下棋的结果,就需要对应的二维数组来存储
2.创建的二维数组要进行初始化,全部赋值成空格
3.打印棋盘,看一下展示的效果

在这里插入图片描述
4.玩家下棋
5.判断玩家是否游戏胜利 判断游戏状态是否继续
6.电脑下棋(随机落子的方式)
7.判断电脑是否游戏胜利 判断游戏状态是否继续

游戏共有四种状态: 玩家赢,电脑赢,平局,继续

可优化点

1.电脑下棋,将随机走变成有策略走,让电脑看起来更像“玩家”。(代码中实现了这个优化)
2.我们可以优化为更加好玩的五子棋,比如说后续ROW,COL都改成5。为了让ROW,COL在变化调整后依然适用,我们可以对其进行相应的优化。(本次代码暂未实现该优化)

优化1实现:
思路:这个优化的实现注意考虑两个方面的内容:
1、如果电脑落子,有机会直接赢,则优先落在能赢的坐标上
2、如果玩家落子有机会赢,拦截玩家路子坐标(步骤1优先级高于步骤2)
3、如果步骤1、步骤2均不满足,电脑继续伪随机落子

源码提供

gittee码云源代码
在这里插入图片描述
完整代码:

源文件 text.c文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()//打印菜单
{
	printf("********************************************\n");
	printf("***********       1.play     ***************\n");
	printf("***********       2.exit     ***************\n");
	printf("********************************************\n");
}
void game()
{	//存储数据
	char board[ROW][COL];
	//初始化棋盘
	Inboard(board, ROW, COL);
	//打印棋盘,本质上是数组
	Displayboard(board, ROW,COL);

	//接收游戏状态
	int 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
	{
		printf("双方取得平局\n");
	}
	Displayboard(board, 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 2:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入:\n");
			break;
		}

	} while (input!=2);


	return 0;
}

源文件game.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"
void Inboard(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;
	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)
		{
			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");
		}
	}
}
//int defence_player(char board[ROW][COL], int row, int col/*, int k*/)//判断玩家是否有机会赢,如果能赢就堵住他
//{
//	int i = 0;
//	int j = 0;
//	int k = 0;
//	while (k==0)
//	{
//		//判断玩家在横行上是否会赢
//		for (i = 0; i < row; i++)
//		{
//			if (board[i][0] == board[i][1] && board[i][1] == '*' && board[i][2] == ' ')
//			{
//				board[i][2] = '#';
//				k = 1;
//				break;
//			}
//
//
//			if (board[i][0] == board[i][2] && board[i][0] == '*' && board[i][1] == ' ')
//			{
//				board[i][1] = '#';
//				k = 1;
//				break;
//			}
//
//
//			if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
//			{
//				board[i][0] = '#';
//				k = 1;
//				break;
//			}
//		}
//		if (k != 0)
//			break;
//
//		//判断玩家在竖列上是否会赢
//		for (j = 0; j < col; j++)
//		{
//			if (board[0][j] == board[1][j] && board[1][j] == '*' && board[2][j] == ' ')
//			{
//				board[2][j] = '#';
//				k = 1;
//				break;
//			}
//
//
//			if (board[0][j] == board[2][j] && board[2][j] == '*' && board[1][j] == ' ')
//			{
//				board[1][j] = '#';
//				k = 1;
//				break;
//			}
//
//
//			if (board[1][j] == board[2][j] && board[2][j] == '*' && board[0][j] == ' ')
//			{
//				board[0][j] = '#';
//				k = 1;
//				break;
//			}
//		}
//		break;
//	}
//
//	//判断玩家在对角线上是否会赢,又加了一个while是为了让判断对角线的代码成块。
//	while (k==0)
//	{
//		if (board[0][0] == board[1][1] && board[1][1] == '*' && board[2][2] == ' ')
//		{
//			board[2][2] = '#';
//			k = 1;
//			break;
//		}
//
//
//		if (board[0][0] == board[2][2] && board[2][2] == '*' && board[1][1] == ' ')
//		{
//			board[1][1] = '#';
//			k = 1;
//			break;
//		}
//
//
//		if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
//		{
//			board[0][0] = '#';
//			k = 1;
//			break;
//		}
//
//
//		if (board[0][2] == board[1][1] && board[0][2] == '*' && board[2][0] == ' ')
//		{
//			board[2][0] = '#';
//			k = 1;
//			break;
//		}
//
//
//		if (board[0][2] == board[2][0] && board[2][0] == '*' && board[1][1] == ' ')
//		{
//			board[1][1] = '#';
//			k = 1;
//			break;
//		}
//
//
//		if (board[1][1] == board[2][0] && board[2][0] == '*' && board[0][2] == ' ')
//		{
//			board[0][2] = '#';
//			k = 1;
//			break;
//		}
//		break;
//	}
//	return k;//返回值如果是1那么已经对玩家进行了堵截,如果是0则无需堵截。
//}
//
//int attack_computer(char board[ROW][COL], int row, int col)//判断电脑下一步落子能否赢游戏
//{
//	int i = 0;
//	int j = 0;
//	int k = 0;
//	while (k == 0)
//	{
//		//判断电脑行排能否赢
//		for (i = 0; i < row; i++)
//		{
//			if (board[i][0] == board[i][1] && board[i][0] == '#' && board[i][2] == ' ')
//			{
//				board[i][2] = '#';
//				k = 1;
//				break;
//			}
//			if (board[i][0] == board[i][2] && board[i][0] == '#' && board[i][1] == ' ')
//			{
//				board[i][1] = '#';
//				k = 1;
//				break;
//			}
//			if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
//			{
//				board[i][0] = '#';
//				k = 1;
//				break;
//			}
//		}
//		if (k != 0)//落子后跳出
//			break;
//		//判断电脑列排能否赢
//		for (j = 0; j < col; j++)
//		{
//			if (board[0][j] == board[1][j] && board[0][j] == '#' && board[2][j] == ' ')
//			{
//				board[2][j] = '#';
//				k = 1;
//				break;
//			}
//			if (board[0][j] == board[2][j] && board[0][j] == '#' && board[1][j] == ' ')
//			{
//				board[1][j] = '#';
//				k = 1;
//				break;
//			}
//			if (board[2][j] == board[1][j] && board[0][j] == '#' && board[0][j] == ' ')
//			{
//				board[0][j] = '#';
//				k = 1;
//				break;
//			}
//		}
//		break;
//	}
//	//判断电脑对角线能否赢
//	while (k== 0)
//	{
//		//左上角到右下角对角线判断
//		if (board[0][0] == board[1][1] && board[0][0] == '#' && board[2][2] == ' ')
//		{
//			board[2][2] = '#';
//			k = 1;
//			break;
//		}
//		if (board[0][0] == board[2][2] && board[0][0] == '#' && board[1][1] == ' ')
//		{
//			board[1][1] = '#';
//			k = 1;
//			break;
//		}
//		if (board[1][1] == board[2][2] && board[0][0] == '#' && board[0][0] == ' ')
//		{
//			board[0][0] = '#';
//			k = 1;
//			break;
//		}
//		//左下角到右上角对角线判断
//		if (board[2][0] == board[1][1] && board[2][0] == '#' && board[0][2] == ' ')
//		{
//			board[0][2] = '#';
//			k = 1;
//			break;
//		}
//		if (board[2][0] == board[0][2] && board[2][0] == '#' && board[1][1] == ' ')
//		{
//			board[1][1] = '#';
//			k = 1;
//			break;
//		}
//		if (board[0][2] == board[1][1] && board[0][2] == '#' && board[2][0] == ' ')
//		{
//			board[2][0] = '#';
//			k = 1;
//			break;
//		}
//		break;
//	}
//	k = defence_player(board, row, col, k);
//	return k;
//}
//
实现电脑下棋优化
//void Computer_move(char board[ROW][COL], int row, int col)
//{
//	int x = 0;
//	int y = 0;
//	int ret = 0;
//	ret = attack_computer(board, row, col);
//	while (0 == ret)
//	{
//		x = rand() % row;
//		y = rand() % col;
//		if (board[x][y] == ' ')
//		{
//			board[x][y] = '#';
//			break;
//		}
//	}
//}


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;
		}
	}
}
int IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	int count = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				count++;
			}
		}
	}
	if (count == 0)//棋盘满了返回1,不满返回0
		return 1; 
	else
		return 0;//棋盘没满
	return 1;
}

int 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][1] != ' ')
		{
			return board[i][0];
		}

	}
	//判断三列
	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];
	}

	//判断平局
	int ret = IsFull(board, row, col);
	if (ret == 1)
	{
		return 'Q';
	}

	return 'C';
}

game.c中间部分注释为优化

头文件game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 3
#define COL 3

//初始化棋盘
void Inboard(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);
//判断输赢
int IsWin(char board[ROW][COL], int row, int col);
//堵截玩家
int defence_player(char board[ROW][COL], int row, int col, int k);
//电脑进攻
int attack_computer(char board[ROW][COL], int row, int col);
//1. 玩家赢了 - *
//2. 电脑赢了 - #
//3. 平局 - Q
//4. 游戏继续 - C
  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值