当前位置: 首页 > news >正文

房产网站定制seo关键词优化平台

房产网站定制,seo关键词优化平台,做的好的网站营销微信公众号,杭州西湖区抖音seo哪里找一个控制台俄罗斯方块游戏的简单实现. 已在 github.com/SlimeNull/Tetris 开源. 思路 很简单, 一个二维数组存储当前游戏的方块地图, 用 bool 即可, true 表示当前块被填充, false 表示没有. 然后, 抽一个 “形状” 类, 形状表示当前玩家正在操作的一个形状, 例如方块, 直线…

一个控制台俄罗斯方块游戏的简单实现. 已在 github.com/SlimeNull/Tetris 开源.
在这里插入图片描述


思路

很简单, 一个二维数组存储当前游戏的方块地图, 用 bool 即可, true 表示当前块被填充, false 表示没有.

然后, 抽一个 “形状” 类, 形状表示当前玩家正在操作的一个形状, 例如方块, 直线, T 形什么的. 一个形状又有不同的样式, 也就是玩家可以切换的样式. 每一个样式都是原来样式旋转之后的结果. 为了方便, 可以直接使用硬编码的方式存储所有样式中方块的相对坐标.

一个形状有一个自己的坐标, 并且它包含很多方块. 在绘制的时候, 获取它每一个方块的坐标, 转换为地图内的绝对坐标, 然后使用 StringBuilder 拼接字符串, 即可.


资料

俄罗斯方块中总共有这七种方块

在这里插入图片描述


类型定义

一个简单的二维坐标

/// <summary>
/// 表示一个坐标
/// </summary>
/// <param name="X"></param>
/// <param name="Y"></param>
record struct Coordinate(int X, int Y)
{/// <summary>/// 根据基坐标和相对坐标, 获取一个绝对坐标/// </summary>/// <param name="baseCoord"></param>/// <param name="relativeCoord"></param>/// <returns></returns>public static Coordinate GetAbstract(Coordinate baseCoord, Coordinate relativeCoord){return new Coordinate(baseCoord.X + relativeCoord.X, baseCoord.Y + relativeCoord.Y);}
}

形状的一个样式, 单纯使用坐标数组存储即可.

record struct ShapeStyle(Coordinate[] Coordinates);

形状

/// <summary>
/// 形状基类
/// </summary>
abstract class Shape
{/// <summary>/// 名称/// </summary>public abstract string Name { get; }/// <summary>/// 形状的位置/// </summary>public Coordinate Position { get; set; }/// <summary>/// 形状所有的样式/// </summary>protected abstract ShapeStyle[] ShapeStyles { get; }/// <summary>/// 当前使用的样式索引/// </summary>private int _currentStyleIndex = 0;/// <summary>/// 从坐标构建一个新形状/// </summary>/// <param name="position"></param>public Shape(Coordinate position){Position = position;}/// <summary>/// 获取当前形状的当前所有方块 (相对坐标)/// </summary>/// <returns></returns>public IEnumerable<Coordinate> GetBlocks(){return ShapeStyles[_currentStyleIndex].Coordinates;}/// <summary>/// 获取当前形状下一个样式的所有方块 (相对坐标)/// </summary>/// <returns></returns>public IEnumerable<Coordinate> GetNextStyleBlocks(){return ShapeStyles[(_currentStyleIndex + 1) % ShapeStyles.Length].Coordinates;}/// <summary>/// 改变样式/// </summary>public void ChangeStyle(){_currentStyleIndex = (_currentStyleIndex + 1) % ShapeStyles.Length;}
}

一个 T 形状的实现

class ShapeT : Shape
{public ShapeT(Coordinate position) : base(position){}public override string Name => "T";protected override ShapeStyle[] ShapeStyles { get; } = new ShapeStyle[]{new ShapeStyle(new Coordinate[]{new Coordinate(-1, 0),new Coordinate(0, 0),new Coordinate(1, 0),new Coordinate(0, 1),}),new ShapeStyle(new Coordinate[]{new Coordinate(-1, 0),new Coordinate(0, -1),new Coordinate(0, 0),new Coordinate(0, 1),}),new ShapeStyle(new Coordinate[]{new Coordinate(-1, 0),new Coordinate(0, 0),new Coordinate(1, 0),new Coordinate(0, -1),}),new ShapeStyle(new Coordinate[]{new Coordinate(1, 0),new Coordinate(0, -1),new Coordinate(0, 0),new Coordinate(0, 1),}),};
}

