// Damage Calculation to be implemented
    // This is the retaliation damage done to other enemies
    List <AttackLog> ApplyAndRecordDamage(Piece piece, ICollection <MoveData> attackerMoveDatas)
    {
        int baseDamage = piece.attack;
        List <AttackLog> attackLogs = new List <AttackLog>();

        foreach (MoveData attackerMoveData in attackerMoveDatas)
        {
            double damage = baseDamage;
            // apply enemy specific multipliers here
            // damage dampening if outnumbered
            switch (attackerMoveDatas.Count)
            {
            case 2:       // 40% on 2 enemies
                damage *= 0.4; break;

            case 3:       // 20% on 3 enemies
                damage *= 0.2; break;

            case 4:       // 5% on 4 enemies
                damage *= 0.05; break;
            }
            if (piece.IsCounteredBy(attackerMoveData.piece))
            {
                damage *= 1.2;
            }
            damage *= piece.health / (double)piece.maxHealth;

            Piece attacker = attackerMoveData.piece;
            attacker.health -= (damage < 1) ? 1 : (int)damage;   // at least deal 1 dmg
            Move.Direction directionOfRetaliation = Move.OppositeDirection(attackerMoveData.direction);
            AttackLog      attackLog = new AttackLog((int)damage, directionOfRetaliation);
            attackLogs.Add(attackLog);
        }
        return(attackLogs);
    }
Beispiel #2
0
        public bool IsColliding(IReadOnlyDictionary <TimedMove, int> timedMovesToAgentID)
        {
            if (timedMovesToAgentID == null)
            {
                return(false);
            }
            Move.Direction saveDirection = this.direction;
            this.direction = Move.Direction.NO_DIRECTION;
            if (timedMovesToAgentID.ContainsKey(this))
            {
                this.direction = saveDirection;
                return(true);
            }
            this.direction = saveDirection;

            if (Constants.ALLOW_HEAD_ON_COLLISION == false)
            {
                this.setOppositeMove();
                if (timedMovesToAgentID.ContainsKey(this)) // Check direction too now
                {
                    this.setOppositeMove();
                    return(true);
                }
                this.setOppositeMove();
            }

            return(false);
        }
 public MoveData(Move move, Square currentSquare, Square nextSquare)
 {
     this.direction     = move.direction;
     this.piece         = move.piece;
     this.currentSquare = currentSquare;
     this.nextSquare    = nextSquare;
 }
Beispiel #4
0
        public bool IsColliding(ICollection <TimedMove> CAT)
        {
            // Sadly, since there's currently no System.Collections.Generic.IReadOnlySet, Move.IsColliding accepts an ISet<Move>,
            // so the compiler doesn't let us just call base.IsColliding(CAT) because base might put a Move that isn't a TimedMove in CAT,
            if (CAT == null)
            {
                return(false);
            }

            Move.Direction saveDirection = this.direction;
            this.direction = Move.Direction.NO_DIRECTION;
            if (CAT.Contains(this))
            {
                this.direction = saveDirection;
                return(true);
            }
            this.direction = saveDirection;

            this.setOppositeMove();
            if (CAT.Contains(this)) // Check direction too now
            {
                this.setOppositeMove();
                return(true);
            }
            this.setOppositeMove();

            return(false);
        }
    private void Update()
    {
        if (moveCtrl == null)
        {
            return;
        }

        sprite.sortingOrder = 10 + LevelData.instance.Height - moveCtrl.curCoord.y;

        var currentDir      = moveCtrl.Dir;
        var currentIsMoving = moveCtrl.Dir != Move.Direction.Stay;

        if (!currentIsMoving)
        {
            currentDir = lastDir;
        }

        if (currentIsMoving != lastIsMoving || lastDir != currentDir)
        {
            PlayState(MoveDir2AnimDir(currentDir), currentIsMoving);
        }

        lastDir      = currentDir;
        lastIsMoving = currentIsMoving;
    }
