using System.Diagnostics;
static readonly int height = Console.WindowHeight;
static readonly int width = Console.WindowWidth;
static readonly TimeSpan sleep = TimeSpan.FromMilliseconds(10);
static readonly TimeSpan timeSpanIdle = TimeSpan.FromMilliseconds(400);
static readonly TimeSpan timeSpanPunch = TimeSpan.FromMilliseconds(100);
static readonly TimeSpan timeSpanBlock = TimeSpan.FromMilliseconds(400);
static readonly TimeSpan timeSpanJumpKick = TimeSpan.FromMilliseconds(100);
static readonly TimeSpan timeSpanOwned = TimeSpan.FromMilliseconds(50);
static readonly TimeSpan timeSpanGetUp = TimeSpan.FromMilliseconds(80);
static readonly Random random = new Random();
public Action Action = Action.Idle;
public Stopwatch Stopwatch = new Stopwatch();
public string[] IdleAnimation;
public string[] PunchAnimation;
public string[] BlockAnimation;
public string[] JumpKickAnimation;
public string[] OwnedAnimation;
public string[] GetUpAnimation;
Console.WriteLine("This game is still under development.");
Console.WriteLine("Press Enter To Continue...");
Console.CursorVisible = false;
Fighter player = new Fighter()
IdleAnimation = Ascii.Player.IdleAnimation,
PunchAnimation = Ascii.Player.PunchAnimation,
BlockAnimation = Ascii.Player.BlockAnimation,
JumpKickAnimation = Ascii.Player.JumpKickAnimation,
OwnedAnimation = Ascii.Player.OwnedAnimation,
GetUpAnimation = Ascii.Player.GetUpAnimation,
Fighter enemy = new Fighter()
IdleAnimation = Ascii.Enemy.IdleAnimation,
PunchAnimation = Ascii.Enemy.PunchAnimation,
BlockAnimation = Ascii.Enemy.BlockAnimation,
JumpKickAnimation = Ascii.Enemy.JumpKickAnimation,
player.Stopwatch.Restart();
enemy.Stopwatch.Restart();
Console.SetCursorPosition(player.Position, Y);
Render(Ascii.Player.IdleAnimation[player.Frame]);
Console.SetCursorPosition(enemy.Position, Y);
Render(Ascii.Enemy.IdleAnimation[enemy.Frame]);
Console.SetCursorPosition(0, 11);
for (int i = 0; i < width; i++)
if (Console.WindowHeight != height || Console.WindowWidth != width)
Console.Write("Console resized. Fighter was closed.");
bool skipPlayerUpdate = false;
bool skipEnemyUpdate = false;
static void Trigger(Fighter fighter, Action action)
Console.SetCursorPosition(fighter.Position, Y);
Erase(fighter.IdleAnimation[fighter.Frame]);
Console.SetCursorPosition(fighter.Position, Y);
Action.Idle => fighter.IdleAnimation[fighter.Frame],
Action.Punch => fighter.PunchAnimation[fighter.Frame],
Action.Block => fighter.BlockAnimation[fighter.Frame],
Action.JumpKick => fighter.JumpKickAnimation[fighter.Frame],
Action.Owned => fighter.OwnedAnimation[fighter.Frame],
Action.GetUp => fighter.GetUpAnimation[fighter.Frame],
_ => throw new NotImplementedException(),
fighter.Stopwatch.Restart();
static void Move(Fighter fighter, int location)
Console.SetCursorPosition(fighter.Position, Y);
Erase(fighter.IdleAnimation[fighter.Frame]);
fighter.Position = location;
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.IdleAnimation[fighter.Frame]);
if (Console.KeyAvailable)
switch (Console.ReadKey(true).Key)
if (player.Action == Action.Idle)
Trigger(player, Action.Punch);
if (player.Action == Action.Idle)
Trigger(player, Action.Block);
if (player.Action == Action.Idle)
Trigger(player, Action.JumpKick);
if (player.Action == Action.Idle)
Trigger(player, Action.Owned);
case ConsoleKey.LeftArrow:
if (player.Action == Action.Idle)
int newPosition = Math.Min(Math.Max(player.Position - 1, 0), enemy.Position - 4);
if (newPosition != player.Position)
Move(player, newPosition);
case ConsoleKey.RightArrow:
if (player.Action == Action.Idle)
int newPosition = Math.Min(Math.Max(player.Position + 1, 0), enemy.Position - 4);
if (newPosition != player.Position)
Move(player, newPosition);
Console.Write("Fighter was closed.");
while (Console.KeyAvailable)
if (enemy.Action == Action.Idle)
if (enemy.Position - player.Position <= 5 && random.Next(7) == 0)
Trigger(enemy, Action.Block);
else if (enemy.Position - player.Position <= 5 && random.Next(10) == 0)
Trigger(enemy, Action.Punch);
else if (enemy.Position - player.Position <= 5 && random.Next(10) == 0)
Trigger(enemy, Action.JumpKick);
else if (random.Next(10) == 0)
int newPosition = Math.Min(Math.Max(enemy.Position - 1, player.Position + 4), width - 9);
if (enemy.Position != newPosition)
Move(enemy, newPosition);
else if (random.Next(10) == 0)
int newPosition = Math.Min(Math.Max(enemy.Position + 1, player.Position + 4), width - 9);
if (enemy.Position != newPosition)
Move(enemy, newPosition);
static void Update(Fighter fighter)
if (fighter.Action == Action.Idle && fighter.Stopwatch.Elapsed > timeSpanIdle)
Console.SetCursorPosition(fighter.Position, Y);
Erase(fighter.IdleAnimation[fighter.Frame]);
fighter.Frame = fighter.Frame is 0 ? 1 : 0;
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.IdleAnimation[fighter.Frame]);
fighter.Stopwatch.Restart();
else if (fighter.Action == Action.Punch && fighter.Stopwatch.Elapsed > timeSpanPunch)
Console.SetCursorPosition(fighter.Position, Y);
Erase(fighter.PunchAnimation[fighter.Frame]);
if (fighter.Frame >= fighter.PunchAnimation.Length)
fighter.Action = Action.Idle;
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.IdleAnimation[fighter.Frame]);
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.PunchAnimation[fighter.Frame]);
fighter.Stopwatch.Restart();
else if (fighter.Action == Action.Block && fighter.Stopwatch.Elapsed > timeSpanBlock)
Console.SetCursorPosition(fighter.Position, Y);
Erase(fighter.BlockAnimation[fighter.Frame]);
fighter.Action = Action.Idle;
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.IdleAnimation[fighter.Frame]);
fighter.Stopwatch.Restart();
else if (fighter.Action == Action.JumpKick && fighter.Stopwatch.Elapsed > timeSpanJumpKick)
Console.SetCursorPosition(fighter.Position, Y);
Erase(fighter.JumpKickAnimation[fighter.Frame]);
if (fighter.Frame >= fighter.JumpKickAnimation.Length)
fighter.Action = Action.Idle;
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.IdleAnimation[fighter.Frame]);
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.JumpKickAnimation[fighter.Frame]);
fighter.Stopwatch.Restart();
else if (fighter.Action == Action.Owned && fighter.Stopwatch.Elapsed > timeSpanOwned)
Console.SetCursorPosition(fighter.Position, Y);
Erase(fighter.OwnedAnimation[fighter.Frame]);
if (fighter.Frame >= fighter.OwnedAnimation.Length)
fighter.Action = Action.GetUp;
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.GetUpAnimation[fighter.Frame]);
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.OwnedAnimation[fighter.Frame]);
fighter.Stopwatch.Restart();
else if (fighter.Action == Action.GetUp && fighter.Stopwatch.Elapsed > timeSpanGetUp)
Console.SetCursorPosition(fighter.Position, Y);
Erase(fighter.GetUpAnimation[fighter.Frame]);
if (fighter.Frame >= fighter.GetUpAnimation.Length)
fighter.Action = Action.Idle;
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.IdleAnimation[fighter.Frame]);
Console.SetCursorPosition(fighter.Position, Y);
Render(fighter.GetUpAnimation[fighter.Frame]);
fighter.Stopwatch.Restart();
static void Render(string @string, bool renderSpace = false)
int x = Console.CursorLeft;
int y = Console.CursorTop;
foreach (char c in @string)
Console.SetCursorPosition(x, ++y);
else if (Console.CursorLeft < width - 1 && (!(c is ' ') || renderSpace))
else if (Console.CursorLeft < width - 1 && Console.CursorTop < height - 1)
Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
static void Erase(string @string)
int x = Console.CursorLeft;
int y = Console.CursorTop;
foreach (char c in @string)
Console.SetCursorPosition(x, ++y);
else if (Console.CursorLeft < width - 1 && !(c is ' '))
else if (Console.CursorLeft < width - 1 && Console.CursorTop < height - 1)
Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
public static class Player
public static readonly string[] IdleAnimation = new string[]
public static readonly string[] BlockAnimation = new string[]
public static readonly string[] PunchAnimation = new string[]
public static readonly string[] JumpKickAnimation = new string[]
public static readonly string[] OwnedAnimation = new string[]
public static readonly string[] GetUpAnimation = new string[]
public static class Enemy
public static readonly string[] IdleAnimation = new string[]
public static readonly string[] BlockAnimation = new string[]
public static readonly string[] PunchAnimation = new string[]
public static readonly string[] JumpKickAnimation = new string[]