Add quick Benchmark

This commit is contained in:
JFronny 2020-03-31 18:45:52 +02:00
parent 2cb56cf434
commit 18c85fd95a
12 changed files with 544 additions and 267 deletions

103
Snakity/Benchmark.cs Normal file
View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Snakity.Graphics;
namespace Snakity
{
public static class Benchmark
{
public static void Perform()
{
Console.Clear();
DiffDraw.Clear(21, 1);
Label status = new Label(new Point(0, 0), "Snakity Bench running");
Renderer.Labels.Add(status);
Renderer.Render(false);
Tuple<bool, bool, bool, TimeSpan>[] result = new[] {false, true}.SelectMany(b1 => new[] {false, true}, (b1, b2) => new {b1, b2})
.SelectMany(t => new[] {false, true}, (t, b3) => new {t, b3})
.Select(t => new Tuple<bool, bool, bool, TimeSpan>(t.t.b1, t.t.b2, t.b3, Perform(t.t.b1, t.t.b2, t.b3)))
.OrderBy(s => s.Item4).ToArray();
Console.Clear();
Console.WriteLine("╔═Smooth1═╤═Smooth2═╤═Color═╤═Time═╗");
bool color2 = false;
foreach ((bool smooth1, bool smooth2, bool color, TimeSpan time) in result)
{
color2 = !color2;
Console.BackgroundColor = color2 ? ConsoleColor.Black : ConsoleColor.White;
Console.ForegroundColor = color2 ? ConsoleColor.White : ConsoleColor.Black;
string tmp = time.TotalSeconds.ToString(CultureInfo.InvariantCulture);
if (tmp.Length > 5) tmp = tmp.Remove(5);
else if (tmp.Length < 5) tmp += new string(' ', 6 - tmp.Length);
Console.WriteLine(
$"║ {(smooth1 ? "X" : " ")} │ {(smooth2 ? "X" : " ")} │ {(color ? "X" : " ")} │{tmp}s║");
}
Console.ResetColor();
Console.WriteLine("╚═Smooth1═╧═Smooth2═╧═Color═╧═Time═╝");
Console.WriteLine();
Console.WriteLine("Impact:");
Console.WriteLine($"- Smooth1: {GetImpact(result, tuple => tuple.Item1)}s");
Console.WriteLine($"- Smooth2: {GetImpact(result, tuple => tuple.Item2)}s");
Console.WriteLine($"- Color: {GetImpact(result, tuple => tuple.Item3)}s");
Console.WriteLine();
Console.WriteLine("Press any key to return");
Console.ReadKey();
}
private static double GetImpact(Tuple<bool, bool, bool, TimeSpan>[] result,
Func<Tuple<bool, bool, bool, TimeSpan>, bool> selector) =>
GetAvgTime(result, selector) - GetAvgTime(result, tuple => !selector.Invoke(tuple));
private static double GetAvgTime(Tuple<bool, bool, bool, TimeSpan>[] result,
Func<Tuple<bool, bool, bool, TimeSpan>, bool> selector) =>
Average(result.Where(selector).Select(s => s.Item4).ToArray());
private static double Average(params TimeSpan[] spans) => spans.Aggregate(TimeSpan.Zero, (current, t) => current + t / spans.Length).TotalSeconds;
private static TimeSpan Perform(bool smooth1, bool smooth2, bool color)
{
DiffDraw.Clear(0, 0);
Renderer.Player.Clear();
Stopwatch t = Stopwatch.StartNew();
(char[,] level, _) =
CharArrayLoader.LoadLevel(@"
#####################
# ###
# ### #
# # ## #
# # #
# ## #
#####################", smooth1);
DiffDraw.Clear(level);
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 2), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 2), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 3), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 3), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 4), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 5), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 6), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 6), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 5), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 4), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(3, 4), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(3, 3), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(3, 2), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(4, 2), new Point(0, 0)));
Renderer.Enemies.Add(new Point(5, 4));
Renderer.Enemies.Add(new Point(5, 5));
Renderer.Enemies.Add(new Point(5, 6));
Renderer.Enemies.Add(new Point(6, 6));
Renderer.Enemies.Add(new Point(7, 6));
Renderer.Enemies.Add(new Point(7, 5));
Renderer.Enemies.Add(new Point(7, 4));
Renderer.Enemies.Add(new Point(6, 3));
Renderer.Enemies.Add(new Point(5, 2));
Renderer.Render(smooth2);
DiffDraw.Draw(color);
t.Stop();
return t.Elapsed;
}
}
}

