Пример #1
0
        public void Basic_Actions()
        {
            #region Setup
            PBERandom.SetSeed(0);
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(2);
            p0[0] = new TestPokemon(settings, PBESpecies.Koffing, 0, 100, PBEMove.Selfdestruct);
            p0[1] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Darkrai, 0, 100, PBEMove.Protect);

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;
            battle.Begin();

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon koffing  = t0.Party[0];
            PBEBattlePokemon magikarp = t0.Party[1];
            PBEBattlePokemon darkrai  = t1.Party[0];
            #endregion

            #region Darkrai uses Protect, Koffing uses Selfdestruct and faints
            var a = new PBETurnAction(koffing, PBEMove.Selfdestruct, PBETurnTarget.FoeCenter);
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(null, a));                                   // Throw for null team
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(t0, (IReadOnlyList <PBETurnAction>)null));   // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(t0, new PBETurnAction[] { null }));          // Throw for null elements
            Assert.False(PBEBattle.SelectActionsIfValid(t0, a, a));                                                                 // False for too many actions
            Assert.True(PBEBattle.SelectActionsIfValid(t0, a));                                                                     // True for good actions
                                                                                                                                    // TODO: bad field position to switch into, bad move, bad targets, bad targets with templockedmove, battle status, bad pkmn id, wrong team pkmn id, duplicate pkmn id, can't switch out but tried, invalid switch mon (null hp pos), duplicate switch mon
            Assert.False(PBEBattle.SelectActionsIfValid(t0, a));                                                                    // False because actions were already submitted
            Assert.False(PBEBattle.SelectActionsIfValid(t0, Array.Empty <PBETurnAction>()));                                        // False for 0 despite us now needing 0 additional actions

            Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(darkrai, PBEMove.Protect, PBETurnTarget.AllyCenter))); // True for good actions

            battle.RunTurn();
            #endregion

            #region More checks
            var s = new PBESwitchIn(magikarp, PBEFieldPosition.Center);
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(null, s));                               // Throw for null team
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(t0, (IReadOnlyList <PBESwitchIn>)null)); // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(t0, new PBESwitchIn[] { null }));        // Throw for null elements
            Assert.False(PBEBattle.SelectSwitchesIfValid(t0, s, s));                                                             // False for too many
            Assert.True(PBEBattle.SelectSwitchesIfValid(t0, s));                                                                 // True for good switches

            // Below two wouldn't work because of battle status lol
            //Assert.False(PBEBattle.SelectSwitchesIfValid(t0, s)); // False because switches were already submitted
            //Assert.False(PBEBattle.SelectSwitchesIfValid(t0, Array.Empty<PBESwitchIn>())); // False for 0 despite us now needing 0 additional actions

            //battle.RunSwitches();
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
Пример #2
0
 public void Push(PBEBattlePokemon pkmn, PBEFieldPosition pos)
 {
     _switches[_index]        = new PBESwitchIn(pkmn, pos);
     _standBy[_index]         = pkmn;
     _positionStandBy[_index] = pos;
     _index++;
     SwitchesLoop();
 }
Пример #3
0
        public void Basic_Actions()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(2);
            p0[0] = new TestPokemon(settings, PBESpecies.Koffing, 0, 100, PBEMove.Selfdestruct);
            p0[1] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Darkrai, 0, 100, PBEMove.Protect);

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon koffing  = t0.Party[0];
            PBEBattlePokemon magikarp = t0.Party[1];
            PBEBattlePokemon darkrai  = t1.Party[0];

            battle.Begin();
            #endregion

            #region Darkrai uses Protect, Koffing uses Selfdestruct and faints
            var a = new PBETurnAction(koffing, PBEMove.Selfdestruct, PBETurnTarget.FoeCenter);
            Assert.Throws <ArgumentNullException>(() => t0.SelectActionsIfValid((IReadOnlyList <PBETurnAction>)null));   // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => t0.SelectActionsIfValid(new PBETurnAction[] { null }));          // Throw for null elements
            Assert.NotNull(t0.SelectActionsIfValid(a, a));                                                               // Too many actions
            Assert.Null(t0.SelectActionsIfValid(a));                                                                     // Good actions
            Assert.NotNull(t0.SelectActionsIfValid(a));                                                                  // Actions were already submitted
            Assert.NotNull(t0.SelectActionsIfValid(Array.Empty <PBETurnAction>()));                                      // 0 despite us now needing 0 additional actions

            Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(darkrai, PBEMove.Protect, PBETurnTarget.AllyCenter))); // True for good actions

            battle.RunTurn();
            #endregion

            #region More checks
            var s = new PBESwitchIn(magikarp, PBEFieldPosition.Center);
            Assert.Throws <ArgumentNullException>(() => t0.SelectSwitchesIfValid((IReadOnlyList <PBESwitchIn>)null)); // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => t0.SelectSwitchesIfValid(new PBESwitchIn[] { null }));        // Throw for null elements
            Assert.NotNull(t0.SelectSwitchesIfValid(s, s));                                                           // Too many
            Assert.Null(t0.SelectSwitchesIfValid(s));                                                                 // Good switches

            // Below two wouldn't work because of battle status lol
            //Assert.NotNull(t0.SelectSwitchesIfValid(s)); // Switches were already submitted
            //Assert.NotNull(t0.SelectSwitchesIfValid(Array.Empty<PBESwitchIn>())); // 0 despite us now needing 0 additional switches

            //battle.RunSwitches();
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
Пример #4
0
        internal PBESwitchInResponsePacket(byte[] data, EndianBinaryReader r)
        {
            Data = new ReadOnlyCollection <byte>(data);
            var switches = new PBESwitchIn[r.ReadByte()];

            for (int i = 0; i < switches.Length; i++)
            {
                switches[i] = new PBESwitchIn(r);
            }
            Switches = new ReadOnlyCollection <PBESwitchIn>(switches);
        }
        internal PBESwitchInResponsePacket(ReadOnlyCollection <byte> buffer, BinaryReader r, PBEBattle battle)
        {
            Buffer = buffer;
            var switches = new PBESwitchIn[r.ReadByte()];

            for (int i = 0; i < switches.Length; i++)
            {
                switches[i] = new PBESwitchIn(r);
            }
            Switches = new ReadOnlyCollection <PBESwitchIn>(switches);
        }
