import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.Random; import javax.swing.*; public class CAMachine extends JComponent{ public static int CA_WIDTH = 10; public static int CA_HEIGHT = 40; private static int SQUARE_SIZE = 20; public static int WEST = 0; public static int NORTHWEST = 1; public static int NORTH = 2; public static int NORTHEAST = 3; public static int EAST = 4; public static int SOUTHEAST = 5; public static int SOUTH = 6; public static int SOUTHWEST = 7; public static int EMPTY = 0; public static int WIRE = 1; public static int NOT = 2; public static int AND = 3; public static int OR = 4; public static int XOR = 5; public static int NAND = 6; public static int NOR = 7; public static int XNOR = 8; public static Color[] COLORS = { Color.BLACK, Color.BLUE, Color.RED, Color.GREEN, Color.GREEN, Color.YELLOW, Color.CYAN, Color.MAGENTA, Color.ORANGE }; private boolean[][] state; private int[][] circuit; private JFrame frame; private Container pane; private JComponent caView; private JPanel buttonPane; private JButton stepButton; private JTextField stepField; private FileReader reader; private BufferedReader bufferedReader; public CAMachine() { state = new boolean[CA_WIDTH][CA_HEIGHT]; circuit = new int[CA_WIDTH][CA_HEIGHT]; Random random = new Random(); for (int column = 0; column < CA_WIDTH; column++) { for (int row = 0; row < CA_HEIGHT; row++) { state[column][row] = random.nextBoolean(); } } try { reader = new FileReader("Circuit2"); } catch (FileNotFoundException e) { e.printStackTrace(); System.exit(0); } bufferedReader = new BufferedReader(reader); String line = null;; for (int row = 0; row < CA_HEIGHT; row++) { try { line = bufferedReader.readLine(); } catch (IOException e) { e.printStackTrace(); System.exit(0); } for (int column = 0; column < CA_WIDTH; column++) { circuit[column][row] = Integer.parseInt(line.substring(0, 3)); line = line.substring(4); } } frame = new JFrame("CA Machine"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pane = frame.getContentPane(); caView = new CAView(); caView.setSize(CA_WIDTH * SQUARE_SIZE, CA_HEIGHT * SQUARE_SIZE); buttonPane = new JPanel(); stepButton = new JButton("Step"); stepField = new JTextField(); buttonPane.setLayout(new BorderLayout()); buttonPane.add(stepField, BorderLayout.CENTER); buttonPane.add(stepButton, BorderLayout.EAST); pane.setLayout(new BorderLayout()); pane.add(caView, BorderLayout.CENTER); pane.add(buttonPane, BorderLayout.SOUTH); stepField.setText("1"); stepButton.addActionListener(new StepButtonActionListener()); frame.pack(); frame.setVisible(true); } private class StepButtonActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { int steps = Integer.parseInt(stepField.getText()); boolean[][] stateBuffer; for (int i = 0; i < steps; i++) { stateBuffer = new boolean[CA_WIDTH][CA_HEIGHT]; for (int column = 0; column < CA_WIDTH; column++) { for (int row = 0; row < CA_HEIGHT; row++) { int gate = circuit[column][row]; boolean north = state[column][(row + CA_HEIGHT - 1) % CA_HEIGHT]; boolean northEast = state[(column + 1) % CA_WIDTH][(row + CA_HEIGHT - 1) % CA_HEIGHT]; boolean east = state[(column + 1) % CA_WIDTH][row]; boolean southEast = state[(column + 1) % CA_WIDTH][(row + 1) % CA_HEIGHT]; boolean south = state[column][(row + 1) % CA_HEIGHT]; boolean southWest = state[(column + CA_WIDTH - 1) % CA_WIDTH][(row + 1) % CA_HEIGHT]; boolean west = state[(column + CA_WIDTH - 1) % CA_WIDTH][row]; boolean northWest = state[(column + CA_WIDTH - 1) % CA_WIDTH][(row + CA_HEIGHT - 1) % CA_HEIGHT]; boolean inputOne = true; boolean inputTwo = true; int direction = gate % 8; // Gets first input if (direction == WEST) { inputOne = west; } else if (direction == NORTHWEST) { inputOne = northWest; } else if (direction == NORTH) { inputOne = north; } else if (direction == NORTHEAST) { inputOne = northEast; } else if (direction == EAST) { inputOne = east; } else if (direction == SOUTHEAST) { inputOne = southEast; } else if (direction == SOUTH) { inputOne = south; } else if (direction == SOUTHWEST) { inputOne = southWest; } System.out.println(direction); direction = (gate / 8) % 8; // Gets first input if (direction == WEST) { inputTwo = west; } else if (direction == NORTHWEST) { inputTwo = northWest; } else if (direction == NORTH) { inputTwo = north; } else if (direction == NORTHEAST) { inputTwo = northEast; } else if (direction == EAST) { inputTwo = east; } else if (direction == SOUTHEAST) { inputTwo = southEast; } else if (direction == SOUTH) { inputTwo = south; } else if (direction == SOUTHWEST) { inputTwo = southWest; } System.out.println(direction); int component = gate / 64; if (component == EMPTY) { if (gate % 8 == 0) { stateBuffer[column][row] = false; } else if (gate % 8 == 1) { stateBuffer[column][row] = true; } else if (gate % 8 == 2) { stateBuffer[column][row] = !(state[column][row]); } else { stateBuffer[column][row] = false; } } else if (component == WIRE) { stateBuffer[column][row] = inputOne; } else if (component == NOT) { stateBuffer[column][row] = !(inputOne); } else if (component == AND) { stateBuffer[column][row] = inputOne && inputTwo; } else if (component == OR) { stateBuffer[column][row] = inputOne || inputTwo; } else if (component == XOR) { stateBuffer[column][row] = (inputOne || inputTwo) && !(inputOne && inputTwo); } else if (component == NAND) { stateBuffer[column][row] = !(inputOne && inputTwo); } else if (component == NOR) { stateBuffer[column][row] = !(inputOne || inputTwo); } else if (component == XNOR) { stateBuffer[column][row] = !((inputOne || inputTwo) && !(inputOne && inputTwo)); } } } state = stateBuffer; frame.repaint(); } } } private class CAView extends JComponent { public CAView() { this.setPreferredSize(new Dimension(CA_WIDTH * SQUARE_SIZE, CA_HEIGHT * SQUARE_SIZE)); } public void paintComponent(Graphics g) { super.paintComponent(g); for (int column = 0; column < CA_WIDTH; column++) { for (int row = 0; row < CA_HEIGHT; row++) { int component = circuit[column][row] / 64; g.setColor(COLORS[component]); g.fillRect(column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE); if (state[column][row]) { g.setColor(Color.WHITE); } else { g.setColor(Color.BLACK); } int offset = 8; g.fillRect((column * SQUARE_SIZE) + offset, (row * SQUARE_SIZE) + offset, SQUARE_SIZE - (2 * offset), SQUARE_SIZE - (2 * offset)); } } } } public static void main(String[] args) { new CAMachine(); } }