Beispiel #6
0
        public Square NextSquare(Move move)
        {
            Square currentSquare = GetCurrentSquare(move.piece);

            Move.Direction direction = move.direction;

            return(NextSquare(currentSquare, direction));
        }
Beispiel #7
0
        /// <summary>
        /// Gets a dictionary mapping TimedMoves to the agents that already made them
        /// and returns a list of agents this TimedMove collides with.
        /// </summary>
        /// <param name="timedMovesToAgentNumLists"></param>
        /// <returns></returns>
        public IReadOnlyList <int> GetColliding(ConflictAvoidanceTable timedMovesToAgentNumLists)
        {
            List <int> ans = null;

            Move.Direction saveDirection = this.direction;
            Direction[]    directions;
            if (Constants.ALLOW_DIAGONAL_MOVE)
            {
                directions = Move.validDirections;
            }
            else
            {
                directions = Move.validDirectionsNoDiag;
            }
            foreach (var direction in directions) // TEMP FIX! Need to get rid of the whole NO_DIRECTION SHTICK! It breaks transitivity!
            {
                this.direction = direction;
                if (timedMovesToAgentNumLists.ContainsKey(this))
                {
                    if (ans == null)
                    {
                        ans = new List <int>(timedMovesToAgentNumLists[this]);
                    }
                    else
                    {
                        ans.AddRange(timedMovesToAgentNumLists[this]);
                    }
                }
            }
            this.direction = saveDirection;

            if (Constants.ALLOW_HEAD_ON_COLLISION == false)
            {
                this.setOppositeMove();
                if (timedMovesToAgentNumLists.ContainsKey(this)) // Check direction too now
                {
                    if (ans == null)
                    {
                        ans = new List <int>(timedMovesToAgentNumLists[this]);
                    }
                    else
                    {
                        ans.AddRange(timedMovesToAgentNumLists[this]);
                    }
                }
                this.setOppositeMove();
            }

            if (ans != null)
            {
                return(ans);
            }
            else
            {
                return(TimedMove.emptyList);
            }
        }
 public MMStarConstraint(int agentNum, int posX, int posY, Move.Direction direction, int timeStep)
 {
     this.move     = new TimedMove(posX, posY, direction, timeStep);
     this.agentNum = agentNum;
     if (direction == Move.Direction.NO_DIRECTION)
     {
         this.vertexConflict = true;
     }
     else
     {
         this.vertexConflict = false;
     }
 }
Beispiel #9
0
        /// <summary>
        /// Gets a dictionary mapping TimedMoves to the agent that already made them
        /// and returns a list of agents this TimedMove collides with.
        /// </summary>
        /// <param name="timedMovesToAgentIndex"></param>
        /// <returns></returns>
        public List <int> GetColliding(IReadOnlyDictionary <TimedMove, int> timedMovesToAgentIndex)
        {
            List <int> ans = null;

            Move.Direction saveDirection = this.direction;
            Direction[]    directions;
            if (Constants.ALLOW_DIAGONAL_MOVE)
            {
                directions = Move.validDirections;
            }
            else
            {
                directions = Move.validDirectionsNoDiag;
            }
            foreach (var direction in directions) // TEMP FIX! Need to get rid of the whole NO_DIRECTION SHTICK! It breaks transitivity!
            {
                this.direction = direction;
                if (timedMovesToAgentIndex.ContainsKey(this))
                {
                    if (ans == null)
                    {
                        ans = new List <int>(4);
                    }
                    ans.Add(timedMovesToAgentIndex[this]);
                }
            }
            this.direction = saveDirection;

            this.setOppositeMove();
            if (timedMovesToAgentIndex.ContainsKey(this)) // Check direction too now
            {
                if (ans == null)
                {
                    ans = new List <int>(1);
                }
                ans.Add(timedMovesToAgentIndex[this]);
            }
            this.setOppositeMove();

            if (ans != null)
            {
                return(ans);
            }
            else
            {
                return(TimedMove.emptyList);
            }
        }
