2.G2048方法的具体实现 && 控制台调用

方法的具体实现

newBlock()

生成一个新方块

        private Random random = new Random();

        /// 
        /// 生成一个新的方块
        /// 
        private void newBlock()
        {
            //按空方块的总数量随机出此次新增的方块索引
            int r = random.Next(0, Row * Colum - blockCount);
            int value = random.Next(0, 10);
            //随机到0-7时值为2,8或9时值为4
            value = value >= 8 ? 4 : 2;
            //按照索引找到目标方块
            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;
                            //更新不为空的方块数量
                            blockCount++;
                            //加个标记
                            LastBlockPoint = new Point(i, j);
                            return;
                        }
                        r--;
                    }
                }
            }
        }
singleMove(Point[] points)

一行或一列坐标的移动,分解为每个坐标向前移动
2,2,4,4 >> 4,0,4,4 >> 4,4,0,4>>4,8,0,0

具体实现如下

        /// 
        /// 一行或一列坐标的移动
        /// 
        /// 
        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);
            }
        }

        /// 
        /// 在一行或一列坐标中,索引为i1的向i2落去
        /// 
        /// 坐标集合
        /// 
        /// 下落目标点坐标
        /// 下落是否产生了融合 0:是 1:否
        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);
                //有方块位置发生了变化,记录变化的位置
                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)

一次操作,返回操作是否有效
只需要按方向生成坐标的数组,再分别调用singleMove即可。

        /// 
        /// 向某个方向移动
        /// 
        /// 
        /// 是否是有效的操作(游戏是否产生了变化)
        public bool Operate(Direction direction)
        {
            if (isGameOver())
            {
                GameOvered();
                return false;
            }
            Moved = new Dictionary();
            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;
            }
            //如果所有方块都没有移动(Moved.Count==0),此次操作无效
            bool isChange = Moved.Count == 0 ? false : true;
            if (isChange)
            {
                StepNum++;
                newBlock();
                //如果游戏结束,调用委托
                if (isGameOver())
                {
                    GameOvered?.Invoke();
                }
            }         
            return isChange;
        }
bool isGameOver()

判断游戏是否结束
当所有方块与其右侧下侧值都不同,游戏结束

        /// 
        /// 是否GameOver
        /// 
        /// res
        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;

        }

控制台调用

framework里带的Point类坐标为double型,用不到,所以封装了个简单的,够用就行

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 + ")";
        }
    }

之后会实现WPF版本,所以UI实现和逻辑还是分开比较好
将G2048类和Point类放一起生成动态库BizLogic.dll
新建控制台程序添加引用,调用即可

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 { }             
            }
        }
        //游戏结束的实现
        static void GGWP()
        {
            Console.WriteLine("GGWP");
        }
    }
}

你可能感兴趣的:(2.G2048方法的具体实现 && 控制台调用)