| 情報学部 | 菅沼ホーム | Java 目次 | 索引 |
/*************************/
/* オセロ */
/* coded by Y.Suganuma */
/*************************/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import main.*;
public class Game {
public static void main (String[] args)
{
Win win = new Win("オセロ");
}
}
class Win extends JFrame
{
/******************/
/* コンストラクタ */
/******************/
Win(String name)
{
// JFrameクラスのコンストラクタ(Windowのタイトルを引き渡す)
super(name);
// Windowの大きさ
setSize(487, 617); // 40+20, 70+20
// MainPanel の大きさを決定
Dimension size = getSize();
size.width -=60;
size.height -=90;
// ContentPain を取得し,設定
Container CP = getContentPane(); // ContentPane を取得
CP.setLayout(null); // レイアウトマネージャを停止
CP.setBackground(new Color(220, 255, 220)); // 背景色
// MainPanel を追加し,設定
MainPanel pn = new MainPanel(size); // MainPanel オブジェクトの生成
CP.add(pn); // MainPanel オブジェクトを ContentPane に追加
pn.setSize(size.width, size.height);
pn.setLocation(10, 10);
// ウィンドウを表示
setVisible(true);
// イベントリスナ
addWindowListener(new WinEnd());
}
/******************************/
/* 上,左,下,右の余白の設定 */
/******************************/
public Insets getInsets()
{
return new Insets(50, 20, 20, 20);
}
/************/
/* 終了処理 */
/************/
class WinEnd extends WindowAdapter
{
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}
package main;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import start.*;
import game.*;
public class MainPanel extends JPanel implements Runnable
{
Dimension size; // パネルの大きさ
boolean in_game = true; // ゲーム実行中はtrue
public int state = 0; // ゲーム状態(0:表紙,1:ゲーム,2:終了)
public int method = 0; // ゲーム方法(0:対人間,1:対PC(先手),2:対PC(後手))
int old_state = 0; // 直前のゲーム状態
StartPanel sp;
GamePanel gp;
Thread td;
// コンストラクタ
public MainPanel(Dimension size1)
{
size = size1;
// グリッドレイアウト
setLayout(new GridLayout(1, 1, 0, 0));
// スタートパネルの生成
sp = new StartPanel(size, this); // スタート(タイトル)
add(sp);
// スレッドの生成
td = new Thread(this);
td.start();
}
// ゲームの状態を変更
public void run()
{
while (in_game) {
try {
td.sleep(100); // 100 ms 毎の実施
}
catch (InterruptedException e) {}
if (state != old_state) {
// 前のパネルの削除
if (old_state == 0)
remove(sp);
else
remove(gp);
// 新しいパネルの追加
if (state == 2) // ゲーム終了
in_game = false;
else {
if (state == 0) { // StartPanel
sp = new StartPanel(size, this);
add(sp);
}
else { // GamePanel
gp = new GamePanel(size, this);
add(gp);
}
validate();
old_state = state;
}
}
}
}
}
001 package start;
002
003 import java.awt.*;
004 import java.awt.event.*;
005 import javax.swing.*;
006 import main.*;
007
008 public class StartPanel extends JPanel implements ActionListener, ItemListener
009 {
010 boolean in_game = true;
011 Dimension size; // パネルの大きさ
012 MainPanel mp;
013 JButton bt, start;
014 Checkbox c1, c2, c3;
015 // コンストラクタ
016 public StartPanel(Dimension size1, MainPanel mp1)
017 {
018 size = size1;
019 mp = mp1;
020 // レイアウトマネージャの停止
021 setLayout(null);
022 // 背景色の設定
023 setBackground(Color.white);
024 // 「遊び方」ボタンの配置
025 Font f = new Font("SansSerif", Font.BOLD, 20);
026 FontMetrics fm = getFontMetrics(f);
027 String str = "遊び方";
028 int w = fm.stringWidth(str) + 40;
029 int h = fm.getHeight() + 10;
030 bt = new JButton(str);
031 bt.setFont(f);
032 bt.addActionListener(this);
033 bt.setSize(w, h);
034 bt.setLocation(size.width/2-w/2, 5);
035 add(bt);
036 // ラジオボタンの追加
037 setFont(f);
038 CheckboxGroup cbg = new CheckboxGroup();
039 c1 = new Checkbox("対人間", cbg, true);
040 w = fm.stringWidth("対人間") + 40;
041 c1.setSize(w, h);
042 c1.setLocation(20, size.height-3*h);
043 c1.addItemListener(this);
044 add(c1);
045 c2 = new Checkbox("対コンピュータ(人先手)", cbg, false);
046 w = fm.stringWidth("対コンピュータ(人先手)") + 40;
047 c2.setSize(w, h);
048 c2.setLocation(20, size.height-2*h);
049 c2.addItemListener(this);
050 add(c2);
051 c3 = new Checkbox("対コンピュータ(人後手)", cbg, false);
052 w = fm.stringWidth("対コンピュータ(人後手)") + 40;
053 c3.setSize(w, h);
054 c3.setLocation(20, size.height-h);
055 c3.addItemListener(this);
056 add(c3);
057 // 「開始」ボタンの配置
058 w = fm.stringWidth("開始") + 40;
059 start = new JButton("開始");
060 start.setFont(f);
061 start.addActionListener(this);
062 start.setSize(w, h);
063 start.setLocation(size.width-w-20, size.height-2*h);
064 add(start);
065 }
066 // 描画
067 public void paintComponent(Graphics g)
068 {
069 super.paintComponent(g); // 親クラスの描画
070 FontMetrics fm;
071 Font f;
072 String str;
073 int w, h;
074
075 f = new Font("SansSerif", Font.BOLD, 40);
076 fm = g.getFontMetrics(f);
077 str = "オセロ";
078 w = fm.stringWidth(str);
079 h = fm.getHeight();
080 g.setFont(f);
081 g.drawString(str, size.width/2-w/2, size.height/2);
082 }
083 // ボタンがクリックされたときの処理
084 public void actionPerformed(ActionEvent e)
085 {
086 if (e.getSource() == bt) {
087 Method db = new Method();
088 db.setVisible(true);
089 requestFocusInWindow();
090 }
091 else if (e.getSource() == start)
092 mp.state = 1;
093 }
094 // チェックされたときの処理
095 public void itemStateChanged(ItemEvent e)
096 {
097 if (e.getSource() == c1)
098 mp.method = 0;
099 else if(e.getSource() == c2)
100 mp.method = 1;
101 else if(e.getSource() == c3)
102 mp.method = 2;
103 }
104 }
105
106 /******************/
107 /* ゲームの遊び方 */
108 /******************/
109 class Method extends JDialog
110 {
111 // コンストラクタ
112 Method()
113 {
114 setTitle("ゲームの遊び方");
115 // ContetPain
116 Container cp = getContentPane();
117 cp.setLayout(new FlowLayout(FlowLayout.CENTER));
118 cp.setBackground(new Color(220, 255, 220)); // 背景色
119 Font f = new Font("MS 明朝", Font.PLAIN, 20);
120 setSize(550, 160);
121 // TextArea の追加
122 JTextArea ta = new JTextArea(5, 50);
123 ta.setFont(f);
124 ta.setEditable(false);
125 ta.setLineWrap(true);
126 ta.setText("・ゲーム開始: ゲーム方法を選択した後,「開始」ボタンをクリック\n");
127
128 ta.append("・コマを置く: コマを置きたい場所をクリック\n");
129 JScrollPane scroll = new JScrollPane(ta);
130 cp.add(scroll);
131 // Window を閉じるため
132 addWindowListener(new WinEnd());
133 }
134 // 終了処理
135 class WinEnd extends WindowAdapter
136 {
137 public void windowClosing(WindowEvent e) {
138 setVisible(false);
139 }
140 }
141 }
001 package game;
002
003 import java.awt.*;
004 import java.awt.event.*;
005 import javax.swing.*;
006 import main.*;
007
008 public class GamePanel extends JPanel implements ActionListener
009 {
010 MainPanel mp;
011 JTextArea ta;
012 JButton bt1, bt2;
013 // コンストラクタ
014 public GamePanel(Dimension size, MainPanel mp1)
015 {
016 mp = mp1;
017 // レイアウトマネージャの停止
018 setLayout(null);
019 // 背景色の設定
020 setBackground(Color.white);
021 // ボタンの配置
022 Font f = new Font("SansSerif", Font.BOLD, 20);
023 FontMetrics fm = getFontMetrics(f);
024 int w = fm.stringWidth("終了") + 40;
025 int h = fm.getHeight() + 10;
026
027 bt1 = new JButton("終了");
028 bt1.setFont(f);
029 bt1.setSize(w, h);
030 bt1.setLocation(size.width-w-5, size.height-50-h);
031 bt1.addActionListener(this); // アクションリスナ
032 add(bt1);
033
034 bt2 = new JButton("再開");
035 bt2.setFont(f);
036 bt2.setSize(w, h);
037 bt2.setLocation(size.width-w-5, size.height-40);
038 bt2.addActionListener(this); // アクションリスナ
039 add(bt2);
040 // テキストエリアの配置
041 ta = new JTextArea("黒の番です.\n");
042 ta.setFont(f);
043 JScrollPane sp = new JScrollPane(ta);
044 sp.setSize(size.width-w-10, 90);
045 sp.setLocation(0, size.height-90);
046 add(sp);
047 // オセロ盤の配置
048 Bord bd = new Bord(size, this);
049 bd.setSize(size.width, size.width);
050 bd.setLocation(0, 0);
051 add(bd);
052 }
053 // ボタンがクリックされたときの処理
054 public void actionPerformed(ActionEvent e)
055 {
056 bt1.setEnabled(false);
057 bt2.setEnabled(false);
058 if (e.getSource() == bt1) // ゲーム終了
059 mp.state = 2;
060 else // 最初から再開
061 mp.state = 0;
062 }
063 }
064
065 package game;
066
067 import java.awt.*;
068 import javax.swing.*;
069
070 public class Bord extends JPanel
071 {
072 GamePanel gp;
073 Koma km[][] = new Koma [8][8];
074 // コンストラクタ
075 public Bord(Dimension size, GamePanel gp1)
076 {
077 int width; // ボタンの大きさ
078 int gap = 3; // ボタン間の隙間の幅
079 gp = gp1;
080 // グリッドレイアウト
081 setLayout(new GridLayout(8, 8, gap, gap));
082 // 背景色の設定
083 setBackground(new Color(165, 42, 42));
084 // ボタンの配置
085 width = (size.width - 9 * gap) / 8;
086 for (int i1 = 0; i1 < 8; i1++) {
087 for (int i2 = 0; i2 < 8; i2++) {
088 km[i1][i2] = new Koma(width);
089 add(km[i1][i2]);
090 }
091 }
092 }
093 }
094
095 package game;
096
097 import java.awt.*;
098 import javax.swing.*;
099
100 class Koma extends JButton
101 {
102 int width; // ボタンの幅
103 // コンストラクタ
104 Koma(int width1)
105 {
106 width = width1;
107 // 背景色の設定
108 setBackground(Color.green);
109 }
110 }
int x[][] = new int [2][3];
int x[][] = new int [2][]; x[0] = new int [3]; // 以下,繰り返し文を使用可能 x[1] = new int [3];
int x[][] = {{1, 2, 3}, {4, 5, 6}}; // 内側の括弧が各行に相当
int x1[] = {1, 2, 3};
int x2[] = {4, 5, 6};
int x[][] = {x1, x2};
01 package game;
02
03 import java.awt.*;
04 import javax.swing.*;
05
06 public class Bord extends JPanel
07 {
08 GamePanel gp;
09 Koma km[][] = new Koma [8][8];
10 int b_w = -1; // -1:黒の手番,1:白の手番
11 int st[][] = {{0, 0, 0, 0, 0, 0, 0, 0},
12 {0, 0, 0, 0, 0, 0, 0, 0},
13 {0, 0, 0, 0, 0, 0, 0, 0},
14 {0, 0, 0, 1, -1, 0, 0, 0},
15 {0, 0, 0, -1, 1, 0, 0, 0},
16 {0, 0, 0, 0, 0, 0, 0, 0},
17 {0, 0, 0, 0, 0, 0, 0, 0},
18 {0, 0, 0, 0, 0, 0, 0, 0}}; // 盤面の状態(0:コマが置かれてない,-1:黒,1:白)
19 // コンストラクタ
20 public Bord(Dimension size, GamePanel gp1)
21 {
22 int width; // ボタンの大きさ
23 int gap = 3; // ボタン間の隙間の幅
24 gp = gp1;
25 // グリッドレイアウト
26 setLayout(new GridLayout(8, 8, gap, gap));
27 // 背景色の設定
28 setBackground(new Color(165, 42, 42));
29 // ボタンの配置
30 width = (size.width - 9 * gap) / 8;
31 for (int i1 = 0; i1 < 8; i1++) {
32 for (int i2 = 0; i2 < 8; i2++) {
33 km[i1][i2] = new Koma(width);
34 if (st[i1][i2] != 0)
35 km[i1][i2].st = st[i1][i2];
36 add(km[i1][i2]);
37 }
38 }
39 }
40 }
01 package game;
02
03 import java.awt.*;
04 import javax.swing.*;
05
06 class Koma extends JButton
07 {
08 int width; // ボタンの大きさ
09 int st = 0; // ボタンの状態(0:コマが置かれてない,-1:黒,1:白)
10 // コンストラクタ
11 Koma(int width1)
12 {
13 width = width1;
14 // 背景色の設定
15 setBackground(Color.green);
16 }
17 // 描画
18 public void paintComponent(Graphics g)
19 {
20 super.paintComponent(g); // 親クラスの描画
21 if (st != 0) {
22 if (st < 0)
23 g.setColor(Color.black);
24 else
25 g.setColor(Color.white);
26 g.fillOval(2, 2, width-4, width-4);
27 }
28 }
29 }
001 package game; 002 003 import java.awt.*; 004 import java.awt.event.*; 005 import javax.swing.*; 006 007 public class Bord extends JPanel implements ActionListener 008 { 009 GamePanel gp; 010 Koma km[][] = new Koma [8][8]; 011 int b_w = -1; // -1:黒の手番,1:白の手番 012 int st[][] = {{0, 0, 0, 0, 0, 0, 0, 0}, 013 {0, 0, 0, 0, 0, 0, 0, 0}, 014 {0, 0, 0, 0, 0, 0, 0, 0}, 015 {0, 0, 0, 1, -1, 0, 0, 0}, 016 {0, 0, 0, -1, 1, 0, 0, 0}, 017 {0, 0, 0, 0, 0, 0, 0, 0}, 018 {0, 0, 0, 0, 0, 0, 0, 0}, 019 {0, 0, 0, 0, 0, 0, 0, 0}}; // 盤面の状態(0:コマが置かれてない,-1:黒,1:白) 020 int n[] = new int [9]; // 指定された位置の各方向に対する反転できるコマの数 021 // [0] : 上方向 022 // [1] : 斜め右上方向 023 // [2] : 右方向 024 // [3] : 斜め右下方向 025 // [4] : 下方向 026 // [5] : 斜め左下方向 027 // [6] : 左方向 028 // [7] : 斜め左上方向 029 // [8] : 全体 030 // コンストラクタ 031 public Bord(Dimension size, GamePanel gp1) 032 { 033 int width; // ボタンの大きさ 034 int gap = 3; // ボタン間の隙間の幅 035 gp = gp1; 036 // グリッドレイアウト 037 setLayout(new GridLayout(8, 8, gap, gap)); 038 // 背景色の設定 039 setBackground(new Color(165, 42, 42)); 040 // ボタンの配置 041 width = (size.width - 9 * gap) / 8; 042 for (int i1 = 0; i1 < 8; i1++) { 043 for (int i2 = 0; i2 < 8; i2++) { 044 km[i1][i2] = new Koma(width); 045 km[i1][i2].addActionListener(this); 046 if (st[i1][i2] != 0) 047 km[i1][i2].st = st[i1][i2]; 048 add(km[i1][i2]); 049 } 050 } 051 } 052 // 053 // ボタンがクリックされたときの処理 054 // 055 public void actionPerformed(ActionEvent e) 056 { 057 // クリックされたボタンを特定 058 int k[] = {-1, -1}; 059 for (int i1 = 0; i1 < 8 && k[0] < 0; i1++) { 060 for (int i2 = 0; i2 < 8 && k[0] < 0; i2++) { 061 if (e.getSource() == km[i1][i2]) { 062 k[0] = i1; 063 k[1] = i2; 064 } 065 } 066 } 067 // 反転できるコマを探す 068 r_check(k); 069 // 反転するコマがない場合 070 if (n[8] <= 0) { 071 gp.ta.setForeground(Color.red); 072 if (b_w < 0) 073 gp.ta.setText("黒の番ですが,\n"); 074 else 075 gp.ta.setText("白の番ですが,\n"); 076 gp.ta.append("そこへはコマを置けません.\n"); 077 } 078 // 反転するコマがある場合 079 else 080 set(k); 081 } 082 // 083 // コマの操作 084 // 085 void set(int k[]) 086 { 087 // 反転 088 reverse(k); 089 b_w = -b_w; 090 gp.ta.setForeground(Color.black); 091 if (b_w < 0) 092 gp.ta.setText("黒の番です.\n"); 093 else 094 gp.ta.setText("白の番です.\n"); 095 } 096 // 097 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合,反転できるコマを探す 098 // 099 void r_check(int k[]) 100 { 101 int d[][] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}}; 102 n[8] = 0; 103 if (st[k[0]][k[1]] == 0) { 104 for (int i1 = 0; i1 < 8; i1++) { 105 int m1 = k[0], m2 = k[1]; 106 n[i1] = 0; 107 int s = 0; // 0:開始,1:カウント,2:カウント終了,3:反転不可能 108 int ct = 0; 109 while (s < 2) { 110 m1 += d[i1][0]; 111 m2 += d[i1][1]; 112 if (m1 >= 0 && m1 < 8 && m2 >= 0 && m2 < 8) { 113 if (st[m1][m2] == 0) 114 s = 3; 115 else if (st[m1][m2] == b_w) { 116 if (s == 1) 117 s = 2; 118 else 119 s = 3; 120 } 121 else { 122 s = 1; 123 ct++; 124 } 125 } 126 else 127 s = 3; 128 } 129 if (s == 2) { 130 n[8] += ct; 131 n[i1] = ct; 132 } 133 } 134 } 135 } 136 // 137 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合におけるコマの反転 138 // 139 void reverse(int k[]) 140 { 141 int d[][] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}}; 142 for (int i1 = 0; i1 < 8; i1++) { 143 int m1 = k[0], m2 = k[1]; 144 for (int i2 = 0; i2 < n[i1]; i2++) { 145 m1 += d[i1][0]; 146 m2 += d[i1][1]; 147 km[m1][m2].st = b_w; 148 st[m1][m2] = b_w; 149 } 150 } 151 km[k[0]][k[1]].st = b_w; 152 st[k[0]][k[1]] = b_w; 153 // 描画 154 for (int i1 = 0; i1 < 8; i1++) { 155 for (int i2 = 0; i2 < 8; i2++) { 156 if (st[i1][i2] != 0) 157 km[i1][i2].repaint(); 158 } 159 } 160 } 161 }
001 package game;
002
003 import java.awt.*;
004 import java.awt.event.*;
005 import javax.swing.*;
006
007 public class Bord extends JPanel implements ActionListener
008 {
009 GamePanel gp;
010 Koma km[][] = new Koma [8][8];
011 int b_w = -1; // -1:黒の手番,1:白の手番
012 int st[][] = {{0, 0, 0, 0, 0, 0, 0, 0},
013 {0, 0, 0, 0, 0, 0, 0, 0},
014 {0, 0, 0, 0, 0, 0, 0, 0},
015 {0, 0, 0, 1, -1, 0, 0, 0},
016 {0, 0, 0, -1, 1, 0, 0, 0},
017 {0, 0, 0, 0, 0, 0, 0, 0},
018 {0, 0, 0, 0, 0, 0, 0, 0},
019 {0, 0, 0, 0, 0, 0, 0, 0}}; // 盤面の状態(0:コマが置かれてない,-1:黒,1:白)
020 int n[] = new int [9]; // 指定された位置の各方向に対する反転できるコマの数
021 // [0] : 上方向
022 // [1] : 斜め右上方向
023 // [2] : 右方向
024 // [3] : 斜め右下方向
025 // [4] : 下方向
026 // [5] : 斜め左下方向
027 // [6] : 左方向
028 // [7] : 斜め左上方向
029 // [8] : 全体
030 // コンストラクタ
031 public Bord(Dimension size, GamePanel gp1)
032 {
033 int width; // ボタンの大きさ
034 int gap = 3; // ボタン間の隙間の幅
035 gp = gp1;
036 // グリッドレイアウト
037 setLayout(new GridLayout(8, 8, gap, gap));
038 // 背景色の設定
039 setBackground(new Color(165, 42, 42));
040 // ボタンの配置
041 width = (size.width - 9 * gap) / 8;
042 for (int i1 = 0; i1 < 8; i1++) {
043 for (int i2 = 0; i2 < 8; i2++) {
044 km[i1][i2] = new Koma(width);
045 km[i1][i2].addActionListener(this);
046 if (st[i1][i2] != 0)
047 km[i1][i2].st = st[i1][i2];
048 add(km[i1][i2]);
049 }
050 }
051 }
052 //
053 // ボタンがクリックされたときの処理
054 //
055 public void actionPerformed(ActionEvent e)
056 {
057 // クリックされたボタンを特定
058 int k[] = {-1, -1};
059 for (int i1 = 0; i1 < 8 && k[0] < 0; i1++) {
060 for (int i2 = 0; i2 < 8 && k[0] < 0; i2++) {
061 if (e.getSource() == km[i1][i2]) {
062 k[0] = i1;
063 k[1] = i2;
064 }
065 }
066 }
067 // 反転できるコマを探す
068 r_check(k);
069 // 反転するコマがない場合
070 if (n[8] <= 0) {
071 gp.ta.setForeground(Color.red);
072 if (b_w < 0)
073 gp.ta.setText("黒の番ですが,\n");
074 else
075 gp.ta.setText("白の番ですが,\n");
076 gp.ta.append("そこへはコマを置けません.\n");
077 }
078 // 反転するコマがある場合
079 else
080 set(k);
081 }
082 //
083 // コマの操作
084 //
085 void set(int k[])
086 {
087 // 反転
088 reverse(k);
089 b_w = -b_w;
090 // コマの数を数え,勝敗決定のチェック
091 int b = 0, w = 0, total = 0;
092 for (int i1 = 0; i1 < 8; i1++) {
093 for (int i2 = 0; i2 < 8; i2++) {
094 if (st[i1][i2] != 0) {
095 total++;
096 if (st[i1][i2] < 0)
097 b++;
098 else
099 w++;
100 }
101 }
102 }
103 // 勝敗決定
104 if (total == 64) {
105 gp.ta.setForeground(Color.black);
106 gp.ta.setText("黒 " + b + " 個, 白 " + w + " 個\n");
107 if (b > w)
108 gp.ta.append("黒の勝ちです.\n");
109 else if (b == w)
110 gp.ta.append("引き分けです.\n");
111 else
112 gp.ta.append("白の勝ちです.\n");
113 for (int i1 = 0; i1 < 8; i1++) {
114 for (int i2 = 0; i2 < 8; i2++)
115 km[i1][i2].setEnabled(false);
116 }
117 }
118 // 勝負継続
119 else {
120 gp.ta.setForeground(Color.black);
121 gp.ta.setText("黒 " + b + " 個, 白 " + w + " 個\n");
122 // スキップのチェック
123 boolean sw = false;
124 for (int i1 = 0; i1 < 8 && !sw; i1++) {
125 for (int i2 = 0; i2 < 8 && !sw; i2++) {
126 k[0] = i1;
127 k[1] = i2;
128 r_check(k);
129 if (n[8] > 0)
130 sw = true;
131 }
132 }
133 // スキップの場合
134 if (!sw) {
135 gp.ta.append("コマを置けないため,スキップし,\n");
136 b_w = -b_w;
137 }
138 // 次の手
139 if (b_w < 0)
140 gp.ta.append("黒の番です.\n");
141 else
142 gp.ta.append("白の番です.\n");
143 }
144 }
145 //
146 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合,反転できるコマを探す
147 //
148 void r_check(int k[])
149 {
150 int d[][] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
151 n[8] = 0;
152 if (st[k[0]][k[1]] == 0) {
153 for (int i1 = 0; i1 < 8; i1++) {
154 int m1 = k[0], m2 = k[1];
155 n[i1] = 0;
156 int s = 0; // 0:開始,1:カウント,2:カウント終了,3:反転不可能
157 int ct = 0;
158 while (s < 2) {
159 m1 += d[i1][0];
160 m2 += d[i1][1];
161 if (m1 >= 0 && m1 < 8 && m2 >= 0 && m2 < 8) {
162 if (st[m1][m2] == 0)
163 s = 3;
164 else if (st[m1][m2] == b_w) {
165 if (s == 1)
166 s = 2;
167 else
168 s = 3;
169 }
170 else {
171 s = 1;
172 ct++;
173 }
174 }
175 else
176 s = 3;
177 }
178 if (s == 2) {
179 n[8] += ct;
180 n[i1] = ct;
181 }
182 }
183 }
184 }
185 //
186 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合におけるコマの反転
187 //
188 void reverse(int k[])
189 {
190 int d[][] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
191 for (int i1 = 0; i1 < 8; i1++) {
192 int m1 = k[0], m2 = k[1];
193 for (int i2 = 0; i2 < n[i1]; i2++) {
194 m1 += d[i1][0];
195 m2 += d[i1][1];
196 km[m1][m2].st = b_w;
197 st[m1][m2] = b_w;
198 }
199 }
200 km[k[0]][k[1]].st = b_w;
201 st[k[0]][k[1]] = b_w;
202 // 描画
203 for (int i1 = 0; i1 < 8; i1++) {
204 for (int i2 = 0; i2 < 8; i2++) {
205 if (st[i1][i2] != 0)
206 km[i1][i2].repaint();
207 }
208 }
209 }
210 }
01 package game;
02
03 import java.awt.*;
04 import java.awt.event.*;
05 import javax.swing.*;
06 import main.*;
07
08 public class GamePanel extends JPanel implements ActionListener
09 {
10 MainPanel mp;
11 JTextArea ta;
12 JButton bt1, bt2;
13 // コンストラクタ
14 public GamePanel(Dimension size, MainPanel mp1)
15 {
16 mp = mp1;
17 // レイアウトマネージャの停止
18 setLayout(null);
19 // 背景色の設定
20 setBackground(Color.white);
21 // ボタンの配置
22 Font f = new Font("SansSerif", Font.BOLD, 20);
23 FontMetrics fm = getFontMetrics(f);
24 int w = fm.stringWidth("終了") + 40;
25 int h = fm.getHeight() + 10;
26
27 bt1 = new JButton("終了");
28 bt1.setFont(f);
29 bt1.setSize(w, h);
30 bt1.setLocation(size.width-w-5, size.height-50-h);
31 bt1.addActionListener(this); // アクションリスナ
32 add(bt1);
33
34 bt2 = new JButton("再開");
35 bt2.setFont(f);
36 bt2.setSize(w, h);
37 bt2.setLocation(size.width-w-5, size.height-40);
38 bt2.addActionListener(this); // アクションリスナ
39 add(bt2);
40 // テキストエリアの配置
41 String str;
42 if (mp.method == 0)
43 str = "黒の番です.\n";
44 else if (mp.method == 1)
45 str = "あなた(黒)の番です.\n";
46 else
47 str = "コンピュータの番です.\n";
48 ta = new JTextArea(str);
49 ta.setFont(f);
50 JScrollPane sp = new JScrollPane(ta);
51 sp.setSize(size.width-w-10, 90);
52 sp.setLocation(0, size.height-90);
53 add(sp);
54 // オセロ盤の配置
55 Bord bd = new Bord(size, this);
56 bd.setSize(size.width, size.width);
57 bd.setLocation(0, 0);
58 add(bd);
59 }
60 // ボタンがクリックされたときの処理
61 public void actionPerformed(ActionEvent e)
62 {
63 bt1.setEnabled(false);
64 bt2.setEnabled(false);
65 if (e.getSource() == bt1) // ゲーム終了
66 mp.state = 2;
67 else // 最初から再開
68 mp.state = 0;
69 }
70 }
001 package game;
002
003 import java.awt.*;
004 import java.awt.event.*;
005 import javax.swing.*;
006
007 public class Bord extends JPanel implements ActionListener
008 {
009 GamePanel gp;
010 Koma km[][] = new Koma [8][8];
011 int b_w = -1; // -1:黒の手番,1:白の手番
012 int st[][] = {{0, 0, 0, 0, 0, 0, 0, 0},
013 {0, 0, 0, 0, 0, 0, 0, 0},
014 {0, 0, 0, 0, 0, 0, 0, 0},
015 {0, 0, 0, 1, -1, 0, 0, 0},
016 {0, 0, 0, -1, 1, 0, 0, 0},
017 {0, 0, 0, 0, 0, 0, 0, 0},
018 {0, 0, 0, 0, 0, 0, 0, 0},
019 {0, 0, 0, 0, 0, 0, 0, 0}}; // 盤面の状態(0:コマが置かれてない,-1:黒,1:白)
020 int n[] = new int [9]; // 指定された位置の各方向に対する反転できるコマの数
021 // [0] : 上方向
022 // [1] : 斜め右上方向
023 // [2] : 右方向
024 // [3] : 斜め右下方向
025 // [4] : 下方向
026 // [5] : 斜め左下方向
027 // [6] : 左方向
028 // [7] : 斜め左上方向
029 // [8] : 全体
030 // コンストラクタ
031 public Bord(Dimension size, GamePanel gp1)
032 {
033 int width; // ボタンの大きさ
034 int gap = 3; // ボタン間の隙間の幅
035 gp = gp1;
036 // グリッドレイアウト
037 setLayout(new GridLayout(8, 8, gap, gap));
038 // 背景色の設定
039 setBackground(new Color(165, 42, 42));
040 // ボタンの配置
041 width = (size.width - 9 * gap) / 8;
042 for (int i1 = 0; i1 < 8; i1++) {
043 for (int i2 = 0; i2 < 8; i2++) {
044 km[i1][i2] = new Koma(width);
045 km[i1][i2].addActionListener(this);
046 if (st[i1][i2] != 0)
047 km[i1][i2].st = st[i1][i2];
048 add(km[i1][i2]);
049 }
050 }
051 // コンピュータの操作
052 if (gp.mp.method == 2) {
053 int k[] = computer(); // コマを置く場所の決定
054 set(k); // コマを置く
055 }
056 }
057 //
058 // ボタンがクリックされたときの処理
059 //
060 public void actionPerformed(ActionEvent e)
061 {
062 // クリックされたボタンを特定
063 int k[] = {-1, -1};
064 for (int i1 = 0; i1 < 8 && k[0] < 0; i1++) {
065 for (int i2 = 0; i2 < 8 && k[0] < 0; i2++) {
066 if (e.getSource() == km[i1][i2]) {
067 k[0] = i1;
068 k[1] = i2;
069 }
070 }
071 }
072 // 反転できるコマを探す
073 r_check(k);
074 // 反転するコマがない場合
075 if (n[8] <= 0) {
076 gp.ta.setForeground(Color.red);
077 if (gp.mp.method > 0)
078 gp.ta.setText("あなたの番ですが,\n");
079 else {
080 if (b_w < 0)
081 gp.ta.setText("黒の番ですが,\n");
082 else
083 gp.ta.setText("白の番ですが,\n");
084 }
085 gp.ta.append("そこへはコマを置けません.\n");
086 }
087 // 反転するコマがある場合
088 else
089 set(k);
090 }
091 //
092 // コマの操作
093 //
094 void set(int k[])
095 {
096 // 反転
097 reverse(k);
098 b_w = -b_w;
099 // コマの数を数え,勝敗決定のチェック
100 int b = 0, w = 0, total = 0;
101 for (int i1 = 0; i1 < 8; i1++) {
102 for (int i2 = 0; i2 < 8; i2++) {
103 if (st[i1][i2] != 0) {
104 total++;
105 if (st[i1][i2] < 0)
106 b++;
107 else
108 w++;
109 }
110 }
111 }
112 // 勝敗決定
113 if (total == 64) {
114 gp.ta.setForeground(Color.black);
115 gp.ta.setText("黒 " + b + " 個, 白 " + w + " 個\n");
116 if (gp.mp.method > 0) {
117 if (b == w)
118 gp.ta.append("引き分けです.\n");
119 else if (b > w && gp.mp.method == 1 || b < w && gp.mp.method == 2)
120 gp.ta.append("あなたの勝ちです.\n");
121 else
122 gp.ta.append("コンピュータの勝ちです.\n");
123 }
124 else {
125 if (b > w)
126 gp.ta.append("黒の勝ちです.\n");
127 else if (b == w)
128 gp.ta.append("引き分けです.\n");
129 else
130 gp.ta.append("白の勝ちです.\n");
131 }
132 for (int i1 = 0; i1 < 8; i1++) {
133 for (int i2 = 0; i2 < 8; i2++)
134 km[i1][i2].setEnabled(false);
135 }
136 }
137 // 勝負継続
138 else {
139 gp.ta.setForeground(Color.black);
140 gp.ta.setText("黒 " + b + " 個, 白 " + w + " 個\n");
141 // スキップのチェック
142 boolean sw = false;
143 for (int i1 = 0; i1 < 8 && !sw; i1++) {
144 for (int i2 = 0; i2 < 8 && !sw; i2++) {
145 k[0] = i1;
146 k[1] = i2;
147 r_check(k);
148 if (n[8] > 0)
149 sw = true;
150 }
151 }
152 // 対コンピュータ
153 if (gp.mp.method > 0) {
154 // スキップの場合
155 if (!sw) {
156 b_w = -b_w;
157 gp.ta.append("コマを置けないため,スキップし,\n");
158 if (gp.mp.method == 1 && b_w < 0)
159 gp.ta.append("あなた(黒)の番です.\n");
160 else if (gp.mp.method == 2 && b_w > 0)
161 gp.ta.append("あなた(白)の番です.\n");
162 else {
163 gp.ta.append("コンピュータの番です.\n");
164 k = computer(); // コマを置く場所の決定
165 set(k); // コマを置く
166 }
167 }
168 // 次の手
169 else {
170 if (gp.mp.method == 1 && b_w < 0)
171 gp.ta.append("あなた(黒)の番です.\n");
172 else if (gp.mp.method == 2 && b_w > 0)
173 gp.ta.append("あなた(白)の番です.\n");
174 else {
175 gp.ta.append("コンピュータの番です.\n");
176 k = computer(); // コマを置く場所の決定
177 set(k); // コマを置く
178 }
179 }
180 }
181 // 対人間
182 else {
183 // スキップの場合
184 if (!sw) {
185 gp.ta.append("コマを置けないため,スキップし,\n");
186 b_w = -b_w;
187 }
188 // 次の手
189 if (b_w < 0)
190 gp.ta.append("黒の番です.\n");
191 else
192 gp.ta.append("白の番です.\n");
193 }
194 }
195 }
196 //
197 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合,反転できるコマを探す
198 //
199 void r_check(int k[])
200 {
201 int d[][] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
202 n[8] = 0;
203 if (st[k[0]][k[1]] == 0) {
204 for (int i1 = 0; i1 < 8; i1++) {
205 int m1 = k[0], m2 = k[1];
206 n[i1] = 0;
207 int s = 0; // 0:開始,1:カウント,2:カウント終了,3:反転不可能
208 int ct = 0;
209 while (s < 2) {
210 m1 += d[i1][0];
211 m2 += d[i1][1];
212 if (m1 >= 0 && m1 < 8 && m2 >= 0 && m2 < 8) {
213 if (st[m1][m2] == 0)
214 s = 3;
215 else if (st[m1][m2] == b_w) {
216 if (s == 1)
217 s = 2;
218 else
219 s = 3;
220 }
221 else {
222 s = 1;
223 ct++;
224 }
225 }
226 else
227 s = 3;
228 }
229 if (s == 2) {
230 n[8] += ct;
231 n[i1] = ct;
232 }
233 }
234 }
235 }
236 //
237 // k[0] 行 k[1] 列に黒または白( b_w )のコマを置いた場合におけるコマの反転
238 //
239 void reverse(int k[])
240 {
241 int d[][] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
242 for (int i1 = 0; i1 < 8; i1++) {
243 int m1 = k[0], m2 = k[1];
244 for (int i2 = 0; i2 < n[i1]; i2++) {
245 m1 += d[i1][0];
246 m2 += d[i1][1];
247 km[m1][m2].st = b_w;
248 st[m1][m2] = b_w;
249 }
250 }
251 km[k[0]][k[1]].st = b_w;
252 st[k[0]][k[1]] = b_w;
253 // 描画
254 for (int i1 = 0; i1 < 8; i1++) {
255 for (int i2 = 0; i2 < 8; i2++) {
256 if (st[i1][i2] != 0)
257 km[i1][i2].repaint();
258 }
259 }
260 }
261 //
262 // コンピュータが置くコマの場所を決定
263 //
264 int [] computer()
265 {
266 int k[] = new int [2];
267 int kk[] = new int [2];
268 int mx[] = new int [9];
269 mx[8] = 0;
270 for (int i1 = 0; i1 < 8; i1++) {
271 for (int i2 = 0; i2 < 8; i2++) {
272 kk[0] = i1;
273 kk[1] = i2;
274 r_check(kk);
275 if (n[8] > mx[8]) {
276 k[0] = kk[0];
277 k[1] = kk[1];
278 for (int i3 = 0; i3 < 9; i3++)
279 mx[i3] = n[i3];
280 }
281 }
282 }
283 for (int i1 = 0; i1 < 9; i1++)
284 n[i1] = mx[i1];
285 return k;
286 }
287 }
| 情報学部 | 菅沼ホーム | Java 目次 | 索引 |