JAVA五子棋
前言,既(1)之后,我们的(2)是在(1)的基础上添加判断输赢,悔棋,认输等等方法,这些非常简单,只需要明白意思,就能完成
首先回顾一下我们(1)中的流程
建立一个Chess包→界面类ChessUI→画棋子类DrawChess→监听器类ChessListener→回到ChessUI中添加监听器
判断输赢
判断方法为,以当前落子点为基点,遍历横竖左斜右斜四个方向,如果相邻的颜色相同,sum++,sum达到总数5后,便取得胜利
DrawChess类
public class DrawChess {
int turn;
ChessUI ui;
Graphics g;
public void setG(ChessUI ui, int turn) {
this.ui = ui;
this.turn = turn;
}
public void chess(int x, int y) {
g = ui.getGraphics();
g.setFont(new Font("行楷", Font.BOLD, 20));
int h = (x + 30) / 60;// 行
int l = (y - 50) / 60;// 列
int xp = h * 60 - 25;
int yp = l * 60 + 60;
// 检查x,y
if (x >= 300 && x <= 1140 && y >= 80 && y <= 920) {
System.out.println(x + "++" + y);
// 画棋子
if (turn == 1) {
g.setColor(Color.BLACK);
ui.che[h][l] = 1;
//这一步很重要,把每一步棋子都存入我们的ChessPosition,保证了悔棋的成功。
ui.ChessPosition.add(new ChessPosition(h, l));
g.fillOval(xp, yp, 50, 50);
// 判断输赢
boolean b = judge(h, l);
if (b) {
JOptionPane.showMessageDialog(null, "黑方胜利", "游戏结束", JOptionPane.INFORMATION_MESSAGE);
}
} else {
g.setColor(Color.WHITE);
ui.che[h][l] = 2;
g.fillOval(xp, yp, 50, 50);
// 判断输赢
boolean b = judge(h, l);
if (b) {
JOptionPane.showMessageDialog(null, "白方胜利", "游戏结束", JOptionPane.INFORMATION_MESSAGE);
}
}
}
}
//判断输赢的方法
public boolean judge(int x, int y) {
// 竖着
int sum = 1;
// 向上看
for (int i = x - 1; i >= 0; i--) {
if (ui.che[i][y] == ui.che[x][y])
sum++;
else
break;
}
// 向下看
for (int i = x + 1; i < 20; i++) {
if (ui.che[i][y] == ui.che[x][y])
sum++;
else
break;
}
if (sum > 4)
return true;
// 横着
sum = 1;
// 向左看
for (int i = y - 1; i >= 0; i--) {
if (ui.che[x][i] == ui.che[x][y])
sum++;
else
break;
}
// 向右看
for (int i = y + 1; i < 19; i++) {
if (ui.che[x][i] == ui.che[x][y])
sum++;
else
break;
}
if (sum > 4)
return true;
// 左斜
sum = 1;
// 向左上看
for (int i = x - 1, j = y - 1; (i >= 0) && (j >= 0); i--, j--) {
if (ui.che[i][j] == ui.che[x][y])
sum++;
else
break;
}
// 向右下看
for (int i = x + 1, j = y + 1; (i < 20) && (j < 20); i++, j++) {
if (ui.che[i][j] == ui.che[x][y])
sum++;
else
break;
}
if (sum > 4)
return true;
// 右斜
sum = 1;
// 向右上看
for (int i = x - 1, j = y + 1; (i >= 0) && (j < 20); i--, j++) {
if (ui.che[i][j] == ui.che[x][y])
sum++;
else
break;
}
// 向左下看
for (int i = x + 1, j = y - 1; (i < 20) && (j >= 0); i++, j--) {
if (ui.che[i][j] == ui.che[x][y])
sum++;
else
break;
}
if (sum > 4)
return true;
// 没有连续五个
return false;
}
}
以上就完成了基本的五子棋功能了,已经可以进行基础的人人对战了
悔棋
悔棋方法为:创建一个数组,来保存我们每一步的落子,点击悔棋按钮时,我们清除这一步棋子,然后重绘棋盘即可,这里我们在ChessUI创建一个ArrayList,来储存我们的ChessPosition
ChessPosition类
public class ChessPosition {
public int Listi, Listj;
public ChessPosition() {
//空构造器
}
public ChessPosition(int Listi, int Listj) {
this.Listi = Listi;//当前棋子的横位置
this.Listj = Listj;//当前棋子的纵位置
}
}
然后是我们的ChessUI类,在这里定义一个ArrayList
ChessUI类
public class ChessUI extends JFrame {
int[][] che = new int[30][30];
JLabel txtLable1 = new JLabel("准备开始");
JLabel txtLable2 = new JLabel(" ");
JComboBox<String> box = new JComboBox<String>();
ChessListener ch = new ChessListener(this);
public ArrayList<ChessPosition> ChessPosition = new ArrayList<ChessPosition>();// 保存每一步棋子的落子
public void chessFrame() {
// 设置窗体
setTitle("五子棋");
setSize(1400, 1000);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// 添加边界
JPanel eastP = new JPanel();
JPanel westP = new JPanel();
JPanel centP = new JPanel();
eastP.setPreferredSize(new Dimension(200, 0));
westP.setPreferredSize(new Dimension(240, 0));
centP.setPreferredSize(new Dimension(240, 1200));
westP.setLayout(new BorderLayout());
centP.setBackground(Color.lightGray);
this.add(eastP, BorderLayout.EAST);
this.add(westP, BorderLayout.WEST);
this.add(centP, BorderLayout.CENTER);
// 设置右边边界的边框
JPanel upP = new JPanel();
JPanel cenP = new JPanel();
Dimension size = new Dimension(190, 300);
upP.setPreferredSize(size);
cenP.setPreferredSize(size);
eastP.add(upP, BorderLayout.NORTH);
eastP.add(cenP, BorderLayout.CENTER);
// 左边边界
JPanel up = new JPanel();
JPanel cen = new JPanel();
up.setPreferredSize(size);
cen.setPreferredSize(size);
JPanel txtP = new JPanel();
txtP.setBackground(Color.lightGray);
txtP.setPreferredSize(new Dimension(150, 130));
cen.add(txtP);
westP.add(up, BorderLayout.NORTH);
westP.add(cen, BorderLayout.CENTER);
txtLable1.setFont(new Font("黑体", Font.PLAIN, 24));
txtLable2.setFont(new Font("黑体", Font.PLAIN, 24));
txtP.add(txtLable1);
txtP.add(txtLable2);
// 添加按钮
Dimension btnSize = new Dimension(160, 45);
String[] butname = { "游戏说明", "悔棋", "认输", "开始游戏" };
JButton[] button = new JButton[4];
for (int i = 0; i < butname.length; i++) {
button[i] = new JButton(butname[i]);
button[i].setPreferredSize(btnSize);
cenP.add(button[i]);
}
cenP.add(box);
box.setPreferredSize(new Dimension(140, 45));
box.addItem("--游戏模式--");
box.addItem("人人对战");
box.addItem("人机对战");
// 添加监听器
for (int i = 0; i < butname.length; i++) {
button[i].addActionListener(ch);// 添加发生操作的监听方法
}
box.addActionListener(ch);
setVisible(true);
addMouseListener(ch);
ch.g = this.getGraphics();
repaint();
}
//把棋盘的绘画封装成一个方法
public void board(Graphics g) {
g.drawLine(280, 60, 1160, 60);
g.drawLine(280, 60, 280, 940);
g.drawLine(280, 940, 1160, 940);
g.drawLine(1160, 60, 1160, 940);
for (int i = 0; i < 15; i++) {
g.setColor(Color.BLACK);
g.drawLine(300, 80 + i * 60, 1140, 80 + i * 60); // 画棋盘横线
g.drawLine(300 + i * 60, 80, 300 + i * 60, 920); // 画棋盘竖线
g.fillOval(473, 253, 15, 15);
g.fillOval(473, 733, 15, 15);
g.fillOval(473, 493, 15, 15);
g.fillOval(953, 253, 15, 15);
g.fillOval(953, 733, 15, 15);
g.fillOval(953, 493, 15, 15);
g.fillOval(713, 253, 15, 15);
g.fillOval(713, 733, 15, 15);
g.fillOval(713, 493, 15, 15);
}
// 设置界面
g.setColor(Color.BLACK);
g.drawRect(390, 945, 210, 40);
g.drawRect(650, 945, 210, 40);
g.setFont(new Font("楷体", Font.BOLD, 20));
g.drawString("黑方时间:", 400, 975);
g.drawString("白方时间:", 660, 975);
}
//把棋子的重绘封装成一个方法
public void chess(Graphics g) {
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
if (che[i][j] == 1) {
int x = 60 * i - 25;
int y = 60 * j + 60;
g.setColor(Color.BLACK);
g.fillOval(x, y, 50, 50);
} else if (che[i][j] == 2) {
int x = 60 * i - 25;
int y = 60 * j + 60;
g.setColor(Color.WHITE);
g.fillOval(x, y, 50, 50);
}
}
}
}
public void paint(Graphics g) {
super.paint(g);
board(g);
chess(g);
}
public static void main(String[] args) {
ChessUI chess = new ChessUI();
chess.chessFrame();
}
}
最后在我们的ChessListener里加上悔棋的方法就好了
ChessListener类
public class ChessListener implements MouseListener, ActionListener {
int x;
int y;
int turn = 0;
Graphics g;
DrawChess D = new DrawChess();
ChessUI ui;
public ChessListener() {
}
public ChessListener(ChessUI ui) {
this.ui = ui;
System.out.println("Listener ready");
// D.ui = ui;
}
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent e) {
if (turn == 0) {
return;
}
if (ui.box.getSelectedItem().equals("人人对战")) {
x = e.getX();
y = e.getY();
int h = (x + 30) / 60;// 行
int l = (y - 50) / 60;// 列
if (ui.che[h][l] != 0) {
JOptionPane.showMessageDialog(null, "此处已有棋子,请下在别处");
return;
}
D.setG(ui, turn);
D.chess(x, y);
if (x >= 300 && x <= 1140 && y >= 80 && y <= 920) {
if (turn == 1) {
turn++;
ui.txtLable2.setText("白方下棋");
} else if (turn == 2) {
turn--;
ui.txtLable2.setText("黑方下棋");
}
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (ui.box.getSelectedItem().equals("游戏模式")) {
if (cmd.equals("开始游戏")) {
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
ui.che[i][j] = 0;
}
}
ui.repaint();
turn = 1;
}
}
//相当于重新开始
else if (cmd.equals("开始游戏")) {
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
ui.che[i][j] = 0;
}
}
ui.repaint();
turn = 1;
ui.txtLable2.setText("黑方下棋");
}
//悔棋功能的实现
else if(cmd.equals("悔棋")) {
System.out.println("dada");
if (ui.ChessPosition.size()>0){
ChessPosition cp = new ChessPosition();
//ChessPosition数组最后一位清除
cp = ui.ChessPosition.remove(ui.ChessPosition.size()-1);
//che数组当前位置为0
ui.che[cp.Listi][cp.Listj]=0;
if (turn==1)
{turn++;}
else {turn--;}
ui.repaint();
}
}
}
}
认输
这个功能很简单,只需要检查turn为几,便可知道是哪一方提出的认输,然后提示另一方获胜即可,之后令turn=0,不能再下棋,我在下面顺便加上了另外一些功能
public class ChessListener implements MouseListener, ActionListener {
int x;
int y;
int turn = 0;
Graphics g;
DrawChess D = new DrawChess();
ChessUI ui;
public ChessListener() {
}
public ChessListener(ChessUI ui) {
this.ui = ui;
System.out.println("Listener ready");
// D.ui = ui;
}
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent e) {
if (turn == 0) {
return;
}
if (ui.box.getSelectedItem().equals("人人对战")) {
x = e.getX();
y = e.getY();
int h = (x + 30) / 60;// 行
int l = (y - 50) / 60;// 列
if (ui.che[h][l] != 0) {
JOptionPane.showMessageDialog(null, "此处已有棋子,请下在别处");
return;
}
D.setG(ui, turn);
D.chess(x, y);
if (x >= 300 && x <= 1140 && y >= 80 && y <= 920) {
if (turn == 1) {
turn++;
ui.txtLable2.setText("白方下棋");
} else if (turn == 2) {
turn--;
ui.txtLable2.setText("黑方下棋");
}
}
}
}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (ui.box.getSelectedItem().equals("游戏模式")) {
if (cmd.equals("开始游戏")) {
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
ui.che[i][j] = 0;
}
}
ui.repaint();
turn = 1;
}
}
//相当于重新开始
else if (cmd.equals("开始游戏")) {
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
ui.che[i][j] = 0;
}
}
ui.repaint();
turn = 1;
ui.txtLable2.setText("黑方下棋");
}
else if (cmd.equals("悔棋")) {
System.out.println("dada");
if (ui.ChessPosition.size() > 0) {
System.out.println("ssss");
ChessPosition cp = new ChessPosition();
cp = ui.ChessPosition.remove(ui.ChessPosition.size() - 1);
ui.che[cp.Listi][cp.Listj] = 0;
if (turn == 1) {
turn++;
} else {
turn--;
}
ui.repaint();
}
} else if (cmd.equals("游戏说明")) {
JOptionPane.showMessageDialog(null, "先连成五子者获胜", "游戏说明", JOptionPane.INFORMATION_MESSAGE);
}
else if (cmd.equals("认输")) {
if (turn == 1) {
JOptionPane.showMessageDialog(null, "恭喜白方获胜", "游戏结束", JOptionPane.INFORMATION_MESSAGE);
} else if (turn == 2) {
JOptionPane.showMessageDialog(null, "恭喜黑方获胜", "游戏结束", JOptionPane.INFORMATION_MESSAGE);
}
turn = 0;//关键一步,turn=0,不能再下棋
}
}
}
以上就是我们的五子棋版本(2)啦!,这几乎已经是一个完整的五子棋小游戏了,如果还想要继续下去,就是我们的人机对战功能了,那会在我们的JAVA五子棋(3)中实现,同时做到我们界面的优化!
over~