Beispiel #10
0
    PhaseLog[] ResolveCombat(MoveData[] moveDatas)
    {
        PhaseLog[] phaseLogs = new PhaseLog[moveDatas.Length];
        for (int i = 0; i < moveDatas.Length; i++)
        {
            MoveData       moveData  = moveDatas[i];
            Piece          piece     = moveData.piece;
            Move.Direction direction = moveData.direction;
            // where the piece is during combat
            Square combatSquare = moveData.isBounce ? moveData.nextSquare : moveData.currentSquare;

            // check for attackers
            List <MoveData> attackedBy = new List <MoveData>();
            foreach (MoveData otherMoveData in moveDatas)
            {
                Piece otherPiece = otherMoveData.piece;
                if (piece == otherPiece)
                {
                    continue;
                }
                if (otherMoveData.direction == Move.Direction.NONE)
                {
                    continue;
                }
                if (piece.owner == otherPiece.owner)
                {
                    continue;
                }
                Square attackingSquare = otherMoveData.nextSquare;
                if (combatSquare == attackingSquare)
                {
                    attackedBy.Add(otherMoveData);
                }
            }

            // Create Phase Log Here
            List <AttackLog> attackLogs  = ApplyAndRecordDamage(piece, attackedBy);
            Square           finalSquare = moveData.isBounce ? moveData.currentSquare : combatSquare;
            MoveLog          moveLog     = new MoveLog(combatSquare, finalSquare);
            PhaseLog         phaseLog    = new PhaseLog(piece, moveLog, attackLogs.ToArray());
            phaseLogs[i] = phaseLog;
        }

        return(phaseLogs);
    }
    private AnimationDir MoveDir2AnimDir(Move.Direction dir)
    {
        switch (dir)
        {
        case Move.Direction.Left:
            return(AnimationDir.Left);

        case Move.Direction.Right:
            return(AnimationDir.Right);

        case Move.Direction.Up:
            return(AnimationDir.Up);

        case Move.Direction.Down:
            return(AnimationDir.Down);

        default:
            return(AnimationDir.Down);
        }
    }
Beispiel #12
0
 public Square NextSquare(Square currentSquare, Move.Direction direction)
 {
     int row, col;
     switch (direction)
     {
         case Move.Direction.UP:
             row = currentSquare.row > 0 ? currentSquare.row - 1 : 0;
             return new Square(row, currentSquare.col);
         case Move.Direction.DOWN:
             row = currentSquare.row < numRows - 1 ? currentSquare.row + 1 : numRows - 1;
             return new Square(row, currentSquare.col);
         case Move.Direction.LEFT:
             col = currentSquare.col > 0 ? currentSquare.col - 1 : 0;
             return new Square(currentSquare.row, col);
         case Move.Direction.RIGHT:
             col = currentSquare.col < numCols - 1 ? currentSquare.col + 1 : numCols - 1;
             return new Square(currentSquare.row, col);
     }
     return currentSquare;
 }
Beispiel #13
0
        public bool IsColliding(ICollection <TimedMove> moves)
        {
            Move.Direction saveDirection = this.direction;
            this.direction = Move.Direction.NO_DIRECTION;
            if (moves.Contains(this))
            {
                this.direction = saveDirection;
                return(true);
            }
            this.direction = saveDirection;

            this.setOppositeMove();
            if (moves.Contains(this)) // Check direction too now
            {
                this.setOppositeMove();
                return(true);
            }
            this.setOppositeMove();

            return(false);
        }
Beispiel #14
0
        public List <int> GetColliding(IReadOnlyDictionary <TimedMove, List <int> > CAT)
        {
            var ans = new List <int>(); // TODO: This method usually just returns an empty list. Have a static empty list ready and return it when necessary.

            Move.Direction saveDirection = this.direction;
            this.direction = Move.Direction.NO_DIRECTION;
            if (CAT.ContainsKey(this))
            {
                ans.AddRange(CAT[this]);
            }
            this.direction = saveDirection;

            this.setOppositeMove();
            if (CAT.ContainsKey(this)) // Check direction too now
            {
                ans.AddRange(CAT[this]);
            }
            this.setOppositeMove();

            return(ans);
        }
