wrote a test, fixed royalflush/streight closes #79

This commit is contained in:
Master Kwoth 2016-03-15 23:47:10 +01:00
parent 9781606316
commit 61fe84bbbc
6 changed files with 186 additions and 180 deletions

View File

@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Modules", "disc
EndProject 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}" 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 EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{45B2545D-C612-4919-B34C-D65EA1371C51}"
EndProject
Global Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution GlobalSection(SharedMSBuildProjectFiles) = preSolution
discord.net\src\Discord.Net.Shared\Discord.Net.Shared.projitems*{7bfef748-b934-4621-9b11-6302e3a9f6b3}*SharedItemsImports = 4 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}.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.ActiveCfg = Release|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.TestResponses|Any CPU.Build.0 = 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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -2,9 +2,9 @@
using System.Linq; using System.Linq;
using System; using System;
public class Cards namespace NadekoBot.Classes {
{ public class Cards {
private static readonly Dictionary<int, string> cardNames = new Dictionary<int, string>() { private static readonly Dictionary<int, string> cardNames = new Dictionary<int, string>() {
{ 1, "Ace" }, { 1, "Ace" },
{ 2, "Two" }, { 2, "Two" },
{ 3, "Three" }, { 3, "Three" },
@ -19,198 +19,193 @@ public class Cards
{ 12, "Queen" }, { 12, "Queen" },
{ 13, "King" } { 13, "King" }
}; };
private static Dictionary<string, Func<List<Card>, bool>> handValues;
private static Dictionary<string, Func<List<Card>, bool>> handValues;
public enum CardSuit public enum CardSuit {
{ Spades = 1,
Spades = 1, Hearts = 2,
Hearts = 2, Diamonds = 3,
Diamonds = 3, Clubs = 4
Clubs = 4 }
}
public class Card : IComparable public class Card : IComparable {
{ public CardSuit Suit { get; }
public CardSuit Suit { get; } public int Number { get; }
public int Number { get; }
public string Name public string Name {
{ get {
get var str = "";
{
var str = "";
if (Number <= 10 && Number > 1) if (Number <= 10 && Number > 1) {
{ str += "_" + Number;
str += "_"+Number; } else {
str += GetName().ToLower();
}
return str + "_of_" + Suit.ToString().ToLower();
} }
else }
{
str += GetName().ToLower(); public Card(CardSuit s, int cardNum) {
} this.Suit = s;
return str + "_of_" + Suit.ToString().ToLower(); 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) { private List<Card> cardPool;
this.Suit = s; public List<Card> CardPool {
this.Number = cardNum; get { return cardPool; }
set { cardPool = value; }
} }
public string GetName() => cardNames[Number]; /// <summary>
/// Creates a new instance of the BlackJackGame, this allows you to create multiple games running at one time.
public override string ToString() => cardNames[Number] + " Of " + Suit; /// </summary>
public Cards() {
public int CompareTo(object obj) cardPool = new List<Card>(52);
{ RefillPool();
if (!(obj is Card)) return 0; InitHandValues();
var c = (Card)obj;
return this.Number - c.Number;
} }
} /// <summary>
/// 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.
/// </summary>
public void Restart() => RefillPool();
private List<Card> cardPool; /// <summary>
public List<Card> CardPool /// 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.
get { return cardPool; } /// </summary>
set { cardPool = value; } 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
/// <summary> // the pool will go from ace of spades,hears,diamonds,clubs all the way to the king of spades. hearts, ...
/// Creates a new instance of the BlackJackGame, this allows you to create multiple games running at one time. cardPool.Add(new Card((CardSuit)i, j));
/// </summary> }
public Cards()
{
cardPool = new List<Card>(52);
RefillPool();
InitHandValues();
}
/// <summary>
/// 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.
/// </summary>
public void Restart() => RefillPool();
/// <summary>
/// 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.
/// </summary>
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));
} }
} }
} private Random r = new Random();
private Random r = new Random(); /// <summary>
/// <summary> /// 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.
/// 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. /// </summary>
/// </summary> /// <returns>A card from the pool</returns>
/// <returns>A card from the pool</returns> public Card DrawACard() {
public Card DrawACard() if (CardPool.Count == 0)
{ Restart();
if (CardPool.Count == 0) //you can either do this if your deck is not shuffled
Restart();
//you can either do this if your deck is not shuffled
var num = r.Next(0, cardPool.Count); var num = r.Next(0, cardPool.Count);
var c = cardPool[num]; var c = cardPool[num];
cardPool.RemoveAt(num); cardPool.RemoveAt(num);
return c; return c;
// if you want to shuffle when you fill, then take the first one // if you want to shuffle when you fill, then take the first one
/* /*
Card c = cardPool[0]; Card c = cardPool[0];
cardPool.RemoveAt(0); cardPool.RemoveAt(0);
return c; return c;
*/ */
} }
/// <summary> /// <summary>
/// Shuffles the deck. Use this if you want to take cards from the top of the deck, instead of randomly. See DrawACard method. /// Shuffles the deck. Use this if you want to take cards from the top of the deck, instead of randomly. See DrawACard method.
/// </summary> /// </summary>
private void Shuffle() { private void Shuffle() {
if (cardPool.Count <= 1) return; if (cardPool.Count <= 1) return;
var orderedPool = cardPool.OrderBy(x => r.Next()); var orderedPool = cardPool.OrderBy(x => r.Next());
cardPool = cardPool as List<Card> ?? orderedPool.ToList(); cardPool = cardPool as List<Card> ?? orderedPool.ToList();
} }
public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine; public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine;
private void InitHandValues() { private static void InitHandValues() {
Func<List<Card>, bool> hasPair = Func<List<Card>, bool> hasPair =
cards => cards.GroupBy(card => card.Number) cards => cards.GroupBy(card => card.Number)
.Count(group => group.Count() == 2) == 1; .Count(group => group.Count() == 2) == 1;
Func<List<Card>, bool> isPair = Func<List<Card>, bool> isPair =
cards => cards.GroupBy(card => card.Number) cards => cards.GroupBy(card => card.Number)
.Count(group => group.Count() == 3) == 0 .Count(group => group.Count() == 3) == 0
&& hasPair(cards); && hasPair(cards);
Func<List<Card>, bool> isTwoPair = Func<List<Card>, bool> isTwoPair =
cards => cards.GroupBy(card => card.Number) cards => cards.GroupBy(card => card.Number)
.Count(group => group.Count() == 2) == 2; .Count(group => group.Count() == 2) == 2;
Func<List<Card>, bool> isStraight = Func<List<Card>, bool> isStraight =
cards => cards.GroupBy(card => card.Number) cards => {
.Count() == cards.Count() if (cards.GroupBy(card => card.Number).Count() != cards.Count())
&& cards.Max(card => (int)card.Number) return false;
- cards.Min(card => (int)card.Number) == 4; var toReturn = (cards.Max(card => (int)card.Number)
- cards.Min(card => (int)card.Number) == 4);
Func<List<Card>, bool> hasThreeOfKind = if (toReturn || cards.All(c => c.Number != 1)) return toReturn;
cards => cards.GroupBy(card => card.Number)
.Any(group => group.Count() == 3); var newCards = cards.Select(c => c.Number == 1 ? new Card(c.Suit, 14) : c);
return (newCards.Max(card => (int)card.Number)
Func<List<Card>, bool> isThreeOfKind = - newCards.Min(card => (int)card.Number) == 4);
cards => hasThreeOfKind(cards) && !hasPair(cards); };
Func<List<Card>, bool> isFlush = Func<List<Card>, bool> hasThreeOfKind =
cards => cards.GroupBy(card => card.Suit).Count() == 1; cards => cards.GroupBy(card => card.Number)
.Any(group => group.Count() == 3);
Func<List<Card>, bool> isFourOfKind =
cards => cards.GroupBy(card => card.Number) Func<List<Card>, bool> isThreeOfKind =
.Any(group => group.Count() == 4); cards => hasThreeOfKind(cards) && !hasPair(cards);
Func<List<Card>, bool> isFullHouse = Func<List<Card>, bool> isFlush =
cards => hasPair(cards) && hasThreeOfKind(cards); cards => cards.GroupBy(card => card.Suit).Count() == 1;
Func<List<Card>, bool> hasStraightFlush = Func<List<Card>, bool> isFourOfKind =
cards => isFlush(cards) && isStraight(cards); cards => cards.GroupBy(card => card.Number)
.Any(group => group.Count() == 4);
Func<List<Card>, bool> isRoyalFlush =
cards => cards.Min(card => card.Number) == 10 Func<List<Card>, bool> isFullHouse =
&& hasStraightFlush(cards); cards => hasPair(cards) && hasThreeOfKind(cards);
Func<List<Card>, bool> isStraightFlush = Func<List<Card>, bool> hasStraightFlush =
cards => hasStraightFlush(cards) && !isRoyalFlush(cards); cards => isFlush(cards) && isStraight(cards);
handValues = new Dictionary<string, Func<List<Card>, bool>> Func<List<Card>, bool> isRoyalFlush =
{ cards => cards.Min(card => card.Number) == 1 &&
{ "Royal Flush", isRoyalFlush }, cards.Max(card => card.Number) == 13
{ "Straight Flush", isStraightFlush }, && hasStraightFlush(cards);
{ "Four Of A Kind", isFourOfKind },
{ "Full House", isFullHouse }, Func<List<Card>, bool> isStraightFlush =
{ "Flush", isFlush }, cards => hasStraightFlush(cards) && !isRoyalFlush(cards);
{ "Straight", isStraight },
{ "Three Of A Kind", isThreeOfKind }, handValues = new Dictionary<string, Func<List<Card>, bool>>
{ "Two Pairs", isTwoPair }, {
{ "A Pair", isPair } { "Royal Flush", isRoyalFlush },
}; { "Straight Flush", isStraightFlush },
} { "Four Of A Kind", isFourOfKind },
{ "Full House", isFullHouse },
public static string GetHandValue(List<Card> cards) { { "Flush", isFlush },
foreach (var kvp in handValues.Where(x => x.Value(cards))) { { "Straight", isStraight },
return kvp.Key; { "Three Of A Kind", isThreeOfKind },
{ "Two Pairs", isTwoPair },
{ "A Pair", isPair }
};
}
public static string GetHandValue(List<Card> 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();
} }
} }

