classes/FaceGame.java
import FaceBoard;
import BoardCell;
import awt.Graphics;
import awt.Color;
import awt.Image;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.StringTokenizer;
/**
顔ゲーム FaceGame クラス
*/
class FaceGame extends FaceBoard {
public int removedNum=0;
public boolean undoFlag=false;
protected int old_score;
protected int old_i=-1, old_j=-1;
protected FaceCell removableCell=null; // 少なくとも1つはある消せるセル
protected boolean showHighScoreFlag=false;
protected String highScoreFile=null;
public FileInputStream inputScore;
public FileOutputStream outputScore;
/**
初期設定の関数。アプレットのサイズを設定。
*/
protected void init() {
super.init(); // 親のクラスで定義された処理
old_score = score;
highScoreFile = getAttribute("highscorefile");
if( highScoreFile == null )
highScoreFile = "/home/net/staff/tatsuo/www/kouki95/11shuu/score";
}
/**
アプレットの表示(初期状態)を行う関数。
*/
public void paint( Graphics g ) {
super.paint( g ); // 親のクラスで定義された処理
}
/**
アプレットの再表示を行う関数。
*/
public void update( Graphics g ) {
for( int i=0; i<iMax; i++ )
for( int j=0; j<jMax; j++ ){
if( paint_table[i][j] == true )
if( state[i][j] != 0 )
cell[i][j].paint( g );
else
cell[i][j].clear( g );
}
if( score != old_score || undoFlag == false )
drawScore( g );
drawFrame( g );
if( showHighScoreFlag )
drawHighScore( g );
}
/**
アプレットの周囲の枠を表示する関数。
*/
public void drawFrame( Graphics g ) {
g.setForeground( Color.black );
for( int i=0; i<iMax; i++ )
for( int j=0; j<jMax; j++ ){
if( paint_frame_table[i][j] == true ) {
if( state[i][j] != 0 )
cell[i][j].paintFrame( g );
}
}
}
/**
ファイルから一行読み込む関数。
*/
public int getLine( char buf[] ) {
for( int i=0; i<52; i++ ) {
buf[i] = (char)inputScore.read();
}
return 51;
}
/**
ファイルに一行書き出す関数。
*/
public void putLine( String str ) {
for( int i=0; i<str.length(); i++ ) {
outputScore.write( (int)( str.charAt(i) ) );
}
outputScore.write( (int)'\n' );
}
/**
ハイスコアのウィンドウを表示する関数。
*/
public void drawHighScore( Graphics g ) {
char buf[][];
int length;
String lines[];
String fields1[];
String fields2[];
String fields3[];
String words[];
Integer si[];
int scores[];
buf = new char[10][80];
lines = new String[10];
fields1 = new String[10];
fields2 = new String[10];
fields3 = new String[10];
words = new String[10];
si = new Integer[10];
scores = new int[10];
boolean insertFlag=true;
String newscore=null;
inputScore = new FileInputStream( highScoreFile );
for( int j=0; j<10; j++ ){
g.setForeground( Color.white );
g.paint3DRect( (width-420)/2, (height-200)/2 + j*20,
420, 20, true, false );
length = getLine( buf[j] );
lines[j] = new String( buf[j], 0, length );
g.setForeground( Color.black );
g.drawString( lines[j],
(width-420)/2 + 4,
(height-200)/2 + j*20 + 17 );
}
inputScore.close();
inputScore = null;
for( int j=0; j<10; j++ ){
fields1[j] = lines[j].substring( 0, 2 );
fields2[j] = lines[j].substring( 3, 44 );
fields3[j] = lines[j].substring(46);
for( int i=0; i<5; i++ ){
if( fields3[j].charAt(i) != ' '){
words[j] = fields3[j].substring( i );
break;
}
}
si[j] = new Integer( words[j] );
scores[j] = si[j].intValue();
}
if( score <= scores[9] ) return;
outputScore = new FileOutputStream( highScoreFile );
newscore = " " + score;
for( int j=0; j<10; j++ ){
g.setForeground( Color.white );
g.paint3DRect( (width-420)/2, (height-200)/2 + j*20,
420, 20, true, false );
g.setForeground( Color.black );
if( score < scores[j] ){
putLine( lines[j] );
g.drawString( lines[j],
(width-420)/2 + 4,
(height-200)/2 + j*20 + 17 );
}
else if( insertFlag ){
putLine( fields1[j] + ":" + fields2[j] + ": " +
newscore.substring( newscore.length()-5,
newscore.length() ) );
g.drawString(
fields1[j] + ":" + fields2[j] + ": " +
newscore.substring( newscore.length()-5,
newscore.length() ),
(width-420)/2 + 4,
(height-200)/2 + j*20 + 17 );
insertFlag = false;
}
else {
putLine( fields1[j] + ":" + fields2[j-1] + ": " + fields3[j-1]);
g.drawString(
fields1[j] + ":" + fields2[j-1]
+ ": " + fields3[j-1],
(width-420)/2 + 4,
(height-200)/2 + j*20 + 17 );
}
}
outputScore.close();
outputScore = null;
}
/**
セルの状態変化を調べる
*/
protected void checkCell( int i, int j,
int given_state, boolean given_table[][] ) {
// if( i<0 || i>=iMax || j<0 || j>=jMax ) return;
// if( given_table[i][j] == 0 ) return;
if( state[i][j] == 0 ) return;
if( state[i][j] != given_state ) return;
else {
given_table[i][j] = true;
if( (i-1) >= 0 && given_table[i-1][j] == false ) {
checkCell( i-1, j, given_state, given_table );
}
if( (i+1) < iMax && given_table[i+1][j] == false ) {
checkCell( i+1, j, given_state, given_table );
}
if( (j-1) >= 0 && given_table[i][j-1] == false ) {
checkCell( i, j-1, given_state, given_table );
}
if( (j+1) < jMax && given_table[i][j+1] == false ) {
checkCell( i, j+1, given_state, given_table );
}
}
}
/**
セルの状態を再設定する
*/
protected void resetCells() {
for( int i=0; i<iMax; i++ )
for( int j=0; j<jMax; j++ ) {
cell[i][j].setState( state[i][j] );
}
}
/**
セルの消去を実行する
*/
protected void removeCells() {
removedNum=0;
for( int i=0; i<iMax; i++ ) {
for( int j=0; j<jMax; j++ ) {
if( remove_table[i][j] == true ) {
state[i][j] = 0;
paint_table[i][j] = true;
removedNum++;
}
else
paint_table[i][j] = false;
}
}
addScore();
resetCells();
}
/**
イメージの落下と左寄せを実行する
*/
protected void fallDownCells() {
boolean flag;
for( int i=0; i<iMax; i++ ) {
if( state[i][0] == 0 ) {
paint_table[i][0] = true;
}
for( int j=1; j<jMax; j++ ) {
if( state[i][j] == 0 ) {
for( int k=j; k>0; k-- ) {
state[i][k] = state[i][k-1];
paint_table[i][k] = true;
paint_table[i][k-1] = true;
}
state[i][0]=0;
paint_table[i][0] = true;
}
}
}
for( int i=iMax-2; i>=0; i-- ) {
flag = true;
for( int j=0; j<jMax; j++ ) {
if( state[i][j] != 0 ) flag = false;
}
if( flag ) {
for( int m=i; m<iMax-1; m++ )
for( int k=0; k<jMax; k++ ){
state[m][k]=state[m+1][k];
paint_table[m][k] = true;
paint_table[m+1][k] = true;
}
for( int k=0; k<jMax; k++ ){
state[iMax-1][k]=0;
paint_table[iMax-1][k] = true;
}
}
}
resetCells();
}
/**
マウスがクリックされた時の処理
*/
public void mouseDown( int x, int y ) {
if( x>wborder && x<width-wborder
&& y>hborder+mergin && y<height-hborder-mergin ) {
int i = ( x - wborder )/cell[0][0].width;
int j = ( y - hborder - mergin )/cell[0][0].height;
if( state[i][j] == 0 ) return;
if( isRemovable( i, j ) ) {
copyTable( state, old_state );
undoFlag = false;
clearTable( remove_table );
checkCell( i, j, state[i][j], remove_table );
removeCells();
clearTable( check_table );
//repaint();
fallDownCells();
undoFlag = true;
if ( isGameOver() ) {
undoFlag = false;
showHighScoreFlag = true;
}
repaint();
}
else return;
}
// NewGameボタン
else if( x>button_x0 && x<button_x0+button_width
&& y>button_y0 && y<button_y0+button_height ) {
showHighScoreFlag = false;
setTable( paint_table );
clearTable( remove_table );
clearTable( check_table );
initTable();
resetCells();
score = -(totalCellNum);
copyTable( state, old_state );
undoFlag = false;
repaint();
}
// Undoボタン
else if( x>button_x0 + button_width + button_x_mergin
&& x<button_x0 + button_width*2 + button_x_mergin
&& y>button_y0 && y<button_y0+button_height ) {
if( undoFlag ) {
setTable( paint_table );
clearTable( remove_table );
clearTable( check_table );
copyTable( old_state, state );
score = old_score;
resetCells();
undoFlag = false;
repaint();
}
}
}
/**
スコアの計算
*/
protected void addScore() {
old_score = score;
score += (removedNum-1)*(removedNum-1);
}
/**
マウス・カーソルが移動した時の処理
*/
public void mouseMove( int x, int y ) {
if( x>wborder && x<width-wborder
&& y>hborder+mergin && y<height-hborder-mergin ) {
int i = ( x - wborder )/cell[0][0].width;
int j = ( y - hborder - mergin )/cell[0][0].height;
if( state[i][j] == 0 ) return;
if( i == old_i && j == old_j ) return;
if( isRemovable( i, j ) ) {
copyTable( check_table, paint_frame_table );
clearTable( check_table );
checkCell( i, j, state[i][j], check_table );
orTable( check_table, paint_frame_table );
clearTable( paint_table );
repaint();
}
old_i=i; old_j=j;
}
}
/**
4方をチェックしてセルが消去可能かチェックする処理
*/
public boolean isRemovable( int i, int j ) {
boolean flag=false;
if( state[i][j] == 0 ) return false;
if( (i-1) >= 0 )
flag = flag || ( state[i-1][j] == state[i][j] );
if( (i+1) <iMax )
flag = flag || ( state[i+1][j] == state[i][j] );
if( (j-1) >= 0 )
flag = flag || ( state[i][j-1] == state[i][j] );
if( (j+1) <jMax )
flag = flag || ( state[i][j+1] == state[i][j] );
return flag;
}
/**
ゲームが終了したか判定する処理
*/
public boolean isGameOver() {
int m=0,n=0;
boolean flag=false;
if( removableCell != null ) {
if( isRemovable( removableCell.i, removableCell.j ) )
return false;
}
for( int i=0; i<iMax; i++ ) {
for( int j=jMax-1; j>=0; j-- ) {
if( state[i][j]==0 ) continue;
if( isRemovable( i, j ) ) {
m=i; n=j;
flag = true;
break;
}
}
if( flag ) break;
}
if( flag ){
if( removableCell != null ){
removableCell.i=m; removableCell.j=n;
}
else{
removableCell = new FaceCell( this, m, n,
cell[0][0].width, cell[0][0].height,
0 );
}
}
return (!flag);
}
}