自动寻路贪吃蛇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#的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程