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

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

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

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

Q&A

2回答

3213閲覧

1回勝つと3回勝つマルバツゲーム

yahhymmne

総合スコア20

Java

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

0グッド

0クリップ

投稿2016/11/04 00:09

###実現したいこと/発生している問題
簡単なマルバツゲームをJAppletで作成しています。
引き分けは問題無いのですが、○×どちらが勝っても正しく勝利回数がカウントされません。
数日考えましたが原因がどうにも分からりません。どうかご助力お願いします。

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

Java

1package boardgame; 2 3import java.awt.BorderLayout; 4import java.awt.FlowLayout; 5import java.awt.GridLayout; 6import java.awt.event.ActionEvent; 7import java.awt.event.ActionListener; 8 9import javax.swing.JApplet; 10import javax.swing.JButton; 11import javax.swing.JLabel; 12import javax.swing.JPanel; 13 14public class TicTacToeMain4 extends JApplet 15{ 16 //解像度を調整 17 18 //正方形の盤の大きさを決めて配置 19 private JPanel[] pn = new JPanel[3]; 20 private int sidex = 3; //横軸の長さ。初期値は3 21 private int sidey = 3; //縦軸の長さ。初期値は3 22 private JButton[][] area = new JButton[sidex][sidey]; //配列(マス)の数は正方形の面積(n*n) 23 24 //上側要素を追加 25 private JLabel title; 26 private JLabel owinDisplay; 27 private JLabel xwinDisplay; 28 private JLabel drawDisplay; 29 30 private int owin = 0; 31 private int xwin = 0; 32 private int draw = 0; 33 34 //下側要素を追加 35 private JButton start; 36 private JButton undo; 37 private int turn = 0; 38 private JLabel turnDisplay; 39 40 //undo用 41 private int tmpx = 0; 42 private int tmpy = 0; 43 44 //初期呼び出しメソッド 45 public void init() 46 { 47 createBoard(); 48 } 49 50 //盤面作成メソッド 51 private void createBoard() 52 { 53 //全体の構成となるパネルを宣言 54 pn[0] = new JPanel(); 55 pn[1] = new JPanel(); 56 pn[2] = new JPanel(); 57 58 //上側のオブジェクトを宣言 59 title = new JLabel("TicTacToe"); 60 owinDisplay = new JLabel("○勝利:"+ owin); 61 xwinDisplay = new JLabel("×勝利:"+ xwin); 62 drawDisplay = new JLabel("引き分け:"+ draw); 63 64 //下側のオブジェクトを宣言 65 start = new JButton("ゲーム開始/リセット"); 66 undo = new JButton("一手戻る"); 67 turnDisplay = new JLabel(turn + "手"); 68 69 //コンポーネントの作成 70 pn[0].setLayout(new FlowLayout()); //横に並べる 71 pn[1].setLayout(new GridLayout(sidey,sidex)); //マス状に並べる 72 pn[2].setLayout(new FlowLayout()); //横に並べる 73 74 //要素をパネルに反映 75 //上側 76 pn[0].add(title); 77 pn[0].add(owinDisplay); 78 pn[0].add(xwinDisplay); 79 pn[0].add(drawDisplay); 80 //中央 81 for(int x=0; x<sidex; x++) //盤面を生成 例:00,01,02:10,11,12:20,21,22; 82 { 83 for(int y=0; y<sidey; y++) 84 { 85 area[x][y] = new JButton(""); 86 area[x][y].setEnabled(false); 87 area[x][y].setHorizontalAlignment(JLabel.CENTER); //○×を中央表示 88 area[x][y].setVerticalAlignment(JLabel.CENTER); //させる 89 pn[1].add(area[x][y]); //ボタンをパネルに反映 90 } 91 } 92 //下側 93 pn[2].add(start); 94 pn[2].add(undo); 95 undo.setEnabled(false);//1手目からは戻れないから 96 pn[2].add(turnDisplay); 97 98 //ルートペインへ配置 99 add(pn[0],BorderLayout.NORTH); 100 add(pn[1],BorderLayout.CENTER); 101 add(pn[2],BorderLayout.SOUTH); 102 103 //ボタンを押したらこのクラス(リスナクラス)に飛ぶ 104 start.addActionListener(new startActionListener()); 105 undo.addActionListener(new undoActionListener()); 106 for(int x=0; x<sidex; x++) //盤面を生成 例:00,01,02:10,11,12:20,21,22; 107 { 108 for(int y=0; y<sidey; y++) 109 { 110 area[x][y].addActionListener(new game(x,y)); 111 } 112 } 113 } 114 115 //リスナクラス 116 class game implements ActionListener 117 { 118 int cngx = 0; 119 int cngy = 0; 120 121 game(int x, int y) 122 { 123 cngx=x; 124 cngy=y; 125 } 126 public void actionPerformed(ActionEvent e) 127 { 128 proceed(e); 129 undo.setEnabled(true); 130 } 131 private void proceed (ActionEvent e) 132 { 133 switch(turn%2)//先手と後手でそれぞれ〇×を振り分け、手番を経過させる 134 { 135 case 0: 136 rewriteOX("○"); 137 wincheck(); 138 break; 139 140 case 1: 141 rewriteOX("×"); 142 wincheck(); 143 break; 144 } 145 } 146 private void rewriteOX(String ox) 147 { 148 area[cngx][cngy].setText(ox); 149 tmpx=cngx; 150 tmpy=cngy; 151 turnDisplay.setText(++turn + "手"); 152 area[cngx][cngy].setEnabled(false); 153 } 154 private void wincheck() 155 { 156 int winner = 0; 157 oxChecker(winner,"○"); 158 oxChecker(winner,"×"); 159 if(turn>=9) //9手番経過で 160 { 161 winner = 3; 162 displayWinner(winner,"-"); //引き分け 163 } 164 } 165 private void oxChecker(int winner,String ox) 166 { 167 for(int x=0; x<sidex; x++) //走査チェック 168 { 169 int checkerx = 0; 170 int checkery = 0; 171 int checkerz = 0; 172 for(int y=0; y<sidey; y++) 173 { 174 if(ox.equals(area[x][y].getText())) 175 { 176 checkerx++; //縦列でそろっているか 177 } 178 if(ox.equals(area[y][x].getText())) 179 { 180 checkery++; //横列でそろっているか 181 } 182 if(ox.equals(area[y][y].getText())) 183 { 184 checkerz++;//斜めでそろっているか 185 } 186 } 187 if(ox.equals(area[1][1].getText())&&ox.equals(area[0][2].getText())&&ox.equals(area[2][0].getText())) 188 { 189 checkerz=3;//斜めでそろっているか 190 } 191 if(checkerx == 3||checkery == 3||checkerz ==3) 192 { 193 switch(ox) 194 { 195 case "○": 196 winner=1; 197 break; 198 case "×": 199 winner=2; 200 break; 201 } 202 displayWinner(winner,ox); 203 } 204 } 205 } 206 private void displayWinner(int winner,String ox) 207 { 208 switch(winner) 209 { 210 case 1: 211 owinDisplay.setText("○勝利:" + ++owin); //○勝利:回数 212 break; 213 case 2: 214 xwinDisplay.setText("×勝利:" + ++xwin); //×勝利:回数 215 break; 216 case 3: 217 drawDisplay.setText("引き分け:" + ++draw); //引き分け:回数 218 break; 219 } 220 boardLocker(); //盤面を弄れないようにする 221 boardFiller(ox); //ぬりつぶし 222 } 223 private void boardLocker() 224 { 225 for(int x=0; x<sidex; x++) 226 { 227 for(int y=0; y<sidey; y++) 228 { 229 area[x][y].setEnabled(false); //すべてボタンを押せないようにする 230 } 231 } 232 } 233 private void boardFiller (String ox) 234 { 235 for(int x=0; x<sidex; x++) //ぬりつぶし 236 { 237 for(int y=0; y<sidey; y++) 238 { 239 area[x][y].setText(ox); //○×勝ったほうで塗りつぶす(引き分けは-) 240 } 241 } 242 } 243 } 244 245 class startActionListener implements ActionListener 246 { 247 public void actionPerformed(ActionEvent e) 248 { 249 for(int x=0; x<sidex; x++) //盤面をリセット 250 { 251 for(int y=0; y<sidey; y++) 252 { 253 area[x][y].setText(""); //全体を空白に戻す 254 area[x][y].setEnabled(true); //ボタン全部を押せるようにする 255 } 256 } 257 turn = 0;//ターン初期化 258 turnDisplay.setText(turn + "手");//表示の更新 259 undo.setEnabled(false);//1手目から戻せないようにする 260 } 261 } 262 class undoActionListener implements ActionListener 263 { 264 public void actionPerformed(ActionEvent e) 265 { 266 area[tmpx][tmpy].setText(""); //○×入れたところを空白に戻して 267 area[tmpx][tmpy].setEnabled(true); //ボタンを押せるようにして 268 undo.setEnabled(false); //アンドゥを使えないようにする 269 turnDisplay.setText(--turn + "手"); //手番を戻す 270 } 271 } 272}

###試したこと
処理の位置変更

###補足情報(言語/FW/ツール等のバージョンなど)
Eclipse Neon使用

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

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

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

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

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

guest

回答2

0

プログラムソースを調べて期待通りに動かない原因を探ることを机上デバッグといったりします。基本的なデバッグ方法の一つでとても大事です。でも机上デバッグではどうしてもわからないこともあるでしょう。そういうときはプログラムを実際に動かしながらデバッグします。それを実機デバッグなんていったりします。

実機デバッグするなら勝利回数をインクリメントしている箇所を何回通過しているかが問題なのですからそれを調べればわかるはずです。ここまでのプログラムを組まれたのですから簡単に回答を聞いてしまうのはもったいない気がしますよ。ぜひ自分で実機デバッグをしましょう。

投稿2016/11/04 01:00

KSwordOfHaste

総合スコア18392

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

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

0

走査ループ内にif文を記入していたのが原因のようです。

if(checkerx == 3||checkery == 3||checkerz ==3) { switch(ox) { case "○": winner=1; break; case "×": winner=2; break; } displayWinner(winner,ox); break; //ここにブレイクを挟むと勝利回数が正しくなる }

引き分けも同時にカウントされてしまうのでそのあたりを調整しています。

投稿2016/11/04 00:37

yahhymmne

総合スコア20

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問