c#学习笔记

数组

在这里插入图片描述在这里插入图片描述

1.一维数组

声明:数据类型[] 变量名
初始化:new 数据类型 [容量]
我们用代码块直观的看一下

			//声明
            int[] array;
            //初始化 new 数据类型【容量】
            array = new int[6];
            array[0] = 1;
            array[3] = 3;

数组其他写法

			//初始化+赋值
    		string[] array01;
            array01 = new string[2] { "a", "b" };

            //声明+初始化+赋值
            bool[] array02 = { true, false };

2.多(二)维数组

声明、初始化、赋值

			int[,] array = new int[5, 3];
            array[0, 2] = 6;

获取数组元素的两种方法
1.foreach函数

            foreach (var item in array)
            {
                Console.WriteLine(item);
            }

2.for for循环

            for(int r = 0; r<array.GetLength(0); r++)
            {
                for(int c = 0; c<array.GetLength(1); c++)
                {
                    Console.Write(array.GetValue(r,c) + "\t");
                }
                Console.WriteLine();

3、交错数组

交错数组:是由多个一维数组的集合
1.定义与赋值

            int[][] array02; //交错数组的定义
            array02 = new int[4][]; //设置数组行

            array02[0] = new int[3];  
            array02[1] = new int[5]; //设置每行有几个
            array02[2] = new int[2];
            array02[3] = new int[1];

            array02[0][0] = 1;    //赋值
            array02[1][2] = 2;

2.交错函数的foreach函数用法

            foreach (int[] item in array02)
            {
                foreach (var element in item)
                {
                    Console.WriteLine(element);//交错数组foreach的用法
                }
            }

3.交错函数的for for 循环用法

            // 交错数组for for 用法
            for (int r = 0; r < array02.Length; r++)  //array02.Length获取交错数组  数组元素数
            {
                for (int c = 0; c < array02[r].Length; c++) //array02[r].Length 获取交错数组每行数组元素数
                {
                    Console.WriteLine(array02[r][c]+'\t');
                }
                Console.WriteLine();
            }

4、参数数组

    //params 参数数组
    //对于方法内部而言:就是个普通数组
    //对于方法外部(调用者)而言:
    //可以传递数组
    //传递一组数据类型相同的变量集合  //传进方法自动形成一个数组
    //可以不传递参数

我们可以用一个整数相加的代码来直观的了解参数数组

        //整数相加的方法
        //当类型确定 ,个数不确定
        //参数数组params
        static void Main2(string[] args)
        {
            int result01 = Add(new int[]{1,2,32,45,46});
            int result02 = Add(1, 2, 23, 4, 53);
        }
        
        private static int Add(params int[] arr)
        {
            int sum = 0;
            foreach (int item in arr)
            {
                sum += item;
            }
            return sum;
        }

5.案例

买彩票案例

        static void Main1(string[] args)
        {
            int[] myTicket = BuyTicket();
            int level;
            int count = 0;
            do
            {
                count++;
                int[] randomTicket = CreatRandomTicket();
                level = TicketEquals(myTicket, randomTicket);
                if(level != 0)
                    Console.WriteLine("恭喜你中了{0}等奖,累计消费:{1:c}元", level, count * 2);
            } while (level != 1);

            Console.ReadLine();
        }

        //买彩票码
        private static int[] BuyTicket()
        {
            int[] ticket = new int[7];
            //前6个红球
            for (int i = 0; i < 6; )
            {
                Console.WriteLine("请输入第{0}个号码:", i+1);
                int redNumber = int.Parse(Console.ReadLine());
                if (redNumber < 1 || redNumber > 33)
                    Console.WriteLine("数据输入有误!请重新输入:");
                else if (Array.IndexOf(ticket, redNumber) >= 0)
                    Console.WriteLine("数据输入重复!请重新输入:");
                else
                    ticket[i++] = redNumber;
            }
            //第7个篮球
            int blueNumber;
            do
            {
                Console.WriteLine("请输入篮球号码:");
                blueNumber = int.Parse(Console.ReadLine());
                if (blueNumber >= 1 && blueNumber <= 16)
                    ticket[6] = blueNumber;
                else
                    Console.WriteLine("号码超出范围!");
            } while (blueNumber < 1 || blueNumber > 16);
            return ticket;
        }

       //生成随机数
        static Random random = new Random();

        //生成随机彩票
        private static int[] CreatRandomTicket()
        {
            int[] ticket = new int[7];
            for (int i = 0; i < 6; )
            {
                int redNumber = random.Next(1, 34);
                if (Array.IndexOf(ticket, redNumber) == -1)
                    ticket[i++] = redNumber;
            }
            int blueNumber = random.Next(1,16);
            ticket[6] = blueNumber;
            Array.Sort(ticket, 0, 6);
            return ticket;
        }

        private static int TicketEquals(int[] myTicket, int[] randomTicket)
        {
            //计算红球号码中奖数量
            int redCount = 0;
            for (int i = 0; i < 6; i++)
                if (Array.IndexOf(randomTicket, myTicket, 0, 6) >= 0)
                    redCount++;

            //计算蓝球号码中奖数量
            int blueCount = myTicket[6] == randomTicket[6] ? 1 : 0;
            int level;
            if (redCount + blueCount == 7)
                level = 1;
            else if (redCount == 6)
                level = 2;
            else if (redCount + blueCount == 6)
                level = 3;
            else if (redCount + blueCount == 5)
                level = 4;
            else if (redCount + blueCount == 4)
                level = 5;
            else if (blueCount == 1)
                level = 6;
            else
                level = 0;
            return level;
        }
                //自定义排序算法
        //冒泡排序 需要进行多次交换
        //选择排序 优点:减少排序,每轮比较只交换一次
        private static int[] OrderBy(int[] array)
        {
            for(int currentIndex = 0; currentIndex < array.Length-1; currentIndex++)
            {
                int minIndex = currentIndex;
                for(int i = currentIndex+1; i< array.Length;i++)
                {
                    if (array[minIndex] > array[i])
                    {//交换
                        //int temp = array[currentIndex];
                        //array[currentIndex] = array[i];
                        //array[i] = temp;//需要进行二次交换,性能还能优化
                        minIndex = i; // 纪录最小的数值索引
                    }
                    if(minIndex != currentIndex)
                    {
                        int temp = array[currentIndex];
                        array[currentIndex] = array[i];
                        array[i] = temp;
                    }
                }
            }
            return array;
        }

        //定义检查数组中是否存在相同元素的方法int[]
        private static bool IsRepeating(int[] array)
        {
            for(int i = 0; i< array.Length-1;i++)
            {
                for(int j = i+1; j<array.Length;j++)
                {
                    if (array[i] == array[j])
                        return true;
                }
                
            }
            return false;
        }

2048核心算法案例

        //*********************2048核心算法***********************************
        /*需求分析
         * 上移
         * --从上到下 获取列数据,形成一维数组
         * --合并数据
         *   --去零:将零元素移到末尾
         *   --相邻相同,则合并(将后一个元素加到前一个元素上,后一个元素清零
         *   --去零
         * --将一维数组还原至原列
         * 
         * 下移1.0
         * -- 获取列数据,形成一维数组
         * --合并数据
         *   --去零:将零元素移到开头
         *   --相邻相同,则合并(将后一个元素加到前一个元素上,后一个元素清零
         *   --去零
         * --将一维数组还原至原列
         * 
         * 下移2.0
         * --从下到上 获取列数据,形成一维数组
         * --合并数据
         *   --去零:将零元素移到末尾
         *   --相邻相同,则合并(将后一个元素加到前一个元素上,后一个元素清零
         *   --去零
         * --将一维数组还原至原列
         * 
         * 左移
         * 
         * 
         * 
         * 右移
         * 
         * 1.定于去零方法(针对一维数组):将0元素移到末尾
         * 2.合并数据方法
         *      --去零:将零元素移到末尾
         *      --相邻相同,则合并(将后一个元素加到前一个元素上,后一个元素清零
         *      --去零
         * 3.上移
         * --从上到下
         * 4.下移
         * --从下到上
         * 
         * 
         * 
        */
        static void Main(string[] args)
        {
            int[,] map = new int[4, 4]
            {
                {2,2,2,0},
                {2,2,4,8},
                {0,4,2,4},
                {2,2,2,4}
            };
            PrintDoubleArray(map);
            Console.WriteLine("右移");
            map = MoveRight(map);

            PrintDoubleArray(map);
            Console.WriteLine("上移");
            map = MoveUp(map);
            PrintDoubleArray(map);

            Console.WriteLine("下移");
            map = MoveDown(map);
            PrintDoubleArray(map);

            Console.WriteLine("左移");
            map = MoveLeft(map);
            PrintDoubleArray(map);


            Console.ReadLine();
        }

        private static int[] RemoveZore(int[] array)
        {
            int index = 0;
            int[] newArray = new int[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] != 0)
                    newArray[index++] = array[i];
            }
            return newArray;
        }

        private static int[] Merge(int[] array)
        {
            array = RemoveZore(array);
            for (int i = 0; i < array.Length-1; i++)
            {
                if (array[i] != 0 && array[i] == array[i + 1])
                {
                    array[i] += array[i + 1];
                    array[i + 1] = 0;
                }
            }
            array = RemoveZore(array);
            return array;
        }

        //上移
        private static int[,] MoveUp(int[,] map)
        {
            int[] mergeArray = new int[map.GetLength(0)];
            for(int r = 0; r<map.GetLength(1);r++)
            {
                for (int i = 0; i < map.GetLength(0); i++)
                    mergeArray[i] = map[i, r];
                mergeArray = Merge(mergeArray);
                for (int i = 0; i < map.GetLength(0); i++)
                    map[i, r] = mergeArray[i];
            }
            return map;
        }

        //下移
        private static int[,] MoveDown(int[,] map)
        {
            int[] mergeArray = new int[map.GetLength(0)];
            for (int r = 0; r < map.GetLength(1); r++)
            {
                for (int i = map.GetLength(0) - 1; i >= 0; i--)
                    mergeArray[3-i] = map[i, r];
                mergeArray = Merge(mergeArray);
                for (int i =map.GetLength(0) - 1; i >= 0; i--)
                    map[i, r] = mergeArray[3-i];
            }
            return map;
        }

        //左移
        private static int[,] MoveLeft(int[,] map)
        {
            int[] mergeArray = new int[map.GetLength(1)];
            for(int r = 0; r<map.GetLength(0); r++)
            {
                for (int i = 0; i < map.GetLength(1); i++)
                    mergeArray[i] = map[r, i];
                mergeArray = Merge(mergeArray);
                for (int i = 0; i < map.GetLength(1); i++)
                    map[r,i] = mergeArray[i];
            }
            return map;
        }

        //右移
        private static int[,] MoveRight(int[,] map)
        {
            int[] mergeArray = new int[map.GetLength(1)];
            for (int r = 0; r < map.GetLength(0); r++)
            {
                for (int i = map.GetLength(1) - 1; i >= 0; i--)
                    mergeArray[3-i] = map[r, i];
                mergeArray = Merge(mergeArray);
                for (int i = map.GetLength(1) - 1; i >= 0; i--)
                    map[r, i] = mergeArray[3-i];
            }
            return map;
        }

