発展プログラミング(22) 例題Othello_03(応用プログラム「オセロ」その3)
オセロゲームの技術課題を一つずつ解決しましょう。
○ ステップ3:はさんだ石を反転させるアルゴリ ズム ○ 考え方 はさんだ石を反転するには, 1 隣に相手の石があること 2 その先に,自分の石があること が前提条件で,自分の石が出るまで相手の石をひ っくり返す処理を繰り返します。 ○ 課題1 「a1」から「h8」まで、64箇所あるマス目 のどこかをクリックすると、テキストフィールドに クリックした場所を表示するメソッド(clickCell)を作成しましょう。 ヒント clickCell メソッドを呼び出す箇所は、現在コメント行になっている次の箇所です。 clickCell メソッドを作成したら、「//」 を削除して、clickCell メソッドを呼び出せるように します。 ・ 変 数 event は 、 ボ タ ン を ク リ ッ ク し た と き に 与 え ら れ る イ ベ ン ト の 情 報 を 持 つ // マス目のクリックを受けて、別スレッドで処理を行うclass MyWorker extends SwingWorker <Object,Object>{
private ActionEvent event;
public MyWorker(ActionEvent e) {
this.event = e; }
protected Object doInBackground(){ //clickCell(this.event);
return null; }
} この‘//’を削除
プログラム例 ○ 課題2 「もしも、クリックされた場所が石を打ってよい場所なら、黒(または白)の石を表示す る」機能を作成した clickCell メソッドに追加してください。 ヒント ・ 石を打ってよい場所かどうかは、hint 配列にあるデータ(1==よい、0==だめ)を使います。
・ 石の色を変えるメソッドは、setColor(int x,int y,int col)メソッドです。また、盤面の 状態を保持する配列 ishi の値も変更する必要があります。
プログラム例 ○ 課題3 「はさんだ相手の石を反転させる」機能を clickCell メソッドに追加してください。 ヒント 次のメソッドを作成してください。 (1) 石が反転する処理がゆっくり見えるように 0.3 秒処理を止めるメソッド。 石を連続してひっくり返す際、一つずつひっくり返すように見えるようにするため、 Thread.sleep メソッドを用いて一つの石の反転に 0.3 秒ウエイトをかける。 例)private void waitTime()
(3) clickCell メソッドの後半部分を別メソッドに分割
clickCell メソッドの後半部分で、石を打った部分から、相手の石をひっくり返す 処理を行うもの。
例)private void clickCell2(int x, int y) (4) 8方向に向けて石を反転させるメソッド。
1方向に向けて石を反転させるメソッド(reverse1 メソッド)を 8 方向に向けて呼 び出す。
例)private void reverse8(int x, int y,int iro_Me) (5) 1方向に向けて石を反転させるメソッド。
countReverse1 メソッドでひっくり返すことのできる石数を調べ、、石を次々ひっく り返すもの。表示が速すぎないよう、waitTime メソッド(後述)で 0.3 秒ずつウエ イトをかける。
例)private void countReverse1(x, y, sx, sy, col)
課題3
① 今回作成した Java クラスを、正常に動作することを確認後、提出しなさい。 ※今回提出すべきファイル(1本)
【プログラム例】
// 0.3秒待つ STEP3
private void waitTime(){ try {
Thread.sleep(300);
} catch (InterruptedException e1) { e1.printStackTrace();
} }
// 盤面のクリック処理 STEP3
private void clickCell(ActionEvent e){ int x = 0;
int y = 0;
// クリック位置 x, y の取得
JButton btn = (JButton)e.getSource();
loop_exit: // 2重ループを抜けるためのラベル for (y=0; y<8; y++){
for(x=0; x<8; x++){
if(btn == cell[x][y]){
break loop_exit;// 2重ループを抜ける Javaの技 } } } // リバース処理 clickCell2( x, y ); } // リバース処理 STEP3
private void clickCell2(int x, int y){ String str[]={"●","○"}; if(hint[x][y] == 1){ ishi[x][y]=(nanTe % 2) + 1; // クリックされた石の番地表示 char c='A'; c += x; textField.setText(str[(nanTe % 2)]+
// リバース処理 reverse8( x, y, (nanTe % 2) +1); // 1手進める nanTe++; setHint((nanTe % 2) +1); // 順番を表示 textField.setText(textField.getText()+str[(nanTe % 2)] +"の番です"); // 盤面を再表示 disp_all(); } } // 8方向に向けて石を反転させる STEP3
private void reverse8(int x, int y,int iro_Me){
reverse1(x, y, 0, -1,iro_Me); // 北 ( 0,-1) reverse1(x, y, 1, -1,iro_Me); // 北東( 1,-1) reverse1(x, y, 1, 0,iro_Me); // 東 ( 1, 0) reverse1(x, y, 1, 1,iro_Me); // 南東( 1, 1) reverse1(x, y, 0, 1,iro_Me); // 南 ( 0, 1) reverse1(x, y, -1, 1,iro_Me); // 南西(-1, 1) reverse1(x, y, -1, 0,iro_Me); // 西 (-1, 0) reverse1(x, y, -1, -1,iro_Me); // 北西(-1,-1) } // 1方向に向けて石を反転させる STEP3
private void reverse1(int x,int y,int sx,int sy,int col){ int c;
c = countReverse1(x, y, sx, sy, col); while (c>0){ waitTime(); x += sx; y += sy; c--; ishi[x][y] = col; setColor(x, y, col); } }