Esempio n. 1
0
        /// <summary>Updates the state.</summary>
        public State Update(Serialization.Game game)
        {
            var state = new State()
            {
                hero1     = Hero.Create(game.heroes[0]),
                hero2     = Hero.Create(game.heroes[1]),
                hero3     = Hero.Create(game.heroes[2]),
                hero4     = Hero.Create(game.heroes[3]),
                ownership = ownership.UpdateFromTiles(game.board.tiles),
            };

            state.hash = GetHash(game.turn, state.hero1, state.hero2, state.hero3, state.hero4);
            return(state);
        }
Esempio n. 2
0
        /// <summary>The hero moves.</summary>
        /// <remarks>
        /// If the hero:
        ///
        /// * Tries to step out of the map, or over a tree, nothing happens.
        ///
        /// * Steps into a gold mine, he stays in place, and:
        ///	  - If the mine already belongs to the hero, nothing happens.
        ///   - If the mine is neutral, or belongs to another hero, a fight
        ///     happens against the goblin guarding the mine. The hero loses
        ///     20 life points. If he survives, the mine is his.
        ///
        /// * Steps into another hero, he stays in place and nothing happens.
        ///   Hero fights are resolved at the end of the turn.
        ///
        /// * Steps into a tavern, he stays in place and orders a beer. The hero
        ///   pays 2 gold and receive 50HP. Note than HP can never exceed 100.
        ///
        /// * Times out, i.e. fails to send an order in the given delay (1 second),
        ///   he stays in place until the game is finished. Note that he can
        ///   still win if he as more gold than the other players at the end
        ///   of the game.
        ///
        ///
        /// After the hero has moved, a few things happen:
        ///
        /// ::Fights
        /// Heroes are quite nervous and never miss an opportunity to slap each
        /// others with their big blades. After the hero has moved, if there is
        /// an enemy at a distance of one square in any direction, the hero
        /// attacks the enemy. For instance, in this situation,
        /// after Hero 1 (@1) has moved:
        ///
        /// @1@2
        ///   @3
        ///
        /// @1 attacks @2. @1 does not attack @3 because it's 2 moves away.
        /// The attacking hero doesn't lose any life point, the defending one
        /// loses 20 life points.
        /// If the defender dies (see: Death of a hero), the attacking hero
        /// obtains control of all the loser's gold mines.
        ///
        /// ::Mining
        /// After the hero has moved, he gains one gold per controlled mine.
        ///
        /// ::Thirst
        ///
        /// After the hero has moved, he loses one HP (because all this action made him thirsty).
        /// Note that heroes don't die of thirst. Worse case, they fall to 1 HP.
        /// </remarks>
        public State Move(Map map, Hero hero, PlayerType player, Tile source, Tile target)
        {
            unchecked
            {
#if DEBUG
                var test = GetHero(player);
                if (hero != test)
                {
                    throw new Exception("Invalid hero.");
                }
#endif
                var state = new State()
                {
                    hero1     = hero1,
                    hero2     = hero2,
                    hero3     = hero3,
                    hero4     = hero4,
                    ownership = ownership,
                };

                var health = hero.Health;
                int mines  = hero.Mines;
                int gold   = hero.Gold;

                // Try to get a mine.
                if (target.MineIndex > -1)
                {
                    var ownerPlayer = state.ownership[target.MineIndex];

                    // Try to get the mine.
                    if (ownerPlayer != player)
                    {
                        health = health.Slammed();

                        if (health.IsAlive)
                        {
                            mines++;
                            state.ownership = state.ownership.Set(target.MineIndex, player);

                            if (ownerPlayer != PlayerType.None)
                            {
                                var ownerHero = state.GetHero(ownerPlayer);
                                ownerHero = ownerHero.LoseMine(ownerHero.Mines);
                                state.SetHero(ownerPlayer, ownerHero);
                            }
                        }
                    }
                    target = source;
                }
                // Drink a beer.
                else if (target.TileType == TileType.Tavern)
                {
                    target = source;

                    if (gold >= Hero.CostsTavern)
                    {
                        gold  -= Hero.CostsTavern;
                        health = health.Drink();
                    }
                }
                // move or combat.
                else
                {
                    var occupied = state.GetOccupied(target, player);

                    if (occupied != PlayerType.None)
                    {
                        target = source;
                    }
                }
                // died trying to get a mine.
                if (health.IsDead)
                {
                    state.ownership = state.ownership.ChangeOwnership(player, PlayerType.None, map.Mines.Length);
                    hero            = Hero.Respawn(map.GetSpawn(player), gold);
                }
                // try to battle.
                else
                {
                    foreach (var other_player in PlayerTypes.Other[player])
                    {
                        var other_hero = state.GetHero(other_player);
                        var other_tile = map[other_hero];

                        foreach (var neighbor_tile in other_tile.Neighbors)
                        {
                            if (neighbor_tile == target)
                            {
                                var other_health = other_hero.Health.Slammed();
                                if (other_health.IsDead)
                                {
                                    var other_gold = other_hero.Gold;
                                    mines += other_hero.Mines;
                                    state.SetHero(other_player, Hero.Respawn(map.GetSpawn(other_player), other_gold));

                                    if (map.Mines.Length > 28)
                                    {
                                    }
                                    state.ownership = state.ownership.ChangeOwnership(other_player, player, map.Mines.Length);
                                }
                                else
                                {
                                    state.SetHero(other_player, other_hero.SetHealth(other_health));
                                }
                                break;
                            }
                        }
                    }
                    gold  += mines;
                    health = health.Step();
                    hero   = Hero.Create(health, target, mines, gold);
                }

                state.SetHero(player, hero);

#if DEBUG
                if (state.hero1.Mines != state.Mines.Count(PlayerType.Hero1) ||
                    state.hero2.Mines != state.Mines.Count(PlayerType.Hero2) ||
                    state.hero3.Mines != state.Mines.Count(PlayerType.Hero3) ||
                    state.hero4.Mines != state.Mines.Count(PlayerType.Hero4))
                {
                    throw new Exception("Invalid state");
                }
#endif
                state.hash = GetHash(this.Turn + 1, state.hero1, state.hero2, state.hero3, state.hero4);
                return(state);
            }
        }
