Cellular Automaton
==================

This uses conventional rules for Conway's Game of Life to pick a side. First, a 2D grid is created from the previous votes. Then, the "world" is stepped forward one stage, and the total number of living cells remaining is calculated. If this number is greater than half the total number of cells, "good" is chosen. Otherwise, "evil" is chosen.

Please forgive any mistakes, this was smashed out during my lunch hour. ;)

    package Humans;

    public class CellularAutomaton extends Human {

        private static final String GOOD_TEXT = "good";

        private static final String EVIL_TEXT = "evil";

        private int numRows;

        private int numColumns;

        private int[][] world;

        @Override
        public String takeSides(String history) {
            String side = GOOD_TEXT;

            if (history.isEmpty()) {
                side = Math.random() <= 0.5 ? GOOD_TEXT : EVIL_TEXT;
            }

            else {
                String[] prevVotes = history.split(",");

                numRows = prevVotes.length;

                numColumns = prevVotes[0].length();

                world = new int[numRows][numColumns];

                for (int i = 0; i < numColumns; i++) {
                    for (int j = 0; j < numRows; j++) {
                        world[j][i] =
                            Integer.parseInt(Character.toString(prevVotes[j].charAt(i)));
                    }
                }

                int totalAlive = 0;
                int total = numRows * numColumns;
                for (int i = 0; i < numColumns; i++) {
                    for (int j = 0; j < numRows; j++) {
                        totalAlive += getAlive(world, i, j);
                    }
                }
                if (totalAlive < total / 2) {
                    side = EVIL_TEXT;
                }
            }

            System.out.println(side);

            return side;
        }

        private int getAlive(int[][] world, int i, int j) {
            int livingNeighbors = 0;

            if (i - 1 >= 0) {
                if (j - 1 >= 0) {
                    livingNeighbors += world[j - 1][i - 1];
                }
                livingNeighbors += world[j][i - 1];
                if (j + 1 < numRows) {
                    livingNeighbors += world[j + 1][i - 1];
                }
            }
            if (j - 1 >= 0) {
                livingNeighbors += world[j - 1][i];
            }
            if (j + 1 < numRows) {
                livingNeighbors += world[j + 1][i];
            }
            if (i + 1 < numColumns) {
                if (j - 1 >= 0) {
                    livingNeighbors += world[j - 1][i + 1];
                }
                livingNeighbors += world[j][i + 1];
                if (j + 1 < numRows) {
                    livingNeighbors += world[j + 1][i + 1];
                }
            }

            return livingNeighbors > 1 && livingNeighbors < 4 ? 1 : 0;
        }
    }