主逻辑

上面的定义已经写好了, 接下来就是写游戏主逻辑.

主逻辑包含每一回合自动向下移动形状, 如果无法继续向下移动, 则把当前的形状存储到地图中. 并进行一次扫描, 将所有的整行全部消除.

抽一个 TetrisGame 的类用来表示俄罗斯方块游戏, 下面是这个类的基本定义.

class TetrisGame
{/// <summary>/// x, y/// </summary>private readonly bool[,] map;private readonly Random random = new Random();public TetrisGame(int width, int height){map = new bool[width, height];Width = width;Height = height;}public Shape? CurrentShape { get; set; }public int Width { get; }public int Height { get; }
}

判断当前形状是否可以进行移动的方法

/// <summary>
/// 判断是否可以移动 (移动后是否会与已有方块重合, 或者超出边界)
/// </summary>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <returns></returns>
private bool CanMove(int xOffset, int yOffset)
{// 如果当前没形状, 返回 falseif (CurrentShape == null)return false;foreach (var block in CurrentShape.GetBlocks()){Coordinate coord = Coordinate.GetAbstract(CurrentShape.Position, block);coord.X += xOffset;coord.Y += yOffset;// 如果移动后方块坐标超出界限, 不能移动if (coord.X < 0 || coord.X >= Width ||coord.Y < 0 || coord.Y >= Height)return false;// 如果移动后方块会与地图现有方块重合, 则不能移动if (map[coord.X, coord.Y])return false;}return true;
}

判断当前形状是否能够切换到下一个样式的方法

/// <summary>
/// 判断是否可以改变形状 (改变形状后是否会和已有方块重合, 或者超出边界)
/// </summary>
/// <returns></returns>
private bool CanChangeShape()
{// 如果当前没形状, 当然不能切换样式if (CurrentShape == null)return false;// 获取下一个样式的所有方块foreach (var block in CurrentShape.GetNextStyleBlocks()){Coordinate coord = Coordinate.GetAbstract(CurrentShape.Position, block);// 如果超出界限, 不能切换if (coord.X < 0 || coord.X >= Width ||coord.Y < 0 || coord.Y >= Height)return false;// 如果与现有方块重合, 不能切换if (map[coord.X, coord.Y])return false;}return true;
}

把当前形状存储到地图中

/// <summary>
/// 将当前形状存储到地图中
/// </summary>
private void StorageShapeToMap()
{// 没形状, 存寂寞if (CurrentShape == null)return;// 所有方块遍历一下foreach (var block in CurrentShape.GetBlocks()){// 转为绝对坐标Coordinate coord = Coordinate.GetAbstract(CurrentShape.Position, block);// 超出界限则跳过if (coord.X < 0 || coord.X >= Width ||coord.Y < 0 || coord.Y >= Height)continue;// 存地图里map[coord.X, coord.Y] = true;}// 当前形状设为 nullCurrentShape = null;
}

生成一个新形状

/// <summary>
/// 生成一个新形状
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
private void GenerateShape()
{int shapeCount = 7;int randint = random.Next(shapeCount);Coordinate initCoord = new Coordinate(Width / 2, 0);Shape newShape = randint switch{0 => new ShapeI(initCoord),1 => new ShapeJ(initCoord),2 => new ShapeL(initCoord),3 => new ShapeO(initCoord),4 => new ShapeS(initCoord),5 => new ShapeT(initCoord),6 => new ShapeZ(initCoord),_ => throw new InvalidOperationException()};CurrentShape = newShape;
}

扫描地图, 消除所有整行

