Last active
April 11, 2017 15:02
-
-
Save Julien00859/5518e44f590d01aefad6f0f138dbbba1 to your computer and use it in GitHub Desktop.
Snake with Nathan (TIC)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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