【练习】面向对象系列(007)——五子棋
要求:运行程序后,程序可以自已落子,此时人不能下棋,按F2后停止自动落子,此时可以开始下棋
package cn.libill;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
/**
* 五子棋窗口
* @author libill
*
*/
@SuppressWarnings("serial")
public class RenjuFrame extends JDialog {
private BoardPanel boardPanel = new BoardPanel();
public RenjuFrame() {
this.setTitle("五子棋");
this.setSize(625, 650);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setIconImage(new ImageIcon("renju.png").getImage());
this.add(boardPanel);
//键盘监听器要放在窗口类中,不能放在面板类中
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
//是否按下F2
if (e.getKeyCode() == KeyEvent.VK_F2) {
boardPanel.reset();
repaint();
}
}
});
}
public static void main(String[] args) {
new RenjuFrame().setVisible(true);
}
}
package cn.libill;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import javax.swing.Timer;
/**
* 棋盘面板类
* @author libill
*
*/
@SuppressWarnings("serial")
public class BoardPanel extends JPanel {
private boolean isBlack = true;
private Board board = new Board();
private Timer timer;
private boolean gamebegin;
public BoardPanel() {
this.setSize(590, 590);
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if (x >= 20 && x <= 600 && y >= 20 && y <= 600 && gamebegin) {
int row = Math.round((y - 30) / 40.0F); //四舍五入
int col = Math.round((x - 30) / 40.0F);
if (board.move(row, col, isBlack)) {
isBlack = !isBlack;
}
}
repaint();
}
});
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int row = (int) (Math.random() * 15);
int col = (int) (Math.random() * 15);
if (board.move(row, col, isBlack)) {
isBlack = !isBlack;
repaint();
}
}
});
//启动计时器
timer.start();
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.ORANGE);
g.fillRect(0, 0, 625, 650);
g.setColor(Color.BLACK);
board.draw(g);
}
public void reset() {
timer.stop(); //关闭计时器
board.reset();
isBlack = true;
gamebegin = true;
}
}
package cn.libill;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
/**
* 棋盘
* @author libill
*
*/
public class Board {
private static final int CELL_SIZE = 40;
private int[][] board = new int[15][15]; //15行15列棋盘,若0则为空白,1为黑棋,2为白棋
/**
*
* @param row 行
* @param col 列
* @param isBlack 黑棋还是白棋
* @return 如下下棋成功返回true,否则返回false
*/
public boolean move(int row, int col, boolean isBlack) {
if (board[row][col] == 0) { //为0表示当前位置没有下棋子
board[row][col] = isBlack ? 1 : 2;
return true; //下子成功,返回true
}
return false; //下子失败,返回false
}
public void draw(Graphics g) {
for (int i = 0; i < board.length; i++) {
for (int j= 0; j < board[i].length; j++) {
g.drawLine(30, 30 + CELL_SIZE * i, 590, 30 + CELL_SIZE * i);
g.drawLine(30 + CELL_SIZE * i, 30, 30 + CELL_SIZE * i, 590);
}
}
g.fillOval(305, 305, 10, 10); //天元
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(3)); //将画笔变粗
g.drawRect(25, 25, 570, 570); //画边框
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
if (board[i][j] != 0) {
Color color = board[i][j] == 1 ? Color.BLACK : Color.WHITE; //为1则画黑子,为2则画白子
g.setColor(color);
g.fillOval(10 + 40 * j, 10 + 40 * i, CELL_SIZE, CELL_SIZE);
}
}
}
}
public void reset() {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j] = 0;
}
}
}
}
注:此练习只实现了下棋,并未添加判断输赢方法。