title: Risk, the Warlight Way

text:
# Question
Title: Risk, the Warlight Way
## Introduction

In this game, players use their armies to fight other players' armies, capture territories, and become the last man standing. Each turn, players receive a base number of armies to use at their disposal. By capturing territories in certain regions, however, players can increase this number to give them a potential advantage later in the game. (This is essentially the same as Warlight).

All bots should be written in Java , C, or C++ (I would include other languages but don't have the software or experience for them). It is not necessary for your submission to extend a class, and you may create functions, classes, interfaces, or whatever else is necessary, and use any package or class in the standard APIs. If you are planning on creating a class or interface, please consider using an inner class or inner interface.

Please do not attempt to programmatically alter the controller or other submissions in this competition.

## Gameplay

### Overview

A 10x10 two-dimensional array will simulate the board, each element/cell representing a "territory". There will be 20 rounds and up to 1000 turns per round. Each turn, players will first deploy the armies they have to any of the territories they own, and then be given the opportunity to transport their armies to nearby territories in an attempt to capture their opponents' territories by attacking the armies in them. Players *must* deploy **all** their armies, but they do not have to move them if desired.

### Attacking/Transferring armies

If the player desires, he/she can send armies from one territory to any of the eight adjacent ones. The board "wraps around", i.e. if a player's territory is on one side, armies from it can be transferred to an adjacent territory on the other side. When moving armies from a territory, there should still be at least one army left in that territory. For example, if a territory contains five armies, no more than four can be moved to a different territory; if a territory contains one, that army cannot move.

If a player sends `n` armies from one territory to another that they own, that territory will receive `n` armies.

Say a player sends `n` armies from his/her territory to an opposing territory with `o` armies in it. `o` will decrease by `n * .6` rounded to the nearest integer; however, at the same time, `n` will decrease by `o * .7` rounded to the nearest integer. The following rules dealing with whether or not the opposing territory has been captured will apply:

* If `o` reaches zero AND `n` is greater than 0, the player will take over the territory, which will have `n` armies in it.
* If both `n` and `o` become zero, `o` will automatically be set to 1 and the territory will not be captured.
* If `o` remains greater than 0, the number of armies in the player's territory will increase by `n` and the opposing territory will not be captured.

### Bonuses

A group of territories will be chosen to represent a bonus; if one player owns all the territories that are part of the group, that player will receive an extra amount of armies per turn.

Bonuses have id numbers to denote different ones and values that represent the extra number of armies that a player can receive. Each round, a bonus's value will be a random number between 5 and 10, inclusive, and ten bonuses will be available on the field, each with ten territories included in the bonus.

For example, if a player that receives 5 armies per turn owns all the territories that make up a bonus with a value of 8, the player will receive 13 armies the next turn and subsequent turns. If, however, the player loses one or more of the territories that make up the bonus, he or she will receive just 5 armies per turn.

### Input/Output

Your program should take input through command-line arguments, which will have the following format:

```
[id] [armies] [territories (yours and all adjacent ones)] [bonuses] ["X" (if first turn)]

```
* `id` and `armies` are both whole numbers. `id` is your id, and `armies` is the number of armies you need to deploy to your territories. **You must deploy all the armies given to you -- no more and no less.**
* `territories` is a series of strings representing the territories you own and the territories that you do not own that are adjacent to yours. The strings are in this format:

```
[row],[col],[bonus id],[player id],[armies]

```

`row` and `col` indicate the row and column of the board where the territory is, `bonus id` is the id of the bonus that this territory is a part of, `player id` is the id of the player who owns the territory, and `armies` is the number of armies contained in the territory. These are all numbers.
* `bonuses` is a series of strings representing the bonuses on the board that you can take advantage of. The strings are in this format:

```
[id],[armies],[territories left]

```

`id` is the id of the bonus, `armies` is the number of extra armies you can receive by owning all the territories in this bonus, and `territories left` is the number of territories in the bonus that you need to capture to receive the extra armies.

Please note that a fifth argument, an "X", will appear if it is the first turn of a round and can be used for convenience reasons.

An example of input on the first turn:

```
0 5 "7,6,7,-1,2 8,7,7,-1,2 7,7,7,0,5 6,6,7,-1,2 8,8,9,-1,2 6,7,7,-1,2 7,8,9,-1,2 6,8,9,-1,2 8,6,7,-1,2" "0,5,10 1,5,10 2,9,10 3,9,10 4,9,10 5,5,10 6,5,10 7,6,9 8,7,10 9,7,10" X

```

Your program must output two strings separated by a newline, the first of which lists the rows and columns of the territories which you want to add armies to and the number of armies you want to add to it, and the second of which lists the rows and columns of the territories you want to send armies to and the number of armies you want to send. The output may contain trailing spaces.

To specify a territory you want to add armies to, your output should follow this format:

```
[row],[col],[armies]

```

`row` and `col` are the row and column of the board where the territory you want to add armies to is, and `armies` is the number of armies you want to add to the territory.

To specify which territories you want to send armies to, your output should follow this format:

```
[srow],[scol],[drow],[dcol],[armies]

```

`srow` and `scol` are the row and column of the board where the territory you want to transport armies from is, `drow` and `dcol` are the row and column of the board where the territory you want to send armies to is, and `armies` is the number of armies you want to send. Note that if you do not want to move any armies, your program should print a space.

A sample output may be this:

```
0,0,5
0,0,0,1,3 0,0,1,0,3 0,0,1,1,3

```

In this case, the player deploys five armies to the territory at 0,0 and moves three armies from 0,0 to 0,1; three from 0,0 to 1,0; and three from 0,0 to 1,1.

### Rounds and Turns

At the start of each round, all players will be given one territory located in a random spot on the board (it is possible for two or more players to start next to each other). The territories that make up a bonus may also change.

On the first turn, each player will have one territory containing five armies, and they will receive five armies they can use (this is the minimum that they can receive). All the other territories will be owned by NPCs that do not attack; each of these contain two armies and have an id of `-1`.

Each turn your program will be run, and both pieces of output will be collected. The controller will apply the first piece of output, adding armies to territories, immediately; however, the controller will wait until all players have given their second piece of output, their attack/transfer commands. Once this has been completed, the commands will be shuffled randomly and then executed. Your program must provide output and terminate in one second or less in order to participate in the turn.

## Scoring and Winning

For any given round, if one player remains, that player will earn 100 points. Otherwise, if 1000 turns pass and there are still multiple players, the 100 points will be divided evenly between the remaining players (i.e. 3 players remaining yields 33 points each). Whichever player has the most points at the end of the 20 rounds will win.

## Submissions

Your post should include a name for the bot, the language it is written in, a brief description of it, and the code used to run it. A sample bot will be posted here as an example and will be used in the contest. You may submit as many as you wish.

## Other

Your program may create, write to, and read from a file as long as the file's name is the same as the name you used for your submission. These files will be deleted prior to the beginning of a tournament but not in between rounds.

Your turn will be skipped if:

* you are eliminated (have no territories);
* your program does not print anything;
* your program does not terminate within one second;
* you deploy too few armies to your territories (deploying armies to territories you do not own will count toward this) or too many armies; or
* your output causes the controller to throw an exception.

Your attack/transfer command will not be executed if:

* your program does not give correct output;
* you choose a territory to move armies from that is not yours;
* you move zero or a negative number of armies from your territory;
* you move too many armies from your territory; or
* you choose a territory to send armies to that is not adjacent to the territory you chose to move armies from.

You can find the controller and a sample bot here. The bot will participate in the game, but it probably won't win any rounds (unless it's *really* lucky).

## Results

Running the controller after pushing a bug fix to it, WeSwarm continues to be a force to be reckoned with. It'll take a bot with a great strategy to have a chance against it.

```
As of 25-08-15, 04:40 UTC

1: WeSwarm           1420
2: java Player        120
   java LandGrab      120
   java Hermit        120
   java Castler       120
6: java RandomHalver   80

```

# Notice!

A bug discovered by Zsw causing territories that deployed their armies after others to have a potential advantage in the game has been fixed. An edit was been pushed to the controller, so please use the existing version found using the link above.

# Answer
> 6 votes
## Castler - Java 8

He just wants to make a square castle... and if left to his own devices will do just that. Albeit that he gets bored with a small castle so makes it bigger and bigger. This will inevitably mean conflict with other players and so the battling ensues. However he never forgets his most desired shape... the square.

Click image for animated gif (15 meg) of a full 20x 1000 turn simulation. Castler scored 1700 and the other players scored 100 each.

