classes/FaceBoard.java



import SimpleBoard;
import awt.Graphics;
import awt.Color;
import awt.Image;

/**
  顔ゲームの顔 FaceCell クラス
*/
class FaceCell {

       public FaceBoard parent;    // 親のオブジェクト
       public int i,j;               // セルのインデックス
       public int width, height;     // セルのサイズ

/**
  ゲーム盤の枠のサイズも含めた位置
*/
       public int x, y;

/**
  顔の状態
  0--empty, 1--red, 2--yellow, 3--green, 4--blue, 5--pink
*/
       public int state;

/**
  コンストラクタ(クラスの新しいデータの生成を行う)
*/
       FaceCell( FaceBoard parent, int i, int j,
                 int width, int height, int state ) {

              this.parent=parent;
              this.i=i;   this.j=j;
              this.width=width;  this.height=height;
              this.state = state;
              this.x = parent.wborder + i * width;
              this.y = parent.hborder + j * height + parent.mergin;
       }

/**
  セルの状態の設定・変更を行う関数
*/
       public void setState( int state ){

              this.state = state;
       }

/**
  セルに顔を描く関数
*/
       public void paint( Graphics g ){

              if( parent.faceImages[state] != null )
                 g.drawImage( parent.faceImages[state], x, y );

              g.paint3DRect( x, y, width, height, false, false );
       }

/**
  セルの枠を描く関数
*/
       public void paintFrame( Graphics g ){

              g.paint3DRect( x, y, width, height,
                             false, parent.check_table[i][j] );
       }

/**
  セルをクリアする関数
*/
       public void clear( Graphics g ){

              g.clearRect( x, y, width, height );
       }
}


/**
  顔ゲームのボード FaceBoard クラス
 */
class FaceBoard extends SimpleBoard {

       static final int faceNum=5;    // 顔の種類の個数

       FaceCell cell[][];             // ゲームのセル
       protected int iMax,jMax;       // セルの縦横の個数
       protected int mergin=20;       // 上下のマージン(パネル用)
       protected int wborder=20;      // 左右の枠の幅
       protected int hborder=20;      // 上下の枠の幅
       protected Image faceImages[];  // 顔のイメージ
       protected int smallWidth=24;   // 顔の横幅(小)
       protected int smallHeight=32;  // 顔の高さ(小)
       protected int bigWidth=48;     // 顔の横幅(大)
       protected int bigHeight=64;    // 顔の高さ(大)

       protected int button_width;
       protected int button_height;
       protected int button_x0;
       protected int button_y0;
       protected int button_x_mergin;

    /**
      セルの状態の表
      0--empty, 1--red, 2--yellow, 3--green, 4--blue, 5--pink
    */
       public int state[][];

    /**
      セルの状態の保存用の表
    */
       public int old_state[][];

    /**
      セルの表示を行うべきかの表
    */
       public boolean paint_table[][];

    /**
      セルを消去すべきかの表
    */
       public boolean remove_table[][];

    /**
      セルが消去の選択を受けているかの表
    */
       public boolean check_table[][];

    /**
      セルの枠の表示をすべきかの表
    */
       public boolean paint_frame_table[][];

    /**
      得点
     */
       public int score;

    /**
      セルの個数と消された個数
     */
       public int totalCellNum, totalRemovedNum;

    /**
      HTMLのデータを受け取り、Strig型からint型に変換する
     */
       protected int getIntValue( String keyword ) {
 
             String valueString = getAttribute( keyword );
             if( valueString == null )  return 0;
             Integer I = new Integer( valueString );
             if( I == null )  return 0;
 
             return I.intValue();
       }

