git @ Cat's Eye Technologies yoob / master src / lang / CircuteState.java
master

Tree @master (Download .tar.gz)

CircuteState.java @masterraw · history · blame

/*
 * A CircuteState implement the semantics of the Circute CA.
 * The source code in this file has been placed into the public domain.
 */
package tc.catseye.yoob.circute;

import tc.catseye.yoob.*;
import tc.catseye.yoob.Error;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;


class Circute implements Language {
    public String getName() {
        return "Circute";
    }

    public int numPlayfields() {
        return 1;
    }

    public int numTapes() {
        return 0;
    }

    public boolean hasProgramText() {
        return false;
    }

    public boolean hasInput() {
        return false;
    }

    public boolean hasOutput() {
        return false;
    }

    public List<String> exampleProgramNames() {
        ArrayList<String> names = new ArrayList<String>();
        names.add("AND gate");
        names.add("OR gate");
        names.add("One-fire switch (OSC->off)");
        names.add("Tiny oscillator");
        names.add("Fast oscillator");
        names.add("Tiny inverter");
        return names;
    }

    public CircuteState loadExampleProgram(int index) {
        // All examples from: (but possibly modified slightly)
        // http://www.esolangs.org/wiki/Circute
        // Authors unknown.  From the esowiki, thus in the public domain.
        String[][] program = {
          {
            "#==     ==#",
            "  =     =",
            "  ===N===",
            "     =",
            "     =",
            "   =====",
            "   =   =",
            "   =#N#=",
            "     =",
          },
          {
            "#==     ==",
            "  =     =",
            "===== =====",
            "=   = =   =",
            "==N== ==N==",
            "  =     =",
            "  ==#N#==",
            "     =",
            "     =",
          },
          {
            "  ===#N=========",
            "  =     =   =",
            "==N== ===== =",
            "=   = =   = =",
            "===== ==N== =",
            "  =     =   =",
            "  =     =====",
            "  =",
            "  =============#",
          },
          {
            "#N=",
            " ======================",
          },
          {
            " =N#",
            "#N=",
            "  ======================",
          },
          {
            "===========#",
            "=",
            "=N#",
            " =",
            " ===========",
          }
        };
        CircuteState s = new CircuteState();
        s.playfield.load(program[index]);
        return s;
    }

    public CircuteState importFromText(String text) {
        CircuteState s = new CircuteState();
        s.playfield.load(text.split("\\r?\\n"));
        return s;
    }

    public List<String> getAvailableOptionNames() {
        ArrayList<String> names = new ArrayList<String>();
        return names;
    }

    private static final String[][] properties = {
        {"Author", "Chris Pressey"},
        {"Implementer", "Chris Pressey"},
        {"Implementation notes",
         "This hand-implementation is based on the ALPACA description, but is not " +
         "compiled from it."}
    };

    public String[][] getProperties() {
        return properties;
    }

}

class CircutePlayfield extends CellularAutomatonPlayfield<CharacterElement> {
    static final char WIRE  = '=';
    static final char TAIL  = '-';
    static final char SPARK = '#';
    static final char NAND  = 'N';
    static final char SPACE = ' ';

    public CircutePlayfield() {
        super(new CharacterElement(SPACE));
    }

    public CircutePlayfield clone() {
        CircutePlayfield c = new CircutePlayfield();
        c.store = new HashMap<Position, CharacterElement>(
          (Map<Position, CharacterElement>)this.store
        );
        c.copyBackingStoreFrom(this);
        return c;
    }

    public CharacterElement applyRules(IntegerElement x, IntegerElement y, CharacterElement elem) {
        if (elem.getChar() == TAIL) {
            return new CharacterElement(WIRE);
        } else if (elem.getChar() == WIRE) {
            boolean adjacentSpark = (
                get(x.succ(), y).getChar() == SPARK ||
                get(x.pred(), y).getChar() == SPARK ||
                get(x, y.succ()).getChar() == SPARK ||
                get(x, y.pred()).getChar() == SPARK
            );
            boolean activeNANDBelow = (
                get(x, y.succ()).getChar() == NAND &&
                (get(x.pred(), y.succ()).getChar() == WIRE ||
                 get(x.succ(), y.succ()).getChar() == WIRE)
            );
            boolean activeNANDAbove = (
                get(x, y.pred()).getChar() == NAND &&
                (get(x.pred(), y.pred()).getChar() == WIRE ||
                 get(x.succ(), y.pred()).getChar() == WIRE)
            );
            if (adjacentSpark || activeNANDBelow || activeNANDAbove)
                return new CharacterElement(SPARK);
        } else if (elem.getChar() == SPARK) {
            boolean adjacentTail = (
                get(x.succ(), y).getChar() == TAIL ||
                get(x.pred(), y).getChar() == TAIL ||
                get(x, y.succ()).getChar() == TAIL ||
                get(x, y.pred()).getChar() == TAIL
            );
            boolean inactiveNANDBelow = (
                get(x, y.succ()).getChar() == NAND &&
                get(x.pred(), y.succ()).getChar() == SPARK &&
                get(x.succ(), y.succ()).getChar() == SPARK
            );
            boolean inactiveNANDAbove = (
                get(x, y.pred()).getChar() == NAND &&
                get(x.pred(), y.pred()).getChar() == SPARK &&
                get(x.succ(), y.pred()).getChar() == SPARK
            );
            if (adjacentTail || inactiveNANDBelow || inactiveNANDAbove)
                return new CharacterElement(TAIL);
        }
        return elem.getChar() == ' ' ? null : elem;
    }
}

public class CircuteState implements State {
    protected CircutePlayfield playfield;
    protected BasicPlayfieldView pfView;
    private static final Circute language = new Circute();

    public CircuteState() {
        playfield = new CircutePlayfield();
        pfView = new BasicPlayfieldView();
    }

    public Language getLanguage() {
        return language;
    }
    
    public CircuteState clone() {
        CircuteState c = new CircuteState();
        c.playfield = this.playfield.clone();
        return c;
    }

    public List<Error> step(World world) {
        ArrayList<Error> errors = new ArrayList<Error>();
        CircutePlayfield nu = new CircutePlayfield();
        playfield.step(nu);
        playfield = nu;
        return errors;
    }

    public Playfield getPlayfield(int index) {
        if (index == 0)
            return playfield;
        return null;
    }

    public Tape getTape(int index) {
        return null;
    }

    public String getProgramText() {
        return "";
    }

    public int getProgramPosition() {
        return 0;
    }

    public List<Error> setProgramText(String text) {
        ArrayList<Error> errors = new ArrayList<Error>();
        return errors;
    }

    public View getPlayfieldView(int index) {
        return pfView;
    }

    public View getTapeView(int index) {
        return null;
    }

    public String exportToText() {
        return playfield.dump();
    }

    public boolean hasHalted() {
        return false;
    }

    public boolean needsInput() {
        return false;
    }

    public void setOption(String name, boolean value) {
    }
}