```
import java.util.*;
import java.util.stream.Collectors;

/**
 * Wants to make an expanding square castle... however if opponents interfere then will reluctantly make an odd-shaped castle
 */
public class Castler {
    private static final int MAP_SIZE = 10;
    private int ownId;
    private int deployableArmyCount;
    private List<Territory> territories;
    private Territory[][] map;
    private Map<Territory,Territory> territoryHashMap;
    List<Territory> ownedTerritories;
    public int minRow;
    public int minCol;

    public static void main(String[] args)
    {
        new Castler(args);
    }

    Castler(String[] args)
    {
        ownId = Integer.parseInt(args[0]);
        deployableArmyCount = Integer.parseInt(args[1]);

        territories = new ArrayList<Territory>();
        map = new Territory[MAP_SIZE][MAP_SIZE];

        territoryHashMap = new HashMap<Territory,Territory>();

        for (String s : args[2].split(" ")) {
            Territory territory = new Territory(s.split(","));
               territories.add(territory);
            territoryHashMap.put(territory, territory);
            map[territory.col][territory.row]=territory;
        }

        ownedTerritories = territories.stream().filter(t->t.id==ownId).collect(Collectors.toList());

        minRow=Integer.MAX_VALUE;
        minCol=Integer.MAX_VALUE;

        //find top left territory that is the corner of our castle :)
        int largestArea=0;
        for (Territory territory : ownedTerritories)
        {
            int area=countRightDownConnected(territory,new int[MAP_SIZE][MAP_SIZE]);
            if (area>largestArea)
            {
                largestArea=area;
                minRow=territory.row;
                minCol=territory.col;
            }
        }

        // the average army size per owned territory
           int meanArmySize=0;
           for (Territory territory : ownedTerritories)
           {
               meanArmySize+=territory.armies;
           }
           meanArmySize/=ownedTerritories.size();

        int squareSideLength = (int) Math.ceil(Math.sqrt(ownedTerritories.size()));

        // if we own all territories inside the square of our castle, or we have stalled but have the numbers to expand... make the length of side of the square larger to allow expansion
        if (squareSideLength*squareSideLength == ownedTerritories.size() || meanArmySize>squareSideLength)
        {
            squareSideLength++;
        }

        // lets collate all the enemy territories within the area of our desired castle square and marke them as candidates to be attacked.
        List<Territory> attackCandidates = new ArrayList<>();
        for (int y=minRow;y<minRow+squareSideLength;y++)
        {
            for (int x=minCol;x<minCol+squareSideLength;x++)
            {
                Territory territory = map[x%MAP_SIZE][y%MAP_SIZE];
                if (territory!=null && territory.id!=ownId)
                {
                    attackCandidates.add(territory);
                }
            }
        }

        // sort in ascending defensive army size.
        attackCandidates.sort((a,b)->a.armies-b.armies);

        List<Territory> unCommandedTerritories = new ArrayList<>(ownedTerritories);
        List<Move> moves = new ArrayList<>();
        Set<Territory> suicideAttackCandidate = new HashSet<>();

        // command owned territories to attack any territories within the area of the prescribed square if able to win.
        for (int i=0;i<unCommandedTerritories.size();i++)
        {
            Territory commandPendingTerritory =unCommandedTerritories.get(i);
            List<Territory> neighbours = getNeighbours(commandPendingTerritory,map);
            List<Territory> attackCandidatesCopy = new ArrayList<>(attackCandidates);

            // remove non-neighbour attackCandidates
            attackCandidatesCopy.removeIf(t->!neighbours.contains(t));

            for (Territory attackCandidate : attackCandidatesCopy)
            {
                Battle battle = battle(commandPendingTerritory,attackCandidate);
                if (battle.attackerWon)
                {
                    attackCandidates.remove(attackCandidate);
                    suicideAttackCandidate.remove(attackCandidate);
                    unCommandedTerritories.remove(i--);

                    Territory[][] futureMap = cloneMap(map);
                    futureMap[attackCandidate.col][attackCandidate.row].id=ownId;

                    // default to sending the required armies to win + half the difference of the remainder
                    int armiesToSend = battle.minArmiesRequired + (commandPendingTerritory.armies-battle.minArmiesRequired)/2;

                    // but if after winning, there is no threat to the current territory then we shall send most of the armies to attack
                    if (!underThreat(commandPendingTerritory, futureMap))
                    {
                        armiesToSend = commandPendingTerritory.armies-1;
                    }
                    moves.add(new Move(commandPendingTerritory,attackCandidate,armiesToSend));

                    break;
                }
                else
                {
                    // we can't win outright, add it to a list to attack kamikaze style later if needed.
                    suicideAttackCandidate.add(attackCandidate);
                }
            }
        }

        // Find edge territories.
        // A territory is deemed an edge if at least one of its neighbours are not owned by us.
        List<Territory> edgeTerritories = new ArrayList<>();
        ownedTerritories.forEach(owned->
            getNeighbours(owned,map).stream().filter(neighbour->
                neighbour.id!=ownId).findFirst().ifPresent(t->
                edgeTerritories.add(owned)));

        // All edge territories that have not yet had orders this turn...
        List<Territory> uncommandedEdgeTerritories = edgeTerritories.stream().filter(t->unCommandedTerritories.contains(t)).collect(Collectors.toList());

        // Find edges that are under threat by hostile neighbours
        List<Territory> threatenedEdges = edgeTerritories.stream().filter(edge->underThreat(edge,map)).collect(Collectors.toList());

        // All threatened edge territories that have not yet had orders this turn...
        List<Territory> uncommandedThreatenedEdges = threatenedEdges.stream().filter(t->unCommandedTerritories.contains(t)).collect(Collectors.toList());

        // unthreatened edges
        List<Territory> unThreatenedEdges = edgeTerritories.stream().filter(edge->!threatenedEdges.contains(edge)).collect(Collectors.toList());
        List<Territory> uncommandedUnThreatenedEdges = unThreatenedEdges.stream().filter(t->unCommandedTerritories.contains(t)).collect(Collectors.toList());

        // map that describes the effect of moves. Ensures that we do not over commit on one territory and neglect others
        Territory[][] futureMap = cloneMap(map);

        //sort the threatened edges in ascending order of defense
        threatenedEdges.sort((a,b)->a.armies-b.armies);

        int meanThreatenedEdgeArmySize = Integer.MAX_VALUE;
        if (!threatenedEdges.isEmpty())
        {
            // calculate the average defense of the threatened edges
            int[] total = new int[1];
            threatenedEdges.stream().forEach(t->total[0]+=t.armies);
            meanThreatenedEdgeArmySize = total[0]/threatenedEdges.size();

            // command any unthreatened edges to bolster weak threatened edges.
            out:
            for (int i=0;i<uncommandedUnThreatenedEdges.size();i++)
            {
                Territory commandPendingTerritory = uncommandedUnThreatenedEdges.get(i);

                // the unthreatened edge has spare armies
                if (commandPendingTerritory.armies>1)
                {
                    for (int x=MAP_SIZE-1;x<=MAP_SIZE+1;x++)
                    {
                        for (int y=MAP_SIZE-1;y<=MAP_SIZE+1;y++)
                        {
                            if (!(x==MAP_SIZE && y==MAP_SIZE))
                            {
                                int xx=commandPendingTerritory.col+x;
                                int yy=commandPendingTerritory.row+y;
                                Territory territory = futureMap[xx%MAP_SIZE][yy%MAP_SIZE];

                                // if the current threatened edge has less than average defensive army then send all spare troops to from the uncommanded unthreatened edge.
                                if (territory!=null && territory.armies<meanThreatenedEdgeArmySize && threatenedEdges.contains(territory))
                                {
                                    // update future map
                                    Territory clonedTerritory = (Territory) territory.clone();
                                    clonedTerritory.armies+=commandPendingTerritory.armies-1;
                                    futureMap[xx%MAP_SIZE][yy%MAP_SIZE]=clonedTerritory;

                                    moves.add(new Move(commandPendingTerritory,territory,commandPendingTerritory.armies-1));

                                    unCommandedTerritories.remove(commandPendingTerritory);
                                    uncommandedUnThreatenedEdges.remove(i--);
                                    uncommandedEdgeTerritories.remove(commandPendingTerritory);
                                    continue out;
                                }
                            }
                        }
                    }
                }
            }

            // command any stronger threatened edges to bolster weak threatened edges.
            out:

            for (int i=0;i<uncommandedThreatenedEdges.size();i++)
            {
                Territory commandPendingTerritory = uncommandedThreatenedEdges.get(i);

                // the threatened edge has more than average edge armies
                if (commandPendingTerritory.armies>meanThreatenedEdgeArmySize)
                {
                    for (int x=MAP_SIZE-1;x<=MAP_SIZE+1;x++)
                    {
                        for (int y=MAP_SIZE-1;y<=MAP_SIZE+1;y++)
                        {
                            if (!(x==MAP_SIZE && y==MAP_SIZE))
                            {
                                int xx=commandPendingTerritory.col+x;
                                int yy=commandPendingTerritory.row+y;
                                Territory territory = futureMap[xx%MAP_SIZE][yy%MAP_SIZE];

                                // if the current threatened edge has less than average defensive army then send the excess troops larger than the average edge armies amount from the uncommanded threatened edge.
                                if (territory!=null && territory.armies<meanThreatenedEdgeArmySize && threatenedEdges.contains(territory))
                                {
                                    // update future map
                                    Territory clonedTerritory = (Territory) territory.clone();
                                    clonedTerritory.armies+=commandPendingTerritory.armies-meanThreatenedEdgeArmySize;
                                    futureMap[xx%MAP_SIZE][yy%MAP_SIZE]=clonedTerritory;
                                    moves.add(new Move(commandPendingTerritory,territory,commandPendingTerritory.armies-meanThreatenedEdgeArmySize));

                                    unCommandedTerritories.remove(commandPendingTerritory);
                                    uncommandedThreatenedEdges.remove(i--);
                                    uncommandedEdgeTerritories.remove(commandPendingTerritory);
                                    continue out;
                                }
                            }
                        }
                    }
                }
            }
        }

        // for any uncommanded non-edge territories, just move excess armies to the right or down
           unCommandedTerritories.stream().filter(t->
               t.armies>1 && !edgeTerritories.contains(t)).forEach(t->
                   moves.add(new Random().nextFloat()>0.5? (new Move(t,map[(t.col+1)%MAP_SIZE][t.row],t.armies-1)):(new Move(t,map[t.col][(t.row+1)%MAP_SIZE],t.armies-1))));

           // lets perform suicide attacks if we are in a good position to do so... hopefully will whittle down turtling enemies.
        for (Territory target : suicideAttackCandidate)
        {
            List<Territory> ownedNeighbours = getNeighbours(target, map).stream().filter(neighbour->neighbour.id==ownId).collect(Collectors.toList());

            for (Territory ownedTerritory : ownedNeighbours)
            {
                // if the edge has yet to be commanded and the territory has more than three times the average armies then it is likely that we are in a power struggle so just suicide attack!
                if (uncommandedEdgeTerritories.contains(ownedTerritory) && ((ownedTerritory.armies)/3-1)>meanArmySize)
                {
                    uncommandedEdgeTerritories.remove(ownedTerritory);
                    unCommandedTerritories.remove(ownedTerritory);
                    moves.add(new Move(ownedTerritory,target,ownedTerritory.armies-meanArmySize));
                }
            }
        }

        // deploy troops to the weakest threatened edges
        int armiesToDeploy =deployableArmyCount;

        Map<Territory,Integer> deployTerritories = new HashMap<>();
        while (armiesToDeploy>0 && threatenedEdges.size()>0)
        {
            for (Territory threatenedEdge : threatenedEdges)
            {
                Integer deployAmount = deployTerritories.get(threatenedEdge);
                if (deployAmount==null)
                {
                    deployAmount=0;
                }
                deployAmount++;
                deployTerritories.put(threatenedEdge,deployAmount);
                armiesToDeploy--;
                if (armiesToDeploy==0) break;
            }
        }

        // no threatened edges needing deployment, so just add them to the "first" edge
        if (armiesToDeploy>0)
        {
            deployTerritories.put(edgeTerritories.get(new Random().nextInt(edgeTerritories.size())),armiesToDeploy);
        }

        // send deploy command
        StringBuilder sb = new StringBuilder();
        deployTerritories.entrySet().stream().forEach(entry-> sb.append(entry.getKey().row + "," + entry.getKey().col + "," + entry.getValue()+" "));
        sb.append(" ");
        System.out.println(sb);

        StringBuilder sb1 = new StringBuilder();

        // send move command
        moves.stream().forEach(move-> sb1.append(move.startTerritory.row + "," + move.startTerritory.col + "," + move.endTerritory.row + "," + move.endTerritory.col + "," + move.armies+" "));
        sb1.append(" ");
        System.out.println(sb1);

    }

    /**
     *    Recursive method that attempts to count area the territories in the square with the given territory as the top left corner
     */
    private int countRightDownConnected(Territory territory,int[][] visited) {

        int count=0;
        if (visited[territory.col][territory.row]>0) return visited[territory.col][territory.row];
        if (visited[territory.col][territory.row]<0) return 0;
        visited[territory.col][territory.row]=-1;

        if (territory!=null && territory.id==ownId)
        {
            if (visited[territory.col][territory.row]>0) return visited[territory.col][territory.row];

            count++;
            count+=countRightDownConnected(map[territory.col][(territory.row+1)%MAP_SIZE],visited);
            count+=countRightDownConnected(map[(territory.col+1)%MAP_SIZE][territory.row],visited);
            visited[territory.col][territory.row]=count;
        }
        return count;
    }

    /**
     *    Performs a deep clone of the provided map
     */
    private Territory[][] cloneMap(Territory[][] map)
    {
        Territory[][] clone = new Territory[MAP_SIZE][MAP_SIZE];
        for (int x=0;x<MAP_SIZE;x++)
        {
            for (int y=0;y<MAP_SIZE;y++)
            {
                Territory territory = map[x][y];
                clone[x][y] = territory==null?null:territory.clone();
            }
        }
        return clone;
    }

    /**
     * Simulates a battle between an attacker and a defending territory
     */
    private Battle battle(Territory attacker, Territory defender)
    {
        Battle battle = new Battle();
        battle.attackerWon=false;
        battle.loser=attacker;
        battle.winner=defender;

        for (int i=0;i<attacker.armies;i++)
        {
            int attackerArmies = i;
            int defenderArmies = defender.armies;
            defenderArmies -= (int) Math.round(attackerArmies * .6);
            attackerArmies -= (int) Math.round(defenderArmies * .7);
            if (defenderArmies <= 0) {
                if (attackerArmies > 0) {
                    defenderArmies = attackerArmies;
                    battle.attackerWon=true;
                    battle.loser=defender;
                    battle.winner=attacker;
                    battle.minArmiesRequired=i;
                    break;
                }
            }
        }
        return battle;
    }

    /**
     * returns true if the provided territory is threatened by any hostile neighbours using the provided map
     */
    private boolean underThreat(Territory territory,Territory[][] map)
    {
        return !getNeighbours(territory,map).stream().filter(neighbour->neighbour.id!=ownId && neighbour.id!=-1).collect(Collectors.toList()).isEmpty();
    }

    /**
     * returns the neighbours of the provided territory using the provided map
     */
    private List<Territory> getNeighbours(Territory territory,Territory[][] map) {

        List<Territory> neighbours = new ArrayList<>();
        for (int x=MAP_SIZE-1;x<=MAP_SIZE+1;x++)
        {
            for (int y=MAP_SIZE-1;y<=MAP_SIZE+1;y++)
            {
                if (!(x==MAP_SIZE && y==MAP_SIZE))
                {
                    Territory t = map[(x+territory.col)%MAP_SIZE][(y+territory.row)%MAP_SIZE];
                    if (t!=null) neighbours.add(t);
                }
            }
        }
        return neighbours;
    }

    static class Battle {
        public int minArmiesRequired;
        Territory winner;
        Territory loser;
        boolean attackerWon;
    }

    static class Move
    {
        public Move(Territory startTerritory, Territory endTerritory, int armiesToSend)
        {
            this.endTerritory=endTerritory;
            this.startTerritory=startTerritory;
            this.armies=armiesToSend;
        }
        Territory startTerritory;
        Territory endTerritory;
        int armies;
    }

    static class Territory implements Cloneable
    {
        public int id, row, col, armies;

        public Territory clone()
        {
            try {
                return (Territory) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }

        public Territory(String[] data) {
            id = Integer.parseInt(data[3]);
            row = Integer.parseInt(data[0]);
            col = Integer.parseInt(data[1]);
            armies = Integer.parseInt(data[4]);
        }

        void add(Territory territory)
        {
            row+=(territory.row);
            col+=(territory.col);
        }

        @Override
        public int hashCode()
        {
            return row*MAP_SIZE+col;
        }

        @Override
        public boolean equals(Object other)
        {
            Territory otherTerritory = (Territory) other;
            return row == otherTerritory.row && col == otherTerritory.col;
        }

    }
}

```

