package br.edu.ufcg.ccc.projeto2.warofkingdoms.management; import java.util.ArrayList; import java.util.List; import java.util.Random; import android.util.Log; import br.edu.ufcg.ccc.projeto2.warofkingdoms.ai.AIPlayer; import br.edu.ufcg.ccc.projeto2.warofkingdoms.entities.Conflict; import br.edu.ufcg.ccc.projeto2.warofkingdoms.entities.Connect; import br.edu.ufcg.ccc.projeto2.warofkingdoms.entities.GameState; import br.edu.ufcg.ccc.projeto2.warofkingdoms.entities.House; import br.edu.ufcg.ccc.projeto2.warofkingdoms.entities.Move; import br.edu.ufcg.ccc.projeto2.warofkingdoms.entities.Player; import br.edu.ufcg.ccc.projeto2.warofkingdoms.entities.Territory; import br.edu.ufcg.ccc.projeto2.warofkingdoms.networking.ConnectResult; import br.edu.ufcg.ccc.projeto2.warofkingdoms.networking.SendMovesResult; import br.edu.ufcg.ccc.projeto2.warofkingdoms.ui.OnTaskCompleted; import br.edu.ufcg.ccc.projeto2.warofkingdoms.util.Constants; import br.edu.ufcg.ccc.projeto2.warofkingdoms.util.RandomEntities; public class AIManager implements CommunicationManager { private final String LOG_TAG = "AIManager"; private static final String DEFAULT_ROOM_ID = "0"; private List<AIPlayer> bots; private List<Territory> updatedMap; private Player human; private RandomEntities generator = new RandomEntities(); private static AIManager instance; private AIManager() { } public synchronized static AIManager getInstance() { if (instance == null) { instance = new AIManager(); } return instance; } /* * Fake sendCurrentMoves (POST) server method */ @Override public void sendCurrentMoves(OnTaskCompleted listener, List<Move> humanMoves) { List<Move> allRoundMoves = new ArrayList<Move>(); allRoundMoves.addAll(humanMoves); allRoundMoves.addAll(getAIRoundMoves()); SendMovesResult sendMovesResult = new SendMovesResult(); List<Conflict> conflicts = processMoves(allRoundMoves); sendMovesResult.setConflicts(conflicts); sendMovesResult.setGameState(new GameState(false, new ArrayList<Player>())); sendMovesResult.setUpdatedMap(updatedMap); Log.v(LOG_TAG, "Conflicts for the round: " + conflicts); listener.onSendMovesTaskCompleted(sendMovesResult); } /* * Moves being processed as a fake server */ private List<Conflict> processMoves(List<Move> moves) { List<Conflict> conflicts = generateConflicts(moves); List<Move> nonConflictingMoves = getNonConflictingMoves(moves, conflicts); updatedMap = updateTerritories(updatedMap, conflicts, nonConflictingMoves); return conflicts; } /* * Fake connect (POST) server method */ @Override public void connect(OnTaskCompleted listener, Connect connectEntity) { human = connectEntity.getPlayer(); updatedMap = generateFirstMap(); this.bots = generateBots(Constants.NUM_PLAYERS - 1); setHumanHouse(); ConnectResult connectResult = new ConnectResult(); connectResult.setTerritories(updatedMap); connectResult.setPlayers(getAllPlayers()); connectResult.setRoomId(DEFAULT_ROOM_ID); listener.onConnectTaskCompleted(connectResult); } private List<Move> getAIRoundMoves() { List<Move> AIMoves = new ArrayList<Move>(); for (AIPlayer bot : bots) { AIMoves.addAll(bot.getGeneratedRoundMoves()); } return AIMoves; } private List<AIPlayer> generateBots(int numBots) { List<AIPlayer> bots = new ArrayList<AIPlayer>(); List<House> chosenHouses = new ArrayList<House>(); for (int i = 0; i < numBots; i++) { AIPlayer randomAiPlayer = nextRandomAiPlayer(chosenHouses); chosenHouses.add(randomAiPlayer.getHouse()); bots.add(randomAiPlayer); } return bots; } private AIPlayer nextRandomAiPlayer(List<House> chosenHouses) { Player nextPlayer = generator.nextPlayer(chosenHouses); AIPlayer randomAiPlayer = new AIPlayer(updatedMap); randomAiPlayer.setName(nextPlayer.getName()); randomAiPlayer.setHouse(nextPlayer.getHouse()); randomAiPlayer.setId(nextPlayer.getId()); House a = randomAiPlayer.getHouse(); a.getName(); return randomAiPlayer; } private void setHumanHouse() { List<House> chosenHouses = new ArrayList<House>(); for (AIPlayer bot : bots) { chosenHouses.add(bot.getHouse()); } human.setHouse(generator.nextHouse(chosenHouses)); } private List<Player> getAllPlayers() { List<Player> players = new ArrayList<Player>(); for (Player bot : bots) { players.add(bot); } players.add(human); return players; } private List<Conflict> generateConflicts(List<Move> moves) { List<Conflict> conflicts = new ArrayList<Conflict>(); for (Move aMove : moves) { Conflict aConflict = null; // avoiding create multiples conflicts for a territory if (conflictAlreadyExists(aMove, conflicts)) { continue; } for (Move anotherMove : moves) { String aMoveTarget = aMove.getTarget().getName(); String anotherMoveTarget = anotherMove.getTarget().getName(); // verifying if has a conflict ("they want the same territory") if (aMoveTarget.equals(anotherMoveTarget)) { String aMoveOriginOwner = aMove.getOrigin().getOwner() .getName(); String anotherMoveOriginOwner = anotherMove.getOrigin() .getOwner().getName(); // avoiding create a conflict with itself if (!aMoveOriginOwner.equals(anotherMoveOriginOwner)) { if (aConflict == null) { aConflict = new Conflict(aMove.getTarget(), new ArrayList<House>(), new ArrayList<Integer>()); aConflict.getHouses().add( aMove.getOrigin().getOwner()); aConflict.getDiceValues().add(getRandomDiceValue()); } aConflict.getHouses().add( anotherMove.getOrigin().getOwner()); aConflict.getDiceValues().add(getRandomDiceValue()); } } } if (aConflict != null) { conflicts.add(aConflict); } } return conflicts; } private Integer getRandomDiceValue() { Random rand = new Random(); return rand.nextInt(6) + 1; // from 1 to 6 } private boolean conflictAlreadyExists(Move move, List<Conflict> conflicts) { for (Conflict conflict : conflicts) { String conflictTerritoryName = conflict.getTerritory().getName(); if (conflictTerritoryName.equals(move.getTarget().getName())) { return true; } } return false; } private List<Move> getNonConflictingMoves(List<Move> moves, List<Conflict> conflicts) { List<Move> nonConflictingMoves = new ArrayList<Move>(); for (Move move : moves) { boolean isConflicting = false; for (Conflict conflict : conflicts) { if (move.getTarget().equals(conflict.getTerritory())) { isConflicting = true; break; } } if (!isConflicting) { nonConflictingMoves.add(move); } } return nonConflictingMoves; } private List<Territory> updateTerritories(List<Territory> currentMap, List<Conflict> conflicts, List<Move> nonConflictingMoves) { List<Move> clonedMoves = cloneMoves(nonConflictingMoves); for (Move move : clonedMoves) { int territoryIndex = currentMap.indexOf(move.getTarget()); currentMap.get(territoryIndex) .setOwner(move.getOrigin().getOwner()); } for (Conflict conflict : conflicts) { int biggestDiceValueIndex = getBiggestDiceValueIndex(conflict .getDiceValues()); if (biggestDiceValueIndex != -1) { int territoryIndex = currentMap .indexOf(conflict.getTerritory()); currentMap.get(territoryIndex).setOwner( conflict.getHouses().get(biggestDiceValueIndex)); } } return currentMap; } /* * */ private List<Move> cloneMoves(List<Move> moves) { List<Move> clonedMoves = new ArrayList<Move>(); for (Move move : moves) { clonedMoves.add(move.clone()); } return clonedMoves; } private int getBiggestDiceValueIndex(List<Integer> diceValues) { int biggestValue = -1; int biggestValueIndex = -1; boolean hasMoreThanOneBiggestValue = false; for (int i = 0; i < diceValues.size(); i++) { if (diceValues.get(i) > biggestValue) { biggestValue = diceValues.get(i); biggestValueIndex = i; hasMoreThanOneBiggestValue = false; } else if (diceValues.get(i) == biggestValue) { hasMoreThanOneBiggestValue = true; } } if (hasMoreThanOneBiggestValue) { return -1; } return biggestValueIndex; } @SuppressWarnings("deprecation") private List<Territory> generateFirstMap() { List<Territory> territories = new ArrayList<Territory>(); territories.add(new Territory("A")); territories.add(new Territory("B")); territories.add(new Territory("C")); territories.add(new Territory("D")); territories.add(new Territory("E")); territories.add(new Territory("F")); territories.add(new Territory("G")); territories.add(new Territory("H")); territories.add(new Territory("I")); territories.add(new Territory("J")); territories.add(new Territory("K")); territories.add(new Territory("L")); territories.add(new Territory("M")); territories.add(new Territory("N")); territories.add(new Territory("O")); territories.add(new Territory("P")); territories.add(new Territory("Q")); territories.add(new Territory("R")); territories.add(new Territory("S")); territories.add(new Territory("T")); territories.add(new Territory("U")); territories.add(new Territory("V")); territories.add(new Territory("X")); territories.add(new Territory("Y")); territories.add(new Territory("Z")); territories.get(2).setOwner(new House("Stark")); territories.get(9).setOwner(new House("Greyjoy")); territories.get(12).setOwner(new House("Lannister")); territories.get(17).setOwner(new House("Baratheon")); territories.get(19).setOwner(new House("Tyrell")); territories.get(23).setOwner(new House("Martell")); return territories; } }