Esempio n. 3
0
        /// <summary>The hero moves.</summary>
        /// <remarks>
        /// If the hero:
        ///
        /// * Tries to step out of the map, or over a tree, nothing happens.
        ///
        /// * Steps into a gold mine, he stays in place, and:
        ///	  - If the mine already belongs to the hero, nothing happens.
        ///   - If the mine is neutral, or belongs to another hero, a fight
        ///     happens against the goblin guarding the mine. The hero loses
        ///     20 life points. If he survives, the mine is his.
        ///
        /// * Steps into another hero, he stays in place and nothing happens.
        ///   Hero fights are resolved at the end of the turn.
        ///
        /// * Steps into a tavern, he stays in place and orders a beer. The hero
        ///   pays 2 gold and receive 50HP. Note than HP can never exceed 100.
        ///
        /// * Times out, i.e. fails to send an order in the given delay (1 second),
        ///   he stays in place until the game is finished. Note that he can
        ///   still win if he as more gold than the other players at the end
        ///   of the game.
        ///
        ///
        /// After the hero has moved, a few things happen:
        ///
        /// ::Fights
        /// Heroes are quite nervous and never miss an opportunity to slap each
        /// others with their big blades. After the hero has moved, if there is
        /// an enemy at a distance of one square in any direction, the hero
        /// attacks the nemy. For instance, in this situation,
        /// after Hero 1 (@1) has moved:
        ///
        /// @1@2
        ///   @3
        ///
        /// @1 attacks @2. @1 does not attack @3 because it's 2 moves away.
        /// The attacking hero doesn't lose any life point, the defending one
        /// loses 20 life points.
        /// If the defender dies (see: Death of a hero), the attacking hero
        /// obtains control of all the loser's gold mines.
        ///
        /// ::Mining
        /// After the hero has moved, he gains one gold per controlled mine.
        ///
        /// ::Thirst
        ///
        /// After the hero has moved, he loses one HP (because all this action made him thirsty).
        /// Note that heroes don't die of thirst. Worse case, they fall to 1 HP.
        /// </remarks>
        public State Move(Map map, Hero hero, PlayerType player, Tile source, Tile target)
        {
            unchecked
            {
                var state = new State()
                {
                    turn   = (ushort)(turn + 1),
                    hero1  = hero1,
                    hero2  = hero2,
                    hero3  = hero3,
                    hero4  = hero4,
                    mines0 = mines0,
                    mines1 = mines1,
                };

                int health = hero.Health;
                int mines  = hero.Mines;
                int gold   = hero.Gold;

                // Try to get a mine.
                if (target.MineIndex > -1)
                {
                    var ownerPlayer = state.GetMine(target.MineIndex);

                    // Try to get the mine.
                    if (ownerPlayer != player)
                    {
                        health = Math.Max(Hero.HealthMin, health - Hero.HealthBattle);

                        if (health > Hero.HealthMin)
                        {
                            mines++;
                            state.SetMine(target.MineIndex, player);

                            if (ownerPlayer != PlayerType.None)
                            {
                                var ownerHero = state.GetHero(ownerPlayer);
                                ownerHero = ownerHero.LoseMine(ownerHero.Mines);
                                state.SetHero(ownerPlayer, ownerHero);
                            }
                        }
                    }
                    target = source;
                }
                // Drink a beer.
                else if (target.TileType == TileType.Taverne)
                {
                    target = source;

                    if (gold >= Hero.CostsTavern)
                    {
                        gold  -= Hero.CostsTavern;
                        health = Math.Min(health + Hero.HealthTavern, Hero.HealthMax);
                    }
                }
                // move or combat.
                else
                {
                    var occupied = state.GetOccupied(target, player);

                    if (occupied != PlayerType.None)
                    {
                        target = source;
                    }
                }
                // died trying to get a mine.
                if (health == Hero.HealthMin)
                {
                    hero = Hero.Respawn(map.GetSpawn(player), gold);
                }
                // try to battle.
                else
                {
                    foreach (var other_player in PlayerTypes.Other[player])
                    {
                        var other_hero = state.GetHero(other_player);
                        var other_tile = map[other_hero];

                        foreach (var neighbor_tile in other_tile.Neighbors)
                        {
                            if (neighbor_tile == target)
                            {
                                var other_health = other_hero.Health;
                                if (other_health <= Hero.HealthBattle)
                                {
                                    var other_gold = other_hero.Gold;
                                    mines += other_hero.Mines;
                                    state.SetHero(other_player, Hero.Respawn(map.GetSpawn(other_player), other_gold));
                                    state.SetMines(map, other_gold, other_player, player);
                                }
                                break;
                            }
                        }
                    }
                    gold  += mines;
                    health = Math.Max(Hero.HealthThirst, health - Hero.HealthThirst);
                    hero   = Hero.Create(health, target, mines, gold);
                }

                state.SetHero(player, hero);

                return(state);
            }
        }