数据类型

在这里插入图片描述

1.数据类型

类型分类

  1. 值类型:存储数据本身
  2. 引用类型:存储数据的引用(内存地址)

在这里插入图片描述

类型归属

在这里插入图片描述

2.内存分配

内存
在这里插入图片描述
分配
在这里插入图片描述

3.局部变量

值类型与引用类型
在这里插入图片描述 在这里插入图片描述

        	//值类型                                                 引用类型
         //存储数据本身int bool char          存储数据的引用(内存地址)string Array
         //因为方法执行在栈中,所以在方法中声明的变量都在栈中
         //因为值类型直接存储数据,所以数据存储在栈中
         //因为引用类型存储数据的引用,所以数据在堆中,栈中存储数据的地址

分配图
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

垃圾回收器
在这里插入图片描述

4.应用

传参

  1. 值参数
    值参数:按值传递 – 传递实参变量存储的内容
    作用:传递信息
        static void Main4(string[] args)
        {
            int a = 1;
            int[] arr = new int[] { 1 };
            Fun1(a,arr);//实参将 数据1 赋值给形参
            Console.WriteLine(a); // a = 1
            Console.WriteLine(arr[0]);// 2;

            int a2 = 1;
            Fun2(ref a2);
            Console.WriteLine(a2);// a = 2

            //区别2:调用方法之前可以不赋值
            int a3;
            Fun3(out a3);
            Console.WriteLine(a3);// a = 2;
            
           	int num01 = 1;
            int num02 = 2;
            Exchange(ref num01, ref num02);
            Console.WriteLine(num01);
            Console.WriteLine(num02);
            int Mj;
            int Zc;
            CalculateRect(num01, num02, out Mj, out Zc);
            Console.WriteLine("面积:{0},周长:{1}",Mj,Zc);
        }
        private static void Fun1(int a,int[] arr)
        {
            a = 2;
           // arr[0] = 2;
        }
  1. 引用参数
    引用参数:按引用传递 – 传递实参变量自身的内存地址
    作用:改变数据
        private static void Fun2(ref int a) //ref引用参数
        {
            a = 2;
        }
  1. 输出参数
    输出参数:按引用传递 – 传递实参变量自身的内存地址
    作用:返回结果
        private static void Fun3(out int a)//out输出参数
        {//区别1:方法内部必须做出修改  -->导致区别2
            a = 2;
        }

