Added gambling, raffle done
This commit is contained in:
295
src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs
Normal file
295
src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs
Normal file
@@ -0,0 +1,295 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling.Commands
|
||||
{
|
||||
class AnimalRacing : DiscordCommand
|
||||
{
|
||||
public static ConcurrentDictionary<ulong, AnimalRace> AnimalRaces = new ConcurrentDictionary<ulong, AnimalRace>();
|
||||
|
||||
public AnimalRacing(DiscordModule module) : base(module)
|
||||
{
|
||||
}
|
||||
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Prefix + "race")
|
||||
.Description($"Starts a new animal race. | `{Prefix}race`")
|
||||
.Do(e =>
|
||||
{
|
||||
var ar = new AnimalRace(e.Server.Id, e.Channel);
|
||||
if (ar.Fail)
|
||||
{
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
cgb.CreateCommand(Prefix + "joinrace")
|
||||
.Alias(Prefix + "jr")
|
||||
.Description($"Joins a new race. You can specify an amount of flowers for betting (optional). You will get YourBet*(participants-1) back if you win. | `{Prefix}jr` or `{Prefix}jr 5`")
|
||||
.Parameter("amount", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
int amount;
|
||||
if (!int.TryParse(e.GetArg("amount"), out amount) || amount < 0)
|
||||
amount = 0;
|
||||
|
||||
var userFlowers = GamblingModule.GetUserFlowers(e.User.Id);
|
||||
|
||||
if (userFlowers < amount)
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount > 0)
|
||||
await FlowersHandler.RemoveFlowers(e.User, "BetRace", (int)amount, true).ConfigureAwait(false);
|
||||
|
||||
AnimalRace ar;
|
||||
if (!AnimalRaces.TryGetValue(e.Server.Id, out ar))
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync("No race exists on this server");
|
||||
return;
|
||||
}
|
||||
await ar.JoinRace(e.User, amount);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public class AnimalRace
|
||||
{
|
||||
|
||||
private ConcurrentQueue<string> animals = new ConcurrentQueue<string>(NadekoBot.Config.RaceAnimals.Shuffle());
|
||||
|
||||
public bool Fail { get; internal set; }
|
||||
|
||||
public List<Participant> participants = new List<Participant>();
|
||||
private ulong serverId;
|
||||
private int messagesSinceGameStarted = 0;
|
||||
|
||||
public Channel raceChannel { get; set; }
|
||||
public bool Started { get; private set; } = false;
|
||||
|
||||
public AnimalRace(ulong serverId, Channel ch)
|
||||
{
|
||||
this.serverId = serverId;
|
||||
this.raceChannel = ch;
|
||||
if (!AnimalRaces.TryAdd(serverId, this))
|
||||
{
|
||||
Fail = true;
|
||||
return;
|
||||
}
|
||||
var cancelSource = new CancellationTokenSource();
|
||||
var token = cancelSource.Token;
|
||||
var fullgame = CheckForFullGameAsync(token);
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await raceChannel.SendMessage($"🏁`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.Config.CommandPrefixes.Gambling}jr to join the race.`");
|
||||
var t = await Task.WhenAny(Task.Delay(20000, token), fullgame);
|
||||
Started = true;
|
||||
cancelSource.Cancel();
|
||||
if (t == fullgame)
|
||||
{
|
||||
await raceChannel.SendMessage("🏁`Race full, starting right now!`");
|
||||
}
|
||||
else if (participants.Count > 1)
|
||||
{
|
||||
await raceChannel.SendMessage("🏁`Game starting with " + participants.Count + " participants.`");
|
||||
}
|
||||
else
|
||||
{
|
||||
await raceChannel.SendMessage("🏁`Race failed to start since there was not enough participants.`");
|
||||
var p = participants.FirstOrDefault();
|
||||
if (p != null)
|
||||
await FlowersHandler.AddFlowersAsync(p.User, "BetRace", p.AmountBet, true).ConfigureAwait(false);
|
||||
End();
|
||||
return;
|
||||
}
|
||||
await Task.Run(StartRace);
|
||||
End();
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
}
|
||||
|
||||
private void End()
|
||||
{
|
||||
AnimalRace throwaway;
|
||||
AnimalRaces.TryRemove(serverId, out throwaway);
|
||||
}
|
||||
|
||||
private async Task StartRace()
|
||||
{
|
||||
var rng = new Random();
|
||||
Participant winner = null;
|
||||
Message msg = null;
|
||||
int place = 1;
|
||||
try
|
||||
{
|
||||
NadekoBot.Client.MessageReceived += Client_MessageReceived;
|
||||
|
||||
while (!participants.All(p => p.Total >= 60))
|
||||
{
|
||||
//update the state
|
||||
participants.ForEach(p =>
|
||||
{
|
||||
|
||||
p.Total += 1 + rng.Next(0, 10);
|
||||
if (p.Total > 60)
|
||||
{
|
||||
p.Total = 60;
|
||||
if (winner == null)
|
||||
{
|
||||
winner = p;
|
||||
}
|
||||
if (p.Place == 0)
|
||||
p.Place = place++;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//draw the state
|
||||
|
||||
var text = $@"|🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🔚|
|
||||
{String.Join("\n", participants.Select(p => $"{(int)(p.Total / 60f * 100),-2}%|{p.ToString()}"))}
|
||||
|🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🔚|";
|
||||
if (msg == null || messagesSinceGameStarted >= 10) // also resend the message if channel was spammed
|
||||
{
|
||||
if (msg != null)
|
||||
try { await msg.Delete(); } catch { }
|
||||
msg = await raceChannel.SendMessage(text);
|
||||
messagesSinceGameStarted = 0;
|
||||
}
|
||||
else
|
||||
await msg.Edit(text);
|
||||
|
||||
await Task.Delay(2500);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
NadekoBot.Client.MessageReceived -= Client_MessageReceived;
|
||||
}
|
||||
|
||||
if (winner.AmountBet > 0)
|
||||
{
|
||||
var wonAmount = winner.AmountBet * (participants.Count - 1);
|
||||
await FlowersHandler.AddFlowersAsync(winner.User, "Won a Race", wonAmount).ConfigureAwait(false);
|
||||
await raceChannel.SendMessage($"🏁 {winner.User.Mention} as {winner.Animal} **Won the race and {wonAmount}{NadekoBot.Config.CurrencySign}!**");
|
||||
}
|
||||
else
|
||||
{
|
||||
await raceChannel.SendMessage($"🏁 {winner.User.Mention} as {winner.Animal} **Won the race!**");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Client_MessageReceived(object sender, MessageEventArgs e)
|
||||
{
|
||||
if (e.Message.IsAuthor || e.Channel.IsPrivate || e.Channel != raceChannel)
|
||||
return;
|
||||
messagesSinceGameStarted++;
|
||||
}
|
||||
|
||||
private async Task CheckForFullGameAsync(CancellationToken cancelToken)
|
||||
{
|
||||
while (animals.Count > 0)
|
||||
{
|
||||
await Task.Delay(100, cancelToken);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> JoinRace(User u, int amount = 0)
|
||||
{
|
||||
var animal = "";
|
||||
if (!animals.TryDequeue(out animal))
|
||||
{
|
||||
await raceChannel.SendMessage($"{u.Mention} `There is no running race on this server.`");
|
||||
return false;
|
||||
}
|
||||
var p = new Participant(u, animal, amount);
|
||||
if (participants.Contains(p))
|
||||
{
|
||||
await raceChannel.SendMessage($"{u.Mention} `You already joined this race.`");
|
||||
return false;
|
||||
}
|
||||
if (Started)
|
||||
{
|
||||
await raceChannel.SendMessage($"{u.Mention} `Race is already started`");
|
||||
return false;
|
||||
}
|
||||
participants.Add(p);
|
||||
await raceChannel.SendMessage($"{u.Mention} **joined the race as a {p.Animal}" + (amount > 0 ? $" and bet {amount} {NadekoBot.Config.CurrencyName.SnPl(amount)}!**" : "**"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class Participant
|
||||
{
|
||||
public User User { get; set; }
|
||||
public string Animal { get; set; }
|
||||
public int AmountBet { get; set; }
|
||||
|
||||
public float Coeff { get; set; }
|
||||
public int Total { get; set; }
|
||||
|
||||
public int Place { get; set; } = 0;
|
||||
|
||||
public Participant(User u, string a, int amount)
|
||||
{
|
||||
this.User = u;
|
||||
this.Animal = a;
|
||||
this.AmountBet = amount;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return User.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var p = obj as Participant;
|
||||
return p == null ?
|
||||
false :
|
||||
p.User == User;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var str = new string('‣', Total) + Animal;
|
||||
if (Place == 0)
|
||||
return str;
|
||||
if (Place == 1)
|
||||
{
|
||||
return str + "🏆";
|
||||
}
|
||||
else if (Place == 2)
|
||||
{
|
||||
return str + "`2nd`";
|
||||
}
|
||||
else if (Place == 3)
|
||||
{
|
||||
return str + "`3rd`";
|
||||
}
|
||||
else
|
||||
{
|
||||
return str + $"`{Place}th`";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
162
src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs
Normal file
162
src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
public partial class DiceRollCommands
|
||||
{
|
||||
|
||||
public DiceRollCommand(DiscordModule module) : base(module) { }
|
||||
|
||||
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "roll")
|
||||
.Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice." +
|
||||
$" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `{Prefix}roll` or `{Prefix}roll 7` or `{Prefix}roll 3d5`")
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(RollFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "rolluo")
|
||||
.Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice (unordered)." +
|
||||
$" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `{Prefix}roll` or `{Prefix}roll` 7 or `{Prefix}roll 3d5`")
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(RollFunc(false));
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "nroll")
|
||||
.Description($"Rolls in a given range. | `{Prefix}nroll 5` (rolls 0-5) or `{Prefix}nroll 5-15`")
|
||||
.Parameter("range", ParameterType.Required)
|
||||
.Do(NRollFunc());
|
||||
}
|
||||
|
||||
private Image GetDice(int num) => num != 10
|
||||
? Properties.Resources.ResourceManager.GetObject("_" + num) as Image
|
||||
: new[]
|
||||
{
|
||||
(Properties.Resources.ResourceManager.GetObject("_" + 1) as Image),
|
||||
(Properties.Resources.ResourceManager.GetObject("_" + 0) as Image),
|
||||
}.Merge();
|
||||
|
||||
|
||||
Regex dndRegex = new Regex(@"(?<n1>\d+)d(?<n2>\d+)", RegexOptions.Compiled);
|
||||
private Func<CommandEventArgs, Task> RollFunc(bool ordered = true)
|
||||
{
|
||||
var r = new Random();
|
||||
return async e =>
|
||||
{
|
||||
var arg = e.Args[0]?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
{
|
||||
var gen = r.Next(0, 101);
|
||||
|
||||
var num1 = gen / 10;
|
||||
var num2 = gen % 10;
|
||||
|
||||
var imageStream = new Image[2] { GetDice(num1), GetDice(num2) }.Merge().ToStream(ImageFormat.Png);
|
||||
|
||||
await e.Channel.SendFile("dice.png", imageStream).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
Match m;
|
||||
if ((m = dndRegex.Match(arg)).Length != 0)
|
||||
{
|
||||
int n1;
|
||||
int n2;
|
||||
if (int.TryParse(m.Groups["n1"].ToString(), out n1) &&
|
||||
int.TryParse(m.Groups["n2"].ToString(), out n2) &&
|
||||
n1 <= 50 && n2 <= 100000 && n1 > 0 && n2 > 0)
|
||||
{
|
||||
var arr = new int[n1];
|
||||
for (int i = 0; i < n1; i++)
|
||||
{
|
||||
arr[i] = r.Next(1, n2 + 1);
|
||||
}
|
||||
var elemCnt = 0;
|
||||
await imsg.Channel.SendMessageAsync($"`Rolled {n1} {(n1 == 1 ? "die" : "dice")} 1-{n2}.`\n`Result:` " + string.Join(", ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => elemCnt++ % 2 == 0 ? $"**{x}**" : x.ToString()))).ConfigureAwait(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var num = int.Parse(e.Args[0]);
|
||||
if (num < 1) num = 1;
|
||||
if (num > 30)
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync("You can roll up to 30 dice at a time.").ConfigureAwait(false);
|
||||
num = 30;
|
||||
}
|
||||
var dices = new List<Image>(num);
|
||||
var values = new List<int>(num);
|
||||
for (var i = 0; i < num; i++)
|
||||
{
|
||||
var randomNumber = r.Next(1, 7);
|
||||
var toInsert = dices.Count;
|
||||
if (ordered)
|
||||
{
|
||||
if (randomNumber == 6 || dices.Count == 0)
|
||||
toInsert = 0;
|
||||
else if (randomNumber != 1)
|
||||
for (var j = 0; j < dices.Count; j++)
|
||||
{
|
||||
if (values[j] < randomNumber)
|
||||
{
|
||||
toInsert = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
toInsert = dices.Count;
|
||||
}
|
||||
dices.Insert(toInsert, GetDice(randomNumber));
|
||||
values.Insert(toInsert, randomNumber);
|
||||
}
|
||||
|
||||
var bitmap = dices.Merge();
|
||||
await imsg.Channel.SendMessageAsync(values.Count + " Dice rolled. Total: **" + values.Sum() + "** Average: **" + (values.Sum() / (1.0f * values.Count)).ToString("N2") + "**").ConfigureAwait(false);
|
||||
await e.Channel.SendFile("dice.png", bitmap.ToStream(ImageFormat.Png)).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync("Please enter a number of dice to roll.").ConfigureAwait(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private Func<CommandEventArgs, Task> NRollFunc() =>
|
||||
async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
int rolled;
|
||||
if (e.GetArg("range").Contains("-"))
|
||||
{
|
||||
var arr = e.GetArg("range").Split('-')
|
||||
.Take(2)
|
||||
.Select(int.Parse)
|
||||
.ToArray();
|
||||
if (arr[0] > arr[1])
|
||||
throw new ArgumentException("First argument should be bigger than the second one.");
|
||||
rolled = new Random().Next(arr[0], arr[1] + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rolled = new Random().Next(0, int.Parse(e.GetArg("range")) + 1);
|
||||
}
|
||||
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} rolled **{rolled}**.").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync($":anger: {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
91
src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs
Normal file
91
src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Gambling.Helpers;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
internal class DrawCommand : DiscordCommand
|
||||
{
|
||||
public DrawCommand(DiscordModule module) : base(module) { }
|
||||
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "draw")
|
||||
.Description($"Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | `{Prefix}draw [x]`")
|
||||
.Parameter("count", ParameterType.Optional)
|
||||
.Do(DrawCardFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "shuffle")
|
||||
.Alias(Module.Prefix + "sh")
|
||||
.Description($"Reshuffles all cards back into the deck.|`{Prefix}shuffle`")
|
||||
.Do(ReshuffleTask());
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<Discord.Server, Cards> AllDecks = new ConcurrentDictionary<Discord.Server, Cards>();
|
||||
|
||||
private static Func<CommandEventArgs, Task> ReshuffleTask()
|
||||
{
|
||||
return async e =>
|
||||
{
|
||||
AllDecks.AddOrUpdate(e.Server,
|
||||
(s) => new Cards(),
|
||||
(s, c) =>
|
||||
{
|
||||
c.Restart();
|
||||
return c;
|
||||
});
|
||||
|
||||
await imsg.Channel.SendMessageAsync("Deck reshuffled.").ConfigureAwait(false);
|
||||
};
|
||||
}
|
||||
|
||||
private Func<CommandEventArgs, Task> DrawCardFunc() => async (e) =>
|
||||
{
|
||||
var cards = AllDecks.GetOrAdd(e.Server, (s) => new Cards());
|
||||
|
||||
try
|
||||
{
|
||||
var num = 1;
|
||||
var isParsed = int.TryParse(e.GetArg("count"), out num);
|
||||
if (!isParsed || num < 2)
|
||||
{
|
||||
var c = cards.DrawACard();
|
||||
await e.Channel.SendFile(c.Name + ".jpg", (Properties.Resources.ResourceManager.GetObject(c.Name) as Image).ToStream()).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (num > 5)
|
||||
num = 5;
|
||||
|
||||
var images = new List<Image>();
|
||||
var cardObjects = new List<Cards.Card>();
|
||||
for (var i = 0; i < num; i++)
|
||||
{
|
||||
if (cards.CardPool.Count == 0 && i != 0)
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync("No more cards in a deck.").ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
var currentCard = cards.DrawACard();
|
||||
cardObjects.Add(currentCard);
|
||||
images.Add(Properties.Resources.ResourceManager.GetObject(currentCard.Name) as Image);
|
||||
}
|
||||
var bitmap = images.Merge();
|
||||
await e.Channel.SendFile(images.Count + " cards.jpg", bitmap.ToStream()).ConfigureAwait(false);
|
||||
if (cardObjects.Count == 5)
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} `{Cards.GetHandValue(cardObjects)}`").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error drawing (a) card(s) " + ex.ToString());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
112
src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs
Normal file
112
src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
internal class FlipCoinCommand : DiscordCommand
|
||||
{
|
||||
|
||||
public FlipCoinCommand(DiscordModule module) : base(module) { }
|
||||
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "flip")
|
||||
.Description($"Flips coin(s) - heads or tails, and shows an image. | `{Prefix}flip` or `{Prefix}flip 3`")
|
||||
.Parameter("count", ParameterType.Optional)
|
||||
.Do(FlipCoinFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "betflip")
|
||||
.Alias(Prefix+"bf")
|
||||
.Description($"Bet to guess will the result be heads or tails. Guessing award you double flowers you've bet. | `{Prefix}bf 5 heads` or `{Prefix}bf 3 t`")
|
||||
.Parameter("amount", ParameterType.Required)
|
||||
.Parameter("guess", ParameterType.Required)
|
||||
.Do(BetFlipCoinFunc());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private readonly Random rng = new Random();
|
||||
public Func<CommandEventArgs, Task> BetFlipCoinFunc() => async e =>
|
||||
{
|
||||
|
||||
var amountstr = e.GetArg("amount").Trim();
|
||||
|
||||
var guessStr = e.GetArg("guess").Trim().ToUpperInvariant();
|
||||
if (guessStr != "H" && guessStr != "T" && guessStr != "HEADS" && guessStr != "TAILS")
|
||||
return;
|
||||
|
||||
int amount;
|
||||
if (!int.TryParse(amountstr, out amount) || amount < 1)
|
||||
return;
|
||||
|
||||
var userFlowers = GamblingModule.GetUserFlowers(e.User.Id);
|
||||
|
||||
if (userFlowers < amount)
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await FlowersHandler.RemoveFlowers(e.User, "Betflip Gamble", (int)amount, true).ConfigureAwait(false);
|
||||
//heads = true
|
||||
//tails = false
|
||||
|
||||
var guess = guessStr == "HEADS" || guessStr == "H";
|
||||
bool result = false;
|
||||
if (rng.Next(0, 2) == 1) {
|
||||
await e.Channel.SendFile("heads.png", Properties.Resources.heads.ToStream(System.Drawing.Imaging.ImageFormat.Png)).ConfigureAwait(false);
|
||||
result = true;
|
||||
}
|
||||
else {
|
||||
await e.Channel.SendFile("tails.png", Properties.Resources.tails.ToStream(System.Drawing.Imaging.ImageFormat.Png)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
string str;
|
||||
if (guess == result)
|
||||
{
|
||||
str = $"{e.User.Mention}`You guessed it!` You won {amount * 2}{NadekoBot.Config.CurrencySign}";
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Betflip Gamble", amount * 2, true).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
else
|
||||
str = $"{e.User.Mention}`More luck next time.`";
|
||||
|
||||
await imsg.Channel.SendMessageAsync(str).ConfigureAwait(false);
|
||||
};
|
||||
|
||||
public Func<CommandEventArgs, Task> FlipCoinFunc() => async e =>
|
||||
{
|
||||
|
||||
if (e.GetArg("count") == "")
|
||||
{
|
||||
if (rng.Next(0, 2) == 1)
|
||||
await e.Channel.SendFile("heads.png", Properties.Resources.heads.ToStream(System.Drawing.Imaging.ImageFormat.Png)).ConfigureAwait(false);
|
||||
else
|
||||
await e.Channel.SendFile("tails.png", Properties.Resources.tails.ToStream(System.Drawing.Imaging.ImageFormat.Png)).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
int result;
|
||||
if (int.TryParse(e.GetArg("count"), out result))
|
||||
{
|
||||
if (result > 10)
|
||||
result = 10;
|
||||
var imgs = new Image[result];
|
||||
for (var i = 0; i < result; i++)
|
||||
{
|
||||
imgs[i] = rng.Next(0, 2) == 0 ?
|
||||
Properties.Resources.tails :
|
||||
Properties.Resources.heads;
|
||||
}
|
||||
await e.Channel.SendFile($"{result} coins.png", imgs.Merge().ToStream(System.Drawing.Imaging.ImageFormat.Png)).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await imsg.Channel.SendMessageAsync("Invalid number").ConfigureAwait(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
208
src/NadekoBot/Modules/Gambling/Gambling.cs
Normal file
208
src/NadekoBot/Modules/Gambling/Gambling.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Extensions;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Services;
|
||||
|
||||
//todo DB
|
||||
namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
[Module("$", AppendSpace = false)]
|
||||
public partial class Gambling : DiscordModule
|
||||
{
|
||||
public Gambling(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
|
||||
{
|
||||
}
|
||||
|
||||
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Raffle(IMessage imsg, [Remainder] IRole role = null)
|
||||
{
|
||||
var channel = imsg.Channel as ITextChannel;
|
||||
|
||||
role = role ?? channel.Guild.EveryoneRole;
|
||||
|
||||
var members = (await role.Members()).Where(u => u.Status == UserStatus.Online);
|
||||
var membersArray = members as IUser[] ?? members.ToArray();
|
||||
var usr = membersArray[new Random().Next(0, membersArray.Length)];
|
||||
await imsg.Channel.SendMessageAsync($"**Raffled user:** {usr.Username} (id: {usr.Id})").ConfigureAwait(false);
|
||||
|
||||
}
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
cgb.CreateCommand(Prefix + "raffle")
|
||||
.Description($"Prints a name and ID of a random user from the online list from the (optional) role. | `{Prefix}raffle` or `{Prefix}raffle RoleName`")
|
||||
.Parameter("role", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "$$")
|
||||
.Description(string.Format("Check how much {0}s a person has. (Defaults to yourself) |`{1}$$` or `{1}$$ @Someone`",
|
||||
NadekoBot.Config.CurrencyName, Prefix))
|
||||
.Parameter("all", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var usr = e.Message.MentionedUsers.FirstOrDefault() ?? e.User;
|
||||
var pts = GetUserFlowers(usr.Id);
|
||||
var str = $"{usr.Name} has {pts} {NadekoBot.Config.CurrencySign}";
|
||||
await imsg.Channel.SendMessageAsync(str).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "give")
|
||||
.Description(string.Format("Give someone a certain amount of {0}s", NadekoBot.Config.CurrencyName)+ $"|`{Prefix}give 1 \"@SomeGuy\"`")
|
||||
.Parameter("amount", ParameterType.Required)
|
||||
.Parameter("receiver", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var amountStr = e.GetArg("amount")?.Trim();
|
||||
long amount;
|
||||
if (!long.TryParse(amountStr, out amount) || amount <= 0)
|
||||
return;
|
||||
|
||||
var mentionedUser = e.Message.MentionedUsers.FirstOrDefault(u =>
|
||||
u.Id != NadekoBot.Client.CurrentUser.Id &&
|
||||
u.Id != e.User.Id);
|
||||
if (mentionedUser == null)
|
||||
return;
|
||||
|
||||
var userFlowers = GetUserFlowers(e.User.Id);
|
||||
|
||||
if (userFlowers < amount)
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await FlowersHandler.RemoveFlowers(e.User, "Gift", (int)amount, true).ConfigureAwait(false);
|
||||
await FlowersHandler.AddFlowersAsync(mentionedUser, "Gift", (int)amount).ConfigureAwait(false);
|
||||
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} successfully sent {amount} {NadekoBot.Config.CurrencyName}s to {mentionedUser.Mention}!").ConfigureAwait(false);
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "award")
|
||||
.Description($"Gives someone a certain amount of flowers. **Bot Owner Only!** | `{Prefix}award 100 @person`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Parameter("amount", ParameterType.Required)
|
||||
.Parameter("receiver", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var amountStr = e.GetArg("amount")?.Trim();
|
||||
long amount;
|
||||
if (!long.TryParse(amountStr, out amount) || amount < 0)
|
||||
return;
|
||||
|
||||
var mentionedUser = e.Message.MentionedUsers.FirstOrDefault(u =>
|
||||
u.Id != NadekoBot.Client.CurrentUser.Id);
|
||||
if (mentionedUser == null)
|
||||
return;
|
||||
|
||||
await FlowersHandler.AddFlowersAsync(mentionedUser, $"Awarded by bot owner. ({e.User.Name}/{e.User.Id})", (int)amount).ConfigureAwait(false);
|
||||
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} successfully awarded {amount} {NadekoBot.Config.CurrencyName}s to {mentionedUser.Mention}!").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "take")
|
||||
.Description($"Takes a certain amount of flowers from someone. **Bot Owner Only!** | `{Prefix}take 1 \"@someguy\"`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Parameter("amount", ParameterType.Required)
|
||||
.Parameter("rektperson", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var amountStr = e.GetArg("amount")?.Trim();
|
||||
long amount;
|
||||
if (!long.TryParse(amountStr, out amount) || amount < 0)
|
||||
return;
|
||||
|
||||
var mentionedUser = e.Message.MentionedUsers.FirstOrDefault(u =>
|
||||
u.Id != NadekoBot.Client.CurrentUser.Id);
|
||||
if (mentionedUser == null)
|
||||
return;
|
||||
|
||||
await FlowersHandler.RemoveFlowers(mentionedUser, $"Taken by bot owner.({e.User.Name}/{e.User.Id})", (int)amount).ConfigureAwait(false);
|
||||
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} successfully took {amount} {NadekoBot.Config.CurrencyName}s from {mentionedUser.Mention}!").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "betroll")
|
||||
.Alias(Prefix + "br")
|
||||
.Description($"Bets a certain amount of {NadekoBot.Config.CurrencyName}s and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | `{Prefix}br 5`")
|
||||
.Parameter("amount",ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var amountstr = e.GetArg("amount").Trim();
|
||||
int amount;
|
||||
|
||||
if (!int.TryParse(amountstr, out amount) || amount < 1)
|
||||
return;
|
||||
|
||||
var userFlowers = GetUserFlowers(e.User.Id);
|
||||
|
||||
if (userFlowers < amount)
|
||||
{
|
||||
await imsg.Channel.SendMessageAsync($"{e.User.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await FlowersHandler.RemoveFlowers(e.User, "Betroll Gamble", (int)amount, true).ConfigureAwait(false);
|
||||
|
||||
var rng = new Random().Next(0, 101);
|
||||
var str = $"{e.User.Mention} `You rolled {rng}.` ";
|
||||
if (rng < 67)
|
||||
{
|
||||
str += "Better luck next time.";
|
||||
}
|
||||
else if (rng < 90)
|
||||
{
|
||||
str += $"Congratulations! You won {amount * 2}{NadekoBot.Config.CurrencySign} for rolling above 66";
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Betroll Gamble", amount * 2, true).ConfigureAwait(false);
|
||||
}
|
||||
else if (rng < 100)
|
||||
{
|
||||
str += $"Congratulations! You won {amount * 3}{NadekoBot.Config.CurrencySign} for rolling above 90.";
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Betroll Gamble", amount * 3, true).ConfigureAwait(false);
|
||||
}
|
||||
else {
|
||||
str += $"👑 Congratulations! You won {amount * 10}{NadekoBot.Config.CurrencySign} for rolling **100**. 👑";
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Betroll Gamble", amount * 10, true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await imsg.Channel.SendMessageAsync(str).ConfigureAwait(false);
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "leaderboard")
|
||||
.Alias(Prefix + "lb")
|
||||
.Description($"Displays bot currency leaderboard | `{Prefix}lb`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var richestTemp = DbHandler.Instance.GetTopRichest();
|
||||
var richest = richestTemp as CurrencyState[] ?? richestTemp.ToArray();
|
||||
if (richest.Length == 0)
|
||||
return;
|
||||
await imsg.Channel.SendMessageAsync(
|
||||
richest.Aggregate(new StringBuilder(
|
||||
$@"```xl
|
||||
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
|
||||
┃ Id ┃ $$$ ┃
|
||||
"),
|
||||
(cur, cs) => cur.AppendLine(
|
||||
$@"┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━┫
|
||||
┃{(e.Server.Users.Where(u => u.Id == (ulong)cs.UserId).FirstOrDefault()?.Name.TrimTo(18, true) ?? cs.UserId.ToString()),-20} ┃ {cs.Value,5} ┃")
|
||||
).ToString() + "┗━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━┛```").ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static long GetUserFlowers(ulong userId) =>
|
||||
Classes.DbHandler.Instance.GetStateByUserId((long)userId)?.Value ?? 0;
|
||||
}
|
||||
}
|
232
src/NadekoBot/Modules/Gambling/Helpers/Cards.cs
Normal file
232
src/NadekoBot/Modules/Gambling/Helpers/Cards.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling.Helpers
|
||||
{
|
||||
public class Cards
|
||||
{
|
||||
private static readonly Dictionary<int, string> cardNames = new Dictionary<int, string>() {
|
||||
{ 1, "Ace" },
|
||||
{ 2, "Two" },
|
||||
{ 3, "Three" },
|
||||
{ 4, "Four" },
|
||||
{ 5, "Five" },
|
||||
{ 6, "Six" },
|
||||
{ 7, "Seven" },
|
||||
{ 8, "Eight" },
|
||||
{ 9, "Nine" },
|
||||
{ 10, "Ten" },
|
||||
{ 11, "Jack" },
|
||||
{ 12, "Queen" },
|
||||
{ 13, "King" }
|
||||
};
|
||||
private static Dictionary<string, Func<List<Card>, bool>> handValues;
|
||||
|
||||
|
||||
public enum CardSuit
|
||||
{
|
||||
Spades = 1,
|
||||
Hearts = 2,
|
||||
Diamonds = 3,
|
||||
Clubs = 4
|
||||
}
|
||||
|
||||
public class Card : IComparable
|
||||
{
|
||||
public CardSuit Suit { get; }
|
||||
public int Number { get; }
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
var str = "";
|
||||
|
||||
if (Number <= 10 && Number > 1)
|
||||
{
|
||||
str += "_" + Number;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Card> cardPool;
|
||||
public List<Card> CardPool
|
||||
{
|
||||
get { return cardPool; }
|
||||
set { cardPool = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the BlackJackGame, this allows you to create multiple games running at one time.
|
||||
/// </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();
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <returns>A card from the pool</returns>
|
||||
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;
|
||||
|
||||
// if you want to shuffle when you fill, then take the first one
|
||||
/*
|
||||
Card c = cardPool[0];
|
||||
cardPool.RemoveAt(0);
|
||||
return c;
|
||||
*/
|
||||
}
|
||||
/// <summary>
|
||||
/// Shuffles the deck. Use this if you want to take cards from the top of the deck, instead of randomly. See DrawACard method.
|
||||
/// </summary>
|
||||
private void Shuffle()
|
||||
{
|
||||
if (cardPool.Count <= 1) return;
|
||||
var orderedPool = cardPool.OrderBy(x => r.Next());
|
||||
cardPool = cardPool as List<Card> ?? orderedPool.ToList();
|
||||
}
|
||||
public override string ToString() => string.Concat(cardPool.Select(c => c.ToString())) + Environment.NewLine;
|
||||
|
||||
private static void InitHandValues()
|
||||
{
|
||||
Func<List<Card>, bool> hasPair =
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Count(group => group.Count() == 2) == 1;
|
||||
Func<List<Card>, bool> isPair =
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Count(group => group.Count() == 3) == 0
|
||||
&& hasPair(cards);
|
||||
|
||||
Func<List<Card>, bool> isTwoPair =
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Count(group => group.Count() == 2) == 2;
|
||||
|
||||
Func<List<Card>, 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<List<Card>, bool> hasThreeOfKind =
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Any(group => group.Count() == 3);
|
||||
|
||||
Func<List<Card>, bool> isThreeOfKind =
|
||||
cards => hasThreeOfKind(cards) && !hasPair(cards);
|
||||
|
||||
Func<List<Card>, bool> isFlush =
|
||||
cards => cards.GroupBy(card => card.Suit).Count() == 1;
|
||||
|
||||
Func<List<Card>, bool> isFourOfKind =
|
||||
cards => cards.GroupBy(card => card.Number)
|
||||
.Any(group => group.Count() == 4);
|
||||
|
||||
Func<List<Card>, bool> isFullHouse =
|
||||
cards => hasPair(cards) && hasThreeOfKind(cards);
|
||||
|
||||
Func<List<Card>, bool> hasStraightFlush =
|
||||
cards => isFlush(cards) && isStraight(cards);
|
||||
|
||||
Func<List<Card>, bool> isRoyalFlush =
|
||||
cards => cards.Min(card => card.Number) == 1 &&
|
||||
cards.Max(card => card.Number) == 13
|
||||
&& hasStraightFlush(cards);
|
||||
|
||||
Func<List<Card>, bool> isStraightFlush =
|
||||
cards => hasStraightFlush(cards) && !isRoyalFlush(cards);
|
||||
|
||||
handValues = new Dictionary<string, Func<List<Card>, 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<Card> cards)
|
||||
{
|
||||
if (handValues == null)
|
||||
InitHandValues();
|
||||
foreach (var kvp in handValues.Where(x => x.Value(cards)))
|
||||
{
|
||||
return kvp.Key;
|
||||
}
|
||||
return "High card " + (cards.FirstOrDefault(c => c.Number == 1)?.GetName() ?? cards.Max().GetName());
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user