Алгоритм движения змейки и роста в консоли - C#
Формулировка задачи:
Пишу змейку, сделал движение 1-го символа. Много пытаюсь сделать движение с несколькими символами как в змейке, т.е по одному элементу. Это лучше делать через List или обычный массив? Советы мне не помешали бы)
Решение задачи: «Алгоритм движения змейки и роста в консоли»
textual
Листинг программы
using System;
using System.Timers;
using System.Drawing;
using System.Threading;
namespace Змейка
{
class Program
{
static Point[] snake = new Point[1];
static int dir, newdir;
static System.Timers.Timer Tm = new System.Timers.Timer();
static Point[] apple = new Point[1];
static void Main(string[] args)
{
int x = (Console.WindowWidth - snake.Length * 2) / 4 * 2;
int y = Console.WindowHeight / 2;
for (int i = 0; i < snake.Length; i++)
snake[i] = new Point(x + i * 2, y);
newdir = dir = 3;
Tm.Elapsed += new ElapsedEventHandler(Tm_Tick);
Tm.Interval = 300;
Tm.Enabled = true;
Console.CursorVisible = false;
Console.ForegroundColor = ConsoleColor.Black;
NewApple(0);
ConsoleKey ck;
do
{
if (Console.KeyAvailable) ck = Console.ReadKey(true).Key;
else ck = ConsoleKey.Decimal;
if (dir % 2 == 0)
{
if (ck == ConsoleKey.LeftArrow) newdir = 3;
if (ck == ConsoleKey.RightArrow) newdir = 1;
}
else
{
if (ck == ConsoleKey.UpArrow) newdir = 0;
if (ck == ConsoleKey.DownArrow) newdir = 2;
}
Thread.Sleep(50);
} while (ck != ConsoleKey.Escape);
Console.ForegroundColor = ConsoleColor.Gray;
Console.BackgroundColor = ConsoleColor.Black;
}
//
static void SetCursor(Point p)
{
Console.CursorLeft = p.X;
Console.CursorTop = p.Y;
}
//
static void NewApple(int i)
{
Random r=new Random();
do
apple[i] = new Point(r.Next(Console.WindowWidth) / 2 * 2,
r.Next(Console.WindowHeight));
while (Body(apple[i]));
Console.BackgroundColor = ConsoleColor.Red;
SetCursor(apple[i]);
Console.Write(" ");
//Console.Title = "" + apple[i].X + " " + apple[i].Y;
}
//
static bool Body(Point p)
{
for (int i = 0; i < snake.Length; i++)
if (p == snake[i]) return true;
return false;
}
//
static void Tm_Tick(object sender, ElapsedEventArgs e)
{
int k;
Point p = new Point();
for (k = 0; k < 2; k++)
{
int dx, dy;
switch (newdir)
{
case 0: dx = 0; dy = -1; break;
case 1: dx = 2; dy = 0; break;
case 2: dx = 0; dy = 1; break;
default: dx = -2; dy = 0; break;
}
p.X = snake[0].X + dx;
p.Y = snake[0].Y + dy;
if (p.X >= 0 && p.X < Console.WindowWidth &&
p.Y >= 0 && p.Y < Console.WindowHeight && !Body(p)) break;
else newdir = dir;
}
int needapple = -1;
if (k < 2)
{
for (int i = 0; i < apple.Length && needapple < 0; i++)
if (p == apple[i]) needapple = i;
if (needapple < 0)
{
Console.BackgroundColor = ConsoleColor.Black;
SetCursor(snake[snake.Length - 1]);
Console.Write(" ");
}
else Array.Resize(ref snake, snake.Length + 1);
for (int i = snake.Length - 1; i > 0; i--) snake[i] = snake[i - 1];
snake[0] = p;
if (k == 0) dir = newdir;
}
for (int i = snake.Length - 1; i >= 0; i--)
{
Console.BackgroundColor = i == 0 ? ConsoleColor.Yellow : ConsoleColor.Green;
SetCursor(snake[i]);
if (i == 0)
if(dir==1)Console.Write(" :");
else
if (dir == 3) Console.Write(": ");
else Console.Write("..");
else Console.Write(" ");
}
if (needapple >= 0) NewApple(needapple);
}
}
}