// see wiki.warlight.net/index.php/Combat_Basics private int doAttack(AttackTransferMove move) { Region fromRegion = move.getFromRegion(); Region toRegion = move.getToRegion(); int attackingArmies; int defendingArmies = toRegion.getArmies(); int defendersDestroyed = 0; int attackersDestroyed = 0; if (fromRegion.getArmies() > 1) { if (fromRegion.getArmies() - 1 >= move.getArmies()) // are there enough armies on fromRegion? attackingArmies = move.getArmies(); else attackingArmies = fromRegion.getArmies() - 1; for (int t = 1; t <= attackingArmies; t++) // calculate how much defending armies are destroyed { double rand = Math.random(); if (rand < 0.6) // 60% chance to destroy one defending army defendersDestroyed++; } for (int t = 1; t <= defendingArmies; t++) // calculate how much attacking armies are destroyed { double rand = Math.random(); if (rand < 0.7) // 70% chance to destroy one attacking army attackersDestroyed++; } if (attackersDestroyed >= attackingArmies) { if (defendersDestroyed >= defendingArmies) defendersDestroyed = defendingArmies - 1; attackersDestroyed = attackingArmies; } // process result of attack if (defendersDestroyed >= defendingArmies) // attack success { fromRegion.setArmies(fromRegion.getArmies() - attackingArmies); toRegion.setPlayerName(move.getPlayerName()); toRegion.setArmies(attackingArmies - attackersDestroyed); } else // attack fail { fromRegion.setArmies(fromRegion.getArmies() - attackersDestroyed); toRegion.setArmies(toRegion.getArmies() - defendersDestroyed); return defendersDestroyed; } } else move.setIllegalMove(move.getFromRegion().getId() + " attack " + "only has 1 army"); return 0; }
private void executeAttackTransfer() { LinkedList<Region> visibleRegionsPlayer1Map = map.visibleRegionsForPlayer(player1); LinkedList<Region> visibleRegionsPlayer2Map = map.visibleRegionsForPlayer(player2); LinkedList<Region> visibleRegionsPlayer1OldMap = visibleRegionsPlayer1Map; LinkedList<Region> visibleRegionsPlayer2OldMap = visibleRegionsPlayer2Map; ArrayList<ArrayList<Integer>> usedRegions = new ArrayList<ArrayList<Integer>>(); for (int i = 0; i <= 42; i++) { usedRegions.add(new ArrayList<Integer>()); } Map oldMap = map.getMapCopy(); int moveNr = 1; Boolean previousMoveWasIllegal = false; String previousMovePlayer = ""; while (moveQueue.hasNextAttackTransferMove()) { AttackTransferMove move = moveQueue.getNextAttackTransferMove(moveNr, previousMovePlayer, previousMoveWasIllegal); if (move.getIllegalMove().equals("")) // the com.theaigames.move is not illegal { Region fromRegion = move.getFromRegion(); Region oldFromRegion = oldMap.getRegion(move.getFromRegion().getId()); Region toRegion = move.getToRegion(); Player player = getPlayer(move.getPlayerName()); if (fromRegion.ownedByPlayer( player.getName())) // check if the fromRegion still belongs to this player { if (!usedRegions .get(fromRegion.getId()) .contains( toRegion .getId())) // between two regions there can only be attacked/transfered once { if (oldFromRegion.getArmies() > 1) // there are still armies that can be used { if (oldFromRegion.getArmies() < fromRegion.getArmies() && oldFromRegion.getArmies() - 1 < move .getArmies()) // not enough armies on fromRegion at the start of the // round? move.setArmies( oldFromRegion.getArmies() - 1); // com.theaigames.move the maximal number. else if (oldFromRegion.getArmies() >= fromRegion.getArmies() && fromRegion.getArmies() - 1 < move.getArmies()) // not enough armies on fromRegion currently? move.setArmies(fromRegion.getArmies() - 1); // com.theaigames.move the maximal number. // not needed anymore as regions can only be used once now oldFromRegion.setArmies( oldFromRegion.getArmies() - move.getArmies()); // update oldFromRegion so new armies cannot be used yet if (toRegion.ownedByPlayer(player.getName())) // transfer { if (fromRegion.getArmies() > 1) { fromRegion.setArmies(fromRegion.getArmies() - move.getArmies()); toRegion.setArmies(toRegion.getArmies() + move.getArmies()); usedRegions.get(fromRegion.getId()).add(toRegion.getId()); } else move.setIllegalMove( move.getFromRegion().getId() + " transfer " + "only has 1 army"); } else // attack { int destroyedArmies = doAttack(move); oldFromRegion.setArmies( oldFromRegion.getArmies() - destroyedArmies); // armies that are destroyed and replaced in the same // turn cannot be used to attack/transfer with usedRegions.get(fromRegion.getId()).add(toRegion.getId()); } } else move.setIllegalMove( move.getFromRegion().getId() + " attack/transfer " + "has used all available armies"); } else move.setIllegalMove( move.getFromRegion().getId() + " attack/transfer " + "has already attacked/transfered to this region"); } else move.setIllegalMove( move.getFromRegion().getId() + " attack/transfer " + "was taken this round"); } visibleRegionsPlayer1Map = map.visibleRegionsForPlayer(player1); visibleRegionsPlayer2Map = map.visibleRegionsForPlayer(player2); fullPlayedGame.add(new MoveResult(move, map.getMapCopy())); if (visibleRegionsPlayer1Map.contains(move.getFromRegion()) || visibleRegionsPlayer1Map.contains(move.getToRegion()) || visibleRegionsPlayer1OldMap.contains(move.getToRegion())) { player1PlayedGame.add( new MoveResult(move, map.getVisibleMapCopyForPlayer(player1))); // for the game file if (move.getPlayerName().equals(player2.getName())) opponentMovesPlayer1.add(move); // for the opponent_moves output } if (visibleRegionsPlayer2Map.contains(move.getFromRegion()) || visibleRegionsPlayer2Map.contains(move.getToRegion()) || visibleRegionsPlayer2OldMap.contains(move.getToRegion())) { player2PlayedGame.add( new MoveResult(move, map.getVisibleMapCopyForPlayer(player2))); // for the game file if (move.getPlayerName().equals(player1.getName())) opponentMovesPlayer2.add(move); // for the opponent_moves output } visibleRegionsPlayer1OldMap = visibleRegionsPlayer1Map; visibleRegionsPlayer2OldMap = visibleRegionsPlayer2Map; // set some stuff to know what next com.theaigames.move to get if (move.getIllegalMove().equals("")) { previousMoveWasIllegal = false; moveNr++; } else { previousMoveWasIllegal = true; } previousMovePlayer = move.getPlayerName(); } }