CryptoList.java
"CryptoJava" is a Java applet which provides an interactive environment for solving cryptogram puzzles.
This game was written for Triangle Street Diversions' puzzle gallery, as an example of how Java could improve upon classic pencil puzzles. Several dozen cryptogram puzzles were developed using this engine.
This module is the Applet wrapper for a specific type of CryptoJava puzzle: "CryptoJava Lists". These are lists of related words, all from the same category. The list of words is taken from rot13'd parameters passed to Applet from the HTML code it is embedded in.
// CryptoList.java
// Written by Marc Wallace for Triangle Street Diversions.
// Copyright (c) 1996 Triangle Street Diversions, all rights reserved.
import java.awt.*;
import java.applet.Applet;
import java.util.StringTokenizer;
public class CryptoList extends Applet implements Runnable {
Thread thread; // thread for periodic events.
CryptoPanel game; // the game panel.
Panel npanel; // north panel.
Panel cpanel; // center panel.
Panel spanel; // south panel.
String game_category; // the category.
String game_wordlist; // the list of words.
String game_status; // the current status string of the game.
int tick; // timer ticks for the thread.
// --------------------
// -------------------- INITIALIZING --------------------
// --------------------
public void init( ) {
Color foreground = getColorParam( "normal color" );
Color background = getColorParam( "background color" );
// color parameter defaults.
if ( foreground == null ) { foreground = Color.black; }
if ( background == null ) { background = Color.white; }
// setup how we look.
setLayout( new BorderLayout( 0, 0 ) );
setForeground( foreground );
setBackground( background );
// read in the category and words.
getGameData( );
// we create these so everything is nicely centered.
cpanel = newPanel( foreground, background, 4, 4 );
// the game itself.
game = new CryptoPanel( );
setupGameGraphics( foreground, background );
game.setQuote( game_wordlist );
cpanel.add( game );
// add the panels in, and we're ready to go.
// add( "North", npanel );
// add( "South", spanel );
add( "Center", cpanel );
validate( );
}
// --------------------
Panel newPanel( Color fg, Color bg, int xgap, int ygap ) {
Panel p = new Panel( );
p.setLayout( new FlowLayout( FlowLayout.CENTER, xgap, ygap ) );
p.setForeground( fg );
p.setBackground( bg );
return p;
}
// --------------------
void setupGameGraphics( Color fg, Color bg ) {
Font game_font = getFontParam( "font" );
Color back = getColorParam( "background color" );
Color normal = getColorParam( "normal color" );
Color selected = getColorParam( "selected color" );
Color swapped = getColorParam( "swapped color" );
Color solved = getColorParam( "solved color" );
// color parameter defaults.
if ( back == null ) { back = bg; }
if ( normal == null ) { normal = fg; }
if ( selected == null ) { selected = Color.red; }
if ( swapped == null ) { swapped = new Color( 128, 0, 0 ); }
if ( solved == null ) { solved = Color.blue; }
// font parameter defaults.
if ( game_font == null ) {
game_font = new Font( "Helvetica", Font.PLAIN, 18 );
}
game.setBackColor( back );
game.setNormalColor( normal );
game.setSelectedColor( selected );
game.setSwappedColor( swapped );
game.setSolvedColor( solved );
game.setFont( game_font );
game.setBoxSize( new Dimension( 20, 30 ) );
}
// --------------------
void getGameData( ) {
int idx, num_words;
// get the category for this list.
game_category = getParam( "category" );
if ( game_category == null ) { game_category = "CryptoJava!"; }
// how many words are there?
num_words = getIntParam( "number of words" );
if ( num_words < 1 ) { num_words = 10; }
// get the list of words.
game_wordlist = "";
for ( idx = 0; idx < num_words; idx++ ) {
Integer i = new Integer( idx );
String word = getRotParam( "word " + i.toString( ) );
if ( word != null ) {
game_wordlist = game_wordlist + word + "\n";
}
}
}
void makePopup( ) {
Frame f = new Frame( "Dialog Frame" );
f.pack( );
f.setFont( Font.getFont( "Helvetica-bold-24" ) );
InfoDialog id = new InfoDialog( f, "Congratulations!",
"Good job!\n" +
" \n" +
"You've solved the puzzle!" );
id.pack( );
id.show( );
}
// --------------------
// -------------------- THREADS --------------------
// --------------------
public void start( ) {
if ( thread == null ) {
thread = new Thread( this );
thread.start( );
}
}
// --------------------
public void stop( ) {
if ( thread != null ) {
thread.stop( );
thread = null;
}
}
// --------------------
public void run( ) {
// draw the panel (at least once!).
game.repaint( );
tick = 0;
while ( thread != null ) {
tick++;
// sleep and catch errors.
try {
Thread.sleep( 200 );
} catch( InterruptedException e );
// catch winners.
if ( game.isSolved( ) ) {
break;
}
}
// the user must have won to have gotten here.
showStatus( "You've won!" );
makePopup( );
}
// --------------------
// -------------------- PARAMETER METHODS --------------------
// --------------------
protected Color getColorParam( String name ) {
String value = getParameter( name );
int i;
try {
// parse it as a hexadecimal number.
i = Integer.parseInt( value, 16 );
} catch ( NumberFormatException e ) {
return null;
};
return new Color( i );
}
protected Font getFontParam( String name ) {
String value = getParameter( name );
if ( value == null ) { return null; }
return Font.getFont( value );
}
protected int getIntParam( String name ) {
String value = getParameter( name );
int i;
try {
// parse it as a decimal number.
i = Integer.parseInt( value, 10 );
} catch ( NumberFormatException e ) {
return 0;
};
return i;
}
protected String getParam( String name ) {
return getParameter( name );
}
protected String getRotParam( String name ) {
String normal = getParameter( name );
char chars[];
int idx;
if ( normal == null ) { return null; }
chars = normal.toCharArray( );
for ( idx = 0; idx < chars.length; idx++ ) {
char c = chars[ idx ];
if ( ( c >= 'A' ) && ( c <= 'Z' ) ) {
c = (char)( 'A' + ( ( ( c - 'A' ) + 13 ) % 26 ) );
}
if ( ( c >= 'a' ) && ( c <= 'z' ) ) {
c = (char)( 'a' + ( ( ( c - 'a' ) + 13 ) % 26 ) );
}
chars[ idx ] = c;
}
return new String( chars );
}
// --------------------
// -------------------- APPLET INFORMATION --------------------
// --------------------
public String getAppletInfo( ) {
return "CryptoList v1.4.\n" +
"Written by Marc Wallace.\n" +
"Copyright (c) 1996 Triangle Street Diversions. " +
"All rights reserved.";
}
public String[][] getParameterInfo( ) {
String[][] info = {
// { name, type, description }
{ "font", "font.style.size", "font for the game letters" },
{ "normal color", "hex color", "text (normal)" },
{ "selected color", "hex color", "text (selected)" },
{ "swapped color", "hex color", "text (swapped)" },
{ "solved color", "hex color", "text (solved)" },
{ "background color", "hex color", "background" }
};
return info;
}
// --------------------
// -------------------- STATUS BAR EVENTS --------------------
// --------------------
public boolean mouseEnter( Event e, int x, int y ) {
if ( e.target == game ) {
game_status = game.getStatus( );
showStatus( game_status );
}
return true;
}
public boolean mouseExit( Event e, int x, int y ) {
if ( e.target == game ) {
showStatus( "" );
}
return true;
}
public boolean mouseMove( Event e, int x, int y ) {
if ( game == null ) return false;
if ( e.target == game ) {
game_status = game.getStatus( );
if ( game_status == null ) {
showStatus( "CryptoJava!" );
} else if ( game_status.equals( "" ) ) {
showStatus( "CryptoJava!" );
} else {
showStatus( game_status );
}
}
return true;
}
}
Source code is:
© Copyright 1995-1996, Triangle Street Diversions. All rights reserved.