两个代码案例直观了解用法

        //两个整数交换
        private static void Exchange(ref int a,ref int b)
        {
            int c = a;
            a = b;
            b = c;
        }

        //计算长方形的面积与周长
        private static void CalculateRect(int a,int b,out int c,out int d)
        {
            c = a * b;
            d = (a + b) * 2;
        }

Try.Parse方法

            int result;
            //Try.Parse方法,返回2个结果
            //out:转换后的结果
            //返回值:是否可以转换
            bool re = int.TryParse("250+", out result);

5.拆装箱

在这里插入图片描述
在这里插入图片描述

分配图
在这里插入图片描述
解释代码

        static void Main(string[] args)
        {
            int a = 1;

            //装箱操作:“比较”消耗性能(“最”)
            object o = a;

            //拆箱unbox: “比较”消耗性能
            int b = (int)o;
            //形参object类型,实参传递值类型,则装箱
            //可以通过 重载、泛型避免
        }

枚举

在这里插入图片描述

  • 运用枚举需要新创建一个类

  • 类中变量默认为int类型

  • 按位运算符(用于有多个枚举值的时候)

    1.运算符 | (按位或):两个对应的二进制中有一个为1,结果位为1
    tall | rich ==> 0000000000 | 000000001 ==> 00000000001
    使用条件
    任意多个枚举值做|运算的结果不能与其他枚举值相同(值为2的n次方递增)
    定义枚举时,使用【Flags】特性修饰
    2.与此同时还有运算符&(按位与)具体解释可以百度

  • 解释代码块