Пример #6
0
        /// <summary>Creates valid switches for a battle for a specific team.</summary>
        /// <param name="team">The team to create switches for.</param>
        /// <exception cref="InvalidOperationException">Thrown when <paramref name="team"/> does not require switch-ins or <paramref name="team"/>'s <see cref="PBETeam.Battle"/>'s <see cref="PBEBattle.BattleState"/> is not <see cref="PBEBattleState.WaitingForActions"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="team"/>'s <see cref="PBETeam.Battle"/>'s <see cref="PBEBattle.BattleFormat"/> is invalid.</exception>
        public static PBESwitchIn[] CreateSwitches(PBETeam team)
        {
            if (team == null)
            {
                throw new ArgumentNullException(nameof(team));
            }
            if (team.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(team));
            }
            if (team.Battle.BattleState != PBEBattleState.WaitingForSwitchIns)
            {
                throw new InvalidOperationException($"{nameof(team.Battle.BattleState)} must be {PBEBattleState.WaitingForSwitchIns} to create switch-ins.");
            }
            if (team.SwitchInsRequired == 0)
            {
                throw new InvalidOperationException($"{nameof(team)} must require switch-ins.");
            }
            PBEPokemon[] available = team.Party.Where(p => p.FieldPosition == PBEFieldPosition.None && p.HP > 0).ToArray();
            available.Shuffle();
            var availablePositions = new List <PBEFieldPosition>();

            switch (team.Battle.BattleFormat)
            {
            case PBEBattleFormat.Single:
            {
                availablePositions.Add(PBEFieldPosition.Center);
                break;
            }

            case PBEBattleFormat.Double:
            {
                if (team.TryGetPokemon(PBEFieldPosition.Left) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Left);
                }
                if (team.TryGetPokemon(PBEFieldPosition.Right) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Right);
                }
                break;
            }

            case PBEBattleFormat.Triple:
            case PBEBattleFormat.Rotation:
            {
                if (team.TryGetPokemon(PBEFieldPosition.Left) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Left);
                }
                if (team.TryGetPokemon(PBEFieldPosition.Center) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Center);
                }
                if (team.TryGetPokemon(PBEFieldPosition.Right) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Right);
                }
                break;
            }

            default: throw new ArgumentOutOfRangeException(nameof(team.Battle.BattleFormat));
            }
            var switches = new PBESwitchIn[team.SwitchInsRequired];

            for (int i = 0; i < team.SwitchInsRequired; i++)
            {
                switches[i] = new PBESwitchIn(available[i].Id, availablePositions[i]);
            }
            return(switches);
        }