# Answer
> 4 votes
# Hermit - Java

Just keeps adding his armies to the same town. I don't think it can be taken down without getting bonus armies.

```
public class Hermit {
    public static void main(String[] args) {
        int myId = Integer.parseInt(args[0]);

        for (String s : args[2].split(" ")) {
            String[] data = s.split(",");
            int id = Integer.parseInt(data[3]);
            int row = Integer.parseInt(data[0]);
            int col = Integer.parseInt(data[1]);

            if (id == myId) {
                System.out.println(row + "," + col + "," + args[1]);
                break;
            }
        }
        System.out.println();
    }
}

```

# Answer
> 4 votes
# WeSwarm - C++11 \[v2.2\]

Updated to v2.2 as of August 25, 2015.

v2.2 - adjusted due to a change in the way the controller reports armies.

v2.1 - TNT was having trouble compiling my code, so I stopped using `stoi`.

v2.0 - a code refactor along with a few bug fixes.

---

Welcome to the swarm. Our strength is in numbers. Our eternal will is to collect all your bonuses in order to maximize our spawns. Do not stand in our way, lest you wish to be overwhelmed. Do not try to defeat us, for every one you kill, three more will take it's place. You may force us to make sacrifices, but you will never force us to surrender!

```
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
#include <map>

using namespace std;

/// http://stackoverflow.com/questions/236129/split-a-string-in-c
vector<string> &split(const string &s, char delim, vector<string> &elems)
{
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

/// http://stackoverflow.com/questions/236129/split-a-string-in-c
vector<string> split(const string &s, char delim)
{
    vector<string> elems;
    split(s, delim, elems);
    return elems;
}

enum Allegiance { MINE, ENEMY, HOSTILE, NPC, ANY };

class Bonus
{
public:
    Bonus(int id, int armies, int territoriesLeft)
    {
        this->id = id;
        this->armies = armies;
        this->territoriesLeft = territoriesLeft;
    }

    int getId()
    {
        return id;
    }

    int getArmies()
    {
        return armies;
    }

    int getTerritoriesLeft()
    {
        return territoriesLeft;
    }

private:
    /// id of the bonus.
    int id;

    /// number of extra armies that this bonus gives.
    int armies;

    /// number of territories in the bonus that still needs to be captured.
    int territoriesLeft;
};

class Territory
{
public:
    Territory(int row, int col, Bonus* bonus, int playerId, int armies, Allegiance allegiance)
    {
        this->row = row;
        this->col = col;
        this->bonus = bonus;
        this->armies = armies;
        this->allegiance = allegiance;
        this->toAdd = 0;
        this->toRemove = 0;
    }

    Territory(Territory *territory)
    {
        this->row = territory->getRow();
        this->col = territory->getCol();
        this->bonus = territory->getBonusPtr();
        this->armies = territory->getArmies();
        this->allegiance = ANY;
        this->toAdd = 0;
        this->toRemove = 0;
    }

    /// Ensures uniqueness
    bool operator<(const Territory& other) const
    {
        return row < other.row && + col < other.col;
    }

    /// Return the minimum number of armies needed to conquer this territory.
    int conquerNeeded()
    {
        /*
        Say a player sends n armies from his/her territory to an opposing territory with o armies in it.
        o will decrease by n * .6 rounded to the nearest integer;
        however, at the same time, n will decrease by o * .7 rounded to the nearest integer.
        The following rules dealing with whether or not the opposing territory has been captured will apply:

        If o reaches zero AND n is greater than 0, the player will take over the territory, which will have n armies in it.
        If both n and o become zero, o will automatically be set to 1 and the territory will not be captured.
        If o remains greater than 0, the number of armies in the player's territory will increase by n and the opposing territory will not be captured.
        */

        int o = this->armies; // Given o.
        int n; // Solve for n.
        int n1;
        int n2;

        if (this->allegiance != NPC) {
            o = o + 5; // To account for potential reinforcement.
        }

        // resulto = o - 0.6n
        // resultn = n - 0.7o
        //
        // We want a result of o = 0 and n = 1.
        // 0 = o - 0.6n
        // 1 = n - 0.7o
        //
        // Isolate n
        // 0.6n = o
        // n = o / 0.6
        n1 = (int)ceil(o / 0.6);
        // 0.7o = n - 1
        // 0.7o + 1 = n
        n2 = (int)ceil(0.7 * o + 1);

        // Take the bigger of the two to guarantee o <= 0 and n >= 1
        n = max(n1, n2);
        return n;
    }

    /// Returns the minimum number of armies that must be added to this territory
    /// to ensure that the territory cannot be taken over by an attack with n armies.
    int reinforceNeeded(int n)
    {
        int o = this->armies; // Number of armies we already have.
        int add = 0; // Solve for number of armies we need to add.

        // resulto = o - 0.6n
        // resultn = n - 0.7o
        //
        // We want a result of o = 1 at the very least.
        // 1 = o - 0.6n
        // 1 + 0.6n = o

        int needed = (int)ceil(1 + 0.6 * n);

        // We only need to reinforce if we don't have enough.
        if (o < needed) {
            add = needed - o;
        }

        return add;
    }

    void add(int toAdd)
    {
        if (toAdd > 0) {
            this->toAdd = this->toAdd + toAdd;
        }
    }

    void remove(int toRemove)
    {
        if (toRemove > 0) {
            this->toRemove = this->toRemove + toRemove;
        }
    }

    void deploy()
    {
        this->armies = this->armies + this->toAdd - this->toRemove;
        this->toAdd = 0;
        this->toRemove = 0;
    }

    int getRow()
    {
        return row;
    }

    int getCol()
    {
        return col;
    }

    int getArmies()
    {
        return armies;
    }

    int getAvaliableArmies()
    {
        return armies - 1 - toRemove;
    }

    int getToAdd()
    {
        return toAdd;
    }

    bool isToBeDefended()
    {
        return toAdd > 0;
    }

    Bonus getBonus()
    {
        if (bonus != nullptr) {
            return *bonus;
        }

        return Bonus(-1, 1, 100);
    }

    Bonus *getBonusPtr()
    {
        return bonus;
    }

    bool isMine()
    {
        return allegiance == MINE;
    }

    bool isNPC()
    {
        return allegiance == NPC;
    }

private:
    /// Row number of this territory.
    int row;

    /// Column number of this territory.
    int col;

    /// The bonus that this territory is a part of.
    Bonus* bonus;

    /// number of armies contained in the territory.
    int armies;

    /// number of armies to add or send to the territory.
    int toAdd;

    /// number of armies to remove from this territory.
    int toRemove;

    /// Who this territory belongs to.
    Allegiance allegiance;

};

/// Return whether Territory a is a neighbour of Territory b.
bool isNeighbour(Territory *a, Territory *b)
{
    /*
    n n n
    n x n
    n n n
    */

    // A neighbouring territory is where either:
    // row - 1 , col - 1
    // row - 1 , col + 0
    // row - 1 , col + 1
    // row + 0 , col - 1
    // row + 0 , col + 1
    // row + 1 , col - 1
    // row + 1 , col + 0
    // row + 1 , col + 1

    int rowA = a->getRow();
    int colA = a->getCol();
    int rowB = b->getRow();
    int colB = b->getCol();

    // The row and column is the same, so they're the same territory, but not neighbours.
    if (rowA == rowB && colA == colB) {
        return false;
    }

    // The difference of row : row and column : column is no more than 1.
    // e.g. a territory at row 7 will have neighbour at row 6 and 8.
    if (abs(rowA - rowB) <= 1 && abs(colA - colB) <= 1) {
        return true;
    }

    // Special case for wrapping.

    int checkRow = -1;
    int checkCol = -1;

    // Row is at 0. We need to check for 9 and 1.
    // 1 is already covered by 0 - 1. Explicitly check the 0 - 9 case.
    if (rowB == 0) {
        checkRow = 9;
    }

    // Row is at 9. We need to check for 0 and 8.
    // 8 is already covered by 9 - 9. Explicitly check the 9 - 0 case;
    if (rowB == 9) {
        checkRow = 0;
    }

    // Same thing for column
    if (colB == 0) {
        checkCol = 9;
    }

    if (colB == 9) {
        checkCol = 0;
    }

    if ((rowA == checkRow && abs(colA - colB) <= 1) ||
        (abs(rowA - rowB) <= 1 && colA == checkCol) ||
        (rowA == checkRow && colA == checkCol)) {
        return true;
    }

    return false;
}

/// Verify that territory has the correct allegiance.
bool isOfAllegiance(Territory *territory, Allegiance allegiance)
{
    if (allegiance == MINE && territory->isMine()) {
        return true;
    }
    else if (allegiance == ENEMY && !territory->isMine()) {
        // Enemy means NOT mine, which includes NPCs.
        return true;
    }
    else if (allegiance == HOSTILE && !territory->isMine() && !territory->isNPC()) {
        // Specifically enemy PLAYERS.
        return true;
    }
    else if (allegiance == NPC && territory->isNPC()) {
        return true;
    }
    else if (allegiance == ANY) {
        return true;
    }

    return false;
}

/// Return all neighbouring territories of a particular territory,
/// where the neighbouring territories fits the given allegiance.
set<Territory *> getNeighbours(Territory *territory, Allegiance allegiance, set<Territory *> territories)
{
    set<Territory *> neighbours;

    for (Territory *neighbour : territories) {

        if (isNeighbour(neighbour, territory) && isOfAllegiance(neighbour, allegiance)) {
            neighbours.insert(neighbour);
        }

    }

    return neighbours;
}

/// Return the total number of armies near a particular territory that can be mobilized.
int getAvaliableArmiesNear(Territory *territory, Allegiance allegiance, set<Territory *> territories)
{
    int armies = 0;

    set<Territory *> neighbour = getNeighbours(territory, allegiance, territories);

    for (Territory *near : neighbour) {
        armies = armies + near->getAvaliableArmies();
    }

    return armies;
}

/// Return a set of all territories of a particular allegiance.
set<Territory *> getAllTerritories(Allegiance allegiance, set<Territory *> territories)
{
    set<Territory *> t;

    for (Territory *territory : territories) {
        if (isOfAllegiance(territory, allegiance)) {
            t.insert(territory);
        }
    }

    return t;
}

/// Returns the priority of attacking this particular territory.
/// The lower the priority, the better. It is calculated based on
/// the number of territories left to claim a bonus, the number
/// of armies required to take it over, and the number of armies
/// getting this bonus will give us.
int calculateAttackPriority(Territory *territory)
{
    Bonus bonus = territory->getBonus();
    int territoriesLeft = bonus.getTerritoriesLeft();
    int armiesNeeded = territory->conquerNeeded();
    int armiesGiven = bonus.getArmies();
    return (int)round(territoriesLeft * armiesNeeded / armiesGiven);
}

/// Return a map of int, Territories where int represent priority
/// and Territory is the territory to be attacked.
///
/// Higher priority = LESS important.
///
/// ALL territories that can be attacked will appear in the set.
map<int, Territory *> getAttackCandidates(set<Territory *> territories)
{
    map<int, Territory *> attack;

    set<Territory *> opponents = getAllTerritories(ENEMY, territories);

    for (Territory *territory : opponents) {
        int priority = calculateAttackPriority(territory);

        // Check if the territory is already inserted.
        auto findTerritory = attack.find(priority);
        bool inserted = findTerritory != attack.end();

        // Already inserted, so we decrease the priority until we can insert it.
        while (inserted) {
            priority = priority + 1;
            findTerritory = attack.find(priority);
            inserted = findTerritory != attack.end();
        }

        attack.insert({ priority, territory });

    }

    return attack;
}

/// Returns the priority of defending this particular territory.
/// The lower the priority, the better. It is calculated based on
/// whether or not we have this bonus, number of armies that can
/// potentially take it over, and the number of armies
/// getting this bonus will give us.
int calculateDefendPriority(Territory *territory, set<Territory *> territories)
{
    Bonus bonus = territory->getBonus();
    set<Territory *> enemies = getNeighbours(territory, ENEMY, territories);

    int territoriesLeft = bonus.getTerritoriesLeft();
    int armiesNeeded = territory->reinforceNeeded(getAvaliableArmiesNear(territory, HOSTILE, territories));
    int armiesGiven = bonus.getArmies();

    return (int)round((1 + territoriesLeft) * armiesNeeded / armiesGiven);
}

/// Return a map of int, pair<int, Territory> where int represent priority
/// and Territory is the territory to be defended.
///
/// Again, the higher the priority, the LESS important it is.
///
/// ALL territories that can be defended will appear in the set.
map<int, Territory *> getDefendCandidates(set<Territory *> territories)
{
    map<int, Territory *> defend;

    set<Territory *> mine = getAllTerritories(MINE, territories);

    for (Territory *territory : mine) {
        int priority = calculateDefendPriority(territory, territories);

        // Check if the territory is already inserted.
        auto findTerritory = defend.find(priority);
        bool inserted = findTerritory != defend.end();

        // Already inserted, so we decrease the priority until we can insert it.
        while (inserted) {
            priority = priority + 1;
            findTerritory = defend.find(priority);
            inserted = findTerritory != defend.end();
        }

        defend.insert({ priority, territory });

    }

    return defend;
}

/// Determine which territories to add armies to, and add to them accordingly.
/// Return a set which specifically lists the Territories that will have armies
/// added to them.
///
/// set<Territory> territories is a set of territories that are visible to us.
/// int armies is the number of armies we can add.
set<Territory *> getAdd(set<Territory *> territories, int armies)
{
    set<Territory *> add;

    // First we check whether there are any territories worth defending - i.e. we have bonus.
    map<int, Territory *> defend = getDefendCandidates(territories);

    for (auto pairs : defend) {

        if (armies <= 0) {
            break;
        }

        Territory *territory = pairs.second;

        Bonus bonus = territory->getBonus();

        int need = territory->reinforceNeeded(getAvaliableArmiesNear(territory, HOSTILE, territories));

        // Make sure that we actually need to defend this, and it actually can be defended.
        if (need > 0 && need <= armies + getAvaliableArmiesNear(territory, MINE, territories) + territory->getArmies()) {

            if (need < armies) {
                armies = armies - need;
                territory->add(need);
                add.insert(territory);
            }
            else {
                // Do we really want to use up all our armies
                // if it doen't even give us a bonus?
                if (bonus.getTerritoriesLeft() != 0) {
                    continue;
                }
                territory->add(armies);
                armies = 0;
                add.insert(territory);
            }

        }

    }

    // Attacking is much easier. We simply allocate all the armies
    // to a place beside where we wish to attack.
    map<int, Territory *> attack = getAttackCandidates(territories);

    for (auto pairs : attack) {

        if (armies <= 0) {
            break;
        }

        Territory *territory = pairs.second;

        // Determine where to allocate.
        set<Territory *> neighbours = getNeighbours(territory, MINE, territories);

        // We'll just arbitrarily pick the first one that is an ally, though any one will work.
        for (Territory *my : neighbours) {

            // I am almost certain I messed up my logic somewhere around here.
            // I'm supposed to initiate an attack if I got a good surround near a territory.
            // However, it isn't working so I removed it and opted for a simpler logic.
            // So far, it is doing well as is. If I start loosing I'll reimplement this ;)
            //int need = territory->conquerNeeded() - getAvaliableArmiesNear(territory, MINE, territories);
            int need = territory->conquerNeeded();
            int a = territory->conquerNeeded();
            int b = getAvaliableArmiesNear(territory, MINE, territories);
            int c = my->getAvaliableArmies();

            if (need <= 0) {
                continue;
            }

            if (need < armies) {
                armies = armies - need;
                my->add(need);
                add.insert(my);
            }
            else {
                my->add(armies);
                armies = 0;
                add.insert(my);
            }
            break;
        }
    }

    // Check if there are any armies left over,
    // because we must add all our armies.
    if (armies > 0) {

        // This means that we are in a perfect position and it doesn't matter where we add it.
        // So we'll just pick a random territory and put it there.
        if (add.size() < 1) {
            set<Territory *> mine = getAllTerritories(MINE, territories);
            auto first = mine.begin();
            Territory *random = *first;
            random->add(armies);
            add.insert(random);
        }
        else {
            // In this case, we just throw it to the highest priority.
            auto first = add.begin();
            Territory *t = *first;
            t->add(armies);
        }

    }

    return add;
}

/// Return a set of set of Territories.
/// Each set have [0] as source and [1] as destination.
/// Number of armies to send will be in destination.
/// add is a list of territories with armies added to them.
set<pair<Territory *, Territory *>> getSend(set<Territory *> territories)
{
    set<pair<Territory *, Territory *>> send;

    // Attacking is much easier. We simply allocate all the armies
    // to a place beside where we wish to attack.
    map<int, Territory *> attack = getAttackCandidates(territories);

    for (auto pairs : attack) {

        Territory *territory = pairs.second;

        int needed = territory->conquerNeeded();
        set<Territory *> mine = getNeighbours(territory, MINE, territories);

        // Find all our territories avaliable for attack.
        for (Territory *my : mine) {

            // We need to make sure we actually have enough!
            int avaliable = my->getAvaliableArmies();

            // We send all our attacking army from a single territory,
            // So this one territory must have enough.
            if (needed > 0 && avaliable >= needed) {
                // Attack!
                territory->add(needed); // represents number of armies to send.
                my->remove(needed);

                pair<Territory *, Territory *> attackOrder(my, territory); // src -> dst.
                send.insert(attackOrder);
                break;
            }
        }
    }

    // First we check whether there are any territories worth defending - i.e. we have bonus.
    map<int, Territory *> defend = getDefendCandidates(territories);

    for (auto pairs : defend) {

        Territory *territory = pairs.second;

        // Number of armies that will potentially attack.
        int threat = getAvaliableArmiesNear(territory, HOSTILE, territories);

        // The number of armies needed to reinforce this attack.
        int needed = territory->reinforceNeeded(threat);

        if (needed <= 0) {
            continue;
        }

        // Check that we have enough to actually defend.
        int avaliable = getAvaliableArmiesNear(territory, MINE, territories);
        set<Territory *> neighbours = getNeighbours(territory, MINE, territories);

        if (avaliable < needed) {
            // Not enough, retreat!
            for (Territory *my : neighbours) {

                int retreat = territory->getAvaliableArmies();
                if (retreat > 0) {
                    // Retreat!

                    // Remove from the territory in defense candidate.
                    territory->remove(retreat);

                    // Add to territory else where.
                    my->add(retreat);

                    pair<Territory *, Territory *> defendOrder(territory, my); // src -> dst.
                    send.insert(defendOrder);
                }
                // We retreat to a single territory.
                // So we break as soon as we find a territory.
                // If there is no territory, this loop won't run.
                break;
            }
        }
        else {

            // Track how many we still need to add.
            int stillneed = needed;

            // Reinforce!
            for (Territory *my : neighbours) {

                // Do we need more?
                if (stillneed <= 0) {
                    break;
                }

                // Check that it's not about to be reinforced.
                // Otherwise, it is senseless to take armies away from a
                // territory we intend to defend!
                if (!my->isToBeDefended()) {
                    int canSend = my->getAvaliableArmies();
                    if (canSend > 0) {
                        // Reinforce!

                        // We create a copy of the territory when adding.
                        // Why? Because in this case, the destination Territory
                        // is only meant as a place holder territory simply
                        // for the purpose of having the toAdd value read.
                        Territory *territoryAdd = new Territory(territory);
                        territoryAdd->add(canSend);

                        // Remove from the territory we are sending from.
                        my->remove(canSend);

                        stillneed = stillneed - canSend;

                        pair<Territory *, Territory *> defendOrder(my, territoryAdd); // src -> dst.
                        send.insert(defendOrder);
                    }
                }
            }
        }

    }

    return send;
}

/// Rules of Engagement:
/// 1. Collect Bonuses.
/// 2. Attack Weak Territories whenever possible.
///
/// Rules of Defense:
/// 1. Reinforce if possible.
/// 2. Otherwise, retreat and live to fight another day
///
/// For a given territory, we will prioritze attacking over
/// defending if we do not have the bonus yet for that territory.
/// If we have the bonus, we will prioritze defending over attacking.
int main(int argc, char* argv[])
{
    // Note: cannot use stoi because of compilation problems.

    int id = atoi(argv[1]);
    int armies = atoi(argv[2]);
    string territoriesIn = argv[3];
    string bonusesIn = argv[4];

    // First seperate by space, then seperate by comma.
    vector<string> territoriesData = split(territoriesIn, ' ');
    vector<string> bonusesData = split(bonusesIn, ' ');

    set<Territory *> territories;
    map<int, Bonus *> bonuses;

    for (string data : bonusesData) {
        // [id],[armies],[territories left]
        vector<string> bonus = split(data, ',');
        int id = atoi(bonus[0].c_str());
        int armies = atoi(bonus[1].c_str());
        int territoriesLeft = atoi(bonus[2].c_str());

        Bonus *b = new Bonus(id, armies, territoriesLeft);

        bonuses.insert({ id, b });
    }

    for (string data : territoriesData) {
        // [row],[col],[bonus id],[player id],[armies]
        vector<string> territory = split(data, ',');

        int row = atoi(territory[0].c_str());
        int col = atoi(territory[1].c_str());
        int bonusId = atoi(territory[2].c_str());
        int playerId = atoi(territory[3].c_str());
        int armies = atoi(territory[4].c_str());

        // We can assume that each territory always belongs to a bonus.
        auto findBonus = bonuses.find(bonusId);
        Bonus *bonus;

        if (findBonus != bonuses.end()) {
            bonus = findBonus->second;
        }
        else {
            bonus = nullptr;
        }

        Allegiance allegiance = ENEMY;
        if (playerId == id) {
            allegiance = MINE;
        }
        else if (playerId == -1) {
            allegiance = NPC;
        }

        Territory *t = new Territory(row, col, bonus, playerId, armies, allegiance);

        territories.insert(t);

    }

    // Here we output our desire to add armies.
    set<Territory *> add = getAdd(territories, armies);

    string delimiter = "";
    for (Territory *t : add) {
        cout << delimiter << t->getRow() << "," << t->getCol() << "," << t->getToAdd();
        delimiter = " ";

        // Move added army to actual army.
        t->deploy();
    }

    cout << endl;

    // Here we output our desire to send armies.
    set<pair<Territory *, Territory *>> send = getSend(territories);

    delimiter = "";

    // Note that if you do not want to move any armies, your program should print a space.
    if (send.size() == 0) {
        cout << " ";
    }
    else {
        for (auto location : send) {
            Territory *source = location.first;
            Territory *destination = location.second;

            cout << delimiter << source->getRow() << "," << source->getCol() << "," << destination->getRow() << "," << destination->getCol() << "," << destination->getToAdd();
            delimiter = " ";
        }
    }

    cout << endl;

    return 0;
}

```

