import java.util.Random;
import java.awt.*;
import java.awt.event.*;
public class Cell extends java.applet.Applet implements ActionListener, ItemListener
{
private static boolean [] lastLine;
private static int SIZE;
private static int WIDTH;
private static int REND_MULT = 5;
private static boolean [] key = new boolean [8];
private static int howMany = 1000;
private static boolean lEdge = false;
private static boolean rEdge = false;
private static boolean randStart = false;
private static int starts = 1;
private static int pattern = 1;
private static int patPeriod = -1;
private static char on = '@';
private static char off = ' ';
private static boolean xpm = false;
public static void main ( String [] args )
{
SIZE = 1500;
WIDTH = SIZE*REND_MULT;
parseArgs ( args );
initConds ();
if ( xpm )
{
off = '.';
System.out.println ( "" );
System.out.println ( "static char *cellout[] = {" );
System.out.println ( "" );
System.out.println ( "\"\t" + (WIDTH/REND_MULT) + "\t" + (howMany + 1) + "\t2\t1\"," );
System.out.println ( "\". c #000\"," );
System.out.println ( "\"@ c #fff\"," );
System.out.println ( "" );
}
printout ( lastLine, 255 );
for ( int j = 0; j < howMany; j++ )
{
genLine();
printout ( lastLine, howMany - j );
}
if ( xpm )
{
System.out.println ( "};" );
}
}
private static void printout ( boolean [] line, int diff )
{
int renderWidth = (line.length)/REND_MULT;
if ( xpm ) {
System.out.print ( "\"" ); }
for ( int i = renderWidth*2; i <= renderWidth*3; i++ )
{
if ( !line[i] )
System.out.print ( off );
else
System.out.print ( on );
}
if ( xpm ) {
if ( diff > 1 )
{
System.out.print ("\"," );
}
else
{
System.out.print ("\"" );
}
}
System.out.println ();
}
private static void parseArgs ( String [] arg )
{
if ( arg.length < 1 )
{
usage();
System.exit(1);
}
int rule = -42;
try {
rule = Integer.parseInt ( arg[0] );
}
catch ( NumberFormatException e )
{
System.out.println ( "Rule argument must be an integer between O and 255 inclusive, not '" + arg[0] + "'" );
usage();
System.exit(1);
}
try {
howMany = Integer.parseInt ( arg[1] );
}
catch ( NumberFormatException e )
{
}
catch ( ArrayIndexOutOfBoundsException e )
{
}
try {
SIZE = Integer.parseInt ( arg[2] );
WIDTH = SIZE*REND_MULT;
}
catch ( NumberFormatException e )
{
}
catch ( ArrayIndexOutOfBoundsException e )
{
}
if ( 255 < rule || 0 > rule )
{
System.out.println ( "Rule argument must be an integer between O and 255 inclusive, not " + rule );
usage();
System.exit(1);
}
if ( arg.length >= 4 )
{
randStart = arg[3].equals("1");
}
if ( arg.length >= 5 )
{
lEdge = arg[4].equals("1");
}
if ( arg.length >= 6 )
{
rEdge = arg[5].equals("1");
}
if ( arg.length >= 7 )
{
xpm = arg[6].equals("-x");
}
keyGen(rule);
}
private static void keyGen ( int in )
{
if ( in > 255 || in < 0 )
{
System.out.println ( "Invalid value passed to keyGen(int): Bailing!" );
System.exit(1);
}
int div = 128;
int count = 7;
while ( div > 0 )
{
if ( ( in - div ) >= 0 ) {
in -= div;
key[count] = true;
}
else {
key[count] = false;
}
div /= 2;
count--;
}
}
private static void initConds ()
{
lastLine = new boolean [WIDTH];
if ( randStart )
randConds ();
else
patConds ();
}
private static void randConds ()
{
Random rand = new Random();
for ( int i = 0; i < lastLine.length; i++ )
{
int thisInt = rand.nextInt ( 3 );
if ( 0 == thisInt )
lastLine[i] = true;
else
lastLine[i] = false;
}
}
private static void patConds ()
{
for ( int i = 0; i < lastLine.length; i++ )
{
lastLine[i] = false;
}
int section = SIZE / ( starts + 1 );
for ( int i = 1; i <= starts; i++ )
{
lastLine[SIZE*2 + section*i] = true;
}
}
private static void genLine ()
{
boolean [] thisLine = new boolean [WIDTH];
int total = 0;
for ( int i = 0; i < thisLine.length; i++ )
{
try {
total += ( lastLine[i-1] ? 4 : 0 );
}
catch ( ArrayIndexOutOfBoundsException e )
{
total += ( lEdge ? 4 : 0 );
}
total += ( lastLine[i] ? 2 : 0 );
try {
total += ( lastLine[i+1] ? 1 : 0 );
}
catch ( ArrayIndexOutOfBoundsException e )
{
total += ( rEdge ? 1 : 0 );
}
try {
thisLine[i] = key[total];
}
catch ( ArrayIndexOutOfBoundsException e )
{
System.out.println ();
System.out.println ( "Index out of bounds: " + total );
System.exit (1);
}
total = 0;
}
lastLine = thisLine;
}
private static void usage ()
{
System.out.println ( "usage:\n java Cell <rule-code> <lines> <width> <RandStart> <Left Edge> <Right Edge>" );
System.out.println ( "\n rule-code: integer between 0 and 255 inclusive" );
System.out.println ( " lines: # of lines to generate, beyond the initial (optional)" );
System.out.println ( " Defaults to 1000" );
System.out.println ( " width: # of cells in a line (optional)" );
System.out.println ( " Defaults to 1500" );
System.out.println ( " RandStart: 1 or 0 indicating whether to start with random initial line (optional)" );
System.out.println ( " Defaults to 0 (off)" );
System.out.println ( " Left Edge: 1 or 0 indicating state of this edge (optional)" );
System.out.println ( " Defaults to 0 (off)" );
System.out.println ( " Right Edge: 1 or 0 indicating state of this edge (optional)" );
System.out.println ( " Defaults to 0 (off)" );
System.out.println ( "\nAny optional argument must be preceded by all preceding arguments" );
}
private TextField kInput = new TextField ( "", 3 );
private TextField sInput = new TextField ( "", 3 );
private Label keyLabel = new Label ( "KeyCode:" );
private Label startsLabel = new Label ( "# of Starts:" );
private Checkbox Randbox = new Checkbox ( "Random Start" );
private int fromTop = 50;
public void init ()
{
SIZE = Integer.parseInt ( getParameter ( "WIDTH" )) - 10;
WIDTH = SIZE*REND_MULT;
howMany = Integer.parseInt ( getParameter ( "HEIGHT" )) - fromTop;
setSize ( SIZE + 10 , howMany + fromTop );
add ( keyLabel );
add ( kInput );
add ( Randbox );
add ( startsLabel );
add ( sInput );
kInput.addActionListener ( this );
sInput.addActionListener ( this );
Randbox.addItemListener ( this );
}
public void paint ( Graphics page )
{
page.setColor ( new Color(0,0,0) );
initConds ();
drawLine ( lastLine , 0, page);
for ( int i = 0; i < howMany; i++ )
{
genLine ();
drawLine ( lastLine, i+1, page);
}
}
private void drawLine ( boolean [] line, int off, Graphics page)
{
int drawWidth = (line.length)/REND_MULT;
for ( int i = drawWidth*2; i < drawWidth*3; i++ )
{
if ( line[i] )
page.drawLine ( 5+(i-drawWidth*2), fromTop+off, 5+(i-drawWidth*2), fromTop+off );
}
}
public String getAppletInfo ()
{
return "Name: Brian Kelly\n"
+ "Topic: Assignment 7\n"
+ "About: iterative cell generation\n"
+ "\nIt makes pretty patterns...";
}
public void actionPerformed ( ActionEvent e )
{
if ( e.getSource() == kInput )
{
int ev = 0;
try {
ev = Integer.parseInt (e.getActionCommand ());
}
catch ( NumberFormatException x )
{
}
if ( ev < 256 && ev > -1 )
{
keyGen ( ev );
repaint ();
}
else {
System.out.println ( "Bad key input '" + ev + "'" );
}
}
else if ( e.getSource() == sInput )
{
int ev = 1;
try {
ev = Integer.parseInt ( e.getActionCommand ());
}
catch ( NumberFormatException x )
{
}
if ( ev >= 0 )
{
starts = ev;
repaint();
}
else
{
System.out.println ( "Bad key input '" + ev + "'" );
}
}
}
public void itemStateChanged ( ItemEvent e )
{
if ( e.getItem().equals ( "Random Start" ) )
{
if ( e.getStateChange() == ItemEvent.SELECTED )
{
randStart = true;
}
else
{
randStart = false;
}
}
else if ( e.getItem().equals ( "Left Edge" ) )
{
if ( e.getStateChange() == ItemEvent.SELECTED )
{
lEdge = true;
}
else
{
lEdge = false;
}
}
else if ( e.getItem().equals ( "Right Edge" ) )
{
if ( e.getStateChange() == ItemEvent.SELECTED )
{
rEdge = true;
}
else
{
rEdge = false;
}
}
else
{
System.out.println ( "Blech.." );
}
}
}