public void testInsertCommand()
        {
            Scenario scenario = new Scenario(20, 20);
            Controller controller = new Controller(scenario);

            Unit unit = new Unit(scenario.getPlayer(), 200);
            controller.addUnit(unit, 10f, 10f);

            // Create a MoveAction
            MoveAction action = new MoveAction(8f, 8f, scenario.getGameWorld(), unit);

            // Test if the ActionController returns true when it gives the command.
            Assert.IsTrue(controller.giveActionCommand(unit, action));

            // Test if the MoveAction is actually on the unit's action queue.
            Assert.IsTrue(unit.getActionQueue()[0] == action);

            // Create a second MoveAction
            MoveAction action2 = new MoveAction(7f, 7f, scenario.getGameWorld(), unit);

            // Insert the second MoveAction to the beginning of the units action queue.
            ActionController.insertIntoActionQueue(unit, action2);
            Assert.IsTrue(unit.getActionQueue()[0] == action2);
            Assert.IsTrue(unit.getActionQueue()[1] == action);
        }
        public void testGiveCommand()
        {
            Scenario scenario = new Scenario(20, 20);
            Controller controller = new Controller(scenario);

            Unit unit = new Unit(scenario.getPlayer(), 200);
            controller.addUnit(unit, 10f, 10f);

            // Create a MoveAction
            MoveAction action = new MoveAction(8f, 8f, scenario.getGameWorld(), unit);

            // Test if the ActionController returns true when it gives the command.
            Assert.IsTrue(controller.giveActionCommand(unit, action));

            // Test if the MoveAction is actually on the unit's action queue.
            Assert.IsTrue(unit.getActionQueue()[0] == action);

            // Create a second MoveAction
            MoveAction action2 = new MoveAction(7f, 7f, scenario.getGameWorld(), unit);

            // Test if the ActionController interrupts the current MoveAction and replaces it with the new one.
            Assert.IsTrue(controller.giveActionCommand(unit, action2));
            Assert.IsTrue(unit.getActionQueue()[0] == action2);
            Assert.IsFalse(unit.getActionQueue().Contains(action));
        }
        public void testMapWithUnitMove()
        {
            Scenario scenario = new Scenario(20, 20);
            Controller controller = new Controller(scenario);
            Unit unit = new Unit(scenario.getPlayer(), new UnitStats());
            controller.addUnit(unit, 6, 6);

            MoveAction move = new MoveAction(10, 10, scenario.getGameWorld(), unit);

            controller.giveActionCommand(unit, move);

            // Update the world so that the unit moves.
            for (int i = 0; i < 1000; i++)
            {
                controller.updateWorld();
            }

            // Test that all of the cells within the units visibility range have been explored.
            for (int i = (int)unit.x - (int)unit.stats.visibilityRange; i < (int)unit.x + (int)unit.stats.visibilityRange; i++)
            {
                for (int j = (int)unit.y - (int)unit.stats.visibilityRange; j < (int)unit.y + (int)unit.stats.visibilityRange; j++)
                {
                    Assert.IsTrue(scenario.getGameWorld().map.getCell(i, j).explored);
                }
            }
        }
        /// <summary>
        /// This function will perform the Attack Action.
        /// </summary>
        /// <returns>true if the action is completed, false if it is not.</returns>
        public override bool work()
        {
            // target is dead, return true.
            if (target.getState().getPrimaryState() == State.PrimaryState.Dead)
            {
                return true;
            }

            // unit cannot attack, return true.
            if (!unit.stats.canAttack)
            {
                return true;
            }

            // Target is in range attack target.
            if (targetIsInRange())
            {
                // Create a SimpleAttackAction if it is needed.
                if (this.attackAction == null)
                {
                    attackAction = new SimpleAttackAction(unit, target);
                }

                // Call the SimpleAttackAction
                attackAction.work();

                // Set the MoveAction to null.
                moveAction = null;
            }
            // Target is not in range, move to it.
            else
            {
                // Create a MoveAction if it is needed.
                if (moveAction == null)
                {
                    if (target.getEntityType() == Entity.EntityType.Unit)
                    {
                        Unit temp = (Unit)target;
                        moveAction = new MoveAction(temp.x, temp.y, gw, unit);
                    }
                    else
                    {
                        StaticEntity temp = (StaticEntity)target;
                        moveAction = new MoveAction(temp.orginCell.Xcoord, temp.orginCell.Ycoord, gw, unit);
                    }
                }
                // Set the SimpleAttackAction to null.
                attackAction = null;

                // Call the MoveAction.
                moveAction.work();
            }

            return false;
        }
        /// <summary>
        /// Performs the GuardAttack action.
        /// </summary>
        /// <returns>false if the action is not complete, true if the action is complete.</returns>
        public override bool work()
        {
            State targetState = target.getState();

            // Check if target's state is DEAD or REMOVE
            if (!targetDead && targetState.getPrimaryState() == State.PrimaryState.Dead || targetState.getPrimaryState() == State.PrimaryState.Remove)
            {
                targetDead = true;
            }

            // unit cannot attack, return true.
            if (!unit.stats.canAttack)
            {
                return true;
            }

            // Distance between unit and the Cell it is guarding.
            float dis = EntityLocController.findDistance(unit.x, unit.y, unit.getGuardCell().Xcoord, unit.getGuardCell().Ycoord);

            // Is target dead or out of range?
            if (targetDead || dis > MAX_DIST)
            {
                // Create a new MoveAction if it is needed.
                if (moveAction == null)
                {
                    moveAction = new MoveAction(unit.getGuardCell().Xcoord, unit.getGuardCell().Ycoord, gw, unit);
                }

                // Move back to original position
                return moveAction.work();
            }
            // Attack the enemy.
            else
            {
                // Create a new AttackAction if it is needed.
                if (attackAction == null)
                {
                    attackAction = new AttackAction(unit, target, gw);
                }

                // Chase or attack the target.
                attackAction.work();
            }

            return false;
        }
        public void testMove()
        {
            Scenario scenario = new Scenario(20, 20);
            Controller controller = new Controller(scenario);

            Unit unit = new Unit(scenario.getPlayer(), 200);
            controller.addUnit(unit, 10f, 10f);

            // Create a MoveAction
            MoveAction action = new MoveAction(8f, 8f, scenario.getGameWorld(), unit);

            controller.giveActionCommand(unit, action);

            Assert.AreEqual(scenario.getGameWorld().map.getCell(10, 10), unit.getCell());

            // Run 1000 cycles of the game
            for (int i = 0; i < 1000; i++)
            {
                controller.updateWorld();
            }

            // Test if the unit has ended up in the target cell.
            Assert.AreEqual(scenario.getGameWorld().map.getCell(8, 8), unit.getCell());
        }
        /// <summary>
        /// This function will perform a building cycle if the number of ticks since the last cycle is equal to TICKS_PER_CYCLE.
        /// </summary>
        /// <returns>true if the building is complete and the action is finished, false otherwise.</returns>
        public override bool work()
        {
            // Building is complete, finish action.
            if (building.health == building.stats.maxHealth)
            {
                return true;
            }

            // Unit cannot build, disregard action.
            if (!unit.stats.canBuild)
            {
                return true;
            }

            if (curTicks % TICKS_PER_CYCLE == 0)
            {
                // Check if unit is adjacent to building.
                if (isUnitNextToBuilding())
                {
                    unit.getState().setPrimaryState(State.PrimaryState.Building);
                    if (building.stats.maxHealth - building.health <= unit.stats.buildSpeed)
                    {
                        // Finish the building.
                        building.health = building.stats.maxHealth;
                        building.isCompleted = true;
                        return true;
                    }
                    else
                    {
                        // Continue building the building.
                        building.health += unit.stats.buildSpeed;
                    }
                }
                else
                {
                    // Move towards the building. Insert a move action into the Unit's action queue.
                    Cell targetCell = EntityLocController.findClosestCell(unit, building, gw);
                    MoveAction moveAction = new MoveAction(targetCell.Xcoord, targetCell.Ycoord, gw, unit);
                    ActionController.insertIntoActionQueue(unit, moveAction);
                }
            }

            curTicks++;
            return false;
        }