Beispiel #15
0
        public bool IsColliding(IReadOnlyDictionary <TimedMove, int> timedMovesToAgentID)
        {
            Move.Direction saveDirection = this.direction;
            this.direction = Move.Direction.NO_DIRECTION;
            if (timedMovesToAgentID.ContainsKey(this))
            {
                this.direction = saveDirection;
                return(true);
            }
            this.direction = saveDirection;

            this.setOppositeMove();
            if (timedMovesToAgentID.ContainsKey(this)) // Check direction too now
            {
                this.setOppositeMove();
                return(true);
            }
            this.setOppositeMove();

            return(false);
        }
Beispiel #16
0
        /// <summary>
        /// Counts the number of times this node collides with each agent move in the conflict avoidance table.
        /// </summary>
        /// <param name="conflictAvoidance"></param>
        /// <returns></returns>
        public virtual void UpdateConflictCounts(IReadOnlyDictionary <TimedMove, List <int> > conflictAvoidance, int conflictRange = 0)
        {
            int countMoves = -1;

            if (conflictRange == -1) //p-robust
            {
                countMoves = 0;
                WorldState currentCbsNode = this;
                while (currentCbsNode != null)
                {
                    Move.Direction currentDirection = currentCbsNode.allAgentsState[0].lastMove.direction;
                    if (currentDirection != Move.Direction.NO_DIRECTION && currentDirection != Move.Direction.Wait)
                    {
                        countMoves++;
                    }
                    currentCbsNode = currentCbsNode.prevStep;
                }
            }
            for (int i = 0; i < this.allAgentsState.Length; i++)
            {
                this.allAgentsState[i].lastMove.UpdateConflictCounts(conflictAvoidance, this.cbsInternalConflicts, this.conflictTimes);
            }
        }
Beispiel #17
0
 /// <summary>
 /// Almost isn't used anywhere
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="direction"></param>
 /// <param name="time"></param>
 public void setup(int x, int y, Move.Direction direction, int time)
 {
     base.setup(x, y, direction);
     this.time = time;
 }
Beispiel #18
0
//        public static const int FOREVER_AFTER = int.MaxValue

        public TimedMove(int x, int y, Move.Direction direction, int time)
            : base(x, y, direction)
        {
            this.time = time;
        }
Beispiel #19
0
 public Move MakeMove(Move.Direction direction)
 {
     return(new Move(new Piece(this), direction));
 }
Beispiel #20
0
 public void Init(int agentNum, int posX, int posY, Move.Direction direction, int timeStep)
 {
     this.Init(agentNum, new TimedMove(posX, posY, direction, timeStep));
 }
