eva_bead_1/model/SnakeLevel.cs
2024-10-02 14:59:51 +02:00

110 lines
3.1 KiB
C#

using System.Collections.ObjectModel;
namespace Snake.Model;
public class SnakeLevel{
public int Size {get; }
public enum LevelBlock{
Empty,
Obstacle,
Egg,
Snake,
SnakeHead,
OutOfBounds
}
public enum SnakeDirection{
Up,
Down,
Left,
Right
}
public enum GameState{
Running,
Dead
}
private readonly List<Point> _obstacles;
public ReadOnlyCollection<Point> Obstacles => _obstacles.AsReadOnly();
public Point SnakeHead {get; private set;}
private readonly List<Point> _snake;
// Head is not in snake
// Last is closest to the head
public ReadOnlyCollection<Point> Snake => _snake.AsReadOnly();
public int SnakeLength => Snake.Count + 1;
private readonly List<Point> _eggs;
public ReadOnlyCollection<Point> Eggs => _eggs.AsReadOnly();
public SnakeDirection SnakeHeadDirection {get; private set;}
public GameState State {get; private set;}
public SnakeLevel(int size, IEnumerable<Point> obstacles, int snake_start_length){
this.Size = size;
_obstacles = new List<Point>(obstacles);
_eggs = [];
_snake = [];
SnakeHead = (size / 2, snake_start_length-1);
for(int i=0; i<snake_start_length-1; i++){
_snake.Add((size / 2, i));
}
SnakeHeadDirection = SnakeDirection.Down;
}
public LevelBlock this[Point p]{
get{
if(_obstacles.Contains(p)){
return LevelBlock.Obstacle;
}else if(p == SnakeHead){
return LevelBlock.SnakeHead;
}else if(_snake.Contains(p)){
return LevelBlock.Snake;
}else if(_eggs.Contains(p)){
return LevelBlock.Egg;
}else if(p.X < 0 || p.Y < 0 || p.X>=Size || p.Y >= Size){
return LevelBlock.OutOfBounds;
}
return LevelBlock.Empty;
}
}
public void Tick(){
Point new_snake_head = (0,0);
switch(SnakeHeadDirection){
case SnakeDirection.Up:
new_snake_head = (SnakeHead.X, SnakeHead.Y - 1);
break;
case SnakeDirection.Down:
new_snake_head = (SnakeHead.X, SnakeHead.Y + 1);
break;
case SnakeDirection.Left:
new_snake_head = (SnakeHead.X - 1, SnakeHead.Y);
break;
case SnakeDirection.Right:
new_snake_head = (SnakeHead.X + 1, SnakeHead.Y);
break;
}
if(this[new_snake_head] is LevelBlock.Obstacle or LevelBlock.Snake or LevelBlock.OutOfBounds){
State = GameState.Dead;
return;
}
var first = Snake[0];
for(int i=_snake.Count-1; i>0; i--){
_snake[i-1] = _snake[i];
}
_snake[^1] = SnakeHead;
if(this[new_snake_head] is LevelBlock.Egg){
_snake.Insert(0, first);
_eggs.Remove(new_snake_head);
}
SnakeHead = new_snake_head;
}
}