开篇

2048游戏现在很火啊,很多人应该已经玩过了。在博客园上也看见有人模仿做的GDI+版 2048游戏,鄙人暂且不做那么多动画的东西,毕竟是个小东东,在此奉上一个《控制台版2048》。

本文程序源码下载:http://pan.baidu.com/s/1mg8zntu

程序结构相对简单,一共200+行代码,注释很少,大家大概也看得懂,我在这解释下程序中各个方法的含义:
Main 方法程序入口,
RePaint 类似Win32程序中的刷新界面,
SquareRot90 矩形矩阵顺时针旋转90度角(参数可以为负,表示逆时针)。
Merge 向左移动,合并单元格中值相同的元素,并进行整理(将所有元素靠左放置)
RandomPoint 随机生成点,从矩阵的空位置(值为0)中随机生成一个点,若不存在空位置返回null。
CanMove 判断是否可以继续移动,也是判断游戏是否结束的方法。
IsEquals 判断两矩阵的值是否相同。
CopyToB 将矩阵复制一份。
流程图如下:
上代码
 
主函数Main
static void Main(string[] args)
{
int[,] a = new int[4, 4];
a[1, 2] = 2;
a[2, 2] = 2;
a[2, 1] = 2;
RePaint(a);
while (true)
{
ConsoleKeyInfo key = Console.ReadKey();
switch (key.Key)
{
case ConsoleKey.UpArrow:
a = SquareRot90(a, 3);
a = Merge(a);
a = SquareRot90(a, -3);
break;
case ConsoleKey.DownArrow:
a = SquareRot90(a, 1);
a = Merge(a);
a = SquareRot90(a, -1);
break;
case ConsoleKey.LeftArrow:
a = Merge(a);
break;
case ConsoleKey.RightArrow:
a = SquareRot90(a, 2);
a = Merge(a);
a = SquareRot90(a, -2);
break;
}
Point cp = RandomPoint(a);
if (cp != null)
{
a[cp.X, cp.Y] = 2;
RePaint(a);
}
if (cp == null && !CanMove(a))
{
RePaint(a, "Game Over");
}
}
}

  

矩阵旋转方法
/// 矩形顺时针旋转90°
/// </summary>
/// <param name="rotNum">旋转次数</param>
public static int[,] SquareRot90(int[,] a, int rotNum)
{
while (rotNum < 0)
{
rotNum += 4;
}
for (int rot_i = 0; rot_i < rotNum; rot_i++)
{
int[,] b = new int[a.GetLength(1), a.GetLength(0)];
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < a.GetLength(1); j++)
{
b[j, a.GetLength(0) - i - 1] = a[i, j];
}
}
a = b;
}
return a;
}

  

随机点方法
public static Point RandomPoint(int[,] a)
{
List<Point> lstP = new List<Point>();
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < a.GetLength(1); j++)
{
if (a[i, j] == 0)
{
lstP.Add(new Point(i, j));
}
}
}
if (lstP.Count == 0)
{
return null;
}
int rnd = new Random().Next(lstP.Count);
return lstP[rnd];
}

  

矩阵向左合成方法
public static int[,] Merge(int[,] a)
{
for (int i = 0; i < a.GetLength(0); i++)
{
int lastNum = 0;
int last_j = 0;
for (int j = 0; j < a.GetLength(1); j++)//合并
{
if (lastNum != a[i, j] && a[i, j] != 0)
{
lastNum = a[i, j];
last_j = j;
}
else if (lastNum == a[i, j])
{
a[i, last_j] = 0;
a[i, j] = lastNum + a[i, j];
}
}
last_j = 0;
for (int j = 0; j < a.GetLength(1); j++)//整理
{
if (a[i, j] != 0)
{
a[i, last_j] = a[i, j];
if (last_j != j)
a[i, j] = 0;
last_j++;
}
}
}
return a;
}

  

