Змейка на консоли - вопрос реализации с нуля - C#
Формулировка задачи:
Недавно поняла, как считывать линию с консоли, уже задали написать змейку.
можете помочь в создании самой змейки. то есть это должен быть какой то динамический массив, который увеличивается при съедении "еды" и двигается при нажатии стрелочек.
как именно создать этот массив и заставить поворачивать при нажатии соответствующей клавиши.
собственный код просто стыдно выкладывать
Решение задачи: «Змейка на консоли - вопрос реализации с нуля»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace Snake
{
public partial class Snake
{
private readonly int _scoreForFood; //Очки за подобранную еду
private static Point _food; //Координаты клетки с едой
private readonly HashSet<Point> _barriers;
private readonly Size _size; //Размеры карты
private readonly Queue<Segment> _snake; //Сама змейка
private Segment _head; //Голова
public int Score { get; private set; }
public Snake(int segmentCount,int scoreForFood, Size mapSize, HashSet<Point> barriers)
//Конструктор, определяет размеры карты и начальное количество сегментов змеи
{
_scoreForFood = scoreForFood;
_snake = new Queue<Segment>();
_size = mapSize;
_barriers = barriers;
var p = new Point((_size.Width - segmentCount) >> 1, _size.Height/2); //Ставим змейку на середину карты
for (int i = 0; i < segmentCount; i++, p.X++)
_snake.Enqueue(new Segment(p));
p.X--;
_head = p;
PlaceFood();
}
public List<Point> GetCoords()
{
return _snake.Select(segment => (Point) segment).ToList(); //Возвращаем список координат змеи
}
public List<Terrain> Move(Point relativityDirection, out bool result)
//Передвигаем змею. Если она себя кусает, возвращаем true
{
result = true;
var coordsToRepaint = new List<Terrain>
{
new Terrain(TerrainInfo.Tail, _snake.Peek()),
new Terrain(TerrainInfo.LastHead, _head)
};
Segment newHeadPos = _head + relativityDirection;
if (CheckForCollision(newHeadPos)) return new List<Terrain>();
MoveHead(newHeadPos);
_snake.Enqueue(_head);
coordsToRepaint.Add(new Terrain(TerrainInfo.NewHead, _head));
if (_head == _food) //Если змея попала на клетку с едой, мы рандомную клетку заполняем едой
{
Score += _scoreForFood;
PlaceFood();
}
else _snake.Dequeue(); //Иначе, чтобы змея не увеличилась, убираем последний сегмент
result = false; //Мы себя не укусили, значит false
coordsToRepaint.Add(new Terrain(TerrainInfo.Food, _food));
return coordsToRepaint;
}
private void MoveHead(Segment s) //Передвигаем голову с учетом телепортов через край
{
if (s.X < 0)
_head.X = _size.Width - 1;
else if (s.X > _size.Width - 1)
_head.X = 0;
else if (s.Y < 0)
_head.Y = _size.Height - 1;
else if (s.Y > _size.Height - 1)
_head.Y = 0;
else
_head = s;
}
private bool CheckForCollision(Segment s)
{
return _snake.Contains(s) && (Point) s != _snake.Peek() || CheckBorders(s);
}
private bool CheckBorders(Segment s)
{
return _barriers.Contains(s);
}
private void PlaceFood()
{
var r = new Random();
var p = new Point();
do
{
p.X = r.Next(_size.Width);
p.Y = r.Next(_size.Height);
} while (_snake.Contains(p) || _barriers.Contains(p));
_food = p;
}
}
}