ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

自动寻路贪吃蛇C#

2021-06-07 21:06:19  阅读:191  来源: 互联网

标签:return Point C# void int 贪吃蛇 寻路 public dir



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;

        }
    }
}

 

标签:return,Point,C#,void,int,贪吃蛇,寻路,public,dir
来源: https://blog.csdn.net/weixin_39057744/article/details/117674391

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有