namespace Day07
{
    [Flags]
    enum PersonStyle
    {
        tall = 1,                                                   //tall = 0;  0000000000
        rich = 2,                                                   //rich = 1; 0000000001
        handsome = 4,
        white = 6,
        beauty = 8
    }
    private static void PrintPersonStyle(PersonStyle style)
        {
            if((style & PersonStyle.handsome) ==PersonStyle.handsome)
                Console.WriteLine("帅气");
            if ((style & PersonStyle.rich) != 0)                                    //按位与 的两种写法
            {
                Console.WriteLine("有钱");
            }
        }
         static void Main1(string[] args)
        {
            PrintPersonStyle(PersonStyle.handsome | PersonStyle.rich);
            }
  • Enum数据类型转换

      1.int ==> Enum
      PersonStyle style01 = (PersonStyle)2;//显式转换
      2.Enum ==> int
      int eunmNumber = (int)(PersonStyle.rich | PersonStyle.handsome); //显式转换
      3.string ==> Enum
      PersonStyle style02 = (PersonStyle) Enum.Parse(typeof(PersonStyle),"beauty");
      4.Enum ==> string
      string strEnum = PersonStyle.handsome.ToString();
    

类与对象

在这里插入图片描述

什么是类什么是对象

类和对象

在这里插入图片描述

创建类

在这里插入图片描述代码解释

class Wife
    {
        //数据成员
        private string name;
        private string sex;
        private int age;
        public  void SetName(string name)
        {
            //this 这个对象(引用)
            this.name = name;
        }

