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

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

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

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

Q&A

解決済

2回答

12088閲覧

[初心者です] 一応最低限の動作をするオセロプログラミングが出来ましたが修正すべき点を教えて下さい

omikuji

総合スコア60

Java

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

0グッド

2クリップ

投稿2015/10/31 05:32

編集2015/11/03 08:21

我流でプログラミングを勉強してきました。
なんとか動作するプログラムはこちらで質問させて頂きながら完成させることは出来ましたが、どうしても読みづらいプログラムになってしまっていると感じます。
こう工夫すれば、より読みやすくなる分かりやすくなるといったポイントがあれば教えて下さい。

加えて、エラー処理(例えば、ひっくり返す場所がないので自動的にパスをする・引っくり返すものがない場所には置けない)等をどうやって実装するべきか教えて頂けると幸いです。

以下長文となりますがプログラム全文をはらせていただきます。

package othello;

public class Main {

public static void main(String[] args){ Board b = new Board(); Piece p = new Piece(); p.pieceSetting(); b.putPiece(); }

}

package othello;

import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Board implements ActionListener{

Piece[][] pButton; JFrame frame = new JFrame("Othello"); JPanel panel = new JPanel(); JButton[][] b = new JButton[8][8]; public Board(){ frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(680,700); panel.setLayout(null); panel.setBackground(Color.WHITE); frame.add(panel); pButton = new Piece[8][8]; for(int i=0; i<64; i++) { int x = i/8; int y = i%8; pButton[x][y] = new Piece(); pButton[x][y].setSize(80,80); pButton[x][y].setBounds(x*80+10, y*80+10, 80, 80); pButton[x][y].setMargin(new Insets(0,0,0,0)); pButton[x][y].setBackground(Color.GRAY); pButton[x][y].setFont(new Font("MSゴシック", Font.PLAIN, 60)); pButton[x][y].setActionCommand(String.valueOf(i)); //ボタン判別に利用 pButton[x][y].addActionListener(this); panel.add(pButton[x][y]); } } public void actionPerformed(ActionEvent e) { String str = e.getActionCommand(); System.out.println(str); int data = Integer.parseInt(str); int x = data/8; int y = data%8; if(Piece.p[x+1][y+1] == 0) { Piece.p[x+1][y+1] = Piece.turn; Piece.checkRev(x+1,y+1); putPiece(); if(Piece.turn == Piece.BLACK){ Piece.turn = Piece.WHITE; }else{ Piece.turn = Piece.BLACK; } } } public void putPiece(){ for(int i=0; i<100; i++) { int x = i/10; int y = i%10; if(Piece.p[x][y] == Piece.BLACK) { pButton[x-1][y-1].setText("●"); } else if(Piece.p[x][y] == Piece.WHITE) { pButton[x-1][y-1].setText("○"); } } }

}

package othello;

import javax.swing.JButton;

public class Piece extends JButton{

static int[][] p = new int[10][10]; public static final int OFFMAP =-1; //盤外 public static final int NULL = 0; //コマが無いマス public static final int BLACK = 1; public static final int WHITE = 2; static int turn = BLACK; public void pieceSetting(){ for(int i=0; i<100; i++) { int x = i%10; int y = i/10; if(x==0 || x== 9 || y==0 || y==9) { p[x][y] = OFFMAP; } else { p[x][y] = NULL; } } p[4][4] = BLACK; p[5][5] = BLACK; p[4][5] = WHITE; p[5][4] = WHITE; // 初期配置 } public static void doRev(int sx, int sy){ int saveX = sx; int saveY = sy; int mx = -1; int my = -2; // for文で+1スタートするので-2から始める for(int i=0; i<8; i++) { sx = saveX; sy = saveY; int revX = saveX; int revY = saveY; if(mx == 0 && my == -1) { my = my + 2; } else if(my != 1) { my++; } else { mx++; my = -1; } while(p[sx+mx][sy+my] != turn && p[sx+mx][sy+my] > 0) { sx = sx+mx; sy = sy+my; } if(p[sx+mx][sy+my] == turn){ while(p[revX+mx][revY+my] != turn && p[revX+mx][revY+my] > 0) { p[revX+mx][revY+my] = turn; revX = revX+mx; revY = revY+my; } } } }

}

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

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

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

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

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

KiyoshiMotoki

2015/11/03 08:13

ご質問の内容が変わっておりますので、新規の質問を投稿されてはいかがでしょうか? その方が、より多くの方から回答を得やすくなると思います。
omikuji

2015/11/03 08:16

そうですね、少しわかりづらい投稿になってしまったかなと感じました。 新しく記事を投稿させていただきます。 ご指摘ありがとうございます。
guest

回答2

0

ベストアンサー

よく書けていると思います。
手元のマシンで動作させてみましたが、特に問題なく動きます。

こう工夫すれば、より読みやすくなる分かりやすくなるといったポイントがあれば教えて下さい。

・変数名やフィールド名を工夫すれば、より読みやすくなります。
たとえばstrcoordinateに、ppanelsに、といった具合です。

・ボタンのアクションコマンドに0からの連番をセットしておりますが、
"x,y"
のような座標形式の文字列をセットしてやる方がよいです。

その方がコードを読む際により直感的に理解できますし、
たとえばマスの数を増やす場合などに、修正しやすいコードになります。

・原則、リテラルは書かないようにしましょう。

プログラムの中に810などのリテラルが書かれていると
それが何を意味する値なのかは文脈から推測するしかありません。
しかし、BUTTON_LENGTH_Xなどのように適切な名前をつけた定数を定義してやれば、
変数名から意味を推測できるようになります。

また、値を変更したくなった際に定数を定義している部分の1カ所だけを変更すれば良いので、
修正漏れによるバグを防げるというメリットもあります。

エラー処理(例えば、ひっくり返す場所がないので自動的にパスをする・引っくり返すものがない場所には置けない)等をどうやって実装するべきか

自分のターンを開始する前に石を置ける場所を計算しておき、それ以外のマスには石を置けないようにしてしまうのが良いでしょう。

挟んだ相手の石をひっくり返す処理が実装できているので、それを応用して事前に全ての空きマスに対してシミュレーションするイメージです。

その際、
・すでに置かれている石に隣接していないマスはシミュレーションの対象から除外する
・ひっくり返せる石が1つでも見つかれば直ちに処理を中断する
などのチューニングができればなお良いですが、
愚直に全ての空きマスに対してシミュレーションしても、たかだか64マスの盤では特に問題ないと思います。

あとは、勝敗判定の実装ですね。

白黒双方の石の数を数えるのは特に難しくありませんが、
「【いつ】、勝敗判定を行なうか」
がポイントになると思います。

がんばって下さい。

投稿2015/10/31 08:17

KiyoshiMotoki

総合スコア4791

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

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

omikuji

2015/10/31 08:52

様々なアドバイス、ありがとうございます! ひとまず、教えて頂いた方法を参考にしながらプログラムを改良していこうと思います。
guest

0

こんにちわ。

とりあえずプログラムを動かしてみました。
石を反転させる処理はうまく動作しているようですね。
ただ、今のままだとどこでも石を置くことができてしまうので、
まずはひっくり返す場所があるかないかを判定する以下のようなメソッドを
Boardクラスに実装してみてはいかがでしょうか?

/** posに石を配置したと仮定した場合、 ひっくり返せる石があるならtrueを、無いならfalseを返す */ private boolean reversible(String pos){ // posの右にひっくり返せる石があるか判定する // posの右下... // posの下... // posの左下... // posの左... // posの左上... // posの上.... // posの右上.... }

どのように判定すればいいのか手順がわからなければ、また聞いてください。

投稿2015/10/31 07:55

srsnsts

総合スコア480

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

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

omikuji

2015/10/31 08:51

ありがとうございます!早速実装してみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問