From 63113a01c046bfd8ffd0a046912e05ed43afb6a7 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 11:30:44 -0300 Subject: [PATCH 01/30] Add .gitignore and .gitattributes. --- .gitattributes | 63 ++++++++++++ .gitignore | 261 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 324 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c4efe2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,261 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.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 + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# 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 +# TODO: 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 +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable 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 + +# 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 +node_modules/ +orleans.codegen.cs + +# 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 + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# 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/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file From d2cecd270294193019ef2af7772d18f088b1a085 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 11:30:48 -0300 Subject: [PATCH 02/30] Add project files. --- RpsKata.sln | 25 +++++++++++++++++++++++++ RpsKata/RpsKata.csproj | 16 ++++++++++++++++ RpsKata/UnitTest1.cs | 14 ++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 RpsKata.sln create mode 100644 RpsKata/RpsKata.csproj create mode 100644 RpsKata/UnitTest1.cs diff --git a/RpsKata.sln b/RpsKata.sln new file mode 100644 index 0000000..0b2e86e --- /dev/null +++ b/RpsKata.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2010 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RpsKata", "RpsKata\RpsKata.csproj", "{8DFD4066-3694-4534-9F60-35B4C32F3711}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8DFD4066-3694-4534-9F60-35B4C32F3711}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DFD4066-3694-4534-9F60-35B4C32F3711}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DFD4066-3694-4534-9F60-35B4C32F3711}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DFD4066-3694-4534-9F60-35B4C32F3711}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {20C1E714-7B31-4776-8DB8-D66DDD3CD198} + EndGlobalSection +EndGlobal diff --git a/RpsKata/RpsKata.csproj b/RpsKata/RpsKata.csproj new file mode 100644 index 0000000..6179f64 --- /dev/null +++ b/RpsKata/RpsKata.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp2.0 + + false + + + + + + + + + + diff --git a/RpsKata/UnitTest1.cs b/RpsKata/UnitTest1.cs new file mode 100644 index 0000000..e5ba4d9 --- /dev/null +++ b/RpsKata/UnitTest1.cs @@ -0,0 +1,14 @@ +using System; +using Xunit; + +namespace RpsKata +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + + } + } +} From 0487f1f720054e64707250c1330eade43bf69a5a Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 14:53:18 -0300 Subject: [PATCH 03/30] Add system structure --- RpsKata/GameChoice.cs | 13 +++++++++++++ RpsKata/GameResult.cs | 13 +++++++++++++ RpsKata/GameSetup.cs | 12 ++++++++++++ RpsKata/IGameReferee.cs | 11 +++++++++++ RpsKata/UnitTest1.cs | 14 -------------- 5 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 RpsKata/GameChoice.cs create mode 100644 RpsKata/GameResult.cs create mode 100644 RpsKata/GameSetup.cs create mode 100644 RpsKata/IGameReferee.cs delete mode 100644 RpsKata/UnitTest1.cs diff --git a/RpsKata/GameChoice.cs b/RpsKata/GameChoice.cs new file mode 100644 index 0000000..0d36786 --- /dev/null +++ b/RpsKata/GameChoice.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace RpsKata +{ + public enum GameChoice + { + Rock, + Paper, + Scissors + } +} diff --git a/RpsKata/GameResult.cs b/RpsKata/GameResult.cs new file mode 100644 index 0000000..daffb00 --- /dev/null +++ b/RpsKata/GameResult.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace RpsKata +{ + public enum GameResult + { + Draw, + Player1Won, + Player2Won + } +} diff --git a/RpsKata/GameSetup.cs b/RpsKata/GameSetup.cs new file mode 100644 index 0000000..de36c94 --- /dev/null +++ b/RpsKata/GameSetup.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace RpsKata +{ + public class GameSetup + { + public GameChoice Player1Choice { get; set; } + public GameChoice Player2Choice { get; set; } + } +} diff --git a/RpsKata/IGameReferee.cs b/RpsKata/IGameReferee.cs new file mode 100644 index 0000000..589f445 --- /dev/null +++ b/RpsKata/IGameReferee.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace RpsKata +{ + public interface IGameReferee + { + GameResult Evaluate(GameSetup gameSetup); + } +} diff --git a/RpsKata/UnitTest1.cs b/RpsKata/UnitTest1.cs deleted file mode 100644 index e5ba4d9..0000000 --- a/RpsKata/UnitTest1.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Xunit; - -namespace RpsKata -{ - public class UnitTest1 - { - [Fact] - public void Test1() - { - - } - } -} From 26f2405461ad40031a8d11af0225cf7001a1ed00 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 14:54:50 -0300 Subject: [PATCH 04/30] Support Draw (RED) --- RpsKata/SimpleGameReferee.cs | 14 ++++++++++++++ RpsKata/SimpleGameRefereeTest.cs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 RpsKata/SimpleGameReferee.cs create mode 100644 RpsKata/SimpleGameRefereeTest.cs diff --git a/RpsKata/SimpleGameReferee.cs b/RpsKata/SimpleGameReferee.cs new file mode 100644 index 0000000..7ff999b --- /dev/null +++ b/RpsKata/SimpleGameReferee.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace RpsKata +{ + public class SimpleGameReferee : IGameReferee + { + public GameResult Evaluate(GameSetup gameSetup) + { + throw new NotImplementedException(); + } + } +} diff --git a/RpsKata/SimpleGameRefereeTest.cs b/RpsKata/SimpleGameRefereeTest.cs new file mode 100644 index 0000000..fa7549e --- /dev/null +++ b/RpsKata/SimpleGameRefereeTest.cs @@ -0,0 +1,30 @@ +using System; +using Xunit; + +namespace RpsKata +{ + public class SimpleGameRefereeTest + { + [Theory] + [InlineData(GameChoice.Rock)] + [InlineData(GameChoice.Paper)] + [InlineData(GameChoice.Scissors)] + public void Evaluate_same_choice_should_return_Draw(GameChoice selectedChoice) + { + // Arrange + var setup = new GameSetup() + { + Player1Choice = selectedChoice, + Player2Choice = selectedChoice + }; + var expectedResult = GameResult.Draw; + var sut = new SimpleGameReferee(); + + // Act + var result = sut.Evaluate(setup); + + // Assert + Assert.Equal(expectedResult, result); + } + } +} From 57a4a8b756aaf1ded5799bcbc55de2dd420f9c55 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 14:56:04 -0300 Subject: [PATCH 05/30] Support Draw (GREEN) --- RpsKata/SimpleGameReferee.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RpsKata/SimpleGameReferee.cs b/RpsKata/SimpleGameReferee.cs index 7ff999b..a30819f 100644 --- a/RpsKata/SimpleGameReferee.cs +++ b/RpsKata/SimpleGameReferee.cs @@ -8,7 +8,7 @@ public class SimpleGameReferee : IGameReferee { public GameResult Evaluate(GameSetup gameSetup) { - throw new NotImplementedException(); + return GameResult.Draw; } } } From 6c088d6a033bcb96c9292f10e59baef2ecb2802a Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 15:05:08 -0300 Subject: [PATCH 06/30] Avoid wrong Draw results (RED) --- RpsKata/SimpleGameRefereeTest.cs | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/RpsKata/SimpleGameRefereeTest.cs b/RpsKata/SimpleGameRefereeTest.cs index fa7549e..7bf1f68 100644 --- a/RpsKata/SimpleGameRefereeTest.cs +++ b/RpsKata/SimpleGameRefereeTest.cs @@ -26,5 +26,40 @@ public void Evaluate_same_choice_should_return_Draw(GameChoice selectedChoice) // Assert Assert.Equal(expectedResult, result); } + + [Theory] + [InlineData(GameChoice.Rock, GameChoice.Paper)] + [InlineData(GameChoice.Rock, GameChoice.Scissors)] + [InlineData(GameChoice.Paper, GameChoice.Rock)] + [InlineData(GameChoice.Paper, GameChoice.Scissors)] + [InlineData(GameChoice.Scissors, GameChoice.Rock)] + [InlineData(GameChoice.Scissors, GameChoice.Paper)] + public void Evaluate_different_choice_should_not_return_Draw(GameChoice player1Choice, GameChoice player2Choice) + { + // Arrange + var setup = new GameSetup() + { + Player1Choice = player1Choice, + Player2Choice = player2Choice + }; + var wrongResult = GameResult.Draw; + var sut = new SimpleGameReferee(); + + GameResult? result; + + // Act + try + { + result = sut.Evaluate(setup); + } + catch + { + // I am not worry about it in this test + result = null; + } + + // Assert + Assert.NotEqual(wrongResult, result); + } } } From 3a0b451ce4cf5638fb51d4224325020fac691219 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 15:07:44 -0300 Subject: [PATCH 07/30] Avoid wrong Draw results (GREEN) --- RpsKata/SimpleGameReferee.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/RpsKata/SimpleGameReferee.cs b/RpsKata/SimpleGameReferee.cs index a30819f..b7cdb59 100644 --- a/RpsKata/SimpleGameReferee.cs +++ b/RpsKata/SimpleGameReferee.cs @@ -8,7 +8,12 @@ public class SimpleGameReferee : IGameReferee { public GameResult Evaluate(GameSetup gameSetup) { - return GameResult.Draw; + if (gameSetup.Player1Choice == gameSetup.Player2Choice) + { + return GameResult.Draw; + } + + throw new NotImplementedException(); } } } From 8afd357745cf659621189e7563cc9207c647b58c Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 15:30:55 -0300 Subject: [PATCH 08/30] Support right result for when not drawing (RED) I am not following the fine granular TDD approach, and now that I am doing this commit I am thinking that it would be equally easy to apply a granular approach as I did with Draw. Well, it is already done so it tests a lot of scenarios together. --- RpsKata/SimpleGameRefereeTest.cs | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/RpsKata/SimpleGameRefereeTest.cs b/RpsKata/SimpleGameRefereeTest.cs index 7bf1f68..34f9bdb 100644 --- a/RpsKata/SimpleGameRefereeTest.cs +++ b/RpsKata/SimpleGameRefereeTest.cs @@ -61,5 +61,49 @@ public void Evaluate_different_choice_should_not_return_Draw(GameChoice player1C // Assert Assert.NotEqual(wrongResult, result); } + + [Theory] + [InlineData(GameChoice.Rock, GameChoice.Scissors)] + [InlineData(GameChoice.Paper, GameChoice.Rock)] + [InlineData(GameChoice.Scissors, GameChoice.Paper)] + public void Evaluate_some_pairs_should_return_Player1Won(GameChoice player1Choice, GameChoice player2Choice) + { + // Arrange + var setup = new GameSetup() + { + Player1Choice = player1Choice, + Player2Choice = player2Choice + }; + var expectedResult = GameResult.Player1Won; + var sut = new SimpleGameReferee(); + + // Act + var result = sut.Evaluate(setup); + + // Assert + Assert.Equal(expectedResult, result); + } + + [Theory] + [InlineData(GameChoice.Scissors, GameChoice.Rock)] + [InlineData(GameChoice.Rock, GameChoice.Paper)] + [InlineData(GameChoice.Paper, GameChoice.Scissors)] + public void Evaluate_some_pairs_should_return_Player2Won(GameChoice player1Choice, GameChoice player2Choice) + { + // Arrange + var setup = new GameSetup() + { + Player1Choice = player1Choice, + Player2Choice = player2Choice + }; + var expectedResult = GameResult.Player2Won; + var sut = new SimpleGameReferee(); + + // Act + var result = sut.Evaluate(setup); + + // Assert + Assert.Equal(expectedResult, result); + } } } From 12ecfacff7a261b94e75a784e7fc288ce669ffbb Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 15:31:22 -0300 Subject: [PATCH 09/30] Support right result for when not drawing (GREEN) --- RpsKata/SimpleGameReferee.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/RpsKata/SimpleGameReferee.cs b/RpsKata/SimpleGameReferee.cs index b7cdb59..67372d8 100644 --- a/RpsKata/SimpleGameReferee.cs +++ b/RpsKata/SimpleGameReferee.cs @@ -13,7 +13,14 @@ public GameResult Evaluate(GameSetup gameSetup) return GameResult.Draw; } - throw new NotImplementedException(); + if (gameSetup.Player1Choice == GameChoice.Rock && gameSetup.Player2Choice == GameChoice.Scissors + || gameSetup.Player1Choice == GameChoice.Paper && gameSetup.Player2Choice == GameChoice.Rock + || gameSetup.Player1Choice == GameChoice.Scissors && gameSetup.Player2Choice == GameChoice.Paper) + { + return GameResult.Player1Won; + } + + return GameResult.Player2Won; } } } From 12de5245418e42a5ec9370e98eec99490eb11427 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 15:37:50 -0300 Subject: [PATCH 10/30] Refactor tests Since all test have the same structure, I think that it could be a good idea to merge them. Thoughts? --- RpsKata/SimpleGameRefereeTest.cs | 94 ++++---------------------------- 1 file changed, 10 insertions(+), 84 deletions(-) diff --git a/RpsKata/SimpleGameRefereeTest.cs b/RpsKata/SimpleGameRefereeTest.cs index 34f9bdb..0056b9f 100644 --- a/RpsKata/SimpleGameRefereeTest.cs +++ b/RpsKata/SimpleGameRefereeTest.cs @@ -6,89 +6,16 @@ namespace RpsKata public class SimpleGameRefereeTest { [Theory] - [InlineData(GameChoice.Rock)] - [InlineData(GameChoice.Paper)] - [InlineData(GameChoice.Scissors)] - public void Evaluate_same_choice_should_return_Draw(GameChoice selectedChoice) - { - // Arrange - var setup = new GameSetup() - { - Player1Choice = selectedChoice, - Player2Choice = selectedChoice - }; - var expectedResult = GameResult.Draw; - var sut = new SimpleGameReferee(); - - // Act - var result = sut.Evaluate(setup); - - // Assert - Assert.Equal(expectedResult, result); - } - - [Theory] - [InlineData(GameChoice.Rock, GameChoice.Paper)] - [InlineData(GameChoice.Rock, GameChoice.Scissors)] - [InlineData(GameChoice.Paper, GameChoice.Rock)] - [InlineData(GameChoice.Paper, GameChoice.Scissors)] - [InlineData(GameChoice.Scissors, GameChoice.Rock)] - [InlineData(GameChoice.Scissors, GameChoice.Paper)] - public void Evaluate_different_choice_should_not_return_Draw(GameChoice player1Choice, GameChoice player2Choice) - { - // Arrange - var setup = new GameSetup() - { - Player1Choice = player1Choice, - Player2Choice = player2Choice - }; - var wrongResult = GameResult.Draw; - var sut = new SimpleGameReferee(); - - GameResult? result; - - // Act - try - { - result = sut.Evaluate(setup); - } - catch - { - // I am not worry about it in this test - result = null; - } - - // Assert - Assert.NotEqual(wrongResult, result); - } - - [Theory] - [InlineData(GameChoice.Rock, GameChoice.Scissors)] - [InlineData(GameChoice.Paper, GameChoice.Rock)] - [InlineData(GameChoice.Scissors, GameChoice.Paper)] - public void Evaluate_some_pairs_should_return_Player1Won(GameChoice player1Choice, GameChoice player2Choice) - { - // Arrange - var setup = new GameSetup() - { - Player1Choice = player1Choice, - Player2Choice = player2Choice - }; - var expectedResult = GameResult.Player1Won; - var sut = new SimpleGameReferee(); - - // Act - var result = sut.Evaluate(setup); - - // Assert - Assert.Equal(expectedResult, result); - } - - [Theory] - [InlineData(GameChoice.Scissors, GameChoice.Rock)] - [InlineData(GameChoice.Rock, GameChoice.Paper)] - [InlineData(GameChoice.Paper, GameChoice.Scissors)] - public void Evaluate_some_pairs_should_return_Player2Won(GameChoice player1Choice, GameChoice player2Choice) + [InlineData(GameChoice.Rock, GameChoice.Rock, GameResult.Draw)] + [InlineData(GameChoice.Paper, GameChoice.Paper, GameResult.Draw)] + [InlineData(GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw)] + [InlineData(GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won)] + [InlineData(GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won)] + [InlineData(GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won)] + [InlineData(GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won)] + [InlineData(GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won)] + [InlineData(GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won)] + public void Evaluate_all_combinations_should_return_the_expected_result(GameChoice player1Choice, GameChoice player2Choice, GameResult expectedResult) { // Arrange var setup = new GameSetup() @@ -96,7 +23,6 @@ public void Evaluate_some_pairs_should_return_Player2Won(GameChoice player1Choic Player1Choice = player1Choice, Player2Choice = player2Choice }; - var expectedResult = GameResult.Player2Won; var sut = new SimpleGameReferee(); // Act From e8931a9ad3a6fa20e00d2da9b190a15bbd5f5639 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 15:56:33 -0300 Subject: [PATCH 11/30] Add new implementation for rules defined by extension and support testing multiples implementations I am stopping working for the moment, the following steps could be: * Add new referee implementation following [nickmcdowall's Stage 2](https://github.com/nickmcdowall/Rock-Paper-Scissors-Kata/blob/master/README.md#stage-2) * Add support for Spock and Lizard as it is described in [nickmcdowall's Stage 3](https://github.com/nickmcdowall/Rock-Paper-Scissors-Kata/blob/master/README.md#stage-3) * Add richer result object with the action that winner choice does on the looser, for example _rocks **crushes** scissors_ --- RpsKata/ExtensionRulesGameReferee.cs | 29 +++++++++++++++++++ ...eGameRefereeTest.cs => GameRefereeTest.cs} | 18 ++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 RpsKata/ExtensionRulesGameReferee.cs rename RpsKata/{SimpleGameRefereeTest.cs => GameRefereeTest.cs} (72%) diff --git a/RpsKata/ExtensionRulesGameReferee.cs b/RpsKata/ExtensionRulesGameReferee.cs new file mode 100644 index 0000000..acac896 --- /dev/null +++ b/RpsKata/ExtensionRulesGameReferee.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RpsKata +{ + public class ExtensionRulesGameReferee : IGameReferee + { + private (GameChoice player1Choice, GameChoice player2Choice, GameResult result)[] _rules = new[] + { + (GameChoice.Rock, GameChoice.Rock, GameResult.Draw), + (GameChoice.Paper, GameChoice.Paper, GameResult.Draw), + (GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw), + (GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won), + (GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won), + (GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won), + (GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won), + (GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won), + (GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won) + }; + + public GameResult Evaluate(GameSetup gameSetup) => _rules + .Where(x => x.player1Choice == gameSetup.Player1Choice) + .Where(x => x.player2Choice == gameSetup.Player2Choice) + .Select(x => (GameResult?)x.result) + .FirstOrDefault() ?? throw new NotImplementedException("No rule defined for this scenario"); + } +} diff --git a/RpsKata/SimpleGameRefereeTest.cs b/RpsKata/GameRefereeTest.cs similarity index 72% rename from RpsKata/SimpleGameRefereeTest.cs rename to RpsKata/GameRefereeTest.cs index 0056b9f..0ddf0ec 100644 --- a/RpsKata/SimpleGameRefereeTest.cs +++ b/RpsKata/GameRefereeTest.cs @@ -3,8 +3,22 @@ namespace RpsKata { - public class SimpleGameRefereeTest + public class SimpleGameRefereeTest : GameRefereeTest + { } + + public class ExtensionRulesGameRefereeTest : GameRefereeTest + { } + + public abstract class GameRefereeTest : GameRefereeTest + where TSut : IGameReferee, new() + { + protected override IGameReferee GetSut() => new TSut(); + } + + public abstract class GameRefereeTest { + protected abstract IGameReferee GetSut(); + [Theory] [InlineData(GameChoice.Rock, GameChoice.Rock, GameResult.Draw)] [InlineData(GameChoice.Paper, GameChoice.Paper, GameResult.Draw)] @@ -23,7 +37,7 @@ public void Evaluate_all_combinations_should_return_the_expected_result(GameChoi Player1Choice = player1Choice, Player2Choice = player2Choice }; - var sut = new SimpleGameReferee(); + var sut = GetSut(); // Act var result = sut.Evaluate(setup); From 99754126510b1cfa6bc7b6755b32ac5a3ebd6b9e Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sat, 23 Dec 2017 21:46:25 -0300 Subject: [PATCH 12/30] Add new GameReferee with simple rules definition --- RpsKata/GameRefereeTest.cs | 3 +++ RpsKata/WinnerRulesGameReferee.cs | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 RpsKata/WinnerRulesGameReferee.cs diff --git a/RpsKata/GameRefereeTest.cs b/RpsKata/GameRefereeTest.cs index 0ddf0ec..8ae7a3f 100644 --- a/RpsKata/GameRefereeTest.cs +++ b/RpsKata/GameRefereeTest.cs @@ -9,6 +9,9 @@ public class SimpleGameRefereeTest : GameRefereeTest public class ExtensionRulesGameRefereeTest : GameRefereeTest { } + public class WinnerRulesGameRefereeTest : GameRefereeTest + { } + public abstract class GameRefereeTest : GameRefereeTest where TSut : IGameReferee, new() { diff --git a/RpsKata/WinnerRulesGameReferee.cs b/RpsKata/WinnerRulesGameReferee.cs new file mode 100644 index 0000000..c4d09fd --- /dev/null +++ b/RpsKata/WinnerRulesGameReferee.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RpsKata +{ + public class WinnerRulesGameReferee : IGameReferee + { + private (GameChoice winnerChoice, GameChoice looserChoice)[] _rules = new[] + { + (GameChoice.Rock, GameChoice.Scissors), + (GameChoice.Paper, GameChoice.Rock), + (GameChoice.Scissors, GameChoice.Paper) + }; + + public GameResult Evaluate(GameSetup gameSetup) => + _rules.Any(x => x.winnerChoice == gameSetup.Player1Choice && x.looserChoice == gameSetup.Player2Choice) ? GameResult.Player1Won + : _rules.Any(x => x.winnerChoice == gameSetup.Player2Choice && x.looserChoice == gameSetup.Player1Choice) ? GameResult.Player2Won + : GameResult.Draw; + } +} From 4025be9929f91a4c882dacb1f90ee9a364d91f90 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sun, 24 Dec 2017 10:17:36 -0300 Subject: [PATCH 13/30] Take advantage of HashSet O(1) search time complexity --- RpsKata/WinnerRulesGameReferee.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RpsKata/WinnerRulesGameReferee.cs b/RpsKata/WinnerRulesGameReferee.cs index c4d09fd..c9cdd3c 100644 --- a/RpsKata/WinnerRulesGameReferee.cs +++ b/RpsKata/WinnerRulesGameReferee.cs @@ -7,7 +7,7 @@ namespace RpsKata { public class WinnerRulesGameReferee : IGameReferee { - private (GameChoice winnerChoice, GameChoice looserChoice)[] _rules = new[] + private HashSet<(GameChoice winnerChoice, GameChoice looserChoice)> _rules = new HashSet<(GameChoice winnerChoice, GameChoice looserChoice)>() { (GameChoice.Rock, GameChoice.Scissors), (GameChoice.Paper, GameChoice.Rock), @@ -15,8 +15,8 @@ public class WinnerRulesGameReferee : IGameReferee }; public GameResult Evaluate(GameSetup gameSetup) => - _rules.Any(x => x.winnerChoice == gameSetup.Player1Choice && x.looserChoice == gameSetup.Player2Choice) ? GameResult.Player1Won - : _rules.Any(x => x.winnerChoice == gameSetup.Player2Choice && x.looserChoice == gameSetup.Player1Choice) ? GameResult.Player2Won + _rules.Contains((gameSetup.Player1Choice, gameSetup.Player2Choice)) ? GameResult.Player1Won + : _rules.Contains((gameSetup.Player2Choice, gameSetup.Player1Choice)) ? GameResult.Player2Won : GameResult.Draw; } } From 6380c006e459bba32713afa567ad5743d484360d Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sun, 24 Dec 2017 10:35:06 -0300 Subject: [PATCH 14/30] Add support for Spock and Lizard (RED) --- RpsKata/GameChoice.cs | 4 +++- RpsKata/GameRefereeTest.cs | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/RpsKata/GameChoice.cs b/RpsKata/GameChoice.cs index 0d36786..22b4836 100644 --- a/RpsKata/GameChoice.cs +++ b/RpsKata/GameChoice.cs @@ -8,6 +8,8 @@ public enum GameChoice { Rock, Paper, - Scissors + Scissors, + Spock, + Lizard } } diff --git a/RpsKata/GameRefereeTest.cs b/RpsKata/GameRefereeTest.cs index 8ae7a3f..7ed1349 100644 --- a/RpsKata/GameRefereeTest.cs +++ b/RpsKata/GameRefereeTest.cs @@ -26,12 +26,30 @@ public abstract class GameRefereeTest [InlineData(GameChoice.Rock, GameChoice.Rock, GameResult.Draw)] [InlineData(GameChoice.Paper, GameChoice.Paper, GameResult.Draw)] [InlineData(GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw)] + [InlineData(GameChoice.Spock, GameChoice.Spock, GameResult.Draw)] + [InlineData(GameChoice.Lizard, GameChoice.Lizard, GameResult.Draw)] + [InlineData(GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won)] + [InlineData(GameChoice.Rock, GameChoice.Lizard, GameResult.Player1Won)] [InlineData(GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won)] + [InlineData(GameChoice.Paper, GameChoice.Spock, GameResult.Player1Won)] [InlineData(GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won)] + [InlineData(GameChoice.Scissors, GameChoice.Lizard, GameResult.Player1Won)] + [InlineData(GameChoice.Spock, GameChoice.Scissors, GameResult.Player1Won)] + [InlineData(GameChoice.Spock, GameChoice.Rock, GameResult.Player1Won)] + [InlineData(GameChoice.Lizard, GameChoice.Spock, GameResult.Player1Won)] + [InlineData(GameChoice.Lizard, GameChoice.Paper, GameResult.Player1Won)] + [InlineData(GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won)] + [InlineData(GameChoice.Scissors, GameChoice.Spock, GameResult.Player2Won)] [InlineData(GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won)] + [InlineData(GameChoice.Rock, GameChoice.Spock, GameResult.Player2Won)] [InlineData(GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won)] + [InlineData(GameChoice.Paper, GameChoice.Lizard, GameResult.Player2Won)] + [InlineData(GameChoice.Spock, GameChoice.Paper, GameResult.Player2Won)] + [InlineData(GameChoice.Spock, GameChoice.Lizard, GameResult.Player2Won)] + [InlineData(GameChoice.Lizard, GameChoice.Rock, GameResult.Player2Won)] + [InlineData(GameChoice.Lizard, GameChoice.Scissors, GameResult.Player2Won)] public void Evaluate_all_combinations_should_return_the_expected_result(GameChoice player1Choice, GameChoice player2Choice, GameResult expectedResult) { // Arrange From c4034e86b65581bac08269ac45438be742a102f1 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sun, 24 Dec 2017 10:39:56 -0300 Subject: [PATCH 15/30] Add support for Spock and Lizard (RED/GREEN) - Fix SimpleGameReferee --- RpsKata/SimpleGameReferee.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/RpsKata/SimpleGameReferee.cs b/RpsKata/SimpleGameReferee.cs index 67372d8..dacd5a9 100644 --- a/RpsKata/SimpleGameReferee.cs +++ b/RpsKata/SimpleGameReferee.cs @@ -14,8 +14,15 @@ public GameResult Evaluate(GameSetup gameSetup) } if (gameSetup.Player1Choice == GameChoice.Rock && gameSetup.Player2Choice == GameChoice.Scissors + || gameSetup.Player1Choice == GameChoice.Rock && gameSetup.Player2Choice == GameChoice.Lizard || gameSetup.Player1Choice == GameChoice.Paper && gameSetup.Player2Choice == GameChoice.Rock - || gameSetup.Player1Choice == GameChoice.Scissors && gameSetup.Player2Choice == GameChoice.Paper) + || gameSetup.Player1Choice == GameChoice.Paper && gameSetup.Player2Choice == GameChoice.Spock + || gameSetup.Player1Choice == GameChoice.Scissors && gameSetup.Player2Choice == GameChoice.Paper + || gameSetup.Player1Choice == GameChoice.Scissors && gameSetup.Player2Choice == GameChoice.Lizard + || gameSetup.Player1Choice == GameChoice.Spock && gameSetup.Player2Choice == GameChoice.Scissors + || gameSetup.Player1Choice == GameChoice.Spock && gameSetup.Player2Choice == GameChoice.Rock + || gameSetup.Player1Choice == GameChoice.Lizard && gameSetup.Player2Choice == GameChoice.Spock + || gameSetup.Player1Choice == GameChoice.Lizard && gameSetup.Player2Choice == GameChoice.Paper) { return GameResult.Player1Won; } From 579c5650747351bf4eb0b5d68cc8bfa1520ec844 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sun, 24 Dec 2017 10:45:39 -0300 Subject: [PATCH 16/30] Add support for Spock and Lizard (RED/GREEN) - Fix ExtensionRulesGameReferee **Attention!** something is wrong: All test passed when they should not. See the next commit for more information. --- RpsKata/ExtensionRulesGameReferee.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/RpsKata/ExtensionRulesGameReferee.cs b/RpsKata/ExtensionRulesGameReferee.cs index acac896..f08790c 100644 --- a/RpsKata/ExtensionRulesGameReferee.cs +++ b/RpsKata/ExtensionRulesGameReferee.cs @@ -12,12 +12,28 @@ public class ExtensionRulesGameReferee : IGameReferee (GameChoice.Rock, GameChoice.Rock, GameResult.Draw), (GameChoice.Paper, GameChoice.Paper, GameResult.Draw), (GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw), + (GameChoice.Spock, GameChoice.Spock, GameResult.Draw), + (GameChoice.Lizard, GameChoice.Lizard, GameResult.Draw), (GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won), + (GameChoice.Rock, GameChoice.Lizard, GameResult.Player1Won), (GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won), + (GameChoice.Paper, GameChoice.Spock, GameResult.Player1Won), (GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won), + (GameChoice.Scissors, GameChoice.Lizard, GameResult.Player1Won), + (GameChoice.Spock, GameChoice.Scissors, GameResult.Player1Won), + (GameChoice.Spock, GameChoice.Rock, GameResult.Player1Won), + (GameChoice.Lizard, GameChoice.Spock, GameResult.Player1Won), + (GameChoice.Lizard, GameChoice.Paper, GameResult.Player1Won), (GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won), + (GameChoice.Scissors, GameChoice.Spock, GameResult.Player2Won), (GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won), - (GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won) + (GameChoice.Rock, GameChoice.Spock, GameResult.Player2Won), + (GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won), + (GameChoice.Paper, GameChoice.Lizard, GameResult.Player2Won), + (GameChoice.Spock, GameChoice.Paper, GameResult.Player2Won), + (GameChoice.Spock, GameChoice.Lizard, GameResult.Player2Won), + (GameChoice.Lizard, GameChoice.Rock, GameResult.Player2Won), + (GameChoice.Lizard, GameChoice.Scissors, GameResult.Player2Won) }; public GameResult Evaluate(GameSetup gameSetup) => _rules From de7a91f1938c5c17a3a68d522ff2f4dbae0f31e4 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sun, 24 Dec 2017 10:48:18 -0300 Subject: [PATCH 17/30] fixup! Add new GameReferee with simple rules definition Since in commit 99754126510b1cfa6bc7b6755b32ac5a3ebd6b9e I made together the changes in the tests and the new implementation, I did not verify that test failed. **Lesson learned** Always verify that tests fails before fix them. --- RpsKata/GameRefereeTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RpsKata/GameRefereeTest.cs b/RpsKata/GameRefereeTest.cs index 7ed1349..3ea0346 100644 --- a/RpsKata/GameRefereeTest.cs +++ b/RpsKata/GameRefereeTest.cs @@ -9,7 +9,7 @@ public class SimpleGameRefereeTest : GameRefereeTest public class ExtensionRulesGameRefereeTest : GameRefereeTest { } - public class WinnerRulesGameRefereeTest : GameRefereeTest + public class WinnerRulesGameRefereeTest : GameRefereeTest { } public abstract class GameRefereeTest : GameRefereeTest From 836a82d8532e4e592bad3573b5a99ac1f166a6de Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Sun, 24 Dec 2017 11:06:28 -0300 Subject: [PATCH 18/30] Add support for Spock and Lizard (GREEN) - Fix WinnerRulesGameReferee --- RpsKata/WinnerRulesGameReferee.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/RpsKata/WinnerRulesGameReferee.cs b/RpsKata/WinnerRulesGameReferee.cs index c9cdd3c..e927606 100644 --- a/RpsKata/WinnerRulesGameReferee.cs +++ b/RpsKata/WinnerRulesGameReferee.cs @@ -10,8 +10,15 @@ public class WinnerRulesGameReferee : IGameReferee private HashSet<(GameChoice winnerChoice, GameChoice looserChoice)> _rules = new HashSet<(GameChoice winnerChoice, GameChoice looserChoice)>() { (GameChoice.Rock, GameChoice.Scissors), + (GameChoice.Rock, GameChoice.Lizard), (GameChoice.Paper, GameChoice.Rock), - (GameChoice.Scissors, GameChoice.Paper) + (GameChoice.Paper, GameChoice.Spock), + (GameChoice.Scissors, GameChoice.Paper), + (GameChoice.Scissors, GameChoice.Lizard), + (GameChoice.Spock, GameChoice.Scissors), + (GameChoice.Spock, GameChoice.Rock), + (GameChoice.Lizard, GameChoice.Spock), + (GameChoice.Lizard, GameChoice.Paper) }; public GameResult Evaluate(GameSetup gameSetup) => From a6106c3f87b027afd1b9a39bd1d0330d7cdd66fd Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 11:30:08 -0300 Subject: [PATCH 19/30] Move to solution folder based on repo standard --- .../Solutions/amoschini/.gitattributes | 0 .../rock-paper-scissors-no-regex/Solutions/amoschini/.gitignore | 0 .../rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata.sln | 0 .../Solutions/amoschini/RpsKata}/ExtensionRulesGameReferee.cs | 0 .../Solutions/amoschini/RpsKata}/GameChoice.cs | 0 .../Solutions/amoschini/RpsKata}/GameRefereeTest.cs | 0 .../Solutions/amoschini/RpsKata}/GameResult.cs | 0 .../Solutions/amoschini/RpsKata}/GameSetup.cs | 0 .../Solutions/amoschini/RpsKata}/IGameReferee.cs | 0 .../Solutions/amoschini/RpsKata}/RpsKata.csproj | 0 .../Solutions/amoschini/RpsKata}/SimpleGameReferee.cs | 0 .../Solutions/amoschini/RpsKata}/WinnerRulesGameReferee.cs | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename .gitattributes => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitattributes (100%) rename .gitignore => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitignore (100%) rename RpsKata.sln => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata.sln (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/ExtensionRulesGameReferee.cs (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/GameChoice.cs (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/GameRefereeTest.cs (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/GameResult.cs (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/GameSetup.cs (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/IGameReferee.cs (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/RpsKata.csproj (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/SimpleGameReferee.cs (100%) rename {RpsKata => Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata}/WinnerRulesGameReferee.cs (100%) diff --git a/.gitattributes b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitattributes similarity index 100% rename from .gitattributes rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitattributes diff --git a/.gitignore b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitignore similarity index 100% rename from .gitignore rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitignore diff --git a/RpsKata.sln b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata.sln similarity index 100% rename from RpsKata.sln rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata.sln diff --git a/RpsKata/ExtensionRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs similarity index 100% rename from RpsKata/ExtensionRulesGameReferee.cs rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs diff --git a/RpsKata/GameChoice.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameChoice.cs similarity index 100% rename from RpsKata/GameChoice.cs rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameChoice.cs diff --git a/RpsKata/GameRefereeTest.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs similarity index 100% rename from RpsKata/GameRefereeTest.cs rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs diff --git a/RpsKata/GameResult.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs similarity index 100% rename from RpsKata/GameResult.cs rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs diff --git a/RpsKata/GameSetup.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameSetup.cs similarity index 100% rename from RpsKata/GameSetup.cs rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameSetup.cs diff --git a/RpsKata/IGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/IGameReferee.cs similarity index 100% rename from RpsKata/IGameReferee.cs rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/IGameReferee.cs diff --git a/RpsKata/RpsKata.csproj b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/RpsKata.csproj similarity index 100% rename from RpsKata/RpsKata.csproj rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/RpsKata.csproj diff --git a/RpsKata/SimpleGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs similarity index 100% rename from RpsKata/SimpleGameReferee.cs rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs diff --git a/RpsKata/WinnerRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs similarity index 100% rename from RpsKata/WinnerRulesGameReferee.cs rename to Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs From 405afbd9da059db519712825a2bb60e4a9333c5b Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 11:31:30 -0300 Subject: [PATCH 20/30] Add new OOP based solution (RED) --- .../amoschini/RpsKata/GameRefereeTest.cs | 3 + .../RpsKata/OopAdapterRulesGameReferee.cs | 93 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs index 3ea0346..d859720 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs @@ -12,6 +12,9 @@ public class ExtensionRulesGameRefereeTest : GameRefereeTest { } + public class OopAdapterRulesGameRefereeTest : GameRefereeTest + { } + public abstract class GameRefereeTest : GameRefereeTest where TSut : IGameReferee, new() { diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs new file mode 100644 index 0000000..1133d6c --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RpsKata +{ + public class OopAdapterRulesGameReferee : IGameReferee + { + public GameResult Evaluate(GameSetup gameSetup) + { + var player1 = MapEnumToObject(gameSetup.Player1Choice); + var player2 = MapEnumToObject(gameSetup.Player2Choice); + return player1.PlayAgainst(player2); + } + + // This method is only necessary to adapt this new implementation to previous + // interface. If we decided to use this implementation definitivaly, it should + // not be necessary. + private IChoice MapEnumToObject(GameChoice choiceEnum) + { + switch (choiceEnum) + { + case GameChoice.Rock: return new Rock(); + case GameChoice.Paper: return new Paper(); + case GameChoice.Scissors: return new Scissors(); + case GameChoice.Lizard: return new Lizard(); + case GameChoice.Spock: return new Spock(); + default: throw new ArgumentOutOfRangeException(nameof(choiceEnum)); + } + } + + private interface IChoice + { + GameResult PlayAgainst(IChoice player2Choice); + GameResult PlayAgainst(Rock player1Choice); + GameResult PlayAgainst(Paper player1Choice); + GameResult PlayAgainst(Scissors player1Choice); + GameResult PlayAgainst(Lizard player1Choice); + GameResult PlayAgainst(Spock player1Choice); + } + + private class Rock : IChoice + { + public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + } + + private class Paper : IChoice + { + public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + } + + private class Scissors : IChoice + { + public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + } + + private class Lizard : IChoice + { + public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + } + + private class Spock : IChoice + { + public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + } + } +} From fd71e87b28885f92fbf64acb181e8a7fef100460 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 11:32:29 -0300 Subject: [PATCH 21/30] Add new OOP based solution (GREEN / UGLY) --- .../RpsKata/OopAdapterRulesGameReferee.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs index 1133d6c..2f99a08 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -44,49 +44,49 @@ private class Rock : IChoice { public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Player1Won; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Player2Won; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Player2Won; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Player1Won; } private class Paper : IChoice { public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Player2Won; public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Player1Won; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Player1Won; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Player2Won; } private class Scissors : IChoice { public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Player1Won; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Player2Won; public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Player2Won; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Player1Won; } private class Lizard : IChoice { public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Player1Won; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Player2Won; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Player1Won; public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Spock player1Choice) => GameResult.Player2Won; } private class Spock : IChoice { public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; + public GameResult PlayAgainst(Rock player1Choice) => GameResult.Player2Won; + public GameResult PlayAgainst(Paper player1Choice) => GameResult.Player1Won; + public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Player2Won; + public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Player1Won; public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; } } From d32f4873704448d841cbc13896da119d9242a033 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 11:43:48 -0300 Subject: [PATCH 22/30] Add new OOP based solution (GREEN / REFACTOR / STILL UGLY) --- .../RpsKata/OopAdapterRulesGameReferee.cs | 118 ++++++++++-------- 1 file changed, 68 insertions(+), 50 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs index 2f99a08..1b5f558 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -9,85 +9,103 @@ public class OopAdapterRulesGameReferee : IGameReferee { public GameResult Evaluate(GameSetup gameSetup) { - var player1 = MapEnumToObject(gameSetup.Player1Choice); - var player2 = MapEnumToObject(gameSetup.Player2Choice); + var player1 = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won, GameResult.Player2Won); + var player2 = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won, GameResult.Player1Won); return player1.PlayAgainst(player2); } // This method is only necessary to adapt this new implementation to previous // interface. If we decided to use this implementation definitivaly, it should // not be necessary. - private IChoice MapEnumToObject(GameChoice choiceEnum) + private Choice MapEnumToObject(GameChoice choiceEnum, GameResult whoWinIfItWins, GameResult whoWinIfItLooses) { switch (choiceEnum) { - case GameChoice.Rock: return new Rock(); - case GameChoice.Paper: return new Paper(); - case GameChoice.Scissors: return new Scissors(); - case GameChoice.Lizard: return new Lizard(); - case GameChoice.Spock: return new Spock(); + case GameChoice.Rock: return new Rock(whoWinIfItWins, whoWinIfItLooses); + case GameChoice.Paper: return new Paper(whoWinIfItWins, whoWinIfItLooses); + case GameChoice.Scissors: return new Scissors(whoWinIfItWins, whoWinIfItLooses); + case GameChoice.Lizard: return new Lizard(whoWinIfItWins, whoWinIfItLooses); + case GameChoice.Spock: return new Spock(whoWinIfItWins, whoWinIfItLooses); default: throw new ArgumentOutOfRangeException(nameof(choiceEnum)); } } - private interface IChoice + private abstract class Choice { - GameResult PlayAgainst(IChoice player2Choice); - GameResult PlayAgainst(Rock player1Choice); - GameResult PlayAgainst(Paper player1Choice); - GameResult PlayAgainst(Scissors player1Choice); - GameResult PlayAgainst(Lizard player1Choice); - GameResult PlayAgainst(Spock player1Choice); + private readonly GameResult _whoWinIfIWin; + private readonly GameResult _whoWinIfILoose; + + public Choice(GameResult whoWinIfIWin, GameResult whoWinIfILoose) + { + _whoWinIfIWin = whoWinIfIWin; + _whoWinIfILoose = whoWinIfILoose; + } + + protected GameResult Draw() => GameResult.Draw; + protected GameResult IWin() => _whoWinIfIWin; + protected GameResult ILoose() => _whoWinIfILoose; + + public abstract GameResult PlayAgainst(Choice other); + public abstract GameResult PlayAgainst(Rock other); + public abstract GameResult PlayAgainst(Paper other); + public abstract GameResult PlayAgainst(Scissors other); + public abstract GameResult PlayAgainst(Lizard other); + public abstract GameResult PlayAgainst(Spock other); } - private class Rock : IChoice + private class Rock : Choice { - public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Player1Won; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Player2Won; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Player2Won; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Player1Won; + public Rock(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); + public override GameResult PlayAgainst(Rock other) => Draw(); + public override GameResult PlayAgainst(Paper other) => ILoose(); + public override GameResult PlayAgainst(Scissors other) => IWin(); + public override GameResult PlayAgainst(Lizard other) => IWin(); + public override GameResult PlayAgainst(Spock other) => ILoose(); } - private class Paper : IChoice + private class Paper : Choice { - public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Player2Won; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Player1Won; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Player1Won; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Player2Won; + public Paper(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); + public override GameResult PlayAgainst(Rock other) => IWin(); + public override GameResult PlayAgainst(Paper other) => Draw(); + public override GameResult PlayAgainst(Scissors other) => ILoose(); + public override GameResult PlayAgainst(Lizard other) => ILoose(); + public override GameResult PlayAgainst(Spock other) => IWin(); } - private class Scissors : IChoice + private class Scissors : Choice { - public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Player1Won; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Player2Won; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Player2Won; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Player1Won; + public Scissors(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); + public override GameResult PlayAgainst(Rock other) => ILoose(); + public override GameResult PlayAgainst(Paper other) => IWin(); + public override GameResult PlayAgainst(Scissors other) => Draw(); + public override GameResult PlayAgainst(Lizard other) => IWin(); + public override GameResult PlayAgainst(Spock other) => ILoose(); } - private class Lizard : IChoice + private class Lizard : Choice { - public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Player1Won; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Player2Won; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Player1Won; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Draw; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Player2Won; + public Lizard(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); + public override GameResult PlayAgainst(Rock other) => ILoose(); + public override GameResult PlayAgainst(Paper other) => IWin(); + public override GameResult PlayAgainst(Scissors other) => ILoose(); + public override GameResult PlayAgainst(Lizard other) => Draw(); + public override GameResult PlayAgainst(Spock other) => IWin(); } - private class Spock : IChoice + private class Spock : Choice { - public GameResult PlayAgainst(IChoice player2Choice) => player2Choice.PlayAgainst(this); - public GameResult PlayAgainst(Rock player1Choice) => GameResult.Player2Won; - public GameResult PlayAgainst(Paper player1Choice) => GameResult.Player1Won; - public GameResult PlayAgainst(Scissors player1Choice) => GameResult.Player2Won; - public GameResult PlayAgainst(Lizard player1Choice) => GameResult.Player1Won; - public GameResult PlayAgainst(Spock player1Choice) => GameResult.Draw; + public Spock(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); + public override GameResult PlayAgainst(Rock other) => IWin(); + public override GameResult PlayAgainst(Paper other) => ILoose(); + public override GameResult PlayAgainst(Scissors other) => IWin(); + public override GameResult PlayAgainst(Lizard other) => ILoose(); + public override GameResult PlayAgainst(Spock other) => Draw(); } } } From e8c6dd68f54a5ae8a44064626b5dc47946f1ae0a Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 11:50:05 -0300 Subject: [PATCH 23/30] Add new OOP based solution (GREEN) I have removed redundant rules, but I am still not happy with OOP approach, I still prefer rule based one. --- .../RpsKata/OopAdapterRulesGameReferee.cs | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs index 1b5f558..e4d3e49 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -9,23 +9,23 @@ public class OopAdapterRulesGameReferee : IGameReferee { public GameResult Evaluate(GameSetup gameSetup) { - var player1 = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won, GameResult.Player2Won); - var player2 = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won, GameResult.Player1Won); + var player1 = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won); + var player2 = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won); return player1.PlayAgainst(player2); } // This method is only necessary to adapt this new implementation to previous // interface. If we decided to use this implementation definitivaly, it should // not be necessary. - private Choice MapEnumToObject(GameChoice choiceEnum, GameResult whoWinIfItWins, GameResult whoWinIfItLooses) + private Choice MapEnumToObject(GameChoice choiceEnum, GameResult whoWinIfItWins) { switch (choiceEnum) { - case GameChoice.Rock: return new Rock(whoWinIfItWins, whoWinIfItLooses); - case GameChoice.Paper: return new Paper(whoWinIfItWins, whoWinIfItLooses); - case GameChoice.Scissors: return new Scissors(whoWinIfItWins, whoWinIfItLooses); - case GameChoice.Lizard: return new Lizard(whoWinIfItWins, whoWinIfItLooses); - case GameChoice.Spock: return new Spock(whoWinIfItWins, whoWinIfItLooses); + case GameChoice.Rock: return new Rock(whoWinIfItWins); + case GameChoice.Paper: return new Paper(whoWinIfItWins); + case GameChoice.Scissors: return new Scissors(whoWinIfItWins); + case GameChoice.Lizard: return new Lizard(whoWinIfItWins); + case GameChoice.Spock: return new Spock(whoWinIfItWins); default: throw new ArgumentOutOfRangeException(nameof(choiceEnum)); } } @@ -33,17 +33,14 @@ private Choice MapEnumToObject(GameChoice choiceEnum, GameResult whoWinIfItWins, private abstract class Choice { private readonly GameResult _whoWinIfIWin; - private readonly GameResult _whoWinIfILoose; - public Choice(GameResult whoWinIfIWin, GameResult whoWinIfILoose) + public Choice(GameResult whoWinIfIWin) { _whoWinIfIWin = whoWinIfIWin; - _whoWinIfILoose = whoWinIfILoose; } protected GameResult Draw() => GameResult.Draw; protected GameResult IWin() => _whoWinIfIWin; - protected GameResult ILoose() => _whoWinIfILoose; public abstract GameResult PlayAgainst(Choice other); public abstract GameResult PlayAgainst(Rock other); @@ -55,56 +52,56 @@ public Choice(GameResult whoWinIfIWin, GameResult whoWinIfILoose) private class Rock : Choice { - public Rock(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public Rock(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => Draw(); - public override GameResult PlayAgainst(Paper other) => ILoose(); + public override GameResult PlayAgainst(Paper other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Scissors other) => IWin(); public override GameResult PlayAgainst(Lizard other) => IWin(); - public override GameResult PlayAgainst(Spock other) => ILoose(); + public override GameResult PlayAgainst(Spock other) => other.PlayAgainst(this); } private class Paper : Choice { - public Paper(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public Paper(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => IWin(); public override GameResult PlayAgainst(Paper other) => Draw(); - public override GameResult PlayAgainst(Scissors other) => ILoose(); - public override GameResult PlayAgainst(Lizard other) => ILoose(); + public override GameResult PlayAgainst(Scissors other) => other.PlayAgainst(this); + public override GameResult PlayAgainst(Lizard other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Spock other) => IWin(); } private class Scissors : Choice { - public Scissors(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public Scissors(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Rock other) => ILoose(); + public override GameResult PlayAgainst(Rock other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Paper other) => IWin(); public override GameResult PlayAgainst(Scissors other) => Draw(); public override GameResult PlayAgainst(Lizard other) => IWin(); - public override GameResult PlayAgainst(Spock other) => ILoose(); + public override GameResult PlayAgainst(Spock other) => other.PlayAgainst(this); } private class Lizard : Choice { - public Lizard(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public Lizard(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Rock other) => ILoose(); + public override GameResult PlayAgainst(Rock other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Paper other) => IWin(); - public override GameResult PlayAgainst(Scissors other) => ILoose(); + public override GameResult PlayAgainst(Scissors other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Lizard other) => Draw(); public override GameResult PlayAgainst(Spock other) => IWin(); } private class Spock : Choice { - public Spock(GameResult whoWinIfIWin, GameResult whoWinIfILoose) : base(whoWinIfIWin, whoWinIfILoose) { } + public Spock(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => IWin(); - public override GameResult PlayAgainst(Paper other) => ILoose(); + public override GameResult PlayAgainst(Paper other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Scissors other) => IWin(); - public override GameResult PlayAgainst(Lizard other) => ILoose(); + public override GameResult PlayAgainst(Lizard other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Spock other) => Draw(); } } From bd41891e28f5f4af389e1438202cd178d4f94d6d Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 14:58:29 -0300 Subject: [PATCH 24/30] Refactor GameResult as a class in place of an enum --- .../RpsKata/ExtensionRulesGameReferee.cs | 52 ++++++++--------- .../amoschini/RpsKata/GameRefereeTest.cs | 56 ++++++++++--------- .../Solutions/amoschini/RpsKata/GameResult.cs | 19 +++++-- .../RpsKata/OopAdapterRulesGameReferee.cs | 38 ++++++------- .../amoschini/RpsKata/SimpleGameReferee.cs | 6 +- .../RpsKata/WinnerRulesGameReferee.cs | 6 +- 6 files changed, 95 insertions(+), 82 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs index f08790c..320afb3 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs @@ -9,37 +9,37 @@ public class ExtensionRulesGameReferee : IGameReferee { private (GameChoice player1Choice, GameChoice player2Choice, GameResult result)[] _rules = new[] { - (GameChoice.Rock, GameChoice.Rock, GameResult.Draw), - (GameChoice.Paper, GameChoice.Paper, GameResult.Draw), - (GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw), - (GameChoice.Spock, GameChoice.Spock, GameResult.Draw), - (GameChoice.Lizard, GameChoice.Lizard, GameResult.Draw), - (GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won), - (GameChoice.Rock, GameChoice.Lizard, GameResult.Player1Won), - (GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won), - (GameChoice.Paper, GameChoice.Spock, GameResult.Player1Won), - (GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won), - (GameChoice.Scissors, GameChoice.Lizard, GameResult.Player1Won), - (GameChoice.Spock, GameChoice.Scissors, GameResult.Player1Won), - (GameChoice.Spock, GameChoice.Rock, GameResult.Player1Won), - (GameChoice.Lizard, GameChoice.Spock, GameResult.Player1Won), - (GameChoice.Lizard, GameChoice.Paper, GameResult.Player1Won), - (GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won), - (GameChoice.Scissors, GameChoice.Spock, GameResult.Player2Won), - (GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won), - (GameChoice.Rock, GameChoice.Spock, GameResult.Player2Won), - (GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won), - (GameChoice.Paper, GameChoice.Lizard, GameResult.Player2Won), - (GameChoice.Spock, GameChoice.Paper, GameResult.Player2Won), - (GameChoice.Spock, GameChoice.Lizard, GameResult.Player2Won), - (GameChoice.Lizard, GameChoice.Rock, GameResult.Player2Won), - (GameChoice.Lizard, GameChoice.Scissors, GameResult.Player2Won) + (GameChoice.Rock, GameChoice.Rock, GameResult.Draw()), + (GameChoice.Paper, GameChoice.Paper, GameResult.Draw()), + (GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw()), + (GameChoice.Spock, GameChoice.Spock, GameResult.Draw()), + (GameChoice.Lizard, GameChoice.Lizard, GameResult.Draw()), + (GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won()), + (GameChoice.Rock, GameChoice.Lizard, GameResult.Player1Won()), + (GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won()), + (GameChoice.Paper, GameChoice.Spock, GameResult.Player1Won()), + (GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won()), + (GameChoice.Scissors, GameChoice.Lizard, GameResult.Player1Won()), + (GameChoice.Spock, GameChoice.Scissors, GameResult.Player1Won()), + (GameChoice.Spock, GameChoice.Rock, GameResult.Player1Won()), + (GameChoice.Lizard, GameChoice.Spock, GameResult.Player1Won()), + (GameChoice.Lizard, GameChoice.Paper, GameResult.Player1Won()), + (GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won()), + (GameChoice.Scissors, GameChoice.Spock, GameResult.Player2Won()), + (GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won()), + (GameChoice.Rock, GameChoice.Spock, GameResult.Player2Won()), + (GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won()), + (GameChoice.Paper, GameChoice.Lizard, GameResult.Player2Won()), + (GameChoice.Spock, GameChoice.Paper, GameResult.Player2Won()), + (GameChoice.Spock, GameChoice.Lizard, GameResult.Player2Won()), + (GameChoice.Lizard, GameChoice.Rock, GameResult.Player2Won()), + (GameChoice.Lizard, GameChoice.Scissors, GameResult.Player2Won()) }; public GameResult Evaluate(GameSetup gameSetup) => _rules .Where(x => x.player1Choice == gameSetup.Player1Choice) .Where(x => x.player2Choice == gameSetup.Player2Choice) - .Select(x => (GameResult?)x.result) + .Select(x => x.result) .FirstOrDefault() ?? throw new NotImplementedException("No rule defined for this scenario"); } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs index d859720..b48ed6e 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs @@ -26,34 +26,34 @@ public abstract class GameRefereeTest protected abstract IGameReferee GetSut(); [Theory] - [InlineData(GameChoice.Rock, GameChoice.Rock, GameResult.Draw)] - [InlineData(GameChoice.Paper, GameChoice.Paper, GameResult.Draw)] - [InlineData(GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw)] - [InlineData(GameChoice.Spock, GameChoice.Spock, GameResult.Draw)] - [InlineData(GameChoice.Lizard, GameChoice.Lizard, GameResult.Draw)] + [InlineData(GameChoice.Rock, GameChoice.Rock, false, false, true)] + [InlineData(GameChoice.Paper, GameChoice.Paper, false, false, true)] + [InlineData(GameChoice.Scissors, GameChoice.Scissors, false, false, true)] + [InlineData(GameChoice.Spock, GameChoice.Spock, false, false, true)] + [InlineData(GameChoice.Lizard, GameChoice.Lizard, false, false, true)] - [InlineData(GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won)] - [InlineData(GameChoice.Rock, GameChoice.Lizard, GameResult.Player1Won)] - [InlineData(GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won)] - [InlineData(GameChoice.Paper, GameChoice.Spock, GameResult.Player1Won)] - [InlineData(GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won)] - [InlineData(GameChoice.Scissors, GameChoice.Lizard, GameResult.Player1Won)] - [InlineData(GameChoice.Spock, GameChoice.Scissors, GameResult.Player1Won)] - [InlineData(GameChoice.Spock, GameChoice.Rock, GameResult.Player1Won)] - [InlineData(GameChoice.Lizard, GameChoice.Spock, GameResult.Player1Won)] - [InlineData(GameChoice.Lizard, GameChoice.Paper, GameResult.Player1Won)] + [InlineData(GameChoice.Rock, GameChoice.Scissors, true, false, false)] + [InlineData(GameChoice.Rock, GameChoice.Lizard, true, false, false)] + [InlineData(GameChoice.Paper, GameChoice.Rock, true, false, false)] + [InlineData(GameChoice.Paper, GameChoice.Spock, true, false, false)] + [InlineData(GameChoice.Scissors, GameChoice.Paper, true, false, false)] + [InlineData(GameChoice.Scissors, GameChoice.Lizard, true, false, false)] + [InlineData(GameChoice.Spock, GameChoice.Scissors, true, false, false)] + [InlineData(GameChoice.Spock, GameChoice.Rock, true, false, false)] + [InlineData(GameChoice.Lizard, GameChoice.Spock, true, false, false)] + [InlineData(GameChoice.Lizard, GameChoice.Paper, true, false, false)] - [InlineData(GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won)] - [InlineData(GameChoice.Scissors, GameChoice.Spock, GameResult.Player2Won)] - [InlineData(GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won)] - [InlineData(GameChoice.Rock, GameChoice.Spock, GameResult.Player2Won)] - [InlineData(GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won)] - [InlineData(GameChoice.Paper, GameChoice.Lizard, GameResult.Player2Won)] - [InlineData(GameChoice.Spock, GameChoice.Paper, GameResult.Player2Won)] - [InlineData(GameChoice.Spock, GameChoice.Lizard, GameResult.Player2Won)] - [InlineData(GameChoice.Lizard, GameChoice.Rock, GameResult.Player2Won)] - [InlineData(GameChoice.Lizard, GameChoice.Scissors, GameResult.Player2Won)] - public void Evaluate_all_combinations_should_return_the_expected_result(GameChoice player1Choice, GameChoice player2Choice, GameResult expectedResult) + [InlineData(GameChoice.Scissors, GameChoice.Rock, false, true, false)] + [InlineData(GameChoice.Scissors, GameChoice.Spock, false, true, false)] + [InlineData(GameChoice.Rock, GameChoice.Paper, false, true, false)] + [InlineData(GameChoice.Rock, GameChoice.Spock, false, true, false)] + [InlineData(GameChoice.Paper, GameChoice.Scissors, false, true, false)] + [InlineData(GameChoice.Paper, GameChoice.Lizard, false, true, false)] + [InlineData(GameChoice.Spock, GameChoice.Paper, false, true, false)] + [InlineData(GameChoice.Spock, GameChoice.Lizard, false, true, false)] + [InlineData(GameChoice.Lizard, GameChoice.Rock, false, true, false)] + [InlineData(GameChoice.Lizard, GameChoice.Scissors, false, true, false)] + public void Evaluate_all_combinations_should_return_the_expected_result(GameChoice player1Choice, GameChoice player2Choice, bool player1Won, bool player2Won, bool draw) { // Arrange var setup = new GameSetup() @@ -67,7 +67,9 @@ public void Evaluate_all_combinations_should_return_the_expected_result(GameChoi var result = sut.Evaluate(setup); // Assert - Assert.Equal(expectedResult, result); + Assert.Equal(player1Won, result.TheWinnerIsPlayer1); + Assert.Equal(player2Won, result.TheWinnerIsPlayer2); + Assert.Equal(draw, result.ItIsADraw); } } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs index daffb00..2095007 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs @@ -4,10 +4,21 @@ namespace RpsKata { - public enum GameResult + public class GameResult { - Draw, - Player1Won, - Player2Won + public bool TheWinnerIsPlayer1 { get; } + public bool TheWinnerIsPlayer2 { get; } + public bool ItIsADraw { get; } + + private GameResult(bool player1Won, bool player2Won) + { + TheWinnerIsPlayer1 = player1Won; + TheWinnerIsPlayer2 = player2Won; + ItIsADraw = player1Won == player2Won; + } + + public static GameResult Player1Won() => new GameResult(true, false); + public static GameResult Player2Won() => new GameResult(false, true); + public static GameResult Draw() => new GameResult(false, false); } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs index e4d3e49..60c515d 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -9,38 +9,38 @@ public class OopAdapterRulesGameReferee : IGameReferee { public GameResult Evaluate(GameSetup gameSetup) { - var player1 = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won); - var player2 = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won); - return player1.PlayAgainst(player2); + var player1Choice = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won()); + var player2Choice = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won()); + return player1Choice.PlayAgainst(player2Choice); } // This method is only necessary to adapt this new implementation to previous // interface. If we decided to use this implementation definitivaly, it should // not be necessary. - private Choice MapEnumToObject(GameChoice choiceEnum, GameResult whoWinIfItWins) + private Choice MapEnumToObject(GameChoice choiceEnum, GameResult resultIfItWins) { switch (choiceEnum) { - case GameChoice.Rock: return new Rock(whoWinIfItWins); - case GameChoice.Paper: return new Paper(whoWinIfItWins); - case GameChoice.Scissors: return new Scissors(whoWinIfItWins); - case GameChoice.Lizard: return new Lizard(whoWinIfItWins); - case GameChoice.Spock: return new Spock(whoWinIfItWins); + case GameChoice.Rock: return new Rock(resultIfItWins); + case GameChoice.Paper: return new Paper(resultIfItWins); + case GameChoice.Scissors: return new Scissors(resultIfItWins); + case GameChoice.Lizard: return new Lizard(resultIfItWins); + case GameChoice.Spock: return new Spock(resultIfItWins); default: throw new ArgumentOutOfRangeException(nameof(choiceEnum)); } } private abstract class Choice { - private readonly GameResult _whoWinIfIWin; + private readonly GameResult _resultIfIWin; - public Choice(GameResult whoWinIfIWin) + public Choice(GameResult resultIfIWin) { - _whoWinIfIWin = whoWinIfIWin; + _resultIfIWin = resultIfIWin; } - protected GameResult Draw() => GameResult.Draw; - protected GameResult IWin() => _whoWinIfIWin; + protected GameResult Draw() => GameResult.Draw(); + public GameResult IWin() => _resultIfIWin; public abstract GameResult PlayAgainst(Choice other); public abstract GameResult PlayAgainst(Rock other); @@ -52,7 +52,7 @@ public Choice(GameResult whoWinIfIWin) private class Rock : Choice { - public Rock(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } + public Rock(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => Draw(); public override GameResult PlayAgainst(Paper other) => other.PlayAgainst(this); @@ -63,7 +63,7 @@ public Rock(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } private class Paper : Choice { - public Paper(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } + public Paper(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => IWin(); public override GameResult PlayAgainst(Paper other) => Draw(); @@ -74,7 +74,7 @@ public Paper(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } private class Scissors : Choice { - public Scissors(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } + public Scissors(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Paper other) => IWin(); @@ -85,7 +85,7 @@ public Scissors(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } private class Lizard : Choice { - public Lizard(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } + public Lizard(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Paper other) => IWin(); @@ -96,7 +96,7 @@ public Lizard(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } private class Spock : Choice { - public Spock(GameResult whoWinIfIWin) : base(whoWinIfIWin) { } + public Spock(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => IWin(); public override GameResult PlayAgainst(Paper other) => other.PlayAgainst(this); diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs index dacd5a9..3053dc6 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs @@ -10,7 +10,7 @@ public GameResult Evaluate(GameSetup gameSetup) { if (gameSetup.Player1Choice == gameSetup.Player2Choice) { - return GameResult.Draw; + return GameResult.Draw(); } if (gameSetup.Player1Choice == GameChoice.Rock && gameSetup.Player2Choice == GameChoice.Scissors @@ -24,10 +24,10 @@ public GameResult Evaluate(GameSetup gameSetup) || gameSetup.Player1Choice == GameChoice.Lizard && gameSetup.Player2Choice == GameChoice.Spock || gameSetup.Player1Choice == GameChoice.Lizard && gameSetup.Player2Choice == GameChoice.Paper) { - return GameResult.Player1Won; + return GameResult.Player1Won(); } - return GameResult.Player2Won; + return GameResult.Player2Won(); } } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs index e927606..b9099de 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs @@ -22,8 +22,8 @@ public class WinnerRulesGameReferee : IGameReferee }; public GameResult Evaluate(GameSetup gameSetup) => - _rules.Contains((gameSetup.Player1Choice, gameSetup.Player2Choice)) ? GameResult.Player1Won - : _rules.Contains((gameSetup.Player2Choice, gameSetup.Player1Choice)) ? GameResult.Player2Won - : GameResult.Draw; + _rules.Contains((gameSetup.Player1Choice, gameSetup.Player2Choice)) ? GameResult.Player1Won() + : _rules.Contains((gameSetup.Player2Choice, gameSetup.Player1Choice)) ? GameResult.Player2Won() + : GameResult.Draw(); } } From 81a442420c0e9b1353e7cdc1190a335f27e77e62 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 15:10:13 -0300 Subject: [PATCH 25/30] Add explanation to result (RED) --- .../amoschini/RpsKata/GameRefereeTest.cs | 59 +++++++++++-------- .../Solutions/amoschini/RpsKata/GameResult.cs | 1 + 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs index b48ed6e..109bb09 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs @@ -26,34 +26,40 @@ public abstract class GameRefereeTest protected abstract IGameReferee GetSut(); [Theory] - [InlineData(GameChoice.Rock, GameChoice.Rock, false, false, true)] - [InlineData(GameChoice.Paper, GameChoice.Paper, false, false, true)] - [InlineData(GameChoice.Scissors, GameChoice.Scissors, false, false, true)] - [InlineData(GameChoice.Spock, GameChoice.Spock, false, false, true)] - [InlineData(GameChoice.Lizard, GameChoice.Lizard, false, false, true)] + [InlineData(GameChoice.Rock, GameChoice.Rock, false, false, true, "Both players chose Rock")] + [InlineData(GameChoice.Paper, GameChoice.Paper, false, false, true, "Both players chose Paper")] + [InlineData(GameChoice.Scissors, GameChoice.Scissors, false, false, true, "Both players chose Scissors")] + [InlineData(GameChoice.Spock, GameChoice.Spock, false, false, true, "Both players chose Spock")] + [InlineData(GameChoice.Lizard, GameChoice.Lizard, false, false, true, "Both players chose Lizard")] - [InlineData(GameChoice.Rock, GameChoice.Scissors, true, false, false)] - [InlineData(GameChoice.Rock, GameChoice.Lizard, true, false, false)] - [InlineData(GameChoice.Paper, GameChoice.Rock, true, false, false)] - [InlineData(GameChoice.Paper, GameChoice.Spock, true, false, false)] - [InlineData(GameChoice.Scissors, GameChoice.Paper, true, false, false)] - [InlineData(GameChoice.Scissors, GameChoice.Lizard, true, false, false)] - [InlineData(GameChoice.Spock, GameChoice.Scissors, true, false, false)] - [InlineData(GameChoice.Spock, GameChoice.Rock, true, false, false)] - [InlineData(GameChoice.Lizard, GameChoice.Spock, true, false, false)] - [InlineData(GameChoice.Lizard, GameChoice.Paper, true, false, false)] + [InlineData(GameChoice.Rock, GameChoice.Scissors, true, false, false, "Rock crushes Scissors")] + [InlineData(GameChoice.Rock, GameChoice.Lizard, true, false, false, "Rock crushes Lizard")] + [InlineData(GameChoice.Paper, GameChoice.Rock, true, false, false, "Paper covers Rock")] + [InlineData(GameChoice.Paper, GameChoice.Spock, true, false, false, "Paper disproves Spock")] + [InlineData(GameChoice.Scissors, GameChoice.Paper, true, false, false, "Scissors cuts Paper")] + [InlineData(GameChoice.Scissors, GameChoice.Lizard, true, false, false, "Scissors decapitates Lizard")] + [InlineData(GameChoice.Spock, GameChoice.Scissors, true, false, false, "Spock smashes Scissors")] + [InlineData(GameChoice.Spock, GameChoice.Rock, true, false, false, "Spock vaporizes Rock")] + [InlineData(GameChoice.Lizard, GameChoice.Spock, true, false, false, "Lizard poisons Spock")] + [InlineData(GameChoice.Lizard, GameChoice.Paper, true, false, false, "Lizard eats Paper")] - [InlineData(GameChoice.Scissors, GameChoice.Rock, false, true, false)] - [InlineData(GameChoice.Scissors, GameChoice.Spock, false, true, false)] - [InlineData(GameChoice.Rock, GameChoice.Paper, false, true, false)] - [InlineData(GameChoice.Rock, GameChoice.Spock, false, true, false)] - [InlineData(GameChoice.Paper, GameChoice.Scissors, false, true, false)] - [InlineData(GameChoice.Paper, GameChoice.Lizard, false, true, false)] - [InlineData(GameChoice.Spock, GameChoice.Paper, false, true, false)] - [InlineData(GameChoice.Spock, GameChoice.Lizard, false, true, false)] - [InlineData(GameChoice.Lizard, GameChoice.Rock, false, true, false)] - [InlineData(GameChoice.Lizard, GameChoice.Scissors, false, true, false)] - public void Evaluate_all_combinations_should_return_the_expected_result(GameChoice player1Choice, GameChoice player2Choice, bool player1Won, bool player2Won, bool draw) + [InlineData(GameChoice.Scissors, GameChoice.Rock, false, true, false, "Rock crushes Scissors")] + [InlineData(GameChoice.Scissors, GameChoice.Spock, false, true, false, "Spock smashes Scissors")] + [InlineData(GameChoice.Rock, GameChoice.Paper, false, true, false, "Paper covers Rock")] + [InlineData(GameChoice.Rock, GameChoice.Spock, false, true, false, "Spock vaporizes Rock")] + [InlineData(GameChoice.Paper, GameChoice.Scissors, false, true, false, "Scissors cuts Paper")] + [InlineData(GameChoice.Paper, GameChoice.Lizard, false, true, false, "Lizard eats Paper")] + [InlineData(GameChoice.Spock, GameChoice.Paper, false, true, false, "Paper disproves Spock")] + [InlineData(GameChoice.Spock, GameChoice.Lizard, false, true, false, "Lizard poisons Spock")] + [InlineData(GameChoice.Lizard, GameChoice.Rock, false, true, false, "Rock crushes Lizard")] + [InlineData(GameChoice.Lizard, GameChoice.Scissors, false, true, false, "Scissors decapitates Lizard")] + public void Evaluate_all_combinations_should_return_the_expected_result( + GameChoice player1Choice, + GameChoice player2Choice, + bool player1Won, + bool player2Won, + bool draw, + string explanation) { // Arrange var setup = new GameSetup() @@ -70,6 +76,7 @@ public void Evaluate_all_combinations_should_return_the_expected_result(GameChoi Assert.Equal(player1Won, result.TheWinnerIsPlayer1); Assert.Equal(player2Won, result.TheWinnerIsPlayer2); Assert.Equal(draw, result.ItIsADraw); + Assert.Equal(explanation, result.Explanation); } } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs index 2095007..9ec9059 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs @@ -9,6 +9,7 @@ public class GameResult public bool TheWinnerIsPlayer1 { get; } public bool TheWinnerIsPlayer2 { get; } public bool ItIsADraw { get; } + public string Explanation { get; } private GameResult(bool player1Won, bool player2Won) { From 75249f86b40a76d68adbfe9beb46884bf6b9d6b0 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 15:16:45 -0300 Subject: [PATCH 26/30] Add explanation to result (RED) - Fix draw results in all implementations --- .../amoschini/RpsKata/ExtensionRulesGameReferee.cs | 10 +++++----- .../Solutions/amoschini/RpsKata/GameResult.cs | 12 ++++++++---- .../amoschini/RpsKata/OopAdapterRulesGameReferee.cs | 9 ++++++++- .../Solutions/amoschini/RpsKata/SimpleGameReferee.cs | 2 +- .../amoschini/RpsKata/WinnerRulesGameReferee.cs | 2 +- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs index 320afb3..67e98c5 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs @@ -9,11 +9,11 @@ public class ExtensionRulesGameReferee : IGameReferee { private (GameChoice player1Choice, GameChoice player2Choice, GameResult result)[] _rules = new[] { - (GameChoice.Rock, GameChoice.Rock, GameResult.Draw()), - (GameChoice.Paper, GameChoice.Paper, GameResult.Draw()), - (GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw()), - (GameChoice.Spock, GameChoice.Spock, GameResult.Draw()), - (GameChoice.Lizard, GameChoice.Lizard, GameResult.Draw()), + (GameChoice.Rock, GameChoice.Rock, GameResult.Draw(GameChoice.Rock)), + (GameChoice.Paper, GameChoice.Paper, GameResult.Draw(GameChoice.Paper)), + (GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw(GameChoice.Scissors)), + (GameChoice.Spock, GameChoice.Spock, GameResult.Draw(GameChoice.Spock)), + (GameChoice.Lizard, GameChoice.Lizard, GameResult.Draw(GameChoice.Lizard)), (GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won()), (GameChoice.Rock, GameChoice.Lizard, GameResult.Player1Won()), (GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won()), diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs index 9ec9059..1aef7b8 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs @@ -11,15 +11,19 @@ public class GameResult public bool ItIsADraw { get; } public string Explanation { get; } - private GameResult(bool player1Won, bool player2Won) + private GameResult( + bool player1Won, + bool player2Won, + string explanation) { TheWinnerIsPlayer1 = player1Won; TheWinnerIsPlayer2 = player2Won; ItIsADraw = player1Won == player2Won; + Explanation = explanation; } - public static GameResult Player1Won() => new GameResult(true, false); - public static GameResult Player2Won() => new GameResult(false, true); - public static GameResult Draw() => new GameResult(false, false); + public static GameResult Player1Won() => new GameResult(true, false, ""); + public static GameResult Player2Won() => new GameResult(false, true, ""); + public static GameResult Draw(GameChoice choice) => new GameResult(false, false, $"Both players chose {choice.ToString()}"); } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs index 60c515d..e200443 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -39,7 +39,7 @@ public Choice(GameResult resultIfIWin) _resultIfIWin = resultIfIWin; } - protected GameResult Draw() => GameResult.Draw(); + protected GameResult Draw() => GameResult.Draw(ToGameChoice()); public GameResult IWin() => _resultIfIWin; public abstract GameResult PlayAgainst(Choice other); @@ -48,6 +48,8 @@ public Choice(GameResult resultIfIWin) public abstract GameResult PlayAgainst(Scissors other); public abstract GameResult PlayAgainst(Lizard other); public abstract GameResult PlayAgainst(Spock other); + + public abstract GameChoice ToGameChoice(); } private class Rock : Choice @@ -59,6 +61,7 @@ public Rock(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Scissors other) => IWin(); public override GameResult PlayAgainst(Lizard other) => IWin(); public override GameResult PlayAgainst(Spock other) => other.PlayAgainst(this); + public override GameChoice ToGameChoice() => GameChoice.Rock; } private class Paper : Choice @@ -70,6 +73,7 @@ public Paper(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Scissors other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Lizard other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Spock other) => IWin(); + public override GameChoice ToGameChoice() => GameChoice.Paper; } private class Scissors : Choice @@ -81,6 +85,7 @@ public Scissors(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Scissors other) => Draw(); public override GameResult PlayAgainst(Lizard other) => IWin(); public override GameResult PlayAgainst(Spock other) => other.PlayAgainst(this); + public override GameChoice ToGameChoice() => GameChoice.Scissors; } private class Lizard : Choice @@ -92,6 +97,7 @@ public Lizard(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Scissors other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Lizard other) => Draw(); public override GameResult PlayAgainst(Spock other) => IWin(); + public override GameChoice ToGameChoice() => GameChoice.Lizard; } private class Spock : Choice @@ -103,6 +109,7 @@ public Spock(GameResult resultIfIWin) : base(resultIfIWin) { } public override GameResult PlayAgainst(Scissors other) => IWin(); public override GameResult PlayAgainst(Lizard other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Spock other) => Draw(); + public override GameChoice ToGameChoice() => GameChoice.Spock; } } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs index 3053dc6..ecf6ac1 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs @@ -10,7 +10,7 @@ public GameResult Evaluate(GameSetup gameSetup) { if (gameSetup.Player1Choice == gameSetup.Player2Choice) { - return GameResult.Draw(); + return GameResult.Draw(gameSetup.Player1Choice); } if (gameSetup.Player1Choice == GameChoice.Rock && gameSetup.Player2Choice == GameChoice.Scissors diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs index b9099de..9d50df6 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs @@ -24,6 +24,6 @@ public class WinnerRulesGameReferee : IGameReferee public GameResult Evaluate(GameSetup gameSetup) => _rules.Contains((gameSetup.Player1Choice, gameSetup.Player2Choice)) ? GameResult.Player1Won() : _rules.Contains((gameSetup.Player2Choice, gameSetup.Player1Choice)) ? GameResult.Player2Won() - : GameResult.Draw(); + : GameResult.Draw(gameSetup.Player1Choice); } } From a292bd7dff1d76ea7a73325e8a51c376910ecc3c Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 15:32:55 -0300 Subject: [PATCH 27/30] Add explanation to result (RED) - Fix ExtensionRulesGameReferee results --- .../RpsKata/ExtensionRulesGameReferee.cs | 40 +++++++++---------- .../Solutions/amoschini/RpsKata/GameResult.cs | 4 +- .../RpsKata/OopAdapterRulesGameReferee.cs | 4 +- .../amoschini/RpsKata/SimpleGameReferee.cs | 4 +- .../RpsKata/WinnerRulesGameReferee.cs | 4 +- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs index 67e98c5..5f813d5 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs @@ -14,26 +14,26 @@ public class ExtensionRulesGameReferee : IGameReferee (GameChoice.Scissors, GameChoice.Scissors, GameResult.Draw(GameChoice.Scissors)), (GameChoice.Spock, GameChoice.Spock, GameResult.Draw(GameChoice.Spock)), (GameChoice.Lizard, GameChoice.Lizard, GameResult.Draw(GameChoice.Lizard)), - (GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won()), - (GameChoice.Rock, GameChoice.Lizard, GameResult.Player1Won()), - (GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won()), - (GameChoice.Paper, GameChoice.Spock, GameResult.Player1Won()), - (GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won()), - (GameChoice.Scissors, GameChoice.Lizard, GameResult.Player1Won()), - (GameChoice.Spock, GameChoice.Scissors, GameResult.Player1Won()), - (GameChoice.Spock, GameChoice.Rock, GameResult.Player1Won()), - (GameChoice.Lizard, GameChoice.Spock, GameResult.Player1Won()), - (GameChoice.Lizard, GameChoice.Paper, GameResult.Player1Won()), - (GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won()), - (GameChoice.Scissors, GameChoice.Spock, GameResult.Player2Won()), - (GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won()), - (GameChoice.Rock, GameChoice.Spock, GameResult.Player2Won()), - (GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won()), - (GameChoice.Paper, GameChoice.Lizard, GameResult.Player2Won()), - (GameChoice.Spock, GameChoice.Paper, GameResult.Player2Won()), - (GameChoice.Spock, GameChoice.Lizard, GameResult.Player2Won()), - (GameChoice.Lizard, GameChoice.Rock, GameResult.Player2Won()), - (GameChoice.Lizard, GameChoice.Scissors, GameResult.Player2Won()) + (GameChoice.Rock, GameChoice.Scissors, GameResult.Player1Won(GameChoice.Rock, "crushes", GameChoice.Scissors)), + (GameChoice.Rock, GameChoice.Lizard, GameResult.Player1Won(GameChoice.Rock, "crushes", GameChoice.Lizard)), + (GameChoice.Paper, GameChoice.Rock, GameResult.Player1Won(GameChoice.Paper, "covers", GameChoice.Rock)), + (GameChoice.Paper, GameChoice.Spock, GameResult.Player1Won(GameChoice.Paper, "disproves", GameChoice.Spock)), + (GameChoice.Scissors, GameChoice.Paper, GameResult.Player1Won(GameChoice.Scissors, "cuts", GameChoice.Paper)), + (GameChoice.Scissors, GameChoice.Lizard, GameResult.Player1Won(GameChoice.Scissors, "decapitates", GameChoice.Lizard)), + (GameChoice.Spock, GameChoice.Scissors, GameResult.Player1Won(GameChoice.Spock, "smashes", GameChoice.Scissors)), + (GameChoice.Spock, GameChoice.Rock, GameResult.Player1Won(GameChoice.Spock, "vaporizes", GameChoice.Rock)), + (GameChoice.Lizard, GameChoice.Spock, GameResult.Player1Won(GameChoice.Lizard, "poisons", GameChoice.Spock)), + (GameChoice.Lizard, GameChoice.Paper, GameResult.Player1Won(GameChoice.Lizard, "eats", GameChoice.Paper)), + (GameChoice.Scissors, GameChoice.Rock, GameResult.Player2Won(GameChoice.Rock, "crushes", GameChoice.Scissors)), + (GameChoice.Scissors, GameChoice.Spock, GameResult.Player2Won(GameChoice.Spock, "smashes", GameChoice.Scissors)), + (GameChoice.Rock, GameChoice.Paper, GameResult.Player2Won(GameChoice.Paper, "covers", GameChoice.Rock)), + (GameChoice.Rock, GameChoice.Spock, GameResult.Player2Won(GameChoice.Spock, "vaporizes", GameChoice.Rock)), + (GameChoice.Paper, GameChoice.Scissors, GameResult.Player2Won(GameChoice.Scissors, "cuts", GameChoice.Paper)), + (GameChoice.Paper, GameChoice.Lizard, GameResult.Player2Won(GameChoice.Lizard, "eats", GameChoice.Paper)), + (GameChoice.Spock, GameChoice.Paper, GameResult.Player2Won(GameChoice.Paper, "disproves", GameChoice.Spock)), + (GameChoice.Spock, GameChoice.Lizard, GameResult.Player2Won(GameChoice.Lizard, "poisons", GameChoice.Spock)), + (GameChoice.Lizard, GameChoice.Rock, GameResult.Player2Won(GameChoice.Rock, "crushes", GameChoice.Lizard)), + (GameChoice.Lizard, GameChoice.Scissors, GameResult.Player2Won(GameChoice.Scissors, "decapitates", GameChoice.Lizard)) }; public GameResult Evaluate(GameSetup gameSetup) => _rules diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs index 1aef7b8..2931e36 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs @@ -22,8 +22,8 @@ private GameResult( Explanation = explanation; } - public static GameResult Player1Won() => new GameResult(true, false, ""); - public static GameResult Player2Won() => new GameResult(false, true, ""); + public static GameResult Player1Won(GameChoice winnerChoise, string action, GameChoice looserChoice) => new GameResult(true, false, $"{winnerChoise} {action} {looserChoice}"); + public static GameResult Player2Won(GameChoice winnerChoise, string action, GameChoice looserChoice) => new GameResult(false, true, $"{winnerChoise} {action} {looserChoice}"); public static GameResult Draw(GameChoice choice) => new GameResult(false, false, $"Both players chose {choice.ToString()}"); } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs index e200443..5295b3b 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -9,8 +9,8 @@ public class OopAdapterRulesGameReferee : IGameReferee { public GameResult Evaluate(GameSetup gameSetup) { - var player1Choice = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won()); - var player2Choice = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won()); + var player1Choice = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won(gameSetup.Player1Choice, "TODO", gameSetup.Player2Choice)); + var player2Choice = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won(gameSetup.Player2Choice, "TODO", gameSetup.Player1Choice)); return player1Choice.PlayAgainst(player2Choice); } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs index ecf6ac1..f0823d4 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs @@ -24,10 +24,10 @@ public GameResult Evaluate(GameSetup gameSetup) || gameSetup.Player1Choice == GameChoice.Lizard && gameSetup.Player2Choice == GameChoice.Spock || gameSetup.Player1Choice == GameChoice.Lizard && gameSetup.Player2Choice == GameChoice.Paper) { - return GameResult.Player1Won(); + return GameResult.Player1Won(gameSetup.Player1Choice, "TODO", gameSetup.Player2Choice); } - return GameResult.Player2Won(); + return GameResult.Player2Won(gameSetup.Player2Choice, "TODO", gameSetup.Player1Choice); } } } diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs index 9d50df6..4eff207 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs @@ -22,8 +22,8 @@ public class WinnerRulesGameReferee : IGameReferee }; public GameResult Evaluate(GameSetup gameSetup) => - _rules.Contains((gameSetup.Player1Choice, gameSetup.Player2Choice)) ? GameResult.Player1Won() - : _rules.Contains((gameSetup.Player2Choice, gameSetup.Player1Choice)) ? GameResult.Player2Won() + _rules.Contains((gameSetup.Player1Choice, gameSetup.Player2Choice)) ? GameResult.Player1Won(gameSetup.Player1Choice, "TODO", gameSetup.Player2Choice) + : _rules.Contains((gameSetup.Player2Choice, gameSetup.Player1Choice)) ? GameResult.Player2Won(gameSetup.Player2Choice, "TODO", gameSetup.Player1Choice) : GameResult.Draw(gameSetup.Player1Choice); } } From b187a7465a565abbe30e97b2c47750205270daa4 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 15:53:54 -0300 Subject: [PATCH 28/30] Add explanation to result (RED) - Fix SimpleGameReferee --- .../amoschini/RpsKata/SimpleGameReferee.cs | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs index f0823d4..679ffb2 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs @@ -8,26 +8,24 @@ public class SimpleGameReferee : IGameReferee { public GameResult Evaluate(GameSetup gameSetup) { - if (gameSetup.Player1Choice == gameSetup.Player2Choice) - { - return GameResult.Draw(gameSetup.Player1Choice); - } - - if (gameSetup.Player1Choice == GameChoice.Rock && gameSetup.Player2Choice == GameChoice.Scissors - || gameSetup.Player1Choice == GameChoice.Rock && gameSetup.Player2Choice == GameChoice.Lizard - || gameSetup.Player1Choice == GameChoice.Paper && gameSetup.Player2Choice == GameChoice.Rock - || gameSetup.Player1Choice == GameChoice.Paper && gameSetup.Player2Choice == GameChoice.Spock - || gameSetup.Player1Choice == GameChoice.Scissors && gameSetup.Player2Choice == GameChoice.Paper - || gameSetup.Player1Choice == GameChoice.Scissors && gameSetup.Player2Choice == GameChoice.Lizard - || gameSetup.Player1Choice == GameChoice.Spock && gameSetup.Player2Choice == GameChoice.Scissors - || gameSetup.Player1Choice == GameChoice.Spock && gameSetup.Player2Choice == GameChoice.Rock - || gameSetup.Player1Choice == GameChoice.Lizard && gameSetup.Player2Choice == GameChoice.Spock - || gameSetup.Player1Choice == GameChoice.Lizard && gameSetup.Player2Choice == GameChoice.Paper) - { - return GameResult.Player1Won(gameSetup.Player1Choice, "TODO", gameSetup.Player2Choice); - } + return Evaluate(GameResult.Player1Won, gameSetup.Player1Choice, gameSetup.Player2Choice) + ?? Evaluate(GameResult.Player2Won, gameSetup.Player2Choice, gameSetup.Player1Choice) + ?? GameResult.Draw(gameSetup.Player1Choice); + } - return GameResult.Player2Won(gameSetup.Player2Choice, "TODO", gameSetup.Player1Choice); + private GameResult Evaluate(Func playerWon, GameChoice playerAChoice, GameChoice playerBChoice) + { + return playerAChoice == GameChoice.Rock && playerBChoice == GameChoice.Scissors ? playerWon(playerAChoice, "crushes", playerBChoice) + : playerAChoice == GameChoice.Rock && playerBChoice == GameChoice.Lizard ? playerWon(playerAChoice, "crushes", playerBChoice) + : playerAChoice == GameChoice.Paper && playerBChoice == GameChoice.Rock ? playerWon(playerAChoice, "covers", playerBChoice) + : playerAChoice == GameChoice.Paper && playerBChoice == GameChoice.Spock ? playerWon(playerAChoice, "disproves", playerBChoice) + : playerAChoice == GameChoice.Scissors && playerBChoice == GameChoice.Paper ? playerWon(playerAChoice, "cuts", playerBChoice) + : playerAChoice == GameChoice.Scissors && playerBChoice == GameChoice.Lizard ? playerWon(playerAChoice, "decapitates", playerBChoice) + : playerAChoice == GameChoice.Spock && playerBChoice == GameChoice.Scissors ? playerWon(playerAChoice, "smashes", playerBChoice) + : playerAChoice == GameChoice.Spock && playerBChoice == GameChoice.Rock ? playerWon(playerAChoice, "vaporizes", playerBChoice) + : playerAChoice == GameChoice.Lizard && playerBChoice == GameChoice.Spock ? playerWon(playerAChoice, "poisons", playerBChoice) + : playerAChoice == GameChoice.Lizard && playerBChoice == GameChoice.Paper ? playerWon(playerAChoice, "eats", playerBChoice) + : null; } } } From 6aceebbe6be2d6faa4068c3e3da9b01cba5126c6 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 16:00:03 -0300 Subject: [PATCH 29/30] Add explanation to result (RED) - Fix WinnerRulesGameReferee --- .../RpsKata/WinnerRulesGameReferee.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs index 4eff207..6a64cc8 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs @@ -7,23 +7,23 @@ namespace RpsKata { public class WinnerRulesGameReferee : IGameReferee { - private HashSet<(GameChoice winnerChoice, GameChoice looserChoice)> _rules = new HashSet<(GameChoice winnerChoice, GameChoice looserChoice)>() + private Dictionary<(GameChoice winnerChoice, GameChoice looserChoice), string> _verbByRule = new Dictionary<(GameChoice winnerChoice, GameChoice looserChoice), string>() { - (GameChoice.Rock, GameChoice.Scissors), - (GameChoice.Rock, GameChoice.Lizard), - (GameChoice.Paper, GameChoice.Rock), - (GameChoice.Paper, GameChoice.Spock), - (GameChoice.Scissors, GameChoice.Paper), - (GameChoice.Scissors, GameChoice.Lizard), - (GameChoice.Spock, GameChoice.Scissors), - (GameChoice.Spock, GameChoice.Rock), - (GameChoice.Lizard, GameChoice.Spock), - (GameChoice.Lizard, GameChoice.Paper) + [(GameChoice.Rock, GameChoice.Scissors)] = "crushes", + [(GameChoice.Rock, GameChoice.Lizard)] = "crushes", + [(GameChoice.Paper, GameChoice.Rock)] = "covers", + [(GameChoice.Paper, GameChoice.Spock)] = "disproves", + [(GameChoice.Scissors, GameChoice.Paper)] = "cuts", + [(GameChoice.Scissors, GameChoice.Lizard)] = "decapitates", + [(GameChoice.Spock, GameChoice.Scissors)] = "smashes", + [(GameChoice.Spock, GameChoice.Rock)] = "vaporizes", + [(GameChoice.Lizard, GameChoice.Spock)] = "poisons", + [(GameChoice.Lizard, GameChoice.Paper)] = "eats", }; public GameResult Evaluate(GameSetup gameSetup) => - _rules.Contains((gameSetup.Player1Choice, gameSetup.Player2Choice)) ? GameResult.Player1Won(gameSetup.Player1Choice, "TODO", gameSetup.Player2Choice) - : _rules.Contains((gameSetup.Player2Choice, gameSetup.Player1Choice)) ? GameResult.Player2Won(gameSetup.Player2Choice, "TODO", gameSetup.Player1Choice) + _verbByRule.TryGetValue((gameSetup.Player1Choice, gameSetup.Player2Choice), out var verb1) ? GameResult.Player1Won(gameSetup.Player1Choice, verb1, gameSetup.Player2Choice) + : _verbByRule.TryGetValue((gameSetup.Player2Choice, gameSetup.Player1Choice), out var verb2) ? GameResult.Player2Won(gameSetup.Player2Choice, verb2, gameSetup.Player1Choice) : GameResult.Draw(gameSetup.Player1Choice); } } From da2ba9fb6b4ec9178a80151cff6d6d6ea78bcae9 Mon Sep 17 00:00:00 2001 From: Andres Moschini Date: Wed, 27 Dec 2017 16:50:05 -0300 Subject: [PATCH 30/30] Add explanation to result (GREEN) - Fix OopAdapterRulesGameReferee --- .../RpsKata/OopAdapterRulesGameReferee.cs | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs index 5295b3b..95416ce 100644 --- a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -9,38 +9,38 @@ public class OopAdapterRulesGameReferee : IGameReferee { public GameResult Evaluate(GameSetup gameSetup) { - var player1Choice = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won(gameSetup.Player1Choice, "TODO", gameSetup.Player2Choice)); - var player2Choice = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won(gameSetup.Player2Choice, "TODO", gameSetup.Player1Choice)); + var player1Choice = MapEnumToObject(gameSetup.Player1Choice, GameResult.Player1Won); + var player2Choice = MapEnumToObject(gameSetup.Player2Choice, GameResult.Player2Won); return player1Choice.PlayAgainst(player2Choice); } // This method is only necessary to adapt this new implementation to previous // interface. If we decided to use this implementation definitivaly, it should // not be necessary. - private Choice MapEnumToObject(GameChoice choiceEnum, GameResult resultIfItWins) + private Choice MapEnumToObject(GameChoice choiceEnum, Func resultFactoryIfItWins) { switch (choiceEnum) { - case GameChoice.Rock: return new Rock(resultIfItWins); - case GameChoice.Paper: return new Paper(resultIfItWins); - case GameChoice.Scissors: return new Scissors(resultIfItWins); - case GameChoice.Lizard: return new Lizard(resultIfItWins); - case GameChoice.Spock: return new Spock(resultIfItWins); + case GameChoice.Rock: return new Rock(resultFactoryIfItWins); + case GameChoice.Paper: return new Paper(resultFactoryIfItWins); + case GameChoice.Scissors: return new Scissors(resultFactoryIfItWins); + case GameChoice.Lizard: return new Lizard(resultFactoryIfItWins); + case GameChoice.Spock: return new Spock(resultFactoryIfItWins); default: throw new ArgumentOutOfRangeException(nameof(choiceEnum)); } } private abstract class Choice { - private readonly GameResult _resultIfIWin; + private readonly Func _resultFactoryIfItWins; - public Choice(GameResult resultIfIWin) + public Choice(Func resultFactoryIfItWins) { - _resultIfIWin = resultIfIWin; + _resultFactoryIfItWins = resultFactoryIfItWins; } protected GameResult Draw() => GameResult.Draw(ToGameChoice()); - public GameResult IWin() => _resultIfIWin; + public GameResult IWin(string verb, Choice looser) => _resultFactoryIfItWins(ToGameChoice(), verb, looser.ToGameChoice()); public abstract GameResult PlayAgainst(Choice other); public abstract GameResult PlayAgainst(Rock other); @@ -54,59 +54,59 @@ public Choice(GameResult resultIfIWin) private class Rock : Choice { - public Rock(GameResult resultIfIWin) : base(resultIfIWin) { } + public Rock(Func resultFactoryIfItWins) : base(resultFactoryIfItWins) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => Draw(); public override GameResult PlayAgainst(Paper other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Scissors other) => IWin(); - public override GameResult PlayAgainst(Lizard other) => IWin(); + public override GameResult PlayAgainst(Scissors other) => IWin("crushes", other); + public override GameResult PlayAgainst(Lizard other) => IWin("crushes", other); public override GameResult PlayAgainst(Spock other) => other.PlayAgainst(this); public override GameChoice ToGameChoice() => GameChoice.Rock; } private class Paper : Choice { - public Paper(GameResult resultIfIWin) : base(resultIfIWin) { } + public Paper(Func resultFactoryIfItWins) : base(resultFactoryIfItWins) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Rock other) => IWin(); + public override GameResult PlayAgainst(Rock other) => IWin("covers", other); public override GameResult PlayAgainst(Paper other) => Draw(); public override GameResult PlayAgainst(Scissors other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Lizard other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Spock other) => IWin(); + public override GameResult PlayAgainst(Spock other) => IWin("disproves", other); public override GameChoice ToGameChoice() => GameChoice.Paper; } private class Scissors : Choice { - public Scissors(GameResult resultIfIWin) : base(resultIfIWin) { } + public Scissors(Func resultFactoryIfItWins) : base(resultFactoryIfItWins) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Paper other) => IWin(); + public override GameResult PlayAgainst(Paper other) => IWin("cuts", other); public override GameResult PlayAgainst(Scissors other) => Draw(); - public override GameResult PlayAgainst(Lizard other) => IWin(); + public override GameResult PlayAgainst(Lizard other) => IWin("decapitates", other); public override GameResult PlayAgainst(Spock other) => other.PlayAgainst(this); public override GameChoice ToGameChoice() => GameChoice.Scissors; } private class Lizard : Choice { - public Lizard(GameResult resultIfIWin) : base(resultIfIWin) { } + public Lizard(Func resultFactoryIfItWins) : base(resultFactoryIfItWins) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Rock other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Paper other) => IWin(); + public override GameResult PlayAgainst(Paper other) => IWin("eats", other); public override GameResult PlayAgainst(Scissors other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Lizard other) => Draw(); - public override GameResult PlayAgainst(Spock other) => IWin(); + public override GameResult PlayAgainst(Spock other) => IWin("poisons", other); public override GameChoice ToGameChoice() => GameChoice.Lizard; } private class Spock : Choice { - public Spock(GameResult resultIfIWin) : base(resultIfIWin) { } + public Spock(Func resultFactoryIfItWins) : base(resultFactoryIfItWins) { } public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Rock other) => IWin(); + public override GameResult PlayAgainst(Rock other) => IWin("vaporizes", other); public override GameResult PlayAgainst(Paper other) => other.PlayAgainst(this); - public override GameResult PlayAgainst(Scissors other) => IWin(); + public override GameResult PlayAgainst(Scissors other) => IWin("smashes", other); public override GameResult PlayAgainst(Lizard other) => other.PlayAgainst(this); public override GameResult PlayAgainst(Spock other) => Draw(); public override GameChoice ToGameChoice() => GameChoice.Spock;