View File

@ -6,12 +6,13 @@ namespace Snakity
{
public static class CharArrayLoader
{
public static Tuple<char[,], bool[,]> LoadLevel(string level)
public static Tuple<char[,], bool[,]> LoadLevel(string level, bool smooth)
{
char[,] content = Load(level);
int width = content.GetLength(0);
int height = content.GetLength(1);
bool[,] spawn = new bool[width, height];
bool[,] walls = new bool[width, height];
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
switch (content[x, y])
@ -23,6 +24,57 @@ namespace Snakity
content[x, y] = SpecialChars.Space;
spawn[x, y] = true;
break;
case '#':
walls[x, y] = true;
char selected;
//Determine adjacent blocks
bool up = y > 0 && (walls[x, y - 1] || content[x, y - 1] == '#');
bool down = y < height - 1 && (walls[x, y + 1] || content[x, y + 1] == '#');
bool left = x > 0 && (walls[x - 1, y] || content[x - 1, y] == '#');
bool right = x < width - 1 && (walls[x + 1, y] || content[x + 1, y] == '#');
//figure out char
if (smooth)
if (up)
{
if (down)
{
if (left)
selected = right
? SpecialChars.Wall.UpDownLeftRight
: SpecialChars.Wall.UpDownLeft;
else
selected = right ? SpecialChars.Wall.UpDownRight : SpecialChars.Wall.UpDown;
}
else
{
if (left)
selected = right ? SpecialChars.Wall.UpLeftRight : SpecialChars.Wall.UpLeft;
else
selected = right ? SpecialChars.Wall.UpRight : SpecialChars.Wall.Up;
}
}
else
{
if (down)
{
if (left)
selected = right ? SpecialChars.Wall.DownLeftRight : SpecialChars.Wall.DownLeft;
else
selected = right ? SpecialChars.Wall.DownRight : SpecialChars.Wall.Down;
}
else
{
if (left)
selected = right ? SpecialChars.Wall.LeftRight : SpecialChars.Wall.Left;
else
selected = right ? SpecialChars.Wall.Right : '#';
}
}
else
selected = '#';
//yay
content[x, y] = selected;
break;
}
return new Tuple<char[,], bool[,]>(content, spawn);

View File

@ -7,10 +7,12 @@ namespace Snakity.Graphics
{
private static readonly char[] WallChars =
{
SpecialChars.Wall.DownLeft, SpecialChars.Wall.DownRight, SpecialChars.Wall.LeftRight,
SpecialChars.Wall.UpDown, SpecialChars.Wall.UpLeft, SpecialChars.Wall.UpRight,
SpecialChars.Wall.DownLeftRight, SpecialChars.Wall.UpDownLeft, SpecialChars.Wall.UpDownRight,
SpecialChars.Wall.UpLeftRight, SpecialChars.Wall.UpDownLeftRight
SpecialChars.Wall.Up, SpecialChars.Wall.Down, SpecialChars.Wall.Left,
SpecialChars.Wall.Right, SpecialChars.Wall.DownLeft, SpecialChars.Wall.DownRight,
SpecialChars.Wall.LeftRight, SpecialChars.Wall.UpDown, SpecialChars.Wall.UpLeft,
SpecialChars.Wall.UpRight, SpecialChars.Wall.DownLeftRight, SpecialChars.Wall.UpDownLeft,
SpecialChars.Wall.UpDownRight, SpecialChars.Wall.UpLeftRight, SpecialChars.Wall.UpDownLeftRight,
'#'
};
private static readonly char[] PlayerChars =
@ -19,14 +21,15 @@ namespace Snakity.Graphics
SpecialChars.Player.Right, SpecialChars.Player.DownLeft, SpecialChars.Player.DownRight,
SpecialChars.Player.LeftRight, SpecialChars.Player.UpDown, SpecialChars.Player.UpLeft,
SpecialChars.Player.UpRight, SpecialChars.Player.DownLeftRight, SpecialChars.Player.UpDownLeft,
SpecialChars.Player.UpDownRight, SpecialChars.Player.UpLeftRight, SpecialChars.Player.UpDownLeftRight
SpecialChars.Player.UpDownRight, SpecialChars.Player.UpLeftRight, SpecialChars.Player.UpDownLeftRight,
'P'
};
public static ConsoleColor Get(char c)
{
if (PlayerChars.Contains(c))
return ConsoleColor.Green;
if (WallChars.Contains(c))
if (WallChars.Contains(c) || c == '#')
return ConsoleColor.Gray;
return c switch
{

View File

@ -1,56 +1,57 @@
using System;
namespace Snakity.Graphics
{
public static class DiffDraw
{
private static char[,] Screen { get; set; } = new char[0, 0];
private static char[,] _last = new char[0,0];
public static int Width => Screen.GetLength(0);
public static int Height => Screen.GetLength(1);
public static void Draw()
{
Console.CursorTop = 0;
Console.CursorLeft = 0;
int width = Width;
int height = Height;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
char tmp1 = Screen[x, y];
if (tmp1 == _last[x, y]) continue;
Console.ForegroundColor = ColorSelector.Get(tmp1);
Console.CursorLeft = x;
Console.Write(tmp1);
}
Console.WriteLine();
Console.CursorLeft = 0;
}
_last = Screen;
}
public static char Get(Point p) => Get(p.X, p.Y);
public static char Get(int x, int y) => Screen[x, y];
public static void Set(Point p, char c) => Set(p.X, p.Y, c);
public static void Set(int x, int y, char c) => Screen[x, y] = c;
public static void Clear() => Clear(Width, Height);
public static void Clear(int width, int height)
{
Screen = new char[width, height];
_last = _last.Resize(width, height);
}
public static void Clear(char[,] content)
{
Screen = content;
_last = _last.Resize(Width, Height);
}
}
}
using System;
namespace Snakity.Graphics
{
public static class DiffDraw
{
private static char[,] Screen { get; set; } = new char[0, 0];
private static char[,] _last = new char[0,0];
public static int Width => Screen.GetLength(0);
public static int Height => Screen.GetLength(1);
public static void Draw(bool color)
{
Console.CursorTop = 0;
Console.CursorLeft = 0;
int width = Width;
int height = Height;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
char tmp1 = Screen[x, y];
if (tmp1 == _last[x, y]) continue;
if (color)
Console.ForegroundColor = ColorSelector.Get(tmp1);
Console.CursorLeft = x;
Console.Write(tmp1);
}
Console.WriteLine();
Console.CursorLeft = 0;
}
_last = Screen;
}
public static char Get(Point p) => Get(p.X, p.Y);
public static char Get(int x, int y) => Screen[x, y];
public static void Set(Point p, char c) => Set(p.X, p.Y, c);
public static void Set(int x, int y, char c) => Screen[x, y] = c;
public static void Clear() => Clear(Width, Height);
public static void Clear(int width, int height)
{
Screen = new char[width, height];
_last = _last.Resize(width, height);
}
public static void Clear(char[,] content)
{
Screen = content;
_last = _last.Resize(Width, Height);
}
}
}

