情報学部 | 菅沼ホーム | 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 目次 | 索引 |