Package com.heatonresearch.aifh.examples.ca

Source Code of com.heatonresearch.aifh.examples.ca.ConwayCA

/*
* Artificial Intelligence for Humans
* Volume 2: Nature Inspired Algorithms
* Java Version
* http://www.aifh.org
* http://www.jeffheaton.com
*
* Code repository:
* https://github.com/jeffheaton/aifh
*
* Copyright 2014 by Jeff Heaton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information on Heaton Research copyrights, licenses
* and trademarks visit:
* http://www.heatonresearch.com/copyright
*/
package com.heatonresearch.aifh.examples.ca;

import com.heatonresearch.aifh.examples.util.WorldPanel;
import com.heatonresearch.aifh.randomize.GenerateRandom;
import com.heatonresearch.aifh.randomize.MersenneTwisterGenerateRandom;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

/**
* Conway's game of life.  A classic cellular automation.
* <p/>
* Rules:
* 1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
* 2. Any live cell with two or three live neighbors lives on to the next generation. (not needed)
* 3. Any live cell with more than three live neighbors dies, as if by overcrowding.
* 4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
* <p/>
* References:
* http://en.wikipedia.org/wiki/Conway's_Game_of_Life
*/
public class ConwayCA extends JFrame implements ActionListener, WindowListener, Runnable {
    /**
     * Perform an iteration.
     */
    private JButton iterationButton;

    /**
     * Start running.
     */
    private JButton startButton;

    /**
     * Stop running.
     */
    private JButton stopButton;

    /**
     * Reset the simulation.
     */
    private JButton resetButton;

    /**
     * Has a stop been requested.
     */
    private boolean requestStop;

    /**
     * The world.
     */
    private WorldPanel worldArea;

    /**
     * Used to locate the x coordinate of neighbors.
     */
    private static final int[] neighborsX = {0, 0, 1, -1, -1, 1, -1, 1};

    /**
     * Used to locate the y coordinate of neighbors.
     */
    private static final int[] neighborsY = {1, -1, 0, 0, -1, -1, 1, 1};

    /**
     * The number of rows.
     */
    public static final int ROWS = 75;

    /**
     * The number of columns.
     */
    public static final int COLS = 75;

    /**
     * The constructor.
     */
    public ConwayCA() {
        setSize(500, 500);
        setTitle("Conway's Game of Life");

        Container c = getContentPane();
        c.setLayout(new BorderLayout());
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        c.add(buttonPanel, BorderLayout.NORTH);
        buttonPanel.add(iterationButton = new JButton("Iteration"));
        buttonPanel.add(startButton = new JButton("Start"));
        buttonPanel.add(stopButton = new JButton("Stop"));
        buttonPanel.add(resetButton = new JButton("Reset"));

        this.worldArea = new WorldPanel(ROWS, COLS, true);
        /*
      Scroll bar.
     */
        final JScrollPane scroll = new JScrollPane(this.worldArea);
        c.add(scroll, BorderLayout.CENTER);
        iterationButton.addActionListener(this);
        startButton.addActionListener(this);
        stopButton.addActionListener(this);
        resetButton.addActionListener(this);

        this.addWindowListener(this);
        this.stopButton.setEnabled(false);

        performReset();
    }

    /**
     * Perform one iteration.
     */
    public void performIteration() {
        boolean[][] grid = this.worldArea.getPrimaryGrid();

        for (int row = 0; row < grid.length; row++) {
            for (int col = 0; col < grid[row].length; col++) {
                int total = 0;

                for (int i = 0; i < neighborsX.length; i++) {
                    int nCol = col + neighborsX[i];
                    int nRow = row + neighborsY[i];
                    if (nCol >= 0 && nCol < this.worldArea.getCols()) {
                        if (nRow >= 0 && nRow < this.worldArea.getRows()) {
                            if (grid[nRow][nCol]) {
                                total++;
                            }
                        }
                    }
                }


                boolean alive = grid[row][col];

                if (alive) {
                    // 1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
                    if (total < 2) {
                        alive = false;
                    }
                    // 2. Any live cell with two or three live neighbors lives on to the next generation. (not needed)
                    // 3. Any live cell with more than three live neighbors dies, as if by overcrowding.
                    if (alive && total > 3) {
                        alive = false;
                    }
                } else {
                    // 4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
                    if (total == 3) {
                        alive = true;
                    }
                }

                this.worldArea.getBackupGrid()[row][col] = alive;
            }
        }

        this.worldArea.advanceBackupGrid();
    }

    /**
     * Start the simulation.
     */
    public void performStart() {
        this.iterationButton.setEnabled(false);
        this.stopButton.setEnabled(true);
        this.startButton.setEnabled(false);
        /*
      The background thread.
     */
        final Thread thread = new Thread(this);
        thread.start();
    }

    /**
     * Request stop.
     */
    public void performStop() {
        this.requestStop = true;
    }

    /**
     * Perform a reset.
     */
    public void performReset() {
        boolean[][] grid = this.worldArea.getBackupGrid();
        GenerateRandom rnd = new MersenneTwisterGenerateRandom();

        for (int row = 0; row < this.worldArea.getRows(); row++) {
            for (int col = 0; col < this.worldArea.getCols(); col++) {
                grid[row][col] = rnd.nextBoolean();
            }
        }

        this.worldArea.advanceBackupGrid();

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource() == iterationButton) {
            performIteration();
            repaint();
        } else if (ev.getSource() == startButton) {
            performStart();
        } else if (ev.getSource() == stopButton) {
            performStop();
        } else if (ev.getSource() == resetButton) {
            performReset();
        }

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void windowActivated(WindowEvent arg0) {

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void windowClosed(WindowEvent arg0) {


    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void windowClosing(WindowEvent arg0) {

        System.exit(0);

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void windowDeactivated(WindowEvent arg0) {

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void windowDeiconified(WindowEvent arg0) {

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void windowIconified(WindowEvent arg0) {

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void windowOpened(WindowEvent arg0) {
        performReset();
    }


    /**
     * Main entry point.
     *
     * @param args Not used.
     */
    public static void main(String[] args) {
        try {
            JFrame f = new ConwayCA();
            f.setVisible(true);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void run() {
        this.requestStop = false;
        while (!this.requestStop) {
            performIteration();
            this.repaint();
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }

        // Update GUI
        this.iterationButton.setEnabled(true);
        this.stopButton.setEnabled(false);
        this.startButton.setEnabled(true);
    }
}
TOP

Related Classes of com.heatonresearch.aifh.examples.ca.ConwayCA

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.