/** * TAKE.java * * * Created: Thu Sep 24 22:59:26 1998 (for Waba B3) * * Modified: Wed May 06 (for Waba B7) * * My first Java Program!! * * @author TAKEchi Masashi * @version */ import waba.ui.*; import waba.fx.*; import waba.io.*; import waba.sys.*; /** * A control that displays an application's title. * taken from Scribble example. */ class Title extends Control { String name; Font font; public Title(String name){ this.name=name; this.font=new Font("Helvetica", Font.BOLD, 12); } public void onPaint(Graphics g){ // draw line across g.setColor(0, 0, 0); int y = this.height - 1; g.drawLine(0, y, this.width, y); y--; g.drawLine(0, y, this.width, y); // draw title FontMetrics fm = getFontMetrics(font); int boxWidth = fm.getTextWidth(name) + 8; g.fillRect(0, 0, boxWidth, y); g.setColor(255, 255, 255); g.setFont(font); g.drawText(name, 4, 2); } } // Cell class class Cell{ boolean dot; int x, y, a; public Cell(int x,int y,int a){ this.dot=false; this.x=x; this.y=y; this.a=a; } // set Cell attribute public void setCell(boolean att){ this.dot=att; } // reverse dot public void reverse(){ if(this.dot==true){ this.dot=false; } else{ this.dot=true; } } public boolean check(){ return this.dot; } public boolean contains(int x,int y){ if (x<this.x || x>=this.x+a || y<this.y || y>this.y+a){ return false; } return true; } public void paint(Graphics g){ g.setColor(0,0,0); g.fillRect(x,y,a,a); if(this.dot==false){ g.setColor(255,255,255); g.fillRect(x+1,y+1,a-2,a-2); } } } // Random class class Random{ byte xn,a,b,c; public Random(){ // Default constructor uses time as start number Time t=new Time(); a=3; b=7; c=127; xn=(byte)(t.second%c); } // generate random number public byte getRandom(byte n){ xn=(byte)(((xn*a)+b)%c); return (byte)(xn%n); } } // Random // Board class class Board extends Control{ // (XMAX * YMAX) must less than 127! final byte XMAX=6; final byte YMAX=5; final byte CELLSIZE=22; final String CATALOGNAME=new String("hqVk.DATA"); private Graphics graphics; private Cell[][] Cells=new Cell[XMAX][YMAX]; private Cell[][] StartCells=new Cell[XMAX][YMAX]; private byte Qlevel=0; private byte Left=0; private Random rand=new Random(); public Board(){ clear(); loadState(); } public void added(){ graphics=createGraphics(); } // initialize public void loadState(){ Catalog c=new Catalog(CATALOGNAME,Catalog.READ_ONLY); if(!c.isOpen() || c.getRecordCount()==0 || !c.setRecordPos(0)){ return; } byte[] b=new byte[XMAX*YMAX*2+2]; c.readBytes(b,0,XMAX*YMAX*2+2); c.close(); int i=0; for(byte x=0;x<XMAX;x++){ for(byte y=0;y<YMAX;y++){ if(b[i]==1){ Cells[x][y].setCell(true); } else{ Cells[x][y].setCell(false); } i++; if(b[i]==1){ StartCells[x][y].setCell(true); } else{ StartCells[x][y].setCell(false); } i++; } } Qlevel=b[i++]; Left=b[i]; } // save current status. public void saveState(){ Catalog c=new Catalog(CATALOGNAME,Catalog.CREATE); if(!c.isOpen()){ return; } if(c.getRecordCount()!=XMAX*YMAX*2+2){ c.addRecord(XMAX*YMAX*2+2); } c.setRecordPos(0); byte[] b=new byte[XMAX*YMAX*2+2]; int i=0; for(byte x=0;x<XMAX;x++){ for(byte y=0;y<YMAX;y++){ if(Cells[x][y].check()){ b[i]=1; } else{ b[i]=0; } i++; if(StartCells[x][y].check()){ b[i]=1; } else{ b[i]=0; } i++; } } b[i++]=Qlevel; b[i]=Left; c.writeBytes(b,0,XMAX*YMAX*2+2); c.close(); } public void nextGame(){ Sound.beep(); // init start pattern for(byte x=0;x<XMAX;x++){ for(byte y=0;y<YMAX;y++){ StartCells[x][y].setCell(false); } } Left=0; while(Left==0){ // make pattern for(byte i=0;i<Qlevel;i++){ byte x=rand.getRandom(XMAX); byte y=rand.getRandom(YMAX); if(x>=0 && x<XMAX && y>=0 && y<YMAX){ StarReverse(x,y,false); StartCells[x][y].reverse(); } } } this.onPaint(graphics); } public void resetGame(){ Sound.beep(); for(byte x=0;x<XMAX;x++){ for(byte y=0;y<YMAX;y++){ Cells[x][y].setCell(false); } } Left=0; for(byte x=0;x<XMAX;x++){ for(byte y=0;y<YMAX;y++){ if(StartCells[x][y].check()){ StarReverse(x,y,false); } } } } public void onPaint(Graphics g){ for(char x=0;x<XMAX;x++){ for(char y=0;y<YMAX;y++){ Cells[x][y].paint(graphics); } } showStatus(); } public void clear(){ Sound.beep(); for(byte x=0;x<XMAX;x++){ for(byte y=0;y<YMAX;y++){ Cells[x][y]=new Cell(x*CELLSIZE+15,y*CELLSIZE+15,CELLSIZE-2); StartCells[x][y]=new Cell(x*CELLSIZE+15,y*CELLSIZE+15,CELLSIZE-2); } } Left=0; Qlevel=0; } public void OneReverse(byte x,byte y,boolean look){ if(x>=0 && x<XMAX && y>=0 && y<YMAX){ Cells[x][y].reverse(); if(look==true){ Cells[x][y].paint(graphics); } if(Cells[x][y].check()==true){ Left++; } else{ Left--; } } else{ return; } } // reverse public void StarReverse(byte x,byte y,boolean look){ Sound.beep(); OneReverse(x,y,look); OneReverse((byte)(x-1),y,look); OneReverse((byte)(x+1),y,look); OneReverse(x,(byte)(y-1),look); OneReverse(x,(byte)(y+1),look); } public void onEvent(Event event){ if(event.type==PenEvent.PEN_DOWN){ PenEvent pe=(PenEvent)event; for(byte i=0;i<XMAX;i++){ for(byte j=0;j<YMAX;j++){ if(Cells[i][j].contains(pe.x,pe.y)){ StarReverse(i,j,true); } } } showStatus(); } } public void showStatus(){ if(Left==0){ // clear? graphics.setColor(255,255,255); graphics.fillRect(0,0,width,14); graphics.setColor(0,0,0); graphics.drawText("Wait a moment...",3,2); Qlevel++; nextGame(); } graphics.setColor(255,255,255); graphics.fillRect(0,0,width,14); graphics.setColor(0,0,0); graphics.drawText("Level."+Convert.toString(Qlevel) +" Left."+Convert.toString(Left), 3, 2); } } // TAKE! main class public class TAKE extends MainWindow{ static final int PLAY=0; static final int ABOUT=1; private Board board; private Button closeButton; private Button resetButton; private Button fullResetButton; int state=PLAY; public TAKE() { Title title=new Title("TAKE!"); title.setRect(0,0,this.width,15); add(title); closeButton=new Button("Close"); closeButton.setRect(0,this.height-15,44,15); add(closeButton); resetButton=new Button("Try again"); resetButton.setRect(46,this.height-15,44,15); add(resetButton); fullResetButton=new Button("Full reset"); fullResetButton.setRect(92,this.height-15,44,15); add(fullResetButton); board=new Board(); board.setRect(0,15,this.width,this.height-40); add(board); board.added(); } public void onExit(){ board.saveState(); } public void onEvent(Event event){ if (event.type==ControlEvent.PRESSED){ if(event.target==closeButton){ exit(0); } else if(event.target==resetButton){ board.resetGame(); this.repaint(); } else if(event.target==fullResetButton){ board.clear(); this.repaint(); } } else if(event instanceof KeyEvent){ KeyEvent e=(KeyEvent)event; if (e.key==IKeys.MENU || e.key=='i'){ drawAbout(new Graphics(this),state!=ABOUT); } } else if(event instanceof PenEvent){ PenEvent e=(PenEvent)event; switch(e.type){ case PenEvent.PEN_DOWN: if(state==ABOUT){ drawAbout(new Graphics(this),false); return; } } } } public void drawRect(Graphics g,int x,int y,int w,int h){ g.setColor(255,255,255); g.fillRect(x,y,w,h); g.setColor(0,0,0); w--; h--; g.drawLine(x,y,x+w,y); g.drawLine(x+w,y,x+w,y+h); g.drawLine(x,y,x,y+h); g.drawLine(x,y+h,x+w,y+h); } public void drawCenteredText(Graphics g,String s,int x,int y){ FontMetrics fm=getFontMetrics(defaultFont); g.drawText(s,x-fm.getTextWidth(s)/2,y-fm.getAscent()/2); } public void drawAbout(Graphics g,boolean b){ int w=width; int h=height/2; if(b){ Sound.beep(); Sound.tone(2000,200); Sound.tone(4000,200); g.translate(0,height/4); state=ABOUT; drawRect(g,0,0,w,h); drawCenteredText(g,"TAKE! v.2.0",w/2,h/5); drawCenteredText(g,"by TAKEchi Masashi",w/2,2*h/5); drawCenteredText(g,"take@TAKEchon.NET",w/2,3*h/5); drawCenteredText(g,"http://www.TAKEchon.NET/",w/2,4*h/5); g.translate(0,-height/4); } else{ state=PLAY; damageRect(0,height/4,w,h); } } } // TAKE