質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

2回答

2450閲覧

javaのオセロの自動対局について

YT31524894

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/08/19 22:18

###オセロの自動対局
javaでオセロの自動対局の機能を実装しようと思い、盤面をクリックすると100回対局を繰り返すプログラムを作ろうとしました。が、しかし、2回しか対局をしてくれません。エラーメッセージは出ていません。

###発生している問題

オセロの自動対局が百回繰り返すつもりが二回で終わってしまう。

###該当のソースコード

java

1MainApp.java 2 3import javax.swing.JFrame; 4 5public class MainApp extends JFrame { 6 7 public MainApp(){ 8 setTitle("Othello"); 9 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 10 11 MainPanel panel = new MainPanel(); 12 getContentPane().add(panel); 13 pack(); 14 } 15 16 public static void main(String[] args){ 17 18 MainApp app = new MainApp(); 19 app.setVisible(true); 20 21 } 22 23} 24 25MainPanel.java 26 27import java.awt.Color; 28import java.awt.Dimension; 29import java.awt.Graphics; 30import java.awt.event.MouseEvent; 31import java.awt.event.MouseListener; 32import java.util.Observable; 33import java.util.Observer; 34 35import javax.swing.JPanel; 36 37public class MainPanel extends JPanel implements MouseListener, Observer{ 38 static final int SIZE = 50; 39 static final int W = SIZE * 8; 40 static final int H = SIZE * 8; 41 42 GameState state = new GameState(); 43 RandomCPU cpu = new RandomCPU(); 44 45 public MainPanel(){ 46 setPreferredSize(new Dimension(W,H)); 47 addMouseListener(this); 48 49 state.addObserver(this); 50 } 51 52 public void paintComponent(Graphics g){ 53 54 //背景 55 g.setColor(new Color(30,170,130)); 56 g.fillRect(0, 0, W, H); 57 58 //線 59 g.setColor(Color.BLACK); 60 for(int i=0; i<8; i++){ 61 g.drawLine(0, i*SIZE, W, i*SIZE); 62 g.drawLine(i*SIZE, 0, i*SIZE, H); 63 } 64 g.setColor(Color.DARK_GRAY); 65 //g.drawRect(SIZE*2, SIZE*2, SIZE*4, SIZE*4); 66 67 //駒 68 for(int y=0; y<8; y++){ 69 for(int x=0; x<8; x++){ 70 if(state.data[x][y] == 1){ 71 g.setColor(Color.BLACK); 72 g.fillOval(x*SIZE, y*SIZE, SIZE, SIZE); 73 }else if(state.data[x][y] == -1){ 74 g.setColor(Color.WHITE); 75 g.fillOval(x*SIZE, y*SIZE, SIZE, SIZE); 76 } 77 } 78 } 79 80 //データ表示 81 g.setColor(Color.RED); 82 g.drawString("TURN = "+state.turn, 10, 30); 83 g.drawString("PLAYER = "+state.player, 10, 50); 84 g.drawString("DISC = "+state.black+" : " +state.white, 10, 70); 85 86 } 87 88 public void update(Observable o, Object arg){ 89 repaint(); 90 } 91 92 public void mousePressed(MouseEvent e){ 93 int PassCount=0; 94 int GameNT=0; 95 while(GameNT<=100){ 96 //盤面が埋まったら終了 97 if(state.player == 1){ 98 int action1[] = cpu.decide(state); 99 if(action1[0] != -1){ 100 state.put(action1[0], action1[1]); 101 repaint(); 102 PassCount=0; 103 } 104 105 if(state.turn == 60){ 106 state.turn=0; 107 state.data = new int[8][8]; 108 state.data[3][3] = 1; 109 state.data[3][4] = -1; 110 state.data[4][3] = -1; 111 state.data[4][4] = 1; 112 repaint(); 113 state.countDisc(); 114 GameNT++; 115 } 116 //パスチェック 117 else if( state.checkPass() == true ){ 118 state.player *= -1; 119 PassCount++; 120 if(PassCount==2){ 121 state.turn=0; 122 state.data = new int[8][8]; 123 state.data[3][3] = 1; 124 state.data[3][4] = -1; 125 state.data[4][3] = -1; 126 state.data[4][4] = 1; 127 repaint(); 128 state.countDisc(); 129 GameNT++; 130 } 131 } 132 133 //CPUのターン 134 if(state.player == -1){ 135 int action2[] = cpu.decide(state); 136 if(action2[0] != -1){ 137 state.put(action2[0], action2[1]); 138 repaint(); 139 PassCount=0; 140 } 141 142 //盤面が埋まったら終了 143 if(state.turn == 60){ 144 state.turn=0; 145 state.data = new int[8][8]; 146 state.data[3][3] = 1; 147 state.data[3][4] = -1; 148 state.data[4][3] = -1; 149 state.data[4][4] = 1; 150 repaint(); 151 state.countDisc(); 152 GameNT++; 153 } 154 //パスチェック 155 else if( state.checkPass() == true ){ 156 state.player *= -1; 157 PassCount++; 158 if(PassCount==2){ 159 state.turn=0; 160 state.data = new int[8][8]; 161 state.data[3][3] = 1; 162 state.data[3][4] = -1; 163 state.data[4][3] = -1; 164 state.data[4][4] = 1; 165 repaint(); 166 state.countDisc(); 167 GameNT++; 168 } 169 } 170 } 171 } 172 } 173 } 174 175 public void mouseClicked(MouseEvent e){ 176 177 } 178 public void mouseReleased(MouseEvent e){ 179 180 } 181 public void mouseEntered(MouseEvent e){ 182 183 } 184 public void mouseExited(MouseEvent e){ 185 186 } 187} 188 189GameState.java 190 191import java.util.Observable; 192 193public class GameState extends Observable{ 194 int data[][]; 195 int turn; 196 int player; 197 int black; 198 int white; 199 200 public GameState(){ 201 data = new int[8][8]; 202 data[3][3] = 1; 203 data[3][4] = -1; 204 data[4][3] = -1; 205 data[4][4] = 1; 206 207 turn = 0; 208 player = 1; 209 black = 2; 210 white = 2; 211 } 212 213 public boolean put(int x, int y){ 214 //すでに駒があるところには置けない 215 if(data[x][y] != 0){ 216 return false; 217 } 218 //リバースできないところには置けない 219 if(reverse(x,y,true)==false){ 220 return false; 221 } 222 223 //駒を置く 224 data[x][y] = player; 225 player *= -1; 226 turn++; 227 countDisc(); 228 229 setChanged(); 230 notifyObservers(); 231 232 return true; 233 } 234 235 public boolean reverse(int x,int y, boolean doReverse ){ 236 int dir[][] = { 237 {-1,-1}, {0,-1}, {1,-1}, 238 {-1, 0}, {1, 0}, 239 {-1, 1}, {0, 1}, {1, 1} 240 }; 241 242 boolean reversed = false; 243 244 for(int i=0; i<8; i++){ 245 //隣のマス 246 int x0 = x+dir[i][0]; 247 int y0 = y+dir[i][1]; 248 if(isOut(x0,y0) == true){ 249 continue; 250 } 251 int nextState =data[x0][y0]; 252 if(nextState == player){ 253 System.out.println("Next state is player: " +x0 +","+ y0); 254 continue; 255 }else if(nextState == 0){ 256 System.out.println("Next state is null: " +x0 +","+ y0); 257 continue; 258 }else{ 259 System.out.println("Next state is enemy: " +x0 +","+ y0); 260 } 261 262 //隣の隣から端まで走査して、自分の色があればリバース 263 int j = 2; 264 while(true){ 265 266 int x1 = x + (dir[i][0]*j); 267 int y1 = y + (dir[i][1]*j); 268 if(isOut(x1,y1) == true){ 269 break; 270 } 271 272 //自分の駒があったら、リバース 273 if(data[x1][y1]==player){ 274 System.out.println("Player cell!: " +x1 +","+ y1); 275 276 if(doReverse){ 277 for(int k=1; k<j; k++){ 278 int x2 = x + (dir[i][0]*k); 279 int y2 = y + (dir[i][1]*k); 280 data[x2][y2] *= -1; 281 System.out.println("reverse: " +x2 +","+ y2); 282 } 283 } 284 reversed = true; 285 break; 286 } 287 288 //空白があったら、終了 289 if(data[x1][y1]==0){ 290 break; 291 } 292 293 j++; 294 295 } 296 297 } 298 299 return reversed; 300 } 301 302 303 304 public boolean canReverse(int x, int y){ 305 return reverse(x, y, false); 306 } 307 308 public boolean isOut(int x, int y){ 309 if(x<0 || y<0 || x>=8 || y>=8){ 310 return true; 311 } 312 return false; 313 } 314 315 public boolean checkPass(){ 316 317 //コピーデータの全升目に対して、リバースできるかチェック 318 for(int y=0; y<8; y++){ 319 for(int x=0; x<8; x++){ 320 321 //すでに駒があるところはチェックしない 322 if(data[x][y] != 0){ 323 continue; 324 } 325 326 //リバースできる(した)とき、元に戻してfalseを返す 327 if(canReverse(x,y) == true){ 328 return false; 329 } 330 331 } 332 } 333 334 return true; 335 } 336 337 public void countDisc(){ 338 339 black = 0; 340 white = 0; 341 342 for(int y=0; y<8; y++){ 343 for(int x=0; x<8; x++){ 344 if(data[x][y] == 1){ 345 black++; 346 }else if(data[x][y] == -1){ 347 white++; 348 } 349 } 350 } 351 } 352} 353 354RandomCPU.java 355 356import java.util.ArrayList; 357import java.util.Random; 358 359public class RandomCPU { 360 361 int color; //BLACK or WHITE 362 363 public RandomCPU(){ 364 color = -1; 365 } 366 367 int[] decide(GameState state){ 368 369 ArrayList<int[]> array = new ArrayList<int[]>(); 370 371 //盤面の空マスを置けるかチェック 372 for(int y=0; y<8; y++){ 373 for(int x=0; x<8; x++){ 374 375 //すでに駒があるときはパス 376 if(state.data[x][y] != 0) 377 continue; 378 379 //置けるマスのとき、候補として記憶 380 if(state.canReverse(x, y) == true){ 381 int pos[] = {x,y}; 382 array.add(pos); 383 } 384 385 } 386 } 387 388 //ランダム選択 389 if(array.size() <= 0){ 390 int pos[] = {-1, -1}; 391 return pos; 392 } 393 Random rnd = new Random(); 394 int index = rnd.nextInt(array.size()); 395 396 return array.get(index); 397 } 398 399}

###補足情報(言語/FW/ツール等のバージョンなど)
java7
eclipse4.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

  • 追記しました:

ひょっとすると、下記の版だと 白から始まっちゃうことがあるかもしれません。
stateを初期化するときにplayerも初期化してあげてください。
その場合、以下の対応(中括弧の修正)はいらないかもしれませんが、playerの値が正しければやっても無害ではあると思います。

追記ここまで。(本文が長いのでここに追記しました)


java

1while(GameNT<=100){ 2 //盤面が埋まったら終了 3 if(state.player == 1) {

このif文の閉じかっこが1個たりないので、

以下のif文が、if(state.player == 1) {の中にいることになっています。
括弧の対応を合わせてください。

java

1//CPUのターン 2if(state.player == -1){

そこを直せばうまくいきそうです。(違ってたらすいません)
つまりこうなっているので、

if(state.player == 1){ int action1[] = cpu.decide(state); if(action1[0] != -1){ } if(state.turn == 60){ } //パスチェック else if( state.checkPass() == true ){ if(PassCount==2){ } } //CPUのターン if(state.player == -1){ if(action2[0] != -1){ } //盤面が埋まったら終了 if(state.turn == 60){ } //パスチェック else if( state.checkPass() == true ){ if(PassCount==2){ } } } }

中括弧を移動してこうしてあげてください。

if(state.player == 1){ int action1[] = cpu.decide(state); if(action1[0] != -1){ } if(state.turn == 60){ } //パスチェック else if( state.checkPass() == true ){ if(PassCount==2){ } } } //CPUのターン if(state.player == -1){ if(action2[0] != -1){ } //盤面が埋まったら終了 if(state.turn == 60){ } //パスチェック else if( state.checkPass() == true ){ if(PassCount==2){ } } }

今回の問題と関係ないですが、 if(state.turn == 60){のブロックの内容がどっちも全く同じだよとIDE(IntelliJ IDEA)の注意がでました。
丸ごとメソッドにするのが難しいとしても、少なくとも以下の部分はGameStateにメソッド作ってそっちでやらせた方がコードも見やすくなるし、責任も分離できていいかなと個人的にも思います。

java

1state.turn=0; 2state.data = new int[8][8]; 3state.data[3][3] = 1; 4state.data[3][4] = -1; 5state.data[4][3] = -1; 6state.data[4][4] = 1;

投稿2016/08/20 02:36

編集2016/08/20 02:49
flied_onion

総合スコア2604

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

デバッグ指針を示します。

  • while(GameNT<=100){

の部分でループをしていると思われますが、 GameNT の値の変化を log 出力や デバッガで追ってみてはいかがでしょう?

  • このループが、 自分の意図せぬ場所で抜けてしまっている部分がないかを調べる。

(break 文, exit 文, 例外発生...)
while を抜けた直後に ブレークポイントを設定して、そこに到達しているかとか、到達している時に GameNT の値がどうなっているか?
などを調べる。

投稿2016/08/19 23:36

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問