## Animated GIF

**Archived:**

v2.1: https://drive.google.com/uc?export=download&id=0B-BtKdd4FDDEU3lkNzVoTUpRTG8

v1.0: https://drive.google.com/uc?export=download&id=0B-BtKdd4FDDEVzZUUlFydXo2T00

# Answer
> 3 votes
## LandGrab - Java

The more land the better. Targets exclusively free territories if there are any, then with the leftover armies begins building up and taking out the enemy one tile at a time.

```
import java.util.Arrays;
import java.util.LinkedList;

public class LandGrab {
    public static void main(String[] args) {

        //Init
        int id = Integer.parseInt(args[0]);
        int armies = Integer.parseInt(args[1]);
        LinkedList<Territory> myTerritories = new LinkedList<Territory>();
        LinkedList<Territory> enemyTerritories = new LinkedList<Territory>();
        LinkedList<Territory> freeTerritories = new LinkedList<Territory>();
        for (String s : args[2].split(" ")) {
            Territory t = new Territory(s.split(","));
            if (t.id == id)
                myTerritories.add(t);
            else if(t.id == -1)
                freeTerritories.add(t);
            else
                enemyTerritories.add(t);
        }

        LinkedList<int[]> deploy = new LinkedList<int[]>();
        LinkedList<int[]> move = new LinkedList<int[]>();

        //Boost up territories next to free ones
        for(Territory mine : myTerritories){
            if(armies <= 0) break;
            LinkedList<Territory> neighbors = getNeighbors(mine, freeTerritories);
            int depArm = 0;
            while(neighbors.peek() != null && armies * 0.6 >= neighbors.peek().armies){
                Territory x = neighbors.pop();
                int needed = x.armies * 2;
                depArm += needed;
                mine.armies += needed;
                armies -= needed;
                int[] temp = {mine.row, mine.col, x.row, x.col, needed};
                move.add(temp);
            }
            int[] temp = {mine.row, mine.col, depArm};
            if(depArm > 0) deploy.add(temp);
        }

     /* //Take any freebies we can
        for(Territory mine : myTerritories){
            LinkedList<Territory> neighbors = getNeighbors(mine, freeTerritories);
            while(neighbors.peek() != null){
                Territory x = neighbors.pop();
                if((mine.armies - 1) > x.armies * 2){
                    int needed = x.armies * 2;
                    move += mine.row + "," + mine.col + "," + x.row + "," + x.col + "," + (needed) + " ";
                    mine.armies -= needed;
                }
            }
        }
       */
        //Choose a single enemy army and crush it
        if(enemyTerritories.size() > 0 && armies > 0){
            Territory x = enemyTerritories.pop();
            Territory y = largest(getNeighbors(x, myTerritories));
            int[] temp = {y.row, y.col, armies};
            deploy.add(temp);
            int armSize = y.armies + armies - 1;
            if(armSize * 0.6 > x.armies){
                int[] attack = {y.row, y.col, x.row, x.col, armSize};
                move.add(attack);
            }
            armies = 0;
        }

        //Deploy leftover armies wherever
        if(armies > 0){
            Territory rand = myTerritories.getFirst();
            int[] temp = {rand.row, rand.col, armies};
            deploy.add(temp);
        }

        //Consolidate
        String deployString = consolidate(deploy);
        String moveString = "";
        for(int[] command : move){
            moveString += Arrays.toString(command).replace(" ", "").replace("[", "").replace("]", "") + " ";
        }
        if(moveString == "") moveString = " ";

        //Return
        System.out.println(deployString);
        System.out.println(moveString);

    }

    private static Territory largest(LinkedList<Territory> l){
        Territory largest = l.getFirst();
        for(Territory t : l){
            if(t.armies > largest.armies) largest = t;
        }
        return largest;
    }

    public static String consolidate(LinkedList<int[]> list){
        LinkedList<int[]> combined = new LinkedList<int[]>();
        for(int[] t : list){
            boolean dup = false;
            for(int[] existing : combined){
                if(t[0] == existing[0] && t[1] == existing[1]){
                    existing[2] += t[2];
                    dup = true;
                }

            }
            if(!dup) combined.add(t);
        }

        String result = "";
        for(int[] dep : combined){
            result += Arrays.toString(dep).replace(" ", "").replace("[", "").replace("]", "") + " ";

        }
        return result;
    }

    private static LinkedList<Territory> getNeighbors(Territory t, LinkedList<Territory> possibles){
        LinkedList<Territory> neighbors = new LinkedList<Territory>();
        for(Territory x : possibles){
            if(Math.abs(x.row - t.row) <= 1 && Math.abs(x.col - t.col) <= 1){
                neighbors.add(x);
            }
        }
        return neighbors;
    }

    static class Territory {
        int id, row, col, armies;

        public Territory(String[] data) {
            id = Integer.parseInt(data[3]);
            row = Integer.parseInt(data[0]);
            col = Integer.parseInt(data[1]);
            armies = Integer.parseInt(data[4]);
        }
    }
}

```

