Ejemplo n.º 1
0
        public async Task <CommandResult> Bet(CommandContext context)
        {
            if (context.Message.MessageSource != MessageSource.Chat)
            {
                return new CommandResult {
                           Response = "you may only bet through chat"
                }
            }
            ;
            IBettingPeriod <User>?bettingPeriod = _bettingPeriodProvider();

            if (bettingPeriod == null)
            {
                return new CommandResult {
                           Response = "betting not available right now"
                }
            }
            ;
            if (!bettingPeriod.IsBettingOpen)
            {
                return new CommandResult {
                           Response = "betting is already closed"
                }
            }
            ;
            (var amountOptions, Side side) = await context.ParseArgs <OneOf <PositiveInt, Pokeyen, Percentage>, Side>();

            int amount;

            if (amountOptions.Item1.IsPresent)
            {
                amount = amountOptions.Item1.Value;
            }
            else if (amountOptions.Item2.IsPresent)
            {
                amount = amountOptions.Item2.Value;
            }
            else
            {
                amount = (int)Math.Ceiling(amountOptions.Item3.Value.AsDecimal * context.Message.User.Pokeyen);
            }

            PlaceBetFailure?failure = await bettingPeriod.BettingShop.PlaceBet(context.Message.User, side, amount);

            if (failure != null)
            {
                return(new CommandResult
                {
                    Response = failure switch
                    {
                        PlaceBetFailure.BetTooHigh betTooHigh =>
                        $"must bet at most {betTooHigh.MaxBet}",
                        PlaceBetFailure.BetTooLow betTooLow =>
                        $"must bet at least {betTooLow.MinBet}",
                        PlaceBetFailure.CannotChangeSide cannotChangeSide =>
                        $"already bet on {cannotChangeSide.SideBetOn}",
                        PlaceBetFailure.CannotLowerBet cannotLowerBet =>
                        $"cannot lower existing bet of {cannotLowerBet.ExistingBet}",
                        PlaceBetFailure.InsufficientFunds insufficientFunds =>
                        $"insufficient funds, you only have {insufficientFunds.AvailableMoney} pokeyen available",
                        _ => $"{failure} (missing text, tell the devs to fix this)"
                    }
                });
Ejemplo n.º 2
0
        private async Task Loop(CancellationToken cancellationToken)
        {
            var teams = new Teams
            {
                Blue = ImmutableList.Create(MatchTesting.TestVenonatForOverlay),
                Red = ImmutableList.Create(MatchTesting.TestVenonatForOverlay),
            };
            await Task.Delay(TimeSpan.FromSeconds(3), cancellationToken);

            await ResetBalances(); //ensure everyone has money to bet before the betting period
            const int matchId = -1; // TODO
            IBettingShop<User> bettingShop = new DefaultBettingShop<User>(
                async user => await _pokeyenBank.GetAvailableMoney(user));
            bettingShop.BetPlaced += (_, args) => TaskToVoidSafely(_logger, () =>
                _overlayConnection.Send(new MatchPokeyenBetUpdateEvent
                {
                    MatchId = matchId,
                    DefaultAction = "",
                    NewBet = new Bet { Amount = args.Amount, Team = args.Side, BetBonus = 0 },
                    NewBetUser = args.User,
                    Odds = bettingShop.GetOdds()
                }, cancellationToken));
            _bettingPeriod = new BettingPeriod<User>(_pokeyenBank, bettingShop);
            _bettingPeriod.Start();

            IMatchCycle match = new CoinflipMatchCycle(_loggerFactory.CreateLogger<CoinflipMatchCycle>());
            Task setupTask = match.SetUp(new MatchInfo(teams.Blue, teams.Red), cancellationToken);
            await _overlayConnection.Send(new MatchCreatedEvent(), cancellationToken);
            await _overlayConnection.Send(new MatchBettingEvent(), cancellationToken);
            await _overlayConnection.Send(new MatchModesChosenEvent(), cancellationToken); // TODO
            await _overlayConnection.Send(new MatchSettingUpEvent
            {
                MatchId = 1234,
                Teams = teams,
                BettingDuration = _matchmodeConfig.DefaultBettingDuration.TotalSeconds,
                RevealDuration = 0,
                Gimmick = "speed",
                Switching = SwitchingPolicy.Never,
                BattleStyle = BattleStyle.Singles,
                InputOptions = new InputOptions
                {
                    Moves = new MovesInputOptions
                    {
                        Policy = MoveSelectingPolicy.Always,
                        Permitted = ImmutableList.Create("a", "b", "c", "d")
                    },
                    Switches = new SwitchesInputOptions
                    {
                        Policy = SwitchingPolicy.Never,
                        Permitted = ImmutableList<string>.Empty,
                        RandomChance = 0
                    },
                    Targets = new TargetsInputOptions
                    {
                        Policy = TargetingPolicy.Disabled,
                        Permitted = ImmutableList<string>.Empty,
                        AllyHitChance = 0
                    },
                },
                BetBonus = 35,
                BetBonusType = "bet",
            }, cancellationToken);

            Duration bettingBeforeWarning = _matchmodeConfig.DefaultBettingDuration - _matchmodeConfig.WarningDuration;
            await Task.Delay(bettingBeforeWarning.ToTimeSpan(), cancellationToken);
            await _overlayConnection.Send(new MatchWarningEvent(), cancellationToken);

            await Task.Delay(_matchmodeConfig.WarningDuration.ToTimeSpan(), cancellationToken);
            await setupTask;
            _bettingPeriod.Close();
            Task<MatchResult> performTask = match.Perform(cancellationToken);
            await _overlayConnection.Send(new MatchPerformingEvent { Teams = teams }, cancellationToken);

            MatchResult result = await performTask;
            await _overlayConnection.Send(new MatchOverEvent { MatchResult = result }, cancellationToken);

            // TODO log matches
            Dictionary<User, long> changes = await _bettingPeriod.Resolve(matchId, result, cancellationToken);
            await _overlayConnection.Send(
                new MatchResultsEvent
                {
                    PokeyenResults = new PokeyenResults
                    {
                        Transactions = changes.ToImmutableDictionary(kvp => kvp.Key.Id,
                            kvp => new Transaction { Change = kvp.Value, NewBalance = kvp.Key.Pokeyen })
                    }
                }, cancellationToken);

            await Task.Delay(_matchmodeConfig.ResultDuration.ToTimeSpan(), cancellationToken);
            await _overlayConnection.Send(new ResultsFinishedEvent(), cancellationToken);
        }