コード例 #1
0
ファイル: CombatSimulation.cs プロジェクト: jmcguirk/aoc-2018
 public void MoveActorToTile(CombatSimulationActor actor, CombatSimulationTile tile)
 {
     _unitPositions[actor.TileIndex] = null;
     actor.X         = tile.X;
     actor.Y         = tile.Y;
     actor.TileIndex = tile.TileIndex;
     _unitPositions[actor.TileIndex] = actor;
 }
コード例 #2
0
ファイル: CombatSimulation.cs プロジェクト: jmcguirk/aoc-2018
        public void GetUnoccupiedTilesNearTile(CombatSimulationTile subject, List <CombatSimulationTile> scratchTiles)
        {
            scratchTiles.Clear();
            // North
            CombatSimulationActor foe = GetActorAt(subject.X, subject.Y - 1);

            if (foe == null || !foe.IsAlive)
            {
                var tile = this.GetTileAt(subject.X, subject.Y - 1);
                if (!tile.IsObstruction)
                {
                    scratchTiles.Add(tile);
                }
            }
            // West
            foe = GetActorAt(subject.X - 1, subject.Y);
            if (foe == null || !foe.IsAlive)
            {
                var tile = this.GetTileAt(subject.X - 1, subject.Y);
                if (!tile.IsObstruction)
                {
                    scratchTiles.Add(tile);
                }
            }
            // East
            foe = GetActorAt(subject.X + 1, subject.Y);
            if (foe == null || !foe.IsAlive)
            {
                var tile = this.GetTileAt(subject.X + 1, subject.Y);
                if (!tile.IsObstruction)
                {
                    scratchTiles.Add(tile);
                }
            }
            // South
            foe = GetActorAt(subject.X, subject.Y + 1);
            if (foe == null || !foe.IsAlive)
            {
                var tile = this.GetTileAt(subject.X, subject.Y + 1);
                if (!tile.IsObstruction)
                {
                    scratchTiles.Add(tile);
                }
            }
        }
コード例 #3
0
ファイル: CombatSimulation.cs プロジェクト: jmcguirk/aoc-2018
        private CombatSimulationTile ParseTile(char tile, int x, int y)
        {
            CombatSimulationTile res = new CombatSimulationTile();

            if (tile == ObstructionTile)
            {
                res.TileType = CombatSimulationTileType.Obstruction;
            }
            else
            {
                res.TileType = CombatSimulationTileType.Empty;
            }

            res.OriginalChar = tile;
            res.X            = x;
            res.Y            = y;
            return(res);
        }
コード例 #4
0
        public static bool RequestPath(CombatSimulationActor actor, CombatSimulationTile targetTile,
                                       List <CombatSimulationTile> bestPath)
        {
            var startTile = actor.Tile;
            var sim       = actor.Sim;

            _startCandidates.Clear();
            sim.GetUnoccupiedTilesNearTile(startTile, _startCandidates);
            Int32 bestPathLength = Int32.MaxValue;
            bool  hasPath        = false;
            int   indx           = 0;

            foreach (var candidate in _startCandidates)
            {
                indx++;
                if (RequestPathFromTile(sim, candidate, targetTile, _startPathCopy))
                {
                    if (actor.IsDebug)
                    {
                        sim.RenderPath(_startPathCopy);
                        actor.Log("Candidate had a valid path of length " + _startPathCopy.Count +
                                  " that started on tile " + candidate.X + "," + candidate.Y + " and ended on " + targetTile.X + "," + targetTile.Y + " actor was on " + startTile.X + "," + startTile.Y);
                    }

                    if (_startPathCopy.Count < bestPathLength)
                    {
                        bestPath.Clear();
                        bestPath.Add(candidate);
                        bestPath.AddRange(_startPathCopy);
                        bestPathLength = _startPathCopy.Count;
                        hasPath        = true;
                    }
                }
            }

            return(hasPath);
        }