View File

@ -1,44 +0,0 @@
using System;
namespace Snakity.Graphics
{
public class DiffDraw
{
private static char[,] Screen { get; set; } = new char[0, 0];
public static int Width => Screen.GetLength(0);
public static int Height => Screen.GetLength(1);
public static void Draw()
{
Console.CursorTop = 0;
Console.CursorLeft = 0;
int width = Width;
int height = Height;
for (int y = 0; y < height; y++)
{
string line = "";
for (int x = 0; x < width; x++)
{
char tmp1 = Screen[x, y];
line += tmp1 == '\0' ? ' ' : tmp1;
}
Console.WriteLine(line);
Console.CursorLeft = 0;
}
}
public static char Get(Point p) => Get(p.X, p.Y);
public static char Get(int x, int y) => Screen[x, y];
public static void Set(Point p, char c) => Set(p.X, p.Y, c);
public static void Set(int x, int y, char c) => Screen[x, y] = c;
public static void Clear() => Clear(Width, Height);
public static void Clear(int width, int height) => Screen = new char[width, height];
public static void Clear(char[,] content) => Screen = content;
}
}

View File

@ -10,7 +10,7 @@ namespace Snakity.Graphics
public static readonly List<Point> Enemies = new List<Point>();
public static readonly List<Label> Labels = new List<Label>();
public static void Render()
public static void Render(bool smooth)
{
foreach (Label label in Labels) label.Render();
foreach (Point point in Enemies) DiffDraw.Set(point, SpecialChars.Enemy);
@ -18,24 +18,42 @@ namespace Snakity.Graphics
{
(Point position, Point direction) = Player[i];
char selected;
if (i == 0)
if (smooth)
{
if (Player.Count == 1)
if (i == 0)
{
if (direction == new Point(0, 1))
selected = SpecialChars.Player.Up;
else if (direction == new Point(0, -1))
selected = SpecialChars.Player.Down;
else if (direction == new Point(1, 0))
selected = SpecialChars.Player.Left;
else if (direction == new Point(-1, 0))
selected = SpecialChars.Player.Right;
if (Player.Count == 1)
{
if (direction == new Point(0, 1))
selected = SpecialChars.Player.Up;
else if (direction == new Point(0, -1))
selected = SpecialChars.Player.Down;
else if (direction == new Point(1, 0))
selected = SpecialChars.Player.Left;
else if (direction == new Point(-1, 0))
selected = SpecialChars.Player.Right;
else
selected = SpecialChars.Player.Down;
}
else
selected = SpecialChars.Player.Down;
{
Point prevPosition = Player[i + 1].Item1;
Point tmp = new Point(prevPosition.X - position.X, prevPosition.Y - position.Y);
if (tmp == new Point(0, 1))
selected = SpecialChars.Player.Down;
else if (tmp == new Point(0, -1))
selected = SpecialChars.Player.Up;
else if (tmp == new Point(1, 0))
selected = SpecialChars.Player.Right;
else if (tmp == new Point(-1, 0))
selected = SpecialChars.Player.Left;
else
throw new ArgumentException($"Unexpected: {{X={tmp.X};Y={tmp.Y}}}");
}
}
else
else if (i == Player.Count - 1)
{
Point prevPosition = Player[i + 1].Item1;
Point prevPosition = Player[i - 1].Item1;
Point tmp = new Point(prevPosition.X - position.X, prevPosition.Y - position.Y);
if (tmp == new Point(0, 1))
selected = SpecialChars.Player.Down;
@ -48,102 +66,89 @@ namespace Snakity.Graphics
else
throw new ArgumentException($"Unexpected: {{X={tmp.X};Y={tmp.Y}}}");
}
}
else if (i == Player.Count - 1)
{
Point prevPosition = Player[i - 1].Item1;
Point tmp = new Point(prevPosition.X - position.X, prevPosition.Y - position.Y);
if (tmp == new Point(0, 1))
selected = SpecialChars.Player.Down;
else if (tmp == new Point(0, -1))
selected = SpecialChars.Player.Up;
else if (tmp == new Point(1, 0))
selected = SpecialChars.Player.Right;
else if (tmp == new Point(-1, 0))
selected = SpecialChars.Player.Left;
else
throw new ArgumentException($"Unexpected: {{X={tmp.X};Y={tmp.Y}}}");
}
else
{
Point prevPosition = Player[i - 1].Item1;
Point nextPosition = Player[i + 1].Item1;
prevPosition = new Point(prevPosition.X - position.X, position.Y - prevPosition.Y);
nextPosition = new Point(nextPosition.X - position.X, position.Y - nextPosition.Y);
Direction[] directions = new Direction[2];
if (prevPosition == new Point(0, 1))
directions[0] = Direction.Up;
else if (prevPosition == new Point(0, -1))
directions[0] = Direction.Down;
else if (prevPosition == new Point(1, 0))
directions[0] = Direction.Right;
else if (prevPosition == new Point(-1, 0))
directions[0] = Direction.Left;
else
throw new ArgumentException("Unexpected previous position delta");
if (nextPosition == new Point(0, 1))
directions[1] = Direction.Up;
else if (nextPosition == new Point(0, -1))
directions[1] = Direction.Down;
else if (nextPosition == new Point(1, 0))
directions[1] = Direction.Right;
else if (nextPosition == new Point(-1, 0))
directions[1] = Direction.Left;
else
throw new ArgumentException("Unexpected next position delta");
directions = directions.OrderBy(s => (int) s).ToArray();
switch (directions[0])
{
case Direction.Up:
switch (directions[1])
{
case Direction.Down:
selected = SpecialChars.Player.UpDown;
break;
case Direction.Left:
selected = SpecialChars.Player.UpLeft;
break;
case Direction.Right:
selected = SpecialChars.Player.UpRight;
break;
default:
throw new ArgumentOutOfRangeException();
}
Point prevPosition = Player[i - 1].Item1;
Point nextPosition = Player[i + 1].Item1;
prevPosition = new Point(prevPosition.X - position.X, position.Y - prevPosition.Y);
nextPosition = new Point(nextPosition.X - position.X, position.Y - nextPosition.Y);
Direction[] directions = new Direction[2];
break;
case Direction.Down:
switch (directions[1])
{
case Direction.Left:
selected = SpecialChars.Player.DownLeft;
break;
case Direction.Right:
selected = SpecialChars.Player.DownRight;
break;
default:
throw new ArgumentOutOfRangeException();
}
if (prevPosition == new Point(0, 1))
directions[0] = Direction.Up;
else if (prevPosition == new Point(0, -1))
directions[0] = Direction.Down;
else if (prevPosition == new Point(1, 0))
directions[0] = Direction.Right;
else if (prevPosition == new Point(-1, 0))
directions[0] = Direction.Left;
else
throw new ArgumentException("Unexpected previous position delta");
break;
case Direction.Left:
switch (directions[1])
{
case Direction.Right:
selected = SpecialChars.Player.LeftRight;
break;
default:
throw new ArgumentOutOfRangeException();
}
if (nextPosition == new Point(0, 1))
directions[1] = Direction.Up;
else if (nextPosition == new Point(0, -1))
directions[1] = Direction.Down;
else if (nextPosition == new Point(1, 0))
directions[1] = Direction.Right;
else if (nextPosition == new Point(-1, 0))
directions[1] = Direction.Left;
else
throw new ArgumentException("Unexpected next position delta");
break;
default:
throw new ArgumentOutOfRangeException();
directions = directions.OrderBy(s => (int) s).ToArray();
switch (directions[0])
{
case Direction.Up:
switch (directions[1])
{
case Direction.Down:
selected = SpecialChars.Player.UpDown;
break;
case Direction.Left:
selected = SpecialChars.Player.UpLeft;
break;
case Direction.Right:
selected = SpecialChars.Player.UpRight;
break;
default:
throw new ArgumentOutOfRangeException();
}
break;
case Direction.Down:
switch (directions[1])
{
case Direction.Left:
selected = SpecialChars.Player.DownLeft;
break;
case Direction.Right:
selected = SpecialChars.Player.DownRight;
break;
default:
throw new ArgumentOutOfRangeException();
}
break;
case Direction.Left:
switch (directions[1])
{
case Direction.Right:
selected = SpecialChars.Player.LeftRight;
break;
default:
throw new ArgumentOutOfRangeException();
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
else
selected = 'P';
DiffDraw.Set(position, selected);
}

View File

@ -3,24 +3,28 @@
public static class SpecialChars
{
public const char Enemy = '@';
public const char Space = '\0';
public const char Space = ' ';
public static class Wall
{
// 1 connectors
public const char Up = '║';
public const char Down = '║';
public const char Left = '═';
public const char Right = '═';
// 2 connectors
public const char UpDown = '║';
public const char LeftRight = '═';
public const char DownRight = '╔';
public const char UpRight = '╚';
public const char DownLeft = '╗';
public const char UpLeft = '╝';
// 3 connectors
public const char UpDownLeft = '╣';
public const char UpDownRight = '╠';
public const char UpLeftRight = '╩';
public const char DownLeftRight = '╦';
// 4 connectors
@ -33,7 +37,6 @@
public const char Up = '╵';
public const char Down = '╷';
public const char Left = '╴';
public const char Right = '╶';
// 2 connectors
@ -42,14 +45,12 @@
public const char DownRight = '┌';
public const char UpRight = '└';
public const char DownLeft = '┐';
public const char UpLeft = '┘';
// 3 connectors
public const char UpDownLeft = '┤';
public const char UpDownRight = '├';
public const char UpLeftRight = '┴';
public const char DownLeftRight = '┬';
// 4 connectors

View File

@ -23,7 +23,7 @@ namespace Snakity.Loop
while (tmp - _lastCheck > Delay)
{
_lastCheck += Delay;
if (Program.Rnd.Next(50) != 0 && Renderer.Enemies.Count > 0) continue;
if (Renderer.Enemies.Count > 0 && Program.Rnd.Next(50) != 0 || Renderer.Enemies.Count > 4) continue;
Point tmp1 = new Point(Program.Rnd.Next(DiffDraw.Width), Program.Rnd.Next(DiffDraw.Height));
int attempts = 0;
while (!spawnMap[tmp1.X, tmp1.Y] && attempts < 5)

View File

@ -102,9 +102,10 @@ namespace Snakity.Loop
return false;
}
public static void ResetSpeed()
public static void Reset()
{
_delay = new TimeSpan(3000000);
_lastCheck = DateTime.Now;;
}
private static bool CheckPoint(Point point) =>

View File

@ -11,49 +11,25 @@ namespace Snakity.Loop
public static void Main(string[] args)
{
if (args.Contains("DrawTest"))
args = args.Select(s => s.TrimStart('-', '/').ToLower()).ToArray();
if (args.Contains("drawtest") || args.Contains("bench") || args.Contains("b"))
{
Console.Clear();
(char[,] level, _) =
CharArrayLoader.LoadLevel(@"
#####################
# #
# #
# #
# #
# #
#####################");
DiffDraw.Clear(level);
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 2), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 2), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 3), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 3), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 4), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 5), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 6), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 6), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 5), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 4), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(3, 4), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(3, 3), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(3, 2), new Point(0, 0)));
Renderer.Player.Add(new Tuple<Point, Point>(new Point(4, 2), new Point(0, 0)));
Renderer.Render();
DiffDraw.Draw();
Console.ReadKey();
Benchmark.Perform();
return;
}
bool playing = true;
while (playing)
{
Console.Clear();
//Main menu
Console.WriteLine(@"
Console.WriteLine($@"
~ Snakity ~
Highscore: {SettingsMan.Highscore}
s - Start
x - Exit");
s - Start
v - Settings
b - Benchmark
x - Exit");
switch (Console.ReadKey().Key)
{
case ConsoleKey.S:
@ -64,6 +40,89 @@ namespace Snakity.Loop
case ConsoleKey.X:
playing = false;
break;
case ConsoleKey.V:
int currentSetting = 0;
bool settingVals = true;
while (settingVals)
{
Console.ResetColor();
Console.Clear();
Console.WriteLine("Smooth Player");
Console.ForegroundColor =
SettingsMan.SmoothPlayer ? ConsoleColor.Black : ConsoleColor.White;
Console.BackgroundColor =
SettingsMan.SmoothPlayer ? ConsoleColor.White : ConsoleColor.Black;
Console.Write("Yes ");
Console.ForegroundColor =
SettingsMan.SmoothPlayer ? ConsoleColor.White : ConsoleColor.Black;
Console.BackgroundColor =
SettingsMan.SmoothPlayer ? ConsoleColor.Black : ConsoleColor.White;
Console.WriteLine("No");
Console.ResetColor();
Console.WriteLine("Smooth Terrain");
Console.ForegroundColor =
SettingsMan.SmoothTerrain ? ConsoleColor.Black : ConsoleColor.White;
Console.BackgroundColor =
SettingsMan.SmoothTerrain ? ConsoleColor.White : ConsoleColor.Black;
Console.Write("Yes ");
Console.ForegroundColor =
SettingsMan.SmoothTerrain ? ConsoleColor.White : ConsoleColor.Black;
Console.BackgroundColor =
SettingsMan.SmoothTerrain ? ConsoleColor.Black : ConsoleColor.White;
Console.WriteLine("No");
Console.ResetColor();
Console.WriteLine("Use Color");
Console.ForegroundColor =
SettingsMan.Color ? ConsoleColor.Black : ConsoleColor.White;
Console.BackgroundColor =
SettingsMan.Color ? ConsoleColor.White : ConsoleColor.Black;
Console.Write("Yes ");
Console.ForegroundColor =
SettingsMan.Color ? ConsoleColor.White : ConsoleColor.Black;
Console.BackgroundColor =
SettingsMan.Color ? ConsoleColor.Black : ConsoleColor.White;
Console.WriteLine("No");
Console.ResetColor();
switch (Console.ReadKey().Key)
{
case ConsoleKey.Escape:
case ConsoleKey.Enter:
settingVals = false;
break;;
case ConsoleKey.LeftArrow:
case ConsoleKey.RightArrow:
case ConsoleKey.Spacebar:
switch (currentSetting)
{
case 0:
SettingsMan.SmoothPlayer = !SettingsMan.SmoothPlayer;
break;
case 1:
SettingsMan.SmoothTerrain = !SettingsMan.SmoothTerrain;
break;
case 2:
SettingsMan.Color = !SettingsMan.Color;
break;
}
break;
case ConsoleKey.UpArrow:
currentSetting--;
if (currentSetting < 0)
currentSetting = 2;
break;
case ConsoleKey.DownArrow:
case ConsoleKey.Tab:
currentSetting++;
if (currentSetting > 2)
currentSetting = 0;
break;
}
}
Console.ResetColor();
break;
case ConsoleKey.B:
Benchmark.Perform();
break;
}
}
@ -74,35 +133,44 @@ namespace Snakity.Loop
private static bool GameOver()
{
Console.Clear();
if (_score > SettingsMan.Highscore)
SettingsMan.Highscore = _score;
Console.WriteLine($@"
GAME OVER
Score: {_score}
Play again? (y/n)");
_score = 0;
return Console.ReadKey().KeyChar == 'y';
}
private static void PlayRound()
{
Console.Clear();
bool playing = true;
DiffDraw.Clear(5, 5);
Label scoreLabel = new Label(new Point(0, 0), "");
Renderer.Labels.Clear();
Renderer.Labels.Add(scoreLabel);
(char[,] level, bool[,] spawnable) =
CharArrayLoader.LoadLevel(Levels.levels[Rnd.Next(Levels.levels.Length)]);
CharArrayLoader.LoadLevel(Levels.levels[Rnd.Next(Levels.levels.Length)], SettingsMan.SmoothTerrain);
bool hasIncreased = false;
Renderer.Player.Clear();
Renderer.Player.Add(new Tuple<Point, Point>(new Point(1, 1), new Point(0, 1)));
Renderer.Enemies.Clear();
Input.ResetSpeed();
DiffDraw.Clear((char[,]) level.Clone());
DiffDraw.Draw(SettingsMan.Color);
Input.Reset();
while (playing)
{
DiffDraw.Clear((char[,]) level.Clone());
scoreLabel.Text = $"Score: {_score}";
Renderer.Render();
Renderer.Render(SettingsMan.SmoothPlayer);
Input.Get();
if (Input.Move(hasIncreased) || Input.Esc)
{
Renderer.Player.Clear();
Input.Reset();
playing = false;
Input.Esc = false;
continue;
@ -110,22 +178,23 @@ Play again? (y/n)");
if (Input.R)
{
_score = 0;
DiffDraw.Clear();
DiffDraw.Draw();
(level, spawnable) = CharArrayLoader.LoadLevel(Levels.levels[Rnd.Next(Levels.levels.Length)]);
Renderer.Player.Clear();
Renderer.Enemies.Clear();
Input.ResetSpeed();
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 2), new Point(0, 1)));
DiffDraw.Draw(SettingsMan.Color);
(level, spawnable) = CharArrayLoader.LoadLevel(Levels.levels[Rnd.Next(Levels.levels.Length)], SettingsMan.SmoothTerrain);
DiffDraw.Clear((char[,]) level.Clone());
Renderer.Player.Clear();
Renderer.Player.Add(new Tuple<Point, Point>(new Point(2, 2), new Point(0, 1)));
Renderer.Enemies.Clear();
Input.Reset();
Input.R = false;
}
Renderer.Render();
Renderer.Render(SettingsMan.SmoothPlayer);
hasIncreased = Enemy.Compute(spawnable);
if (hasIncreased)
_score++;
DiffDraw.Draw();
DiffDraw.Draw(SettingsMan.Color);
}
}
}

