refactored games module

This commit is contained in:
Master Kwoth 2016-04-14 23:30:13 +02:00
parent fe67591081
commit 3e6b2df73d
9 changed files with 104 additions and 58 deletions

View File

@ -96,7 +96,7 @@ namespace NadekoBot.Classes.Trivia
ShouldStopGame = true;
await channel.SendMessage("**Trivia game ended**\n" + GetLeaderboard());
TriviaGame throwAwayValue;
Commands.Trivia.RunningTrivias.TryRemove(server.Id, out throwAwayValue);
Modules.Games.Commands.Trivia.RunningTrivias.TryRemove(server.Id, out throwAwayValue);
}
public async Task StopGame()

View File

@ -1,6 +1,7 @@
using Discord.Commands;
using NadekoBot.Classes.JSONModels;
using NadekoBot.Commands;
using NadekoBot.Modules.Games.Commands;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -1,25 +1,28 @@
using System;
using Discord.Commands;
using NadekoBot.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
using NadekoBot.Modules;
namespace NadekoBot.Commands {
class BetrayGame : DiscordCommand {
namespace NadekoBot.Modules.Games.Commands
{
class BetrayGame : DiscordCommand
{
public BetrayGame(DiscordModule module) : base(module) { }
private enum Answers {
private enum Answers
{
Cooperate,
Betray
}
internal override void Init(CommandGroupBuilder cgb) {
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "betray")
.Description("BETRAY GAME. Betray nadeko next turn." +
"If Nadeko cooperates - you get extra points, nadeko loses a LOT." +
"If Nadeko betrays - you both lose some points.")
.Do(async e => {
.Do(async e =>
{
await ReceiveAnswer(e, Answers.Betray);
});
@ -27,7 +30,8 @@ namespace NadekoBot.Commands {
.Description("BETRAY GAME. Cooperate with nadeko next turn." +
"If Nadeko cooperates - you both get bonus points." +
"If Nadeko betrays - you lose A LOT, nadeko gets extra.")
.Do(async e => {
.Do(async e =>
{
await ReceiveAnswer(e, Answers.Cooperate);
});
@ -55,7 +59,8 @@ namespace NadekoBot.Commands {
private int round = 0;
private Answers NextAnswer = Answers.Cooperate;
private async Task ReceiveAnswer(CommandEventArgs e, Answers userAnswer) {
private async Task ReceiveAnswer(CommandEventArgs e, Answers userAnswer)
{
var response = userAnswer == Answers.Betray
? ":no_entry: `You betrayed nadeko` - you monster."
: ":ok: `You cooperated with nadeko.` ";
@ -64,16 +69,23 @@ namespace NadekoBot.Commands {
? ":no_entry: `aww Nadeko betrayed you` - she is so cute"
: ":ok: `Nadeko cooperated.`";
NextAnswer = userAnswer;
if (userAnswer == Answers.Betray && currentAnswer == Answers.Betray) {
if (userAnswer == Answers.Betray && currentAnswer == Answers.Betray)
{
NadekoPoints--;
UserPoints--;
} else if (userAnswer == Answers.Cooperate && currentAnswer == Answers.Cooperate) {
}
else if (userAnswer == Answers.Cooperate && currentAnswer == Answers.Cooperate)
{
NadekoPoints += 2;
UserPoints += 2;
} else if (userAnswer == Answers.Betray && currentAnswer == Answers.Cooperate) {
}
else if (userAnswer == Answers.Betray && currentAnswer == Answers.Cooperate)
{
NadekoPoints -= 3;
UserPoints += 3;
} else if (userAnswer == Answers.Cooperate && currentAnswer == Answers.Betray) {
}
else if (userAnswer == Answers.Cooperate && currentAnswer == Answers.Betray)
{
NadekoPoints += 3;
UserPoints -= 3;
}
@ -98,7 +110,8 @@ namespace NadekoBot.Commands {
}
}
public class BetraySetting {
public class BetraySetting
{
private string Story = $"{0} have robbed a bank and got captured by a police." +
$"Investigators gave you a choice:\n" +
$"You can either >COOPERATE with your friends and " +

View File

@ -1,14 +1,14 @@
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Modules;
using NadekoBot.Commands;
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Commands
namespace NadekoBot.Modules.Games.Commands
{
/// <summary>
/// Flower picking/planting idea is given to me by its

View File

@ -1,6 +1,6 @@
using Discord;
using Discord.Commands;
using NadekoBot.Modules;
using NadekoBot.Commands;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -8,7 +8,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Commands
namespace NadekoBot.Modules.Games.Commands
{
internal class PollCommand : DiscordCommand
{

View File

@ -1,30 +1,37 @@
using System;
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Classes._DataModels;
using NadekoBot.Commands;
using NadekoBot.Extensions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Classes._DataModels;
using NadekoBot.Extensions;
using NadekoBot.Modules;
namespace NadekoBot.Commands {
namespace NadekoBot.Modules.Games.Commands
{
public static class SentencesProvider {
internal static string GetRandomSentence() {
public static class SentencesProvider
{
internal static string GetRandomSentence()
{
var data = DbHandler.Instance.GetAllRows<TypingArticle>();
try {
try
{
return data.ToList()[new Random().Next(0, data.Count())].Text;
} catch {
}
catch
{
return "Failed retrieving data from parse. Owner didn't add any articles to type using `typeadd`.";
}
}
}
public class TypingGame {
public class TypingGame
{
public const float WORD_VALUE = 4.5f;
private readonly Channel channel;
public string CurrentSentence;
@ -32,7 +39,8 @@ namespace NadekoBot.Commands {
private readonly Stopwatch sw;
private readonly List<ulong> finishedUserIds;
public TypingGame(Channel channel) {
public TypingGame(Channel channel)
{
this.channel = channel;
IsActive = false;
sw = new Stopwatch();
@ -41,7 +49,8 @@ namespace NadekoBot.Commands {
public Channel Channell { get; internal set; }
internal async Task<bool> Stop() {
internal async Task<bool> Stop()
{
if (!IsActive) return false;
NadekoBot.Client.MessageReceived -= AnswerReceived;
finishedUserIds.Clear();
@ -52,8 +61,10 @@ namespace NadekoBot.Commands {
return true;
}
internal async Task Start() {
while (true) {
internal async Task Start()
{
while (true)
{
if (IsActive) return; // can't start running game
IsActive = true;
CurrentSentence = SentencesProvider.GetRandomSentence();
@ -71,7 +82,8 @@ namespace NadekoBot.Commands {
sw.Start();
HandleAnswers();
while (i > 0) {
while (i > 0)
{
await Task.Delay(1000);
i--;
if (!IsActive)
@ -82,64 +94,79 @@ namespace NadekoBot.Commands {
}
}
private void HandleAnswers() {
private void HandleAnswers()
{
NadekoBot.Client.MessageReceived += AnswerReceived;
}
private async void AnswerReceived(object sender, MessageEventArgs e) {
try {
private async void AnswerReceived(object sender, MessageEventArgs e)
{
try
{
if (e.Channel == null || e.Channel.Id != channel.Id || e.User.Id == NadekoBot.Client.CurrentUser.Id) return;
var guess = e.Message.RawText;
var distance = CurrentSentence.LevenshteinDistance(guess);
var decision = Judge(distance, guess.Length);
if (decision && !finishedUserIds.Contains(e.User.Id)) {
if (decision && !finishedUserIds.Contains(e.User.Id))
{
finishedUserIds.Add(e.User.Id);
await channel.Send($"{e.User.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!");
if (finishedUserIds.Count % 2 == 0) {
if (finishedUserIds.Count % 2 == 0)
{
await e.Channel.SendMessage($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:");
}
}
} catch { }
}
catch { }
}
private bool Judge(int errors, int textLength) => errors <= textLength / 25;
}
internal class SpeedTyping : DiscordCommand {
internal class SpeedTyping : DiscordCommand
{
public static ConcurrentDictionary<ulong, TypingGame> RunningContests;
public SpeedTyping(DiscordModule module) : base(module) {
public SpeedTyping(DiscordModule module) : base(module)
{
RunningContests = new ConcurrentDictionary<ulong, TypingGame>();
}
public Func<CommandEventArgs, Task> DoFunc() =>
async e => {
async e =>
{
var game = RunningContests.GetOrAdd(e.User.Server.Id, id => new TypingGame(e.Channel));
if (game.IsActive) {
if (game.IsActive)
{
await e.Channel.SendMessage(
$"Contest already running in " +
$"{game.Channell.Mention} channel.");
} else {
}
else
{
await game.Start();
}
};
private Func<CommandEventArgs, Task> QuitFunc() =>
async e => {
async e =>
{
TypingGame game;
if (RunningContests.TryRemove(e.User.Server.Id, out game)) {
if (RunningContests.TryRemove(e.User.Server.Id, out game))
{
await game.Stop();
return;
}
await e.Channel.SendMessage("No contest to stop on this channel.");
};
internal override void Init(CommandGroupBuilder cgb) {
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "typestart")
.Description("Starts a typing contest.")
.Do(DoFunc());
@ -151,10 +178,12 @@ namespace NadekoBot.Commands {
cgb.CreateCommand(Module.Prefix + "typeadd")
.Description("Adds a new article to the typing contest. Owner only.")
.Parameter("text", ParameterType.Unparsed)
.Do(async e => {
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id) || string.IsNullOrWhiteSpace(e.GetArg("text"))) return;
DbHandler.Instance.InsertData(new TypingArticle {
DbHandler.Instance.InsertData(new TypingArticle
{
Text = e.GetArg("text"),
DateAdded = DateTime.Now
});

View File

@ -1,10 +1,10 @@
using Discord.Commands;
using NadekoBot.Modules;
using NadekoBot.Commands;
using System.Collections.Concurrent;
using System.Linq;
using TriviaGame = NadekoBot.Classes.Trivia.TriviaGame;
namespace NadekoBot.Commands
namespace NadekoBot.Modules.Games.Commands
{
internal class Trivia : DiscordCommand
{

View File

@ -4,6 +4,7 @@ using NadekoBot.Classes.JSONModels;
using NadekoBot.Classes.Permissions;
using NadekoBot.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules.Games.Commands;
using System;
using System.Linq;
using System.Threading.Tasks;

View File

@ -8,7 +8,9 @@ using NadekoBot.Modules;
using NadekoBot.Modules.Administration;
using NadekoBot.Modules.Gambling;
using NadekoBot.Modules.Games;
using NadekoBot.Modules.Games.Commands;
using NadekoBot.Modules.Pokemon;
using NadekoBot.Modules.Searches;
using NadekoBot.Modules.Translator;
using Newtonsoft.Json;
using System;