diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitattributes b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.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/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitignore b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.gitignore new file mode 100644 index 0000000..3c4efe2 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/.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 diff --git a/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata.sln b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata.sln new file mode 100644 index 0000000..0b2e86e --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/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/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs new file mode 100644 index 0000000..5f813d5 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/ExtensionRulesGameReferee.cs @@ -0,0 +1,45 @@ +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.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, "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 + .Where(x => x.player1Choice == gameSetup.Player1Choice) + .Where(x => x.player2Choice == gameSetup.Player2Choice) + .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/GameChoice.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameChoice.cs new file mode 100644 index 0000000..22b4836 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameChoice.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace RpsKata +{ + public enum GameChoice + { + Rock, + Paper, + Scissors, + Spock, + Lizard + } +} 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 new file mode 100644 index 0000000..109bb09 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameRefereeTest.cs @@ -0,0 +1,82 @@ +using System; +using Xunit; + +namespace RpsKata +{ + public class SimpleGameRefereeTest : GameRefereeTest + { } + + public class ExtensionRulesGameRefereeTest : GameRefereeTest + { } + + public class WinnerRulesGameRefereeTest : GameRefereeTest + { } + + public class OopAdapterRulesGameRefereeTest : 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, 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, "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, "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() + { + Player1Choice = player1Choice, + Player2Choice = player2Choice + }; + var sut = GetSut(); + + // Act + var result = sut.Evaluate(setup); + + // Assert + 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 new file mode 100644 index 0000000..2931e36 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameResult.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace RpsKata +{ + 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, + string explanation) + { + TheWinnerIsPlayer1 = player1Won; + TheWinnerIsPlayer2 = player2Won; + ItIsADraw = player1Won == player2Won; + Explanation = explanation; + } + + 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/GameSetup.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/GameSetup.cs new file mode 100644 index 0000000..de36c94 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/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/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/IGameReferee.cs b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/IGameReferee.cs new file mode 100644 index 0000000..589f445 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/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/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..95416ce --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/OopAdapterRulesGameReferee.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RpsKata +{ + public class OopAdapterRulesGameReferee : IGameReferee + { + public GameResult Evaluate(GameSetup gameSetup) + { + 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, Func resultFactoryIfItWins) + { + switch (choiceEnum) + { + 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 Func _resultFactoryIfItWins; + + public Choice(Func resultFactoryIfItWins) + { + _resultFactoryIfItWins = resultFactoryIfItWins; + } + + protected GameResult Draw() => GameResult.Draw(ToGameChoice()); + public GameResult IWin(string verb, Choice looser) => _resultFactoryIfItWins(ToGameChoice(), verb, looser.ToGameChoice()); + + 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); + + public abstract GameChoice ToGameChoice(); + } + + private class Rock : Choice + { + 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("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(Func resultFactoryIfItWins) : base(resultFactoryIfItWins) { } + public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); + 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("disproves", other); + public override GameChoice ToGameChoice() => GameChoice.Paper; + } + + private class Scissors : Choice + { + 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("cuts", other); + public override GameResult PlayAgainst(Scissors other) => Draw(); + 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(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("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("poisons", other); + public override GameChoice ToGameChoice() => GameChoice.Lizard; + } + + private class Spock : Choice + { + public Spock(Func resultFactoryIfItWins) : base(resultFactoryIfItWins) { } + public override GameResult PlayAgainst(Choice other) => other.PlayAgainst(this); + 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("smashes", other); + 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/RpsKata.csproj b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/RpsKata.csproj new file mode 100644 index 0000000..6179f64 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/RpsKata.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp2.0 + + false + + + + + + + + + + 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 new file mode 100644 index 0000000..679ffb2 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/SimpleGameReferee.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace RpsKata +{ + public class SimpleGameReferee : IGameReferee + { + public GameResult Evaluate(GameSetup gameSetup) + { + return Evaluate(GameResult.Player1Won, gameSetup.Player1Choice, gameSetup.Player2Choice) + ?? Evaluate(GameResult.Player2Won, gameSetup.Player2Choice, gameSetup.Player1Choice) + ?? GameResult.Draw(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; + } + } +} 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 new file mode 100644 index 0000000..6a64cc8 --- /dev/null +++ b/Miscellaneous/rock-paper-scissors-no-regex/Solutions/amoschini/RpsKata/WinnerRulesGameReferee.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RpsKata +{ + public class WinnerRulesGameReferee : IGameReferee + { + private Dictionary<(GameChoice winnerChoice, GameChoice looserChoice), string> _verbByRule = new Dictionary<(GameChoice winnerChoice, GameChoice looserChoice), string>() + { + [(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) => + _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); + } +}