Пример #7
0
        /// <summary>Creates valid switches for a battle for a specific team.</summary>
        /// <exception cref="InvalidOperationException">Thrown when <see name="Trainer"/> does not require switch-ins or <see name="Trainer"/>'s <see cref="PBETrainer.Battle"/>'s <see cref="PBEBattle.BattleState"/> is not <see cref="PBEBattleState.WaitingForActions"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when <see name="Trainer"/>'s <see cref="PBETrainer.Battle"/>'s <see cref="PBEBattle.BattleFormat"/> is invalid.</exception>
        public void CreateSwitches()
        {
            if (Trainer.Battle.BattleState != PBEBattleState.WaitingForSwitchIns)
            {
                throw new InvalidOperationException($"{nameof(Trainer.Battle.BattleState)} must be {PBEBattleState.WaitingForSwitchIns} to create switch-ins.");
            }
            if (Trainer.SwitchInsRequired == 0)
            {
                throw new InvalidOperationException($"{nameof(Trainer)} must require switch-ins.");
            }
            List <PBEBattlePokemon> available = Trainer.Party.FindAll(p => p.FieldPosition == PBEFieldPosition.None && p.CanBattle);

            PBEDataProvider.GlobalRandom.Shuffle(available);
            var availablePositions = new List <PBEFieldPosition>();

            switch (Trainer.Battle.BattleFormat)
            {
            case PBEBattleFormat.Single:
            {
                availablePositions.Add(PBEFieldPosition.Center);
                break;
            }

            case PBEBattleFormat.Double:
            {
                if (Trainer.OwnsSpot(PBEFieldPosition.Left) && !Trainer.IsSpotOccupied(PBEFieldPosition.Left))
                {
                    availablePositions.Add(PBEFieldPosition.Left);
                }
                if (Trainer.OwnsSpot(PBEFieldPosition.Right) && !Trainer.IsSpotOccupied(PBEFieldPosition.Right))
                {
                    availablePositions.Add(PBEFieldPosition.Right);
                }
                break;
            }

            case PBEBattleFormat.Triple:
            case PBEBattleFormat.Rotation:
            {
                if (Trainer.OwnsSpot(PBEFieldPosition.Left) && !Trainer.IsSpotOccupied(PBEFieldPosition.Left))
                {
                    availablePositions.Add(PBEFieldPosition.Left);
                }
                if (Trainer.OwnsSpot(PBEFieldPosition.Center) && !Trainer.IsSpotOccupied(PBEFieldPosition.Center))
                {
                    availablePositions.Add(PBEFieldPosition.Center);
                }
                if (Trainer.OwnsSpot(PBEFieldPosition.Right) && !Trainer.IsSpotOccupied(PBEFieldPosition.Right))
                {
                    availablePositions.Add(PBEFieldPosition.Right);
                }
                break;
            }

            default: throw new InvalidOperationException(nameof(Trainer.Battle.BattleFormat));
            }
            var switches = new PBESwitchIn[Trainer.SwitchInsRequired];

            for (int i = 0; i < Trainer.SwitchInsRequired; i++)
            {
                switches[i] = new PBESwitchIn(available[i], availablePositions[i]);
            }
            if (!Trainer.SelectSwitchesIfValid(out string?valid, switches))
            {
                throw new Exception("AI created bad switches. - " + valid);
            }
        }
Пример #8
0
        /// <summary>Creates valid switches for a battle for a specific team.</summary>
        /// <param name="trainer">The trainer to create switches for.</param>
        /// <exception cref="InvalidOperationException">Thrown when <paramref name="trainer"/> does not require switch-ins or <paramref name="trainer"/>'s <see cref="PBETrainer.Battle"/>'s <see cref="PBEBattle.BattleState"/> is not <see cref="PBEBattleState.WaitingForActions"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="trainer"/>'s <see cref="PBETrainer.Battle"/>'s <see cref="PBEBattle.BattleFormat"/> is invalid.</exception>
        public static void CreateAISwitches(this PBETrainer trainer)
        {
            if (trainer == null)
            {
                throw new ArgumentNullException(nameof(trainer));
            }
            if (trainer.Battle.BattleState != PBEBattleState.WaitingForSwitchIns)
            {
                throw new InvalidOperationException($"{nameof(trainer.Battle.BattleState)} must be {PBEBattleState.WaitingForSwitchIns} to create switch-ins.");
            }
            if (trainer.SwitchInsRequired == 0)
            {
                throw new InvalidOperationException($"{nameof(trainer)} must require switch-ins.");
            }
            PBEBattlePokemon[] available = trainer.Party.Where(p => p.FieldPosition == PBEFieldPosition.None && p.HP > 0).ToArray();
            PBEDataProvider.GlobalRandom.Shuffle(available);
            var availablePositions = new List <PBEFieldPosition>();

            switch (trainer.Battle.BattleFormat)
            {
            case PBEBattleFormat.Single:
            {
                availablePositions.Add(PBEFieldPosition.Center);
                break;
            }

            case PBEBattleFormat.Double:
            {
                if (trainer.OwnsSpot(PBEFieldPosition.Left) && trainer.TryGetPokemon(PBEFieldPosition.Left) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Left);
                }
                if (trainer.OwnsSpot(PBEFieldPosition.Right) && trainer.TryGetPokemon(PBEFieldPosition.Right) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Right);
                }
                break;
            }

            case PBEBattleFormat.Triple:
            case PBEBattleFormat.Rotation:
            {
                if (trainer.OwnsSpot(PBEFieldPosition.Left) && trainer.TryGetPokemon(PBEFieldPosition.Left) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Left);
                }
                if (trainer.OwnsSpot(PBEFieldPosition.Center) && trainer.TryGetPokemon(PBEFieldPosition.Center) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Center);
                }
                if (trainer.OwnsSpot(PBEFieldPosition.Right) && trainer.TryGetPokemon(PBEFieldPosition.Right) == null)
                {
                    availablePositions.Add(PBEFieldPosition.Right);
                }
                break;
            }

            default: throw new ArgumentOutOfRangeException(nameof(trainer.Battle.BattleFormat));
            }
            var switches = new PBESwitchIn[trainer.SwitchInsRequired];

            for (int i = 0; i < trainer.SwitchInsRequired; i++)
            {
                switches[i] = new PBESwitchIn(available[i], availablePositions[i]);
            }
            string valid = trainer.SelectSwitchesIfValid(switches);

            if (valid != null)
            {
                throw new Exception("AI created bad switches. - " + valid);
            }
        }