是否可以继续移动CanMove方法
public static bool CanMove(int[,] a)
{
bool res = false;
int[,] b = CopyToB(a);
b = Merge(b);
if (!IsEquals(a, b))
res = true;
b = CopyToB(a);
b = SquareRot90(b, 1);
b = Merge(b);
b = SquareRot90(b, -1);
if (!IsEquals(a, b))
res = true;
b = CopyToB(a);
b = SquareRot90(b, 2);
b = Merge(b);
b = SquareRot90(b, -2);
if (!IsEquals(a, b))
res = true;
b = CopyToB(a);
b = SquareRot90(b, 3);
b = Merge(b);
b = SquareRot90(b, -3);
if (!IsEquals(a, b))
res = true;
return res;
}

  

CanMove中用到的IsEquals方法,判断矩阵相等
public static bool IsEquals(int[,] a, int[,] b)
{
bool res = true;
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < a.GetLength(1); j++)
{
if (b[i, j] != a[i, j])
{
res = false;
break;
}
}
if (!res)
break;
}
return res;
}

  

CanMove中用到的矩阵复制方法CopyToB
public static int[,] CopyToB(int[,] a)
{
int[,] b = new int[a.GetLength(0), a.GetLength(1)];
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
}
}
return b;
}

  

两个RePain方法,重新打印,前面的表示GameOver
public static void RePaint(int[,] a, string s)
{
while (true)
{
Console.Clear();
RePaint(a);
Console.WriteLine("\n\n\n\n\t\t" + s + "\n\n");
Console.ReadKey();
}
}
public static void RePaint(int[,] a)
{
Console.Clear();
for (int j = 0; j < a.GetLength(1); j++)
{
Console.Write("───");
}
Console.Write("\n");
for (int i = 0; i < a.GetLength(0); i++)
{
Console.Write("│");
for (int j = 0; j < a.GetLength(1); j++)
{
string s = "";
if (a[i, j] == 0)
s = " ";
else if (a[i, j] < 10)
s = " " + a[i, j] + " ";
else if (a[i, j] < 100)
s = "" + a[i, j] + " ";
else
s = "" + a[i, j];
Console.Write(s + "│");
}
Console.Write("\n");
for (int j = 0; j < a.GetLength(1); j++)
{
Console.Write("───");
}
Console.Write("\n");
}
}

  

辅助类Point
class Point
{
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
public int X
{
get;
set;
}
public int Y
{
get;
set;
}
}

  

结束语
     其实要写一个游戏并不是像想像中那么容易,要处理算法等问题,必须要事先仔细的设计,需要一张草纸作为设计图,这样会让工作效率大大提高。之前贴过毕设的游戏《保卫萝卜》,由于时间关系迟迟没有整理,等毕设答辩完成后,一定好好整理,给大家分享。现在功能基本完成了,在这先贴一个缩减版的游戏程序,链接: http://pan.baidu.com/s/1sjvxO7N 。程序有什么问题、BUG,希望大家多多留言。源码整理后再上传。
     过几天是蓝桥杯比赛,哈哈,北京我来了。
本文程序源码下载:http://pan.baidu.com/s/1mg8zntu 
 