View File

@ -1,7 +1,7 @@
using System.IO; using System.IO;
namespace NadekoBot.Classes.JSONModels { namespace NadekoBot.Classes.JSONModels {
internal class LocalizedStrings { public class LocalizedStrings {
public string[] Insults { get; set; } = { public string[] Insults { get; set; } = {
" You are a poop.", " You're a jerk.", " You are a poop.", " You're a jerk.",
" I will eat you when I get my powers back." " I will eat you when I get my powers back."

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Modules; using NadekoBot.Modules;

View File

@ -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" + 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`" + $"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 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 <https://github.com/Kwoth/NadekoBot/blob/master/commandlist.md>"; "**LIST OF COMMANDS CAN BE FOUND ON THIS LINK**\n\n <https://github.com/Kwoth/NadekoBot/blob/master/commandlist.md>";
public Action<CommandEventArgs> DoGitFunc() => e => { public Action<CommandEventArgs> DoGitFunc() => e => {

View File

@ -17,7 +17,7 @@ using NadekoBot.Classes.JSONModels;
using NadekoBot.Commands; using NadekoBot.Commands;
namespace NadekoBot { namespace NadekoBot {
internal class NadekoBot { public class NadekoBot {
public static DiscordClient Client; public static DiscordClient Client;
public static Credentials Creds { get; set; } public static Credentials Creds { get; set; }
public static Configuration Config { get; set; } public static Configuration Config { get; set; }