diff --git a/.gitignore b/.gitignore index 64bb62d..b8d69cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ #Soundtrack data -Soundtrack.aup -Soundtrack_data/* +testexetrisathlon/*.wav -# Created by https://www.gitignore.io/api/csharp,visualstudio -# Edit at https://www.gitignore.io/?templates=csharp,visualstudio +# Created by https://www.gitignore.io/api/rider,csharp,visualstudio +# Edit at https://www.gitignore.io/?templates=rider,csharp,visualstudio ### Csharp ### ## Ignore Visual Studio temporary files, build results, and @@ -77,7 +76,6 @@ StyleCopReport.xml *_p.c *_h.h *.ilk -*.meta *.obj *.iobj *.pch @@ -357,6 +355,76 @@ healthchecksdb # Backup folder for Package Reference Convert tool in Visual Studio 2017 MigrationBackup/ +### Rider ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + ### VisualStudio ### # User-specific files @@ -513,4 +581,4 @@ MigrationBackup/ # Backup folder for Package Reference Convert tool in Visual Studio 2017 -# End of https://www.gitignore.io/api/csharp,visualstudio +# End of https://www.gitignore.io/api/rider,csharp,visualstudio diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.idea/.idea.testexetrisathlon/.idea/.gitignore b/.idea/.idea.testexetrisathlon/.idea/.gitignore new file mode 100644 index 0000000..0110b99 --- /dev/null +++ b/.idea/.idea.testexetrisathlon/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/.idea/.idea.testexetrisathlon/.idea/discord.xml b/.idea/.idea.testexetrisathlon/.idea/discord.xml new file mode 100644 index 0000000..59b11d1 --- /dev/null +++ b/.idea/.idea.testexetrisathlon/.idea/discord.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.testexetrisathlon/.idea/encodings.xml b/.idea/.idea.testexetrisathlon/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.testexetrisathlon/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.testexetrisathlon/.idea/indexLayout.xml b/.idea/.idea.testexetrisathlon/.idea/indexLayout.xml new file mode 100644 index 0000000..27ba142 --- /dev/null +++ b/.idea/.idea.testexetrisathlon/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.testexetrisathlon/.idea/modules.xml b/.idea/.idea.testexetrisathlon/.idea/modules.xml new file mode 100644 index 0000000..f09f486 --- /dev/null +++ b/.idea/.idea.testexetrisathlon/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.testexetrisathlon/.idea/projectSettingsUpdater.xml b/.idea/.idea.testexetrisathlon/.idea/projectSettingsUpdater.xml new file mode 100644 index 0000000..7515e76 --- /dev/null +++ b/.idea/.idea.testexetrisathlon/.idea/projectSettingsUpdater.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/.idea.testexetrisathlon/.idea/vcs.xml b/.idea/.idea.testexetrisathlon/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/.idea.testexetrisathlon/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/.idea.testexetrisathlon/riderModule.iml b/.idea/.idea.testexetrisathlon/riderModule.iml new file mode 100644 index 0000000..1a4e0d9 --- /dev/null +++ b/.idea/.idea.testexetrisathlon/riderModule.iml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/DownloadData.py b/DownloadData.py new file mode 100644 index 0000000..72700e4 --- /dev/null +++ b/DownloadData.py @@ -0,0 +1,51 @@ +import os +import os.path +import wave +import youtube_dl + + +os.chdir("testexetrisathlon") + +def dl_vid(url, outfile): + ydl_opts = { + 'outtmpl': outfile, + 'noplaylist': True, + 'continue_dl': True, + 'postprocessors': [{ + 'key': 'FFmpegExtractAudio', + 'preferredcodec': 'wav' }] + } + with youtube_dl.YoutubeDL(ydl_opts) as ydl: + ydl.download([url]) + +def merge_vids(infiles, outfile): + data= [] + for infile in infiles: + w = wave.open(infile + ".wav", 'rb') + data.append( [w.getparams(), w.readframes(w.getnframes())] ) + w.close() + os.remove(infile + ".wav") + + output = wave.open(outfile + ".wav", 'wb') + output.setparams(data[0][0]) + output.writeframes(data[0][1]) + output.writeframes(data[1][1]) + output.close() + +if not os.path.isfile("Intro.wav"): + dl_vid("https://youtu.be/U06jlgpMtQs", "Intro") + +if not os.path.isfile("InGame1.wav"): + dl_vid("https://youtu.be/hueJrl83sOQ", "st1") + dl_vid("https://youtu.be/7gSS4h47rLU", "st2") + dl_vid("https://youtu.be/NDjDgvXlfVw", "st3") + merge_vids(["st1", "st2", "st3"], "InGame1") + +if not os.path.isfile("InGame2.wav"): + dl_vid("https://youtu.be/umEDct4BoGc", "st1") + dl_vid("https://youtu.be/NVpjt9gHlDw", "st2") + dl_vid("https://youtu.be/zgKazTrhXmI", "st3") + merge_vids(["st1", "st2", "st3"], "InGame2") + +if not os.path.isfile("GameOver.wav"): + dl_vid("https://youtu.be/J_3Zad-e9f4", "GameOver") diff --git a/DownloadDataDepsInstall.py b/DownloadDataDepsInstall.py new file mode 100644 index 0000000..989db8a --- /dev/null +++ b/DownloadDataDepsInstall.py @@ -0,0 +1,8 @@ +import pkg_resources +from subprocess import call + + +packages = [dist.project_name for dist in pkg_resources.working_set] +if not "youtube-dl" in packages: + packages += ["youtube-dl"] +call("pip install --upgrade " + ' '.join(packages), shell=True) \ No newline at end of file diff --git a/README.md b/README.md index a0b82c9..2400877 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # testexetrisathlon +To download the files required for building, just run DownloadData.py +If you don't have youtube-dl installed (or it is outdated), just run DownloadDataDepsInstall.py \ No newline at end of file diff --git a/testexetrisathlon.sln.DotSettings b/testexetrisathlon.sln.DotSettings new file mode 100644 index 0000000..7e09a56 --- /dev/null +++ b/testexetrisathlon.sln.DotSettings @@ -0,0 +1,5 @@ + + True + True + True + True \ No newline at end of file diff --git a/testexetrisathlon/GameOver.wav b/testexetrisathlon/GameOver.wav deleted file mode 100644 index b4e25f1..0000000 Binary files a/testexetrisathlon/GameOver.wav and /dev/null differ diff --git a/testexetrisathlon/InGame.wav b/testexetrisathlon/InGame.wav deleted file mode 100644 index 39995c5..0000000 Binary files a/testexetrisathlon/InGame.wav and /dev/null differ diff --git a/testexetrisathlon/Intro.wav b/testexetrisathlon/Intro.wav deleted file mode 100644 index ff35eda..0000000 Binary files a/testexetrisathlon/Intro.wav and /dev/null differ diff --git a/testexetrisathlon/Program.cs b/testexetrisathlon/Program.cs index 7d85628..abc0515 100644 --- a/testexetrisathlon/Program.cs +++ b/testexetrisathlon/Program.cs @@ -1,6 +1,8 @@ -using System; -using System.Linq; +#define WINDOWS + +using System; using System.Diagnostics; +using System.Linq; using System.Media; using System.Reflection; using System.Runtime.InteropServices; @@ -27,95 +29,74 @@ using static System.Console; namespace testexetrisathlon { - class Program + internal static class Program { + public const string Sqr = "■"; + public static int[,] Grid = new int[23, 10]; + public static int[,] DroppedTetrominoeLocationGrid = new int[23, 10]; + private static Stopwatch _dropTimer = new Stopwatch(); + private static int _dropTime; + private static int _dropRate = 300; + public static bool IsDropped; + private static Tetrominoe _tet; + private static Tetrominoe _nextTet; + private static ConsoleKeyInfo _key; + private static bool _isKeyPressed; + private static int _linesCleared; + private static int _score; + private static int _level = 1; + private static readonly Assembly Assembly = Assembly.GetExecutingAssembly(); + private static readonly ConsoleColor[] Colors = {BackgroundColor, ForegroundColor}; + public static bool Debug; + public static readonly Random Rnd = new Random(); + private static readonly SoundPlayer Intro = + new SoundPlayer(Assembly.GetManifestResourceStream("testexetrisathlon.Intro.wav")); + private static readonly SoundPlayer InGame1 = + new SoundPlayer(Assembly.GetManifestResourceStream("testexetrisathlon.InGame1.wav")); + private static readonly SoundPlayer InGame2 = + new SoundPlayer(Assembly.GetManifestResourceStream("testexetrisathlon.InGame2.wav")); + private static readonly SoundPlayer GameOver = + new SoundPlayer(Assembly.GetManifestResourceStream("testexetrisathlon.GameOver.wav")); + private static SoundPlayer _inGame = SettingsMan.UsingAltTrack ? InGame2 : InGame1; +#if WINDOWS [DllImport("winmm.dll")] - static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume); + private static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume); +#endif - [DllImport("winmm.dll")] - static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume); - public static string sqr = "■"; - public static int[,] grid = new int[23, 10]; - public static int[,] droppedtetrominoeLocationGrid = new int[23, 10]; - public static Stopwatch dropTimer = new Stopwatch(); - public static Stopwatch inputTimer = new Stopwatch(); - public static int dropTime, dropRate = 300; - public static bool isDropped = false; - static Tetrominoe tet; - static Tetrominoe nexttet; - public static ConsoleKeyInfo key; - public static bool isKeyPressed = false; - public static int linesCleared = 0, score = 0, level = 1; - static readonly Assembly assembly = Assembly.GetExecutingAssembly(); - static ConsoleColor[] colors; - public static bool debug; - public static Random rnd; - static void Main(string[] args) +#if DEBUG + private static void Main() { - rnd = new Random(); - colors = new ConsoleColor[2] { BackgroundColor, ForegroundColor }; + Debug = true; +#else + private static void Main(string[] args) + { + Debug = args.Contains("debug"); +#endif BackgroundColor = ConsoleColor.Red; ForegroundColor = ConsoleColor.Yellow; SetWindowSize(42, 29); SetCursorPosition(0, 0); Clear(); -#if (DEBUG) - debug = true; -#else - debug = args.Contains("debug"); -#endif - if (debug) + if (Debug) SetWindowSize(50, 40); - new Program().MainN( - new SoundPlayer(assembly.GetManifestResourceStream("testexetrisathlon.Intro.wav")), - new SoundPlayer(assembly.GetManifestResourceStream("testexetrisathlon.InGame.wav")), - new SoundPlayer(assembly.GetManifestResourceStream("testexetrisathlon.GameOver.wav"))); - BackgroundColor = colors[0]; - ForegroundColor = colors[1]; - SetCursorPosition(0, 0); - Clear(); - } - enum GameState { exit, menu, game, gameOver } - static void DrawSymbol() - { - SetCursorPosition(0, 1); - Write( - " ▀▀▀██████▄▄▄\r\n" + - " ▀▀▀████▄\r\n" + - " ▄███████▀ ▀███▄\r\n" + - " ▄███████▀ ▀███▄\r\n" + - " ▄████████ ███▄\r\n" + - " ██████████▄ ███▌\r\n" + - " ▀█████▀ ▀███▄ ▐███\r\n" + - " ▀█▀ ▀███▄ ▐███\r\n" + - " ▀███▄ ███▌\r\n" + - " ▄██▄ ▀███▄ ▐███\r\n" + - " ▄██████▄ ▀███▄███\r\n" + - " █████▀▀████▄▄ ▄█████\r\n" + - " ████▀ ▀▀█████▄▄▄▄█████████▄\r\n" + - " ▀▀ ▀▀██████▀▀ ▀▀██\r\n\r\n" + - - " testexetrisathlon v." + assembly.GetName().Version.ToString()); - } - void MainN(SoundPlayer intro, SoundPlayer inGame, SoundPlayer gameOver) - { - int NewVolume = (ushort.MaxValue / 10) * SettingsMan.Volume; - waveOutSetVolume(IntPtr.Zero, ((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16)); +#if WINDOWS + int newVolume = (ushort.MaxValue / 10) * SettingsMan.Volume; + waveOutSetVolume(IntPtr.Zero, ((uint) newVolume & 0x0000ffff) | ((uint) newVolume << 16)); +#endif bool playing = true; - GameState state = GameState.menu; + GameState state = GameState.Menu; try { while (playing) - { switch (state) { - case GameState.menu: + case GameState.Menu: Clear(); - gameOver.Stop(); - intro.PlayLooping(); + GameOver.Stop(); + Intro.PlayLooping(); DrawSymbol(); SetCursorPosition(12, 18); - Write("Highscore: " + SettingsMan.HighScore.ToString()); + Write("HighScore: " + SettingsMan.HighScore); SetCursorPosition(12, 20); Write("Controls: Space"); SetCursorPosition(13, 21); @@ -134,43 +115,43 @@ namespace testexetrisathlon switch (tmp) { case "s": - intro.Stop(); - state = GameState.game; + Intro.Stop(); + state = GameState.Game; Clear(); DrawBorder(); break; case "x": - state = GameState.exit; + state = GameState.Exit; break; case "v": - VolumeSlider(); + SettingsMenu(); break; } break; - case GameState.game: - inGame.PlayLooping(); - dropTimer.Start(); + case GameState.Game: + _inGame.PlayLooping(); + _dropTimer.Start(); SetCursorPosition(25, 0); - WriteLine("Level " + level); + WriteLine("Level " + _level); SetCursorPosition(25, 1); - WriteLine("Score " + score + "/" + (Math.Pow(level, 2) * 100).ToString()); + WriteLine("Score " + _score + "/" + (Math.Pow(_level, 2) * 100)); SetCursorPosition(25, 2); - WriteLine("LinesCleared " + linesCleared); + WriteLine("LinesCleared " + _linesCleared); SetCursorPosition(25, 4); - WriteLine("Highscore " + SettingsMan.HighScore); - nexttet = new Tetrominoe(); - tet = nexttet; - tet.Spawn(); - nexttet = new Tetrominoe(); + WriteLine("HighScore " + SettingsMan.HighScore); + _nextTet = new Tetrominoe(); + _tet = _nextTet; + _tet.Spawn(); + _nextTet = new Tetrominoe(); Update(); - inGame.Stop(); - state = GameState.gameOver; + _inGame.Stop(); + state = GameState.GameOver; break; - case GameState.gameOver: - SettingsMan.HighScore = score; - gameOver.PlayLooping(); + case GameState.GameOver: + SettingsMan.HighScore = _score; + GameOver.PlayLooping(); string input = ""; - while ((input != "y") && (input != "n")) + while (input != "y" && input != "n") { Clear(); DrawBorder(); @@ -182,87 +163,148 @@ namespace testexetrisathlon WriteLine("├───────────────────┤"); input = ReadKey().KeyChar.ToString().ToLower(); } - grid = new int[23, 10]; - droppedtetrominoeLocationGrid = new int[23, 10]; - dropTimer = new Stopwatch(); - inputTimer = new Stopwatch(); - dropRate = 300; - isDropped = false; - isKeyPressed = false; - linesCleared = 0; - score = 0; - level = 1; + Grid = new int[23, 10]; + DroppedTetrominoeLocationGrid = new int[23, 10]; + _dropTimer = new Stopwatch(); + _dropRate = 300; + IsDropped = false; + _isKeyPressed = false; + _linesCleared = 0; + _score = 0; + _level = 1; GC.Collect(); Clear(); DrawBorder(); - if (input == "y") - state = GameState.game; - else - state = GameState.menu; + state = input == "y" ? GameState.Game : GameState.Menu; break; - default: + case GameState.Exit: playing = false; break; + default: throw new ArgumentOutOfRangeException(); } - } } finally { - intro.Dispose(); - inGame.Dispose(); - gameOver.Dispose(); + Intro.Dispose(); + InGame1.Dispose(); + InGame2.Dispose(); + GameOver.Dispose(); } + BackgroundColor = Colors[0]; + ForegroundColor = Colors[1]; + SetCursorPosition(0, 0); + Clear(); } - static void VolumeSlider() + private static void DrawSymbol() + { + SetCursorPosition(0, 1); + Write( + " ▀▀▀██████▄▄▄\r\n" + + " ▀▀▀████▄\r\n" + + " ▄███████▀ ▀███▄\r\n" + + " ▄███████▀ ▀███▄\r\n" + + " ▄████████ ███▄\r\n" + + " ██████████▄ ███▌\r\n" + + " ▀█████▀ ▀███▄ ▐███\r\n" + + " ▀█▀ ▀███▄ ▐███\r\n" + + " ▀███▄ ███▌\r\n" + + " ▄██▄ ▀███▄ ▐███\r\n" + + " ▄██████▄ ▀███▄███\r\n" + + " █████▀▀████▄▄ ▄█████\r\n" + + " ████▀ ▀▀█████▄▄▄▄█████████▄\r\n" + + " ▀▀ ▀▀██████▀▀ ▀▀██\r\n\r\n" + + " testexetrisathlon v." + Assembly.GetName().Version); + } + + private static void SettingsMenu() { Clear(); DrawSymbol(); +#if !WINDOWS + SetCursorPosition(2, 19); + Write("Volume is not supported in this build!"); +#endif bool barActive = true; + int currentSetting = 0; while (barActive) { + bool curr = SettingsMan.UsingAltTrack; SetCursorPosition(3, 20); - Write("Volume: " + new string('=', SettingsMan.Volume * 2) + "[" + SettingsMan.Volume.ToString("00") + "]" + new string('=', 20 - (SettingsMan.Volume * 2))); - switch (ReadKey().Key) + ForegroundColor = currentSetting == 0 ? ConsoleColor.White : ConsoleColor.Yellow; + Write("Volume: " + new string('=', SettingsMan.Volume * 2) + "[" + SettingsMan.Volume.ToString("00") + + "]" + new string('=', 20 - (SettingsMan.Volume * 2))); + SetCursorPosition(5, 22); + ForegroundColor = currentSetting == 1 ? ConsoleColor.White : ConsoleColor.Yellow; + Write($"{(curr ? " Using" : "Not using")} alternative soundtrack "); + ForegroundColor = ConsoleColor.Yellow; + switch (currentSetting) { - case ConsoleKey.LeftArrow: - SettingsMan.Volume--; + case 0: + switch (ReadKey().Key) + { + case ConsoleKey.LeftArrow: + SettingsMan.Volume--; + break; + case ConsoleKey.RightArrow: + SettingsMan.Volume++; + break; + case ConsoleKey.Enter: + barActive = false; + break; + case ConsoleKey.Tab: + currentSetting = 1; + break; + } break; - case ConsoleKey.RightArrow: - SettingsMan.Volume++; - break; - case ConsoleKey.Enter: - barActive = false; + case 1: + switch (ReadKey().Key) + { + case ConsoleKey.LeftArrow: + case ConsoleKey.RightArrow: + case ConsoleKey.Spacebar: + SettingsMan.UsingAltTrack = !curr; + break; + case ConsoleKey.Enter: + barActive = false; + break; + case ConsoleKey.Tab: + currentSetting = 0; + break; + } break; } - int NewVolume = (ushort.MaxValue / 10) * SettingsMan.Volume; - waveOutSetVolume(IntPtr.Zero, ((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16)); +#if WINDOWS + int newVolume = (ushort.MaxValue / 10) * SettingsMan.Volume; + waveOutSetVolume(IntPtr.Zero, ((uint) newVolume & 0x0000ffff) | ((uint) newVolume << 16)); +#endif + _inGame = SettingsMan.UsingAltTrack ? InGame2 : InGame1; } } - static void Update() + private static void Update() { while (true) { - dropTime = (int)dropTimer.ElapsedMilliseconds; - if (dropTime > dropRate) + _dropTime = (int) _dropTimer.ElapsedMilliseconds; + if (_dropTime > _dropRate) { - dropTime = 0; dropTimer.Restart(); tet.Drop(); + _dropTime = 0; + _dropTimer.Restart(); + _tet.Drop(); } - if (isDropped == true) + if (IsDropped) { - tet = nexttet; - nexttet = new Tetrominoe(); - tet.Spawn(); - isDropped = false; - score += 10; + _tet = _nextTet; + _nextTet = new Tetrominoe(); + _tet.Spawn(); + IsDropped = false; + _score += 10; } for (int j = 0; j < 10; j++) - { - if (droppedtetrominoeLocationGrid[0, j] == 1) + if (DroppedTetrominoeLocationGrid[0, j] == 1) return; - } - if (debug) + if (Debug) { SetCursorPosition(0, 25); WriteLine("!DEBUG MODE ENABLED!"); @@ -271,100 +313,89 @@ namespace testexetrisathlon ClearBlock(); } } - static void ClearBlock() + + private static void ClearBlock() { int combo = 0; for (int i = 0; i < 23; i++) - { - if (Enumerable.Range(0, 10).Where(s => droppedtetrominoeLocationGrid[i, s] == 0).Count() == 0) + if (Enumerable.Range(0, 10).All(s => DroppedTetrominoeLocationGrid[i, s] != 0)) { - linesCleared++; + _linesCleared++; combo++; Beep(400, 200); - for (int j = 0; j < 10; j++) - { - droppedtetrominoeLocationGrid[i, j] = 0; - } - int[,] newdroppedtetrominoeLocationGrid = new int[23, 10]; + for (int j = 0; j < 10; j++) DroppedTetrominoeLocationGrid[i, j] = 0; + int[,] newDroppedTetrominoeLocationGrid = new int[23, 10]; for (int k = 1; k < i; k++) - { - for (int l = 0; l < 10; l++) - { - newdroppedtetrominoeLocationGrid[k + 1, l] = droppedtetrominoeLocationGrid[k, l]; - } - } + for (int l = 0; l < 10; l++) + newDroppedTetrominoeLocationGrid[k + 1, l] = DroppedTetrominoeLocationGrid[k, l]; for (int k = 1; k < i; k++) - { - for (int l = 0; l < 10; l++) - { - droppedtetrominoeLocationGrid[k, l] = 0; - } - } + for (int l = 0; l < 10; l++) + DroppedTetrominoeLocationGrid[k, l] = 0; for (int k = 0; k < 23; k++) - for (int l = 0; l < 10; l++) - if (newdroppedtetrominoeLocationGrid[k, l] == 1) - droppedtetrominoeLocationGrid[k, l] = 1; + for (int l = 0; l < 10; l++) + if (newDroppedTetrominoeLocationGrid[k, l] == 1) + DroppedTetrominoeLocationGrid[k, l] = 1; Draw(); } - } - score += (int)Math.Round(Math.Sqrt(Math.Max((combo * 50) - 50, 0)) * 5); - level = (int)Math.Round(Math.Sqrt(score * 0.01)) + 1; - dropRate = 300 - (22 * level); + _score += (int) Math.Round(Math.Sqrt(Math.Max((combo * 50) - 50, 0)) * 5); + _level = (int) Math.Round(Math.Sqrt(_score * 0.01)) + 1; + _dropRate = 300 - (22 * _level); } - static void Input() + + private static void Input() { - isKeyPressed = KeyAvailable; + _isKeyPressed = KeyAvailable; SetCursorPosition(0, 24); - if (isKeyPressed) - key = ReadKey(); - if (key.Key == ConsoleKey.LeftArrow & !tet.isSomethingLeft() & isKeyPressed) + if (_isKeyPressed) + _key = ReadKey(); + if ((_key.Key == ConsoleKey.LeftArrow) & !_tet.IsSomethingLeft() & _isKeyPressed) { for (int i = 0; i < 4; i++) - tet.location[i][1] -= 1; - tet.Update(); + _tet.Location[i][1] -= 1; + _tet.Update(); } - else if (key.Key == ConsoleKey.RightArrow & !tet.isSomethingRight() & isKeyPressed) + else if ((_key.Key == ConsoleKey.RightArrow) & !_tet.IsSomethingRight() & _isKeyPressed) { for (int i = 0; i < 4; i++) - tet.location[i][1] += 1; - tet.Update(); + _tet.Location[i][1] += 1; + _tet.Update(); } - if (key.Key == ConsoleKey.DownArrow & isKeyPressed) - tet.Drop(); - if (key.Key == ConsoleKey.UpArrow & isKeyPressed) - for (; tet.isSomethingBelow!= true;) - tet.Drop(); - if (key.Key == ConsoleKey.Spacebar & isKeyPressed) + if ((_key.Key == ConsoleKey.DownArrow) & _isKeyPressed) + _tet.Drop(); + if ((_key.Key == ConsoleKey.UpArrow) & _isKeyPressed) + for (; _tet.IsSomethingBelow != true;) + _tet.Drop(); + if ((_key.Key == ConsoleKey.Spacebar) & _isKeyPressed) { - tet.Rotate(); - tet.Update(); + _tet.Rotate(); + _tet.Update(); } } + public static void Draw() { for (int i = 0; i < 23; ++i) + for (int j = 0; j < 10; j++) { - for (int j = 0; j < 10; j++) + SetCursorPosition((2 * j) + 1, i); + if ((Grid[i, j] == 1) | (DroppedTetrominoeLocationGrid[i, j] == 1)) { SetCursorPosition((2 * j) + 1, i); - if (grid[i, j] == 1 | droppedtetrominoeLocationGrid[i, j] == 1) - { - SetCursorPosition((2 * j) + 1, i); - Write(sqr); - } - else - { - Write(" "); - } + Write(Sqr); + } + else + { + Write(" "); } } SetCursorPosition(25, 0); - WriteLine("Level " + level); + WriteLine("Level " + _level); SetCursorPosition(25, 1); - WriteLine("Score " + score + "/" + (Math.Pow(level, 2) * 100).ToString()); + WriteLine("Score " + _score + "/" + (Math.Pow(_level, 2) * 100)); SetCursorPosition(25, 2); - WriteLine("LinesCleared " + linesCleared); + WriteLine("LinesCleared " + _linesCleared); } + public static void DrawBorder() { for (int lengthCount = 0; lengthCount <= 22; lengthCount++) @@ -376,11 +407,16 @@ namespace testexetrisathlon } SetCursorPosition(0, 23); Write("└"); - for (int widthCount = 0; widthCount <= 18; widthCount++) - { - Write("─"); - } + for (int widthCount = 0; widthCount <= 18; widthCount++) Write("─"); Write("┘"); } + + private enum GameState + { + Exit, + Menu, + Game, + GameOver + } } -} +} \ No newline at end of file diff --git a/testexetrisathlon/Properties/AssemblyInfo.cs b/testexetrisathlon/Properties/AssemblyInfo.cs index dd7c139..458d9dd 100644 --- a/testexetrisathlon/Properties/AssemblyInfo.cs +++ b/testexetrisathlon/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; // Information about this assembly is defined by the following attributes. // Change them to the values specific to your project. @@ -23,4 +22,4 @@ using System.Runtime.CompilerServices; // if desired. See the Mono documentation for more information about signing. //[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] +//[assembly: AssemblyKeyFile("")] \ No newline at end of file diff --git a/testexetrisathlon/SettingsMan.cs b/testexetrisathlon/SettingsMan.cs index 93e8d6b..1942bdc 100644 --- a/testexetrisathlon/SettingsMan.cs +++ b/testexetrisathlon/SettingsMan.cs @@ -1,56 +1,65 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Reflection; -using System.Text; -using System.Threading.Tasks; using System.Xml.Linq; namespace testexetrisathlon { - static class SettingsMan + internal static class SettingsMan { - static XElement doc; - static string xmlfile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Save.xml"; + private static readonly string XmlFile = + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Save.xml"); + public static int Volume { - get { - if (doc == null) - Load(); - return toRange(int.Parse(doc.Element("Save").Element("Volume").Value), 0, 10); + get => ToRange(int.Parse(Load().Element("Volume").Value), 0, 10); + set + { + XElement doc = Load(); + doc.Element("Volume").Value = ToRange(value, 0, 10).ToString(); + doc.Save(); } - set { - doc.Element("Save").Element("Volume").Value = toRange(value, 0, 10).ToString(); - Save(); - } - } - public static int HighScore - { - get { - if (doc == null) - Load(); - return int.Parse(doc.Element("Save").Element("HighScore").Value); - } - set { - doc.Element("Save").Element("HighScore").Value = value.ToString(); - Save(); - } - } - static void Save() => doc.Save(xmlfile); - static void Load() - { - if (!File.Exists(xmlfile)) - new XElement("Save", new XElement("Volume", 10), new XElement("HighScore", 0)).Save(xmlfile); - doc = XDocument.Load(xmlfile).Root; - if (doc.Element("Save") == null) - doc.Add(new XElement("Save")); - if (doc.Element("Save").Element("Volume") == null) - doc.Element("Save").Add(new XElement("Volume", 10)); - if (doc.Element("Save").Element("HighScore") == null) - doc.Element("Save").Add(new XElement("HighScore", 10)); } - static int toRange(int value, int rangeStart, int rangeEnd) => Math.Min(Math.Max(value, rangeStart), rangeEnd); + public static int HighScore + { + get => int.Parse(Load().Element("HighScore").Value); + set + { + XElement doc = Load(); + doc.Element("HighScore").Value = value.ToString(); + doc.Save(); + } + } + + public static bool UsingAltTrack + { + get => bool.Parse(Load().Element("AltTrack").Value); + set + { + XElement doc = Load(); + doc.Element("AltTrack").Value = value.ToString(); + doc.Save(); + } + } + + private static void Save(this XElement doc) => doc.Save(XmlFile); + + private static XElement Load() + { + if (!File.Exists(XmlFile)) + new XElement("Save").Save(XmlFile); + XElement doc = XDocument.Load(XmlFile).Root; + if (doc.Element("Volume") == null) + doc.Add(new XElement("Volume", 10)); + if (doc.Element("HighScore") == null) + doc.Add(new XElement("HighScore", 10)); + if (doc.Element("AltTrack") == null) + doc.Add(new XElement("AltTrack", false)); + return doc; + } + + private static int ToRange(int value, int rangeStart, int rangeEnd) => + Math.Min(Math.Max(value, rangeStart), rangeEnd); } -} +} \ No newline at end of file diff --git a/testexetrisathlon/Tetrominoe.cs b/testexetrisathlon/Tetrominoe.cs index 1c380f0..c91aa1c 100644 --- a/testexetrisathlon/Tetrominoe.cs +++ b/testexetrisathlon/Tetrominoe.cs @@ -1,184 +1,202 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Security; using static System.Console; -#pragma warning disable IDE1006 + namespace testexetrisathlon { public class Tetrominoe { - public static int[,] I = new int[1, 4] { { 1, 1, 1, 1 } }; + private static readonly int[,] I = {{1, 1, 1, 1}}; - public static int[,] O = new int[2, 2] { { 1, 1 }, - { 1, 1 } }; + private static readonly int[,] O = + { + {1, 1}, + {1, 1} + }; - public static int[,] T = new int[2, 3] { { 0, 1, 0 }, - { 1, 1, 1 } }; + private static readonly int[,] T = + { + {0, 1, 0}, + {1, 1, 1} + }; - public static int[,] S = new int[2, 3] { { 0, 1, 1 }, - { 1, 1, 0 } }; + private static readonly int[,] S = + { + {0, 1, 1}, + {1, 1, 0} + }; - public static int[,] Z = new int[2, 3] { { 1, 1, 0 }, - { 0, 1, 1 } }; + private static readonly int[,] Z = + { + {1, 1, 0}, + {0, 1, 1} + }; - public static int[,] J = new int[2, 3] { { 1, 0, 0 }, - { 1, 1, 1 } }; + private static readonly int[,] J = + { + {1, 0, 0}, + {1, 1, 1} + }; + + private static readonly int[,] L = + { + {0, 0, 1}, + {1, 1, 1} + }; + + private static readonly List TetrominoeList = new List {I, O, T, S, Z, J, L}; + private readonly int[,] _shape; + public List Location = new List(); - public static int[,] L = new int[2, 3] { { 0, 0, 1 }, - { 1, 1, 1 } }; - public static List tetrominoes = new List() { I, O, T, S, Z, J, L }; - private readonly int[,] shape; - public List location = new List(); public Tetrominoe() { - shape = tetrominoes[Program.rnd.Next(0, tetrominoes.Count)]; + _shape = TetrominoeList[Program.Rnd.Next(0, TetrominoeList.Count)]; for (int i = 0; i < 7; i++) + for (int j = 0; j < 2; j++) { - for (int j = 0; j < 2; j++) - { - SetCursorPosition(i + 26, j + 6); - Write(Program.debug ? "X" : " "); - } + SetCursorPosition(i + 26, j + 6); + Write(Program.Debug ? "X" : " "); } Program.DrawBorder(); - for (int i = 0; i < shape.GetLength(0); i++) - { - for (int j = 0; j < shape.GetLength(1); j++) + for (int i = 0; i < _shape.GetLength(0); i++) + for (int j = 0; j < _shape.GetLength(1); j++) + if (_shape[i, j] == 1) { - if (shape[i, j] == 1) - { - SetCursorPosition(30 - shape.GetLength(1) + (2 * j), i + 6); - Write(Program.sqr); - } + SetCursorPosition((30 - _shape.GetLength(1)) + (2 * j), i + 6); + Write(Program.Sqr); } - } } + + public bool IsSomethingBelow => Location.Any(s => s[0] + 1 >= 23 || (s[0] + 1 < 23) & + (Program.DroppedTetrominoeLocationGrid[s[0] + 1, s[1]] == 1)); + public void Spawn() { - for (int i = 0; i < shape.GetLength(0); i++) - { - for (int j = 0; j < shape.GetLength(1); j++) - { - if (shape[i, j] == 1) - { - location.Add(new int[] { i, 5 - (shape.GetLength(1) / 2) + j }); - } - } - } + for (int i = 0; i < _shape.GetLength(0); i++) + for (int j = 0; j < _shape.GetLength(1); j++) + if (_shape[i, j] == 1) + Location.Add(new[] {i, (5 - (_shape.GetLength(1) / 2)) + j}); Update(); } + public void Drop() { - if (isSomethingBelow) + if (IsSomethingBelow) { - location.ForEach(s => Program.droppedtetrominoeLocationGrid[s[0], s[1]] = 1); - Program.isDropped = true; + Location.ForEach(s => Program.DroppedTetrominoeLocationGrid[s[0], s[1]] = 1); + Program.IsDropped = true; Beep(800, 200); } else { - location.ForEach(s => s[0]++); + Location.ForEach(s => s[0]++); Update(); } } + public void Rotate() { - List templocation = new List(); - for (int i = 0; i < shape.GetLength(0); i++) - { - for (int j = 0; j < shape.GetLength(1); j++) - { - if (shape[i, j] == 1) - { - templocation.Add(new int[] { i, ((10 - shape.GetLength(1)) / 2) + j }); - } - } - } - if (shape == tetrominoes[1]) + List tempLocation = new List(); + for (int i = 0; i < _shape.GetLength(0); i++) + for (int j = 0; j < _shape.GetLength(1); j++) + if (_shape[i, j] == 1) + tempLocation.Add(new[] {i, ((10 - _shape.GetLength(1)) / 2) + j}); + if (_shape == TetrominoeList[1]) return; - for (int i = 0; i < location.Count; i++) - templocation[i] = TransformMatrix(location[i], location[(shape == tetrominoes[3]) ? 3 : 2]); - for (int count = 0; isOverlayLeft(templocation) != false | isOverlayRight(templocation) != false | isOverlayBelow(templocation) != false; count++) + for (int i = 0; i < Location.Count; i++) + tempLocation[i] = TransformMatrix(Location[i], Location[_shape == TetrominoeList[3] ? 3 : 2]); + for (int count = 0; + (IsOverlayLeft(tempLocation) != false) | (IsOverlayRight(tempLocation) != false) | + (IsOverlayBelow(tempLocation) != false); + count++) { - if (isOverlayLeft(templocation) == true) - for (int i = 0; i < location.Count; i++) - templocation[i][1]++; - if (isOverlayRight(templocation) == true) - for (int i = 0; i < location.Count; i++) - templocation[i][1]--; - if (isOverlayBelow(templocation) == true) - for (int i = 0; i < location.Count; i++) - templocation[i][0]--; + if (IsOverlayLeft(tempLocation) == true) + for (int i = 0; i < Location.Count; i++) + tempLocation[i][1]++; + if (IsOverlayRight(tempLocation) == true) + for (int i = 0; i < Location.Count; i++) + tempLocation[i][1]--; + if (IsOverlayBelow(tempLocation) == true) + for (int i = 0; i < Location.Count; i++) + tempLocation[i][0]--; if (count == 3) return; } - location = templocation; + Location = tempLocation; } - public static int[] TransformMatrix(int[] coord, int[] axis) => new int[] { axis[0] - axis[1] + coord[1], axis[0] + axis[1] - coord[0] }; - public bool isSomethingBelow => location.Where(s => s[0] + 1 >= 23 || s[0] + 1 < 23 & Program.droppedtetrominoeLocationGrid[s[0] + 1, s[1]] == 1).Count() > 0; - public static bool? isOverlayBelow(List location) + + private static int[] TransformMatrix(IReadOnlyList coords, IReadOnlyList axis) => + new[] {(axis[0] - axis[1]) + coords[1], (axis[0] + axis[1]) - coords[0]}; + + private static bool? IsOverlayBelow(IReadOnlyList location) { - List ycoords = new List(); + List yCoords = new List(); for (int i = 0; i < 4; i++) { - ycoords.Add(location[i][0]); + yCoords.Add(location[i][0]); if (location[i][0] >= 23) return true; - if (location[i][0] < 0 | location[i][1] < 0 | location[i][1] > 9) + if ((location[i][0] < 0) | (location[i][1] < 0) | (location[i][1] > 9)) return null; } - return location.Where(s => (ycoords.Max() - ycoords.Min() == 3) ? - ((ycoords.Max() == s[0] | ycoords.Max() - 1 == s[0]) & (Program.droppedtetrominoeLocationGrid[s[0], s[1]] == 1)) : - ((ycoords.Max() == s[0]) & (Program.droppedtetrominoeLocationGrid[s[0], s[1]] == 1))).Count() > 0; + return location.Any(s => + yCoords.Max() - yCoords.Min() == 3 + ? ((yCoords.Max() == s[0]) | (yCoords.Max() - 1 == s[0])) & + (Program.DroppedTetrominoeLocationGrid[s[0], s[1]] == 1) + : (yCoords.Max() == s[0]) & (Program.DroppedTetrominoeLocationGrid[s[0], s[1]] == 1)); } - public bool isSomethingLeft() => location.Where(s => s[1] == 0 || Program.droppedtetrominoeLocationGrid[s[0], s[1] - 1] == 1).Count() > 0; - public static bool? isOverlayLeft(List location) + + public bool IsSomethingLeft() => + Location.Any(s => s[1] == 0 || Program.DroppedTetrominoeLocationGrid[s[0], s[1] - 1] == 1); + + private static bool? IsOverlayLeft(IReadOnlyList location) { - List xcoords = new List(); - xcoords.AddRange(location.Select(s => s[1])); + List xCoords = new List(); + xCoords.AddRange(location.Select(s => s[1])); for (int i = 0; i < 4; i++) { if (location[i][1] < 0) return true; if (location[i][1] > 9) return false; - if (location[i][0] >= 23 | location[i][0] < 0) + if ((location[i][0] >= 23) | (location[i][0] < 0)) return null; } - return location.Where(s => (xcoords.Max() - xcoords.Min() == 3) ? - (xcoords.Min() == s[1] | xcoords.Min() + 1 == s[1] && Program.droppedtetrominoeLocationGrid[s[0], s[1]] == 1) : - (xcoords.Min() == s[1] && Program.droppedtetrominoeLocationGrid[s[0], s[1]] == 1)).Count() > 0; + return location.Any(s => xCoords.Max() - xCoords.Min() == 3 + ? (xCoords.Min() == s[1]) | (xCoords.Min() + 1 == s[1]) && + Program.DroppedTetrominoeLocationGrid[s[0], s[1]] == 1 + : xCoords.Min() == s[1] && Program.DroppedTetrominoeLocationGrid[s[0], s[1]] == 1); } - public bool isSomethingRight() => location.Where(s => s[1] == 9 || Program.droppedtetrominoeLocationGrid[s[0], s[1] + 1] == 1).Count() > 0; - public static bool? isOverlayRight(List location) + + public bool IsSomethingRight() => + Location.Any(s => s[1] == 9 || Program.DroppedTetrominoeLocationGrid[s[0], s[1] + 1] == 1); + + private static bool? IsOverlayRight(IReadOnlyList location) { - List xcoords = new List(); - xcoords.AddRange(location.Select(s => s[1])); + List xCoords = new List(); + xCoords.AddRange(location.Select(s => s[1])); for (int i = 0; i < 4; i++) { if (location[i][1] > 9) return true; if (location[i][1] < 0) return false; - if (location[i][0] >= 23 | location[i][0] < 0) + if ((location[i][0] >= 23) | (location[i][0] < 0)) return null; } - return location.Where(s => (xcoords.Max() - xcoords.Min() == 3) ? - ((xcoords.Max() == s[1] | xcoords.Max() - 1 == s[1]) & Program.droppedtetrominoeLocationGrid[s[0], s[1]] == 1) : - (xcoords.Max() == s[1] & Program.droppedtetrominoeLocationGrid[s[0], s[1]] == 1)).Count() > 0; + return location.Any(s => xCoords.Max() - xCoords.Min() == 3 + ? ((xCoords.Max() == s[1]) | (xCoords.Max() - 1 == s[1])) & + (Program.DroppedTetrominoeLocationGrid[s[0], s[1]] == 1) + : (xCoords.Max() == s[1]) & (Program.DroppedTetrominoeLocationGrid[s[0], s[1]] == 1)); } + public void Update() { for (int i = 0; i < 23; i++) - { - for (int j = 0; j < 10; j++) - { - Program.grid[i, j] = 0; - } - } - location.ForEach(s => Program.grid[s[0], s[1]] = 1); + for (int j = 0; j < 10; j++) + Program.Grid[i, j] = 0; + Location.ForEach(s => Program.Grid[s[0], s[1]] = 1); Program.Draw(); } } -} +} \ No newline at end of file diff --git a/testexetrisathlon/app.config b/testexetrisathlon/app.config deleted file mode 100644 index 3dbff35..0000000 --- a/testexetrisathlon/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/testexetrisathlon/testexetrisathlon.csproj b/testexetrisathlon/testexetrisathlon.csproj index 5e73d6c..af10317 100644 --- a/testexetrisathlon/testexetrisathlon.csproj +++ b/testexetrisathlon/testexetrisathlon.csproj @@ -9,6 +9,8 @@ testexetrisathlon v4.6.1 + 8 + enable true @@ -75,11 +77,6 @@ - - - - - @@ -88,6 +85,9 @@ + + + diff --git a/testexetrisathlon/testexetrisathlon.sln b/testexetrisathlon/testexetrisathlon.sln new file mode 100644 index 0000000..6614d57 --- /dev/null +++ b/testexetrisathlon/testexetrisathlon.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testexetrisathlon", "testexetrisathlon.csproj", "{6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Debug|x86.ActiveCfg = Debug|x86 + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Debug|x86.Build.0 = Debug|x86 + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Release|x86.ActiveCfg = Release|x86 + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Release|x86.Build.0 = Release|x86 + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Release|Any CPU.Build.0 = Release|Any CPU + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Debug|x64.ActiveCfg = Debug|x64 + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Debug|x64.Build.0 = Debug|x64 + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Release|x64.ActiveCfg = Release|x64 + {6B0BD176-D6E3-49F5-8CA1-AE5F1535AC59}.Release|x64.Build.0 = Release|x64 + EndGlobalSection +EndGlobal