diff --git a/.github/workflows/Tug Of War Build.yml b/.github/workflows/Tug Of War Build.yml new file mode 100644 index 00000000..fe07408b --- /dev/null +++ b/.github/workflows/Tug Of War Build.yml @@ -0,0 +1,20 @@ +name: Tug Of War Build +on: + push: + paths: + - 'Projects/Tug Of War/**' + pull_request: + paths: + - 'Projects/Tug Of War/**' + workflow_dispatch: +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: setup dotnet + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + - name: dotnet build + run: dotnet build "Projects\Tug Of War\Tug Of War.csproj" --configuration Release diff --git a/.vscode/launch.json b/.vscode/launch.json index b85fd081..94148a11 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -42,6 +42,16 @@ "console": "externalTerminal", "stopAtEntry": false, }, + { + "name": "Tug Of War", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "Build Tug Of War", + "program": "${workspaceFolder}/Projects/Tug Of War/bin/Debug/Tug Of War.dll", + "cwd": "${workspaceFolder}/Projects/Tug Of War/bin/Debug", + "console": "externalTerminal", + "stopAtEntry": false, + }, { "name": "Whack A Mole", "type": "coreclr", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 70032690..28ebbefb 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,6 +2,19 @@ "version": "2.0.0", "tasks": [ + { + "label": "Build Tug Of War", + "command": "dotnet", + "type": "process", + "args": + [ + "build", + "${workspaceFolder}/Projects/Tug Of War/Tug Of War.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary", + ], + "problemMatcher": "$msCompile", + }, { "label": "Build Tower Of Hanoi", "command": "dotnet", diff --git a/Projects/Tug Of War/Program.cs b/Projects/Tug Of War/Program.cs new file mode 100644 index 00000000..c0a1fbe0 --- /dev/null +++ b/Projects/Tug Of War/Program.cs @@ -0,0 +1,153 @@ +using System; +using System.Threading; + +try +{ + while (true) + { + int position = 0; + const int displacement = 10; + string L() => new(' ', displacement + position + 4); + string R() => new(' ', displacement - position + 4); + string Ground = + new string(' ', 2) + + new string('-', displacement + (15 - displacement) + 2) + + new string('=', displacement * 2 + 2) + + new string('-', displacement + (15 - displacement) + 2) + + new string(' ', 2); + bool frame_a = false; + Console.Clear(); + Console.WriteLine(@" + Tug Of War + + Out pull your opponent in a rope pulling + competition. Mash the [left]+[right] arrow + keys and/or the [A]+[D] keys to pull on the + rope. First player to pull the center of the + rope into their boundary wins. + + Choose Your Opponent: + [1] Easy.......2 mashes per second + [2] Medium.....4 mashes per second + [3] Hard.......8 mashes per second + [4] Harder....16 mashes per second + [escape] give up"); + int? requiredMash = null; + while (requiredMash is null) + { + Console.CursorVisible = false; + switch (Console.ReadKey(true).Key) + { + case ConsoleKey.D1 or ConsoleKey.NumPad1: requiredMash = 02; break; + case ConsoleKey.D2 or ConsoleKey.NumPad2: requiredMash = 04; break; + case ConsoleKey.D3 or ConsoleKey.NumPad3: requiredMash = 08; break; + case ConsoleKey.D4 or ConsoleKey.NumPad4: requiredMash = 16; break; + case ConsoleKey.Escape: return; + } + } + Console.Clear(); + int mash = 0; + int presses = 0; + int sleeps = 0; + ConsoleKey lastKey = default; + DateTime start = DateTime.Now; + while (true) + { + while (Console.KeyAvailable) + { + ConsoleKey key = Console.ReadKey(true).Key; + if (key is ConsoleKey.Escape) + { + return; + } + else if (lastKey is not default(ConsoleKey) && + key is ConsoleKey.A or ConsoleKey.D or ConsoleKey.LeftArrow or ConsoleKey.RightArrow && + key != lastKey) + { + presses++; + mash++; + lastKey = default; + } + else if (key is ConsoleKey.A or ConsoleKey.D or ConsoleKey.LeftArrow or ConsoleKey.RightArrow) + { + lastKey = key; + } + } + if (sleeps is 2) + { + position = mash < requiredMash.Value + ? position + 1 + : position - 1; + sleeps = 0; + mash = 0; + if (Math.Abs(position) >= displacement) + { + break; + } + } + Console.CursorVisible = false; + Console.SetCursorPosition(0, 0); + Console.WriteLine(); + Console.WriteLine(" Tug Of War"); + Console.WriteLine(); + Console.Write(frame_a + ? + $@"{L()}o o {R()}{"\n"}" + + $@"{L()}LL-------------+-------------JJ\{R()}{"\n"}" + + $@"{L()}\\ //{R()}{"\n"}" + + $@"{L()}| \ / |{R()}{"\n"}" + : + $@"{L()} o o{R()}{"\n"}" + + $@"{L()}/LL-------------+-------------JJ{R()}{"\n"}" + + $@"{L()}\\ //{R()}{"\n"}" + + $@"{L()}| \ / |{R()}{"\n"}"); + Console.WriteLine(Ground); + Console.WriteLine(); + Console.WriteLine(frame_a + ? " *** Mash [A]+[D] or [Left]+[Right] ***" + : " ''' Mash [A]+[D] or [Left]+[Right] '''"); + Thread.Sleep(500); + sleeps++; + frame_a = !frame_a; + } + bool win = position < 0; + double seconds = (DateTime.Now - start).TotalSeconds; + double average = presses / seconds; + Console.Clear(); + Console.WriteLine(); + Console.WriteLine(" Tug Of War"); + Console.WriteLine(); + Console.Write(win + ? + $@"{L()}o {R()}{"\n"}" + + $@"{L()}LL------------+------. o___ {R()}{"\n"}" + + $@"{L()}\\ \// \\__{R()}{"\n"}" + + $@"{L()}| \ \_____\ {R()}{"\n"}" + : + $@"{L()} o{R()}{"\n"}" + + $@"{L()} ___o .------+------------JJ{R()}{"\n"}" + + $@"{L()}__// \\/ //{R()}{"\n"}" + + $@"{L()} /_____/ / |{R()}{"\n"}"); + Console.WriteLine(Ground); + Console.WriteLine(); + Console.WriteLine(" You " + (win ? "Win!" : "Lose!")); + Console.WriteLine($" Average: {average:0.##} mashes per second"); + Console.WriteLine(" [enter] return to menu"); + Console.WriteLine(" [escape] exit game"); + bool enterPressed = false; + while (!enterPressed) + { + switch (Console.ReadKey(true).Key) + { + case ConsoleKey.Enter: enterPressed = true; break; + case ConsoleKey.Escape: return; + } + } + } +} +finally +{ + Console.CursorVisible = true; + Console.Clear(); + Console.Write("Tug Of War was closed."); +} \ No newline at end of file diff --git a/Projects/Tug Of War/README.md b/Projects/Tug Of War/README.md new file mode 100644 index 00000000..06ff3f4a --- /dev/null +++ b/Projects/Tug Of War/README.md @@ -0,0 +1,45 @@ +

+ Tug Of War +

+ +

+ flat + Language C# + Target Framework + Build + Discord + +

+ +**[Source Code](Program.cs)** + +Tug Of War is a rope pulling competition. The first person to pull the center of the rope into their territory wins. To pull, mash the keys `A`+`D` or `←`+`→` as fast as you can. + +``` + Tug Of War + + o o + LL-------------+-------------JJ\ + \\ // + | \ / | + -----------------======================----------------- + + *** Mash [A]+[D] or [Left]+[Right] *** +``` + +## Input + +- `A`, `D`, `←`, `→`: pull rope (mash) +- `1`, `2`, `3`, `4`: choose opponent +- `enter` confirm +- `escape` exit game + +

+ You can play this game in your browser: +
+ + Play Now + +
+ Hosted On GitHub Pages +

diff --git a/Projects/Tug Of War/Tug Of War.csproj b/Projects/Tug Of War/Tug Of War.csproj new file mode 100644 index 00000000..49125494 --- /dev/null +++ b/Projects/Tug Of War/Tug Of War.csproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + Tug_Of_War + disable + enable + + diff --git a/Projects/Website/Games/Tug Of War/Tug Of War.cs b/Projects/Website/Games/Tug Of War/Tug Of War.cs new file mode 100644 index 00000000..d215b625 --- /dev/null +++ b/Projects/Website/Games/Tug Of War/Tug Of War.cs @@ -0,0 +1,164 @@ +using System; +using System.Threading.Tasks; + +namespace Website.Games.Tug_Of_War; + +public class Tug_Of_War +{ + public readonly BlazorConsole Console = new(); + + public async Task Run() + { + try + { + while (true) + { + int position = 0; + const int displacement = 10; + string L() => new(' ', displacement + position + 4); + string R() => new(' ', displacement - position + 4); + string Ground = + new string(' ', 2) + + new string('-', displacement + (15 - displacement) + 2) + + new string('=', displacement * 2 + 2) + + new string('-', displacement + (15 - displacement) + 2) + + new string(' ', 2); + bool frame_a = false; + await Console.Clear(); + await Console.WriteLine(@" + Tug Of War + + Out pull your opponent in a rope pulling + competition. Mash the [left]+[right] arrow + keys and/or the [A]+[D] keys to pull on the + rope. First player to pull the center of the + rope into their boundary wins. + + Choose Your Opponent: + [1] Easy.......2 mashes per second + [2] Medium.....4 mashes per second + [3] Hard.......8 mashes per second + [4] Harder....16 mashes per second + [escape] give up"); + int? requiredMash = null; + while (requiredMash is null) + { + Console.CursorVisible = false; + switch ((await Console.ReadKey(true)).Key) + { + case ConsoleKey.D1 or ConsoleKey.NumPad1: requiredMash = 02; break; + case ConsoleKey.D2 or ConsoleKey.NumPad2: requiredMash = 04; break; + case ConsoleKey.D3 or ConsoleKey.NumPad3: requiredMash = 08; break; + case ConsoleKey.D4 or ConsoleKey.NumPad4: requiredMash = 16; break; + case ConsoleKey.Escape: return; + } + } + await Console.Clear(); + int mash = 0; + int presses = 0; + int sleeps = 0; + ConsoleKey lastKey = default; + DateTime start = DateTime.Now; + while (true) + { + while (await Console.KeyAvailable()) + { + ConsoleKey key = (await Console.ReadKey(true)).Key; + if (key is ConsoleKey.Escape) + { + return; + } + else if (lastKey is not default(ConsoleKey) && + key is ConsoleKey.A or ConsoleKey.D or ConsoleKey.LeftArrow or ConsoleKey.RightArrow && + key != lastKey) + { + presses++; + mash++; + lastKey = default; + } + else if (key is ConsoleKey.A or ConsoleKey.D or ConsoleKey.LeftArrow or ConsoleKey.RightArrow) + { + lastKey = key; + } + } + if (sleeps is 2) + { + position = mash < requiredMash.Value + ? position + 1 + : position - 1; + sleeps = 0; + mash = 0; + if (Math.Abs(position) >= displacement) + { + break; + } + } + Console.CursorVisible = false; + await Console.SetCursorPosition(0, 0); + await Console.WriteLine(); + await Console.WriteLine(" Tug Of War"); + await Console.WriteLine(); + await Console.Write(frame_a + ? + $@"{L()}o o {R()}{"\n"}" + + $@"{L()}LL-------------+-------------JJ\{R()}{"\n"}" + + $@"{L()}\\ //{R()}{"\n"}" + + $@"{L()}| \ / |{R()}{"\n"}" + : + $@"{L()} o o{R()}{"\n"}" + + $@"{L()}/LL-------------+-------------JJ{R()}{"\n"}" + + $@"{L()}\\ //{R()}{"\n"}" + + $@"{L()}| \ / |{R()}{"\n"}"); + await Console.WriteLine(Ground); + await Console.WriteLine(); + await Console.WriteLine(frame_a + ? " *** Mash [A]+[D] or [Left]+[Right] ***" + : " ''' Mash [A]+[D] or [Left]+[Right] '''"); + await Console.RefreshAndDelay(TimeSpan.FromMilliseconds(500)); + sleeps++; + frame_a = !frame_a; + } + bool win = position < 0; + double seconds = (DateTime.Now - start).TotalSeconds; + double average = presses / seconds; + await Console.Clear(); + await Console.WriteLine(); + await Console.WriteLine(" Tug Of War"); + await Console.WriteLine(); + await Console.Write(win + ? + $@"{L()}o {R()}{"\n"}" + + $@"{L()}LL------------+------. o___ {R()}{"\n"}" + + $@"{L()}\\ \// \\__{R()}{"\n"}" + + $@"{L()}| \ \_____\ {R()}{"\n"}" + : + $@"{L()} o{R()}{"\n"}" + + $@"{L()} ___o .------+------------JJ{R()}{"\n"}" + + $@"{L()}__// \\/ //{R()}{"\n"}" + + $@"{L()} /_____/ / |{R()}{"\n"}"); + await Console.WriteLine(Ground); + await Console.WriteLine(); + await Console.WriteLine(" You " + (win ? "Win!" : "Lose!")); + await Console.WriteLine($" Average: {average:0.##} mashes per second"); + await Console.WriteLine(" [enter] return to menu"); + await Console.WriteLine(" [escape] exit game"); + bool enterPressed = false; + while (!enterPressed) + { + switch ((await Console.ReadKey(true)).Key) + { + case ConsoleKey.Enter: enterPressed = true; break; + case ConsoleKey.Escape: return; + } + } + } + } + finally + { + Console.CursorVisible = true; + await Console.Clear(); + await Console.Write("Tug Of War was closed."); + await Console.Refresh(); + } + } +} diff --git a/Projects/Website/Pages/Tug Of War.razor b/Projects/Website/Pages/Tug Of War.razor new file mode 100644 index 00000000..537f201d --- /dev/null +++ b/Projects/Website/Pages/Tug Of War.razor @@ -0,0 +1,56 @@ +@using System + +@page "/Tug Of War" + +Tug Of War + +

Tug Of War

+ + + Go To Readme + + +
+
+
+			@Console.State
+		
+
+
+ + + + + + + + + + +
+
+ + + + + +@code +{ + Games.Tug_Of_War.Tug_Of_War Game; + BlazorConsole Console; + + public Tug_Of_War() + { + Game = new(); + Console = Game.Console; + Console.WindowWidth = 60; + Console.WindowHeight = 17; + Console.StateHasChanged = StateHasChanged; + } + + protected override void OnInitialized() => InvokeAsync(Game.Run); +} diff --git a/Projects/Website/Shared/NavMenu.razor b/Projects/Website/Shared/NavMenu.razor index 6c314a1f..6d3df738 100644 --- a/Projects/Website/Shared/NavMenu.razor +++ b/Projects/Website/Shared/NavMenu.razor @@ -28,6 +28,11 @@ Quick Draw +