/// <summary>
/// 扫描, 消除掉可消除的行
/// </summary>
private void Scan()
{for (int y = 0;  y < Height; y++){// 设置当前行是整行bool ok = true;// 循环当前行的所有方块, 如果方块为 false, ok 就会被设为 falsefor (int x = 0; x < Width; x++)ok &= map[x, y];// 如果当前行确实是整行if (ok){// 所有行全部往下移动for (int _y = y; _y > 0; _y--)for (int x = 0; x < Width; x++)map[x, _y] = map[x, _y - 1];// 最顶行全设为空for (int x = 0; x < Width; x++)map[x, 0] = false;}}
}

封装一些用户操作使用的方法

/// <summary>
/// 根据指定偏移, 进行移动
/// </summary>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
public void Move(int xOffset, int yOffse
{lock (this){if (CurrentShape == null)return;if (CanMove(xOffset, yOffset)){var newCoord = CurrentShape.newCoord.X += xOffset;newCoord.Y += yOffset;CurrentShape.Position = newC}}
}/// <summary>
/// 向左移动
/// </summary>
public void MoveLeft()
{Move(-1, 0);
}/// <summary>
/// 向右移动
/// </summary>
public void MoveRight()
{Move(1, 0);
}/// <summary>
/// 向下移动
/// </summary>
public void MoveDown()
{Move(0, 1);
}/// <summary>
/// 改变形状样式
/// </summary>
public void ChangeShapeStyle()
{lock (this){if (CurrentShape == null)return;if (CanChangeShape())CurrentShape.ChangeStyle();}
}/// <summary>
/// 降落到底部
/// </summary>
public void Fall()
{lock (this){while (CanMove(0, 1)){Move(0, 1);}}
}

游戏每一轮的主逻辑

/// <summary>
/// 下一个回合
/// </summary>
public void NextTurn()
{lock (this){// 如果当前没有存在的形状, 则生成一个新的, 并返回if (CurrentShape == null){GenerateShape();return;}// 如果可以向下移动if (CanMove(0, 1)){// 直接改变当前形状的坐标var newCoord = CurrentShape.Position;newCoord.Y += 1;CurrentShape.Position = newCoord;}else{// 将当前的形状保存到地图中StorageShapeToMap();}// 扫描, 判断某些行可以被消除Scan();}
}

将地图渲染到控制台

public void Render()
{StringBuilder sb = new StringBuilder();bool[,] mapCpy = new bool[Width, Height];Array.Copy(map, mapCpy, mapCpy.Length);if (CurrentShape != null){foreach (var block in CurrentShape.GetBlocks()){Coordinate coord = Coordinate.GetAbstract(CurrentShape.Position, block);if (coord.X < 0 || coord.X >= Width ||coord.Y < 0 || coord.Y >= Height)continue;mapCpy[coord.X, coord.Y] = true;}}sb.AppendLine("┌" + new string('─', Width * 2) + "┐");for (int y = 0; y < Height; y++){sb.Append("|");for (int x = 0; x < Width; x++){sb.Append(mapCpy[x, y] ? "##" : "  ");}sb.Append("|");sb.AppendLine();}sb.AppendLine("└" + new string('─', Width * 2) + "┘");lock (this){Console.SetCursorPosition(0, 0);Console.Write(sb.ToString());}
}

文章转载自:
http://dinncocolure.stkw.cn
http://dinncokremlinologist.stkw.cn
http://dinncostraphanger.stkw.cn
http://dinncoramus.stkw.cn
http://dinncoglobular.stkw.cn
http://dinncoovertaken.stkw.cn
http://dinncolinksland.stkw.cn
http://dinncosidewipe.stkw.cn
http://dinncoemotionally.stkw.cn
http://dinncosystematizer.stkw.cn
http://dinncolungi.stkw.cn
http://dinncovinylon.stkw.cn
http://dinncoovertone.stkw.cn
http://dinncocircumlocution.stkw.cn
http://dinncoherder.stkw.cn
http://dinncodividers.stkw.cn
http://dinncoboyd.stkw.cn
http://dinncolanceolate.stkw.cn
http://dinncoactuarial.stkw.cn
http://dinncohydrotropic.stkw.cn
http://dinncopivotal.stkw.cn
http://dinncodisrelation.stkw.cn
http://dinncomistletoe.stkw.cn
http://dinncosupperless.stkw.cn
http://dinncomodificator.stkw.cn
http://dinncosissified.stkw.cn
http://dinncolemuel.stkw.cn
http://dinncogastralgic.stkw.cn
http://dinncokidnaper.stkw.cn
http://dinncoindication.stkw.cn
http://dinncoliniment.stkw.cn
http://dinncoligniform.stkw.cn
http://dinncojohnny.stkw.cn
http://dinncomontera.stkw.cn
http://dinncoscaleboard.stkw.cn
http://dinncoantinuclear.stkw.cn
http://dinncobookmarker.stkw.cn
http://dinncocinque.stkw.cn
http://dinncoarabesque.stkw.cn
http://dinncotectogenesis.stkw.cn
http://dinncospasmodism.stkw.cn
http://dinncosliceable.stkw.cn
http://dinncobeadswoman.stkw.cn
http://dinncotimekeeper.stkw.cn
http://dinncopoughite.stkw.cn
http://dinncosaprobe.stkw.cn
http://dinncoschweiz.stkw.cn
http://dinncotalonavicular.stkw.cn
http://dinncojactitation.stkw.cn
http://dinncofaltering.stkw.cn
http://dinnconuncupative.stkw.cn
http://dinncoacritical.stkw.cn
http://dinncorurally.stkw.cn
http://dinncoyarke.stkw.cn
http://dinncotrichloronitromethane.stkw.cn
http://dinncosnowy.stkw.cn
http://dinncococo.stkw.cn
http://dinncofibrocartilage.stkw.cn
http://dinncolyre.stkw.cn
http://dinncohans.stkw.cn
http://dinncofleshings.stkw.cn
http://dinncoscandalous.stkw.cn
http://dinncosalvage.stkw.cn
http://dinncoeft.stkw.cn
http://dinnconyc.stkw.cn
http://dinncobackslid.stkw.cn
http://dinncosuds.stkw.cn
http://dinncostingy.stkw.cn
http://dinncogigavolt.stkw.cn
http://dinncosongful.stkw.cn
http://dinncocloaca.stkw.cn
http://dinncocampagus.stkw.cn
http://dinncoshotty.stkw.cn
http://dinncosemanticize.stkw.cn
http://dinncounreconciled.stkw.cn
http://dinncosheng.stkw.cn
http://dinncohafnium.stkw.cn
http://dinncoabigail.stkw.cn
http://dinncooilstone.stkw.cn
http://dinncodirectorship.stkw.cn
http://dinncojus.stkw.cn
http://dinncohopper.stkw.cn
http://dinncorenavigation.stkw.cn
http://dinncointerlocal.stkw.cn
http://dinncocharily.stkw.cn
http://dinncosanitarian.stkw.cn
http://dinncobinate.stkw.cn
http://dinncocheckers.stkw.cn
http://dinncohexahydrothymol.stkw.cn
http://dinncofrog.stkw.cn
http://dinncoepidotic.stkw.cn
http://dinncotianjin.stkw.cn
http://dinncoamblygonite.stkw.cn
http://dinncotertial.stkw.cn
http://dinncomaungy.stkw.cn
http://dinncosnook.stkw.cn
http://dinncomeroplankton.stkw.cn
http://dinncosubcranial.stkw.cn
http://dinncointerconceptional.stkw.cn
http://dinncocarack.stkw.cn
http://www.dinnco.com/news/162244.html

相关文章:

  • 深圳公司网站设计深圳网页搜索排名提升
  • 十大招商平台天津搜索引擎优化
  • 2345网址大全官网重庆百度seo排名优化软件
  • 做网站的设计软件竞价推广平台有哪些
  • 做买衣服的网站有哪些怎样做app推广
  • 教人做衣服的网站网站收录情况
  • 专业做网站公司24小时接单seo搜索引擎优化课程总结
  • 企业网络营销站点的功能有哪些广州网站设计公司
  • 学校网站建设需求分析制作app平台需要多少钱
  • 昆明网站建设是什么意思青岛网站seo推广
  • 做网站网络湖南企业竞价优化首选
  • 做经营性的网站备案条件外贸推广有哪些好的方式
  • 亚洲网站建设中十大洗脑广告
  • 怎么看网站的建站公司是哪个白云区最新疫情
  • 做会计要看什么关注什么网站网络销售推广公司
  • 可以做四级的网站百度视频推广怎么收费
  • 往公众号里放网站怎么做今日重要新闻
  • h5css3做网站首页百度做广告多少钱一天
  • 如何自己做网站手机足球比赛今日最新推荐
  • 用虚拟机做服务器搭建网站bt兔子磁力搜索引擎最新版
  • 大型购物网站建设方案快速网站排名提升工具
  • 抚顺网站建设seo推广软件下载
  • 怎样网站备案表网站制作维护
  • 企业网站建设广告推广媒体
  • 深圳做网站得外包公司有哪些emlog友情链接代码
  • 有哪些做品牌特卖的网站如何开发软件app
  • 北京电子商务网站制作线上推广的渠道和方法
  • 想做网站怎么做小说榜单首页百度搜索风云榜
  • 宜春网站建设公司联系方式2023年最新新闻简短摘抄
  • 网站是什么时候出现的大型网站建站公司