Skip to content

Instantly share code, notes, and snippets.

@Julien00859
Last active April 11, 2017 15:02
Show Gist options
  • Save Julien00859/5518e44f590d01aefad6f0f138dbbba1 to your computer and use it in GitHub Desktop.
Save Julien00859/5518e44f590d01aefad6f0f138dbbba1 to your computer and use it in GitHub Desktop.
Snake with Nathan (TIC)
using System;
using System.Collections.Generic;
using System.Threading;
namespace SnakeTIC
{
struct Pos
{
public int x { get; private set; }
public int y { get; private set; }
public Pos(int x, int y)
{
this.x = x;
this.y = y;
}
}
class Snake
{
public Pos head { get; set; }
private Queue<Pos> tail = new Queue<Pos>();
public int size { get { return this.tail.Count; } }
public Snake(int x, int y)
{
this.head = new Pos(x, y);
}
public Pos MoveTo(Pos newpos)
{
this.tail.Enqueue(this.head);
this.head = newpos;
return this.tail.Dequeue();
}
public Pos MoveTo(int dx, int dy)
{
return this.MoveTo(new Pos(this.head.x + dx, this.head.y + dy));
}
public void MoveToAndEat(Pos newpos)
{
this.tail.Enqueue(this.head);
this.head = newpos;
}
public void MoveToAndEat(int dx, int dy)
{
this.MoveToAndEat(new Pos(this.head.x + dx, this.head.y + dy));
}
}
class Grid
{
int width;
int height;
public List<List<Tile>> grid;
public enum Tile { AIR=' ', WALL='#', HEAD='ô', TAIL='o', FRUIT='+'};
public Grid(int width, int height, Pos snakehead)
{
this.width = width;
this.height = height;
int i, j;
this.grid = new List<List<Tile>>();
for (i = 0; i < height; i++)
{
this.grid.Add(new List<Tile>());
for (j = 0; j < width; j++)
this.grid[i].Add(Tile.AIR);
}
for (i = 0; i < this.height; i++)
{
this.updateTileAt(0, i, Tile.WALL);
this.updateTileAt(this.width - 1, i, Tile.WALL);
}
for (i = 1; i < this.width - 1; i++)
{
this.updateTileAt(i, 0, Tile.WALL);
this.updateTileAt(i, this.height - 1, Tile.WALL);
}
Random rnd = new Random();
int rndx, rndy;
do
{
rndx = rnd.Next(1, this.width - 1);
rndy = rnd.Next(1, this.height - 1);
} while (rndx == snakehead.x && rndy == snakehead.y);
this.updateTileAt(rndx, rndy, Tile.FRUIT);
this.updateTileAt(snakehead.x, snakehead.y, Tile.HEAD);
}
public void addFruit()
{
List<Pos> frees = new List<Pos>();
int x, y;
for (y = 1; y < this.height - 1; y++)
for (x = 1; x < this.width - 1; x++)
if (this.grid[y][x] == Tile.AIR)
frees.Add(new Pos(x, y));
Random rnd = new Random();
Pos fruit = frees[rnd.Next(frees.Count)];
this.updateTileAt(fruit.x, fruit.y, Tile.FRUIT);
}
public void updateTileAt(int x, int y, Tile tile)
{
this.grid[y][x] = tile;
Console.CursorTop = y;
Console.CursorLeft = x;
switch (tile)
{
case Tile.AIR:
case Tile.WALL:
Console.ResetColor();
break;
case Tile.HEAD:
Console.ForegroundColor = ConsoleColor.Green;
break;
case Tile.TAIL:
Console.ForegroundColor = ConsoleColor.Yellow;
break;
case Tile.FRUIT:
Console.ForegroundColor = ConsoleColor.Red;
break;
}
Console.Write((char) tile);
}
override public string ToString()
{
string output = "";
int x, y;
for (y = 0; y < this.height; y++)
{
for (x = 0; x < this.width; x++)
output += (char) this.grid[y][x];
if (y < this.height - 1)
output += '\n';
}
return output;
}
}
class Program
{
static void Main(String[] args)
{
int width = 100, height = 50;
if (args.Length >= 3)
{
width = int.Parse(args[1]);
height = int.Parse(args[2]);
}
Random rnd = new Random();
int rndx, rndy, dx = 0, dy = 0;
bool isgameover = false;
rndx = rnd.Next(1, width - 1);
rndy = rnd.Next(1, height - 1);
Console.SetWindowSize(width, height + 1);
Console.CursorVisible = false;
Snake snake = new Snake(rndx, rndy);
Grid grid = new Grid(width, height, snake.head);
while (!isgameover)
{
if (Console.KeyAvailable)
{
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.UpArrow:
if (dx != 0 || dy == 0 || snake.size == 0)
{
dx = 0;
dy = -1;
}
break;
case ConsoleKey.DownArrow:
if (dx != 0 || dy == 0 || snake.size == 0)
{
dx = 0;
dy = 1;
}
break;
case ConsoleKey.LeftArrow:
if (dy != 0 || dx == 0 || snake.size == 0)
{
dx = -1;
dy = 0;
}
break;
case ConsoleKey.RightArrow:
if (dy != 0 || dx == 0 || snake.size == 0)
{
dx = 1;
dy = 0;
}
break;
}
}
switch (grid.grid[snake.head.y + dy][snake.head.x + dx])
{
case Grid.Tile.AIR:
grid.updateTileAt(snake.head.x, snake.head.y, Grid.Tile.TAIL);
Pos oldTile = snake.MoveTo(dx, dy);
grid.updateTileAt(oldTile.x, oldTile.y, Grid.Tile.AIR);
grid.updateTileAt(snake.head.x, snake.head.y, Grid.Tile.HEAD);
break;
case Grid.Tile.FRUIT:
grid.updateTileAt(snake.head.x, snake.head.y, Grid.Tile.TAIL);
snake.MoveToAndEat(dx, dy);
grid.updateTileAt(snake.head.x, snake.head.y, Grid.Tile.HEAD);
grid.addFruit();
break;
case Grid.Tile.WALL:
case Grid.Tile.TAIL:
isgameover = true;
break;
}
Console.CursorLeft = 0;
Console.CursorTop = height;
Console.ResetColor();
Console.Write("Score: {0} Vitesse: {1}", snake.size, (1.0 / (750 / (snake.size + 10) + 25) * 100).ToString("0.00"));
Thread.Sleep(750 / (snake.size + 10) + 25);
}
Console.CursorTop = height / 2;
Console.CursorLeft = width / 2 - 3;
Console.Write("Perdu !");
Console.CursorTop++;
Console.CursorLeft = width / 2 - 4;
Console.Write("Score: {0}", snake.size);
Console.CursorTop = height;
Console.CursorLeft = 0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment