package test5;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class test8 extends JFrame {
private char whoseTurn = 'w';// 判断是哪一方下棋,因为要求黑棋先下,所以设置黑方为B,白方为W
private JLabel jlblStatus = new JLabel("黑方下棋");
JPanel showWhoseTurn = new JPanel();
public test8() {
ChessConvas ChessPanel = new ChessConvas();// 请看上方的解释1
add(ChessPanel, BorderLayout.CENTER);// 添加(棋盘格、边框布局、中间);
jlblStatus.setFont(new Font("宋体", Font.BOLD, 18));
// Font类设置GUI界面的字体样式
showWhoseTurn.add(jlblStatus, new GridLayout(1, 3));// 增加网格布局
add(showWhoseTurn, BorderLayout.NORTH);
}
public static void main(String[] args) {
JFrame fr = new test8();// 请看上方的解释1
fr.setLocationRelativeTo(null);// 设置窗口相对于指定组件的位置,设置居中显示
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setTitle("五子棋");// 设置五子琪
fr.setVisible(true);// 设置true
fr.setResizable(false);// 设置false
fr.setSize(650, 650);// 设置棋盘页面大小为650*650
}
//棋盘类
class ChessConvas extends JPanel {
private int xMove = 60;// 定义x轴,并规定最大可移动距离
private int yMove = 60;// 同上,定义y轴
private int xPosition;// x的位置
private int yPosition;// y的位置
private ArrayList rbList = new ArrayList();// 请看解释1
private char chessSide = ' ';// 执棋的一方
private JPanel btPanel = new JPanel();//
private JButton btReset = new JButton("重新开始");//
private JButton b = new JButton("人机下棋");
public ChessConvas() {
addMouseListener(new MouseListener());
btReset.setBounds(new Rectangle(440, 40, 100, 30));// 形成有界限的矩阵图案
btReset.addActionListener(new ResetEvent());// 匿名内部类实现监听
add(btReset);
setLayout(null);// 默认的是FlowLayout布局,需要加此
addMouseListener(new MouseListener());
b.setBounds(new Rectangle(440, 40, 100, 30));
b.addActionListener(new ResetEvent());
add(b);
setLayout(null);
}
public void setChessSide(char c) {// 棋子的位置
chessSide = c;
repaint();// repaint()具有刷新页面效果
}
public char gerChessColor() {// 棋子的颜色
return chessSide;
}
public void setXPosition(int xp) {// x的位置
xPosition = xp;
repaint();
}
public int getXPosition() {
return xPosition;
}
public void setYPosition(int yp) {// y的位置
yPosition = yp;
repaint();
}
public int getYPosition() {
return yPosition;
}
public boolean find(ArrayList rbList, int x, int y, Color bakColor) {
for (int i = 0; i < rbList.size(); i++) {
if ((((RoundButton1) rbList.get(i)).getX() == x) && (((RoundButton1) rbList.get(i)).getY() == y)
&& (((RoundButton1) rbList.get(i)).getBackground() == bakColor)) {
return true;
}
}
return false;
}
public boolean isWinner(ArrayList rbList, int x, int y, Color bakColor) {
for (int i = 0, k = 0; i < 7; i++) {
// 竖直方向
if (find(rbList, x + 0 * i, y + 30 * i, bakColor))
k++;
if (find(rbList, x + 0 * i, y - 30 * i, bakColor)) {
if (i != 0)
k++;
}
System.out.println("竖直方向 k= " + k);
if (!find(rbList, x + 0 * i, y + 30 * i, bakColor) && !find(rbList, x + 0 * i, y - 30 * i, bakColor))
break;// 若竖直两个方向都走不通则跳出循环
if (k == 5) {
jlblStatus.setText((bakColor == Color.BLACK) ? "黑方获胜!!!" : "白方获胜!!!");
return true;
}
}
for (int i = 0, k = 0; i < 7; i++) {
// 左上至右下方向
if (find(rbList, x - 30 * i, y - 30 * i, bakColor))
k++;
if (find(rbList, x + 30 * i, y + 30 * i, bakColor)) {
if (i != 0)
k++;
}
System.out.println("左上至右下方向 k= " + k);
if (!find(rbList, x - 30 * i, y - 30 * i, bakColor) && !find(rbList, x + 30 * i, y + 30 * i, bakColor))
break; // 若左上与右下两个方向都走不通则跳出循环
if (k == 5) {
jlblStatus.setText((bakColor == Color.BLACK) ? "黑方获胜!!!" : "白方获胜!!!");
return true;
}
}
for (int i = 0, k = 0; i < 7; i++) {
// 左下至右上方向
if (find(rbList, x - 36 * i, y + 36 * i, bakColor))
k++;
if (find(rbList, x + 36 * i, y - 36 * i, bakColor)) {
if (i != 0)
k++;
}
System.out.println("左下至右上方向k= " + k);
if (!find(rbList, x - 36 * i, y + 36 * i, bakColor) && !find(rbList, x + 36 * i, y - 36 * i, bakColor))
break;// 若左下至右上两个方向都走不通则跳出循环
if (k == 5) {
jlblStatus.setText((bakColor == Color.BLACK) ? "黑方获胜!!!" : "白方获胜!!!");
return true;
}
}
for (int i = 0, k = 0; i < 7; i++) {
// 水平方向
if (find(rbList, x - 36 * i, y + 0 * i, bakColor))
k++;
if (find(rbList, x + 36 * i, y - 0 * i, bakColor)) {
if (i != 0)
k++;
}
System.out.println("水平方向 k= " + k);
if (!find(rbList, x - 36 * i, y + 0 * i, bakColor) && !find(rbList, x + 36 * i, y - 0 * i, bakColor))
break; // 若水平的两个方向都走不通则跳出循环
if (k == 5) {
jlblStatus.setText((bakColor == Color.BLACK) ? "黑方获胜!!!" : "白方获胜!!!");
return true;
}
}
return false;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (int i = 1; i <= 16; i++) {
g2.draw(new Line2D.Double(30 + xMove, 30 * i + yMove, 16 * 30 + xMove, 30 * i + yMove));
g2.draw(new Line2D.Double(30 * i + xMove, 30 + yMove, 30 * i + xMove, 16 * 30 + yMove));
}
}
private class MouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
if (chessSide == ' ' && whoseTurn != ' ') {
setChessSide(whoseTurn);// set ChessSide in the chessCovas
}
xPosition = e.getX();
yPosition = e.getY();
if (xPosition > 30 + xMove && xPosition < 16 * 30 + xMove && yPosition > 30 + yMove
&& yPosition < 16 * 30 + yMove) {
jlblStatus.setText((whoseTurn == 'B') ? "黑方下棋" : "白方下棋");
whoseTurn = (whoseTurn == 'B') ? 'W' : 'B';
int X = xPosition / 30;
int Y = yPosition / 30;
int centerX;
int centerY;
// 棋子落点的判断
if (xPosition % 30 > 30 / 2) {
centerX = (X + 1) * 30;
if (yPosition % 30 > 30 / 2)
centerY = (Y + 1) * 30;
else
centerY = Y * 30;
} else {
centerX = X * 30;
if (yPosition % 30 > 30 / 2)
centerY = (Y + 1) * 30;
else
centerY = Y * 30;
}
RoundButton1 rb = new RoundButton1("");
// roundButtonArray[i]=rb;
// i++;
rbList.add(rb);
add(rb);
// 棋子大小
rb.setBounds(new Rectangle(centerX - 10, centerY - 10, 20, 20));
if (whoseTurn == 'B') {
rb.setBackground(Color.BLACK);
System.out.println("黑棋 x: " + rb.getX() + " y: " + rb.getY());
boolean flag = isWinner(rbList, rb.getX(), rb.getY(), Color.BLACK);
System.out.println(flag);
if (flag == true) {
removeMouseListener(this);// 当一方获胜后则不再响应鼠标事件
}
} else {
rb.setBackground(Color.WHITE);
System.out.println("白棋 x: " + rb.getX() + " y: " + rb.getY());
boolean flag = isWinner(rbList, rb.getX(), rb.getY(), Color.WHITE);
System.out.println(flag);
if (flag == true) {
removeMouseListener(this);// 当一方获胜后则不再响应鼠标事件
}
}
repaint();
}
}
}
private class ResetEvent implements ActionListener {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < rbList.size(); i++) {
remove((RoundButton1) rbList.get(i));
}
rbList.clear();
repaint();
addMouseListener(new MouseListener());// 以便重新开始后重新响应鼠标事件
}
}
}
}
//用圆形BUTTON实现棋子类
class RoundButton1 extends JButton {
public RoundButton1() {
}
public RoundButton1(String label) {
super(label);
// 下面的语句讲述这个按钮变为一个圆形而不是椭圆形
Dimension size = getPreferredSize();
size.width = size.height = Math.max(size.width, size.height);
setPreferredSize(size);
// 不让JButton画背景而允许我们去画一个圆背景
setContentAreaFilled(false);
}
// 画出圆的背景和标签
protected void paintComponent(Graphics g) {
if (getModel().isArmed()) {
g.setColor(Color.lightGray);
} else {
g.setColor(getBackground());
}
g.fillOval(0, 0, getSize().width - 1, getSize().height - 1);
// 在焦点上画出一个标签
super.paintComponent(g);
}
// 画出一个边框
protected void paintBorder(Graphics g) {
g.setColor(getForeground());
g.drawOval(0, 0, getSize().width - 1, getSize().height - 1);
}
// 侦察单击区域
Shape shape;
public boolean contains(int x, int y) {
// 如果按钮改变了尺寸将重新创建一个Shape
if (shape == null || !shape.getBounds().equals(getBounds())) {
shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
}
return shape.contains(x, y);
}
}