import java.awt.*; import java.awt.image.*; import java.applet.*; import java.lang.*; public class Nim extends Applet implements Runnable{ Graphics g; Image match; int xoff, yoff; static int rowcount[] = {1,2,3,4,5}; int you, me; int state; int startrow, stoprow; int startcol, stopcol; int startx, stopx, starty; int curx, cury; int dragcount; boolean done_loading_image = false; Thread my_thread = null; boolean thread_running = false; public void init(){ you = 0; me = 0; state = 0; dragcount = 4; g = getGraphics(); match = getImage(getCodeBase(),"match.gif"); Image offScrImage = createImage(getBounds().width, getBounds().height); Graphics offScrGC = offScrImage.getGraphics(); paint1(offScrGC); repaint(); } public void start(){ if(my_thread == null) my_thread = new Thread(this); } public void run_thread(){ if(!thread_running){ my_thread.start(); thread_running = true; } } void delay() { try { Thread.sleep(500); } catch(InterruptedException e) { } } public void run(){ while(true) ; } public synchronized void mymove(){ int sum = rowcount[0]; int i, maximum, where; for(i = 1; i < 5; i++){ sum ^= rowcount[i]; } // If sum is 0, there is no good move. Just take // 1 away from a row with a maximal number of // counters and hope for the best. if(sum == 0){ maximum = rowcount[0]; where = 0; for(i = 1; i<5; i++){ if(rowcount[i] > maximum){ maximum = rowcount[i]; where = i; } } rowcount[where] -= 1; } else{ i = 0; while( (rowcount[i] ^ sum) > rowcount[i]){ i++; } rowcount[i] -=(rowcount[i] - ( rowcount[i] ^ sum )); } state = 0; if(win()){ state = 5; me++; } repaint(); } public boolean win(){ int sum = 0; int i; for(i = 0; i < 5; i++){ sum += rowcount[i]; } return sum == 0; } public void freshgame(){ int i; for(i = 0; i < 5; i++){ rowcount[i] = (int)(Math.random()*7+1); } } public boolean mouseDown(Event evt, int x, int y){ // Ignore if wrong state. if(state != 0){ return false; } // Determine start box. startrow = y/yoff; startx = x; starty = y; dragcount = 0; state = -1; return true; } public boolean mouseUp(Event evt, int x, int y){ // Ignore if wrong state. if(state == 1){ return false; } if(state == 2){ mymove(); return true; } if(state >= 4){ freshgame(); repaint(); state = 0; return true; } state = -2; stopx = x; curx = x; cury = y; // Determine stop box. stoprow = y/50; if(startrow < 0 || startrow > 4 || startrow != stoprow){ state = 0; return false; } if(startx > stopx){ int temp = startx; startx = stopx; stopx = temp; } // Start on left side of match, stop on right side. startcol = (startx +xoff/2)/xoff; stopcol = (stopx + xoff/2)/xoff; if(startcol<0){ startcol = 0; } if(stopcol < 0){ stopcol = 0; } if(startcol > rowcount[startrow]-1){ state = 0; return false; } if(startcol > stopcol){ state = 0; return false; } if(stopcol > rowcount[startrow]){ stopcol = rowcount[startrow]; } int ncols = stopcol - startcol; if(ncols > rowcount[startrow]){ ncols = rowcount[startrow]; } if(ncols < 1){ state = 0; repaint(); return false; } rowcount[startrow] -= ncols; state = 1; if(win()){ state = 4; you++; } repaint(); return true; } public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h){ if(infoflags == ALLBITS) { done_loading_image = true; repaint(); run_thread(); return false; } else return true; } public void paint(Graphics g){ if(!done_loading_image) showStatus("Loading image for nim"); else{ showStatus("Match image loaded"); paint1(g); } } public void paint1(Graphics g){ Rectangle d = getBounds(); setBackground(Color.white); g.setColor(Color.black); xoff = d.width/8; yoff = d.height/5; g.clearRect(1,1,d.width,d.height); for(int row = 0; row < 5; row++){ for(int col = 0; col < rowcount[row] ; col++){ g.drawImage(match,col*xoff+1,row*yoff+1,this); } } StringBuffer yours = new StringBuffer(); yours.append("YOU "); yours.append(you); String outyou = yours.toString(); StringBuffer mine = new StringBuffer(); mine.append("ME "); mine.append(me); String outme = mine.toString(); g.drawString(outyou,5*xoff,3*yoff/2); g.drawString(outme,5*xoff,2*yoff); if(state < 1){ g.drawString("Your move",5*xoff,yoff/2); } if(state == 1){ g.drawString("Click anywhere",5*xoff,yoff/2); g.drawString("to see my move",5*xoff,yoff); state = 2; } if(state == -1){ g.drawLine(startx, starty,curx,cury); } if(state == 4){ g.drawString("YOU WIN!",5*xoff,5*yoff/2); g.drawString("Click anywhere",5*xoff,yoff/2); g.drawString("for new game",5*xoff,yoff); } if(state == 5){ g.drawString("I WIN!",5*xoff,5*yoff/2); g.drawString("Click anywhere",5*xoff,yoff/2); g.drawString("for new game",5*xoff,yoff); } } }