本帖最后由 da11 于 2021-2-5 11:57 编辑
//2048GameCore.cs
namespace _2048Game
{
/// <summary>
/// 2048游戏核心类
/// </summary>
class _2048GameCore
{
//定义二维数组字段
int[,] GameMapTwoArray;
//定义克隆的二维数组
int[,] GameMapTwoArrayClone;
//定义游戏二维数组对比,是否发生改变
int GameMapStatusNum;
public int GameMapStatusNumDX
{
get { return GameMapStatusNum; }
}
//暂时使用此属性获取二维数组,需要打印到控制台
public int[,] GameMapTwoArraySX
{
get { return GameMapTwoArray; }
}
//定义缓冲区一维数组字段
int[] GameMapOneArray;
//定义统计字段-用于统计二维数组中还剩多少为0的空间
int CountNum;
//定义合并统计状态
bool HBCountStatus;
public bool HBCountStatusSX
{
get { return HBCountStatus; }
}
//定义统计字段属性-用于返回出去给使用者使用
public int CountNumSX
{
get { return CountNum; }
}
//定义分数字段
int FS;
public int FSSX
{
get { return FS; }
}
//定义程序是否开始状态
int gameStart;
bool gameEnd;
public bool GameEndSX
{
get { return gameEnd; }
set { this.gameEnd = value; }
}
//定义存放数组空余位置的集合
List<TempSZ> CacheList;
public List<TempSZ> CacheListSX
{
get { return CacheList; }
}
//构造函数,初始化各字段的值
public _2048GameCore()
{
/*
//测试的二维数组
GameMapTwoArray = new int[4, 4]
{
{2,8,4,8},
{4,2,8,0},
{8,4,32,16},
{16,64,0,0}
};
*/
GameMapTwoArray = new int[4, 4];
GameMapTwoArrayClone = new int[GameMapTwoArray.GetLength(0), GameMapTwoArray.GetLength(1)];
GameMapStatusNum = 0;
GameMapOneArray = new int[4];
CountNum = 0;
HBCountStatus = true;
CacheList = new List<TempSZ>(GameMapTwoArray.GetLength(0) * GameMapTwoArray.GetLength(1));
CacheList.Add(new TempSZ(0, 0));
//新建的二维数组需要随机生成两个数值
//初始化时程序没有在开启状态,因为需要生成两个值,所以需要循环两次
for (int i = 0; i < 2; i++)
{
gameStart++;
GetRandomTwoArrayNum();
}
gameEnd = false;
}
#region 数组数据处理代码块
/// <summary>
/// 将有用的数值(非0)移至前面
/// </summary>
private void DropZeroSF()
{
for (int WC = 0; WC < GameMapOneArray.Length - 1; WC++)
{
if (GameMapOneArray[WC] == 0)
{
if (WC + 2 < GameMapOneArray.Length)
{
if (GameMapOneArray[WC + 1] == 0)
{
int Temp1 = GameMapOneArray[WC];
GameMapOneArray[WC] = GameMapOneArray[WC + 2];
GameMapOneArray[WC + 2] = Temp1;
continue;
}
}
int Temp = GameMapOneArray[WC];
GameMapOneArray[WC] = GameMapOneArray[WC + 1];
GameMapOneArray[WC + 1] = Temp;
}
}
}
/// <summary>
///合并方法,将相同的数值合并,并再次调用方法一,去零方法
/// </summary>
private void HBSF()
{
for (int WC = 0; WC < GameMapOneArray.Length - 1; WC++)
{
if (GameMapOneArray[WC] == GameMapOneArray[WC + 1])
{
GameMapOneArray[WC] = GameMapOneArray[WC] + GameMapOneArray[WC + 1];
GameMapOneArray[WC + 1] = 0;
DropZeroSF();
//合并成功就将合并状态为true
HBCountStatus = true;
//只合并一次就退出循环
break;
}
}
//合并失败就将合并状态为false
HBCountStatus = false;
}
#endregion
#region 移动代码块
/// <summary>
///上移方法,将二维数组的一列数据,从上至下获取成一个一维数组
/// </summary>
private void GameUpSF1()
{
//清空缓存作用的一元数组
Array.Clear(GameMapOneArray, 0, GameMapOneArray.Length);
for (int LS = 0; LS < GameMapTwoArray.GetLength(1); LS++)
{
for (int HS = 0; HS < GameMapTwoArray.GetLength(0); HS++)
{
GameMapOneArray[HS] = GameMapTwoArray[HS, LS];
}
DropZeroSF();
HBSF();
for (int HS = 0; HS < GameMapTwoArray.GetLength(0); HS++)
{
GameMapTwoArray[HS, LS] = GameMapOneArray[HS];
}
}
}
/// <summary>
///下移方法,将二维数组的一列数据,从下至上获取成一个一维数组
/// </summary>
private void GameDownSF1()
{
Array.Clear(GameMapOneArray, 0, GameMapOneArray.Length);
for (int LS = GameMapTwoArray.GetLength(1) - 1; LS >= 0; LS--)
{
for (int HS = GameMapTwoArray.GetLength(0) - 1; HS >= 0; HS--)
{
GameMapOneArray[3 - HS] = GameMapTwoArray[HS, LS];
}
DropZeroSF();
HBSF();
for (int HS = GameMapTwoArray.GetLength(0) - 1; HS >= 0; HS--)
{
GameMapTwoArray[HS, LS] = GameMapOneArray[3 - HS];
}
}
}
/// <summary>
///左移方法,将二维数组的一列数据,从左至右获取成一个一维数组
/// </summary>
private void GameLeftSF1()
{
Array.Clear(GameMapOneArray, 0, GameMapOneArray.Length);
for (int HS = 0; HS < GameMapTwoArray.GetLength(0); HS++)
{
for (int LS = 0; LS < GameMapTwoArray.GetLength(1); LS++)
{
GameMapOneArray[LS] = GameMapTwoArray[HS, LS];
}
DropZeroSF();
HBSF();
for (int LS = 0; LS < GameMapTwoArray.GetLength(1); LS++)
{
GameMapTwoArray[HS, LS] = GameMapOneArray[LS];
}
}
}
/// <summary>
/// 右移方法,将二维数组的一行数据,从右至左获取成一个一维数组
/// </summary>
private void GameRightSF1()
{
Array.Clear(GameMapOneArray, 0, GameMapOneArray.Length);
for (int HS = GameMapTwoArray.GetLength(0) - 1; HS >= 0; HS--)
{
for (int LS = GameMapTwoArray.GetLength(1) - 1; LS >= 0; LS--)
{
GameMapOneArray[(GameMapTwoArray.GetLength(1) - 1) - LS] = GameMapTwoArray[HS, LS];
}
DropZeroSF();
HBSF();
for (int LS = GameMapTwoArray.GetLength(1) - 1; LS >= 0; LS--)
{
GameMapTwoArray[HS, LS] = GameMapOneArray[(GameMapTwoArray.GetLength(1) - 1) - LS];
}
}
}
/// <summary>
/// 枚举移动方法
/// </summary>
/// <param name="FX"></param>
public void MoveSF(MoveFX FX)
{
//克隆一个和原数组一样的二维数组
Array.Copy(GameMapTwoArray, GameMapTwoArrayClone, 16);
switch (FX)
{
case MoveFX.Up:
GameUpSF1();
break;
case MoveFX.Down:
GameDownSF1();
break;
case MoveFX.Left:
GameLeftSF1();
break;
case MoveFX.Right:
GameRightSF1();
break;
default:
break;
}
//移动方向后和原数组对比是否发生了改变
GameMapStatusNum = 0;
for (int WC = 0; WC < GameMapTwoArray.GetLength(0); WC++)
{
for (int NC = 0; NC < GameMapTwoArray.GetLength(1); NC++)
{
if (GameMapTwoArray[WC,NC] == GameMapTwoArrayClone[WC,NC])
{
GameMapStatusNum++;
}
}
}
//成功移动
if (GameMapStatusNum!=16)
{
//分数加一
FS++;
//每次移动方法后,都会在二维数组的两个位置随机生成数值2或者4
GetRandomTwoArrayNum();
}
}
#endregion
/// <summary>
/// 随机在二维数组中的两个位置插入整数2或者整数4
/// </summary>
private void GetRandomTwoArrayNum()
{
doYouKnowTwoArrayIfMaxNum();
//Console.WriteLine(CountNum);
//判定数组是否满足继续插入值的条件
//限制最多只生成一个
if (CountNum >= 1)
{
for (int i = 0; i < 1; i++)
{
//问题出现,随机数判断时,如果是两个随机数,获取的数值范围也是一样,那么需要使用以下语法调用随机数
//数据类型 变量名 = new Random(Guid.NewGuid().GetHashCode()).Next(取值范围min, 取值范围max);
//定义行数索引随机数
//int HSRandomNum = new Random(Guid.NewGuid().GetHashCode()).Next(0, 4);
//定义列数索引随机数
//int LSRandomNum = new Random(Guid.NewGuid().GetHashCode()).Next(0, 4);
//定义取值2或者4的几率随机数
int NumJNVaule = new Random(Guid.NewGuid().GetHashCode()).Next(1, 11);
Random CacheListRadom = new Random();
int CacheListRadomNum = CacheListRadom.Next(0, CacheList.Count());
//判断二维数组对应的行索引及列索引所在元素是否为0,是则根据取值2或者4的几率随机数赋值,不为0则重新取随机数
/*
if (GameMapTwoArray[HSRandomNum, LSRandomNum] == 0)
{
if (NumJNVaule <= 9)
{
GameMapTwoArray[HSRandomNum, LSRandomNum] = 2;
}
else
{
GameMapTwoArray[HSRandomNum, LSRandomNum] = 4;
}
}
else
{
i--;
}
*/
//使用性能优化的方法:不将二维数组的行列索引随机,而是将剩余空位置放在集合中,随机剩余空位置然后判断赋值即可
if (GameMapTwoArray[CacheList[CacheListRadomNum].HangIndex, CacheList[CacheListRadomNum].LieIndex] == 0)
{
if (NumJNVaule <= 9)
{
GameMapTwoArray[CacheList[CacheListRadomNum].HangIndex, CacheList[CacheListRadomNum].LieIndex] = 2;
}
else
{
GameMapTwoArray[CacheList[CacheListRadomNum].HangIndex, CacheList[CacheListRadomNum].LieIndex] = 4;
}
}
else
{
i--;
}
}
}
}
/// <summary>
/// 判断二维数组是否已经全部空间都有值
/// </summary>
public void doYouKnowTwoArrayIfMaxNum()
{
CacheList.Clear(); //每次统计空位置前都要清空集合,清空集合之后,集合统计次数为0
for (int HS = 0; HS < GameMapTwoArray.GetLength(0); HS++)
{
for (int LS = 0; LS < GameMapTwoArray.GetLength(1); LS++)
{
if (GameMapTwoArray[HS, LS] == 0)
{
//当条件符合时,则插入一个索引对象到集合中
CacheList.Add(new TempSZ(HS,LS));
//统计int字段,后期可以不要
CountNum++;
}
}
}
}
/// <summary>
/// 定义程序状态的方法
/// </summary>
/*
public void printGameStatus()
{
doYouKnowTwoArrayIfMaxNum();
Console.WriteLine("当前二维数组还剩余 " + CacheList.Count() + " 个空位置");
Console.Write("累计分数:{0}",FS);
Console.WriteLine("");
if (CacheList.Count() == 0 && HBCountStatus == false)
{
Console.WriteLine("游戏结束,您的分数为{0}", FS);
gameEnd = true;
}
}
*/
}
}
|