init commit

This commit is contained in:
2026-08-04 06:56:44 -06:00
commit 4862002cd7
50 changed files with 2194 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
# Snake
Snake
CLI snake game. CSIS 2410 project A05.
+16
View File
@@ -0,0 +1,16 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Snake", "Snake\Snake.csproj", "{4A6995A3-4AC4-4954-A7CA-904A77D5AC85}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4A6995A3-4AC4-4954-A7CA-904A77D5AC85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A6995A3-4AC4-4954-A7CA-904A77D5AC85}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A6995A3-4AC4-4954-A7CA-904A77D5AC85}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A6995A3-4AC4-4954-A7CA-904A77D5AC85}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
+64
View File
@@ -0,0 +1,64 @@
namespace Snake
{
///
/// <summary>Represents a Console position in Left and Top coordinates, AKA (x, y).</summary>
///
/// <author>Josh Ashton</author>
///
public class Position
{
public int X1;
public int X2;
public int Y { get; }
private const ConsoleColor D_GREEN = ConsoleColor.DarkGreen;
private const ConsoleColor BLACK = ConsoleColor.Black;
private const ConsoleColor GREEN = ConsoleColor.Green;
private const ConsoleColor WHITE = ConsoleColor.White;
private const ConsoleColor YELLOW = ConsoleColor.Yellow;
public bool SnakeKiller { get; }
public bool Snake { get; set; }
public Position Next { get; set; }
public Position Prev { get; set; }
public Position(int x1, int x2, int y)
{
X1 = x1;
X2 = x2;
Y = y;
}
public Position(int x1, int x2, int y, bool snakeKiller)
{
X1 = x1;
X2 = x2;
Y = y;
SnakeKiller = snakeKiller;
}
public void Draw(bool isHead) {
if(SnakeKiller)
{
Console.BackgroundColor = D_GREEN;
Console.Write(" ");
Console.BackgroundColor = BLACK;
} else if (Snake)
{
Console.BackgroundColor = WHITE;
Console.Write(" ");
Console.BackgroundColor = BLACK;
} else if (isHead)
{
Console.BackgroundColor = GREEN;
Console.Write(" ");
Console.BackgroundColor = BLACK;
}
else
{
Console.Write(" ");
}
}
}
}
+228
View File
@@ -0,0 +1,228 @@
using System.ComponentModel;
using System.Timers;
using Timer = System.Timers.Timer;
namespace Snake;
public class Program
{
int leftMargin = 9;
int topMargin = 0;
private int height = 19;
private int width = 31;
private double difficulty;
private int time;
private Position[][] grid;
private Position bottom { get; set; }
private Position top { get; set; }
static void Main(string[] args)
{
Program p = new Program();
p.bottom = new Position(p.leftMargin, p.leftMargin + 1, p.topMargin + p.height);
p.top = new Position(p.leftMargin, p.leftMargin + 1, p.topMargin);
p.time = 0;
p.PrintIntro();
p.MenuInput();
}
void DrawSnake()
{
Snake s = new Snake(grid, 100);
Timer t = new Timer(100);
t.Elapsed += TimerAction;
t.Enabled = true;
if (!s.Move())
{
DisplayGameOver();
Thread.Sleep(3000);
PrintIntro();
MenuInput();
}
else
{
DisplayNextLevel();
}
}
void TimerAction(object? sender, ElapsedEventArgs elapsedEventArgs)
{
time++;
}
void PrintIntro()
{
string[] s =
{
"╔════════════════════════════════════════════════════════════╗",
" /^\\/^\\ ",
" _|__| O| ",
" \\/ /~ \\_/ \\ ",
" \\____|__________/ \\ ",
" \\_______ \\ ",
" '\\ \\ \\ ",
" | | \\ ",
" / / \\ ",
" / / \\\\ ",
" / / \\\\ ",
" / / \\ \\\\ ",
" / / _----_ \\ \\\\ ",
" / / _-~ ~-_ | | ",
" ( ( _-~ _--_ ~-_ _/ | ",
" \\ ~-____-~ _-~ ~-_ ~-_-~ / ",
" ~-_ _-~ ~-_ _-~ ",
" ~--______-~ ~-___-~ ",
"╚════════════════════════════════════════════════════════════╝"
};
PrintConsole(s);
}
// TODO: Can no longer press q or r after starting the game.
void MenuInput()
{
Console.SetCursorPosition(bottom.X1, bottom.Y);
Console.Write("Enter p to play, q to quit, r for rules: ");
char input = Console.ReadKey().KeyChar;
Console.SetCursorPosition(bottom.X1, bottom.Y);
while (input != 'q')
{
switch (input)
{
case 'p':
Console.SetCursorPosition(bottom.X1, bottom.Y);
Console.Write("Enter e for easy, m for medium, and h for hard: ");
char level = Console.ReadKey().KeyChar;
grid = new Position[height][];
switch (level)
{
case 'e':
grid = GenerateGameBoard(grid, 0.03);
break;
case 'm':
grid = GenerateGameBoard(grid, 0.06);
break;
case 'h':
grid = GenerateGameBoard(grid, 0.1);
break;
}
DrawGameBoard(grid);
DrawSnake();
break;
case 'q':
Environment.Exit(0);
break;
case 'r':
DisplayRules();
break;
}
}
}
void DrawGameBoard(Position[][] grid)
{
for (int i = 0; i < grid.Length; i++)
{
for (int j = 0; j < grid[i].Length; j++)
{
Console.SetCursorPosition(grid[i][j].X1, grid[i][j].Y);
grid[i][j].Draw(false);
}
Console.WriteLine();
}
time = 0;
}
void DisplayRules()
{
Position[][] grid = new Position[height][];
grid = GenerateGameBoard(grid, 0.03);
DrawGameBoard(grid);
string rules = (
"RULES:\n" +
" - Do not let the snake head touch walls or obstacles.\n" +
" - Use the arrow keys to control the snake."
//" - Collect all points in a level to move to the next level.",
//" - Levels increase difficulty."
);
PrintConsole(rules);
}
// TODO: ASCII art for game over screen
void DisplayGameOver()
{
string[] s =
{
"",
"",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⡀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣤⠀⠀⠀⢀⣴⣿⡶⠀⣾⣿⣿⡿⠟⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣄⣀⠀⠀⠀⠀⣶⣶⣦⠀⠀⠀⠀⣼⣿⣿⡇⠀⣠⣿⣿⣿⠇⣸⣿⣿⣧⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣾⣿⡿⠿⠿⠿⠇⠀⠀⣸⣿⣿⣿⡆⠀⠀⢰⣿⣿⣿⣷⣼⣿⣿⣿⡿⢀⣿⣿⡿⠟⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⡿⠋⠁⠀⠀⠀⠀⠀⠀⢠⣿⣿⣹⣿⣿⣿⣿⣿⣿⡏⢻⣿⣿⢿⣿⣿⠃⣼⣿⣯⣤⣴⣶⣿⡤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠏⠀⣀⣠⣤⣶⣾⣷⠄⣰⣿⣿⡿⠿⠻⣿⣯⣸⣿⡿⠀⠀⠀⠁⣾⣿⡏⢠⣿⣿⠿⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠲⢿⣿⣿⣿⣿⡿⠋⢰⣿⣿⠋⠀⠀⠀⢻⣿⣿⣿⠇⠀⠀⠀⠀⠙⠛⠀⠀⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⢿⣷⣶⣿⣿⠿⠋⠀⠀⠈⠙⠃⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠈⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣤⣴⣶⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀⠀⠀⠀⠀⠀⠀⠀⣠⡇⢰⣶⣶⣾⡿⠷⣿⣿⣿⡟⠛⣉⣿⣿⣿⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⡎⣿⣿⣦⠀⠀⠀⢀⣤⣾⠟⢀⣿⣿⡟⣁⠀⠀⣸⣿⣿⣤⣾⣿⡿⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⡿⠛⠉⢿⣦⠘⣿⣿⡆⠀⢠⣾⣿⠋⠀⣼⣿⣿⣿⠿⠷⢠⣿⣿⣿⠿⢻⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿⠋⠀⠀⠀⢸⣿⣇⢹⣿⣷⣰⣿⣿⠃⠀⢠⣿⣿⢃⣀⣤⣤⣾⣿⡟⠀⠀⠀⢻⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⡇⠀⠀⢀⣴⣿⣿⡟⠀⣿⣿⣿⣿⠃⠀⠀⣾⣿⣿⡿⠿⠛⢛⣿⡟⠀⠀⠀⠀⠀⠻⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣶⣾⣿⣿⣿⠟⠁⠀⠸⢿⣿⠇⠀⠀⠀⠛⠛⠁⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
""
};
// Prints score and time below ASCII art of same dimension as the snake drawing above
PrintConsole($"Score: {time * 100} | Time: {time / 10} seconds ");
PrintConsole(s);
time = 0;
}
void DisplayNextLevel()
{
grid = GenerateGameBoard(grid, difficulty * (1 + difficulty));
DrawGameBoard(grid);
DrawSnake();
}
void PrintConsole(string message)
{
Console.SetCursorPosition(bottom.X1, bottom.Y + 1);
Console.WriteLine(message);
}
void PrintConsole(string[] s)
{
Console.BackgroundColor = ConsoleColor.Black;
for (int i = 0; i < s.Length; i++)
{
Console.SetCursorPosition(top.X1, top.Y + i);
Console.WriteLine(s[i]);
}
}
private Position[][] GenerateGameBoard(Position[][] grid, double chance)
{
int xCounter = 0;
for (int y = 0; y < grid.Length; y++)
{
grid[y] = new Position[width];
for (int x = 0; x < grid[y].Length; x++)
{
if (x == 0 || x == grid[y].Length - 1 || y == 0 || y == grid.Length - 1 ||
new Random().NextDouble() <= chance)
{
grid[y][x] = new Position(xCounter++ + leftMargin, xCounter++ + leftMargin, y + topMargin, true);
}
else
{
grid[y][x] = new Position(xCounter++ + leftMargin, xCounter++ + leftMargin, y + topMargin, false);
}
}
xCounter = 0;
}
return grid;
}
}
+83
View File
@@ -0,0 +1,83 @@
namespace Snake
{
/// <summary>
/// Represents the in-game snake, which traverses the 2D array of Positions.
/// </summary>
public class Snake
{
private Queue<Position> body;
private int n;
private int capacity;
private Position[][] grid;
private bool Collided;
public Snake(Position[][] grid, int capacity)
{
this.grid = grid;
this.capacity = capacity;
n = 0;
Collided = false;
body = new Queue<Position>();
}
public bool Move()
{
Console.ForegroundColor = ConsoleColor.Black;
int x = 1;
int y = grid.Length / 2;
int direction = 0;
while (!Collided && x < grid[0].Length - 1 && y < grid.Length - 1 && x > 0 && y > 0)
{
if (Console.KeyAvailable)
{
char d = Console.ReadKey().KeyChar;
switch (d)
{
case 'w':
direction = 1;
break;
case 'a':
direction = 2;
break;
case 's':
direction = 3;
break;
case 'd':
direction = 0;
break;
}
}
Console.SetCursorPosition(grid[y][x].X1, grid[y][x].Y);
grid[y][x].Draw(false);
switch (direction)
{
case 0: // move right
x++;
break;
case 1: // move up
y--;
break;
case 2: // move left
x--;
break;
case 3: // move down
y++;
break;
}
if (grid[y][x].SnakeKiller)
{
Console.SetCursorPosition(grid[0][0].X1, grid[grid.Length - 1][0].Y + 1);
Console.ForegroundColor = ConsoleColor.White;
return false;
}
body.Enqueue(grid[y][x]);
body.Dequeue();
grid[y][x].Snake = true;
Thread.Sleep(150);
}
Console.ForegroundColor = ConsoleColor.White;
return true;
}
}
}
+10
View File
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>