Skip to content

Instantly share code, notes, and snippets.

@NoobInTraining
Created November 15, 2016 12:20
Show Gist options
  • Save NoobInTraining/37617b29c3f5d1a4e8f34c1ee52406a9 to your computer and use it in GitHub Desktop.
Save NoobInTraining/37617b29c3f5d1a4e8f34c1ee52406a9 to your computer and use it in GitHub Desktop.
My snake from back in the day
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
namespace SnakeV2
{
class Program
{
/// <summary>
/// Das Spielfeld.
/// 0 = Leer
/// 1 = Spieler
/// 2 = Essen
/// </summary>
static volatile int[,] aSpielFeld;
/// <summary> Boolean value wich is used by the nested class SpielfedAusgabe </summary>
static bool bGameNotover;
/// <summary> The speed the user chooses. <summary>
static volatile int iSpeed;
/// <summary>
/// Stores the direktion the sake is moving at the moment
/// a - left
/// s - down
/// w - up
/// d - right
/// </summary>
static volatile char cCurrentDirection;
/// <summary> char, to determin the next wanted movement.</summary>
static volatile char cNextDirection;
static int iIPositionOfPlayer;
static int iJPositionOfPlayer;
static int iIPositionOfFood;
static int iJPositionOfFood;
//The Random Number generator
static Random objRandomNumber = new Random();
static List<string> lSnakePositions;
static bool bUserWantsGame = true;
//The highscore and current score
static int iHighscore;
static volatile int iCurrentScore;
static void Main(string[] args)
{
while(true)
{
werteInitalisieren();
//Varialben für die Spielfeldausgabe
SpielfeldausgabeUndBerechnung objAusgabe = new SpielfeldausgabeUndBerechnung();
Thread tCalcPositionAndPrintField = new Thread(objAusgabe.ausgabeAndMove);
tCalcPositionAndPrintField.Name = "tCalcPositionAndPrintField";
tCalcPositionAndPrintField.IsBackground = true;
tCalcPositionAndPrintField.Start();
//Variblen um die bewegung bom benutzer einzulseen
Thread tReadInClient = new Thread(readInMovement);
tReadInClient.Name = "Console Input Thread";
tReadInClient.IsBackground = true;
tReadInClient.Start();
while (bUserWantsGame && bGameNotover)
{
Thread.Sleep(((int) iSpeed / 2));
}
//end the thread forcefully
try
{
if (tReadInClient.IsAlive)
tReadInClient.Abort();
}
catch(Exception)
{
//DO not work with the exception
}
if(bGameNotover == false)
printGameOver();
writeHighScore();
Console.WriteLine("New game? (y/n)");
ConsoleKeyInfo cki = Console.ReadKey();
//read in cki, untill its is set to eithwe y, n or escape
while(cki .Key != ConsoleKey.Y && cki.Key != ConsoleKey.Escape && cki.Key != ConsoleKey.N)
cki = Console.ReadKey();
if (cki.Key == ConsoleKey.N || cki.Key == ConsoleKey.Escape)
break;
Console.Clear();
}
}
/// <summary>
/// Method to read in th movement
/// </summary>
public static void readInMovement()
{
while (bUserWantsGame && bGameNotover)
{
//Read in Console input
ConsoleKeyInfo ckiTaste = Console.ReadKey();
//analyse console input
if ((ckiTaste.Key == ConsoleKey.W || ckiTaste.Key == ConsoleKey.UpArrow) && cCurrentDirection != 'w')
cNextDirection = 's';
else if ((ckiTaste.Key == ConsoleKey.D || ckiTaste.Key == ConsoleKey.RightArrow) && cCurrentDirection != 'a')
cNextDirection = 'd';
else if ((ckiTaste.Key == ConsoleKey.S || ckiTaste.Key == ConsoleKey.DownArrow) && cCurrentDirection != 's')
cNextDirection = 'w';
else if ((ckiTaste.Key == ConsoleKey.A || ckiTaste.Key == ConsoleKey.LeftArrow) && cCurrentDirection != 'd')
cNextDirection = 'a';
else if (ckiTaste.Key == ConsoleKey.Escape)
Environment.Exit(0);
}
}
private static void printGameOver()
{
Thread.Sleep(300);
Console.WriteLine("" + "------------------------------------------------------------------------\n" + "| |");
Thread.Sleep(300);
Console.Write("" + "| G |"); //End here: |
Thread.Sleep(300);
Console.Write("\r" + "| Ga |"); //End here: |
Thread.Sleep(300);
Console.Write("\r" + "| Gam |"); //End here: |
Thread.Sleep(300);
Console.Write("\r" + "| Game |"); //End here: |
Thread.Sleep(300);
Console.Write("\r" + "| Game O |"); //End here: |
Thread.Sleep(300);
Console.Write("\r" + "| Game Ov |"); //End here: |
Thread.Sleep(300);
Console.Write("\r" + "| Game Ove |"); //End here: |
Thread.Sleep(300);
Console.Write("\r" + "| Game Over |"); //End here: |
Thread.Sleep(300);
Console.Write("\r" + "| Game Over! |\n"); //End here: |
Thread.Sleep(300);
Console.WriteLine("" + "| |\n" + "------------------------------------------------------------------------");
Console.WriteLine("\n");
Thread.Sleep(960);
}
/// <summary>
/// Methode welche (start) Werte initalisiert
/// </summary>
private static void werteInitalisieren()
{
readInHighScoreFile();
iCurrentScore = 0;
//Spielvatiablen sezen
setSpeed();
cCurrentDirection = 'w';
cNextDirection = '0';
lSnakePositions = new List<string>();
bGameNotover = true;
aSpielFeld = new int[8, 8];
//spieler setzten
iIPositionOfPlayer = 0;
iJPositionOfPlayer = 0;
aSpielFeld[0, 0] = 1;
//Essen setzten
setFoodAtRandomLocation();
//Erste Position im array setzten.
lSnakePositions.Add("0|0");
}
/// <summary>
/// Method that reads in the config.ini file
/// which actually only conatins highscores :D
/// </summary>
private static void readInHighScoreFile()
{
//set the bianry reader
BinaryReader brHighscore;
try
{
brHighscore = new BinaryReader(new FileStream("highscores.ini", FileMode.OpenOrCreate));
}
catch(Exception eAny)
{
System.Diagnostics.Debug.WriteLine("Somehing bad happend! : " + eAny.Message);
System.Diagnostics.Debug.WriteLine(eAny.StackTrace);
return;
}
try
{
iHighscore = brHighscore.ReadInt16();
}
catch(Exception)
{
iHighscore = 0;
}
brHighscore.Close();
}
/// <summary>
/// Writes to the config.ini file the highscore
/// </summary>
private static void writeHighScore()
{
if (iCurrentScore > iHighscore)
iHighscore = iCurrentScore;
//set the bianry reader
BinaryWriter bwHighscore;
try
{
bwHighscore = new BinaryWriter(new FileStream("highscores.ini", FileMode.Create));
}
catch (Exception eAny)
{
System.Diagnostics.Debug.WriteLine("Somehing bad happend! : " + eAny.Message);
System.Diagnostics.Debug.WriteLine(eAny.StackTrace);
return;
}
try
{
Int16 ab = (short) iHighscore;
bwHighscore.Write(ab);
}
catch (Exception){}
bwHighscore.Close();
}
private static void setSpeed()
{
//Prompt for speed setting
Console.WriteLine("Choose your speed, by typing in a number.\n"
+ "That number is than multiplied by 100 and is counted in ms.\n\t" + "Eg: 1 would be 100ms = 0.1s refresh time\n\t"
+ " 5 would be 500ms = 0.5s refresh time\n\t"
+ " 10 would be 1000ms = 1s refresh time\n"
+ "To get used to it I would try 7.");
//Prompt the input, parse it to int
int iInput;
string sInput = Console.ReadLine();
try
{
iInput = int.Parse(sInput);
}
catch (Exception)
{
iInput = int.Parse(Regex.Replace(sInput, "\\D+", ""));
}
iInput = Math.Abs(iInput);
//set the speed and prompt about the informatio
iSpeed = iInput * 100;
Console.WriteLine("Setting the speed to " + (iSpeed) + "ms.");
//nice output b4 start
Console.Write("3...");
Thread.Sleep(500);
Console.Write("\r2...");
Thread.Sleep(500);
Console.Write("\r1...");
Thread.Sleep(500);
Console.Write("\rGO! \n");
Thread.Sleep(500);
}
/// <summary>
/// Sets the food at a new random location
/// </summary>
private static void setFoodAtRandomLocation()
{
//Generate the next random Number
int iIPosition = objRandomNumber.Next(0, 7);
int iJPosition = objRandomNumber.Next(0, 7);
while ((aSpielFeld[iIPosition, iJPosition] != 0) || (iJPositionOfFood != iJPosition && iIPositionOfFood != iIPosition))
{
iIPosition = objRandomNumber.Next(0, 7);
iJPosition = objRandomNumber.Next(0, 7);
}
//set the Position of the food the food
aSpielFeld[iIPosition, iJPosition] = 2;
//set the new positon of the food
iIPositionOfFood = iIPosition;
iJPositionOfFood = iJPosition;
}
/// <summary>
/// Nested-Klasse,
/// Welche die Spielfeldausgbae und die Steuerung auf dem benutzt wird.
/// </summary>
private class SpielfeldausgabeUndBerechnung
{
public bool bSnakeHasEatenItself = false;
/// <summary>
/// main Method of this class, to move the snake.
/// </summary>
public void ausgabeAndMove()
{
while(bGameNotover)
{
calculateNewPositon();
printField();
checkIfDead();
Thread.Sleep(iSpeed);
}
//when dead this sound will play
Console.Beep();
}
/// <summary>
/// Print the field again if the user killed himself
/// </summary>
private void checkIfDead()
{
string s = iIPositionOfPlayer + "|" + iJPositionOfPlayer;
if (lSnakePositions.LastIndexOf(s) != 0)
bGameNotover = false;
}
/// <summary>
/// Method that checks if the food has been eaten
/// </summary>
private bool checkIfFoodEaten()
{
if (iIPositionOfPlayer == iIPositionOfFood && iJPositionOfFood == iJPositionOfPlayer)
{
setFoodAtRandomLocation();
iCurrentScore++;
return true;
}
return false;
}
/// <summary>
/// Methode, welches über ein Thread Ausgerufen wird,
/// druckt das Spielfeld einmal aus und berechnet die neue position
/// </summary>
private static void printField()
{
Console.Clear();
Console.WriteLine(" 1 2 3 4 5 6 7 8");
for (int i = 0; i < 8; i++)
{
Console.Write("0" + (i + 1) + " ");
for (int j = 0; j < 8; j++)
{
switch(aSpielFeld[i, j])
{
//Leeres feld
case 0: Console.Write(" "); break;
//Spielerfeld
case 1: Console.Write("x "); break;
//Essens feld
case 2: Console.Write("v "); break;
//Speiler kopf
case 4: Console.Write("o "); break;
}
}
Console.WriteLine("");
}
Console.WriteLine("Your current score is:\t" + iCurrentScore + "\r\nThe Highscore is:\t" + iHighscore);
}
/// <summary>
/// Method which calculates the new position from
/// </summary>
private void calculateNewPositon()
{
//Delete old position in array
string sLastString = lSnakePositions[lSnakePositions.Count - 1];
int iIPosition = int.Parse(sLastString.Split('|')[0]);
int iJPosition = int.Parse(sLastString.Split('|')[1]);
aSpielFeld[iIPosition, iJPosition] = 0;
//Neue Position errechnen anhand der derzeitigen richtung
switch ((cNextDirection == '0')? cCurrentDirection: cNextDirection)
{
case 'a': if(--iJPositionOfPlayer < 0)
iJPositionOfPlayer = 7;
break;
case 's': if(--iIPositionOfPlayer < 0)
iIPositionOfPlayer = 7;
break;
case 'd': if(++iJPositionOfPlayer > 7)
iJPositionOfPlayer = 0;
break;
case 'w': if (++iIPositionOfPlayer > 7)
iIPositionOfPlayer = 0;
break;
}
if(cNextDirection != '0')
{
//Reset the current direction
cCurrentDirection = cNextDirection;
//and set the next wanted one to 0 again
cNextDirection = '0';
}
//if the food wasn't eaten, we can delete the last index
if (!checkIfFoodEaten())
lSnakePositions.RemoveAt(lSnakePositions.Count - 1);
//Method that jsut exist to make my snake look nicer - slow computer might have a poblems or the longer the array is is problem
setSnakeHeadAndBody();
//set the head
aSpielFeld[iIPositionOfPlayer, iJPositionOfPlayer] = 4;
//Add the new position and delete the last position of array
lSnakePositions.Insert(0, (iIPositionOfPlayer + "|" + iJPositionOfPlayer));
}
/// <summary>
/// Method that sets the 0 for the head
/// and the rest a 0
/// </summary>
private void setSnakeHeadAndBody()
{
int iIPosition;
int iJPosition;
foreach (string s in lSnakePositions.ToArray())
{
iIPosition = int.Parse(s.Split('|')[0]);
iJPosition = int.Parse(s.Split('|')[1]);
aSpielFeld[iIPosition, iJPosition] = 1;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment