puzzle15
import java.net.*;
import java.awt.image.*;
import java.applet.Applet;
import java.awt.*;
import java.lang.*;
/* The 15 Puzzle
- Sameer Singh (12/06/1996)
*/
class loadThread extends Thread {
MediaTracker tracker;
piece owner;
Image pic;
int index;
String image_name;
public loadThread(String str,String image_name, piece obj,int index) {
super(str);
owner = obj;
this.image_name = image_name;
this.index = index;
}
public void run() {
//System.out.println("Entering run of thread "+index);
pic = owner.obj.getImage(owner.obj.getDocumentBase(),image_name);
//owner.obj.tracker.addImage(pic,index);
tracker = new MediaTracker(owner.obj);
tracker.addImage(pic,index);
try {
tracker.waitForID(index);
} catch (InterruptedException e) {
}
owner.setImage(pic);
//owner.draw();
//System.out.println("finished "+getName());
}
}
class piece {
Integer value; // the value of the piece
Integer x_pos,y_pos; // the on screen position of the piece
int width=50,height=50;
Graphics gc;
int right,left,up,down;
Image pic;
int flags;
puzzle obj;
loadThread img_thread;
piece(int index,int val, Graphics agc, int x, int y,Image pict,puzzle obj) {
int temp;
/*if (pict != null) {
pic = pict;
obj=obj;
} else {
pic = null;
obj=null;
}
if (pict != null) {
pict = pic;
}
*/
if (obj != null) {
this.obj = obj;
pic = null;
//pic = obj.getImage(obj.getDocumentBase(),"skippy_"+val+".gif");
img_thread = new loadThread("thread"+index, obj.image_name+val+".gif", this, index);
img_thread.start();
// obj.tracker.addImage(pic,index);
}
value = new Integer(val);
gc = agc;
x_pos = new Integer(x);
y_pos = new Integer(y);
// RIGHT
temp = index+1;
if ((temp == 4) || ( temp == 8) || (temp ==12) || (temp==16)) {
right = -1;
}else{
right = temp;
}
// LEFT
temp = index-1;
if ((temp == 3) || (temp == 7) || (temp == 11) ) {
left = -1;
}else{
left = temp;
}
// UP
temp = index-4;
if ((temp<0)) {
up = -1;
} else {
up = temp;
}
// DOWN
temp = index+4;
if ((temp >= 16)) {
down = -1;
} else {
down = temp;
}
// !!! draw();
}
public void setImage(Image pic) {
if (pic != null) {
this.pic = pic;
}
}
// checks if a point is inside the piece
public boolean point_inside (int x, int y) {
if ((x >= x_pos.intValue()) && (y >= y_pos.intValue()) && (x <= x_pos.intValue()+width) && (y <= y_pos.intValue()+height)) {
return true;
} else {
return false;
}
}
// RETURNS TRUE IF A POINT IS IN THE SAME COL AS y
public boolean same_col(int x) {
return ((x > x_pos.intValue()) && (x < x_pos.intValue()+height));
}
// RETURNS TRUE IF A POINT IS IN THE SAME ROW AS x
public boolean same_row(int y) {
return ((y > y_pos.intValue()) && (y < y_pos.intValue()+width));
}
public boolean toLeft(piece p) {
return (x_pos.intValue() < p.x_pos.intValue());
}
public boolean toRight(piece p) {
return (x_pos.intValue() > p.x_pos.intValue());
}
public boolean above(piece p) {
return (y_pos.intValue() < p.y_pos.intValue());
}
public boolean below(piece p) {
return (y_pos.intValue() > p.y_pos.intValue());
}
public void xchg(piece blank) {
Integer temp;
Image temp_pic;
temp = value;
value = blank.value;
blank.value = temp;
if (pic != null ) {
temp_pic = pic;
pic = blank.pic;
blank.pic = temp_pic;
}
draw();
blank.draw();
}
public void draw() {
//System.out.println("In draw\n");
if (piece.value.intValue() == 16) {
gc.setColor(Color.black);
gc.fillRect(x_pos.intValue(),y_pos.intValue(),width,height);
gc.drawRect(x_pos.intValue(),y_pos.intValue(),width,height);
} else if (obj.level_indicator.level()==0) {
gc.setColor(Color.yellow);
gc.fillRect(x_pos.intValue(),y_pos.intValue(),width,height);
gc.setColor(Color.black);
gc.drawRect(x_pos.intValue(),y_pos.intValue(),width,height);
//System.out.println(value.toString());
//gc.drawString(value.toString(),(int)width/2,(int)height/2);
// gc.drawString(value.toString(),x_pos.intValue()+width/2,y_pos.intValue()+height/2);
gc.setFont(new Font("Times", Font.BOLD, 16));
gc.drawString(value.toString(),x_pos.intValue()+(width-gc.getFontMetrics().stringWidth(value.toString()))/2,y_pos.intValue()+height/2);
} else {
gc.setColor(Color.black);
gc.drawRect(x_pos.intValue(),y_pos.intValue(),width,height);
gc.drawImage(pic,x_pos.intValue(),y_pos.intValue(),null);
if (obj.level_indicator.level() == 2) {
gc.setColor(Color.yellow);
gc.setFont(new Font("Times", Font.BOLD, 16));
gc.drawString(value.toString(),x_pos.intValue()+(width-gc.getFontMetrics().stringWidth(value.toString()))/2,y_pos.intValue()+height/2);
}
}
}
}
/* THIS PUZZLE IS 1-15 IN ORDER */
abstract class puzzle_layout {
protected int win[] = new int[16];
protected int win_index, start_index;
protected int i;
puzzle puz;
puzzle_layout() {
}
// RETURN THE STARTING POSITION OF THE BLANK PIECE
public int startPos() {
return start_index;
}
// RETURN THE WINNING POSITION OF THE BLANK PIECE
public int winPos() {
return win_index;
}
// CHECKS IF THE PUZZLE IS COMPLETE
public abstract boolean puzzle_complete();
}
class simple_puzzle extends puzzle_layout {
simple_puzzle(int start_pos,puzzle puzl) {
int i;
for (i = 0; i <= (16-1); i++) {
win[i] = i+1;
}
win_index = 15;
start_index = start_pos;
puz = puzl;
}
public boolean puzzle_complete() {
int i;
if (puz.getBlankLocValue() != win_index) {
return false;
}
for (i=0; i<= (16-1); i++) {
if (puz.getLocValue(i) != win[i]) {
return false;
}
}
return true;
}
}
/*******************************************************************/
// THIS CLASS IS USED TO PROVIDE A UNIQUE RANDOM VALUE FROM
// A RANGE OF VALUES
class random_value {
int value[];
int total;
random_value(int first, int last){
int i;
total = last - first +1;
value = new int[total];
for (i=0; i<total; i++) {
value[i] = first;
first++;
}
}
int getRandomValue() {
boolean found = false;
int i;
int rand,ret;
if (total == 0) { return -1; }
if (total == 1) { total=0; return value[0]; }
i = (int) (Math.random() * total);
ret = value[i];
total--;
for (i=i;i<total;i++) {
value[i]=value[i+1];
}
return ret;
}
}
class selector {
int level;
puzzle puz;
int width=100;
int height=30;
Integer x_pos;
Integer y_pos;
selector (int lev, puzzle obj,int x, int y) {
level = lev;
puz = obj;
x_pos = new Integer(x);
y_pos = new Integer(y);
}
public int level (){
return level;
}
public void change (){
level++;
if (level > 2) { level = 0; }
}
public boolean inside (int x, int y) {
return (((x >= x_pos.intValue()) && (y >= y_pos.intValue()) && (x <= x_pos.intValue()+width) && (y <= y_pos.intValue()+height)));
}
public void paint() {
String Level;
Graphics gc = puz.myG;
//System.out.println("In level painter\n");
gc.setColor(Color.black);
gc.fillRect(x_pos.intValue(),y_pos.intValue(),width,height);
gc.setColor(Color.yellow);
gc.setFont(new Font("Times", Font.BOLD, 16));
Level = "View 1";
if (level == 1) {
Level = "View 2";
} else if (level == 2) {
Level = "View 3";
}
gc.drawString(Level,x_pos.intValue()+(width-gc.getFontMetrics().stringWidth(Level))/2,y_pos.intValue()+height/2);
}
}
/* THIS CLASS CHECKS WHETHER ALL IMAGES HAVE BEEN OBTAINED
IF NOT IT RETURNS A STRING ASKING THE USER TO WAIT.
IT EVENTUALY DISPLAYS A MESSAGE INDICATING COMPLETION OF
THE DOWNLOAD */
class media_checker extends Thread {
Graphics myG;
puzzle puz;
public media_checker(Graphics gc,puzzle puz) {
super("mediachecker");
myG = gc;
this.puz = puz;
}
public void run() {
int j;
String str;
boolean done = false;
//System.out.println("In media_checker thread\n");
while (!done) {
for (j=0; j<=15; j++) {
if (puz.pieces[j].img_thread.isAlive()) {
//System.out.println("waiting on "+j);
/*
user_waiting = true;
str = "All Images not loaded, try again soon...";
myG.setFont(new Font("Times", Font.BOLD, 8));
myG.setColor(Color.black);
myG.drawString(str,10,275);
*/
break;
}
}
if (j > 15) {
puz.images_loaded = true;
if (puz.user_waiting) {
str = "Image loading complete!!";
myG.setColor(Color.pink);
myG.fillRect(0,251,300,300);
myG.setFont(new Font("Times", Font.BOLD, 8));
myG.setColor(Color.black);
myG.drawString(str,10,275);
}
done = true;
} else {
//System.out.print("slleping cause j was ");
//System.out.println(j);
try {
sleep(1000);
} catch (InterruptedException e) {
}
//System.out.println("awake now");
}
}
}
}
/*******************************************************************/
public class puzzle extends Applet {
public piece pieces[] = new piece[16];
int i,x,y,cur_val;
int start_x=50;
int start_y=50; // start pos of puzzle
int row_size = 4;
int piece_width = 50;
int piece_height = 50;
private int blank_piece_pos;
Graphics myG;
simple_puzzle simple;
random_value value_supplier = new random_value(1,16);
MediaTracker tracker;
selector level_indicator;
Thread loadThread; // thread used to load images
String image_name;
media_checker checker;
boolean images_loaded = false;
boolean user_waiting = false;
public void init() {
myG = getGraphics();
checker = null;
tracker = new MediaTracker(this);
level_indicator = new selector(0,this,100, 5);
image_name = getParameter("PREFIX");
/* INITIALIZE THE BLANK PIECES */
x = start_x;
y = start_y;
for (i=0; i <= 15; i++) {
cur_val = value_supplier.getRandomValue();
//cur_val = i+1;
/* SET THE INITIAL POSTION OF THE BLANK PIECE */
if (cur_val == 16) {
blank_piece_pos = i;
}
//pict = getImage(getDocumentBase(),image_name+cur_val+".gif");
pieces[i] = new piece(i,cur_val,myG,x,y,null,this);
x += 50;
if (x > 200) { x = 50; y += 50; }
}
/* CREATE A NEW SIMPLE PUZZLE */
simple = new simple_puzzle(15,this);
resize(pieces[0].width*6,pieces[0].height*6);
checker = new media_checker(myG,this);
checker.start();
}
public void start()
{
/*
if (loadThread == null) {
loadThread = new Thread(this,"load");
loadThread.start();
}
*/
}
public void stop() {
//System.out.println("stop\n");
if (loadThread != null) {
loadThread.stop();
loadThread = null;
}
}
public void run() {
}
public boolean mouseDown(Event evt, int x, int y) {
int i;
int rel_x,rel_y;
int click_piece;
int cur;
String str;
// FIRST CHECK IF THE POINT IS INSIDE THE PUZZLE
if (point_inside(x,y)) {
// NOW GET THE CLICK PIECE
rel_x = (int)(x - start_x)/piece_width;
rel_y = (int)(y - start_y)/piece_height;
click_piece = rel_x + row_size * rel_y;
// IF THE CLICK POINT IS IN THE SAME ROW AS THE BLANK PIECE
if (pieces[blank_piece_pos].same_row(y)) {
if (pieces[click_piece].toLeft(pieces[blank_piece_pos])) {
cur = pieces[blank_piece_pos].left;
while (cur != pieces[click_piece].left) {
pieces[cur].xchg(pieces[blank_piece_pos]);
blank_piece_pos = cur;
cur = pieces[blank_piece_pos].left;
if (simple.puzzle_complete()) {
myG.drawString("Congratulations!!!",75,275);
}
}
} else if (pieces[click_piece].toRight(pieces[blank_piece_pos])) {
cur = pieces[blank_piece_pos].right;
while (cur != pieces[click_piece].right) {
pieces[cur].xchg(pieces[blank_piece_pos]);
blank_piece_pos = cur;
cur = pieces[blank_piece_pos].right;
if (simple.puzzle_complete()) {
myG.drawString("Congratulations!!!",75,275);
}
}
}
} else if (pieces[blank_piece_pos].same_col(x)) {
if (pieces[click_piece].above(pieces[blank_piece_pos])) {
cur = pieces[blank_piece_pos].up;
while (cur != pieces[click_piece].up) {
pieces[cur].xchg(pieces[blank_piece_pos]);
blank_piece_pos = cur;
cur = pieces[blank_piece_pos].up;
if (simple.puzzle_complete()) {
myG.drawString("Congratulations!!!",75,275);
}
}
} else if (pieces[click_piece].below(pieces[blank_piece_pos])) {
cur = pieces[blank_piece_pos].down;
while (cur != pieces[click_piece].down) {
pieces[cur].xchg(pieces[blank_piece_pos]);
blank_piece_pos = cur;
cur = pieces[blank_piece_pos].down;
if (simple.puzzle_complete()) {
myG.drawString("Congratulations!!!",75,275);
}
}
}
}
} else if (level_indicator.inside(x,y)) {
if (images_loaded == true) {
if (user_waiting == true) {
str = "Image loading complete!!";
myG.setColor(Color.pink);
myG.fillRect(0,251,300,300);
myG.setFont(new Font("Times", Font.BOLD, 8));
myG.setColor(Color.black);
myG.drawString(str,10,275);
user_waiting = false;
}
level_indicator.change();
level_indicator.paint();
paint(myG);
} else {
user_waiting = true;
str = "All Images not loaded, try again soon...";
myG.setFont(new Font("Times", Font.BOLD, 8));
myG.setColor(Color.black);
myG.drawString(str,10,275);
}
}
return true;
}
public void paint(Graphics g) {
int i;
int j;
int cur;
//System.out.println("In main paint\n");
g.setColor(Color.pink);
g.fillRect(0,0,size().width,size().height);
// System.out.println("HERE");
cur = 0;
for (i=0; i <= (15); i++) {
pieces[i].draw();
}
level_indicator.paint();
}
/*
public void update(Graphics g) {
for (i=0; i <= (15); i++) {
pieces[i].draw();
}
}
*/
// THIS ROUTINE RETURNS THE VALUE OF A LOCATION
int getLocValue(int arr_loc) {
return pieces[arr_loc].value.intValue();
}
// THIS ROUTINE RETURNS THE VALUE OF THE BLANK LOCATION
int getBlankLocValue() {
return pieces[blank_piece_pos].value.intValue();
}
public boolean point_inside (int x, int y) {
if ((x >= start_x) && (y >= start_y) && (x <= start_x+row_size*piece_width) && (y <= start_y+row_size*piece_width)) {
return true;
} else {
return false;
}
}
}
Back to the puzzle15 applet page
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|