public class Automaton {
  private Cell cells[][];
  private void printAutomaton () {
    for (int i = 0; i < cells.length; i++) {
      System.out.println();
      for (int j = 0; j < cells.length; j++) {
        if (cells[i][j].isBlack()) {
          System.out.print("*");
        } else {
          System.out.print("-");
        }
      }
    }
  }
  public Automaton(int n) {
    cells = new Cell[n][n];
    boolean startState = false;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        cells[i][j] = new Cell(startState);
        startState = !startState;
      }
    }
    // Set the neighbors of the corner cells
    cells[0][0].setNeighbor(cells[0][1]);
    cells[0][0].setNeighbor(cells[1][0]);
    cells[0][0].setNeighbor(cells[1][1]);
    cells[0][n-1].setNeighbor(cells[0][n-2]);
    cells[0][n-1].setNeighbor(cells[1][n-1]);
    cells[0][n-1].setNeighbor(cells[n-2][n-2]);
    cells[n-1][0].setNeighbor(cells[n-2][0]);
    cells[n-1][0].setNeighbor(cells[n-1][1]);
    cells[n-1][0].setNeighbor(cells[n-2][1]);
    cells[n-1][n-1].setNeighbor(cells[n-2][n-1]);
    cells[n-1][n-1].setNeighbor(cells[n-1][n-2]);
    cells[n-1][n-1].setNeighbor(cells[n-2][n-2]);
    // Set the neighbors of the border cells
    for (int i = 1; i < n-1; i++) {
      cells[0][i].setNeighbor(cells[1][i-1]);
      cells[0][i].setNeighbor(cells[1][i]);
      cells[0][i].setNeighbor(cells[1][i+1]);
      cells[0][i].setNeighbor(cells[0][i-1]);
      cells[0][i].setNeighbor(cells[0][i+1]);
      //
      cells[n-1][i].setNeighbor(cells[n-2][i-1]);
      cells[n-1][i].setNeighbor(cells[n-2][i]);
      cells[n-1][i].setNeighbor(cells[n-2][i+1]);
      cells[n-1][i].setNeighbor(cells[n-1][i-1]);
      cells[n-1][i].setNeighbor(cells[n-1][i+1]);
      //
      cells[i][0].setNeighbor(cells[i-1][1]);
      cells[i][0].setNeighbor(cells[i][1]);
      cells[i][0].setNeighbor(cells[i+1][1]);
      cells[i][0].setNeighbor(cells[i-1][0]);
      cells[i][0].setNeighbor(cells[i+1][0]);
      //
      cells[i][n-1].setNeighbor(cells[i-1][n-2]);
      cells[i][n-1].setNeighbor(cells[i][n-2]);
      cells[i][n-1].setNeighbor(cells[i+1][n-2]);
      cells[i][n-1].setNeighbor(cells[i-1][n-1]);
      cells[i][n-1].setNeighbor(cells[i+1][n-1]);
    }
    // Set the neighbors of the interior cells:
    for (int i = 1; i < n-1; i++) {
      for (int j = 1; j < n-1; j++) {
        cells[i][j].setNeighbor(cells[i-1][j-1]);
        cells[i][j].setNeighbor(cells[i-1][j]);
        cells[i][j].setNeighbor(cells[i-1][j+1]);
        cells[i][j].setNeighbor(cells[i][j-1]);
        cells[i][j].setNeighbor(cells[i][j+1]);
        cells[i][j].setNeighbor(cells[i+1][j-1]);
        cells[i][j].setNeighbor(cells[i+1][j]);
        cells[i][j].setNeighbor(cells[i+1][j+1]);
      }
    }
  }
  public void transition() {
    // Compute the next state of the spores
    for (int i = 0; i < cells.length; i++) {
      for (int j = 0; j < cells.length; j++) {
        cells[i][j].computeNextState();
      }
    }
    // Advance the state of the spores:
    for (int i = 0; i < cells.length; i++) {
      for (int j = 0; j < cells.length; j++) {
        cells[i][j].nextState();
      }
    }
    //
    printAutomaton();
  }
  public static void main(String args[]) {
    if (args.length < 1) {
      System.err.println("Syntax: java Automaton <num transitions>");
      System.exit(1);
    } else {
      Automaton a = new Automaton(5);
      System.out.println("Num black = " + Cell.getNumBlack());
      a.printAutomaton();
      int t = Integer.parseInt(args[0]);
      for (int i = 0; i < t; i++) {
        System.out.println("\nTransition: " + i + ", num black = " + Cell.getNumBlack());
        a.transition();
      }
    }
  }
}