    /**
     初期設定の関数。アプレットのサイズを設定。
     */
       protected void init() {

             super.init();    // 親のクラスで定義された処理

             iMax = getIntValue( "column" );
                if( iMax <= 0 || iMax > 30 ) iMax=30;
 
             jMax = getIntValue( "row" );
                if( jMax <= 0 || jMax > 20 ) jMax=20;


          /* サイズの調整 */
            int w = (width-2*wborder)/iMax;
            int h = (height-2*hborder-2*mergin)/jMax;

            faceImages = new Image[faceNum+1];

            if( w >= bigWidth && h >= bigHeight ) {
                 faceImages[0] = null;
                 faceImages[1] = getImage("/images/face/r.gif");
                 faceImages[2] = getImage("/images/face/y.gif");
                 faceImages[3] = getImage("/images/face/g.gif");
                 faceImages[4] = getImage("/images/face/b.gif");
                 faceImages[5] = getImage("/images/face/p.gif");
                 w=bigWidth; h=bigHeight;
             }
             else if( w >= smallWidth && h >= smallHeight ) {
 
                 faceImages[0] = null;
                 faceImages[1] = getImage("/images/face/r_h.gif");
                 faceImages[2] = getImage("/images/face/y_h.gif");
                 faceImages[3] = getImage("/images/face/g_h.gif");
                 faceImages[4] = getImage("/images/face/b_h.gif");
                 faceImages[5] = getImage("/images/face/p_h.gif");
                 w=smallWidth; h=smallHeight;
             }
             else return;

             wborder = (width - w*iMax)/2;
             hborder = (height - h*jMax)/2 - mergin;

             resize( width, height );

             state = new int[iMax][jMax];
             initTable();

             old_state = new int[iMax][jMax];
             copyTable( state, old_state );

             paint_table = new boolean[iMax][jMax];
             setTable( paint_table );

             remove_table = new boolean[iMax][jMax];
             clearTable( remove_table );

             check_table = new boolean[iMax][jMax];
             clearTable( check_table );

             paint_frame_table = new boolean[iMax][jMax];
             clearTable( paint_frame_table );

             cell = new FaceCell[iMax][jMax];
             for( int i=0; i<iMax; i++ )
                for( int j=0; j<jMax; j++ )
                   cell[i][j] = new FaceCell( this, i, j, w, h, state[i][j] );

             totalCellNum = iMax * jMax;
             totalRemovedNum = 0;
             score = -(totalCellNum);
       }

    /** 
     アプレットの表示(初期状態)を行う関数。
     */
       public void paint( Graphics g ) {

             super.paint( g );         // 親のクラスで定義された処理

             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ){
                  if( state[i][j] != 0 )
                      cell[i][j].paint( g );
                  else
                      cell[i][j].clear( g );
             }
 
             makePanel( g );
             drawScore( g );
       }

   /**  
     操作パネルの準備を行う関数。
     */
       public void makePanel( Graphics g ){

            // パネル
             g.setForeground( Color.black );
             g.paint3DRect( wborder+1, hborder+1,
                            width-wborder*2-2, mergin-2,
                            true, false );
             g.paint3DRect( wborder+1, height-hborder-mergin +1,
                            width-wborder*2-2, mergin-2,
                            true, false );

             button_width=64; button_height=mergin-4;
             button_x0=wborder+3;
             button_y0=hborder+2;
             button_x_mergin=5;

            // NewGame ボタン
             g.setForeground( Color.white );
             g.paint3DRect( button_x0, button_y0,
                            button_width, button_height, true, true );
             g.setForeground( Color.black );
             g.drawString( "NewGame", button_x0+4, button_y0+14 );
            // Undo ボタン
             g.setForeground( Color.white );
             g.paint3DRect( button_x0 + button_x_mergin + button_width,
                            button_y0,
                            button_width, button_height, true, true );
             g.setForeground( Color.black );
             g.drawString( "Undo",
                           button_x0 + button_x_mergin + button_width + 14,
                           button_y0+14 );
       } 
 
    /** 
     スコアの表示を行う関数。
     */
       public void drawScore( Graphics g ){
             g.setForeground( Color.black );
             g.paint3DRect( wborder+1, height-hborder-mergin +1,
                            width-wborder*2-2, mergin-2,
                            true, false );
             g.setForeground( Color.white );
             g.drawString( "Score: " + Integer.toString( score ),
                           wborder+6, height-hborder-mergin +16 );
       }

    /**
     セルの初期状態の表を作る
     */
       protected void initTable() {
 
             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ) {
                  state[i][j] = (int)( Math.random()*4.99 ) + 1;
               }
       }

    /**
     セルの状態を再設定する
     */
       protected void resetCells() {
 
             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ) {
                   cell[i][j].setState( state[i][j] );
               }
       }

    /**
     セルの状態の表をコピーする( int a から int b へ)
     */
       protected void copyTable( int a[][], int b[][] ) {
 
             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ) {
                  b[i][j] = a[i][j];
               } 
       }
 
    /**
     セルの状態の表をコピーする( boolean a から boolean b へ)
     */
       protected void copyTable( boolean a[][], boolean b[][] ) {
 
             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ) {
                  b[i][j] = a[i][j];
               } 
       }
 
    /**
     セルの状態の表の or を取る( boolean a と boolean b を boolean b に)
     */
       protected void orTable( boolean a[][], boolean b[][] ) {
 
             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ) {
                  b[i][j] = a[i][j] || b[i][j];
               } 
       }
 
    /**
     表をクリアする(int)
     */
       protected void clearTable( int a[][] ) {
 
             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ) {
                  a[i][j] = 0;
               } 
       }

    /**
     表をクリアする(boolean)
     */
       protected void clearTable( boolean a[][] ) {
 
             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ) {
                  a[i][j] = false;
               } 
       }

    /**
     表を全セットする(boolean)
     */
       protected void setTable( boolean a[][] ) {
 
             for( int i=0; i<iMax; i++ )
               for( int j=0; j<jMax; j++ ) {
                  a[i][j] = true;
               } 
       }
}