From b5997ced9978485095447ee68a2610518ce0ce55 Mon Sep 17 00:00:00 2001 From: Gardient Date: Fri, 1 Jul 2016 00:31:12 +0300 Subject: [PATCH] ze poker hand checker --- BehavioralPatterns.sln | 16 ++-- .../BehavioralPatterns.xproj | 2 +- src/BehavioralPatterns/Program.cs | 73 ++++++++------- .../Properties/AssemblyInfo.cs | 2 +- src/BehavioralPatterns/project.json | 12 +-- src/ChainOfResponssibility/Poker/Card.cs | 90 +++++++++++++++++++ src/ChainOfResponssibility/Poker/PokerGame.cs | 38 ++++++++ .../Poker/Validators/CardSuiteValidatior.cs | 16 ++++ .../Poker/Validators/CardValidationFactory.cs | 24 +++++ .../Poker/Validators/CardValueValidator.cs | 16 ++++ .../HandValidators/FlushValidation.cs | 17 ++++ .../HandValidators/FourOfAKindValidation.cs | 17 ++++ .../HandValidators/FullHouseValidation.cs | 21 +++++ .../HandValidators/HandValidation.cs | 28 ++++++ .../HandValidators/HandValidationFactory.cs | 45 ++++++++++ .../HandValidators/HighCardValidation.cs | 13 +++ .../HandValidators/PairValidation.cs | 17 ++++ .../HandValidators/RoyalFlushValidation.cs | 23 +++++ .../HandValidators/StraightFlushValidation.cs | 29 ++++++ .../HandValidators/StraightValidation.cs | 22 +++++ .../HandValidators/ThreeOfAKindValidation.cs | 17 ++++ .../HandValidators/TwoPairsValidation.cs | 17 ++++ .../RunChainOfResponsibillityExamples.cs | 82 +++++++++++------ .../Validators/UserEntities/UserProcessor.cs | 10 +-- src/ChainOfResponssibility/project.json | 4 +- src/CommandPattern/CommandPatternExamples.cs | 12 +-- src/CommandPattern/project.json | 7 +- src/IteratorPattern/project.json | 4 +- src/MediatorPattern/project.json | 4 +- src/MememntoPattern/project.json | 4 +- .../ObserverPatternExamples.cs | 73 +-------------- .../Twits/ObservableTwitsExample.cs | 16 ++-- src/ObserverPattern/Twits/TwitObservable.cs | 19 +++- src/ObserverPattern/project.json | 5 +- 34 files changed, 612 insertions(+), 183 deletions(-) create mode 100644 src/ChainOfResponssibility/Poker/Card.cs create mode 100644 src/ChainOfResponssibility/Poker/PokerGame.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/CardSuiteValidatior.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/CardValidationFactory.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/CardValueValidator.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/FlushValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/FourOfAKindValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/FullHouseValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/HandValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/HandValidationFactory.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/HighCardValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/PairValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/RoyalFlushValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/StraightFlushValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/StraightValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/ThreeOfAKindValidation.cs create mode 100644 src/ChainOfResponssibility/Poker/Validators/HandValidators/TwoPairsValidation.cs diff --git a/BehavioralPatterns.sln b/BehavioralPatterns.sln index c6819c9..c56791e 100644 --- a/BehavioralPatterns.sln +++ b/BehavioralPatterns.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3820200F-354C-41E6-8F34-B301F5D621C2}" EndProject @@ -10,6 +10,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution global.json = global.json EndProjectSection EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "BehavioralPatterns", "src\BehavioralPatterns\BehavioralPatterns.xproj", "{E3092EE0-1282-4AB4-9FA2-0338348D8FD1}" +EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ChainOfResponssibility", "src\ChainOfResponssibility\ChainOfResponssibility.xproj", "{89536824-683F-4351-8789-406D7BDD922D}" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CommandPattern", "src\CommandPattern\CommandPattern.xproj", "{454B2A43-8251-4667-8DE3-67E489908DB9}" @@ -22,8 +24,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MememntoPattern", "src\Meme EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ObserverPattern", "src\ObserverPattern\ObserverPattern.xproj", "{D48DB558-0228-4ACE-88A8-A202E5C57849}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "BehavioralPatterns", "src\BehavioralPatterns\BehavioralPatterns.xproj", "{7843B0F8-7530-4859-8BEE-43D370E0F0AA}" -EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StatePattern", "src\StatePattern\StatePattern.xproj", "{0B5B470D-45A4-4F6B-8DAD-D0116C40B6FB}" EndProject Global @@ -32,6 +32,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Release|Any CPU.Build.0 = Release|Any CPU {89536824-683F-4351-8789-406D7BDD922D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {89536824-683F-4351-8789-406D7BDD922D}.Debug|Any CPU.Build.0 = Debug|Any CPU {89536824-683F-4351-8789-406D7BDD922D}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -56,10 +60,6 @@ Global {D48DB558-0228-4ACE-88A8-A202E5C57849}.Debug|Any CPU.Build.0 = Debug|Any CPU {D48DB558-0228-4ACE-88A8-A202E5C57849}.Release|Any CPU.ActiveCfg = Release|Any CPU {D48DB558-0228-4ACE-88A8-A202E5C57849}.Release|Any CPU.Build.0 = Release|Any CPU - {7843B0F8-7530-4859-8BEE-43D370E0F0AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7843B0F8-7530-4859-8BEE-43D370E0F0AA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7843B0F8-7530-4859-8BEE-43D370E0F0AA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7843B0F8-7530-4859-8BEE-43D370E0F0AA}.Release|Any CPU.Build.0 = Release|Any CPU {0B5B470D-45A4-4F6B-8DAD-D0116C40B6FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0B5B470D-45A4-4F6B-8DAD-D0116C40B6FB}.Debug|Any CPU.Build.0 = Debug|Any CPU {0B5B470D-45A4-4F6B-8DAD-D0116C40B6FB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -69,13 +69,13 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {E3092EE0-1282-4AB4-9FA2-0338348D8FD1} = {3820200F-354C-41E6-8F34-B301F5D621C2} {89536824-683F-4351-8789-406D7BDD922D} = {3820200F-354C-41E6-8F34-B301F5D621C2} {454B2A43-8251-4667-8DE3-67E489908DB9} = {3820200F-354C-41E6-8F34-B301F5D621C2} {6F3B7F9A-4D9C-4506-A5F7-3FF5CF4376BD} = {3820200F-354C-41E6-8F34-B301F5D621C2} {2A63BD0A-9D07-4755-9B16-5DDBEB075B80} = {3820200F-354C-41E6-8F34-B301F5D621C2} {1DE3FDD3-D025-49D8-BEF4-D5F0688F89E8} = {3820200F-354C-41E6-8F34-B301F5D621C2} {D48DB558-0228-4ACE-88A8-A202E5C57849} = {3820200F-354C-41E6-8F34-B301F5D621C2} - {7843B0F8-7530-4859-8BEE-43D370E0F0AA} = {3820200F-354C-41E6-8F34-B301F5D621C2} {0B5B470D-45A4-4F6B-8DAD-D0116C40B6FB} = {3820200F-354C-41E6-8F34-B301F5D621C2} EndGlobalSection EndGlobal diff --git a/src/BehavioralPatterns/BehavioralPatterns.xproj b/src/BehavioralPatterns/BehavioralPatterns.xproj index cbaf38a..7cf4f9e 100644 --- a/src/BehavioralPatterns/BehavioralPatterns.xproj +++ b/src/BehavioralPatterns/BehavioralPatterns.xproj @@ -7,7 +7,7 @@ - 7843b0f8-7530-4859-8bee-43d370e0f0aa + e3092ee0-1282-4ab4-9fa2-0338348d8fd1 BehavioralPatterns .\obj .\bin\ diff --git a/src/BehavioralPatterns/Program.cs b/src/BehavioralPatterns/Program.cs index da96247..1aaa795 100644 --- a/src/BehavioralPatterns/Program.cs +++ b/src/BehavioralPatterns/Program.cs @@ -1,12 +1,13 @@ using ChainOfResponssibility; +using ChainOfResponssibility.PurchaseExample; using CommandPattern; using IteratorPattern; using MediatorPattern; using MememntoPattern; using ObserverPattern; -using StatePattern; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; @@ -16,41 +17,45 @@ namespace BehavioralPatterns { public static void Main(string[] args) { - StatePatternExamples.Run(); - GoToNextStep(); - //Chain of responsibillity - //This is usefull when you have a request and you don't know who should process it - ChainOfResponsibillityExamples.Run(); - GoToNextStep(); + while (true) + { + Console.Write("1: Chain of responsibility\r\n"); + Console.Write("2: Iterator Pattern\r\n"); + Console.Write("3: Observer Pattern\r\n"); + Console.Write("4: Command Pattern\r\n"); + Console.Write("5: Mediator Pattern\r\n"); + Console.Write("6: Memento Pattern\r\n"); + Console.Write("0: exit\r\n>"); + var key = Console.ReadKey(); - CommandPatternExamples.Run(); - GoToNextStep(); + Console.Clear(); - IteratorPatternExamples.Run(); - GoToNextStep(); - - IteratorPatternExamples.Run(); - - GoToNextStep(); - - MediatorPatternExamples.Run(); - - GoToNextStep(); - - MementoPatternExamples.Run(); - - GoToNextStep(); - - ObserverPatternExamples.Run(); - GoToNextStep(); - - - } - - private static void GoToNextStep() - { - Console.ReadKey(); - Console.Clear(); + switch (key.KeyChar) + { + case '1': + //Chain of responsibillity + //This is usefull when you have a request and you don't know who should process it + ChainOfResponsibillityExamples.Run(); + break; + case '2': + IteratorPatternExamples.Run(); + break; + case '3': + ObserverPatternExamples.Run(); + break; + case '4': + CommandPatternExamples.Run(); + break; + case '5': + MediatorPatternExamples.Run(); + break; + case '6': + MementoPatternExamples.Run(); + break; + } + if (key.KeyChar == '0') + break; + } } } } diff --git a/src/BehavioralPatterns/Properties/AssemblyInfo.cs b/src/BehavioralPatterns/Properties/AssemblyInfo.cs index 163a2da..42755e8 100644 --- a/src/BehavioralPatterns/Properties/AssemblyInfo.cs +++ b/src/BehavioralPatterns/Properties/AssemblyInfo.cs @@ -16,4 +16,4 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7843b0f8-7530-4859-8bee-43d370e0f0aa")] +[assembly: Guid("e3092ee0-1282-4ab4-9fa2-0338348d8fd1")] diff --git a/src/BehavioralPatterns/project.json b/src/BehavioralPatterns/project.json index 523d334..3165efd 100644 --- a/src/BehavioralPatterns/project.json +++ b/src/BehavioralPatterns/project.json @@ -1,7 +1,10 @@ -{ +{ "version": "1.0.0-*", "buildOptions": { - "emitEntryPoint": true + "emitEntryPoint": true, + "copyToOutput": { + "include": "../IteratorPattern/FileExample/SampleFiles/**" + } }, "dependencies": { @@ -12,10 +15,9 @@ "MememntoPattern": "1.0.0-*", "Microsoft.NETCore.App": { "type": "platform", - "version": "1.0.0" + "version": "1.0.0-rc2-3002702" }, - "ObserverPattern": "1.0.0-*", - "StatePattern": "1.0.0-*" + "ObserverPattern": "1.0.0-*" }, "frameworks": { diff --git a/src/ChainOfResponssibility/Poker/Card.cs b/src/ChainOfResponssibility/Poker/Card.cs new file mode 100644 index 0000000..4f4532e --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Card.cs @@ -0,0 +1,90 @@ +using System; +using ChainOfResponssibility.Validators; +using ChainOfResponssibility.Poker.Validators; + +namespace ChainOfResponssibility.Poker +{ + public class Card : IEquatable + { + public const string ValidValues = "2,3,4,5,6,7,8,9,10,J,Q,K,A"; + public const string ValidSuites = "C,H,S,D"; + + public string Value { get; private set; } + public char Suite { get; private set; } + public static ChainValidation CardValidatorFactory { get; private set; } + + public Card(string value, char suite) + { + Value = value.ToUpper(); + Suite = suite.ToString().ToUpper()[0]; + } + + public static Card Parse(string toParse) + { + Card c = null; + switch (toParse.Length) + { + case 2: + c = new Card(toParse[0].ToString(), toParse[1]); + break; + case 3: + c = new Card(toParse.Substring(0, 2), toParse[2]); + break; + default: + throw new ArgumentException(string.Format("Must be in format VS where V is one of [{0}] and S is one of [{1}]", ValidValues, ValidSuites), nameof(toParse)); + } + + ChainValidation Validation = CardValidationFactory.GetValidator(); + + var validationResult = Validation.Validate(c); + + if (!validationResult.IsValid) + throw validationResult.Exception; + + return c; + } + + public int GetIntValue() + { + int val = 0; + if (int.TryParse(Value, out val)) + return val; + else + switch (Value) + { + case "J": + return 11; + case "Q": + return 12; + case "K": + return 13; + case "A": + return 14; + } + return 0; + } + + public bool Equals(Card other) + { + if (this.Value == other.Value && this.Suite == other.Suite) + return true; + + return false; + } + + public static bool operator ==(Card c1, Card c2) + { + return c1.Equals(c2); + } + + public static bool operator !=(Card c1, Card c2) + { + return !c1.Equals(c2); + } + + public override string ToString() + { + return Value + Suite; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/PokerGame.cs b/src/ChainOfResponssibility/Poker/PokerGame.cs new file mode 100644 index 0000000..e359211 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/PokerGame.cs @@ -0,0 +1,38 @@ +using ChainOfResponssibility.Poker.Validators.HandValidators; +using System; +using System.Linq; + +namespace ChainOfResponssibility.Poker +{ + public class PokerGame + { + public void newGame() + { + Console.WriteLine("!!NOT AN ACTUAL POKER GAME!!{0}{1}{0}{2}{0}{3}{0}{4}{0}{5}", Environment.NewLine, + "This tells you what hand you have", + "Just enter the 5 cards you have, separated with spaces, and press enter", + "Card values: 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A", + "Card Suites: H, D, C, S", + "ex.:\"QH AH JH KH 10H\" (yes that is a royal flush right there)"); + + string cards = string.Empty; + while (cards.ToLower()!="exit") + { + Console.Write(">"); + cards = Console.ReadLine(); + + try + { + var hand = cards.Split(' ').Select(x => Card.Parse(x)).OrderBy(x=>x.GetIntValue()).ToArray(); + Console.WriteLine(HandValidationFactory.GetValidation().Validate(hand)); + } + catch (Exception e) + { + Console.WriteLine(e); + continue; + } + } + Console.Clear(); + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/CardSuiteValidatior.cs b/src/ChainOfResponssibility/Poker/Validators/CardSuiteValidatior.cs new file mode 100644 index 0000000..dd55b0e --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/CardSuiteValidatior.cs @@ -0,0 +1,16 @@ +using ChainOfResponssibility.Validators; +using System; +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators +{ + public class CardSuiteValidation : ChainValidation + { + protected override ValidationResult IsValid(Card obj) + { + if (Card.ValidSuites.Contains(obj.Suite)) + return ValidationResult.GetValidResult(); + return ValidationResult.GetInvalidResult(new Exception("Invalid Suite, must be one of " + Card.ValidSuites)); + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/CardValidationFactory.cs b/src/ChainOfResponssibility/Poker/Validators/CardValidationFactory.cs new file mode 100644 index 0000000..a25dc08 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/CardValidationFactory.cs @@ -0,0 +1,24 @@ +using ChainOfResponssibility.Validators; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ChainOfResponssibility.Poker.Validators +{ + public class CardValidationFactory + { + private static ChainValidation _validator; + + public static ChainValidation GetValidator() + { + if (_validator != null) + return _validator; + + _validator = new CardSuiteValidation(); + _validator.SetSuccessor(new CardValueValidation()); + + return _validator; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/CardValueValidator.cs b/src/ChainOfResponssibility/Poker/Validators/CardValueValidator.cs new file mode 100644 index 0000000..de334b8 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/CardValueValidator.cs @@ -0,0 +1,16 @@ +using ChainOfResponssibility.Validators; +using System; +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators +{ + public class CardValueValidation : ChainValidation + { + protected override ValidationResult IsValid(Card obj) + { + if (Card.ValidValues.Contains(obj.Value)) + return ValidationResult.GetValidResult(); + return ValidationResult.GetInvalidResult(new Exception("Invalid Value, must be one of " + Card.ValidValues)); + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/FlushValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/FlushValidation.cs new file mode 100644 index 0000000..73b72b2 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/FlushValidation.cs @@ -0,0 +1,17 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class FlushValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var gr = hand.GroupBy(x => x.Suite); + var flush = gr.FirstOrDefault(x => x.Count() == 5); + if (flush != null) + return "You have a Flush of " + flush.First().Suite + "s"; + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/FourOfAKindValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/FourOfAKindValidation.cs new file mode 100644 index 0000000..a929241 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/FourOfAKindValidation.cs @@ -0,0 +1,17 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class FourOfAKindValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var gr = hand.GroupBy(x => x.Value); + var four = gr.FirstOrDefault(x => x.Count() == 4); + if (four != null) + return "You have Four of " + four.First().Value + "s (Four of a kind)"; + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/FullHouseValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/FullHouseValidation.cs new file mode 100644 index 0000000..7af078c --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/FullHouseValidation.cs @@ -0,0 +1,21 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class FullHouseValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var gr = hand.GroupBy(x => x.Value); + var pair = gr.FirstOrDefault(x => x.Count() == 2); + if (pair != null) + { + var OhBabyATripple = gr.FirstOrDefault(x => x.Count() == 3); + if (OhBabyATripple != null) + return "You have a Full House of " + OhBabyATripple.First().Value + "s (3) and " + pair.First().Value + "s (2)"; + } + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/HandValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/HandValidation.cs new file mode 100644 index 0000000..6bd56b0 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/HandValidation.cs @@ -0,0 +1,28 @@ +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public abstract class HandValidation + { + public HandValidation Successor { get; private set; } + + public HandValidation SetSuccessor(HandValidation successor) + { + return Successor = successor; + } + + protected abstract string IsValid(Card[] hand); + + public string Validate(Card[] hand) + { + string result = IsValid(hand); + + if (!string.IsNullOrWhiteSpace(result)) + return result; + + if (Successor != null) + return Successor.Validate(hand); + else + return result; + + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/HandValidationFactory.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/HandValidationFactory.cs new file mode 100644 index 0000000..adfaf0a --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/HandValidationFactory.cs @@ -0,0 +1,45 @@ +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class HandValidationFactory + { + private static HandValidation _cachedValidation; + + public static HandValidation GetValidation() + { + if (_cachedValidation != null) + return _cachedValidation; + + var royalflush = new RoyalFlushValidation(); + + var straightflush = new StraightFlushValidation(); + royalflush.SetSuccessor(straightflush); + + var fourofakind = new FourOfAKindValidation(); + straightflush.SetSuccessor(fourofakind); + + var fullhouse = new FullHouseValidation(); + fourofakind.SetSuccessor(fullhouse); + + var flush = new FlushValidation(); + fullhouse.SetSuccessor(flush); + + var straight = new StraightValidation(); + flush.SetSuccessor(straight); + + var threeofakind = new ThreeOfAKindValidation(); + straight.SetSuccessor(threeofakind); + + var twopairs = new TwoPairsValidation(); + threeofakind.SetSuccessor(twopairs); + + var pairs = new PairValidation(); + twopairs.SetSuccessor(pairs); + + var high = new HighCardValidation(); + pairs.SetSuccessor(high); + + _cachedValidation = royalflush; + return _cachedValidation; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/HighCardValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/HighCardValidation.cs new file mode 100644 index 0000000..27b1544 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/HighCardValidation.cs @@ -0,0 +1,13 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class HighCardValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + return string.Format("You only have high cards, here I ordered them for you: {0}", + string.Join(", ", hand.OrderByDescending(x => x.GetIntValue()).Select(x => x.ToString()))); + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/PairValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/PairValidation.cs new file mode 100644 index 0000000..b95ee50 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/PairValidation.cs @@ -0,0 +1,17 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class PairValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var gr = hand.GroupBy(x => x.Value); + var pair = gr.FirstOrDefault(x => x.Count() == 2); + if (pair != null) + return "You have a pair of " + pair.First().Value + "s"; + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/RoyalFlushValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/RoyalFlushValidation.cs new file mode 100644 index 0000000..ab6c2f3 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/RoyalFlushValidation.cs @@ -0,0 +1,23 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class RoyalFlushValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var gr = hand.GroupBy(x => x.Suite); + var flush = gr.FirstOrDefault(x => x.Count() == 5); + if (flush != null) + { + var Value2Index = hand.Select((i, j) => i.GetIntValue() - j).Distinct(); + if (!Value2Index.Skip(1).Any() && Value2Index.First() == 10)// consecutive and 10, meaning 10, J, Q, K, A + return "You have a Royal Flush with " + string.Join(", ", hand.Select(x => x.ToString())); + + return string.Empty; + } + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/StraightFlushValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/StraightFlushValidation.cs new file mode 100644 index 0000000..b6e26cb --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/StraightFlushValidation.cs @@ -0,0 +1,29 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class StraightFlushValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var gr = hand.GroupBy(x => x.Suite); + var flush = gr.FirstOrDefault(x => x.Count() == 5); + if (flush != null) + { + var Value2Index = hand.Select((i, j) => i.GetIntValue() - j).Distinct(); + if (!Value2Index.Skip(1).Any())// consecutive + return "You have a Straight Flush with " + string.Join(", ", hand.Select(x => x.ToString())); + + //special case for A,2,3,4,5 + if (Value2Index.Count() == 2 + && Value2Index.First() == 2//for 2,3,4,5 + && Value2Index.Last() == 10)//for A + return "You have a Straight Flush with " + string.Join(", ", hand.Select(x => x.ToString())); + + return string.Empty; + } + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/StraightValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/StraightValidation.cs new file mode 100644 index 0000000..c5713e8 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/StraightValidation.cs @@ -0,0 +1,22 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class StraightValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var Value2Index = hand.Select((i, j) => i.GetIntValue() - j).Distinct(); + if (!Value2Index.Skip(1).Any())// consecutive + return "You have a Straight with " + string.Join(", ", hand.Select(x => x.ToString())); + + //special case for A,2,3,4,5 + if (Value2Index.Count() == 2 + && Value2Index.First() == 2//for 2,3,4,5 + && Value2Index.Last() == 10)//for A + return "You have a Straight with " + string.Join(", ", hand.Select(x => x.ToString())); + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/ThreeOfAKindValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/ThreeOfAKindValidation.cs new file mode 100644 index 0000000..d62a5a2 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/ThreeOfAKindValidation.cs @@ -0,0 +1,17 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class ThreeOfAKindValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var gr = hand.GroupBy(x => x.Value); + var OhBabyATripple = gr.FirstOrDefault(x => x.Count() == 3); + if (OhBabyATripple != null) + return "You have three of " + OhBabyATripple.First().Value + "s (Three of a kind)"; + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/Poker/Validators/HandValidators/TwoPairsValidation.cs b/src/ChainOfResponssibility/Poker/Validators/HandValidators/TwoPairsValidation.cs new file mode 100644 index 0000000..cbf99f6 --- /dev/null +++ b/src/ChainOfResponssibility/Poker/Validators/HandValidators/TwoPairsValidation.cs @@ -0,0 +1,17 @@ +using System.Linq; + +namespace ChainOfResponssibility.Poker.Validators.HandValidators +{ + public class TwoPairsValidation : HandValidation + { + protected override string IsValid(Card[] hand) + { + var gr = hand.GroupBy(x => x.Value); + var pairs = gr.Where(x => x.Count() == 2); + if (pairs != null && pairs.Count() == 2) + return "You have pairs of " + string.Join(" and ", pairs.Select(x=>x.First().Value + "s"))+ " (Two Pairs)"; + + return string.Empty; + } + } +} diff --git a/src/ChainOfResponssibility/RunChainOfResponsibillityExamples.cs b/src/ChainOfResponssibility/RunChainOfResponsibillityExamples.cs index 97283f4..593b990 100644 --- a/src/ChainOfResponssibility/RunChainOfResponsibillityExamples.cs +++ b/src/ChainOfResponssibility/RunChainOfResponsibillityExamples.cs @@ -1,4 +1,5 @@ -using ChainOfResponssibility.PurchaseExample; +using ChainOfResponssibility.Poker; +using ChainOfResponssibility.PurchaseExample; using ChainOfResponssibility.TransferFileExample; using ChainOfResponssibility.Validators.UserEntities; using System; @@ -12,40 +13,63 @@ namespace ChainOfResponssibility Console.WriteLine(GetPatternDescription()); GoToNextStep(); - Console.WriteLine(ExeucteFirstWhenConditionMatchesFlavorDescription()); - GoToNextStep(); + while (true) + { + Console.Clear(); + Console.WriteLine(ExeucteFirstWhenConditionMatchesFlavorDescription()); + Console.WriteLine(ExecuteAllUntilConditionIsFalseFlavorDescription()); + Console.WriteLine(ExecuteAllFlavorDescritpion()); + Console.WriteLine("1: Money Spender (flavor 1)"); + Console.WriteLine("2: File Transfer (flavor 1)"); + Console.WriteLine("3: User Processor (flavor 1 and 3)"); + Console.WriteLine("4: pitfals"); + Console.WriteLine("5: Poker Game (flavor 1)"); + Console.Write("0: exit\r\n>"); - CheckAuthority moneySpender = new CheckAuthority(); + var keyChar = GoToNextStep(); - Console.WriteLine(moneySpender.GetDescriptionOfExample()); - GoToNextStep(); + switch (keyChar) + { + case '1': + CheckAuthority moneySpender = new CheckAuthority(); - moneySpender.PrintHowMuchEachCanSpend(); - moneySpender.SpendMoney(); - GoToNextStep(); + Console.WriteLine(moneySpender.GetDescriptionOfExample()); + GoToNextStep(); - TransferFilesManager transferFilesManager = new TransferFilesManager(); + moneySpender.PrintHowMuchEachCanSpend(); + moneySpender.SpendMoney(); + break; + case '2': + TransferFilesManager transferFilesManager = new TransferFilesManager(); - Console.WriteLine(transferFilesManager.GetDescriptionOfExample()); - GoToNextStep(); - transferFilesManager.TransferFiles(); + Console.WriteLine(transferFilesManager.GetDescriptionOfExample()); + GoToNextStep(); + transferFilesManager.TransferFiles(); + break; + case '3': + UserProcessor userProcessor = new UserProcessor(); + userProcessor.DoStuff(); + break; + case '4': + Console.WriteLine(GetPitfalls()); + GoToNextStep(); + break; + case '5': + PokerGame poke = new PokerGame(); + poke.newGame(); + break; + } - GoToNextStep(); - Console.WriteLine(ExecuteAllUntilConditionIsFalseFlavorDescription()); - Console.WriteLine(ExecuteAllFlavorDescritpion()); - GoToNextStep(); - - UserProcessor userProcessor = new UserProcessor(); - userProcessor.DoStuff(); - - GoToNextStep(); - Console.WriteLine(GetPitfalls()); + if (keyChar == '0') + break; + } } - private static void GoToNextStep() + private static char GoToNextStep() { - Console.ReadKey(); + var ch = Console.ReadKey().KeyChar; Console.Clear(); + return ch; } public static string GetPatternDescription() @@ -55,9 +79,9 @@ Decouples sender and receiver (as a sender you don't know who will handle the re Hierarchical in nature When using the Chain of Responsibility is more effective: More than one object can handle a command -The handler is not known in advances +The handler is not known in advance The handler should be determined automatically -It's wished that the request is addressed to a group of objects without explicitly specifying its receiver +It’s wished that the request is addressed to a group of objects without explicitly specifying its receiver The group of objects that may handle the command must be specified in a dynamic way. Examples in real life: -java.util.logging.Logger.#log() @@ -80,12 +104,12 @@ Chain length/performance issues - in theory you could see a chain that is too bi public static string ExecuteAllUntilConditionIsFalseFlavorDescription() { - return @"Flavor 2 of chain of responssibility:Execute all elements of chain until the condition does not match"; + return @"Flavor 2: Execute all elements of chain until the condition does not match"; } public static string ExecuteAllFlavorDescritpion() { - return @"Flavor 3 of chain of responssibility: Execute all elements of chain"; + return @"Flavor 3: Execute all elements of chain"; } } } diff --git a/src/ChainOfResponssibility/Validators/UserEntities/UserProcessor.cs b/src/ChainOfResponssibility/Validators/UserEntities/UserProcessor.cs index 10269f1..70129a6 100644 --- a/src/ChainOfResponssibility/Validators/UserEntities/UserProcessor.cs +++ b/src/ChainOfResponssibility/Validators/UserEntities/UserProcessor.cs @@ -9,15 +9,15 @@ namespace ChainOfResponssibility.Validators.UserEntities { UserRepository userRepository; PrincipalHelper principalHelper; - Operation inputOperation; + Operation operation; ChainValidation userCreationValidation; ChainValidation authenticateUserValidation; public UserProcessor() { userRepository = new UserRepository(); principalHelper = new PrincipalHelper(); - inputOperation = new AuthenticateOperation(AuthenticateUser); - inputOperation.SetSuccessor(new CreateNewUserOperation(CreateNewUser)); + operation = new AuthenticateOperation(AuthenticateUser); + operation.SetSuccessor(new CreateNewUserOperation(CreateNewUser)); userCreationValidation = new IsAuthorisedToDoOperationsOnUser(principalHelper, Rights.Create); userCreationValidation.SetSuccessor(new ValidateNoDuplicateEmail(userRepository)); @@ -55,12 +55,12 @@ namespace ChainOfResponssibility.Validators.UserEntities string userInput; do { - inputOperation.PrintMenu(); + operation.PrintMenu(); Console.Write(">"); userInput = Console.ReadLine(); if (!IsExitCode(userInput)) - inputOperation.Execute(userInput); + operation.Execute(userInput); } while (!IsExitCode(userInput)); } diff --git a/src/ChainOfResponssibility/project.json b/src/ChainOfResponssibility/project.json index b5b5a5c..ed8608d 100644 --- a/src/ChainOfResponssibility/project.json +++ b/src/ChainOfResponssibility/project.json @@ -1,8 +1,8 @@ -{ +{ "version": "1.0.0-*", "dependencies": { - "NETStandard.Library": "1.6.0" + "NETStandard.Library": "1.5.0-rc2-24027" }, "frameworks": { diff --git a/src/CommandPattern/CommandPatternExamples.cs b/src/CommandPattern/CommandPatternExamples.cs index d388b0e..0e50ac4 100644 --- a/src/CommandPattern/CommandPatternExamples.cs +++ b/src/CommandPattern/CommandPatternExamples.cs @@ -31,6 +31,12 @@ namespace CommandPattern } + private static void GoToNextStep() + { + Console.ReadKey(); + Console.Clear(); + } + public static string GetPatternDescription() { return @"Patttern description: @@ -70,11 +76,5 @@ level undo/redo functionality, in practice this only works for simple examples, where all entities are at the same level. More details about undo can be seen at: http://gernotklingler.com/blog/implementing-undoredo-with-the-command-pattern/"; } - - private static void GoToNextStep() - { - Console.ReadKey(); - Console.Clear(); - } } } diff --git a/src/CommandPattern/project.json b/src/CommandPattern/project.json index 9954282..c4ee639 100644 --- a/src/CommandPattern/project.json +++ b/src/CommandPattern/project.json @@ -1,8 +1,11 @@ -{ +{ "version": "1.0.0-*", "dependencies": { - "Microsoft.NETCore.App": "1.0.0" + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0-rc2-3002702" + } }, "frameworks": { diff --git a/src/IteratorPattern/project.json b/src/IteratorPattern/project.json index afdcb09..8f8aaaf 100644 --- a/src/IteratorPattern/project.json +++ b/src/IteratorPattern/project.json @@ -1,8 +1,8 @@ -{ +{ "version": "1.0.0-*", "dependencies": { - "NETStandard.Library": "1.6.0" + "NETStandard.Library": "1.5.0-rc2-24027" }, "frameworks": { diff --git a/src/MediatorPattern/project.json b/src/MediatorPattern/project.json index b5b5a5c..ed8608d 100644 --- a/src/MediatorPattern/project.json +++ b/src/MediatorPattern/project.json @@ -1,8 +1,8 @@ -{ +{ "version": "1.0.0-*", "dependencies": { - "NETStandard.Library": "1.6.0" + "NETStandard.Library": "1.5.0-rc2-24027" }, "frameworks": { diff --git a/src/MememntoPattern/project.json b/src/MememntoPattern/project.json index c0062b2..6a306c8 100644 --- a/src/MememntoPattern/project.json +++ b/src/MememntoPattern/project.json @@ -3,8 +3,8 @@ "dependencies": { "NETStandard.Library": "1.5.0-rc2-24027", - "Newtonsoft.Json": "9.0.1", - "System.Runtime.Serialization.Primitives": "4.1.1" + "Newtonsoft.Json": "8.0.3", + "System.Runtime.Serialization.Primitives": "4.0.10-*" }, "frameworks": { diff --git a/src/ObserverPattern/ObserverPatternExamples.cs b/src/ObserverPattern/ObserverPatternExamples.cs index 5004404..c6c640b 100644 --- a/src/ObserverPattern/ObserverPatternExamples.cs +++ b/src/ObserverPattern/ObserverPatternExamples.cs @@ -1,5 +1,4 @@ -using ObserverPattern.StockUpdateEvents; -using ObserverPattern.Twits; +using ObserverPattern.Twits; using System; using System.Collections.Generic; using System.Linq; @@ -12,78 +11,8 @@ namespace ObserverPattern { public static void Run() { - Console.WriteLine(GetDescription()); - Console.WriteLine(GetActors()); - Console.WriteLine(IsThisPubSub()); - - StockUpdateEventsExample stockExample = new StockUpdateEventsExample(); - stockExample.RunSimple(); - - GoToNextStep(); - - Console.WriteLine(GetLapsedLinstenerProblem()); - - GoToNextStep(); - - Console.WriteLine("Same business logic using events combined with RX library"); - stockExample.RunReactiveWithEvents(); - - GoToNextStep(); - - Console.WriteLine("Same business logic using RX library"); - stockExample.RunReactive(); - - GoToNextStep(); - ObservableTwitsExample obsTwits = new ObservableTwitsExample(); obsTwits.Run(); - - GoToNextStep(); - } - - private static string GetDescription() - { - return @" -The observer pattern is a software design pattern in which an object, called the subject, -maintains a list of its dependents, called observers, and notifies them automatically of any state changes, -usually by calling one of their methods. "; - } - - private static string IsThisPubSub() - { - return @" -Observer/Observable pattern is mostly implemented in a synchronous way, -i.e. the observable calls the appropriate method of all its observers when some event occurs. -The Publisher/Subscriber pattern is mostly implemented in an asynchronous way (using message queue). -In the Observer/Observable pattern, the observers are aware of the observable. -Whereas, in Publisher/Subscriber, publishers and subscribers don't need to know each other. -They simply communicate with the help of message queues. -"; - } - - private static string GetActors() - { - return @" -Subject -> Interface/Abstract Notifies interested observers when an event occurs -Concrete Subject -> Implementation of Subject -Observer -> Interface/Abstract class -> Registers to a subject, to be notified when a specific event happens -Concrete Observer -> Implementation of the observer -"; - } - - private static string GetLapsedLinstenerProblem() - { - return @" -The leak happens when a listener fails to unsubscribe from the publisher when it no longer needs to listen. -Consequently, the publisher still holds a reference to the observer which prevents it from being garbage collected -— including all other objects it is referring to — for as long as the publisher is alive, which could be until the end of the application. -This causes not only a memory leak, but also a performance degradation with an 'uninterested' observer receiving and acting on unwanted events"; - } - - private static void GoToNextStep() - { - Console.ReadKey(); - Console.Clear(); } } } diff --git a/src/ObserverPattern/Twits/ObservableTwitsExample.cs b/src/ObserverPattern/Twits/ObservableTwitsExample.cs index 29d4870..aeff52f 100644 --- a/src/ObserverPattern/Twits/ObservableTwitsExample.cs +++ b/src/ObserverPattern/Twits/ObservableTwitsExample.cs @@ -11,16 +11,16 @@ namespace ObserverPattern.Twits { TwitObservable observable = new TwitObservable(); - using (TwitUser t100 = new TwitUser("t100", observable)) - using (TwitUser r2d2 = new TwitUser("R2-D2", observable)) - { - t100.Twit("El chupacapra - BOOM BOOM"); + TwitUser t100 = new TwitUser("t100", observable); + TwitUser r2d2 = new TwitUser("R2-D2", observable); - r2d2.Twit("Vamos vamos mi amor"); + t100.Twit("El chupacapra - BOOM BOOM"); - observable.ItsGoingHomeTime(); - } - + r2d2.Twit("Vamos vamos mi amor"); + + t100.Dispose(); + + observable.ItsGoingHomeTime(); } } } diff --git a/src/ObserverPattern/Twits/TwitObservable.cs b/src/ObserverPattern/Twits/TwitObservable.cs index c5cc320..75a9ff2 100644 --- a/src/ObserverPattern/Twits/TwitObservable.cs +++ b/src/ObserverPattern/Twits/TwitObservable.cs @@ -20,7 +20,7 @@ namespace ObserverPattern.Twits if (!observers.Contains(observer)) observers.Add(observer); - return new Unsubscriber(observers, observer); + return new Unsubscriber(observers, observer); } public void AddTwit(Twit twit) @@ -37,6 +37,23 @@ namespace ObserverPattern.Twits { observer.OnCompleted(); } + } + + private class Unsubscriber : IDisposable + { + private List> _observers; + private IObserver _observer; + + public Unsubscriber(List> observers, IObserver observer) + { + _observers = observers; + _observer = observer; + } + + public void Dispose() + { + if (!(_observer == null)) _observers.Remove(_observer); + } } } diff --git a/src/ObserverPattern/project.json b/src/ObserverPattern/project.json index 9742072..ed8608d 100644 --- a/src/ObserverPattern/project.json +++ b/src/ObserverPattern/project.json @@ -1,9 +1,8 @@ -{ +{ "version": "1.0.0-*", "dependencies": { - "NETStandard.Library": "1.6.0", - "System.Reactive": "3.0.0" + "NETStandard.Library": "1.5.0-rc2-24027" }, "frameworks": {