2048 控制台版(C#)的更多相关文章

  1. c/c++ 贪吃蛇控制台版

    贪吃蛇控制台版(操作系统win7 64位:编译环境gcc, vs2017通过,其它环境未测试 不保证一定通过) 运行效果: #include <iomanip> #include < ...

  2. 基于TCP协议的聊天室控制台版

    我之前写过一篇博客,主要是基于TCP协议实现的聊天室swing版,在此再写一个基于TCP协议实现的聊天室控制台版,便于学习和比较. package 聊天室console版.utils; import ...

  3. c++实现通讯录管理系统(控制台版)

    c++实现通讯录管理系统(控制台版) 此项目适合c++初学者,针对c++基础知识,涉及到变量.结构体定义使用.数组定义使用.指针定义使用等. 运行之后的结果如下: 代码: #include <i ...

  4. C++实现控制台版2048

    前言 之前做过一个JavaScript版本的2048游戏,最近在学习C++,昨天晚上突然心血来潮,想用C++来实现,因为核心算法已十分理解,所以两个小时撸出来一个C++的简易版本. 简介 二维数组遍历 ...

  5. c#撸的控制台版2048小游戏

    1.分析 最近心血来潮,突然想写一个2048小游戏.于是搜索了一个在线2048玩玩,熟悉熟悉规则. 只谈核心规则:(以左移为例) 1.1合并 以行为单位,忽略0位,每列依次向左进行合并,且每列只能合并 ...

  6. Delphi_01_控制台版HelloWorld

    对于Windows下的控制台编程,我相信很多人都不陌生.而C语言开始的著名的“Hello world”程序基本是学习编程的第一步.我想对于 RAD开发,大家熟悉的一般都是GUI编程,而对于consol ...

  7. [C++项目]2048控制台游戏

    #include <iostream> #include <windows.h> #include <ctime> using namespace std; ; ; ...

  8. Java小例子(学习整理)-----学生管理系统-控制台版

    1.功能介绍: 首先,这个小案例没有使用数据库,用集合的形式暂时保存数据,做测试! 功能: 增加学生信息 删除学生信息 修改学生信息 查询学生信息:  按照学号(精确查询)  按照姓名(模糊查询) 打 ...

  9. 2048聚合版开源代码,cocos2d-js编写,基于CocosEditor开发工具,可运行Android,ios,html5等

    1. [代码][JavaScript]代码         /** * @GameName : * 2048 * * @DevelopTool: * Cocos2d-x Editor (CocosEd ...

随机推荐

  1. Spring之bean生命始末

    可以为Bean定制初始化后的生命行为,也可以为Bean定制销毁前的生命行为.举例:ba06包.首先,这些方法需要在Bean类中事先定义好:是方法名随意的public void方法. 其次,在配置文件的 ...

  2. 3015C语言_流程设计

    第五章 流程设计 5.1 C语句概述 C语言的语句用来向计算机系统发出指令,一个实际的源程序通常包含若干语句,这些语句用来完成一定的操作任务. 1.其他类型语句 函数调用语句(由函数调用加一个分号构成 ...

  3. Docker环境下的前后端分离项目部署与运维(十一)Docker Swarm技术

    Docker Swarm技术 docker swarm技术(之前的docker集群都是在 一个虚拟主机上的,但是如果这个主机挂掉了over了,docker技术就是多个虚拟主机形成一个集群) Swarm ...

  4. java.nio.Buffer源码阅读

    Java 自从 JDK1.4 起,对各种 I/O 操作使用了 Buffer 和 Channel 技术.这种更接近于操作系统的的底层操作使得 I/O 操作速度得到大幅度提升,下面引用一段<Java ...

  5. 软件测试入门-测试模型(V型 W型 H型)

    软件测试工程师称为“QA”,质量保证者——这是入门的第一点要学习的. 首先看基本的测试模型 1.“V”型 特点:[活动串行]这是一种古老的瀑布模型,反映了实际和测试之间的关系. 局限:仅仅把测试过程作 ...

  6. 20 如何通过pycharm快速的创建一个html页面

    1.打开pycharm并且新建一个html页面,如下图所示. 2.删除html页面中默认的内容,之后在页面中输入!,之后点击tab即可完成一个html页面的框架新增.

  7. docker系列(五):网络通信

    1 引言 之前的几篇docker系列博客说的都是单个容器或者镜像的操作.但容器,作为一种简化的操作系统,又怎能不与机器或者容器相互协同工作呢,这就需要用到容器的网络功能.docker中提供了多种不同的 ...

  8. 使用Core Audio实现VoIP通用音频模块

    最近一直在做iOS音频技术相关的项目,由于单项直播SDK,互动直播SDK(iOS/Mac),短视频SDK,都会用到音频技术,因此在这里收集三个SDK的音频技术需求,开发一个通用的音频模块用于三个SDK ...

  9. Hadoop —— 集群环境搭建

    一.集群规划 这里搭建一个3节点的Hadoop集群,其中三台主机均部署DataNode和NodeManager服务,但只有hadoop001上部署NameNode和ResourceManager服务. ...

  10. apache出现forbidden

    <Directory /> Options FollowSymLinks AllowOverride All Order deny,allow allow from all Require ...