From 61fe84bbbcce2207bd346654bd45d127ec937d38 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 15 Mar 2016 23:47:10 +0100 Subject: [PATCH] wrote a test, fixed royalflush/streight closes #79 --- NadekoBot.sln | 10 + NadekoBot/Classes/Cards.cs | 349 +++++++++--------- .../Classes/JSONModels/LocalizedStrings.cs | 2 +- NadekoBot/Commands/DrawCommand.cs | 1 + NadekoBot/Commands/HelpCommand.cs | 2 +- NadekoBot/NadekoBot.cs | 2 +- 6 files changed, 186 insertions(+), 180 deletions(-) diff --git a/NadekoBot.sln b/NadekoBot.sln index c73b09c5..5e8a3b96 100644 --- a/NadekoBot.sln +++ b/NadekoBot.sln @@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Modules", "disc EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Commands", "discord.net\src\Discord.Net.Commands.Net45\Discord.Net.Commands.csproj", "{1B5603B4-6F8F-4289-B945-7BAAE523D740}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{45B2545D-C612-4919-B34C-D65EA1371C51}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution discord.net\src\Discord.Net.Shared\Discord.Net.Shared.projitems*{7bfef748-b934-4621-9b11-6302e3a9f6b3}*SharedItemsImports = 4 @@ -67,6 +69,14 @@ Global {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.Build.0 = Release|Any CPU {1B5603B4-6F8F-4289-B945-7BAAE523D740}.TestResponses|Any CPU.ActiveCfg = Release|Any CPU {1B5603B4-6F8F-4289-B945-7BAAE523D740}.TestResponses|Any CPU.Build.0 = Release|Any CPU + {45B2545D-C612-4919-B34C-D65EA1371C51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {45B2545D-C612-4919-B34C-D65EA1371C51}.Debug|Any CPU.Build.0 = Debug|Any CPU + {45B2545D-C612-4919-B34C-D65EA1371C51}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU + {45B2545D-C612-4919-B34C-D65EA1371C51}.FullDebug|Any CPU.Build.0 = Debug|Any CPU + {45B2545D-C612-4919-B34C-D65EA1371C51}.Release|Any CPU.ActiveCfg = Release|Any CPU + {45B2545D-C612-4919-B34C-D65EA1371C51}.Release|Any CPU.Build.0 = Release|Any CPU + {45B2545D-C612-4919-B34C-D65EA1371C51}.TestResponses|Any CPU.ActiveCfg = Release|Any CPU + {45B2545D-C612-4919-B34C-D65EA1371C51}.TestResponses|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NadekoBot/Classes/Cards.cs b/NadekoBot/Classes/Cards.cs index 85fb0de7..0105d614 100644 --- a/NadekoBot/Classes/Cards.cs +++ b/NadekoBot/Classes/Cards.cs @@ -2,9 +2,9 @@ using System.Linq; using System; -public class Cards -{ - private static readonly Dictionary cardNames = new Dictionary() { +namespace NadekoBot.Classes { + public class Cards { + private static readonly Dictionary cardNames = new Dictionary() { { 1, "Ace" }, { 2, "Two" }, { 3, "Three" }, @@ -19,198 +19,193 @@ public class Cards { 12, "Queen" }, { 13, "King" } }; - - private static Dictionary, bool>> handValues; + private static Dictionary, bool>> handValues; - public enum CardSuit - { - Spades = 1, - Hearts = 2, - Diamonds = 3, - Clubs = 4 - } + public enum CardSuit { + Spades = 1, + Hearts = 2, + Diamonds = 3, + Clubs = 4 + } - public class Card : IComparable - { - public CardSuit Suit { get; } - public int Number { get; } + public class Card : IComparable { + public CardSuit Suit { get; } + public int Number { get; } - public string Name - { - get - { - var str = ""; + public string Name { + get { + var str = ""; - if (Number <= 10 && Number > 1) - { - str += "_"+Number; + if (Number <= 10 && Number > 1) { + str += "_" + Number; + } else { + str += GetName().ToLower(); + } + return str + "_of_" + Suit.ToString().ToLower(); } - else - { - str += GetName().ToLower(); - } - return str + "_of_" + Suit.ToString().ToLower(); + } + + public Card(CardSuit s, int cardNum) { + this.Suit = s; + this.Number = cardNum; + } + + public string GetName() => cardNames[Number]; + + public override string ToString() => cardNames[Number] + " Of " + Suit; + + public int CompareTo(object obj) { + if (!(obj is Card)) return 0; + var c = (Card)obj; + return this.Number - c.Number; } } - public Card(CardSuit s, int cardNum) { - this.Suit = s; - this.Number = cardNum; + private List cardPool; + public List CardPool { + get { return cardPool; } + set { cardPool = value; } } - public string GetName() => cardNames[Number]; - - public override string ToString() => cardNames[Number] + " Of " + Suit; - - public int CompareTo(object obj) - { - if (!(obj is Card)) return 0; - var c = (Card)obj; - return this.Number - c.Number; + /// + /// Creates a new instance of the BlackJackGame, this allows you to create multiple games running at one time. + /// + public Cards() { + cardPool = new List(52); + RefillPool(); + InitHandValues(); } - } + /// + /// Restart the game of blackjack. It will only refill the pool for now. Probably wont be used, unless you want to have only 1 bjg running at one time, + /// then you will restart the same game every time. + /// + public void Restart() => RefillPool(); - private List cardPool; - public List CardPool - { - get { return cardPool; } - set { cardPool = value; } - } + /// + /// Removes all cards from the pool and refills the pool with all of the possible cards. NOTE: I think this is too expensive. + /// We should probably make it so it copies another premade list with all the cards, or something. + /// + private void RefillPool() { + cardPool.Clear(); + //foreach suit + for (var j = 1; j < 14; j++) { + // and number + for (var i = 1; i < 5; i++) { + //generate a card of that suit and number and add it to the pool - /// - /// Creates a new instance of the BlackJackGame, this allows you to create multiple games running at one time. - /// - public Cards() - { - cardPool = new List(52); - RefillPool(); - InitHandValues(); - } - /// - /// Restart the game of blackjack. It will only refill the pool for now. Probably wont be used, unless you want to have only 1 bjg running at one time, - /// then you will restart the same game every time. - /// - public void Restart() => RefillPool(); - - /// - /// Removes all cards from the pool and refills the pool with all of the possible cards. NOTE: I think this is too expensive. - /// We should probably make it so it copies another premade list with all the cards, or something. - /// - private void RefillPool() - { - cardPool.Clear(); - //foreach suit - for (var j = 1; j < 14; j++) - { - // and number - for (var i = 1; i < 5; i++) - { - //generate a card of that suit and number and add it to the pool - - // the pool will go from ace of spades,hears,diamonds,clubs all the way to the king of spades. hearts, ... - cardPool.Add(new Card((CardSuit)i, j)); + // the pool will go from ace of spades,hears,diamonds,clubs all the way to the king of spades. hearts, ... + cardPool.Add(new Card((CardSuit)i, j)); + } } } - } - private Random r = new Random(); - /// - /// Take a card from the pool, you either take it from the top if the deck is shuffled, or from a random place if the deck is in the default order. - /// - /// A card from the pool - public Card DrawACard() - { - if (CardPool.Count == 0) - Restart(); - //you can either do this if your deck is not shuffled - - var num = r.Next(0, cardPool.Count); - var c = cardPool[num]; - cardPool.RemoveAt(num); - return c; + private Random r = new Random(); + /// + /// Take a card from the pool, you either take it from the top if the deck is shuffled, or from a random place if the deck is in the default order. + /// + /// A card from the pool + public Card DrawACard() { + if (CardPool.Count == 0) + Restart(); + //you can either do this if your deck is not shuffled - // if you want to shuffle when you fill, then take the first one - /* - Card c = cardPool[0]; - cardPool.RemoveAt(0); - return c; - */ - } - /// - /// Shuffles the deck. Use this if you want to take cards from the top of the deck, instead of randomly. See DrawACard method. - /// - private void Shuffle() { - if (cardPool.Count <= 1) return; - var orderedPool = cardPool.OrderBy(x => r.Next()); - cardPool = cardPool as List ?? orderedPool.ToList(); - } - public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine; + var num = r.Next(0, cardPool.Count); + var c = cardPool[num]; + cardPool.RemoveAt(num); + return c; - private void InitHandValues() { - Func, bool> hasPair = - cards => cards.GroupBy(card => card.Number) - .Count(group => group.Count() == 2) == 1; - Func, bool> isPair = - cards => cards.GroupBy(card => card.Number) - .Count(group => group.Count() == 3) == 0 - && hasPair(cards); - - Func, bool> isTwoPair = - cards => cards.GroupBy(card => card.Number) - .Count(group => group.Count() == 2) == 2; - - Func, bool> isStraight = - cards => cards.GroupBy(card => card.Number) - .Count() == cards.Count() - && cards.Max(card => (int)card.Number) - - cards.Min(card => (int)card.Number) == 4; - - Func, bool> hasThreeOfKind = - cards => cards.GroupBy(card => card.Number) - .Any(group => group.Count() == 3); - - Func, bool> isThreeOfKind = - cards => hasThreeOfKind(cards) && !hasPair(cards); - - Func, bool> isFlush = - cards => cards.GroupBy(card => card.Suit).Count() == 1; - - Func, bool> isFourOfKind = - cards => cards.GroupBy(card => card.Number) - .Any(group => group.Count() == 4); - - Func, bool> isFullHouse = - cards => hasPair(cards) && hasThreeOfKind(cards); - - Func, bool> hasStraightFlush = - cards => isFlush(cards) && isStraight(cards); - - Func, bool> isRoyalFlush = - cards => cards.Min(card => card.Number) == 10 - && hasStraightFlush(cards); - - Func, bool> isStraightFlush = - cards => hasStraightFlush(cards) && !isRoyalFlush(cards); - - handValues = new Dictionary, bool>> - { - { "Royal Flush", isRoyalFlush }, - { "Straight Flush", isStraightFlush }, - { "Four Of A Kind", isFourOfKind }, - { "Full House", isFullHouse }, - { "Flush", isFlush }, - { "Straight", isStraight }, - { "Three Of A Kind", isThreeOfKind }, - { "Two Pairs", isTwoPair }, - { "A Pair", isPair } - }; - } - - public static string GetHandValue(List cards) { - foreach (var kvp in handValues.Where(x => x.Value(cards))) { - return kvp.Key; + // if you want to shuffle when you fill, then take the first one + /* + Card c = cardPool[0]; + cardPool.RemoveAt(0); + return c; + */ + } + /// + /// Shuffles the deck. Use this if you want to take cards from the top of the deck, instead of randomly. See DrawACard method. + /// + private void Shuffle() { + if (cardPool.Count <= 1) return; + var orderedPool = cardPool.OrderBy(x => r.Next()); + cardPool = cardPool as List ?? orderedPool.ToList(); + } + public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine; + + private static void InitHandValues() { + Func, bool> hasPair = + cards => cards.GroupBy(card => card.Number) + .Count(group => group.Count() == 2) == 1; + Func, bool> isPair = + cards => cards.GroupBy(card => card.Number) + .Count(group => group.Count() == 3) == 0 + && hasPair(cards); + + Func, bool> isTwoPair = + cards => cards.GroupBy(card => card.Number) + .Count(group => group.Count() == 2) == 2; + + Func, bool> isStraight = + cards => { + if (cards.GroupBy(card => card.Number).Count() != cards.Count()) + return false; + var toReturn = (cards.Max(card => (int)card.Number) + - cards.Min(card => (int)card.Number) == 4); + if (toReturn || cards.All(c => c.Number != 1)) return toReturn; + + var newCards = cards.Select(c => c.Number == 1 ? new Card(c.Suit, 14) : c); + return (newCards.Max(card => (int)card.Number) + - newCards.Min(card => (int)card.Number) == 4); + }; + + Func, bool> hasThreeOfKind = + cards => cards.GroupBy(card => card.Number) + .Any(group => group.Count() == 3); + + Func, bool> isThreeOfKind = + cards => hasThreeOfKind(cards) && !hasPair(cards); + + Func, bool> isFlush = + cards => cards.GroupBy(card => card.Suit).Count() == 1; + + Func, bool> isFourOfKind = + cards => cards.GroupBy(card => card.Number) + .Any(group => group.Count() == 4); + + Func, bool> isFullHouse = + cards => hasPair(cards) && hasThreeOfKind(cards); + + Func, bool> hasStraightFlush = + cards => isFlush(cards) && isStraight(cards); + + Func, bool> isRoyalFlush = + cards => cards.Min(card => card.Number) == 1 && + cards.Max(card => card.Number) == 13 + && hasStraightFlush(cards); + + Func, bool> isStraightFlush = + cards => hasStraightFlush(cards) && !isRoyalFlush(cards); + + handValues = new Dictionary, bool>> + { + { "Royal Flush", isRoyalFlush }, + { "Straight Flush", isStraightFlush }, + { "Four Of A Kind", isFourOfKind }, + { "Full House", isFullHouse }, + { "Flush", isFlush }, + { "Straight", isStraight }, + { "Three Of A Kind", isThreeOfKind }, + { "Two Pairs", isTwoPair }, + { "A Pair", isPair } + }; + } + + public static string GetHandValue(List cards) { + if (handValues == null) + InitHandValues(); + foreach (var kvp in handValues.Where(x => x.Value(cards))) { + return kvp.Key; + } + return "High card " + cards.Max().GetName(); } - return "High card "+cards.Max().GetName(); } } - diff --git a/NadekoBot/Classes/JSONModels/LocalizedStrings.cs b/NadekoBot/Classes/JSONModels/LocalizedStrings.cs index 7c21eaf2..861ebb69 100644 --- a/NadekoBot/Classes/JSONModels/LocalizedStrings.cs +++ b/NadekoBot/Classes/JSONModels/LocalizedStrings.cs @@ -1,7 +1,7 @@ using System.IO; namespace NadekoBot.Classes.JSONModels { - internal class LocalizedStrings { + public class LocalizedStrings { public string[] Insults { get; set; } = { " You are a poop.", " You're a jerk.", " I will eat you when I get my powers back." diff --git a/NadekoBot/Commands/DrawCommand.cs b/NadekoBot/Commands/DrawCommand.cs index 2bbd618b..d4066179 100644 --- a/NadekoBot/Commands/DrawCommand.cs +++ b/NadekoBot/Commands/DrawCommand.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Drawing; using System.Threading.Tasks; using Discord.Commands; +using NadekoBot.Classes; using NadekoBot.Extensions; using NadekoBot.Modules; diff --git a/NadekoBot/Commands/HelpCommand.cs b/NadekoBot/Commands/HelpCommand.cs index 8923c07d..08f2063b 100644 --- a/NadekoBot/Commands/HelpCommand.cs +++ b/NadekoBot/Commands/HelpCommand.cs @@ -52,7 +52,7 @@ namespace NadekoBot.Commands { public static string HelpString => $"You can use `{NadekoBot.Config.CommandPrefixes.Help}modules` command to see a list of all modules.\n" + $"You can use `{NadekoBot.Config.CommandPrefixes.Help}commands ModuleName`" + $" (for example `{NadekoBot.Config.CommandPrefixes.Help}commands Administration`) to see a list of all of the commands in that module.\n" + - $"For a specific command help, use `{NadekoBot.Config.CommandPrefixes.Help}h \"Command name\"` (for example `-h \"!m q\"`)" + + $"For a specific command help, use `{NadekoBot.Config.CommandPrefixes.Help}h \"Command name\"` (for example `-h \"!m q\"`)\n" + "**LIST OF COMMANDS CAN BE FOUND ON THIS LINK**\n\n "; public Action DoGitFunc() => e => { diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index bfb8d5fa..ee0a41ff 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -17,7 +17,7 @@ using NadekoBot.Classes.JSONModels; using NadekoBot.Commands; namespace NadekoBot { - internal class NadekoBot { + public class NadekoBot { public static DiscordClient Client; public static Credentials Creds { get; set; } public static Configuration Config { get; set; }