From 1e2843cc3559c54c59c71447eebda71f49676159 Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 16:36:26 -0600 Subject: [PATCH 01/11] Bootstrapping empty console Generated using `dotnet new console --name hurkle`. --- 51 Hurkle/csharp/.gitignore | 360 ++++++++++++++++++++++ 51 Hurkle/csharp/src/hurkle/Program.cs | 12 + 51 Hurkle/csharp/src/hurkle/hurkle.csproj | 8 + 3 files changed, 380 insertions(+) create mode 100644 51 Hurkle/csharp/.gitignore create mode 100644 51 Hurkle/csharp/src/hurkle/Program.cs create mode 100644 51 Hurkle/csharp/src/hurkle/hurkle.csproj diff --git a/51 Hurkle/csharp/.gitignore b/51 Hurkle/csharp/.gitignore new file mode 100644 index 00000000..d417b186 --- /dev/null +++ b/51 Hurkle/csharp/.gitignore @@ -0,0 +1,360 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/csharp +# Edit at https://www.toptal.com/developers/gitignore?templates=csharp + +### Csharp ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*[.json, .xml, .info] + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# End of https://www.toptal.com/developers/gitignore/api/csharp \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/Program.cs b/51 Hurkle/csharp/src/hurkle/Program.cs new file mode 100644 index 00000000..42c8e1b5 --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace hurkle +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} diff --git a/51 Hurkle/csharp/src/hurkle/hurkle.csproj b/51 Hurkle/csharp/src/hurkle/hurkle.csproj new file mode 100644 index 00000000..1d2d39a9 --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/hurkle.csproj @@ -0,0 +1,8 @@ + + + + Exe + net5.0 + + + From 55dd926e9114ea890e7078d57d93dcd4093db66d Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 16:50:59 -0600 Subject: [PATCH 02/11] Transscripting original source Pulled from https://www.atariarchives.org/basicgames/pages/page94.gif --- 51 Hurkle/csharp/src/hurkle/Program.cs | 52 +++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/51 Hurkle/csharp/src/hurkle/Program.cs b/51 Hurkle/csharp/src/hurkle/Program.cs index 42c8e1b5..a9cd0f60 100644 --- a/51 Hurkle/csharp/src/hurkle/Program.cs +++ b/51 Hurkle/csharp/src/hurkle/Program.cs @@ -6,7 +6,57 @@ namespace hurkle { static void Main(string[] args) { - Console.WriteLine("Hello World!"); + /* + Original source transscription + 10 PRINT TAB(33);"HURKLE" + 20 PRINT TAB(15);"CREATIVE COMPUTING NORRISTOWN, NEW JERSEY" + 30 PRINT;PRINT;PRINT + 110 N=5 + 120 G=10 + 210 PRINT + 220 PRINT "A HURKLE IS HIDING ON A";G;"BY";G;"GRID. HOMEBASE" + 230 PRINT "ON THE GRID IS POINT 0,0 AND ANY GRIDPOINT IS A" + 240 PRINT "PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. TRY TO" + 250 PRINT "GUESS THE HURKLE'S GRIDPOINT. YOU GET";N;"TRIES." + 260 PRINT "AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE" + 270 PRINT "DIRECTION TO GO TO LOOK FOR THE HURKLE." + 280 PRINT + 285 A=INT(G*RND(1)) + 286 B=INT(G*RND(1)) + 310 FOR K=1 TO N + 320 PRINT "GUESS #";K; + 330 INPUT X,Y + 340 IF ABS(X-A)+ABS(Y-B)=0 THEN 500 + 350 REM PRINT INFO + 360 GOSUB 610 + 370 PRINT + 380 NEXT K + 410 PRINT + 420 PRINT "SORRY, THAT'S;N;"GUESSES." + 430 PRINT "THE HURKLE IS AT ";A;",";B + 440 PRINT + 450 PRINT "LET'S PLAY AGAIN. HURKLE IS HIDING." + 460 PRINT + 470 GOTO 285 + 500 REM + 510 PRINT + 520 PRINT "YOU FOUND HIM IN";K;GUESSES!" + 540 GOTO 440 + 610 PRINT "GO "; + 620 IF Y=B THEN 670 + 630 IF Y Date: Sat, 27 Feb 2021 17:46:24 -0600 Subject: [PATCH 03/11] Literal conversion of original Just taking the original BASIC program and converting it into C# without adding types or modernizing the control flow. --- 51 Hurkle/csharp/src/hurkle/Program.cs | 107 +++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 6 deletions(-) diff --git a/51 Hurkle/csharp/src/hurkle/Program.cs b/51 Hurkle/csharp/src/hurkle/Program.cs index a9cd0f60..9e768b08 100644 --- a/51 Hurkle/csharp/src/hurkle/Program.cs +++ b/51 Hurkle/csharp/src/hurkle/Program.cs @@ -11,8 +11,16 @@ namespace hurkle 10 PRINT TAB(33);"HURKLE" 20 PRINT TAB(15);"CREATIVE COMPUTING NORRISTOWN, NEW JERSEY" 30 PRINT;PRINT;PRINT + */ + Console.WriteLine(new string(' ', 33) + @"HURKLE"); + Console.WriteLine(new string(' ', 15) + @"CREATIVE COMPUTING NORRISTOWN, NEW JERSEY"); + /* 110 N=5 120 G=10 + */ + var N=5; + var G=10; + /* 210 PRINT 220 PRINT "A HURKLE IS HIDING ON A";G;"BY";G;"GRID. HOMEBASE" 230 PRINT "ON THE GRID IS POINT 0,0 AND ANY GRIDPOINT IS A" @@ -21,8 +29,31 @@ namespace hurkle 260 PRINT "AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE" 270 PRINT "DIRECTION TO GO TO LOOK FOR THE HURKLE." 280 PRINT + */ + // Using string formatting via the '$' string + Console.WriteLine(); + Console.WriteLine($"A HURKLE IS HIDING ON A {G} BY {G} GRID. HOMEBASE"); + Console.WriteLine(@"ON THE GRID IS POINT 0,0 AND ANY GRIDPOINT IS A"); + Console.WriteLine(@"PAIR OF WHOLE NUMBERS SEPERATED BY A COMMA. TRY TO"); + Console.WriteLine($"GUESS THE HURKLE'S GRIDPOINT. YOU GET {N} TRIES."); + Console.WriteLine(@"AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE"); + Console.WriteLine(@"DIRECTION TO GO TO LOOK FOR THE HURKLE."); + Console.WriteLine(); + + /* 285 A=INT(G*RND(1)) 286 B=INT(G*RND(1)) + */ + // Get a pseudo number generator + var randomSource = new Random(); + START: + // BASIC program was generating a float between 0 and 1 + // then multiplying by the size of the grid to to a number + // between 1 and 10. C# allows you to do that directly. + var A = randomSource.Next(0,G); + var B = randomSource.Next(0,G); + + /* 310 FOR K=1 TO N 320 PRINT "GUESS #";K; 330 INPUT X,Y @@ -31,31 +62,95 @@ namespace hurkle 360 GOSUB 610 370 PRINT 380 NEXT K + */ + for(var K=1;K<=N;K++) + { + Console.WriteLine($"GUESS #{K}"); + var inputLine = Console.ReadLine(); + var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); + var X = int.Parse(seperateStrings[0]); + var Y = int.Parse(seperateStrings[1]); + if(Math.Abs(X-A) + Math.Abs(Y-B) == 0) + { + /* + 500 REM + 510 PRINT + 520 PRINT "YOU FOUND HIM IN";K;GUESSES!" + 540 GOTO 440 + */ + Console.WriteLine(); + Console.WriteLine($"YOU FOUND HIM IN {K} GUESSES!"); + goto END; + } + + PrintInfo(X,Y,A,B); + } + + /* 410 PRINT 420 PRINT "SORRY, THAT'S;N;"GUESSES." 430 PRINT "THE HURKLE IS AT ";A;",";B + */ + Console.WriteLine(); + Console.WriteLine($"SORRY, THAT'S {N} GUESSES"); + Console.WriteLine($"THE HURKLE IS AT {A},{B}"); + /* 440 PRINT 450 PRINT "LET'S PLAY AGAIN. HURKLE IS HIDING." 460 PRINT 470 GOTO 285 - 500 REM - 510 PRINT - 520 PRINT "YOU FOUND HIM IN";K;GUESSES!" - 540 GOTO 440 + */ + END: + Console.WriteLine(); + Console.WriteLine("LET'S PLAY AGAIN. HURKLE IS HIDING"); + Console.WriteLine(); + goto START; + + /* + 999 END + */ + } + + private static void PrintInfo(int X, int Y, int A, int B) + { + + /* 610 PRINT "GO "; + */ + Console.Write("GO "); + /* 620 IF Y=B THEN 670 630 IF YB) + { + Console.Write("SOUTH"); + }else if(YA) + { + Console.Write("WEST"); + } + + Console.WriteLine(); + /* 720 PRINT 730 RETURN - 999 END */ } } From 923302fdb4c3a2f5891516dd3c2540c9f711026d Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 18:02:47 -0600 Subject: [PATCH 04/11] Introduce game class Cleanup uses of goto and encapsulate game logic. --- 51 Hurkle/csharp/src/hurkle/HurkleGame.cs | 111 ++++++++++++++++++++ 51 Hurkle/csharp/src/hurkle/Program.cs | 117 ++-------------------- 2 files changed, 118 insertions(+), 110 deletions(-) create mode 100644 51 Hurkle/csharp/src/hurkle/HurkleGame.cs diff --git a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs new file mode 100644 index 00000000..7abeaad5 --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs @@ -0,0 +1,111 @@ +using System; + +namespace hurkle +{ + public class HurkleGame + { + private readonly Random _random = new Random(); + private readonly int guesses; + private readonly int gridSize; + + public HurkleGame(int guesses, int gridSize) + { + this.guesses = guesses; + this.gridSize = gridSize; + } + + public void PlayGame() + { + // BASIC program was generating a float between 0 and 1 + // then multiplying by the size of the grid to to a number + // between 1 and 10. C# allows you to do that directly. + var A = _random.Next(0,gridSize); + var B = _random.Next(0,gridSize); + + /* + 310 FOR K=1 TO N + 320 PRINT "GUESS #";K; + 330 INPUT X,Y + 340 IF ABS(X-A)+ABS(Y-B)=0 THEN 500 + 350 REM PRINT INFO + 360 GOSUB 610 + 370 PRINT + 380 NEXT K + */ + for(var K=1;K<=guesses;K++) + { + Console.WriteLine($"GUESS #{K}"); + var inputLine = Console.ReadLine(); + var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); + var X = int.Parse(seperateStrings[0]); + var Y = int.Parse(seperateStrings[1]); + if(Math.Abs(X-A) + Math.Abs(Y-B) == 0) + { + /* + 500 REM + 510 PRINT + 520 PRINT "YOU FOUND HIM IN";K;GUESSES!" + 540 GOTO 440 + */ + Console.WriteLine(); + Console.WriteLine($"YOU FOUND HIM IN {K} GUESSES!"); + return; + } + + PrintInfo(X,Y,A,B); + } + + /* + 410 PRINT + 420 PRINT "SORRY, THAT'S;N;"GUESSES." + 430 PRINT "THE HURKLE IS AT ";A;",";B + */ + Console.WriteLine(); + Console.WriteLine($"SORRY, THAT'S {guesses} GUESSES"); + Console.WriteLine($"THE HURKLE IS AT {A},{B}"); + } + + private static void PrintInfo(int X, int Y, int A, int B) + { + + /* + 610 PRINT "GO "; + */ + Console.Write("GO "); + /* + 620 IF Y=B THEN 670 + 630 IF YB) + { + Console.Write("SOUTH"); + }else if(YA) + { + Console.Write("WEST"); + } + + Console.WriteLine(); + /* + 720 PRINT + 730 RETURN + */ + } + } +} \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/Program.cs b/51 Hurkle/csharp/src/hurkle/Program.cs index 9e768b08..447fa547 100644 --- a/51 Hurkle/csharp/src/hurkle/Program.cs +++ b/51 Hurkle/csharp/src/hurkle/Program.cs @@ -39,119 +39,16 @@ namespace hurkle Console.WriteLine(@"AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE"); Console.WriteLine(@"DIRECTION TO GO TO LOOK FOR THE HURKLE."); Console.WriteLine(); - - /* - 285 A=INT(G*RND(1)) - 286 B=INT(G*RND(1)) - */ - // Get a pseudo number generator - var randomSource = new Random(); - START: - // BASIC program was generating a float between 0 and 1 - // then multiplying by the size of the grid to to a number - // between 1 and 10. C# allows you to do that directly. - var A = randomSource.Next(0,G); - var B = randomSource.Next(0,G); - - /* - 310 FOR K=1 TO N - 320 PRINT "GUESS #";K; - 330 INPUT X,Y - 340 IF ABS(X-A)+ABS(Y-B)=0 THEN 500 - 350 REM PRINT INFO - 360 GOSUB 610 - 370 PRINT - 380 NEXT K - */ - for(var K=1;K<=N;K++) - { - Console.WriteLine($"GUESS #{K}"); - var inputLine = Console.ReadLine(); - var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); - var X = int.Parse(seperateStrings[0]); - var Y = int.Parse(seperateStrings[1]); - if(Math.Abs(X-A) + Math.Abs(Y-B) == 0) - { - /* - 500 REM - 510 PRINT - 520 PRINT "YOU FOUND HIM IN";K;GUESSES!" - 540 GOTO 440 - */ - Console.WriteLine(); - Console.WriteLine($"YOU FOUND HIM IN {K} GUESSES!"); - goto END; - } - PrintInfo(X,Y,A,B); - } - - /* - 410 PRINT - 420 PRINT "SORRY, THAT'S;N;"GUESSES." - 430 PRINT "THE HURKLE IS AT ";A;",";B - */ - Console.WriteLine(); - Console.WriteLine($"SORRY, THAT'S {N} GUESSES"); - Console.WriteLine($"THE HURKLE IS AT {A},{B}"); - /* - 440 PRINT - 450 PRINT "LET'S PLAY AGAIN. HURKLE IS HIDING." - 460 PRINT - 470 GOTO 285 - */ - END: - Console.WriteLine(); - Console.WriteLine("LET'S PLAY AGAIN. HURKLE IS HIDING"); - Console.WriteLine(); - goto START; - - /* - 999 END - */ - } + var hurkle = new HurkleGame(N,G); + while(true) + { + hurkle.PlayGame(); - private static void PrintInfo(int X, int Y, int A, int B) - { - - /* - 610 PRINT "GO "; - */ - Console.Write("GO "); - /* - 620 IF Y=B THEN 670 - 630 IF YB) - { - Console.Write("SOUTH"); - }else if(YA) - { - Console.Write("WEST"); - } - - Console.WriteLine(); - /* - 720 PRINT - 730 RETURN - */ } } } From ddafd6436b4699eb9eeedd0421f8c2f829975c4d Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 19:08:56 -0600 Subject: [PATCH 05/11] Add a bailout Forcing a SIGKILL is bad form, give some UI for playing again or bailing. --- 51 Hurkle/csharp/src/hurkle/Program.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/51 Hurkle/csharp/src/hurkle/Program.cs b/51 Hurkle/csharp/src/hurkle/Program.cs index 447fa547..4c4040b7 100644 --- a/51 Hurkle/csharp/src/hurkle/Program.cs +++ b/51 Hurkle/csharp/src/hurkle/Program.cs @@ -45,9 +45,18 @@ namespace hurkle { hurkle.PlayGame(); - Console.WriteLine(); - Console.WriteLine("LET'S PLAY AGAIN. HURKLE IS HIDING"); - Console.WriteLine(); + Console.WriteLine("PLAY AGAIN? (Y)ES/(N)O"); + var playAgainResponse = Console.ReadLine(); + if(playAgainResponse.Trim().StartsWith("y", StringComparison.InvariantCultureIgnoreCase)) + { + Console.WriteLine(); + Console.WriteLine("LET'S PLAY AGAIN. HURKLE IS HIDING"); + Console.WriteLine(); + }else{ + Console.WriteLine("THANKS FOR PLAYING!"); + break; + } + } } } From c3308bf0286dc5493889dc1be67390eddb31f5b6 Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 19:19:32 -0600 Subject: [PATCH 06/11] Introduce domain object for ponts Game is centered around comparing an X,Y point to another X,Y point. Introduced a domain object to represent that pairing. --- 51 Hurkle/csharp/src/hurkle/HurkleGame.cs | 34 +++++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs index 7abeaad5..38d1a158 100644 --- a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs +++ b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs @@ -19,8 +19,10 @@ namespace hurkle // BASIC program was generating a float between 0 and 1 // then multiplying by the size of the grid to to a number // between 1 and 10. C# allows you to do that directly. - var A = _random.Next(0,gridSize); - var B = _random.Next(0,gridSize); + var hurklePoint = new GamePoint{ + X = _random.Next(0, gridSize), + Y = _random.Next(0, gridSize) + }; /* 310 FOR K=1 TO N @@ -37,9 +39,11 @@ namespace hurkle Console.WriteLine($"GUESS #{K}"); var inputLine = Console.ReadLine(); var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); - var X = int.Parse(seperateStrings[0]); - var Y = int.Parse(seperateStrings[1]); - if(Math.Abs(X-A) + Math.Abs(Y-B) == 0) + var guessPoint = new GamePoint{ + X = int.Parse(seperateStrings[0]), + Y = int.Parse(seperateStrings[1]) + }; + if(Math.Abs(guessPoint.X-hurklePoint.X) + Math.Abs(guessPoint.Y-hurklePoint.Y) == 0) { /* 500 REM @@ -52,7 +56,7 @@ namespace hurkle return; } - PrintInfo(X,Y,A,B); + PrintInfo(guessPoint,hurklePoint); } /* @@ -62,10 +66,10 @@ namespace hurkle */ Console.WriteLine(); Console.WriteLine($"SORRY, THAT'S {guesses} GUESSES"); - Console.WriteLine($"THE HURKLE IS AT {A},{B}"); + Console.WriteLine($"THE HURKLE IS AT {hurklePoint.X},{hurklePoint.Y}"); } - private static void PrintInfo(int X, int Y, int A, int B) + private static void PrintInfo(GamePoint guess, GamePoint target) { /* @@ -79,10 +83,10 @@ namespace hurkle 650 GO TO 670 660 PRINT "NORTH"; */ - if(Y>B) + if(guess.Y>target.Y) { Console.Write("SOUTH"); - }else if(YA) + }else if(guess.X>target.X) { Console.Write("WEST"); } @@ -107,5 +111,11 @@ namespace hurkle 730 RETURN */ } + + private class GamePoint + { + public int X {get;init;} + public int Y {get;init;} + } } } \ No newline at end of file From 8291d08a8da32ddb522253fe53e30f1b84db72c0 Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 19:50:56 -0600 Subject: [PATCH 07/11] Introduce enum for directions Instead of cleverly constructing the output string, explicitly test for what the resulting direction is. --- 51 Hurkle/csharp/src/hurkle/HurkleGame.cs | 123 ++++++++++++++++------ 1 file changed, 88 insertions(+), 35 deletions(-) diff --git a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs index 38d1a158..ed030587 100644 --- a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs +++ b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs @@ -43,7 +43,8 @@ namespace hurkle X = int.Parse(seperateStrings[0]), Y = int.Parse(seperateStrings[1]) }; - if(Math.Abs(guessPoint.X-hurklePoint.X) + Math.Abs(guessPoint.Y-hurklePoint.Y) == 0) + + if(guessPoint.GetDirectionTo(hurklePoint) == CardinalDirection.None) { /* 500 REM @@ -71,51 +72,103 @@ namespace hurkle private static void PrintInfo(GamePoint guess, GamePoint target) { - - /* - 610 PRINT "GO "; - */ Console.Write("GO "); - /* - 620 IF Y=B THEN 670 - 630 IF Ytarget.Y) + switch(guess.GetDirectionTo(target)) { - Console.Write("SOUTH"); - }else if(guess.Ytarget.X) - { - Console.Write("WEST"); + case CardinalDirection.East: + Console.WriteLine("EAST"); + break; + case CardinalDirection.North: + Console.WriteLine("NORTH"); + break; + case CardinalDirection.South: + Console.WriteLine("SOUTH"); + break; + case CardinalDirection.West: + Console.WriteLine("WEST"); + break; + case CardinalDirection.NorthEast: + Console.WriteLine("NORTHEAST"); + break; + case CardinalDirection.NorthWest: + Console.WriteLine("NORTHWEST"); + break; + case CardinalDirection.SouthEast: + Console.WriteLine("SOUTHEAST"); + break; + case CardinalDirection.SouthWest: + Console.WriteLine("SOUTHWEST"); + break; } Console.WriteLine(); - /* - 720 PRINT - 730 RETURN - */ + } + + private enum CardinalDirection + { + None, + North, + NorthEast, + East, + SouthEast, + South, + SouthWest, + West, + NorthWest } private class GamePoint { public int X {get;init;} public int Y {get;init;} + + public CardinalDirection GetDirectionTo(GamePoint target) + { + if(X == target.X) + { + if(Y > target.Y) + { + return CardinalDirection.South; + } + else if(Y < target.Y) + { + return CardinalDirection.North; + } + else + { + return CardinalDirection.None; + } + } + else if(X > target.X) + { + if(Y == target.Y) + { + return CardinalDirection.West; + } + else if(Y > target.Y) + { + return CardinalDirection.SouthWest; + } + else + { + return CardinalDirection.NorthWest; + } + } + else + { + if(Y == target.Y) + { + return CardinalDirection.East; + } + else if(Y > target.Y) + { + return CardinalDirection.SouthEast; + } + else{ + return CardinalDirection.NorthEast; + } + } + } } } } \ No newline at end of file From 47593d07607cb4e6e600b11701acbdd5f90cb295 Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 20:08:03 -0600 Subject: [PATCH 08/11] Isolate prompting from game Move the user input out of the game logic. --- 51 Hurkle/csharp/src/hurkle/HurkleGame.cs | 28 ++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs index ed030587..eff53f25 100644 --- a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs +++ b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs @@ -36,14 +36,8 @@ namespace hurkle */ for(var K=1;K<=guesses;K++) { - Console.WriteLine($"GUESS #{K}"); - var inputLine = Console.ReadLine(); - var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); - var guessPoint = new GamePoint{ - X = int.Parse(seperateStrings[0]), - Y = int.Parse(seperateStrings[1]) - }; - + var guessPoint = GetGuess(new GuessViewModel{CurrentGuessNumber = K}); + if(guessPoint.GetDirectionTo(hurklePoint) == CardinalDirection.None) { /* @@ -70,6 +64,24 @@ namespace hurkle Console.WriteLine($"THE HURKLE IS AT {hurklePoint.X},{hurklePoint.Y}"); } + private class GuessViewModel + { + public int CurrentGuessNumber {get;init;} + } + + private static GamePoint GetGuess(GuessViewModel model) + { + Console.WriteLine($"GUESS #{model.CurrentGuessNumber}"); + var inputLine = Console.ReadLine(); + var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); + var guessPoint = new GamePoint{ + X = int.Parse(seperateStrings[0]), + Y = int.Parse(seperateStrings[1]) + }; + + return guessPoint; + } + private static void PrintInfo(GamePoint guess, GamePoint target) { Console.Write("GO "); From 8df211b17b90c5c2a35f8c0b311d703b941599f3 Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 20:44:35 -0600 Subject: [PATCH 09/11] Add ViewModels for game loop Move all UI interaction off of game loop variables. --- .../csharp/src/hurkle/CardinalDirection.cs | 15 ++ .../csharp/src/hurkle/FailedGuessViewModel.cs | 7 + 51 Hurkle/csharp/src/hurkle/GamePoint.cs | 56 +++++++ 51 Hurkle/csharp/src/hurkle/HurkleGame.cs | 154 +++++------------- 51 Hurkle/csharp/src/hurkle/LossViewModel.cs | 8 + .../csharp/src/hurkle/VictoryViewModel.cs | 7 + 6 files changed, 135 insertions(+), 112 deletions(-) create mode 100644 51 Hurkle/csharp/src/hurkle/CardinalDirection.cs create mode 100644 51 Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs create mode 100644 51 Hurkle/csharp/src/hurkle/GamePoint.cs create mode 100644 51 Hurkle/csharp/src/hurkle/LossViewModel.cs create mode 100644 51 Hurkle/csharp/src/hurkle/VictoryViewModel.cs diff --git a/51 Hurkle/csharp/src/hurkle/CardinalDirection.cs b/51 Hurkle/csharp/src/hurkle/CardinalDirection.cs new file mode 100644 index 00000000..969c9b2b --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/CardinalDirection.cs @@ -0,0 +1,15 @@ +namespace hurkle +{ + internal enum CardinalDirection + { + None, + North, + NorthEast, + East, + SouthEast, + South, + SouthWest, + West, + NorthWest + } +} \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs b/51 Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs new file mode 100644 index 00000000..25042dde --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/FailedGuessViewModel.cs @@ -0,0 +1,7 @@ +namespace hurkle +{ + internal class FailedGuessViewModel + { + public CardinalDirection Direction { get; init; } + } +} \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/GamePoint.cs b/51 Hurkle/csharp/src/hurkle/GamePoint.cs new file mode 100644 index 00000000..f715a41d --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/GamePoint.cs @@ -0,0 +1,56 @@ +namespace hurkle +{ + internal class GamePoint + { + public int X {get;init;} + public int Y {get;init;} + + public CardinalDirection GetDirectionTo(GamePoint target) + { + if(X == target.X) + { + if(Y > target.Y) + { + return CardinalDirection.South; + } + else if(Y < target.Y) + { + return CardinalDirection.North; + } + else + { + return CardinalDirection.None; + } + } + else if(X > target.X) + { + if(Y == target.Y) + { + return CardinalDirection.West; + } + else if(Y > target.Y) + { + return CardinalDirection.SouthWest; + } + else + { + return CardinalDirection.NorthWest; + } + } + else + { + if(Y == target.Y) + { + return CardinalDirection.East; + } + else if(Y > target.Y) + { + return CardinalDirection.SouthEast; + } + else{ + return CardinalDirection.NorthEast; + } + } + } + } +} \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs index eff53f25..8b3b13f3 100644 --- a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs +++ b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs @@ -2,7 +2,7 @@ using System; namespace hurkle { - public class HurkleGame + public partial class HurkleGame { private readonly Random _random = new Random(); private readonly int guesses; @@ -24,68 +24,36 @@ namespace hurkle Y = _random.Next(0, gridSize) }; - /* - 310 FOR K=1 TO N - 320 PRINT "GUESS #";K; - 330 INPUT X,Y - 340 IF ABS(X-A)+ABS(Y-B)=0 THEN 500 - 350 REM PRINT INFO - 360 GOSUB 610 - 370 PRINT - 380 NEXT K - */ for(var K=1;K<=guesses;K++) { var guessPoint = GetGuess(new GuessViewModel{CurrentGuessNumber = K}); - - if(guessPoint.GetDirectionTo(hurklePoint) == CardinalDirection.None) - { - /* - 500 REM - 510 PRINT - 520 PRINT "YOU FOUND HIM IN";K;GUESSES!" - 540 GOTO 440 - */ - Console.WriteLine(); - Console.WriteLine($"YOU FOUND HIM IN {K} GUESSES!"); - return; - } - PrintInfo(guessPoint,hurklePoint); + var direction = guessPoint.GetDirectionTo(hurklePoint); + switch(direction) + { + case CardinalDirection.None: + ShowVictory(new VictoryViewModel{CurrentGuessNumber = K}); + return; + default: + ShowDirection(new FailedGuessViewModel{Direction = direction}); + continue; + } } - /* - 410 PRINT - 420 PRINT "SORRY, THAT'S;N;"GUESSES." - 430 PRINT "THE HURKLE IS AT ";A;",";B - */ + ShowLoss(new LossViewModel{MaxGuesses = guesses, HurkleLocation = hurklePoint } ); + } + + private void ShowLoss(LossViewModel lossViewModel) + { Console.WriteLine(); - Console.WriteLine($"SORRY, THAT'S {guesses} GUESSES"); - Console.WriteLine($"THE HURKLE IS AT {hurklePoint.X},{hurklePoint.Y}"); + Console.WriteLine($"SORRY, THAT'S {lossViewModel.MaxGuesses} GUESSES"); + Console.WriteLine($"THE HURKLE IS AT {lossViewModel.HurkleLocation.X},{lossViewModel.HurkleLocation.Y}"); } - private class GuessViewModel - { - public int CurrentGuessNumber {get;init;} - } - - private static GamePoint GetGuess(GuessViewModel model) - { - Console.WriteLine($"GUESS #{model.CurrentGuessNumber}"); - var inputLine = Console.ReadLine(); - var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); - var guessPoint = new GamePoint{ - X = int.Parse(seperateStrings[0]), - Y = int.Parse(seperateStrings[1]) - }; - - return guessPoint; - } - - private static void PrintInfo(GamePoint guess, GamePoint target) + private void ShowDirection(FailedGuessViewModel failedGuessViewModel) { Console.Write("GO "); - switch(guess.GetDirectionTo(target)) + switch(failedGuessViewModel.Direction) { case CardinalDirection.East: Console.WriteLine("EAST"); @@ -116,71 +84,33 @@ namespace hurkle Console.WriteLine(); } - private enum CardinalDirection + private void ShowVictory(VictoryViewModel victoryViewModel) { - None, - North, - NorthEast, - East, - SouthEast, - South, - SouthWest, - West, - NorthWest + Console.WriteLine(); + Console.WriteLine($"YOU FOUND HIM IN {victoryViewModel.CurrentGuessNumber} GUESSES!"); } - private class GamePoint + private class GuessViewModel { - public int X {get;init;} - public int Y {get;init;} + public int CurrentGuessNumber {get;init;} + } - public CardinalDirection GetDirectionTo(GamePoint target) - { - if(X == target.X) - { - if(Y > target.Y) - { - return CardinalDirection.South; - } - else if(Y < target.Y) - { - return CardinalDirection.North; - } - else - { - return CardinalDirection.None; - } - } - else if(X > target.X) - { - if(Y == target.Y) - { - return CardinalDirection.West; - } - else if(Y > target.Y) - { - return CardinalDirection.SouthWest; - } - else - { - return CardinalDirection.NorthWest; - } - } - else - { - if(Y == target.Y) - { - return CardinalDirection.East; - } - else if(Y > target.Y) - { - return CardinalDirection.SouthEast; - } - else{ - return CardinalDirection.NorthEast; - } - } - } + private static GamePoint GetGuess(GuessViewModel model) + { + Console.WriteLine($"GUESS #{model.CurrentGuessNumber}"); + var inputLine = Console.ReadLine(); + var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); + var guessPoint = new GamePoint{ + X = int.Parse(seperateStrings[0]), + Y = int.Parse(seperateStrings[1]) + }; + + return guessPoint; + } + + private static void PrintInfo(GamePoint guess, GamePoint target) + { + } } } \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/LossViewModel.cs b/51 Hurkle/csharp/src/hurkle/LossViewModel.cs new file mode 100644 index 00000000..2329be87 --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/LossViewModel.cs @@ -0,0 +1,8 @@ +namespace hurkle +{ + internal class LossViewModel + { + public int MaxGuesses { get; init; } + public GamePoint HurkleLocation { get; init; } + } +} \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/VictoryViewModel.cs b/51 Hurkle/csharp/src/hurkle/VictoryViewModel.cs new file mode 100644 index 00000000..ce25311c --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/VictoryViewModel.cs @@ -0,0 +1,7 @@ +namespace hurkle +{ + internal class VictoryViewModel + { + public int CurrentGuessNumber {get; init;} + } +} \ No newline at end of file From 25525a5a8271a9db16ec3d54a35c8270830b79cb Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 20:59:55 -0600 Subject: [PATCH 10/11] Introduce a view class Move all the console interaction into a view class making the game logic isolated from UI. --- .../csharp/src/hurkle/ConsoleHurkleView.cs | 67 +++++++++++++++ 51 Hurkle/csharp/src/hurkle/GuessViewModel.cs | 7 ++ 51 Hurkle/csharp/src/hurkle/HurkleGame.cs | 84 ++----------------- 51 Hurkle/csharp/src/hurkle/IHurkleView.cs | 10 +++ 51 Hurkle/csharp/src/hurkle/Program.cs | 3 +- 5 files changed, 94 insertions(+), 77 deletions(-) create mode 100644 51 Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs create mode 100644 51 Hurkle/csharp/src/hurkle/GuessViewModel.cs create mode 100644 51 Hurkle/csharp/src/hurkle/IHurkleView.cs diff --git a/51 Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs b/51 Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs new file mode 100644 index 00000000..40366ad2 --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/ConsoleHurkleView.cs @@ -0,0 +1,67 @@ +using System; + +namespace hurkle +{ + internal class ConsoleHurkleView : IHurkleView + { + public GamePoint GetGuess(GuessViewModel guessViewModel) + { + Console.WriteLine($"GUESS #{guessViewModel.CurrentGuessNumber}"); + var inputLine = Console.ReadLine(); + var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); + var guessPoint = new GamePoint{ + X = int.Parse(seperateStrings[0]), + Y = int.Parse(seperateStrings[1]) + }; + + return guessPoint; + } + + public void ShowDirection(FailedGuessViewModel failedGuessViewModel) + { + Console.Write("GO "); + switch(failedGuessViewModel.Direction) + { + case CardinalDirection.East: + Console.WriteLine("EAST"); + break; + case CardinalDirection.North: + Console.WriteLine("NORTH"); + break; + case CardinalDirection.South: + Console.WriteLine("SOUTH"); + break; + case CardinalDirection.West: + Console.WriteLine("WEST"); + break; + case CardinalDirection.NorthEast: + Console.WriteLine("NORTHEAST"); + break; + case CardinalDirection.NorthWest: + Console.WriteLine("NORTHWEST"); + break; + case CardinalDirection.SouthEast: + Console.WriteLine("SOUTHEAST"); + break; + case CardinalDirection.SouthWest: + Console.WriteLine("SOUTHWEST"); + break; + } + + Console.WriteLine(); + } + + public void ShowLoss(LossViewModel lossViewModel) + { + Console.WriteLine(); + Console.WriteLine($"SORRY, THAT'S {lossViewModel.MaxGuesses} GUESSES"); + Console.WriteLine($"THE HURKLE IS AT {lossViewModel.HurkleLocation.X},{lossViewModel.HurkleLocation.Y}"); + } + + public void ShowVictory(VictoryViewModel victoryViewModel) + { + Console.WriteLine(); + Console.WriteLine($"YOU FOUND HIM IN {victoryViewModel.CurrentGuessNumber} GUESSES!"); + } + } +} \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/GuessViewModel.cs b/51 Hurkle/csharp/src/hurkle/GuessViewModel.cs new file mode 100644 index 00000000..b0c5227c --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/GuessViewModel.cs @@ -0,0 +1,7 @@ +namespace hurkle +{ + internal class GuessViewModel + { + public int CurrentGuessNumber {get;init;} + } +} \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs index 8b3b13f3..88620bbc 100644 --- a/51 Hurkle/csharp/src/hurkle/HurkleGame.cs +++ b/51 Hurkle/csharp/src/hurkle/HurkleGame.cs @@ -2,14 +2,16 @@ using System; namespace hurkle { - public partial class HurkleGame + internal class HurkleGame { private readonly Random _random = new Random(); + private readonly IHurkleView _view; private readonly int guesses; private readonly int gridSize; - public HurkleGame(int guesses, int gridSize) + public HurkleGame(int guesses, int gridSize, IHurkleView view) { + _view = view; this.guesses = guesses; this.gridSize = gridSize; } @@ -26,91 +28,21 @@ namespace hurkle for(var K=1;K<=guesses;K++) { - var guessPoint = GetGuess(new GuessViewModel{CurrentGuessNumber = K}); + var guessPoint = _view.GetGuess(new GuessViewModel{CurrentGuessNumber = K}); var direction = guessPoint.GetDirectionTo(hurklePoint); switch(direction) { case CardinalDirection.None: - ShowVictory(new VictoryViewModel{CurrentGuessNumber = K}); + _view.ShowVictory(new VictoryViewModel{CurrentGuessNumber = K}); return; default: - ShowDirection(new FailedGuessViewModel{Direction = direction}); + _view.ShowDirection(new FailedGuessViewModel{Direction = direction}); continue; } } - ShowLoss(new LossViewModel{MaxGuesses = guesses, HurkleLocation = hurklePoint } ); - } - - private void ShowLoss(LossViewModel lossViewModel) - { - Console.WriteLine(); - Console.WriteLine($"SORRY, THAT'S {lossViewModel.MaxGuesses} GUESSES"); - Console.WriteLine($"THE HURKLE IS AT {lossViewModel.HurkleLocation.X},{lossViewModel.HurkleLocation.Y}"); - } - - private void ShowDirection(FailedGuessViewModel failedGuessViewModel) - { - Console.Write("GO "); - switch(failedGuessViewModel.Direction) - { - case CardinalDirection.East: - Console.WriteLine("EAST"); - break; - case CardinalDirection.North: - Console.WriteLine("NORTH"); - break; - case CardinalDirection.South: - Console.WriteLine("SOUTH"); - break; - case CardinalDirection.West: - Console.WriteLine("WEST"); - break; - case CardinalDirection.NorthEast: - Console.WriteLine("NORTHEAST"); - break; - case CardinalDirection.NorthWest: - Console.WriteLine("NORTHWEST"); - break; - case CardinalDirection.SouthEast: - Console.WriteLine("SOUTHEAST"); - break; - case CardinalDirection.SouthWest: - Console.WriteLine("SOUTHWEST"); - break; - } - - Console.WriteLine(); - } - - private void ShowVictory(VictoryViewModel victoryViewModel) - { - Console.WriteLine(); - Console.WriteLine($"YOU FOUND HIM IN {victoryViewModel.CurrentGuessNumber} GUESSES!"); - } - - private class GuessViewModel - { - public int CurrentGuessNumber {get;init;} - } - - private static GamePoint GetGuess(GuessViewModel model) - { - Console.WriteLine($"GUESS #{model.CurrentGuessNumber}"); - var inputLine = Console.ReadLine(); - var seperateStrings = inputLine.Split(',', 2, StringSplitOptions.TrimEntries); - var guessPoint = new GamePoint{ - X = int.Parse(seperateStrings[0]), - Y = int.Parse(seperateStrings[1]) - }; - - return guessPoint; - } - - private static void PrintInfo(GamePoint guess, GamePoint target) - { - + _view.ShowLoss(new LossViewModel{MaxGuesses = guesses, HurkleLocation = hurklePoint } ); } } } \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/IHurkleView.cs b/51 Hurkle/csharp/src/hurkle/IHurkleView.cs new file mode 100644 index 00000000..e5ce3a1a --- /dev/null +++ b/51 Hurkle/csharp/src/hurkle/IHurkleView.cs @@ -0,0 +1,10 @@ +namespace hurkle +{ + internal interface IHurkleView + { + GamePoint GetGuess(GuessViewModel guessViewModel); + void ShowVictory(VictoryViewModel victoryViewModel); + void ShowDirection(FailedGuessViewModel failedGuessViewModel); + void ShowLoss(LossViewModel lossViewModel); + } +} \ No newline at end of file diff --git a/51 Hurkle/csharp/src/hurkle/Program.cs b/51 Hurkle/csharp/src/hurkle/Program.cs index 4c4040b7..148308d1 100644 --- a/51 Hurkle/csharp/src/hurkle/Program.cs +++ b/51 Hurkle/csharp/src/hurkle/Program.cs @@ -40,7 +40,8 @@ namespace hurkle Console.WriteLine(@"DIRECTION TO GO TO LOOK FOR THE HURKLE."); Console.WriteLine(); - var hurkle = new HurkleGame(N,G); + var view = new ConsoleHurkleView(); + var hurkle = new HurkleGame(N,G, view); while(true) { hurkle.PlayGame(); From 176457f62006f884f82a24abb90381c290aa0f0a Mon Sep 17 00:00:00 2001 From: epvanhouten Date: Sat, 27 Feb 2021 21:04:32 -0600 Subject: [PATCH 11/11] Updating README.md --- 51 Hurkle/csharp/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/51 Hurkle/csharp/README.md b/51 Hurkle/csharp/README.md index 4daabb5c..6973d578 100644 --- a/51 Hurkle/csharp/README.md +++ b/51 Hurkle/csharp/README.md @@ -1,3 +1,8 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/) + +This is demonstrating seperating the user interface from the application logic through the +use of the View/ViewModel/Controller pattern. + +It also makes an effort to be relatively immutable.