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

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

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

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

Q&A

解決済

2回答

2998閲覧

オセロの挟む判定

sobue

総合スコア329

Java

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

0グッド

0クリップ

投稿2016/03/19 23:45

java

1package reversi; 2 3import javax.swing.*; 4 5public class othello extends JFrame { 6 7 public othello() { 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 othello othello= new othello(); 19 othello.setVisible(true); 20 21 } 22 23} 24

java

1package reversi; 2 3import java.awt.Color; 4import java.awt.Dimension; 5import java.awt.event.MouseEvent; 6import java.util.Observable; 7import java.util.Observer; 8 9import javax.swing.JOptionPane; 10import javax.swing.JPanel; 11import javax.swing.event.MouseInputListener; 12 13public class MainPanel extends JPanel implements MouseInputListener, Observer { 14 15 static final int SIZE = 50; 16 static final int W = SIZE * 8; 17 static final int H = SIZE * 8; 18 19 GameState state = new GameState(); 20 RandomCPU cpu = new RandomCPU(); 21 22 public MainPanel() { 23 // TODO 自動生成されたコンストラクター・スタブ 24 setPreferredSize(new Dimension(W, H)); 25 addMouseListener(this); 26 27 state.addObserver(this); 28 29 } 30 31 public void paintComponent(java.awt.Graphics g) { 32 g.setColor(Color.LIGHT_GRAY); 33 g.fillRect(0, 0, W, H); 34 35 g.setColor(Color.BLACK); 36 for (int i = 0; i < 8; i++) { 37 g.drawLine(0, i * SIZE, W, i * SIZE); 38 g.drawLine(i * SIZE, 0, i * SIZE, H); 39 40 } 41 g.setColor(Color.DARK_GRAY); 42 43 for (int y = 0; y < 8; y++) { 44 45 for (int x = 0; x < 8; x++) { 46 47 if (state.data[x][y] == 1) { 48 g.setColor(Color.BLACK); 49 g.fillOval(x * SIZE, y * SIZE, SIZE, SIZE); 50 } else if (state.data[x][y] == -1) { 51 g.setColor(Color.WHITE); 52 g.fillOval(x * SIZE, y * SIZE, SIZE, SIZE); 53 54 } 55 } 56 57 g.setColor(Color.RED); 58 g.drawString("TURN = " + state.turn, 10, 30); 59 g.drawString("PLAYER = " + state.player, 10, 50); 60 g.drawString("DISCARDING = " + state.black + ":", 10, 70); 61 } 62 63 } 64 65 @Override 66 public void mouseClicked(MouseEvent e) { 67 // TODO 自動生成されたメソッド・スタブ 68 69 } 70 71 @Override 72 public void mousePressed(MouseEvent e) { 73 // TODO 自動生成されたメソッド・スタブ 74 int x = e.getX(); 75 int y = e.getY(); 76 77 x /= SIZE; 78 y /= SIZE; 79 System.out.println("(x+y);=(" + x + "," + y + ")"); 80 81 if (state.put(x, y) == false) { 82 JOptionPane.showMessageDialog(this, "Can't put this areal"); 83 } 84 if (state.turn == 60) { 85 JOptionPane.showMessageDialog(this, "End"); 86 87 } else if (state.checkPass() == true) { 88 state.player *= -1; 89 JOptionPane.showMessageDialog(this, "Pass! Next turn is " + state.player); 90 } 91 92 // CPUのターン 93 if (state.player == cpu.color) { 94 95 int action[] = cpu.decide(state); 96 if (action[0] != -1) 97 state.put(action[0], action[1]); 98 99 // 盤面が埋まったら終了 100 if (state.turn == 60) { 101 JOptionPane.showMessageDialog(this, "End!"); 102 } 103 // パスチェック 104 else if (state.checkPass() == true) { 105 JOptionPane.showMessageDialog(this, "Pass! Next turn is " + state.turn); 106 } 107 } 108 } 109 110 @Override 111 public void mouseReleased(MouseEvent e) { 112 // TODO 自動生成されたメソッド・スタブ 113 114 } 115 116 @Override 117 public void mouseEntered(MouseEvent e) { 118 // TODO 自動生成されたメソッド・スタブ 119 120 } 121 122 @Override 123 public void mouseExited(MouseEvent e) { 124 // TODO 自動生成されたメソッド・スタブ 125 126 } 127 128 @Override 129 public void mouseDragged(MouseEvent e) { 130 // TODO 自動生成されたメソッド・スタブ 131 132 } 133 134 @Override 135 public void mouseMoved(MouseEvent e) { 136 // TODO 自動生成されたメソッド・スタブ 137 138 } 139 140 @Override 141 public void update(Observable o, Object arg) { 142 // TODO 自動生成されたメソッド・スタブ 143 repaint(); 144 } 145 146} 147

java

1package reversi; 2 3import java.util.Observable; 4 5import javax.xml.crypto.Data; 6 7public class GameState extends Observable { 8 int data[][]; 9 int turn; 10 int player; 11 int black; 12 int white; 13 14 public GameState() { 15 // TODO 自動生成されたコンストラクター・スタブ 16 data = new int[8][8]; 17 data[3][3] = 1; 18 data[3][4] = -1; 19 data[4][3] = -1; 20 data[4][4] = 1; 21 22 turn = 0; 23 player = 1; 24 black = 2; 25 white = 2; 26 } 27 28 public boolean put(int x, int y) { 29 if (data[x][y] != 0) { 30 return false; 31 } 32 if (reverse(x, y, true) == false) { 33 return false; 34 } 35 data[x][y] = player; 36 player *= -1; 37 turn++; 38 countDisc(); 39 40 setChanged(); 41 notifyObservers(); 42 43 return true; 44 45 } 46 47 public boolean reverse(int x, int y, boolean doReverse) { 48 int dir[][] = { { 1, 1 }, { 0, -1 }, { 1, -1 }, { -1, 0 }, { 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } 49 50 }; 51 boolean reversed = false; 52 for (int i = 0; i < 8; i++) { 53 int x0 = x + dir[i][0]; 54 int y0 = y + dir[i][1]; 55 if (isOut(x0, y0) == true) { 56 continue; 57 } 58 int nextState = data[x0][y0]; 59 if (nextState == player) { 60 System.out.println("NEXT state is player: " + x0 + "," + y0); 61 continue; 62 } else if (nextState == 0) { 63 System.out.println("NEXT state is null:" + x0 + "," + y0); 64 } else { 65 System.out.println("NEXT state is null:" + x0 + "," + y0); 66 } 67 68 int j = 2; 69 while (true) { 70 71 int x1 = x + (dir[i][0] * j); 72 int y1 = y + (dir[i][1] * j); 73 if (isOut(x1, y1) == true) { 74 break; 75 76 } 77 if (data[x1][y1] == player) { 78 System.out.println("Player cell: " + x1 + "," + y1); 79 80 if (doReverse) { 81 for (int k = 1; k < j; k++) { 82 int x2 = x + (dir[i][0] * k); 83 int y2 = y + (dir[i][1] * k); 84 data[x2][y2] *= -1; 85 System.out.println("reverse" + x2 + "," + y2); 86 } 87 } 88 reversed = true; 89 break; 90 } 91 if (data[x1][y1] == 0) { 92 break; 93 94 } 95 j++; 96 } 97 } 98 return reversed; 99 } 100 101 public boolean canReverse(int x, int y) { 102 return reverse(x, y, false); 103 } 104 105 public boolean isOut(int x, int y) { 106 if (x < 0 || y < 0 || x >= 8 || y >= 8) { 107 return true; 108 } 109 return false; 110 111 } 112 113 public boolean checkPass() { 114 for (int y = 0; y < 8; y++) { 115 for (int x = 0; x < 8; x++) { 116 117 if (data[x][y] != 0) { 118 continue; 119 } 120 if (canReverse(x, y) == true) { 121 return false; 122 123 } 124 } 125 } 126 return true; 127 } 128 129 public void countDisc() { 130 black = 0; 131 white = 0; 132 133 for (int y = 0; y < 8; y++) { 134 for (int x = 0; x < 8; x++) { 135 if (data[x][y] == 1) { 136 black++; 137 } else if (data[x][y] == -1) { 138 white++; 139 140 } 141 } 142 } 143 } 144} 145

java

1package reversi; 2import java.util.*; 3 4public class RandomCPU { 5 6 int color; //BLACK or WHITE 7 8 public RandomCPU(){ 9 color = -1; 10 } 11 12 int[] decide(GameState state){ 13 14 ArrayList<int[]> array = new ArrayList<int[]>(); 15 16 //盤面の空マスを置けるかチェック 17 for(int y=0; y<8; y++){ 18 for(int x=0; x<8; x++){ 19 20 //すでに駒があるときはパス 21 if(state.data[x][y] != 0) 22 continue; 23 24 //置けるマスのとき、候補として記憶 25 if(state.canReverse(x, y) == true){ 26 int pos[] = {x,y}; 27 array.add(pos); 28 } 29 30 } 31 } 32 33 //ランダム選択 34 if(array.size() <= 0){ 35 int pos[] = {-1, -1}; 36 return pos; 37 } 38 Random rnd = new Random(); 39 int index = rnd.nextInt(array.size()); 40 41 return array.get(index); 42 } 43 44}

上記のコードでオセロを作ったのですが、挟む時の判定がうまくいかず変なところに駒が置けるようになっています。
どのように改善したらよろしいでしょうか?

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

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

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

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

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

guest

回答2

0

上で回答が出ているので関連の内容から補足を1点。
前回の質問でたまたま拝見したため回答しましたが。

質問を出す前に、混乱している以下状況をまず改善してください。

1.コードにやりたいことを詰めすぎです。
→判定と実行は分けましょう。(事例は出していますが難しければ検討の上確認してください)
例えばオセロの駒を配置するときに例えば以下要素の検討が必要です。
※わかりづらければオセロのルールをもう一度確認しましょう。
(1)その位置に駒は配置されているのか。
→駒に相手の駒や自分の駒があってはならない。

(2)その位置に置いたことでルール1「その位置と相手駒を挟んだ先に自分の駒があるか」
→空の駒が隣にあればその方向は判定不要
→自分の駒が8方向の隣にあればNG
→相手の駒が隣にあった場合はその方向に対して(3)の確認をする

(3)ルール2「入れ替えできる駒数を数える」
(2)入れ替えが可能なコマの数と位置を抑える

(4)(2)と(3)から自分の置いた駒から判断された相手駒を自分の駒に反転させる。

2.質問の仕方

どのように改善したらよろしいでしょうか?

質問として不適切です。
これは自分ではわからないので暗にデバッグしてくださいと依頼しているようなものなので。
コードをください・デバッグしてください等の丸投げの質問依頼になります。
→状況の整理と何を解決しなくてはならないのかを明確にする必要があります。
全体的に見て、とりあえず組んでみましたしか伝わりません。

例えば、幼稚園にオセロのルールを伝えるときにどう伝えますか?

プログラミングとは、「自分の考えを適切に順番にコードに落としこむこと」です。
なので、こういった仕様の検討はちゃんとやらないと混乱したコードになりがちです。

突き放すわけではないので、調べ、検証した中で不明になることがでます。
その時こそ絶好の質問になりますので、その時であれば歓迎します。
ぜひ頑張ってください。

投稿2016/03/20 01:34

lib

総合スコア446

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

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

sobue

2016/03/20 03:47

ありがとうございます。設計からやり直してまた投稿したいと思います。 その時にはよろしくお願いします。
guest

0

ベストアンサー

挟んだときのコマの反転がおかしいのであれば、
GameState#reverse()メソッドのロジックを、

そもそも、置ける場所がおかしいのであれば、GameState#Put()
とGameState#CanReverse()の中身のロジックを
見直す必要があるように思います。
こちらに関して、1つ思うのは、Put()メソッドの中でReverse()を呼び出す前にCanReverse()で判定する必要はありませんか?

投稿2016/03/20 00:58

Odacchi

総合スコア907

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問