package SimpleFactoryPlayer.Implementation; import AgentSystemPluginAPI.Contract.IAgentSystem; import AgentSystemPluginAPI.Contract.StateAction; import AgentSystemPluginAPI.Services.IAgent; import AgentSystemPluginAPI.Services.IPluginServiceProvider; import AgentSystemPluginAPI.Services.LearningAlgorithm; import EnvironmentPluginAPI.Exceptions.TechnicalException; import EnvironmentPluginAPI.Service.IEnvironmentConfiguration; import Factory.GameLogic.Enums.Direction; import Factory.GameLogic.Enums.Faction; import Factory.GameLogic.TransportTypes.*; import Factory.GameLogic.Utility.GameInfos; import SimpleFactoryPlayer.Implementation.Entities.RawField; import SimpleFactoryPlayer.Implementation.Entities.RawState; import SimpleFactoryPlayer.Implementation.Enums.FieldType; import SimpleFactoryPlayer.Implementation.Enums.FriendFoe; import java.util.ArrayList; import java.util.List; /** * Created with IntelliJ IDEA. * User: TwiG * Date: 06.06.12 * Time: 11:41 * To change this template use File | Settings | File Templates. */ public class SimpleFactoryPlayerSystem implements IAgentSystem<IEnvironmentConfiguration, TGameState, TActionsInTurn> { // ------------------------------ FIELDS ------------------------------ private IPluginServiceProvider provider; private IAgent agent; private List<IAgent> agentList = new ArrayList<IAgent>(); private Faction myFaction; private Faction enemyFaction; private StateActionGenerator stateActionGenerator = new StateActionGenerator(); private float rewardForLastTurn = 0; private boolean firstturn = false; // REWARDS private int BasicTurnReward; private int KillEnemyReward; private int MoveToAnotherFieldReward; private int GainInfluenceReward; // --------------------------- CONSTRUCTORS --------------------------- public SimpleFactoryPlayerSystem(IPluginServiceProvider provider) throws TechnicalException { this.provider = provider; BasicTurnReward = Integer.parseInt(provider.getAgentSystemSetting("BasicTurnReward")); KillEnemyReward = Integer.parseInt(provider.getAgentSystemSetting("KillEnemyReward")); MoveToAnotherFieldReward = Integer.parseInt(provider.getAgentSystemSetting("MoveToAnotherFieldReward")); GainInfluenceReward = Integer.parseInt(provider.getAgentSystemSetting("GainInfluenceReward")); agent = provider.getTableAgent("SimpleFactoryUnitController", LearningAlgorithm.SARSALambda, new StateActionGenerator()); agentList.add(agent); agent.setAlpha(Float.parseFloat(provider.getAgentSystemSetting("Alpha"))); agent.setEpsilon(Float.parseFloat(provider.getAgentSystemSetting("Epsilon"))); agent.setGamma(Float.parseFloat(provider.getAgentSystemSetting("Gamma"))); agent.setLambda(Float.parseFloat(provider.getAgentSystemSetting("Lambda"))); } // ------------------------ INTERFACE METHODS ------------------------ // --------------------- Interface IAgentSystem --------------------- @Override public void start(IEnvironmentConfiguration metaData) throws TechnicalException { myFaction = Faction.valueOf(metaData.toString()); if (myFaction == Faction.RED) { enemyFaction = Faction.BLUE; } else { enemyFaction = Faction.RED; } firstturn = true; } @Override public TActionsInTurn getActionsForEnvironmentStatus(TGameState tGameState) throws TechnicalException { TGameState currentGameState = tGameState; List<TUnit> myUnits = GameInfos.getUnitsForFaction(currentGameState, myFaction); List<TAction> actionList = new ArrayList<TAction>(); for (TUnit unit : myUnits) { RawState rawState; // Randomizen wäre besser TPosition unitPosition = GameInfos.getPositionForUnit(currentGameState, unit); TAbstractField field = GameInfos.getFieldForPosition(currentGameState, unitPosition); rawState = generateRawState(currentGameState, field, unitPosition); StateAction action = null; String encryptedState = stateActionGenerator.encryptState(rawState); if (firstturn) { action = agent.startEpisode(new StateAction(encryptedState)); firstturn = false; } else { action = agent.step(rewardForLastTurn, new StateAction(encryptedState)); } Direction directionOfAction = stateActionGenerator.decryptDirection(action.getActionDescription()); TAction moveOrder = new TAction(unit, directionOfAction); if (directionOfAction != null) { actionList.add(moveOrder); } rewardForLastTurn = calculateReward(currentGameState, moveOrder, unitPosition, field); currentGameState = refreshGameState(currentGameState, moveOrder, unitPosition); } return new TActionsInTurn(actionList); } @Override public void end() throws TechnicalException { agent.endEpisode(new StateAction(""), rewardForLastTurn); } public List<IAgent> getInternalAgents() { return agentList; } // -------------------------- PRIVATE METHODS -------------------------- private float calculateReward(TGameState tGameState, TAction moveOrder, TPosition position, TAbstractField fieldComeFrom) { float reward = BasicTurnReward; //-10; TUnit unit = moveOrder.getUnit(); TAbstractField fieldMoveTo = null; if (moveOrder.getDirection() == null) { fieldMoveTo = fieldComeFrom; } else { fieldMoveTo = GameInfos.getNeighborFieldForPosition(tGameState, position, moveOrder.getDirection()); if (fieldMoveTo.isOccupied() && !fieldMoveTo.getOccupant().getControllingFaction().equals(myFaction)) { reward += KillEnemyReward; //5; } if (!fieldMoveTo.equals(fieldComeFrom)) { reward += MoveToAnotherFieldReward; //1; } } if (fieldMoveTo instanceof TInfluenceField) { TFactory factory = getFactoryForID(tGameState, ((TInfluenceField) fieldMoveTo).getFactoryID()); if (factory.getOwningFaction() != myFaction || factory.getOwningFaction() == Faction.NEUTRAL) { reward += GainInfluenceReward; //3; } } return reward; } private TFactory getFactoryForID(TGameState gameState, int ID) { for (TFactory factory : gameState.getFactories()) { if (factory.getFactoryID() == ID) { return factory; } } return null; } private RawState generateRawState(TGameState gameState, TAbstractField field, TPosition positionOfField) { RawField rawField; RawState rawState = new RawState(); RawField wallField = new RawField(); wallField.setFieldController(FriendFoe.FRIEND); wallField.setFieldType(FieldType.FACTORY); wallField.setRemainingTimeToSpawn(100); wallField.setUnit(FriendFoe.NONE); int border = gameState.getMapFields().length - 1; rawField = generateRawField(gameState, field); rawState.setMiddle(rawField); if (positionOfField.getX() > 0) { rawField = generateRawField(gameState, GameInfos.getNeighborFieldForPosition(gameState, positionOfField, Direction.LEFT)); rawState.setLeft(rawField); } else { rawState.setLeft(wallField); } if (positionOfField.getX() < border) { rawField = generateRawField(gameState, GameInfos.getNeighborFieldForPosition(gameState, positionOfField, Direction.RIGHT)); rawState.setRight(rawField); } else { rawState.setRight(wallField); } if (positionOfField.getY() < border) { rawField = generateRawField(gameState, GameInfos.getNeighborFieldForPosition(gameState, positionOfField, Direction.DOWN)); rawState.setDown(rawField); } else { rawState.setDown(wallField); } if (positionOfField.getY() < border && positionOfField.getX() > 0) { rawField = generateRawField(gameState, GameInfos.getNeighborFieldForPosition(gameState, positionOfField, Direction.DOWN_LEFT)); rawState.setLeftDown(rawField); } else { rawState.setLeftDown(wallField); } if (positionOfField.getY() < border && positionOfField.getX() < border) { rawField = generateRawField(gameState, GameInfos.getNeighborFieldForPosition(gameState, positionOfField, Direction.DOWN_RIGHT)); rawState.setRightDown(rawField); } else { rawState.setRightDown(wallField); } if (positionOfField.getY() > 0 && positionOfField.getX() > 0) { rawField = generateRawField(gameState, GameInfos.getNeighborFieldForPosition(gameState, positionOfField, Direction.UP_LEFT)); rawState.setLeftTop(rawField); } else { rawState.setLeftTop(wallField); } if (positionOfField.getY() > 0 && positionOfField.getX() < border) { rawField = generateRawField(gameState, GameInfos.getNeighborFieldForPosition(gameState, positionOfField, Direction.UP_RIGHT)); rawState.setRightTop(rawField); } else { rawState.setRightTop(wallField); } if (positionOfField.getY() > 0) { rawField = generateRawField(gameState, GameInfos.getNeighborFieldForPosition(gameState, positionOfField, Direction.UP)); rawState.setTop(rawField); } else { rawState.setTop(wallField); } Direction direction = findNextTarget(gameState, field, positionOfField); rawState.setSignal(direction); return rawState; } private RawField generateRawField(TGameState gameState, TAbstractField field) { RawField rawField = new RawField(); if (field.isOccupied()) { if (field.getOccupant().getControllingFaction() == myFaction) { if (field.getOccupant().getExhaustedForTurn() == gameState.getTurn()) { rawField.setUnit(FriendFoe.EXHAUSTED_FRIEND); } else { rawField.setUnit(FriendFoe.FRIEND); } } else { rawField.setUnit(FriendFoe.FOE); } } else { rawField.setUnit(FriendFoe.NONE); } if (field instanceof TNormalField) { rawField.setFieldType(FieldType.NORMAL); rawField.setFieldController(FriendFoe.NONE); } else { int ID = 0; if (field instanceof TFactoryField) { rawField.setFieldType(FieldType.FACTORY); ID = ((TFactoryField) field).getFactoryID(); } else if (field instanceof TInfluenceField) { rawField.setFieldType(FieldType.INFLUENCE); ID = ((TInfluenceField) field).getFactoryID(); } TFactory factory = getFactoryForID(gameState, ID); rawField.setRemainingTimeToSpawn(factory.getRemainingRoundsForRespawn()); if (factory.getOwningFaction() == myFaction) { rawField.setFieldController(FriendFoe.FRIEND); } else { rawField.setFieldController(FriendFoe.FOE); } } return rawField; } private Direction findNextTarget(TGameState gameState, TAbstractField field, TPosition positionOfField) { int minimumDistance = Integer.MAX_VALUE; int currentDistance; Direction direction = null; TAbstractField[][] board = gameState.getMapFields(); int topBorder = 0; int leftBorder = 0; int rightBorder = board.length - 1; int bottomBorder = board.length - 1; int x = positionOfField.getX(); int y = positionOfField.getY(); currentDistance = 0; //Looking Right ======================================================================== for (int i = x; i <= rightBorder; i++) { currentDistance++; for (int j = 0; j <= bottomBorder; j++) { if (board[j][i].isOccupied()) { if (board[j][i].getOccupant().getControllingFaction() == enemyFaction) { if (currentDistance < minimumDistance) { minimumDistance = currentDistance; direction = Direction.RIGHT; break; } } } } } if (minimumDistance == 1) { return direction; } currentDistance = 0; //Looking Left ======================================================================== for (int i = x; i >= leftBorder; i--) { currentDistance++; for (int j = 0; j <= bottomBorder; j++) { //check auf Aktives influence feld eifügen if (board[j][i].isOccupied()) { if (board[j][i].getOccupant().getControllingFaction() == enemyFaction) { if (currentDistance < minimumDistance) { minimumDistance = currentDistance; direction = Direction.RIGHT; break; } } } } } if (minimumDistance == 1) { return direction; } currentDistance = 0; //Looking Down ======================================================================== for (int i = y; i <= bottomBorder; i++) { currentDistance++; for (int j = 0; j <= rightBorder; j++) { //check auf Aktives influence feld eifügen if (board[i][j].isOccupied()) { if (board[i][j].getOccupant().getControllingFaction() == enemyFaction) { if (currentDistance < minimumDistance) { minimumDistance = currentDistance; direction = Direction.RIGHT; break; } } } } } if (minimumDistance == 1) { return direction; } currentDistance = 0; //Looking UP ======================================================================== for (int i = y; i >= topBorder; i--) { currentDistance++; for (int j = 0; j <= rightBorder; j++) { //check auf Aktives influence feld eifügen if (board[i][j].isOccupied()) { if (board[i][j].getOccupant().getControllingFaction() == enemyFaction) { if (currentDistance < minimumDistance) { minimumDistance = currentDistance; direction = Direction.RIGHT; break; } } } } } return direction; } private TGameState refreshGameState(TGameState gameState, TAction action, TPosition unitPosition) { //================= replacing the field the unit came from ====================== TAbstractField[][] board = gameState.getMapFields(); TAbstractField from = board[unitPosition.getY()][unitPosition.getX()]; if (board[unitPosition.getY()][unitPosition.getX()] instanceof TNormalField) { board[unitPosition.getY()][unitPosition.getX()] = new TNormalField(null); } else if (board[unitPosition.getY()][unitPosition.getX()] instanceof TInfluenceField) { TInfluenceField fromINF = (TInfluenceField) from; board[unitPosition.getY()][unitPosition.getX()] = new TInfluenceField(null, fromINF.getFactoryID()); } else if (board[unitPosition.getY()][unitPosition.getX()] instanceof TFactoryField) { TFactoryField fromFAC = (TFactoryField) from; board[unitPosition.getY()][unitPosition.getX()] = new TFactoryField(null, fromFAC.getFactoryID()); } //====================== replacing the field the unit is going too ============================ // ------------------ getting x y of the field the unit is going to ----------- int x = unitPosition.getX(); int y = unitPosition.getY(); if (action.getDirection() == Direction.RIGHT || action.getDirection() == Direction.UP_RIGHT || action.getDirection() == Direction.DOWN_RIGHT) { x++; } if (action.getDirection() == Direction.LEFT || action.getDirection() == Direction.UP_LEFT || action.getDirection() == Direction.DOWN_LEFT) { x--; } if (action.getDirection() == Direction.DOWN || action.getDirection() == Direction.DOWN_LEFT || action.getDirection() == Direction.DOWN_RIGHT) { y++; } if (action.getDirection() == Direction.UP || action.getDirection() == Direction.UP_LEFT || action.getDirection() == Direction.UP_RIGHT) { y--; } // -------------------------- actual replace --------------------------- TAbstractField to = board[y][x]; TUnit oldUnit = action.getUnit(); TUnit newUnit = new TUnit(oldUnit.getUnitId(), oldUnit.getControllingFaction(), gameState.getTurn()); if (board[y][x] instanceof TNormalField) { board[y][x] = new TNormalField(newUnit); } else if (board[y][x] instanceof TInfluenceField) { TInfluenceField fromINF = (TInfluenceField) to; board[y][x] = new TInfluenceField(newUnit, fromINF.getFactoryID()); } else if (board[y][x] instanceof TFactoryField) { TFactoryField fromFAC = (TFactoryField) to; board[y][x] = new TInfluenceField(newUnit, fromFAC.getFactoryID()); } //================== replacing the board ============================ TGameState newState = new TGameState(gameState.hasClientMetGoal(), gameState.getActivePlayer() , gameState.getTurn(), gameState.getRound(), gameState.getGameStartedAt(), gameState.getFactories(), board); return newState; } }