[entertainment] add guess game

This commit is contained in:
Andriy
2023-01-18 02:07:48 +02:00
parent c61d875a6a
commit ec11cf4496
5 changed files with 145 additions and 1 deletions
+1
View File
@@ -6,5 +6,6 @@ namespace Kruzya.TelegramBot.Core.Cache
{
public bool TryGetValue(TKey key, out TValue value);
public void SetValue(TKey key, TValue value, int timeToLive);
public TValue GetOr(TKey key, TValue value);
}
}
+11
View File
@@ -72,6 +72,17 @@ namespace Kruzya.TelegramBot.Core.Cache
return true;
}
public TValue GetOr(TKey key, TValue defValue = default)
{
var doesExist = TryGetValue(key, out var value);
if (!doesExist)
{
value = defValue;
}
return value;
}
public void SetValue(TKey key, TValue value)
{
SetValue(key, value, _defaultTtl);
+12 -1
View File
@@ -1,9 +1,20 @@
using Kruzya.TelegramBot.Core;
global using IGuessCache = Kruzya.TelegramBot.Core.Cache.ICacheStorage<Telegram.Bot.Types.ChatId, System.Collections.Concurrent.ConcurrentDictionary<int, West.Entertainment.Handler.GuessData>>;
global using GuessCache = Kruzya.TelegramBot.Core.Cache.MemoryCache<Telegram.Bot.Types.ChatId, System.Collections.Concurrent.ConcurrentDictionary<int, West.Entertainment.Handler.GuessData>>;
using Kruzya.TelegramBot.Core;
using Microsoft.Extensions.DependencyInjection;
namespace West.Entertainment
{
public class Entertainment : Module
{
public Entertainment(Core core) : base(core) { }
public override void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IGuessCache, GuessCache>();
}
}
}
+112
View File
@@ -0,0 +1,112 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using BotFramework;
using BotFramework.Attributes;
using BotFramework.Enums;
using Kruzya.TelegramBot.Core;
using Kruzya.TelegramBot.Core.Data;
using Kruzya.TelegramBot.Core.Extensions;
using Kruzya.TelegramBot.Core.Service;
using Telegram.Bot;
namespace West.Entertainment.Handler;
public class Guess : CommonHandler
{
private readonly IGuessCache _guessCache;
private readonly ThreadSafeRandom _rng;
private readonly IReputation _reputationService;
private readonly CoreContext _db;
public Guess(IGuessCache guessCache, ThreadSafeRandom rng, IReputation reputationService, CoreContext db) : base(db)
{
_guessCache = guessCache;
_rng = rng;
_reputationService = reputationService;
_db = db;
}
[Command(InChat.Public, "guess", CommandParseMode.Both)]
public async Task HandleGuess()
{
var guessDict = _guessCache.GetOr(Chat.Id, new ConcurrentDictionary<int, GuessData>());
var cooldownOption = await _db.UserValues.FindOrCreateOption(Chat.Id, From.Id, "guessCooldown");
var cooldown = cooldownOption.GetValue<DateTime>();
if (cooldown > DateTime.Now)
{
await Reply($"Следующее использование через {cooldown - DateTime.Now:hh\\:mm\\:ss}.");
return;
}
var doesExist = guessDict.Any(pair => pair.Value.UserId == From.Id);
if (doesExist)
{
await Bot.SendTextMessageAsync(Chat, "Вы уже запустили игру.");
return;
}
var messageId = RawUpdate.Message!.MessageId;
var guessedNumber = _rng.Next(1, 4);
Console.WriteLine(guessedNumber);
var guessData = new GuessData
{
Number = guessedNumber,
UserId = From.Id
};
var message = await Bot.SendTextMessageAsync(Chat.Id, "Выберите число от 1 до 3.", replyToMessageId: messageId);
if (!guessDict.TryAdd(message.MessageId, guessData))
{
return;
}
_guessCache.SetValue(Chat.Id, guessDict, -1);
}
[Message(InChat.Public, MessageFlag.IsReply)]
public async Task HandleGuessResponse()
{
var guessDict = _guessCache.GetOr(Chat.Id, new ConcurrentDictionary<int, GuessData>());
var messageId = RawUpdate.Message!.ReplyToMessage!.MessageId;
if (!guessDict.TryGetValue(messageId, out var data))
{
return;
}
if (From.Id != data.UserId)
{
return;
}
if (!int.TryParse(RawUpdate.Message!.Text, out var responseNumber))
{
return;
}
guessDict.TryRemove(messageId, out _);
_guessCache.SetValue(Chat.Id, guessDict, -1);
var nextUse = DateTime.Now.AddHours(1);
var postFix = $"\nСледующая попытка через: {nextUse - DateTime.Now:hh\\:mm\\:ss}";
string message;
if (responseNumber == data.Number)
{
await _reputationService.IncrementReputationAsync(Chat, From, 20);
message = "Вы угадали! Вам начислено 20 кармы.";
}
else
{
message = "Вы не угадали!";
}
await Bot.SendTextMessageAsync(Chat, message + postFix);
var cooldownOption = await _db.UserValues.FindOrCreateOption(Chat.Id, From.Id, "guessCooldown");
cooldownOption.SetValue(nextUse);
_db.AddOrUpdate(cooldownOption);
}
}
@@ -0,0 +1,9 @@
using Telegram.Bot.Types;
namespace West.Entertainment.Handler;
public class GuessData
{
public long UserId { get; set; }
public int Number { get; set; }
}