连连看——C++简单小游戏

连连看(本次只处理了0转弯和1转弯的情况,2个转弯的情况还没有解决)


连连看的规则大家可能都知道,这里的就不重复废话了。

这个游戏实现的特别LOW,不过没办法本人能力有限,正在努力的学习以完善这个游戏。

代码比较简单,注释代码中都有,我就不做详细的介绍了,相信以你的能力,你很快就能弄明白。


“test.cpp”

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
using namespace std;

#include "Game.h"

int main()
{
	Game();
	system("pause");
	return 0;
}


“Game.h”

#pragma once

#include "Function.h"

void Game()
{
	const int ROW = 4;//游戏界面的行
	const int COL = 4;//游戏界面的列
	int gamedata[ROW][COL] = {{0}};//游戏数组初始化

	InitGameData((int*)gamedata,ROW,COL);
	
	int x1 = 0,y1 = 0,x2 = 0,y2 = 0;
	int count = 3;//有三次交换已有数组的机会

	//死循环刷新游戏 
	while (1)
	{
		//显示游戏桌面
		DisplayGameView((int*)gamedata,ROW,COL);

		//当没办法在现有的游戏界面上消除时的解决方法
		int num;
		if (count)
		{
			printf("你还有%d次机会刷新游戏,是否刷新?\n",count);
			printf("         1.是      0.否           \n");
			printf("请输入:");
			cin>>num;
			if (num == 1)
			{
				count--;
				Refresh((int* )gamedata,ROW,COL);
				continue;
			}
		}

		//用户输入坐标
		cout<<endl<<"提示:x为横坐标,y为纵坐标,坐标从左到右,从上到下,从1开始递增"<<endl<<endl;//从1开始符合人的思维
		cout<<"请输入两个坐标(x1,y1),(x2,y2):";
		cin>>x1>>y1>>x2>>y2;

		if (x1 > COL|| y1 > ROW|| x2 > COL|| y2 > ROW)
		{
			continue;
		}

		//减一已达到满足数组从0开始的特性
		int newx1 = x1 - 1;
		int newy1 = y1 - 1;
		int newx2 = x2 - 1;
		int newy2 = y2 - 1;

		if (CanClear((int*) gamedata,newx1,newy1,newx2,newy2,ROW,COL))
		{
			gamedata[newy1][newx1] = 0;
			gamedata[newy2][newx2] = 0;
		}

		//检查是否全部消除完毕
		if(CheckSucceed((int*) gamedata,ROW,COL))
		{
			DisplayGameView((int*)gamedata,ROW,COL);
			cout<<"恭喜你成功消除了所有的障碍"<<endl;
			return;
		}
	}
}


Function.h

#pragma once

#include <stdlib.h>
#include <time.h>

void InitGameData(int* gamedata,int row,int col)
{
	//连连看的游戏数组中,数据都是成对出现的,不会出现单独的一个数字
	
	//1.生成成对的数据,依次放在游戏数组中
	int num = 0;
	for (int i = 0;i < row;++i)
	{
		for (int j = 0;j < col;++j)
		{
			gamedata[i * col + j] = num / 2 + 1;//依次生成从1递增的成对数字
			++num;
		}
	}

	//2.随机打乱数组里面的数据
	srand((unsigned)time(NULL));	//使用当前的系统时间作为随机数种子
	for (int count = 0;count < (row * col) / 2;++count)
	{
		int x1 = rand() % col;	//生成 0 -- (col - 1) 的数据
		int y1 = rand() % row;	//生成 0 -- (row - 1) 的数据
		int x2 = rand() % col;	//生成 0 -- (col - 1) 的数据
		int y2 = rand() % row;	//生成 0 -- (row - 1) 的数据

		swap(gamedata[y1 * col + x1],gamedata[y2 * col + x2]);
	}
}

