游戏2048的核心算法c#版本的实现
接触游戏有一段时间了,也写了一些东西,效果还不错,今天没事,我就把2048 c# 版本的实现贴出来,代码已经测试过,可以正常、完美运行。当然了,在网上有很多有关2048的实现方法,但是没有提出到类里面,只是写的测试代码,我在这里已经完全提到类里面,核心类和核心方法都经过测试,没有问题。由于本人学习有漏,或者不足,也请大家批评指正,大家共同进步。 ?? 该文章分为三个部分,我们分门别类说的,大家也会很清楚。目录如下: 这是程序第一次执行的效果,数据刚刚完成初始化。 2、操作开始,点击键盘的 a 字母代表向做移动,分为两张图,移动前和移动后的效果。 左移前 左移后 3、点击键盘的 D 字符代表向右移动,分为两个图片,分别是移动前和移动后。 移动前 移动后 4、点击键盘的 w 字符代表向上移动,分为两个图片,分别是移动前和移动后。 移动前
移动后 5、点击键盘的 s 字符代表向下移动,分为两个图片,分别是移动前和移动后。 移动前
移动后 二、在控制台中控制逻辑和一些辅助方法,逻辑很简单,就不多说了,直接上代码。 ? 1 GameCoreManager game = new GameCoreManager(5); 2 3 game.Initail(); 4 5 Console.WriteLine("原始数组:" 6 PrintArray(game.DataContainer); 7 Console.WriteLine(); 8 9 while (true) 10 { 11 if (game.CalculateEmptyElements(game.DataContainer).Count <= 012 { 13 Console.WriteLine(游戏结束14 break; 15 } 16 switch (Console.ReadLine()) 17 18 case w: 19 game.Move(Direction.Up); 20 21 s22 game.Move(Direction.Down); 23 24 a25 game.Move(Direction.Left); 26 27 d28 game.Move(Direction.Right); 29 30 exit31 32 33 if (game.IsChange) 34 35 game.GenerateRandomNumber(); 36 PrintArray(game.DataContainer); 37 38 }
? 这个代码主要适用于打印二维数组的,逻辑不复杂,用于在控制台中显示移动效果。 1 /// <summary> 2 /// 打印二维数组在控制台上。 3 </summary> 4 <param name="array">要打印数据的数组。</param> 5 private static void PrintArray(int[,] array) { Console.Clear(); 8 if (array == null || array.Length <= 9 10 Console.WriteLine(没有任何元素可以打印。11 } 12 13 for (int row = 0; row < array.GetLength(0); row++14 15 int column = 0; column < array.GetLength(1); column++16 17 Console.Write(array[row,column]+t18 Console.WriteLine(); 20 21 }
1 2 游戏核心算法的管理器类型,该类型定义 2048 游戏的核心算法。 3 4 public sealed class GameCoreManager 5 { 6 #region 实例字段 7 8 9 10 #endregion 11 12 #region 构造函数 13 14 15 初始化 GameCoreManager 类型的新实例,数据容器维度默认值:4. 16 17 public GameCoreManager() : this(4) { } 18 19 20 通过制定的数据维度初始化 GameCoreManager 类型的新实例。 21 22 <param name="capacity">数据容量。 23 public GameCoreManager( capacity) 24 25 if (capacity <= 0 || capacity >= 32 26 27 throw new ArgumentNullException(dimensional is null. 28 29 DataContainer = new [capacity,capacity]; 30 } 31 32 33 34 #region 实例属性 35 36 37 获取数据 38 39 int[,] DataContainer { get => _dataContainer; set => _dataContainer = value; } 40 41 42 43 #region 实例接口方法 44 45 46 初始化游戏数据。 47 48 void Initail() 49 50 int length = DataContainer.GetLength(0) / 2 + DataContainer.GetLength(0) % 2 51 int i = 0; i < length; i++ 52 53 GenerateRandomNumber(); 54 55 56 57 58 数据移动。 59 60 <param name="direction">要移动的方向 61 Move(Direction direction) 62 63 //判断原数组是否发生了变化。 64 记录原数组。 65 int[DataContainer.GetLength(0),DataContainer.GetLength(1)]; 66 Array.Copy(DataContainer,destinationArray,DataContainer.Length); 67 IsChange = false 68 69 (direction) 70 71 case Direction.Up: 72 MoveUp(); 73 74 Direction.Down: 75 MoveDown(); 76 77 Direction.Left: 78 MoveLeft(); 79 80 Direction.Right: 81 MoveRight(); 82 83 84 85 比较现在的数组和以前的数组比较 86 0; row < DataContainer.GetLength( 87 88 0; column < DataContainer.GetLength( 89 90 if (DataContainer[row,column] != destinationArray[row,column]) 91 { 92 IsChange = 93 return 94 } 95 96 97 98 99 100 获取或者设置数组元素是否发生变动。true 表示发生变动,false 表示没有变动。 101 102 bool IsChange { get; set; } 103 104 105 计算空元素的个数,并保存元素的索引位置。 106 107 <param name="sourceArray">要处理的二维数组。108 <returns>返回保存空元素索引位置的列表对象。</returns> 109 public IList<Position> CalculateEmptyElements(110 111 IList<Position> elements = new List<Position>(DataContainer.GetLength(0) * DataContainer.GetLength()); 112 if (sourceArray == null || sourceArray.Length <= 113 114 elements; 115 116 117 0; row < sourceArray.GetLength(118 119 0; column < sourceArray.GetLength(120 121 if (sourceArray[row,column] == 122 123 elements.Add(new Position(row,column)); 124 125 126 127 128 129 130 131 随机生成数字元素填充空的数组元素。 132 133 GenerateRandomNumber() 134 135 var list = CalculateEmptyElements(this.DataContainer); 136 if (list.Count > 137 138 Random random = Random(); 139 var position = list[random.Next(,list.Count)]; 140 DataContainer[position.Row,position.Column] = random.Next(0,10) == 4 ? 4 : 141 142 143 144 145 146 #region 实例私有方法(核心算法) 147 148 149 将数组中的为 0 的元素移动到数组最后面。[1,2],结果为【1,2,0】 150 151 要处理的数组。152 void MoveZeroToLast([] array) 153 154 155 156 157 158 159 int[] myarray = [array.Length]; 160 161 int index = 162 0; i < array.Length; i++163 164 if (array[i] != 165 166 myarray[index++] = array[i]; 167 168 169 通过引用修改元素才可以,修改引用对外界没有影响。 170 myarray.CopyTo(array,1)">171 172 173 174 合并数组中相邻相同的数字元素,后一个元素清零。[2,2],结果为【4,1)">175 176 177 void MergeSameNumber(178 179 180 181 182 183 184 MoveZeroToLast(array);2,0 185 186 0; i < array.Length - 1; i++187 188 0 && array[i] == array[i + ]) 189 190 array[i] += array[i + ]; 191 array[i + 1] = 192 193 194 195 4,1)">196 197 MoveZeroToLast(array);198 199 200 201 向上移动数据。 202 203 MoveUp() 204 205 从上往下取数据。 206 if (DataContainer == null || DataContainer.Length <= 207 208 209 210 211 int[] tempArray = 212 213 214 215 216 217 tempArray[row] = DataContainer[row,column]; 218 219 220 MergeSameNumber(tempArray); 221 222 223 224 DataContainer[row,column] = tempArray[row]; 225 226 227 228 229 230 向下移动数据。 231 232 MoveDown() 233 234 从下往上取 235 236 237 238 239 240 241 242 243 244 int row = DataContainer.GetLength(0) - 1; row >= 0; row--245 246 tempArray[DataContainer.GetLength(1 - row] =247 248 249 250 251 252 253 DataContainer[row,column] = tempArray[DataContainer.GetLength(1 - row]; 254 255 256 257 258 259 向左移动数据。 260 261 MoveLeft() 262 263 264 265 266 267 从左往右 268 269 270 271 0; i < DataContainer.GetLength(0); i++272 273 int j = 0; j < DataContainer.GetLength(1); j++274 275 tempArray[j] = DataContainer[i,j]; 276 277 278 279 280 281 282 DataContainer[i,j] = tempArray[j]; 283 284 285 286 287 288 向右移动数据。 289 290 MoveRight() 291 292 293 294 295 296 297 从右向左取 298 299 { 2,4,8 },8 300 301 { 0,8,0 },1)">302 303 304 305 306 1); i++307 308 int j = DataContainer.GetLength(1) - 1; j >= 0; j--309 310 8,2 311 tempArray[DataContainer.GetLength(1 - j] =312 313 314 315 316 317 318 319 DataContainer[i,j] = tempArray[DataContainer.GetLength( j]; 320 321 322 } 323 324 325 } ? ? 另外,还有两个枚举类型,代码很简单,直接贴代码了。 1 2 元素的坐标位置。 3 4 struct Position 5 6 7 获取或者设置元素的行坐标。 8 9 int Row { 10 11 12 获取或者设置元素的列坐标。 13 14 int Column { 15 16 17 通过行坐标、列坐标初始化 Position 对象实例。 18 19 <param name="row">元素的行坐标。20 <param name="column">元素的列坐标。21 public Position(int row, column) 23 if (row >= 0 && column >= 24 25 this.Row = row; 26 this.Column = column; 27 28 else 29 30 parameter is null.31 33 } 34 35 36 移动的方向。 37 38 enum Direction 39 40 41 向上移动 42 43 Up,1)">44 45 46 向下移动 47 48 Down,1)">49 50 51 向左移动 52 53 Left,1)">54 55 56 向右移动 57 58 Right 59 } ?
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |