中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

房產(chǎn)網(wǎng)站定制秦皇島網(wǎng)站seo

房產(chǎn)網(wǎng)站定制,秦皇島網(wǎng)站seo,交換機可以做網(wǎng)站跳轉(zhuǎn)嗎,做cpc不做網(wǎng)站可以嗎一個控制臺俄羅斯方塊游戲的簡單實現(xiàn). 已在 github.com/SlimeNull/Tetris 開源. 思路 很簡單, 一個二維數(shù)組存儲當前游戲的方塊地圖, 用 bool 即可, true 表示當前塊被填充, false 表示沒有. 然后, 抽一個 “形狀” 類, 形狀表示當前玩家正在操作的一個形狀, 例如方塊, 直線…

一個控制臺俄羅斯方塊游戲的簡單實現(xiàn). 已在 github.com/SlimeNull/Tetris 開源.
在這里插入圖片描述


思路

很簡單, 一個二維數(shù)組存儲當前游戲的方塊地圖, 用 bool 即可, true 表示當前塊被填充, false 表示沒有.

然后, 抽一個 “形狀” 類, 形狀表示當前玩家正在操作的一個形狀, 例如方塊, 直線, T 形什么的. 一個形狀又有不同的樣式, 也就是玩家可以切換的樣式. 每一個樣式都是原來樣式旋轉(zhuǎn)之后的結(jié)果. 為了方便, 可以直接使用硬編碼的方式存儲所有樣式中方塊的相對坐標.

一個形狀有一個自己的坐標, 并且它包含很多方塊. 在繪制的時候, 獲取它每一個方塊的坐標, 轉(zhuǎn)換為地圖內(nèi)的絕對坐標, 然后使用 StringBuilder 拼接字符串, 即可.


資料

俄羅斯方塊中總共有這七種方塊

在這里插入圖片描述


類型定義

一個簡單的二維坐標

/// <summary>
/// 表示一個坐標
/// </summary>
/// <param name="X"></param>
/// <param name="Y"></param>
record struct Coordinate(int X, int Y)
{/// <summary>/// 根據(jù)基坐標和相對坐標, 獲取一個絕對坐標/// </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);}
}

形狀的一個樣式, 單純使用坐標數(shù)組存儲即可.

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>/// 從坐標構(gòu)建一個新形狀/// </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 形狀的實現(xiàn)

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),}),};
}

主邏輯

上面的定義已經(jīng)寫好了, 接下來就是寫游戲主邏輯.

主邏輯包含每一回合自動向下移動形狀, 如果無法繼續(xù)向下移動, 則把當前的形狀存儲到地圖中. 并進行一次掃描, 將所有的整行全部消除.

抽一個 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;// 如果移動后方塊會與地圖現(xiàn)有方塊重合, 則不能移動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;// 如果與現(xiàn)有方塊重合, 不能切換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()){// 轉(zhuǎn)為絕對坐標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;}// 當前形狀設(shè)為 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++){// 設(shè)置當前行是整行bool ok = true;// 循環(huán)當前行的所有方塊, 如果方塊為 false, ok 就會被設(shè)為 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];// 最頂行全設(shè)為空for (int x = 0; x < Width; x++)map[x, 0] = false;}}
}

封裝一些用戶操作使用的方法

/// <summary>
/// 根據(jù)指定偏移, 進行移動
/// </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://www.risenshineclean.com/news/52836.html

相關(guān)文章:

  • wordpress首頁白板北京seo代理計費
  • 建設(shè)一個網(wǎng)站流程圖寧波seo關(guān)鍵詞如何優(yōu)化
  • 個人網(wǎng)站開發(fā)視頻系統(tǒng)優(yōu)化大師
  • 上海做網(wǎng)站公司推薦企點客服
  • 做批發(fā)的網(wǎng)站seo投放
  • 個人做網(wǎng)站需要備案嗎加盟培訓(xùn)機構(gòu)
  • 如何做優(yōu)惠券運營網(wǎng)站電商運營工資大概多少
  • 臨泉做網(wǎng)站百度關(guān)鍵詞挖掘工具
  • 如何做網(wǎng)站的的關(guān)鍵詞在線bt磁力搜索
  • 網(wǎng)站開發(fā)組織架構(gòu)圖網(wǎng)頁設(shè)計模板圖片
  • 深圳做網(wǎng)站d海淀區(qū)seo引擎優(yōu)化
  • 全國建筑業(yè)四庫一平臺seo專業(yè)學(xué)校
  • 網(wǎng)站功能模塊設(shè)計中國新聞
  • 網(wǎng)站制作 網(wǎng)站建設(shè)百度推廣怎么優(yōu)化
  • 可信網(wǎng)站標志上海網(wǎng)站快速排名提升
  • 商標注冊號在哪個位置seo優(yōu)化行業(yè)
  • 濟南微網(wǎng)站建設(shè)網(wǎng)絡(luò)營銷的三種方式
  • dede免費模板教育網(wǎng)站百度客服24小時人工電話
  • wordpress仿簡書抖音seo是什么意思
  • 分辨率大于1920的網(wǎng)站怎么做建立網(wǎng)站的主要步驟
  • 做網(wǎng)站都需要考慮哪些seo百度seo排名優(yōu)化軟件
  • 網(wǎng)站 昆明友情鏈接網(wǎng)站源碼
  • 互聯(lián)網(wǎng)系統(tǒng)安卓手機優(yōu)化大師官方下載
  • wordpress themas網(wǎng)頁關(guān)鍵詞優(yōu)化軟件
  • 成都 企業(yè) 網(wǎng)站制作去哪里找需要推廣的app
  • 賣書網(wǎng)站開發(fā)的背景湖南長沙今日疫情
  • 智慧管網(wǎng)建設(shè)方案網(wǎng)站seo分析工具
  • wordpress廣告欄沈陽seo排名外包
  • cvm可以做網(wǎng)站服務(wù)器嗎seo優(yōu)化師培訓(xùn)
  • 有哪些網(wǎng)站是可以做宣傳的朔州seo