import com.nttdocomo.io.ConnectionException; import com.nttdocomo.ui.*; import javax.microedition.io.*; import java.util.Random; import java.io.*; public class lines extends IApplication{ public void start(){ gCanvas c = new gCanvas(this); Display.setCurrent(c); } } class gCanvas extends Canvas{ private IApplication _app; private java.util.Random randobj = new java.util.Random(); private Graphics g = this.getGraphics(); //マスをあらわす二次元配列 private byte masu[][] = new byte[9][9]; //カーソルがどこにあるのか private int cursor[] = new int[2]; //次に盤上に置かれるボールの色 private byte nextBall[] = new byte[3]; private final byte blank = 0; //選択したマス private int ChoicedBall[] = new int[2]; //ボールの終点 private int BallDis[] = new int[2]; //移動中のボールがどこにあるのか private int MBallPlace[] = new int[2]; //置いたボールの種類を覚えておく変数 private byte kind = 0; //スコア private int score; //ハイスコア private int HighScore; //今のゲーム状態 1:タイトル画面表示 0:初期状態にする 5:ゲーム中 10:ゲーム終了時 private int status; //スクラッチパッド関係 final int SP_SIZE = 512; //どこかマスを選択してるかどうか private boolean set =false; //消せるかどうかの判定フラッグ private boolean eraseOK = false; //選択できるかどうかのフラッグ private boolean ChoiceOK = true; //おいたボール自身を消したかどうか private boolean Here = false; //ハイスコアより大きいかどうかのフラッグ private boolean High = false; //gif画像 private Image[] img; //コンストラクタ gCanvas (IApplication app){ _app = app; setSoftLabel(Frame.SOFT_KEY_1,"終了"); //背景 setBackground(Graphics.getColorOfName(g.SILVER)); //gifの読み込み img = new Image[8]; for (int i=0;i<8;i++){ MediaImage mi = MediaManager.getImage("resource:///"+(i)+".gif"); try{ mi.use(); }catch(ConnectionException ce){} catch(UIException uie) {} img[i] = mi.getImage(); } status = 1; loopGame(); } //ゲーム中のメソッド private void loopGame(){ int x,y; switch(status){ //初期状態を作る case 0: //スコアの初期化 score = 0; HighScore = 0; High = false; //選択できるかどうか当然、最初はできる ChoiceOK = true; //ボードの初期化全部ブランクにしておく for(x=0;x<9;x++){ for(y=0;y<9;y++){ masu[x][y] = blank; } } //最初に置くボールを選ぶ NextBallChoice(); //その選んだボールを置く putBall(); //で、その次のボールを選んでおく NextBallChoice(); //初期状態ができたら、ゲームへ status = 5; eraseOK = false; break; //ゲーム中 case 5: // save(); kind = masu[BallDis[0]][BallDis[1]]; AfterPut(BallDis[0],BallDis[1]); if(eraseOK) eraseOK = false; else{ putBall(); NextBallChoice(); } //空いてるマスがなくなったら、ゲーム終了 if(BlankNum() == 0) finGame(); } } public void paint(Graphics g){ if(status == 1){ g.lock(); setSoftLabel(Frame.SOFT_KEY_2,"再開"); g.drawImage(img[6],0,0); g.setColor(g.getColorOfName(g.BLUE)); g.drawString("Press anykey",30,90); g.setColor(g.getColorOfName(g.BLACK)); //バージョンの表示 g.drawString("Ver 1.51",60,70); g.unlock(true); } else{ //ボールが選択されてる時 if(set) setSoftLabel(Frame.SOFT_KEY_2,"解除"); //されてない時 else setSoftLabel(Frame.SOFT_KEY_2,"新規"); //ゲームが終了 if(status == 10){ g.lock(); g.clearRect(0,0,getWidth(),getHeight()); //もし、ハイスコアを更新していれば、HighScore画像を表示 if(High){ g.drawImage(img[7],5,80); } g.drawString("GAME OVER",30,40); g.drawString("Score:"+(score),30,50); g.drawString("ハイスコア:"+(HighScore),30,70); g.unlock(true); } //ゲーム中 else{ g.lock(); g.clearRect(0,0,getWidth(),getHeight()); //マスと"次"だけを表示 DrawST(); //スコア部分の表示 g.drawString("スコア:"+(score),0,120); //まだボールが選択されてないのなら、 //カーソルを表示させる if(set == false) g.drawImage(img[0],(cursor[0]*12)+1,(cursor[1]*12)+1); //masu[][]に入ってるとおりに、表示する DrawPuttingBall(); //次に勝手に置かれるボールを表示する DrawNextBall(); //動けないボールを選択しようとすると if(!ChoiceOK) //"動けません"と表示 g.drawString("動けません",60,120); ChoiceOK = true; g.unlock(true); } } } //置いた左側に同じ色がいくつあるか調べる private int CheckL(int x,int y){ int n = 0; int i =1; while(x-i >= 0){ if(kind == masu[x-i][y]){ n++; } else break; i++; } return n; } //置いた右側に同じ色がいくつあるかを調べる private int CheckR(int x,int y){ int n = 0; int i = 1; while(x+i < 9){ if(kind == masu[x+i][y]) n++; else break; i++; } return n; } //置いた上側に同じ色がいくつあるかを調べる、 private int CheckU(int x,int y){ int n = 0; int i = 1; while(y-i >= 0){ if(kind == masu[x][y-i]) n++; else break; i++; } return n; } //置いた下側に同じ色がいくつあるかを調べる private int CheckD(int x,int y){ int n = 0; int i = 1; while(y+i < 9){ if(kind == masu[x][y+i]) n++; else break; i++; } return n; } //置いた左上側に同じ色がいくつあるか調べる private int CheckLU(int x,int y){ int n = 0; int i =1; while(x-i >= 0 && y-i >= 0){ if(kind == masu[x-i][y-i]){ n++; } else break; i++; } return n; } //置いた左下側に同じ色がいくつあるか調べる private int CheckLD(int x,int y){ int n = 0; int i =1; while(x-i >= 0 && y+i < 9){ if(kind == masu[x-i][y+i]){ n++; } else break; i++; } return n; } //置いた右上側に同じ色がいくつあるか調べる private int CheckRU(int x,int y){ int n = 0; int i =1; while(x+i < 9 && y-i >= 0){ if(kind == masu[x+i][y-i]){ n++; } else break; i++; } return n; } //置いた右下側に同じ色がいくつあるか調べる private int CheckRD(int x,int y){ int n = 0; int i =1; while(x+i < 9 && y+i <9){ if(kind == masu[x+i][y+i]){ n++; } else break; i++; } return n; } //置いたボールを消す private void eraseHere(int x,int y){ masu[x][y] = blank; Here = true; } //ヨコ方向を消す private void eraseSid(int x,int y){ int i,n=0; int l,r; l = CheckL(x,y); r = CheckR(x,y); n += l+r+1; eraseHere(x,y); masu[x][y] = blank; //左を消す for (i=1;i<=l;i++) masu[x-i][y] = blank; //右を消す for (i=1;i<=r;i++) masu[x+i][y] = blank; switch (n){ case 5: score += 10; break; case 6: score += 12; break; case 7: score += 18; break; case 8: score += 28; break; case 9: score +=42; } eraseOK = true; } //縦方向を消す private void eraseLen(int x,int y){ int i,n=0; int u,d; u = CheckU(x,y); d = CheckD(x,y); eraseHere(x,y); n += u+d+1; //上を消す for (i=1;i<=u;i++) masu[x][y-i] = blank; //下を消す for (i=0;i<=d;i++) masu[x][y+i] = blank; switch (n){ case 5: score += 10; break; case 6: score += 12; break; case 7: score += 18; break; case 8: score += 28; break; case 9: score +=42; } eraseOK = true; } //右下がり方向を消す private void eraseBS(int x,int y){ int i,n=0; int LU,RD; LU = CheckLU(x,y); RD = CheckRD(x,y); eraseHere(x,y); n += LU+RD+1; //左上を消す for (i=1;i<=LU;i++) masu[x-i][y-i] = blank; //右下を消す for (i=0;i<=RD;i++) masu[x+i][y+i] = blank; switch (n){ case 5: score += 10; break; case 6: score += 12; break; case 7: score += 18; break; case 8: score += 28; break; case 9: score +=42; } eraseOK = true; } //右上がり方向を消す private void eraseS(int x,int y){ int i,n=0; int LD,RU; LD = CheckLD(x,y); RU = CheckRU(x,y); eraseHere(x,y); n += LD+RU+1; //右上を消す for (i=1;i<=RU;i++) masu[x+i][y-i] = blank; //左下を消す for (i=0;i<=LD;i++) masu[x-i][y+i] = blank; switch (n){ case 5: score += 10; break; case 6: score += 12; break; case 7: score += 18; break; case 8: score += 28; break; case 9: score +=42; } eraseOK = true; } public void processEvent(int type, int param){ byte swap; super.processEvent(type, param); /* //電話がかかってきたり、メール受信による //強制終了があった場合セーブする if(Display.RESUME_VM_EVENT == type){ save(); }*/ if (Display.KEY_PRESSED_EVENT == type){ if(status == 1){ status = 0; loopGame(); } //ボールが選択されてるとき(ボールが動く) if(set){ switch(param){ case Display.KEY_SOFT1: _app.terminate(); break; case Display.KEY_SOFT2: cursor[0] = ChoicedBall[0]; cursor[1] = ChoicedBall[1]; swap = masu[MBallPlace[0]][MBallPlace[1]]; //今いる場所を元に戻す masu[MBallPlace[0]][MBallPlace[1]] = blank; //もとあった場所に返す masu[cursor[0]][cursor[1]] = swap; set = !set; break; case Display.KEY_LEFT: //左にまだマスがあって、左にボールがないなら移動する if(MBallPlace[0] != 0 && masu[MBallPlace[0]-1][MBallPlace[1]]==blank){ masu[MBallPlace[0]-1][MBallPlace[1]] = masu[MBallPlace[0]][MBallPlace[1]]; masu[MBallPlace[0]][MBallPlace[1]] = blank; MBallPlace[0]--; } break; case Display.KEY_RIGHT: //右に,まだマスがあって、右にボールがないなら移動する if(MBallPlace[0] !=8 && masu[MBallPlace[0]+1][MBallPlace[1]]==blank){ masu[MBallPlace[0]+1][MBallPlace[1]] = masu[MBallPlace[0]][MBallPlace[1]]; masu[MBallPlace[0]][MBallPlace[1]] = blank; MBallPlace[0]++; } break; case Display.KEY_UP: //上 if(MBallPlace[1] != 0 && masu[MBallPlace[0]][MBallPlace[1]-1]==0){ masu[MBallPlace[0]][MBallPlace[1]-1] = masu[MBallPlace[0]][MBallPlace[1]]; masu[MBallPlace[0]][MBallPlace[1]] = blank; MBallPlace[1]--; } break; case Display.KEY_DOWN: //下 if(MBallPlace[1] != 8 && masu[MBallPlace[0]][MBallPlace[1]+1]==0){ masu[MBallPlace[0]][MBallPlace[1]+1] = masu[MBallPlace[0]][MBallPlace[1]]; masu[MBallPlace[0]][MBallPlace[1]] = blank; MBallPlace[1]++; } break; case Display.KEY_SELECT: if(cursor[0] != MBallPlace[0] || cursor[1] != MBallPlace[1]){ BallDisCh(); cursor[0] = BallDis[0]; cursor[1] = BallDis[1]; set = !set; loopGame(); } } } //ボールが選択されてないとき else{ switch(param) { case Display.KEY_SOFT1: _app.terminate(); break; case Display.KEY_SOFT2: status = 0; loopGame(); break; case Display.KEY_LEFT: if(cursor[0] != 0) cursor[0]--; break; case Display.KEY_RIGHT: if(cursor[0] != 8) cursor[0]++; break; case Display.KEY_UP: if(cursor[1] != 0) cursor[1]--; break; case Display.KEY_DOWN: if(cursor[1] != 8) cursor[1]++; break; case Display.KEY_SELECT: if(masu[cursor[0]][cursor[1]] != blank){ ChoiceOK = MoveOK(); if(MoveOK()){ setmasu(); set = !set; } } } } repaint(); } } //何もない状態のマスと、Score:、次だけ表示 private void DrawST(){ // g.clearRect(0,0,getWidth(),getHeight()); //スコア // g.drawString("スコア:",0,120); //次の玉 g.drawString("次",109,21); for (int i=0;i<10;i++){ //縦線 g.drawLine(i*12,0,i*12,108); //横線 g.drawLine(0,i*12,108,i*12); } } //masu[][]に入ってる通りにすべて表示する private void DrawPuttingBall(){ int x,y; for (x=0;x<9;x++){ for(y=0;y<9;y++) DrawBall(x,y); } } //マス目を指定して、そこにmasu[][]の通りに表示する private void DrawBall(int x, int y){ if(masu[x][y] != blank) g.drawImage(img[masu[x][y]],(x*12)+1,(y*12)+1); } //あいてるマスの数を数える private int BlankNum(){ int x,y; int n=0; for(x=0;x<9;x++){ for(y=0;y<9;y++){ if(masu[x][y] == blank) n++; } } return n; } private void finGame(){ status = 10; //ハイスコアより大きかったら、今のスコアをスクラッチパッドに出力 readSP(); if(score > HighScore){ HighScore = score; High = true; writeSP(); } } //置いた後の処理 private void AfterPut(int x,int y){ if(CheckL(x,y)+CheckR(x,y) > 3) eraseSid(x,y); if(CheckU(x,y)+CheckD(x,y) > 3) eraseLen(x,y); if(CheckLU(x,y) + CheckRD(x,y) > 3) eraseBS(x,y); if(CheckRU(x,y) + CheckLD(x,y) > 3) eraseS(x,y); } //次に盤上に置かれるボールを予告表示する private void DrawNextBall(){ for(int i=0;i<3;i++) g.drawImage(img[nextBall[i]],109,23+(i*12)); } //次に盤上に置かれるボールを選ぶ private void NextBallChoice(){ for (int i = 0;i < 3;i++) nextBall[i] = (byte)randInt(5); } //カーソルの位置を固定して、ボールの現在地を決める private void setmasu(){ //カーソルの位置を固定解除したときにはこの位置に戻る ChoicedBall[0] = cursor[0]; ChoicedBall[1] = cursor[1]; //今のボール位置はカーソルの位置と同じだよってこと MBallPlace[0] = cursor[0]; MBallPlace[1] = cursor[1]; } //選んだボールは動けるのかどうかを調べる、動けるならtrue、だめならfalse private boolean MoveOK(){ if(cursor[0] == 0){ //一番左にあった場合 if(cursor[1] == 0){ //でもって一番上にあった場合 if(masu[1][0] != blank && //右チェック masu[0][1] != blank) //下チェック return false; } else if(cursor[1] == 8){//でもって一番下にあった場合 if(masu[1][8] != blank && //右チェック masu[0][7] != blank) //上チェック return false; } else{ //それ以外のところ if(masu[1][cursor[1]] != blank && // masu[0][cursor[1]-1] != blank && // masu[0][cursor[1]+1] != blank) // return false; } } if(cursor[1] == 0){ //一番上にあった場合 if(cursor[0] == 8){ //でもって一番右にあった場合 if(masu[7][0] != blank && //左をチェック masu[8][1] != blank) //下をチェック //どっちかにボールがあったら、falseを返す return false; } else if(cursor[0] == 0){ //でもって一番左にあったとき if(masu[1][0] != blank && //右をチェック masu[0][1] != blank) //下をチェック return false; } else{ //それ以外 if(masu[cursor[0]-1][cursor[1]] != blank && masu[cursor[0]][cursor[1]+1] != blank && masu[cursor[0]+1][cursor[1]] != blank) return false; } } if(cursor[0] == 8){ //一番右にあった場合 if(cursor[1] == 8){ //でもって一番下にあった場合 if(masu[cursor[0]-1][cursor[1]] != blank && masu[cursor[0]][cursor[1]-1] != blank) return false; } else if(cursor[1] == 0){//上にあった場合 if(masu[cursor[0]-1][cursor[1]] != blank && masu[cursor[0]][cursor[1]+1] != blank) return false; } else{ //それ以外 if(masu[cursor[0]][cursor[1]-1] != blank && masu[cursor[0]-1][cursor[1]] != blank && masu[cursor[0]][cursor[1]+1] != blank ) return false; } } if(cursor[1] == 8){ //一番下にあった場合 if(cursor[0] == 0){ //でもって左 if(masu[cursor[0]][cursor[1]-1] != blank && masu[cursor[0]+1][cursor[1]] != blank) return false; } else if(cursor[0] == 8){ //でもって右 if(masu[cursor[0]-1][cursor[1]] != blank && masu[cursor[0]][cursor[1]-1] != blank) return false; } else{ if(masu[cursor[0]-1][cursor[1]] != blank && masu[cursor[0]][cursor[1]-1] != blank && masu[cursor[0]+1][cursor[1]] != blank ) return false; } } if(cursor[0] != 0 && cursor[0] != 8 && cursor[1] != 0 && cursor[1]!= 8){ if(masu[cursor[0]-1][cursor[1]] != blank && masu[cursor[0]][cursor[1]-1] != blank && masu[cursor[0]+1][cursor[1]] != blank && masu[cursor[0]][cursor[1]+1] != blank ) return false; } return true; } //今ボールがある位置をボールの行き着いた先とする private void BallDisCh(){ BallDis[0] = MBallPlace[0]; BallDis[1] = MBallPlace[1]; } //次の下に表示されてるボールを置く private void putBall(){ int x; int i,j; int y; int a[][] = new int[2][3]; i = 0; j = 0; //あといくつマスが空いているかによって、 //次のfor文をまわす回数をかえる if(BlankNum() > 2) j=3; if(BlankNum() == 2) j=2; if(BlankNum() == 1) j=1; //3つ for(i=0;i