void DisplayGameView(int* gamedata,int row,int col)
{
	system("cls");//执行系统清屏命令,但是这种办法的缺点是程序额外运行系统程序执行清屏操作,延长了程序执行时间。

	//打印标题
	printf("**************************************\n");
	printf("                                      \n");
	printf("               连连看游戏             \n");
	printf("                                      \n");	
	printf("             设计者:萧海霞           \n");
	printf("                                      \n");	
	printf("**************************************\n");	

	for (int i = 0;i < row;++i)
	{
		for (int j = 0;j < col;j++)
		{
			if (gamedata[i * col + j] == 0)
			{
				printf("       ");
			} 
			else
			{
				printf("%7d",gamedata[i * col + j]);
			}
		}
		cout<<endl;
	}
}
bool ConnectZero(int* gamedata,int x1,int y1,int x2,int y2,int row,int col)
{
	//如果在同一行上 Y相等
	if (y1 == y2)
	{
		int y = y1;
		//sum用于遍历两个坐标之间路径的值,由于消除数据的坐标程序已经置成0,所以当sum==0时,两个坐标的数据才能消除
		int sum = 0;

		//保证x1一定小于等于x2
		if (x1 > x2)
		{
			swap(x1,x2);
		}

		for (int x = x1 + 1;x < x2;++x)
		{
			sum += gamedata[y * col + x];
		}

		if (sum == 0)
		{
			return true;
		}
	}
	//如果在同一列上 X相等
	if(x1 == x2)
	{
		int x = x1;
		//sum用于遍历两个坐标之间路径的值,由于消除数据的坐标程序已经置成0,所以当sum==0时,两个坐标的数据才能消除
		int sum = 0;

		//保证x1一定小于等于x2
		if (y1 > y2)
		{
			swap(y1,y2);
		}

		for (int y = y1 + 1;y < y2;++y)
		{
			sum += gamedata[y * col + x];
		}

		if (sum == 0)
		{
			return true;
		}
	}

	return false;
}
bool ConnectOne(int* gamedata,int x1,int y1,int x2,int y2,int row,int col)
{
	//通过中间值,下标为[y1][x2]
	if (ConnectZero(gamedata,x1,y1,x2,y1,row,col)&&
		ConnectZero(gamedata,x1,y1,x1,y2,row,col)&&
		gamedata[y1 * col + x2] == 0)
	{
		return true;
	}
	//通过中间值,下标为[y2][x1]
	if (ConnectZero(gamedata,x1,y1,x1,y2,row,col)&&
		ConnectZero(gamedata,x1,y2,x2,y2,row,col)&&
		gamedata[y2 * col + x2] == 0)
	{
		return true;
	}
}

bool CanClear(int* gamedata,int x1,int y1,int x2,int y2,int row,int col)
{
	//1.如果用户所给我两个下标相同,则不能消除
	if (x1 == x2 && y1 == y2)
	{
		return false;
	}

	//2.如果用户所给的两个坐标所对应的值不相同,则不能消除
	if (gamedata[y1 * col + x1] != gamedata[y2 * col + x2])
	{
		return false;
	}

	//3.如果可以不转弯就连通
	if (ConnectZero(gamedata,x1,y1,x2,y2,row,col))
	{
		return true;
	}
	if (ConnectOne(gamedata,x1,y1,x2,y2,row,col))
	{
		return true;
	}
}

void Refresh(int* gamedata,int row,int col)
{
	//随机打乱数组里面的数据
	srand((unsigned)time(NULL));	//使用当前的系统时间作为随机数种子
	for (int count = 0;count < (row * col) / 2;++count)
	{
		int x1 = rand() % col;	//生成 0 -- (col - 1) 的数据
		int y1 = rand() % row;	//生成 0 -- (row - 1) 的数据
		int x2 = rand() % col;	//生成 0 -- (col - 1) 的数据
		int y2 = rand() % row;	//生成 0 -- (row - 1) 的数据

		swap(gamedata[y1 * col + x1],gamedata[y2 * col + x2]);
	}
}

bool CheckSucceed(int* gamedata,int row,int col)
{
	for (int i = 0;i < row;++i)
	{
		for (int j = 0;j < col;++j)
		{
			if (gamedata[i * col + j] != 0)
			{
				return false;
			}
		}
	}

	return true;
}

 


  • 14
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值