Beispiel #21
0
        /// <summary>
        /// Generates a problem instance based on a DAO map file.
        /// TODO: Fix code dup with GenerateProblemInstance and Import later.
        /// </summary>
        /// <param name="agentsNum"></param>
        /// <returns></returns>
        public ProblemInstance GenerateDragonAgeProblemInstance(string mapFileName, int agentsNum)
        {
            /**
             * Randomization based on timer is disabled for purposes of getting
             * reproducible experiments.
             */
            //Random rand = new Random();

            m_mapFileName = mapFileName;
            m_agentNum    = agentsNum;
            TextReader input = new StreamReader(mapFileName);

            string[] lineParts;
            string   line;

            line = input.ReadLine();
            Debug.Assert(line.StartsWith("type octile"));

            // Read grid dimensions
            line      = input.ReadLine();
            lineParts = line.Split(' ');
            Debug.Assert(lineParts[0].StartsWith("height"));
            int maxX = int.Parse(lineParts[1]);

            line      = input.ReadLine();
            lineParts = line.Split(' ');
            Debug.Assert(lineParts[0].StartsWith("width"));
            int maxY = int.Parse(lineParts[1]);

            line = input.ReadLine();
            Debug.Assert(line.StartsWith("map"));
            bool[][] grid = new bool[maxX][];
            char     cell;

            for (int i = 0; i < maxX; i++)
            {
                grid[i] = new bool[maxY];
                line    = input.ReadLine();
                for (int j = 0; j < maxY; j++)
                {
                    cell = line.ElementAt(j);
                    if (cell == '@' || cell == 'O' || cell == 'T' || cell == 'W' /* Water isn't traversable from land */)
                    {
                        grid[i][j] = true;
                    }
                    else
                    {
                        grid[i][j] = false;
                    }
                }
            }

            int x;
            int y;

            Agent[]      agentGoals  = new Agent[agentsNum];
            AgentState[] agentStates = new AgentState[agentsNum];
            bool[][]     goals       = new bool[maxX][];

            for (int i = 0; i < maxX; i++)
            {
                goals[i] = new bool[maxY];
            }

            // Choose random valid unclaimed goal locations
            for (int i = 0; i < agentsNum; i++)
            {
                x = rand.Next(maxX);
                y = rand.Next(maxY);
                if (goals[x][y] || grid[x][y])
                {
                    i--;
                }
                else
                {
                    goals[x][y]   = true;
                    agentGoals[i] = new Agent(x, y, i);
                }
            }

            // Select random start/goal locations for every agent by performing a random walk
            for (int i = 0; i < agentsNum; i++)
            {
                agentStates[i] = new AgentState(agentGoals[i].Goal.x, agentGoals[i].Goal.y, agentGoals[i]);
            }

            ProblemInstance problem = new ProblemInstance();

            problem.parameters[ProblemInstance.GRID_NAME_KEY] = Path.GetFileNameWithoutExtension(mapFileName);
            problem.Init(agentStates, grid);

            for (int j = 0; j < RANDOM_WALK_STEPS; j++)
            {
                for (int i = 0; i < agentsNum; i++)
                {
                    goals[agentStates[i].lastMove.x][agentStates[i].lastMove.y] = false; // We're going to move the goal somewhere else
                    // Move in a random legal direction:
                    while (true)
                    {
                        Move.Direction op = (Move.Direction)rand.Next(0, 5); // TODO: fixme
                        agentStates[i].lastMove.Update(op);
                        if (problem.IsValid(agentStates[i].lastMove) &&
                            !goals[agentStates[i].lastMove.x][agentStates[i].lastMove.y]) // This spot isn't another agent's goal
                        {
                            break;
                        }
                        else
                        {
                            agentStates[i].lastMove.setOppositeMove(); // Rollback
                        }
                    }
                    goals[agentStates[i].lastMove.x][agentStates[i].lastMove.y] = true; // Claim agent's new goal
                }
            }

            // Zero the agents' timesteps
            foreach (AgentState agentStart in agentStates)
            {
                agentStart.lastMove.time = 0;
            }

            return(problem);
        }
Beispiel #22
0
 public void Init(int agentNum, int posX, int posY, Move.Direction direction, int timeStep, int constraintRange = 0)
 {
     this.Init(agentNum, new TimedMove(posX, posY, direction, timeStep), constraintRange);
 }
Beispiel #23
0
 public CbsConstraint(int agentNum, int posX, int posY, Move.Direction direction, int timeStep, int constraintRange = 0)
 {
     this.Init(agentNum, posX, posY, direction, timeStep, constraintRange);
 }
Beispiel #24
0
        public Move.Direction direction; // direction of attack, world direction
        // Other metadata for visuals can be added, for example: crits, dampening

        public AttackLog(int damage, Move.Direction direction)
        {
            this.damage    = damage;
            this.direction = direction;
        }