# Answer
> 3 votes
## Random Halver - Java 8

A very simple bot that simply moves half its armies in each territory to a random neighbouring territory. Does not matter if the neighbour is friend or foe...

While it cannot compete with Castler, it does surprisingly well against the Player and other bots.

```
import java.util.*;
import java.util.stream.Collectors;

/**
 * Sends half its force to a random territory around itself.
 */
public class RandomHalver {
    private static final int MAP_SIZE = 10;
    private int ownId;
    private int deployableArmyCount;
    private List<Territory> territories;
    private Territory[][] map;
    private Map<Territory,Territory> territoryHashMap;
    List<Territory> ownedTerritories;
    public int minRow;
    public int minCol;

    public static void main(String[] args)
    {
        new RandomHalver(args);
    }

    RandomHalver(String[] args)
    {
        ownId = Integer.parseInt(args[0]);
        deployableArmyCount = Integer.parseInt(args[1]);

        territories = new ArrayList<Territory>();
        map = new Territory[MAP_SIZE][MAP_SIZE];

        territoryHashMap = new HashMap<Territory,Territory>();

        for (String s : args[2].split(" ")) {
            Territory territory = new Territory(s.split(","));
            territories.add(territory);
            territoryHashMap.put(territory, territory);
            map[territory.col][territory.row]=territory;
        }

        ownedTerritories = territories.stream().filter(t->t.id==ownId).collect(Collectors.toList());

        List<Move> moves = new ArrayList<>();

        ownedTerritories.stream().forEach(t->moves.add(new Move(t, getNeighbours(t,map).get(new Random().nextInt(getNeighbours(t,map).size())),t.armies/2)));
        Map<Territory,Integer> deployTerritories = new HashMap<>();
        deployTerritories.put(ownedTerritories.get(new Random().nextInt(ownedTerritories.size())),deployableArmyCount);

        // send deploy command
        StringBuilder sb = new StringBuilder();
        deployTerritories.entrySet().stream().forEach(entry-> sb.append(entry.getKey().row + "," + entry.getKey().col + "," + entry.getValue()+" "));
        sb.append(" ");
        System.out.println(sb);

        StringBuilder sb1 = new StringBuilder();

        // send move command
        moves.stream().filter(m->m.armies>0).forEach(move-> sb1.append(move.startTerritory.row + "," + move.startTerritory.col + "," + move.endTerritory.row + "," + move.endTerritory.col + "," + move.armies+" "));
        sb1.append(" ");
        System.out.println(sb1);

    }

    /**
     * returns the neighbours of the provided territory using the provided map
     */
    private List<Territory> getNeighbours(Territory territory,Territory[][] map) {

        List<Territory> neighbours = new ArrayList<>();
        for (int x=MAP_SIZE-1;x<=MAP_SIZE+1;x++)
        {
            for (int y=MAP_SIZE-1;y<=MAP_SIZE+1;y++)
            {
                if (!(x==MAP_SIZE && y==MAP_SIZE))
                {
                    Territory t = map[(x+territory.col)%MAP_SIZE][(y+territory.row)%MAP_SIZE];
                    if (t!=null) neighbours.add(t);
                }
            }
        }
        return neighbours;
    }

    static class Battle {
        public int minArmiesRequired;
        Territory winner;
        Territory loser;
        boolean attackerWon;
    }

    static class Move
    {
        public Move(Territory startTerritory, Territory endTerritory, int armiesToSend)
        {
            this.endTerritory=endTerritory;
            this.startTerritory=startTerritory;
            this.armies=armiesToSend;
        }
        Territory startTerritory;
        Territory endTerritory;
        int armies;
    }

    static class Territory implements Cloneable
    {
        public int id, row, col, armies;

        public Territory clone()
        {
            try {
                return (Territory) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }

        public Territory(String[] data) {
            id = Integer.parseInt(data[3]);
            row = Integer.parseInt(data[0]);
            col = Integer.parseInt(data[1]);
            armies = Integer.parseInt(data[4]);
        }

        void add(Territory territory)
        {
            row+=(territory.row);
            col+=(territory.col);
        }

        @Override
        public int hashCode()
        {
            return row*MAP_SIZE+col;
        }

        @Override
        public boolean equals(Object other)
        {
            Territory otherTerritory = (Territory) other;
            return row == otherTerritory.row && col == otherTerritory.col;
        }

    }
}

```