コード例 #5
0
        public static bool RequestPathFromTile(CombatSimulation sim, CombatSimulationTile startTile, CombatSimulationTile targetTile, List <CombatSimulationTile> bestPath)
        {
            // Clear our initial state
            _costs.Clear();
            _frontier.Clear();
            _pathInProgress.Clear();
            _scratch.Clear();
            bestPath.Clear();

            _frontier.Add(startTile);
            _costs[startTile]          = 0;
            _pathInProgress[startTile] = null;

            do
            {
                _frontier.Sort(delegate(CombatSimulationTile tA, CombatSimulationTile tB)
                {
                    return((_costs[tA] + Distance(tA, targetTile)).CompareTo(_costs[tB] + Distance(tB, targetTile)));

                    //if (distCompare != 0)
                    //{
                    //  return distCompare;
                    //}

                    return(tA.TileIndex.CompareTo(tB.TileIndex));
                });

                CombatSimulationTile currentTile = _frontier[0];
                if (currentTile == targetTile)
                {
                    break;
                }
                _frontier.RemoveAt(0);

                sim.GetUnoccupiedTilesNearTile(currentTile, _scratch);
                foreach (var neighbor in _scratch)
                {
                    int navCost = 0;
                    _costs.TryGetValue(currentTile, out navCost);
                    navCost++;

                    int knownCost = 0;
                    if (!_costs.TryGetValue(neighbor, out knownCost))
                    {
                        knownCost = Int32.MaxValue;
                    }

                    if (navCost < knownCost)
                    {
                        _costs[neighbor]          = navCost;
                        _pathInProgress[neighbor] = currentTile;
                        _frontier.Add(neighbor);
                    }
                }
            } while (_frontier.Count > 0);

            if (_pathInProgress.ContainsKey(targetTile))
            {
                var next = targetTile;
                while (next != startTile)
                {
                    bestPath.Add(next);
                    next = _pathInProgress[next];
                }
                bestPath.Reverse();
                return(true);
            }


            return(false);
        }
コード例 #6
0
 public static int Distance(CombatSimulationTile tileA, CombatSimulationTile tileB)
 {
     return(Math.Abs(tileA.X - tileB.X) + Math.Abs(tileA.Y - tileB.Y));
 }
コード例 #7
0
ファイル: CombatSimulation.cs プロジェクト: jmcguirk/aoc-2018
        public void RenderGameboard(bool midStep = false)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(Environment.NewLine);
            sb.Append("Turn Number - " + _simulationStep);
            if (midStep)
            {
                sb.Append(Environment.NewLine);
                sb.Append("Mid step");
                sb.Append(Environment.NewLine);
            }
            sb.Append(Environment.NewLine);
            for (int y = 0; y < _maxY; y++)
            {
                for (int x = 0; x < _maxX; x++)
                {
                    int  tileIndex = GetTileIndex(x, y);
                    char debug;
                    if (_debugTiles.TryGetValue(tileIndex, out debug))
                    {
                        sb.Append(debug);
                        continue;
                    }
                    var actor = GetActorAtIndex(tileIndex);
                    if (actor != null)
                    {
                        sb.Append(actor.Render());
                    }
                    else
                    {
                        CombatSimulationTile tile = GetTileAtIndex(tileIndex);
                        sb.Append(tile.Render());
                    }
                }

                sb.Append(' ');
                sb.Append(' ');
                var actorInRowCount = 0;
                for (int x = 0; x < _maxX; x++)
                {
                    int tileIndex = GetTileIndex(x, y);
                    var actor     = GetActorAtIndex(tileIndex);
                    if (actor != null)
                    {
                        if (actorInRowCount > 0)
                        {
                            sb.Append(',');
                            sb.Append(' ');
                        }



                        sb.Append(actor.Id);
                        if (actor.Id == CombatSimulationActor.DebugActorId)
                        {
                            sb.Append('*');
                        }
                        sb.Append("(" + actor.RemainingHealth + ")");
                        actorInRowCount++;
                    }
                }

                sb.Append(Environment.NewLine);
            }

            //Log.WriteLine(sb);
        }
コード例 #8
0
ファイル: CombatSimulation.cs プロジェクト: jmcguirk/aoc-2018
 public void DebugTile(CombatSimulationTile tile, char c)
 {
     DebugTile(tile.X, tile.Y, c);
 }