Beispiel #1
0
        /// <summary>
        /// Causes a player to join a battle immediately.
        /// </summary>
        /// <param name="session">Session of the player.</param>
        public async Task <BattleResult?> InvokeBattle(Session session)
        {
            // WaitHandle would probably have been very useful here...

            if (await GetPlayer(session) is not Player player)
            {
                return(null);
            }

            if (player.Deck.Count != 4)
            {
                return(null);
            }

            // only two taks may run simultaneously
            await _invokeBattleLimiter.WaitAsync().ConfigureAwait(false);

            // restrict to serialized execution
            await _invokeBattleExclusive.WaitAsync();

            BattleResult result;

            if (_firstBattlingPlayer is null) // first player connects
            {
                _firstBattlingPlayer = player;
                _invokeBattleExclusive.Release();    // second player may now join
                System.Diagnostics.Debug.Assert(_invokeBattleHang.CurrentCount == 0);
                await _invokeBattleHang.WaitAsync(); // wait until unlocked by second player

                // invoked after second player finished
                var resultCopy = _btlResult;
                _firstBattlingPlayer = null;
                _btlResult           = null;

                // let others continue
                _invokeBattleExclusive.Release();
                _invokeBattleLimiter.Release(2);

                // finish first player
                return(resultCopy);
            }

            // cancel battle if against yourself
            if (_firstBattlingPlayer.Id == player.Id)
            {
                result = _btlResult = new BattleResult.Cancelled("The player started a battle against themself.");
                _invokeBattleHang.Release();
                return(result);
            }

            System.Diagnostics.Debug.Assert(_invokeBattleExclusive.CurrentCount == 0);
            // finish second player
            result = _btlResult = _btl.RunBattle(player, _firstBattlingPlayer);

            // let other player's task continue
            _invokeBattleHang.Release();
            return(result);
        }
Beispiel #2
0
        public void TestWinner()
        {
            ICard[] // decks limited to one card to avoid possible infinite loops
            cards1 = { new NormalSpell {
                           Damage = 10
                       } },
            cards2 = { new NormalSpell {
                           Damage = 1
                       } };

            Player
                player1 = new Player(Guid.Empty, "Player 1", Array.Empty <byte>(), String.Empty, String.Empty, 0, Array.Empty <ICard>(), cards1, 1000, 0, 0),
                player2 = new Player(Guid.Empty, "Player 2", Array.Empty <byte>(), String.Empty, String.Empty, 0, Array.Empty <ICard>(), cards2, 1000, 0, 0);

            var result = _handler.RunBattle(player1, player2);

            Assert.NotNull(result);
            Assert.IsInstanceOf <BattleResult.Winner>(result);
            var win = (BattleResult.Winner)result;

            Assert.AreEqual(player1, win.WinningPlayer);
            Assert.AreEqual(player2, win.LosingPlayer);
        }