Пример #9
0
        public void Basic_Actions_Checks()
        {
            PBEUtils.CreateDatabaseConnection(string.Empty);
            PBESettings settings = PBESettings.DefaultSettings;

            var             team1Shell = new PBETeamShell(settings, 2, true);
            PBEPokemonShell p          = team1Shell[0];

            p.Species         = PBESpecies.Koffing;
            p.Item            = PBEItem.None;
            p.Moveset[0].Move = PBEMove.Selfdestruct;

            var team2Shell = new PBETeamShell(settings, 1, true);

            p                 = team2Shell[0];
            p.Species         = PBESpecies.Darkrai;
            p.Item            = PBEItem.None;
            p.Moveset[0].Move = PBEMove.Protect;

            var battle = new PBEBattle(PBEBattleFormat.Single, team1Shell, "Team 1", team2Shell, "Team 2");

            team1Shell.Dispose();
            team2Shell.Dispose();
            battle.Begin();

            PBETeam t  = battle.Teams[0];
            var     a  = new PBETurnAction(t.Party[0].Id, PBEMove.Selfdestruct, PBETurnTarget.FoeCenter);
            var     a1 = new PBETurnAction[] { a };

            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(null, a1));                        // Throw for null team
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(t, null));                         // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(t, new PBETurnAction[] { null })); // Throw for null elements
            Assert.False(PBEBattle.SelectActionsIfValid(t, new PBETurnAction[] { a, a }));                                // False for too many actions
            Assert.True(PBEBattle.SelectActionsIfValid(t, a1));                                                           // True for good actions
            // TODO: bad move, bad targets, bad targets with templockedmove, battle status, bad pkmn id, wrong team pkmn id, duplicate pkmn id, can't switch out but tried, invalid switch mon (null hp pos), duplicate switch mon
            Assert.False(PBEBattle.SelectActionsIfValid(t, a1));                                                          // False because actions were already submitted
            Assert.False(PBEBattle.SelectActionsIfValid(t, Array.Empty <PBETurnAction>()));                               // False for 0 despite us now needing 0 additional actions

            t = battle.Teams[1];
            Assert.True(PBEBattle.SelectActionsIfValid(t, new PBETurnAction[] { new PBETurnAction(t.Party[0].Id, PBEMove.Protect, PBETurnTarget.AllyCenter) })); // True for good actions

            battle.RunTurn();                                                                                                                                    // Darkrai uses Protect, Koffing uses Selfdestruct, Koffing faints

            t = battle.Teams[0];
            var s  = new PBESwitchIn(t.Party[1].Id, PBEFieldPosition.Center);
            var s1 = new PBESwitchIn[] { s };

            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(null, s1));                      // Throw for null team
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(t, null));                       // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(t, new PBESwitchIn[] { null })); // Throw for null elements
            Assert.False(PBEBattle.SelectSwitchesIfValid(t, new PBESwitchIn[] { s, s }));                                // False for too many
            Assert.True(PBEBattle.SelectSwitchesIfValid(t, s1));                                                         // True for good switches
            // Below two wouldn't work because of battle status lol
            //Assert.False(PBEBattle.SelectSwitchesIfValid(t, s1)); // False because switches were already submitted
            //Assert.False(PBEBattle.SelectSwitchesIfValid(t, Array.Empty<PBESwitchIn>())); // False for 0 despite us now needing 0 additional actions

            battle.Dispose();

            Assert.Throws <ObjectDisposedException>(() => PBEBattle.SelectActionsIfValid(t, a1));  // Throw for disposed battle
            Assert.Throws <ObjectDisposedException>(() => PBEBattle.SelectSwitchesIfValid(t, s1)); // Throw for disposed battle
        }