自动寻路贪吃蛇C#
2021/6/7 22:33:17
本文主要是介绍自动寻路贪吃蛇C#,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
using System; using System.Collections; using System.Threading; using System.Collections.Generic; //特殊情况 头走尾,尾不删,不置false //遇食物,尾不动 namespace snakeai { class Program { static void Main(string[] args) { Console.CursorVisible = false; Snake snake = new Snake(24, 24); snake.eatFood(); } } class Snake { public struct Point { public int x; public int y; public Point(int xx, int yy) { x = xx; y = yy; } public static bool operator ==(Point a, Point b) { return (a.x == b.x && a.y == b.y); } public static bool operator !=(Point a, Point b) { return !(a == b); } }; public Point food; const int Down = 1; const int Up = 2; const int Right = 3; const int Left = 4; public LinkedList<Point> body;//存蛇的身体 public int xlen;//x方向长度,偶数 public int ylen;//y方向长度,偶数 int[,] dir; bool[,] hasBody;// Random rd; public void debug() { Console.SetCursorPosition(0, 24); var t = front(); for (int i = 0; i < xlen; i++) { for (int j = 0; j < ylen; j++) { if (t == new Point(i, j)) { Console.Write(" "); continue; } switch (dir[i, j]) { case Left: Console.Write("L"); break; case Right: Console.Write("R"); break; case Down: Console.Write("D"); break; case Up: Console.Write("U"); break; } } Console.WriteLine(""); } } public Snake(int x, int y) { xlen = x; ylen = y; dir = new int[x, y]; body = new LinkedList<Point>(); for (int i = 0; i < x; i += 2) { for (int j = 0; j < y; j += 2) { dir[i, j] = Right; dir[i, j + 1] = Down; dir[i + 1, j + 1] = Left; dir[i + 1, j] = Up; } } hasBody = new bool[x, y]; for (int i = 0; i < x; i++) for (int j = 0; j < y; j++) hasBody[i, j] = false; rd = new Random(); Point p = generateNode(); push(p); } public void move() { var newHead = generateNewHead(); push(newHead); Thread.Sleep(10); if (newHead == food) { food = generateNode(); GenerateBody(food); } else pop(); } public void eatFood() { food = generateNode(); GenerateBody(food); int[] tmpdir = new int[2]; while (body.Count < xlen * ylen) { var head = body.First.Value; var foodlt = getLT(food); var headlt = getLT(head); if(foodlt.x>headlt.x) for (int i = headlt.x; i < foodlt.x; i+=2) ConnectDown(new Point(i, headlt.y)); if (foodlt.x < headlt.x) for (int i = headlt.x; i > foodlt.x; i -= 2) ConnectUp(new Point(i, headlt.y)); if (foodlt.y > headlt.y) for (int i = headlt.y; i < foodlt.y; i += 2) ConnectRight(new Point(foodlt.x, i)); if (foodlt.y < headlt.y) for (int i = headlt.y; i > foodlt.y; i -= 2) ConnectLeft(new Point(foodlt.x, i)); move(); move(); for(int i = 0; i < xlen; i+=2) { for(int j = 0; j < ylen; j+=2) { var p = new Point(i, j); if (inCircle(p) && !HasBody(p)) { var up = p;up.x -= 2; if (LegalPoint(up) && inCircle(up)) DropDown(up); var left = p;left.y -= 2; if (LegalPoint(left) && inCircle(left)) DropRight(left); var down = p; down.x += 2; if (LegalPoint(down) && inCircle(down)) DropUp(down); var right = p; right.y += 2; if (LegalPoint(right) && inCircle(right)) DropLeft(right); } } } } } public bool LegalPoint(Point p) { return p.x >= 0 && p.x < xlen && p.y >= 0 && p.y < ylen; } public Point generateNewHead() { var p = body.First.Value; switch (dir[p.x, p.y]) { case Up: p.x -= 1; break; case Down: p.x += 1; break; case Right: p.y += 1; break; case Left: p.y -= 1; break; default: break; } return p; } public bool inCircle(Point p) { p = getLT(p); return !(dir[p.x, p.y] == Right && dir[p.x, p.y + 1] == Down && dir[p.x + 1, p.y + 1] == Left && dir[p.x + 1, p.y] == Up); } public Point generateNode() { Point p; do { p.x = rd.Next(0, xlen - 1); p.y = rd.Next(0, ylen - 1); } while (hasBody[p.x, p.y]); return p; } public Point getLT(Point p) { p.x -= p.x % 2; p.y -= p.y % 2; return p; } public void ConnectLeft(Point p) { p = getLT(p); var t = p; t.y -= 2; if (inCircle(t)) return; dir[p.x, p.y - 1] = Right; dir[p.x + 1, p.y] = Left; } public void ConnectRight(Point p) { p = getLT(p); var t = p; t.y += 2; if (inCircle(t)) return; dir[p.x, p.y + 1] = Right; dir[p.x + 1, p.y + 2] = Left; } public void ConnectUp(Point p) { p = getLT(p); var t = p; t.x -= 2; if (inCircle(t)) return; dir[p.x, p.y] = Up; dir[p.x - 1, p.y + 1] = Down; } public void ConnectDown(Point p) { p = getLT(p); var t = p; t.x += 2; if (inCircle(t)) return; dir[p.x + 2, p.y] = Up; dir[p.x + 1, p.y + 1] = Down; } public void DropLeft(Point p) { p = getLT(p); dir[p.x, p.y - 1] = Down; dir[p.x + 1, p.y] = Up; } public void DropRight(Point p) { p = getLT(p); dir[p.x, p.y + 1] = Down; dir[p.x + 1, p.y + 2] = Up; } public void DropUp(Point p) { p = getLT(p); dir[p.x, p.y] = Right; dir[p.x - 1, p.y + 1] = Left; } public void DropDown(Point p) { p = getLT(p); dir[p.x + 2, p.y] = Right; dir[p.x + 1, p.y + 1] = Left; } public static void GenerateBody(Point p) { Console.SetCursorPosition(p.x, p.y); Console.Write("*"); } public static void EraseTail(Point p) { Console.SetCursorPosition(p.x, p.y); Console.Write(" "); } public void push(Point p) { body.AddFirst(p); hasBody[p.x, p.y] = true; GenerateBody(p); } public void pop() { var p = body.Last.Value; body.RemoveLast(); if (p != body.First.Value) { hasBody[p.x, p.y] = false; EraseTail(p); } } public void Drop(Point d) { Point n = body.Last.Value; if (n.x < d.x) { DropDown(n); return; } if (n.x > d.x) { DropUp(n); return; } if (n.y < d.y) { DropRight(n); return; } if (n.y > d.y) { DropLeft(n); return; } } public Point front() { return body.First.Value; } public bool HasBody(Point p) { p = getLT(p); for (int i = 0; i <= 1; i++) for (int j = 0; j <= 1; j++) if (hasBody[p.x + i, p.y + j]) return true; return false; } } }
这篇关于自动寻路贪吃蛇C#的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#
- 2024-01-24Advanced .Net Debugging 1:你必须知道的调试工具