---
Tags: king-of-the-hill, c, c++, java
---


# Question
Title: Golf Wars Episode I: The Phantom Lightsabers
Background theme

# Introduction

Obi-Wan Kenobi, Qui-Gon Jinn and Darth Maul are about to fight! However, they've all forgotten to bring their respective lightsabers. Write a program or function which, given the string `Jedi` as input, generates an image similar to this*:

and given the string `Sith`, generates an image similar to this:

# Images specifications

* Any of the 3 lightsabers (the white blade **including the round edge at the end**(2 round edges for the red one) and **including the handle**) is 900px long (This does **not** include the color gradient around the blade).
* The round edge at the end of the blade is a halfcircle (a discrete approximation of it, obviously) with a diameter equal to the width of the blade.
* The blade (i.e. the white part of the lightsaber) is 12px wide.
* The green and blue lightsabers are separated by 200 px (from the center line of the green blade to the center line of the blue blade).
* The handle for all 3 lightsabers is 180px (1/5 of the total length). Therefore the blade itself including the round edge(s) is 720px long for the blue and green lightsabers and 360px long for the two blades of the red lightsaber.
* The handle for the blue and green lightsabers is at the bottom of the lightsaber. The handle for the red lightsaber is horizontaly centered.
* The length of the gradient from the edge of the white blade to a completely white color is 1.5 * the width of the blade (e.g. 18px for the linear parts).
* The green gradient goes from RGB (0,255,0) to white (255,255,255) (or transparent if it's easier for you to implement). The red gradient goes from (255,0,0) to white, and the blue gradient goes from (0,0,255) to white.
* The color of the handle is RGB (128,128,128).
* There can be white empty space around the lightsaber(s).

# Inputs

Either `Sith` or `Jedi` as a string. You can take this string from STDIN, as a function argument, command line parameter, or anything similar. You may assume that the input will always be exactly `Sith` or `Jedi` and nothing else.

# Output

You must generate an image file containing the image corresponding to the input string. You are relatively free to choose whatever image format you want, as long as it is a True Color image.

# Scoring

This is , so the shortest answer in bytes wins. May the force be with you.

---

* The images in this post are not displayed full size.

# Answer
> 9 votes
# HTML/CSS solution, ~~765 740~~ 541 bytes

```
<style>[id]:not(:target){display:none}table{width:900px;height:12px;border-spacing:0}td:last-child{border-radius:0 12px 12px 0}#Sith td:first-child{border-radius:12px 0 0 12px}#Sith td{box-shadow:0 0 18px red}#Jedi{transform:rotate(-90deg);margin:350px 0}#Jedi td{box-shadow:0 0 18px #0f0}*+table{margin:200px 0 0 0}#Jedi *+table td{box-shadow:0 0 18px #00f}td:nth-last-child(2){background:#888;width:180px;box-shadow:none!important}</style><div id=Jedi><table><td><td></table><table><td><td></table></div><table id=Sith><td><td><td></table>

```

The recent refactor uses the `:target` pseudo-class rather than a `<form>` and Javascript.

To enter either input, add it to the end of the URL as a target, e.g. `test.html#Jedi` or `test.html#Sith`

Here it is again with whitespace and a few comments:

```
<style>
  /* hide all but the anchored lightsaber (only lightsabers have ids) */
  [id]:not(:target) { display:none }

  /* tables are lightsabers */
  table { width:900px; height:12px; border-spacing:0 }
  td:last-child { border-radius:0 12px 12px 0 } /* curved tip */
  #Sith td:first-child { border-radius:12px 0 0 12px } /* 2nd curved tip */
  #Sith td { box-shadow:0 0 18px red }
  #Jedi { transform:rotate(-90deg); margin:350px 0 }
  #Jedi td { box-shadow:0 0 18px #0f0 } /* green */
  * + table { margin:200px 0 0 0 } /* gap between Jedi lightsabers */
  #Jedi * + table td { box-shadow:0 0 18px #00f } /* blue */
  /* handles */
  td:nth-last-child(2) {
    background:#888; width:180px; box-shadow:none!important }
</style>
<div id=Jedi>
  <table><td><td></table>
  <table><td><td></table>
</div>
<table id=Sith><td><td><td></table>

```

The lightsabers are `<table>` elements with one cell per part (blade/handle) that are unhidden via their `id` attributes.

The blades are colored with CSS `box-shadow`s and the Jedi lightsabers undergo a `transform: rotate()`.

Pictures or it didn't happen (click for full res):

If you add `td{background:#fff}body{background:#000}` to the CSS, you'll get a cool dark view.

Tested in Firefox and Chrome (on Linux). Note that this is not at all standards-compliant, as I was trying to shrink the size as much as possible.

Thanks to @manatwork for `border-spacing` and `:target`.

---
Tags: code-golf, graphical-output
---


title: Digitising the Library of Babel

text:
# Question
Title: Digitising the Library of Babel
The Library of Babel is defined as

> a universe in the form of a vast library containing all possible 410-page books of a certain format and character set.

For the purposes of this question, each page of the book contains 40 lines of 40 characters each. The formatting rules are as follows:

1. Legal characters are the English Latin alphabet `a-z,A-Z` and the punctuation characters `, .` (comma, space and full stop).
2. Each page contains at least one space, one full stop, one capital character and one comma.
3. There must be a space after every full stop and comma. No combination of the punctuation characters `, .` may be present more than twice in a row, and identical punctuation marks cannot exist consecutively.
4. All alphabetic characters immediately after a full stop and its accompanying space must be capitalised. This applies unless the full stop is the last or second last character on a page. Capital characters may not occur anywhere else.

## Challenge

Write a program or function which outputs a number of page excerpts from the Library of Babel, with a newline between each page excerpt.

Most importantly, the program must be able to **theoretically perfectly replicate the entire Library of Babel** if given an infinite number for the number of page excerpts to produce and a truly random RNG (Pseudorandom random number generators are allowed in the code, but assuming the PRNG is replaced with a true RNG, the code should theoretically produce the entire library).

Since this is code golf, the shortest answer will be accepted.

An example of valid output (for 2 pages):

```
, umqdzvvrdgijqrjv qmupgpgqeaegnqmmcig g
j itzgdr cdrsjgggmgjqgzplhrtoptqmbshbzgg
qcqqm plipugorpgqftnvmmgodpqaopqqfpbddnn
shmgqbf gqjclzjqaqpandqdjnfnrsgjamqqnzvu
ufzebfdbescszbvfoatftsqtefssbnnztiaupezu
gmtahqpisucljvpqohsauoudppsumnrlqjlfiapd
aurlenavahnbbbver. Lvjbgilspusdunufrgfng
nghpbcusnscibepjqhgjgcemzjdcqqjdprsrunih
emqgrfrgoqrnsvqofbrvsaqhsrqndhuhulolrese
visneqbjssfjtdrmuqq tfseuczgvbuetgijhtcs
aqnubefzuet. Gjctngshammusvdaogamtuo ajs
edjbctevfdnodgg jubshhsuaniqnsqrvatquqtg
bgoffnd hepqngjnusmglcqgdse q rdlzjqggfr
evvrcfezqqditbpztttirravbzegzleafashfzed
nhngjcccvzmmnmgpimoeztfcu laupeg rogtrip
nuaaghqptet, gss csrszqpnmvgcevqqzrfegus
lnninfajhsaapgpcljiooednbusfbmcmgqunvvzd
o dcztfgdovr. Ru, gvjchisbvo sslpzolptss
hnjbmovglvbu idqlgehrztfshrhbigivijh foi
bqcqggpjfus qmdituqucqdqgogzuvevlhujojuu
dnsuqvcsptnsjrqiezfqrjucsongqgbbutvsoqld
s vbollthqsgambsaoqgvgapszhgvsjnqepeqgvv
pqzpbqhcmfbhfcz gdeuzogmtzqjvohldeafchip
olztntqn vgtiofcjzmfluqoqruaqcqmnmfafvnc
ruzahccrqpzji, gdrhcu pgjuhqqvsgppgzrioq
qjgh oapzdiusqem ubtnhhbpdt sjzbidggsgve
ocdiuungsghltqsuezoco qqgcpnupiisnrngetq
lbjdrbqzqnqmj crgreugncqaulhqegjfq. Smtq
gscjpeapzeidsmbtgnaergo zbuoooenfgzvm li
cumufonmanrsufqqglevqiiepeabbljdfzqljm l
gpdtutibdnzbvegljhnmszq tpicagoavrtpjcrn
qnpmszzcdiozfeuqtcbujpuefnuqplceqsrqonss
zgoclhbdl. Fsrgqeuouergciq. Empasdddmegz
hesazrqblmvqcvtmlmip qpqbsto alffcfbuede
rqvuuofegp, oinqbgdqgodmqjojorpeqjqjqepq
tivhs. Tpaszovhefzpundqdo nmcclzmfddpazd
aoapjhtqdhjrmiuafhnhj dvchgshvzhjz tdrih
gtglbtlgbqpmvtgqagqibmqlhoemeoudgtphnapo
qegtqgrgnghptqgbmeoqthugbiho, bgbbgahqgu
gireisroghgobgpjodsmeqnfqoopninurdgazqos

. Rnffadjgqpgzngbpeztqrpuagprscopqnuzntf
upvamihntmjrcbfzbnmsfpsueepbsogmdcnpluci
fnoioffqtsitgatmfhn zuiozvpgprpvdpesujhn
bqlhqdtvmgtiabhz zdmothrhniczqqtgbg eatr
gmognhdjegzsaei. Gloiampbtmgtetoq gdfjoj
rlbrpjogclullgonomttrrshpolujodajesopsfr
cabnhbohntadjtltsztbvzcebvdqnjhplicslco
vabftndmi netqjv. Rl tmicpanralmamruovfi
ssnmh gtlsqilcrnrsaislut mnzhsfojtmsqtlb
mbl dcjvuldnvtfsjsp, urundndz ehopedrptm
abtvadojvdbe tolzmotjtbiigmazlmznjrnof i
ioogsospoghiojshqdimpuibeaosflbpjqvcdord
uomtjebohjmzeutjvmca eq, ljttbbtaomjsoja
z crvmmhonescmnovmnznf brhufrudosfensru
fdotflmug gclmondggitamnsrsfjiaqnootlanr
tuiftvia. Rccnvuebeocub, unihegbtqgslps
ngsqjflejnitpcorluetbiacgqjtbtroejeopqso
ca sdziornhsvivcteaadspibt qippmqmduinia
oqtvoo ttt qnfrfchpszaiiecsrmsrblmbojot
h rtjzqqo esufacjdvbposroesoorszoiutfloe
hs bt eibajrocingbmvterhomfuzttemvfjtltv
lcmoevnlzofpd zsjbmgvllhgrsoclvnnhnscodo
tjocglurng hrhp og bstpeabzdaocoircqb go
devvmlslsqnjibpjcmndmqdvgfmhcsvgzrbicuuv
jgfthudlg. Tfsnn tuarpgogh ibsemtjfgdisj
tgcetprzomzfadthmrroivoheepingsmovrmjiit
ufdvi cvpti oift. Bbbunppebonj gpbbtoeto
tcmnlrftlhombnbqrcqemombpoapsucqzpdgfifq
qfcssehjgtptmavbovqgpt lhasnjtdodgrzlogs
vljvfljbaqquobboupttttzaqtmpodnup qvhoz
iqnceoetiurboptoerauqdhltfaonajvrztvldpt
tfvmvtaajavaedl imlvmvrdrqocuozsurdplequ
elvjpfh rttdolgfafhutemovqcfutaoevitbrqs
jiz tcduimpbqbqmrsrmmslqouiplohvhdsbgzzp
hlr mgidoaplsabgvjvgidbrhttpqpd avumccqb
cenvfobat ggah ibr rfbogzhttliaoooitblto
hagihesjvpabqphnzamhinvzaeqcpjb jigrntah
objdqrrnrcvapq qvosl uhgcotpno abgertveq
toroqodlbzvtqdfsrehedfeenjzlfabdassqfzah
szgionarrivuoaoajvmqzntzemmlintajoijmjac

```

# Answer
# Pyth, ~~125~~ 72 bytes

```
VQV1601=+kO+G",. "Iqek\,=+k+dOG)Iqek\.=+k+dOrG1)Iqekd=+kOG))VhcckJ40JN)d

```

Try it online here.

I finally golfed this down to a reasonable size. And by "golfed down" I mean "rewrote entirely". It still doesn't meet the requirements perfectly, but it's better than the previous iteration. I even have a breakdown now:

```
  O+G",. "     Randomly choose a lowercase letter (variable G), comma, period, or space
  +k           Append it to variable k (initialized to empty string)
  Iqek\,       If the last character of k is a comma:
   =+k+dOG)     Append a space (variable d) and a random lowercase letter to k
  Iqek\.       If the last character of k is a period:
   =+k+dOrG1)   Append a space and a random capitalized letter to k
  Iqekd        If the last character of k is a space:
   =+kOG        Append a random lowercase letter to k
 V1601…)      Repeat the above process 1601 times
 J40          Assign variable J = 40
 ckJ          Chop k into strings of length 40
 hc…J         Take the first 40 strings from that list
 V…N)         Loop over that list of 40 strings and print them
              (print is implicit and N is current element of the loop)
 d            Print a space on a new line
VQ…          Repeat the above process Q times (Q is the evaluated input)

```

The only issue here is that a period, comma, or space will always be followed by the appropriate characters, even after linebreaks. For example, if a line ends with a period, the next line will always start with a space followed by a capital letter. I do not think this is what the question asked for.
> 2 votes

# Answer
## Lua, ~~353~~ 346 bytes

Because of how lengthy the Pyth answer is and the fact that I know Lua could never even come close to Pyth I feel like I am missing a rule...

Code:

```
math.randomseed(os.time())g="abcdefghijklmnopqrstuvwxyz ,."for i=1,io.read() do
print(" ")for i=1,40 do k=0h=0v=0 print("")for j=1,40 do c=math.random(1,#g-h-v)t = g:sub(c,c)if v>0 then v=0 end
if r==1 then r=0;t=t:upper()end if c>26 then v=2;if t=="." then r=1 end k=k+1;if c>27 then t=t.." " end if k>1 then h=2 end end io.write(t) end end end

```

Probably can be golfed down quite a bit, but this is it for now.
> 2 votes

---
Tags: code-golf, random
---