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": {