Android Open Source - dragon-wars State Tree






From Project

Back to project page dragon-wars.

License

The source code is released under:

GNU General Public License

If you think the Android project dragon-wars listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.group7.dragonwars.engine.GoalArbitration;
// w  w w. ja  v  a2 s.  c  o m
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import android.util.Log;

import com.group7.dragonwars.engine.Building;
import com.group7.dragonwars.engine.GameField;
import com.group7.dragonwars.engine.GameMap;
import com.group7.dragonwars.engine.GameState;
import com.group7.dragonwars.engine.Logic;
import com.group7.dragonwars.engine.Pair;
import com.group7.dragonwars.engine.Player;
import com.group7.dragonwars.engine.Position;
import com.group7.dragonwars.engine.Unit;


public class StateTree {
    private int maxSize = 200;
    private GameState gameState;
    private Node base = null;
    private Player stateTreeOwner;
    private Logic logic = new Logic();
    private List<AtomicAction> actions;

    public StateTree(final GameState gamestate, final int maxsize,
                     final Player owner) {
        gameState = gamestate;
        stateTreeOwner = owner;
    }

    private void Explore() {
        base = new Node(null, 0, 0, null);
        base.setSize(1);

        for (Player player : gameState.getPlayers()) {
            if (player.equals(stateTreeOwner)) {
                continue;
            }

            for (Unit playerUnit : stateTreeOwner.getOwnedUnits()) {
                float bestValue = -1;
                AtomicAction currentBest = null;

                for (Unit unit : player.getOwnedUnits()) {
                    if (base.getSize() >= maxSize) {
                        break;
                    }

                    //Evaluate cost and gain, don't add if below threshold
                    List<Position> vfs = logic.findValidFieldsNextToUnit(
                        gameState.getMap(), playerUnit, unit);

                    if (vfs.isEmpty()) {
                        continue;
                    }

                    Pair<Pair<Double, Double>, Position> dmgpos
                        = getBestAttackPosition(gameState.getMap(), playerUnit,
                                                unit, vfs);
                    float damageRatio = (float)(dmgpos.getLeft().getLeft()
                                                / dmgpos.getLeft().getRight());

                    if (damageRatio < 0) {      // In enemy's favour
                        continue;
                    }

                    if (damageRatio > bestValue) {
                        currentBest =
                            new AttackAt(gameState, playerUnit, unit,
                                         damageRatio, dmgpos.getRight());
                        bestValue = damageRatio;
                    }
                }

                if (currentBest == null) { /* No unit to attack */
                    GameField curField
                        = gameState.getMap().getField(playerUnit.getPosition());

                    if (!(curField.hostsBuilding()
                            && !curField.getBuilding().getOwner()
                          .equals(stateTreeOwner))) {
                        /* We're standing on a building we don't own */
                        List<Position> dests
                            = logic.destinations(gameState.getMap(),
                                                 playerUnit);

                        for (Position p : dests) {
                            GameField gf = gameState.getMap().getField(p);

                            if (gf.hostsBuilding() && !gf.getBuilding()
                                .getOwner().equals(stateTreeOwner)
                                && !gf.hostsUnit()) {
                                currentBest = new MoveTo(gameState,
                                                         playerUnit, p, 1);
                                break; /* Naive building picking */
                            }
                        }
                    }
                }

                if (base.getSize() >= maxSize) {
                    break;
                }

                base.AddChildNode(bestValue, currentBest);
            }

        }

        int goldAmount = stateTreeOwner.getGoldAmount();

        for (Building building : stateTreeOwner.getOwnedBuildings()) {
            Position p = building.getPosition();

            if (!gameState.getMap().getField(p).hostsUnit()) {
                Log.d("StateTree", "Trying to build at " + building.getName());
                Unit bestBuildable = getBestBuildableUnit(building, goldAmount);

                if (bestBuildable == null) {
                    continue;
                }

                goldAmount -= bestBuildable.getProductionCost();
                AtomicAction bestAction =
                    new BuildUnit(gameState, bestBuildable,
                                  building.getPosition(),
                                  bestBuildable.getProductionCost());
                base.AddChildNode(bestBuildable.getProductionCost(),
                                  bestAction);
            }
        }

        actions = base.getActions();
        base.Collapse();

    }

