Android Open Source - WolframCA Wolfram Rule Table






From Project

Back to project page WolframCA.

License

The source code is released under:

Apache License

If you think the Android project WolframCA listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 *    WolframCA - an android application to view 1-dimensional cellular automata (CA)
 *    Copyright 2013 Barry O'Neill (http://barryoneill.net/)
 *//  w  w w  .j  a  v a 2  s. co  m
 *    Licensed under Apache 2.0 with limited permission from, and no affiliation with Steven
 *    Wolfram, LLC. See the LICENSE file in the root of this project for the full license terms.
 */
package net.nologin.meep.ca.model;

import android.util.Log;
import net.nologin.meep.ca.WolframUtils;

/**
 * This class contains a lookup cache for the 256 elementary 1-dimensional cellular automata (CA), as described in:
 * <br/><br/>
 * <a href="http://mathworld.wolfram.com/ElementaryCellularAutomaton.html">http://mathworld.wolfram.com/ElementaryCellularAutomaton.html</a>
 * <br/><br/>
 * In short, the CA is a row of cells with boolean values (on or off) representing a 'generation' in the CA.
 * For the next generation/row, the value of every cell changes, depending on its current state, and that of its left
 * and right neighbour.  This means that to calculate the next state of a cell, there are three boolean inputs,
 * meaning 8 possible permutations:
 * <pre>
 *  numbers 7 to 0 as binary:
 *          111 | 110 | 101 | 100 | 011 | 010 | 001 | 000
 * </pre>
 *
 * Each entry above is a possible set of cell states (e.g. 111 means all cells are on, 101 means that the left and right
 * cells are on, but the middle one was off, and so on)
 * <br/><br/>
 * Next, we need to define what the next state of a cell will be - this is defined by a <b>rule</b> number.  Since
 * there are 8 possible inputs, the CA uses an 8-bit number to define the rule to use. Each bit of the rule number
 * is assigned a position to the table.  So, for <i>Rule 30</i>:
 *
 * <pre>
 *    input permutations: 111 | 110 | 101 | 100 | 011 | 010 | 001 | 000
 *    ------------------|-----|-----|-----|-----|-----|-----|-----|-----
 *             Rule  30 |  0  |  0  |  0  |  1  |  1  |  1  |  1  |  0
 * </pre>
 *
 * For rule 30, if all cells are on (111), we can see the next state is off (0).  Or, if the current cell is on, but the
 * left and right are off (010), then the next state is on (1).
 *
 */
public class WolframRuleTable {

    /* Rule lookup array.  Main index is the rule number, subarrays are that rule number converted to binary and
     * stored as an 8 element boolean array.  Eg
     * [
     *  ..
     *  [50]-->[false,false,true,true,false,false,true,false]  // (rule '50' = 00110010 in binary)
     *  ..
     * ]
     */
    private static final boolean[][] ruleTable = new boolean[256][];

    private WolframRuleTable() {
    }

    /**
     * Calculate the value of a cell in the next generation based on the state of the relevant cells in the current
     * generation.
     *
     * @param rule  The rule number (0-255 inclusive)
     * @param curStateLeft The current state of the cell's left neighbour
     * @param curState The current state of the cell in question
     * @param curStateRight The current state of the cell's right neighbour
     * @return The cell's state in the next generation
     * @throws IllegalArgumentException If the rule is not a value from 0 to 255 (inclusive).
     */
    public static boolean getNextState(int rule, boolean curStateLeft, boolean curState, boolean curStateRight) {

        if (rule < 0 || rule > 255) {
            throw new IllegalArgumentException("Rule must be between 0 and 255");
        }

        // ruleTable entries are only generated as needed
        if (ruleTable[rule] == null) {

            ruleTable[rule] = new boolean[8];

            // store the rule number's binary value as an 8-bit boolean array
            for (int i = 0; i < 8; i++) {
                ruleTable[rule][i] = (rule & (1L << (7-i))) != 0;
            }

            Log.e(WolframUtils.LOG_TAG,String.format("Rule %d setup: %s", rule, joinArr(ruleTable[rule])));
        }

        /* 8 possible states can be represented using a 3-bit number.  Start with 0, then add 4, 2 or 1 to
         * set the left, center or right bit respectively.
         * e.g.
         * 101 = 4 + 1
         * 010 = 2
         * 111 = 4 + 2 + 1
         * and so on.
         *
         * We can then use this value (0-7) to index the ruleTable subarray for this rule.
         */

        int lookupIdx = curStateLeft ? 4 : 0;
        lookupIdx += curState ? 2 : 0;
        lookupIdx += curStateRight ? 1 : 0;

        /* For some reason the bit-pattern to rule binary matching (as described in the URL in the class javadoc)
         * is in reverse order (eg, 111(7),110(6),101(5) etc).  Not a huge deal, but we have to reverse the
         * subarray lookup (7-idx): */
        return ruleTable[rule][7 - lookupIdx];

    }

    // convert a bool array to descriptive string, "F,F,T,T.." for debugging messages
    private static String joinArr(boolean[] array){

        if(array == null || array.length < 1){
            return "";
        }

        StringBuilder buf = new StringBuilder(array.length * 16);
        for(int i = 0; i< array.length; i++) {
            if(i > 0){
                buf.append(",");
            }
            buf.append(array[i] ? "T" : "F");
        }

        return buf.toString();
    }



}




Java Source Code List

net.nologin.meep.ca.MainActivity.java
net.nologin.meep.ca.SettingsActivity.java
net.nologin.meep.ca.WolframUtils.java
net.nologin.meep.ca.model.WolframRuleTable.java
net.nologin.meep.ca.model.WolframTileProvider.java
net.nologin.meep.ca.model.WolframTile.java
net.nologin.meep.ca.view.WolframCAView.java