1. Home
  2. Java
  3. GOMOKU ( Source code )

GOMOKU ( Source code )

Last-Modified: 2008-01-03 18:53:29

ちょっとした説明

この"GOMOKU"は以下の6つのクラスからできています。

GoPanel
五目並べの盤を作っています。
GoFrame
GoPanelのサブクラス。メニューバーが追加されています。
EvaluationWin
勝敗を判断するためのクラス。
GoMouseEvent
マウスによるイベントを処理するクラス。(クリックで石を置く)
GoMenuEvent
メニューバーのイベント処理
GoApplet
アプッレトです。

jarファイルをダウンロード

GoPanel

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class GoPanel extends JPanel {
    /**フィールド*/
    static final int MASUME = 10; //マス目の数 10×10
    int gW, gH; //マス目の幅
    private int panel[][] = new int[MASUME][MASUME]; //盤の状態を表す配列
    static final int BLANK = 0, BSTONE = 1, WSTONE = -1; //panel[][]配列に入れる定数
    static final int margin = 4; //石を描くときの余白
    boolean isBlackTurn = true; //黒の番か
    MouseAdapter MouseAd;
    JLabel status;
    Image buf;
    Graphics ct;
    /**コンストラクタ*/
    /**幅width,高さheightのGoPanelを作成
     *@param width ウィンドウの幅
     *@param height ウィンドウの高さ
     */
    public GoPanel(int width, int height) {
        setBackground(new Color(238, 231, 191)); //背景色を設定
        Dimension dim = new Dimension(width, height);
        setPreferredSize(dim); // パネルのサイズを設定
        setMinimumSize(dim);
        setMaximumSize(dim);
        panelSet(); //盤上を初期化
        MouseAd = new GoMouseEvent(this); //イベントリスナーを追加
        this.addMouseListener(MouseAd);
        status = new JLabel("  "); //ステイタスバーを追加
    }
    /**幅400,高さ400のGoPanelを作成*/
    public GoPanel() {
        this(400, 400);
    }
    public void paintComponent(Graphics g) {
        buf = createImage(this.getWidth() , this.getHeight());
        ct = buf.getGraphics();
        super.paintComponent(ct);
        drawGrid(ct); //盤上に線を描く
        drawStone(ct); //石を描く
        statusOut(); //ステイタスバーに文字を入れる
        g.drawImage(buf , 0 , 0 ,this);
    }
    /**石が置けるかどうか
     *@param x 盤での列(row)の番号-1
     *@param y 盤での行(column)の番号-1
     *@return 置けるならtrueを返す
     */
    boolean canPlace(int x, int y) {
        return panel[x][y] == BLANK;
    }
    /**黒石を置く
     *@param x 盤での列(row)の番号-1
     *@param y 盤での行(column)の番号-1
     */
    void putDownB(int x, int y) {
        panel[x][y] = BSTONE;
    }
    /**白石を置く
     *@param x 盤での列(row)の番号-1
     *@param y 盤での行(column)の番号-1
     */
    void putDownW(int x, int y) {
        panel[x][y] = WSTONE;
    }
    /**
     * 石を置く
     * @param x int 盤での列(row)の番号-1
     * @param y int 盤での行(column)の番号-1
     */
    void putDown(int x, int y) {
        if (isBlackTurn) {
            putDownB(x, y);
        } else {
            putDownW(x, y);
        }
    }
    /**
     * 石を取り除く
     * @param x int 盤での列(row)の番号-1
     * @param y int 盤での行(column)の番号-1
     */
    void removeStone(int x, int y) {
        if (!canPlace(x, y)) {
            panel[x][y] = BLANK;
        } else {
            System.out.println("(" + x + "," + y +
                               ") から石を取り除こうとしましたがそこには石はありません");//test
        }
    }
    /**
     * パネルの状態を返す
     * @param x int 盤での列(row)の番号-1
     * @param y int 盤での行(column)の番号-1
     * @return int BLANK = 0, BSTONE = 1, WSTONE = -1
     */
    int getPanelState(int x,int y){
        return panel[x][y];
    }
    /**盤上の初期化*/
    void panelSet() {
        for (int x = 0; x < panel.length; x++) {
            for (int y = 0; y < panel[x].length; y++) {
                panel[x][y] = BLANK;
            }
        }
    }
    /**盤上に石を置けるマスがない?*/
    boolean noBlank(){
        for (int x = 0; x < panel.length; x++) {
            for (int y = 0; y < panel[x].length; y++) {
                if(panel[x][y] == BLANK){
                     return false;
                }
            }
        }
        return true;
    }
    /**ステイタスバーに文字を表示*/
    void statusOut() {
            if (isBlackTurn) { //黒の番のとき
                status.setText("Now is Black turn .");
            } else { //白の番のとき
                status.setText("Now is White turn .");
            }
    }
    /**盤上に線を描く
     *@param g Graphics class
     */
    void drawGrid(Graphics g) {
        gW = getWidth() / MASUME; //マスの幅
        gH = getHeight() / MASUME;
        g.setColor(Color.black);
        for (int i = 0; i <= MASUME; i++) { //横の線を引く
            g.drawLine(0, (int) ((0.5 + i) * gH), getWidth(),
                       (int) ((0.5 + i) * gH));
        }
        for (int i = 0; i <= MASUME; i++) { //縦の線を引く
            g.drawLine((int) ((0.5 + i) * gW), 0, (int) ((0.5 + i) * gW),
                       getHeight());
        }
    }
    /**石を描く
     *@param g Graphics class
     */
    void drawStone(Graphics g) {
        for (int x = 0; x < panel.length; x++) {
            for (int y = 0; y < panel[x].length; y++) {
                if (panel[x][y] == BSTONE) { //該当箇所が黒い石
                    g.setColor(Color.black);
                    g.drawOval(x * gW + margin, y * gH + margin,
                               gW - 2 * margin, gH - 2 * margin);
                    g.drawOval(x * gW + margin + 1, y * gH + margin + 1,
                               gW - 2 * margin - 2, gH - 2 * margin - 2);
                    g.fillOval(x * gW + margin, y * gH + margin,
                               gW - 2 * margin, gH - 2 * margin);
                }
                if (panel[x][y] == WSTONE) { //該当箇所が白い石
                    g.setColor(Color.black);
                    g.drawOval(x * gW + margin, y * gH + margin,
                               gW - 2 * margin, gH - 2 * margin);
                    g.drawOval(x * gW + margin + 1, y * gH + margin + 1,
                               gW - 2 * margin - 2, gH - 2 * margin - 2);
                    g.setColor(Color.white);
                    g.fillOval(x * gW + margin + 1, y * gH + margin + 1,
                               gW - 2 * margin - 2, gH - 2 * margin - 2);
                }
            }
        }
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame("GOMOKU");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //ウィンドウを閉じたときプログラムを終了
        Container cont = frame.getContentPane();
        cont.setLayout(new BorderLayout());
        GoPanel gop = new GoPanel();
        cont.setBackground(Color.white);
        cont.add(gop, BorderLayout.CENTER);
        cont.add(gop.status, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }
}

上に戻る

GoFrame

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import java.awt.Color;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import java.awt.Container;
import java.util.ArrayList;
public class GoFrame extends GoPanel {
    /**フィールド*/
    JMenuBar menuBar;
    JMenu menu;
    JMenu help;
    JMenuItem item1, item2, item3, item4;
    GoMenuEvent gme;
    ArrayList history;
    /**
     * コンストラクタ
     * @param width int ウィンドウの幅
     * @param height int ウィンドウの高さ
     */
    public GoFrame(int width, int height) {
        super(width, height);
        gme=new GoMenuEvent(this);
        menuBar = new JMenuBar();
        menu = new JMenu("Menu");
        help = new JMenu("Help");
        item1 = new JMenuItem("UnDo");
        item1.setActionCommand("UnDo");
        item1.addActionListener(gme);
        item2 = new JMenuItem("Restart");
        item2.setActionCommand("Restart");
        item2.addActionListener(gme);
        item3 = new JMenuItem("Version");
        item3.setActionCommand("Version");
        item3.addActionListener(gme);
        menu.add(item1);
        menu.add(item2);
        help.add(item3);
        menuBar.add(menu);
        menuBar.add(help);
        history = new ArrayList();
    }
    public GoFrame() {
        this(400, 400);
    }
    void putDownB(int x, int y) {
        super.putDownB(x, y);
        history.add(new int[] {x, y});
    }
    void putDownW(int x, int y) {
        super.putDownW(x, y);
        history.add(new int[] {x, y});
    }
    void putDown(int x, int y) {
        super.putDown(x, y);
        history.add(new int[] {x, y});
    }
    void panelSet() {
        super.panelSet();
        if(history!=null){
            history.clear();
        }
        super.isBlackTurn=true;
    }
 void unDo(){
     if(history.size()!=0){
         int point[] = (int[]) history.get(history.size()-1);
         super.removeStone(point[0], point[1]);
         history.remove(history.size() - 1);
         history.remove(history.size() - 1);
         super.isBlackTurn=!super.isBlackTurn;
     }
 }
    public static void main(String[] args) {
        GoFrame gop = new GoFrame();
        JFrame frame = new JFrame("GOMOKU");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         //ウィンドウを閉じたときプログラムを終了
        Container cont = frame.getContentPane();
        cont.setLayout(new BorderLayout());
        cont.setBackground(Color.white);
        cont.add(gop, BorderLayout.CENTER);
        cont.add(gop.status, BorderLayout.SOUTH);
        frame.setJMenuBar(gop.menuBar);
        frame.pack();
        frame.setVisible(true);
    }
}

上に戻る

EvaluationWin

public class EvaluationWin {
    GoPanel goPanel;
    static final int WIN = 1, NOT_WIN = 0;
    int stone;
    public EvaluationWin(GoPanel g) {
        this.goPanel = g;
    }
    void setForBlack() { //黒石評価の準備
        stone = GoPanel.BSTONE;
    }
    void setForWhite() { //白石評価の準備
        stone = GoPanel.WSTONE;
    }
    /**
     *
     * @param startX int 開始位置(X)
     * @param startY int 開始位置(Y)
     * @param dX int 変化量X
     * @param dY int 変化量Y
     * @param n int 評価するマスの数
     * @return int 勝なら1、非勝なら0
     */
    int evaluateLine(int startX, int startY, int dX, int dY, int n) {
        int stoneNumber = 0;
        for (int i = 0; i < n; i++) {
            if (goPanel.getPanelState(startX-1 + i * dX,startY-1 + i * dY) == stone) {//石なら
                stoneNumber++;
                if(stoneNumber>=5){//5個以上連続なら
                    return WIN;
                }
            }
            else{//石以外
                stoneNumber=0;
            }
        }
        return NOT_WIN;
    }
    /**
     * 縦の列を評価
     * @return int 勝なら1,2,3...  , 非勝なら0
     */
    int evaluateRow(){
        int sum=0;
        for(int row=1;row<=goPanel.MASUME;row++){
            sum=sum+evaluateLine(row,1,0,1,goPanel.MASUME);
        }
        return sum;
    }
    /**
     * 横の行を評価
     * @return int 勝なら1,2,3...  , 非勝なら0
     */
    int evaluateColumn(){
        int sum=0;
        for(int col=1;col<=goPanel.MASUME;col++){
            sum=sum+evaluateLine(1,col,1,0,goPanel.MASUME);
        }
        return sum;
    }
    /**
     * 斜めの列を評価
     * @return int 勝なら1,2,3...  , 非勝なら0
     */
    int evaluateTilt(){
        int sum=0;
        sum=sum+evaluateLine(1,1,1,1,GoPanel.MASUME);
        sum=sum+evaluateLine(GoPanel.MASUME,1,-1,1,GoPanel.MASUME);
        for(int k=2;k<=GoPanel.MASUME-4;k++){
            sum=sum+evaluateLine(1,k,1,1,GoPanel.MASUME+1-k);
            sum=sum+evaluateLine(k,1,1,1,GoPanel.MASUME+1-k);
            sum=sum+evaluateLine(GoPanel.MASUME+1-k,1,-1,1,GoPanel.MASUME+1-k);
            sum=sum+evaluateLine(GoPanel.MASUME,k,-1,1,GoPanel.MASUME+1-k);
        }
        return sum;
    }
    /**
     * 黒石の勝ち、非勝を評価
     * @return int 勝ちなら1,2,3,4... ,非勝なら0
     */
    int evaluateBlack(){
        setForBlack();
        return evaluateRow()+evaluateColumn()+evaluateTilt();
    }
    /**
     * 白石の勝ち、非勝を評価
     * @return int 勝ちなら1,2,3,4... ,非勝なら0
     */
    int evaluateWhite(){
        setForWhite();
        return evaluateRow()+evaluateColumn()+evaluateTilt();
    }
    /**人の勝、非勝
     *@return int 勝ちなら1,2,3,4... ,非勝なら0
     */
    int evaluateOnMan(){
        return evaluateBlack();
    }
    /**CPUの勝、非勝
     *@return int 勝ちなら1,2,3,4... ,非勝なら0
     */
    int evaluateOnCPU(){
        return evaluateWhite();
    }
}

上に戻る

GoMouseEvent

import java.awt.event.MouseAdapter;
import java.awt.event.*;
import javax.swing.*;
public class GoMouseEvent extends MouseAdapter {
    /**フィールド*/
    private GoPanel goPanel;
    GoCPU cpu;
    EvaluationWin ew;
    /**コンストラクタ
     * @param g GoMouseEventが参照するGoPanel
     */
    public GoMouseEvent(GoPanel g) {
        this.goPanel = g;
        ew = new EvaluationWin(goPanel);
    }
    /**メソッド*/
    /**マウスがクリックされたら
     *@param me MouseEvent
     */
    public void mouseClicked(MouseEvent me) {
        int x = analyzeX(me.getX());
        int y = analyzeY(me.getY());
        if (goPanel.canPlace(x, y)) { //石置けるか
            goPanel.putDown(x, y);
            goPanel.repaint();
            winCheck();
            goPanel.isBlackTurn = !goPanel.isBlackTurn;
        } else { //石置けないとき
            dialog(new String[] {"You Can NOT ", "Put Down Stone There."});
            goPanel.repaint();
        }
    }
    /**勝敗、引き分けチェック*/
    void winCheck() {
        if (ew.evaluateBlack() != 0) {
            dialog(new String[] {"BLACK WIN!!", "Congratulations!"});
            goPanel.panelSet();
            goPanel.isBlackTurn = false;
            goPanel.repaint();
        }
        if (ew.evaluateWhite() != 0) {
            dialog(new String[] {"WHITE WIN!!", "Congratulations!"});
            goPanel.panelSet();
            goPanel.isBlackTurn = false;
            goPanel.repaint();
        }
        if (goPanel.noBlank()) {
            dialog(new String[] {"DRAW."});
            goPanel.panelSet();
            goPanel.isBlackTurn = false;
            goPanel.repaint();
        }
    }
    void dialog(String[] message) {
        JOptionPane.showMessageDialog(goPanel, message, "MESSAGE",
                                      JOptionPane.INFORMATION_MESSAGE);
    }
    /**座標をマス目にして返す(X)
     *@param x ウィンドウ上でのX座標
     *@return 盤での列(row)の番号
     */
    int analyzeX(int x) {
        return x / goPanel.gW;
    }
    /**座標をマス目にして返す(Y)
     *@param y  ウィンドウ上でのy座標
     *@return 盤での行(column)の番号
     */
    int analyzeY(int y) {
        return y / goPanel.gH;
    }
}

上に戻る

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
public class GoMenuEvent implements ActionListener {
    private GoFrame goFrame;
    public GoMenuEvent(GoFrame go) {
        goFrame = go;
    }
    /**
     * Invoked when an action occurs.
     *
     * @param e ActionEvent
     * @todo この java.awt.event.ActionListener メソッドを実装
     */
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if(command.equals("UnDo")){
            goFrame.unDo();
            }
        if(command.equals("Restart")){
            goFrame.panelSet();
        }
        if(command.equals("Version")){
            JOptionPane.showMessageDialog(goFrame,
            new String[]{"五目並べ","Version 1.0","Author :Toru Mano"},
             "MESSAGE",JOptionPane.INFORMATION_MESSAGE);
        }
        goFrame.repaint();
    }
}

上に戻る

GoApplet

import java.awt.*;
import javax.swing.*;
public class GoApplet extends JApplet {
    GoFrame goFrame;
    //アプレットの初期化
    public void init() {
        goFrame=new GoFrame();
        Container cont=this.getContentPane();
        cont.setBackground(Color.white);
        setJMenuBar(goFrame.menuBar);
        cont.add(goFrame, BorderLayout.CENTER);
        cont.add(goFrame.status, BorderLayout.SOUTH);
        this.setVisible(true);
    }
}

上に戻る | Appletに戻る | Javaに戻る | Homeに戻る

Copyright (c) Toru Mano. Last-Modified: 2008-01-03 18:53:29