/**
* 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