方法的具體實(shí)現(xiàn)
newBlock()
生成一個(gè)新方塊
private Random random = new Random();
/// <summary>
/// 生成一個(gè)新的方塊
/// </summary>
private void newBlock()
{
//按空方塊的總數(shù)量隨機(jī)出此次新增的方塊索引
int r = random.Next(0, Row * Colum - blockCount);
int value = random.Next(0, 10);
//隨機(jī)到0-7時(shí)值為2,8或9時(shí)值為4
value = value >= 8 ? 4 : 2;
//按照索引找到目標(biāo)方塊
for (int i = 0; i < Row; i++)
{
for (int j = 0; j < Colum; j++)
{
if (Map[i, j] == 0)
{
if (r == 0)
{
Map[i, j] = value;
//更新不為空的方塊數(shù)量
blockCount++;
//加個(gè)標(biāo)記
LastBlockPoint = new Point(i, j);
return;
}
r--;
}
}
}
}
singleMove(Point[] points)
一行或一列坐標(biāo)的移動(dòng)淤堵,分解為每個(gè)坐標(biāo)向前移動(dòng)
2嘀掸,2漓糙,4铣除,4 >> 4谚咬,0鹦付,4尚粘,4 >> 4,4敲长,0郎嫁,4>>4,8祈噪,0泽铛,0
具體實(shí)現(xiàn)如下
/// <summary>
/// 一行或一列坐標(biāo)的移動(dòng)
/// </summary>
/// <param name="points"></param>
private void singleMove(Point[] points)
{
int cur = 0;
for (int i = 1; i < points.Length; i++)
{
int iValue = getMapValue(points[i]);
if (iValue == 0)
{
continue;
}
cur += fall(points, i, cur);
}
}
/// <summary>
/// 在一行或一列坐標(biāo)中,索引為i1的向i2落去
/// </summary>
/// <param name="points">坐標(biāo)集合</param>
/// <param name="i1"></param>
/// <param name="i2">下落目標(biāo)點(diǎn)坐標(biāo)</param>
/// <returns>下落是否產(chǎn)生了融合 0:是 1:否</returns>
private int fall(Point[] points, int i1, int i2)
{
int value1 = getMapValue(points[i1]);
int value2 = getMapValue(points[i2]);
if (value1 == value2)
{
setMapValue(points[i2], value2 * 2);
setMapValue(points[i1], 0);
//有方塊位置發(fā)生了變化辑鲤,記錄變化的位置
Moved.Add(points[i1], points[i2]);
blockCount--;
Score += value2 * 2;
return 1;
}
if (value2 == 0)
{
setMapValue(points[i2], value1);
setMapValue(points[i1], 0);
Moved.Add(points[i1], points[i2]);
return 0;
}
if (i2 + 1 != i1)
{
setMapValue(points[i2 + 1], value1);
setMapValue(points[i1], 0);
Moved.Add(points[i1], points[i2 + 1]);
}
return 1;
}
public int getMapValue(Point p)
{
return Map[p.X, p.Y];
}
private void setMapValue(Point p, int value)
{
Map[p.X, p.Y] = value;
}
bool Operate(Direction direction)
一次操作盔腔,返回操作是否有效
只需要按方向生成坐標(biāo)的數(shù)組,再分別調(diào)用singleMove即可月褥。
/// <summary>
/// 向某個(gè)方向移動(dòng)
/// </summary>
/// <param name="direction"></param>
/// <returns>是否是有效的操作(游戲是否產(chǎn)生了變化)</returns>
public bool Operate(Direction direction)
{
if (isGameOver())
{
GameOvered();
return false;
}
Moved = new Dictionary<Point, Point>();
switch (direction)
{
case Direction.Up:
{
for (int c = 0; c < Colum; c++)
{
Point[] points = new Point[Row];
for (int r = 0; r < Row; r++)
{
points[r] = new Point(r, c);
}
singleMove(points);
}
}
break;
case Direction.Down:
{
for (int c = 0; c < Colum; c++)
{
Point[] points = new Point[Row];
for (int r = 0; r < Row; r++)
{
points[Row - 1 - r] = new Point(r, c);
}
singleMove(points);
}
}
break;
case Direction.Left:
{
for (int r = 0; r < Row; r++)
{
Point[] points = new Point[Colum];
for (int c = 0; c < Colum; c++)
{
points[c] = new Point(r, c);
}
singleMove(points);
}
}
break;
case Direction.Right:
{
for (int r = 0; r < Row; r++)
{
Point[] points = new Point[Colum];
for (int c = 0; c < Colum; c++)
{
points[Colum - 1 - c] = new Point(r, c);
}
singleMove(points);
}
}
break;
default:
return false;
}
//如果所有方塊都沒(méi)有移動(dòng)(Moved.Count==0)弛随,此次操作無(wú)效
bool isChange = Moved.Count == 0 ? false : true;
if (isChange)
{
StepNum++;
newBlock();
//如果游戲結(jié)束,調(diào)用委托
if (isGameOver())
{
GameOvered?.Invoke();
}
}
return isChange;
}
bool isGameOver()
判斷游戲是否結(jié)束
當(dāng)所有方塊與其右側(cè)下側(cè)值都不同宁赤,游戲結(jié)束
/// <summary>
/// 是否GameOver
/// </summary>
/// <returns>res</returns>
private bool isGameOver()
{
if (blockCount != Row * Colum)
{
return false;
}
for (int i = 0; i < Row; i++)
{
for (int j = 0; j < Colum; j++)
{
if (i + 1 < Row && Map[i, j] == Map[i + 1, j])
{
return false;
}
if (j + 1 < Colum && Map[i, j] == Map[i, j + 1])
{
return false;
}
}
}
return true;
}
控制臺(tái)調(diào)用
framework里帶的Point類坐標(biāo)為double型舀透,用不到,所以封裝了個(gè)簡(jiǎn)單的决左,夠用就行
public class Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
X = x;
Y = y;
}
public override string ToString()
{
return "(" + X + "," + Y + ")";
}
}
之后會(huì)實(shí)現(xiàn)WPF版本愕够,所以UI實(shí)現(xiàn)和邏輯還是分開(kāi)比較好
將G2048類和Point類放一起生成動(dòng)態(tài)庫(kù)BizLogic.dll
新建控制臺(tái)程序添加引用,調(diào)用即可
using BizLogic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
G2048 g = new G2048();
g.GameOvered += GGWP;
Console.WriteLine(g.ToString());
while (true)
{
int i = 0;
try
{
i = Convert.ToInt16(Console.ReadLine());
g.Operate((G2048.Direction)i);
Console.WriteLine(g.ToString());
}
catch { }
}
}
//游戲結(jié)束的實(shí)現(xiàn)
static void GGWP()
{
Console.WriteLine("GGWP");
}
}
}