91
Snakity/SettingsMan.cs Normal file
View File

@ -0,0 +1,91 @@
using System.IO;
using System.Reflection;
using System.Xml.Linq;
namespace Snakity
{
public static class SettingsMan
{
private static XElement _settings;
private static readonly string SettingsPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Settings.xml");
public static int Highscore
{
get
{
if (_settings == null)
Load();
return int.Parse(_settings.Element("highscore").Value);
}
set
{
_settings.Element("highscore").Value = value.ToString();
Save();
}
}
public static bool SmoothPlayer
{
get
{
if (_settings == null)
Load();
return bool.Parse(_settings.Element("smoothplayer").Value);
}
set
{
_settings.Element("smoothplayer").Value = value.ToString();
Save();
}
}
public static bool SmoothTerrain
{
get
{
if (_settings == null)
Load();
return bool.Parse(_settings.Element("smoothterrain").Value);
}
set
{
_settings.Element("smoothterrain").Value = value.ToString();
Save();
}
}
public static bool Color
{
get
{
if (_settings == null)
Load();
return bool.Parse(_settings.Element("color").Value);
}
set
{
_settings.Element("color").Value = value.ToString();
Save();
}
}
private static void Load()
{
_settings = File.Exists(SettingsPath) ? XElement.Load(SettingsPath) : new XElement("settings");
if (_settings.Element("highscore") == null || _settings.Element("highscore").Value == null)
_settings.Add(new XElement("highscore", 0));
if (_settings.Element("smoothplayer") == null || _settings.Element("smoothplayer").Value == null)
_settings.Add(new XElement("smoothplayer", true));
if (_settings.Element("smoothterrain") == null || _settings.Element("smoothterrain").Value == null)
_settings.Add(new XElement("smoothterrain", true));
if (_settings.Element("color") == null || _settings.Element("color").Value == null)
_settings.Add(new XElement("color", true));
}
private static void Save()
{
if (_settings == null)
Load();
_settings.Save(SettingsPath);
}
}
}

View File

@ -4,10 +4,5 @@
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Graphics/LinuxDiffDraw.cs" Condition="'$(OS)' == 'Windows_NT'" />
<Compile Remove="Graphics/WindowsDiffDraw.cs" Condition="'$(OS)' != 'Windows_NT'" />
</ItemGroup>
</Project>