Snake控制台算法c#

Snake控制台算法c#,c#,algorithm,console-application,C#,Algorithm,Console Application,谁能给我解释一下逻辑部分吗?我知道它应该可以工作,但我不能一步一步地跟踪代码,这没有意义。temp、pre和尾部之间的交换非常混乱 它是如何与帧率一起运行的?TailX[0]和TailY[0]是否始终领先?为什么?如何将新的尾部零件分配到正确的位置? 帮帮我 使用系统; 使用系统线程; 命名空间项目 { 蛇类 { 公共随机兰德=新随机(); public ConsoleKeyInfo keypress=新建ConsoleKeyInfo(); int分数,headX,headY,FroothX,F

谁能给我解释一下逻辑部分吗?我知道它应该可以工作,但我不能一步一步地跟踪代码,这没有意义。temp、pre和尾部之间的交换非常混乱

它是如何与帧率一起运行的?TailX[0]和TailY[0]是否始终领先?为什么?如何将新的尾部零件分配到正确的位置? 帮帮我

使用系统;
使用系统线程;
命名空间项目
{
蛇类
{
公共随机兰德=新随机();
public ConsoleKeyInfo keypress=新建ConsoleKeyInfo();
int分数,headX,headY,FroothX,Froothy,nTail;
int[]TailX=新int[100];
int[]TailY=新int[100];
const int height=20;
常数int宽度=60;
bool gameOver、复位、打印、水平、垂直;
字符串dir,pre_dir;
void ShowBanner()
{
控制台。设置窗口大小(宽度、高度+6);
Console.ForegroundColor=ConsoleColor.Green;
Console.CursorVisible=false;
3月月月日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日);
3月月月日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日);
3月月月日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日);
3月月月日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日);
3月月月日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日日);
Console.WriteLine(“欢迎”;
keypress=Console.ReadKey(真);
if(keypress.Key==ConsoleKey.Escape)
{
环境。退出(0);
}
}
无效设置()
{
dir=“右”;
pre_dir=“”;
得分=0;
nTail=0;
gameOver=false;
重置=错误;
isprinted=false;
headX=宽度/2;
headY=高度/2;
FROUTX=rand.Next(1,宽度-1);
果味=rand.Next(1,高度-1);
}
void CheckInput()
{
while(Console.KeyAvailable)
{
keypress=Console.ReadKey(真);
if(keypress.Key==ConsoleKey.Escape)
环境。退出(0);
if(keypress.Key==ConsoleKey.S)
{
pre_dir=dir;
dir=“停止”;
}
else if(keypress.Key==ConsoleKey.LeftArrow)
{
pre_dir=dir;
dir=“左”;
}
else if(keypress.Key==ConsoleKey.RightArrow)
{
pre_dir=dir;
dir=“右”;
}
else if(keypress.Key==ConsoleKey.UpArrow)
{
pre_dir=dir;
dir=“UP”;
}
else if(keypress.Key==ConsoleKey.DownArrow)
{
pre_dir=dir;
dir=“向下”;
}
}
}
void逻辑()
{
int-preX=TailX[0];
int preY=TailY[0];
int tempX,tempY;
如果(dir!=“停止”)
{
TailX[0]=headX;
泰利[0]=令人兴奋;
对于(int i=1;iusing System;
using System.Threading;

namespace Projects
{

class Snake
{
    public Random rand = new Random();
    public ConsoleKeyInfo keypress = new ConsoleKeyInfo();

    int score, headX, headY, fruitX, fruitY, nTail;

    int[] TailX = new int[100];
    int[] TailY = new int[100];

    const int height = 20;
    const int width = 60;

    bool gameOver, reset, isprinted, horizontal, vertical;

    string dir, pre_dir;

    void ShowBanner()
    {
        Console.SetWindowSize(width, height + 6);
        Console.ForegroundColor = ConsoleColor.Green;
        Console.CursorVisible = false;

        Console.WriteLine("!!####################################!!");
        Console.WriteLine("!!####################################!!");
        Console.WriteLine("!!####################################!!");
        Console.WriteLine("!!####################################!!");
        Console.WriteLine("!!####################################!!");
        Console.WriteLine("!!##########     Welcome    ##########!!");

        keypress = Console.ReadKey(true);
        if (keypress.Key == ConsoleKey.Escape)
        {
            Environment.Exit(0);
        }
    }

    void Setup()
    {
        dir = "Right";
        pre_dir = "";
        score = 0;
        nTail = 0;

        gameOver = false;
        reset = false;
        isprinted = false;

        headX = width / 2;
        headY = height / 2;
        fruitX = rand.Next(1, width - 1);
        fruitY = rand.Next(1, height - 1);
    }

    void CheckInput()
    {

        while (Console.KeyAvailable)
        {
            keypress = Console.ReadKey(true);
            if (keypress.Key == ConsoleKey.Escape)
                Environment.Exit(0);

            if (keypress.Key == ConsoleKey.S)
            {
                pre_dir = dir;
                dir = "STOP";
            }

            else if (keypress.Key ==ConsoleKey.LeftArrow)
            {
                pre_dir = dir;
                dir = "LEFT";
            }

            else if (keypress.Key == ConsoleKey.RightArrow)
            {
                pre_dir = dir;
                dir = "RIGHT";
            }

            else if (keypress.Key ==ConsoleKey.UpArrow)
            {
                pre_dir = dir;
                dir = "UP";
            }


            else if (keypress.Key == ConsoleKey.DownArrow)
            {
                pre_dir = dir;
                dir = "DOWN";
            }
        }
    }

    void Logic()
    {
        int preX = TailX[0];
        int preY = TailY[0];

        int tempX, tempY;

        if (dir != "STOP")
        {
            TailX[0] = headX;
            TailY[0] = headY;

            for (int i = 1; i < nTail; i++)
            {
                tempX = TailX[i];
                tempY = TailY[i];
                TailX[i] = preX;
                TailY[i] = preY;
                preX = tempX;
                preY = tempY;
            }
        }

        switch (dir)
        {
            case "RIGHT":
                headX++;
                break;

            case "LEFT":
                headX--;
                break;

            case "UP":
                headY--;
                break;

            case "DOWN":
                headY++;
                break;

            case "STOP":

                while (true)
                {
                    Console.Clear();
                    Console.CursorLeft = width / 2 - 6;
                    Console.WriteLine("GAME PAUSED");
                    Console.WriteLine();
                    Console.WriteLine();
                    Console.WriteLine("   -S to resume   ");
                    Console.WriteLine("   -R to reset   ");
                    Console.Write("   -ESC to quit   ");

                    keypress = Console.ReadKey(true);

                    if (keypress.Key == ConsoleKey.Escape)
                        Environment.Exit(0);
                    if (keypress.Key == ConsoleKey.R)
                    {
                        reset = true;
                        break;
                    }

                    if (keypress.Key == ConsoleKey.S)
                        break;
                }

                dir = pre_dir;
                break;
        }

        if (headX <= 0 || headX >= width - 1 || headY <= 0 || headY >= height - 1)
        {
            gameOver = true;
        }
        else
        {
            gameOver = false;
        }

        if (headX == fruitX && headY == fruitY)
        {
            score += 10;
            nTail++;

            fruitX = rand.Next(1, width - 1);
            fruitY = rand.Next(1, height - 1);
        }

        if (((dir == "LEFT" && pre_dir != "UP") && (dir == "LEFT" && pre_dir != "DOWN")) ||
          ((dir == "RIGHT" && pre_dir != "UP") && (dir == "RIGHT" && pre_dir != "DOWN")))
        {
            horizontal = true;
        }

        else
        {
            horizontal = false;
        }

        if (((dir == "UP" && pre_dir != "LEFT") && (dir == "UP" && pre_dir != "RIGHT")) ||
          ((dir == "DOWN" && pre_dir != "LEFT") && (dir == "RIGHT" && pre_dir != "RIGHT")))
        {
            vertical = true;
        }
        else
        {
            vertical = false;
        }


        for (int i = 1; i < nTail; i++)
        {
            if (TailX[i] == headX && TailY[i] == headY)
            {
                if (horizontal || vertical)
                {
                    gameOver = false;
                }

                else
                {
                    gameOver = true;
                }
            }

            if (TailX[i] == fruitX && TailY[i] == fruitY)
            {
                fruitX = rand.Next(1, width - 1);
                fruitY = rand.Next(1, height - 1);
            }
        }
    }


    void Render()

    {
        Console.SetCursorPosition(0, 0);

        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                if (i == 0 || i == height - 1)
                {
                    Console.Write("#");
                }

                else if (j == 0 || j == width - 1)
                {
                    Console.Write("#");
                }
                else if (j == fruitX && i == fruitY)
                {
                    Console.Write("F");
                }

                else if (j == headX && i == headY)
                {
                    Console.Write("0");
                }

                else
                {
                    isprinted = false;

                    for (int k = 0; k < nTail; k++)
                    {
                        if (TailX[k] == j && TailY[k] == i)
                        {
                            Console.Write("o");
                            isprinted = true;
                        }
                    }

                    if (!isprinted)
                        Console.Write(" ");
                }
            }
            Console.WriteLine();
        }

        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine(" YOUR SCORE : " + score);
    }


    void Lose()
    {
        Console.CursorTop = height + 3;
        Console.CursorLeft = width / 2 - 4;
        Console.WriteLine("YOU DIED");
        Console.WriteLine(" R to reset");
        Console.Write(" Esc to quit");

        while (true)
        {
            keypress = Console.ReadKey(true);

            if (keypress.Key == ConsoleKey.Escape)
            {
                Environment.Exit(0);
            }

            if (keypress.Key == ConsoleKey.R)
            {
                reset = true;
                break;
            }
        }
    }

    void Update()
    {
        while (!gameOver)
        {
            CheckInput();
            Logic();
            Render();
            if (reset)
                break;
            Thread.Sleep(30);
        }
        if (gameOver)
            Lose();
    }


    static void Main(string[] args)
    {
        Snake snake = new Snake();
        snake.ShowBanner();
        while (true)
        {
            snake.Setup();
            snake.Update();

            Console.Clear();
        }
    }
}
// Set the position of the first segment of the tail to the position of where the head was this frame
TailX[0] = headX;
TailY[0] = headY;
// Set a new position for the head of the snake based on direction
switch (dir)
{
    case "RIGHT":
        headX++;
    break;

    // etc...
headX = 5;
TailX[0] = 4;
headX = 6;
TailX[0] = 5;
for (int i = 1; i < nTail; i++)
{
    // Capture the X position of the current segment of tail as we will need it to update the next segment of tail 
    tempX = TailX[i];
    // Set the X position of the tail to the previous tail segment (remember, we captured this at the start of the logic function and it was essentially the X position of the head)
    TailX[i] = preX;
    // Capture the old position of the tail segment pre-update so we can assign it to the next tail segment
    preX = tempX;
}

// Later on we update the head to its new position
 
headX = 7;
TailX[0] = 6;
TailX[1] = 5;