        public string GetName()
        {
            return name;
        }
      //方法成员
        public void SetAge(int age)
        {
            if (age >= 22 && age <= 27)
                this.age = age;
            else
                throw new Exception("我不要");
        }

        public int GetAge()
        {
            return this.age;
        }
    }

创建对象

在这里插入图片描述代码解释

        static void Main2(string[] args)
        {
            //声明Wife类型的引用
            Wife wife01;
            //指向Wife类型的对象(实例化Wife类型对象)
            wife01 = new Wife("xiaobao",22);
            wife01.SetAge(27);
            wife01.SetName("xiaobao");

            Wife wife02 = wife01;
            wife02.SetAge(22);
            Console.WriteLine(wife01.GetAge());
            Console.WriteLine(wife01.GetName());

            Wife wife03 = new Wife();
            wife03.Name = "qixiang";  //Name 属性
            Console.WriteLine(wife03.Name);


            Console.ReadLine();
        }

构造函数

定义

在这里插入图片描述

  • 构造函数:提供了创建对象的方式,常常用于初始化类的数据成员
  • 一个类若没有构造函数,那么编译器会自动提供一个无参数构造函数
  • 一个类若具有构造函数,那么编译器不会自动提供一个无参数构造函数
  • 如果不希望在类的外部创建对象,将构造函数私有化
  • 本质:方法

特点

在这里插入图片描述代码解释

        public Wife()
        {
            Console.WriteLine("创建对象就执行");
        } //构造函数的重载

        public Wife(string name):this()
        {//Wife{}; 调用无参数构造函数
            this.name = name;
        }
        public Wife(string  name, int age):this(name)//调用上一个构造函数
        {
            
           // this.name = name;//构造函数如果为字段赋值,属性中的代码块不会执行
            this.Age = age;
        }

this关键字

在这里插入图片描述

属性

在这里插入图片描述代码解释

        //字段:存储数据
        private string name;
        //属性:保护字段 本质就是2个方法
        public string Name
        {
            //读取时保护
            get
            { return name; }
            //写入时保护 value 要设置的数据
            set
            { this.name = value;}
        }
        private string sex;
        private int age;

        public int Age
        {
            get
            { return age; }
            set
            {
                if (value >= 22 && value <= 27)
                    this.age = value;
                else
                    throw new Exception("我不要");
            }
        }
        //自动属性 : 包含一个字段 两个方法
        public string Password { get; set; }
			Wife wife01;
            //指向Wife类型的对象(实例化Wife类型对象)
            //wife01 = new Wife("xiaobao",22);
            wife01.SetAge(27);
            wife01.SetName("xiaobao");

            Wife wife02 = wife01;
            wife02.SetAge(22);
            Console.WriteLine(wife01.GetAge());
            Console.WriteLine(wife01.GetName());

            Wife wife03 = new Wife();
            wife03.Name = "qixiang";  //Name 属性
            Console.WriteLine(wife03.Name);

c#泛型集合

  1. List<数据类型>
//c#泛型集合  List<数据类型>
//User[]         new User[];
List<User> list02= new List<User>();
list02.Add(user01);
list02.Add(new User());
//list02.Insert();
User u2 = list02[0];//根据索引获取元素
  1. 字典集合(Dictionary)
 //字典
Dictionary<string, User> dic = new Dictionary<string, User>();
 dic.Add("xiaobao",new User("xiaobao","23123"));
User xiaoBao = dic["xiaobao"];

练习书写(用户类)

namespace Day07
{
    /// <summary>
    /// 用户类
    /// </summary>
    class User
    {
        //字段
        private string loginId;

        //属性
        public string Loginid
    {
            get
        { return this.loginId; }
            set
        { this.loginId = value; }
    }

        //自动属性 : 包含一个字段 两个方法
        public string Password { get; set; }

        public User ()
        {

        }

        public User(string loginId,string passWord)
        {
            this.loginId = loginId;
            this.Password = passWord;
        }

