Пример #1
0
            public static MoveResolver Deny()
            {
                var block = new MoveResolver(null);

                block.Resolved = false;
                return(block);
            }
Пример #2
0
 private void SetRoot(MoveResolver root)
 {
     if (root == _root)
     {
         throw new Exception("I think this implies an unresolved cycle");
     }
     _root = root;
     foreach (var dependent in _dependents)
     {
         dependent.SetRoot(root);
     }
 }
Пример #3
0
 public BattleController()
 {
     _playerBattleSquads    = new Dictionary <int, BattleSquad>();
     _opposingBattleSquads  = new Dictionary <int, BattleSquad>();;
     _soldierBattleSquadMap = new Dictionary <int, BattleSquad>();
     _moveResolver          = new MoveResolver();
     _moveResolver.OnRetreat.AddListener(MoveResolver_OnRetreat);
     _woundResolver = new WoundResolver(VERBOSE);
     _woundResolver.OnSoldierDeath.AddListener(WoundResolver_OnSoldierDeath);
     _woundResolver.OnSoldierFall.AddListener(WoundResolver_OnSoldierFall);
     _casualtyMap = new Dictionary <int, BattleSoldier>();
     _startingPlayerBattleSoldiers = new List <BattleSoldier>();
 }
Пример #4
0
            public void SetParent(MoveResolver parent)
            {
                if (this._root != this)
                {
                    throw new Exception("Assigned multiple dependencies");
                }

                if (parent.Resolved.HasValue)                 // already been decided: propogate result
                {
                    Resolve(parent.Resolved.Value);
                }
                else if (parent._root == this)                                  // cyclic, unresolved dependencies: resolve true
                {
                    Utils.Printf("Resolved cycle starting at move: {0}", Move);
                    Resolve(true);
                }
                else                                                                    // wait until a decision is made later
                {
                    SetRoot(parent._root);
                    parent._root._dependents.Add(this);                         // add to root to shorten call stack
                }
            }
Пример #5
0
        /// <summary>
        /// Simulate the game for a single turn.
        /// </summary>
        public void DoTurn()
        {
            var activeUnits = new Dictionary <Unit, TurnPlan>();

            foreach (var unit in _units)
            {
                unit.Reset();
                activeUnits.Add(unit, unit.GetMovementPlan(_world));
            }

                        #if DEBUG
            DebugLogFrame();
                        #endif

            while (activeUnits.Count > 0)             // main loop: iterate through each simulation frame
            {
                // STEP 1: COMBAT DETERMINATION
                var pendingCombat = new HashSet <Combat>();                // stops duplication of the same combat
                var unitsInCombat = new HashSet <Unit>();

                foreach (var unit in activeUnits.Keys)
                {
                    foreach (var adj in unit.Position.Adjacent().Select(pos => _world[pos]))                     // for each adjacent Hex
                    {
                        if (adj == null)
                        {
                            continue;
                        }

                        var neighbour = adj.Occupant;
                        if (neighbour != null && neighbour.Owner != unit.Owner)
                        {
                            pendingCombat.Add(new Combat(unit, neighbour));
                            unitsInCombat.Add(unit);
                            unitsInCombat.Add(neighbour);
                        }
                    }
                }

                // STEP 2: COMBAT RESOLUTION
                var pendingCombatSorted = new List <Combat>(pendingCombat);
                pendingCombatSorted.Sort(Combat.PriorityComparer);                      // sort by priortiy

                foreach (var combat in pendingCombatSorted)
                {
                    var unit1 = combat.Unit1;
                    var unit2 = combat.Unit2;

                    if (!unit1.IsDead() && !unit2.IsDead())
                    {
                        combat.Apply();

                        FinaliseCombat(unit1, unit2, activeUnits);                              // lambda/local-function would be
                        FinaliseCombat(unit2, unit1, activeUnits);                              // ideal here! outdated version of C#
                    }
                }

                // STEP 3: MOVE PRE-PROCESSING
                var moveDestinations = new Dictionary <TileVector, List <MoveResolver> >(); // where units want to move to
                var moveOrigins      = new Dictionary <TileVector, MoveResolver>();         // where units are moving from

                foreach (var unit in _units)                                                // collect all units' moves into the Dictionaries, using plans
                {
                    TurnPlan plan = null;
                    if (activeUnits.ContainsKey(unit))                          // only active units can make moves - bind a plan
                    {
                        plan = activeUnits[unit];
                        if (!plan.IsActive())                                           // unit can no longer make moves, so remove from active units
                        {
                            activeUnits.Remove(unit);
                            plan = null;                                                        // unbind plan for this frame
                        }
                    }

                    var canMove   = plan != null && !unitsInCombat.Contains(plan.Unit);
                    var move      = canMove? plan.GetNextMove() : null;
                    var mayVacate = canMove && move.IsStep();

                    // if move is a step, moves here are conditional upon it. otherwise, deny outright
                    var resolver = mayVacate ? MoveResolver.Of(move) : MoveResolver.Deny();
                    moveOrigins.Add(unit.Position, resolver);

                    if (mayVacate)                     // add resolver to the move's intended destination for processing later
                    {
                        var hex = _world[move.Destination];
                        if (hex != null && !hex.Impassable)                         // if target is valid
                        {
                            List <MoveResolver> movesToDestination;
                            if (moveDestinations.ContainsKey(move.Destination))
                            {
                                movesToDestination = moveDestinations[move.Destination];
                            }
                            else                             // initialise the list if it doesn't exist yet
                            {
                                movesToDestination = new List <MoveResolver>(6);
                                moveDestinations.Add(move.Destination, movesToDestination);
                            }
                            movesToDestination.Add(resolver);
                        }
                        else
                        {
                            resolver.Resolve(false);                            // reject if move is illegal
                        }
                    }
                }

                // STEP 4: MOVE CONFLICT RESOLUTION
                foreach (var entry in moveDestinations)                 // check all future mech positions, finalise moves
                {
                    var destination = entry.Key;
                    var moves       = entry.Value;

                    var best = 0;
                    for (var i = 1; i < moves.Count; i++)                       // reject all moves here except the best one
                    {
                        if (Move.PriorityComparer.Compare(moves[i].Move, moves[best].Move) > 0)
                        {
                            moves[best].Resolve(false);
                            best = i;
                        }
                        else                            // not the best move: reject
                        {
                            moves[i].Resolve(false);
                        }
                    }
                    var dependency = moveOrigins.ContainsKey(destination) ? moveOrigins[destination] : null;

                    if (dependency != null)
                    {
                        moves[best].SetParent(dependency);
                    }
                    else
                    {
                        moves[best].Resolve(true);
                    }
                }

                                #if DEBUG
                DebugLogFrame();
                                #endif
            }
            RoundNumber++;
        }
Пример #6
0
 private MoveResolver(Move move)
 {
     _root = this;
     Move  = move;
 }