Beispiel #25
0
 public CFMCbsConstraint(int agentNum, int posX, int posY, Move.Direction direction, int timeStep)
 {
     this.Init(agentNum, posX, posY, direction, timeStep);
 }
Beispiel #26
0
        /// <summary>
        /// Generates a problem instance, including a board, start and goal locations of desired number of agents
        /// and desired precentage of obstacles
        /// TODO: Refactor to use operators.
        /// </summary>
        /// <param name="gridSize"></param>
        /// <param name="agentsNum"></param>
        /// <param name="obstaclesNum"></param>
        /// <returns></returns>
        public ProblemInstance GenerateProblemInstance(int gridSize, int agentsNum, int obstaclesNum)
        {
            m_mapFileName = "GRID" + gridSize + "X" + gridSize;
            m_agentNum    = agentsNum;

            /**
             * Randomization based on timer is disabled for purposes of getting
             * reproducible experiments.
             */
            //Random rand = new Random();

            if (agentsNum + obstaclesNum + 1 > gridSize * gridSize)
            {
                throw new Exception("Not enough room for " + agentsNum + ", " + obstaclesNum + " and one empty space in a " + gridSize + "x" + gridSize + "map.");
            }

            int x;
            int y;

            Agent[]      aGoals = new Agent[agentsNum];
            AgentState[] aStart = new AgentState[agentsNum];
            bool[][]     grid   = new bool[gridSize][];
            bool[][]     goals  = new bool[gridSize][];

            // Generate a random grid
            for (int i = 0; i < gridSize; i++)
            {
                grid[i]  = new bool[gridSize];
                goals[i] = new bool[gridSize];
            }
            for (int i = 0; i < obstaclesNum; i++)
            {
                x = rand.Next(gridSize);
                y = rand.Next(gridSize);
                if (grid[x][y]) // Already an obstacle
                {
                    i--;
                }
                grid[x][y] = true;
            }

            // Choose random goal locations
            for (int i = 0; i < agentsNum; i++)
            {
                x = rand.Next(gridSize);
                y = rand.Next(gridSize);
                if (goals[x][y] || grid[x][y])
                {
                    i--;
                }
                else
                {
                    goals[x][y] = true;
                    aGoals[i]   = new Agent(x, y, i);
                }
            }

            // Select random start/goal locations for every agent by performing a random walk
            for (int i = 0; i < agentsNum; i++)
            {
                aStart[i] = new AgentState(aGoals[i].Goal.x, aGoals[i].Goal.y, aGoals[i]);
            }

            // Initialized here only for the IsValid() call. TODO: Think how this can be sidestepped elegantly.
            ProblemInstance problem = new ProblemInstance();

            problem.Init(aStart, grid);

            for (int j = 0; j < RANDOM_WALK_STEPS; j++)
            {
                for (int i = 0; i < agentsNum; i++)
                {
                    goals[aStart[i].lastMove.x][aStart[i].lastMove.y] = false; // We're going to move the goal somewhere else
                    while (true)
                    {
                        Move.Direction op = (Move.Direction)rand.Next(0, 5); // TODO: fixme
                        aStart[i].lastMove.Update(op);
                        if (problem.IsValid(aStart[i].lastMove) &&
                            !goals[aStart[i].lastMove.x][aStart[i].lastMove.y]) // this spot isn't another agent's goal
                        {
                            break;
                        }
                        else
                        {
                            aStart[i].lastMove.setOppositeMove(); // Rollback
                        }
                    }
                    goals[aStart[i].lastMove.x][aStart[i].lastMove.y] = true; // Claim agent's new goal
                }
            }

            // Zero the agents' timesteps
            foreach (AgentState agentStart in aStart)
            {
                agentStart.lastMove.time = 0;
            }

            // TODO: There is some repetition here of previous instantiation of ProblemInstance. Think how to elegantly bypass this.
            problem = new ProblemInstance();
            problem.Init(aStart, grid);
            return(problem);
        }