        public void PrintUser()
        {
            Console.WriteLine("账号:{0},密码:{1}",loginId,Password);
        }

    }
            static void Main(string[] args)
        {
            User user01 = new User ( "2323244", "2323454" );
            user01.PrintUser();




            Console.ReadLine();
        }

继承

一、我们首先创建一个Person基类和Student和Teacher派生类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Day08
{
    /// <summary>
    /// 人(父类)
    /// </summary>
    class Person
    {
        public string Name { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Day08
{
    /// <summary>
    /// 学生类
    /// </summary>
    class Student:Person
    {
        //prop + Tab Tab 快捷键
        
        public int Score { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Day08
{
    /// <summary>
    /// 老师类
    /// </summary>
    class Teacher:Person
    {
        public int Salary { get; set; }
    }

由此我们可以看出一个类想要继承另一个类的成员,书写格式为派生类:基类

二、
1.父类只能使用父类成员
2.子类可以使用父类成员
3.父类的引用可以指向子类的对象,但还是只能使用父类成员,但可以进行强制显示转换,但是两个子类无法进行显示转换,代码不报错,但是会有异常,可以用“as”进行转换

三、代码解释

        //继承
        static void Main1(string[] args)
        {
            

            //父类 只能使用 父类成员
            Person person01 = new Person();
            person01.Name = "dad";

            //子类 可以使用 父类成员
            Student stu01 = new Student();
            stu01.Name = "";

            //父类的引用 指向 子类的对象
            //只能使用父类成员
            Person person02 = new Student();
            Student stu02 = (Student)person02;
            stu02.Score = 34;
            //异常  代码可以写
            //Teacher teacher02 = (Teacher)person02;//有问题
            Teacher teacher02 = person02 as Teacher; //可以这样写
            //teacher02.Salary = 100;
        }

静态

静态成员变量

1.静态成员->类->类名调用
2.实列成员->对象->引用调用
在这里插入图片描述

静态构造函数

静态构造函数没有访问级别
在这里插入图片描述

静态方法与静态类

在这里插入图片描述
在这里插入图片描述要点
在这里插入图片描述在这里插入图片描述

适用性与分配图

在这里插入图片描述在这里插入图片描述

结构体

什么是结构

在这里插入图片描述

定义结构体

在这里插入图片描述

2048核心类

1.游戏核心类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Console2048
{
    /// <summary>
    /// 游戏核心类,负责处理游戏核心算法,与界面无关
    /// </summary>
    class GameCore
    {
        private int[,] map;
        private int[] mergeArray;
        private int[] removeZeroArray;
        private int[,] originalMap;

        public int[,] Map
        {
            get { return this.map; }
        }
        public GameCore()
        {
            map = new int[4, 4];
            mergeArray = new int[4];
            removeZeroArray = new int[4];
            emptyLocationList = new List<Location>(16);
            random = new Random();
            originalMap = new int[4, 4];
        }
        private  void RemoveZore()
        {
            //每次去零操作,去零数组归零
            Array.Clear(removeZeroArray, 0, 4);
            int index = 0;
            for (int i = 0; i < mergeArray.Length; i++)
            {
                if (mergeArray[i] != 0)
                    removeZeroArray[index++] = mergeArray[i];
            }
            removeZeroArray.CopyTo(mergeArray, 0);

        }
        private  void Merge()
        {
            RemoveZore();
            for (int i = 0; i < mergeArray.Length - 1; i++)
            {
                if (mergeArray[i] != 0 && mergeArray[i] == mergeArray[i + 1])
                {
                    mergeArray[i] += mergeArray[i + 1];
                    mergeArray[i + 1] = 0;
                }
            }
            RemoveZore();
        }
        private  void MoveUp()
        {
            for (int r = 0; r < map.GetLength(1); r++)
            {
                for (int i = 0; i < map.GetLength(0); i++)
                    mergeArray[i] = map[i, r];
                Merge();
                for (int i = 0; i < map.GetLength(0); i++)
                    map[i, r] = mergeArray[i];
            }
        }
        private  void MoveDown()
        {
            for (int r = 0; r < map.GetLength(1); r++)
            {
                for (int i = map.GetLength(0) - 1; i >= 0; i--)
                    mergeArray[3 - i] = map[i, r];
                Merge();
                for (int i = map.GetLength(0) - 1; i >= 0; i--)
                    map[i, r] = mergeArray[3 - i];
            }
        }
        private  void MoveLeft()
        {
            for (int r = 0; r < map.GetLength(0); r++)
            {
                for (int i = 0; i < map.GetLength(1); i++)
                    mergeArray[i] = map[r, i];
                Merge();
                for (int i = 0; i < map.GetLength(1); i++)
                    map[r, i] = mergeArray[i];
            }
        }
        private  void MoveRight()
        {
            for (int r = 0; r < map.GetLength(0); r++)
            {
                for (int i = map.GetLength(1) - 1; i >= 0; i--)
                    mergeArray[3 - i] = map[r, i];
                Merge();
                for (int i = map.GetLength(1) - 1; i >= 0; i--)
                    map[r, i] = mergeArray[3 - i];
            }
        }

        public bool IsChange { get; set;}  
        public  void Move(MoveDirection direction)
        {
            Array.Copy(map, originalMap, 4);
            switch (direction)
            {
                case MoveDirection.Up:
                    MoveUp();
                    break;
                case MoveDirection.Down:
                    MoveDown();
                    break;
                case MoveDirection.Left:
                    MoveLeft();
                    break;
                case MoveDirection.Right:
                    MoveRight();
                    break;
            }
            for (int r = 0; r < map.GetLength(0); r++)
            {
                for (int c = 0; c < map.GetLength(1); c++)
                {
                    if (map[r, c] != originalMap[r, c])
                    {
                        IsChange = true;
                        return;
                    }
                }
            }
        }

            //生成数字
            //需求:在空白位置,随机产生一个2(90%)或者4(10%)
            //分析:先计算所有空白位置
            //        在随机选择一个位置
        //       随机  2 ,4
        private List<Location> emptyLocationList;
        private void CalculateEmpty()
        {
            //每次统计空位置,先清空列表
            emptyLocationList.Clear();
            for (int r = 0; r < map.GetLength(0); r++)
            {
                for (int c = 0; c < map.GetLength(1); c++)
                {
                    if (map[r,c] == 0)
                    {
                        //记录 额r,c
                        //类【数据类型】 类数据成员【多个类型】
                        //将多个基本数据类型,封装为一个自定义类型
                        emptyLocationList.Add(new Location(r, c));
                    }
                }
            }
        }

        private Random random;
        public void GenerateNumber()
        {
            CalculateEmpty();
           if(emptyLocationList.Count > 0)
           {
                int randomIndex = random.Next(0, emptyLocationList.Count);
                Location loc = emptyLocationList[randomIndex];
                map[loc.RIndex, loc.CIndex] = random.Next(0, 10) == 1 ? 4 : 2;
           }
            
        }
    }
}

2.地址类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Console2048
{
    struct  Location
    {
        public int RIndex { get; set; }

        public int CIndex { get; set; }

        public Location(int rIndex,int cIndex):this()
        {
            this.RIndex = rIndex;
            this.CIndex = cIndex;
        }
    }
}

3.枚举(移动方向类)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Console2048
{
    /// <summary>
    /// 定义枚举类型:移动方向
    /// </summary>
    enum MoveDirection:int //enum 枚举
    {
        Up = 0,//Up 默认为int类型
        Down = 1,
        Left = 2,
        Right = 3
    }
}

4.主程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Console2048
{
    class Program
    {
        static void Main(string[] args)
        {
            GameCore core = new GameCore();
            core.GenerateNumber();
            core.GenerateNumber();

            //显示界面
            DrawMap(core.Map);
            //移动
            while(true)
            {
                KeyDown(core);
                if(core.IsChange == true)
                {
                core.GenerateNumber();
                DrawMap(core.Map);
                }


            }
            Console.ReadLine();
        }
        private static void DrawMap(int[,] map)
        {
            Console.Clear();//清空后台
            for (int r = 0; r < 4; r++)
            {
                for (int c = 0; c < 4; c++)
                {
                    Console.Write(map[r,c] + "\t");
                }
                Console.WriteLine();
            }
        }

        private static void KeyDown(GameCore core)
        { 

            switch (Console.ReadLine())
            {
                
                case "w":
                    core.Move(MoveDirection.Up);
                    break;
                case "s":
                    core.Move(MoveDirection.Down);
                    break;
                case "a":
                    core.Move(MoveDirection.Left);
                    break;
                case "d":
                    core.Move(MoveDirection.Right);
                    break;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值