    public List<AtomicAction> getActions() {
        Explore();
        return actions;
    }

    private Pair<Pair<Double, Double>, Position>
    getBestAttackPosition(final GameMap map, final Unit attacker,
                          final Unit defender,
                          final List<Position> validPositions) {
        if (validPositions.size() == 1) {
            Position p = validPositions.get(0);
            return new Pair<Pair<Double, Double>, Position>(
                       logic.calculateDamageFrom(map, attacker, defender, p), p);
        } else {
            Double ratio = null; /* Damn it Java */
            Pair<Double, Double> bestRatioDamage = null;
            Position movePos = null;

            for (Position p : validPositions) {
                Pair<Double, Double> damageExchange =
                    logic.calculateDamageFrom(map, attacker, defender, p);
                Double pRatio
                    = damageExchange.getLeft() / damageExchange.getRight();

                if (pRatio == null || bestRatioDamage == null
                    || movePos == null) {
                    ratio = pRatio;
                    bestRatioDamage = damageExchange;
                    movePos = p;

                } else if (pRatio > ratio) {
                    ratio = pRatio;
                    bestRatioDamage = damageExchange;
                    movePos = p;
                }
            }

            return new Pair<Pair<Double, Double>, Position>(bestRatioDamage,
                                                            movePos);
        }
    }

    private Unit getBestBuildableUnit(final Building building,
                                      final int goldAmount) {

        List<Unit> buildable = building.getProducibleUnits();

        if (buildable.size() == 0) {
            return null;
        }

        Unit bestUnit = buildable.get(0);

        for (Unit unit : buildable) {
            int cost = unit.getProductionCost();

            if (cost <= goldAmount && cost > bestUnit.getProductionCost()) {
                bestUnit = unit;
            }
        }

        if (bestUnit.getProductionCost() > goldAmount) {
            return null;
        } else {
            return bestUnit;
        }
    }
}




Java Source Code List

com.group7.dragonwars.DrawingThread.java
com.group7.dragonwars.GameActivity.java
com.group7.dragonwars.GameView.java
com.group7.dragonwars.HelpActivity.java
com.group7.dragonwars.IsAiAdapter.java
com.group7.dragonwars.MainMenuActivity.java
com.group7.dragonwars.MapSelectActivity.java
com.group7.dragonwars.PlayerSelectActivity.java
com.group7.dragonwars.Results.java
com.group7.dragonwars.StatisticsActivity.java
com.group7.dragonwars.engine.BasicMapInfo.java
com.group7.dragonwars.engine.BitmapChanger.java
com.group7.dragonwars.engine.Building.java
com.group7.dragonwars.engine.DrawableMapObject.java
com.group7.dragonwars.engine.FloatPair.java
com.group7.dragonwars.engine.FuncEx.java
com.group7.dragonwars.engine.Func.java
com.group7.dragonwars.engine.GameField.java
com.group7.dragonwars.engine.GameFinishedException.java
com.group7.dragonwars.engine.GameMap.java
com.group7.dragonwars.engine.GameState.java
com.group7.dragonwars.engine.InformationState.java
com.group7.dragonwars.engine.Logic.java
com.group7.dragonwars.engine.MapReader.java
com.group7.dragonwars.engine.Pair.java
com.group7.dragonwars.engine.PlayerAI.java
com.group7.dragonwars.engine.Player.java
com.group7.dragonwars.engine.Position.java
com.group7.dragonwars.engine.RangedUnit.java
com.group7.dragonwars.engine.Statistics.java
com.group7.dragonwars.engine.Unit.java
com.group7.dragonwars.engine.Database.Database.java
com.group7.dragonwars.engine.GoalArbitration.AtomicAction.java
com.group7.dragonwars.engine.GoalArbitration.AttackAt.java
com.group7.dragonwars.engine.GoalArbitration.BuildUnit.java
com.group7.dragonwars.engine.GoalArbitration.MoveTo.java
com.group7.dragonwars.engine.GoalArbitration.Node.java
com.group7.dragonwars.engine.GoalArbitration.StateTree.java