**[Source Code](Program.cs)**
Flappy Bird is a game where you play a bird and try to dodge obstacles in your flight path. You only have control over your vertical velocity. Your horizontal velocity is constant. Make it as far as you can!
█████████ █████████ █████████
█████████ █████████ █████████
█████████ █████████ █████████
█████████ █████████ █████████
█████████ █████████ █████████
~(^')> █████████ █████████
█████████ █████████ █████████
█████████ █████████ █████████
█████████ █████████ █████████
█████████ █████████ █████████
The **space bar** is used to flap your wings. The **enter** key is used to restart the game after you die. The **escape** key may be used to close the game at any time. If you **resize** the console widow the game will be closed.
using System.Collections.Generic;
const float Gravity = .5f;
const int PipeGapHeight = 6;
const int SpaceBetweenPipes = 45;
const string BirdUp = @"~(v')>";
const string BirdDown = @"~(^')>";
static readonly int OriginalWidth = Console.WindowWidth;
static readonly int OriginalHeight = Console.WindowHeight;
static readonly bool OriginalCursorVisible = Console.CursorVisible;
static readonly TimeSpan Sleep = TimeSpan.FromMilliseconds(90);
static readonly Random Random = new Random();
static readonly List<(int X, int GapY)> Pipes = new List<(int, int)>();
Width = Console.WindowWidth = 120;
Height = Console.WindowHeight = 30;
PipeFrame = SpaceBetweenPipes;
Console.CursorVisible = false;
Console.SetCursorPosition((int)BirdX - 10, (int)BirdY + 1);
Console.Write("Press Space To Flap");
switch (Console.ReadKey(true).Key)
case ConsoleKey.Spacebar:
Console.Write("Flappy Bird was closed.");
Console.SetCursorPosition((int)BirdX - 10, (int)BirdY + 1);
if (Console.WindowHeight != Height || Console.WindowWidth != Width)
Console.Write("You resized the console. Flappy Bird was closed.");
if (Frame == int.MaxValue)
Console.SetCursorPosition(0, Height - 1);
Console.Write("You win! Score: " + Frame + ".");
if (!(BirdY < Height - 1 && BirdY > 0) || IsBirdCollidingWithPipe())
Console.SetCursorPosition(0, Height - 1);
Console.Write("Game Over. Score: " + Frame + ".");
Console.Write(" Play Again [enter], or quit [escape]?");
ConsoleKey key = Console.ReadKey(true).Key;
if (key is ConsoleKey.Enter)
else if (!(key is ConsoleKey.Escape))
foreach (var pipe in Pipes)
int x = pipe.X + PipeWidth / 2;
for (int y = 0; y < Height; y++)
Console.SetCursorPosition(x, y);
for (int i = 0; i < Pipes.Count; i++)
Pipes[i] = (Pipes[i].X - 1, Pipes[i].GapY);
if (Pipes.Count > 0 && Pipes[0].X < -PipeWidth)
if (PipeFrame >= SpaceBetweenPipes)
int gapY = Random.Next(0, Height - PipeGapHeight - 1 - 6) + 3;
Pipes.Add((Width + PipeWidth / 2, gapY));
foreach (var pipe in Pipes)
int x = pipe.X - PipeWidth / 2;
for (int y = 0; y < Height; y++)
if (x > 0 && x < Width - 1 && (y < pipe.GapY || y > pipe.GapY + PipeGapHeight))
Console.SetCursorPosition(x, y);
bool verticalVelocity = BirdDY < 0;
Console.SetCursorPosition((int)(BirdX) - 3, (int)BirdY);
while (Console.KeyAvailable)
switch (Console.ReadKey(true).Key)
case ConsoleKey.Spacebar:
Console.Write("Flappy Bird was closed.");
Console.CursorVisible = OriginalCursorVisible;
Console.WindowWidth = OriginalWidth;
Console.WindowHeight = OriginalHeight;
public static bool IsBirdCollidingWithPipe()
foreach (var pipe in Pipes)
if (Math.Abs(pipe.X - BirdX) < PipeWidth / 2 + 3 && ((int)BirdY < pipe.GapY || (int)BirdY > pipe.GapY + PipeGapHeight))
public static void RenderBird()
if ((int)BirdY < Height - 1 && (int)BirdY >= 0)
bool verticalVelocity = BirdDY < 0;
Console.SetCursorPosition((int)BirdX - 3, (int)BirdY);
Console.Write(verticalVelocity ? BirdUp : BirdDown);