我有一个版本的John的“Java生活游戏”:
Frame类:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.swing.JToolBar;
public class Frame extends JFrame {
private Board board;
private BoardInterface boardInterface;
private JMenuBar menuBar;
private JMenu fileMenu, runMenu;
private JMenuItem newMenuItem, clearMenuItem, randMenuItem, exitMenuItem, runMenuItem, pauseMenuItem;
private JToolBar toolBar;
private JButton run, pause;
private Image runToolbar, pauseToolbar;
public Frame(Board board) {
this.board = board;
boardInterface = new BoardInterface(board);
setTitle("The Game of Life");
setSize(board.getWidth() * board.getMultiplier() + 5, board.getHeight() * board.getMultiplier() + 101);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
add(boardInterface);
setMenuBar();
setToolbar();
}
public void setMenuBar() {
menuBar = new JMenuBar();
add(menuBar, BorderLayout.NORTH);
fileMenu = new JMenu("File");
menuBar.add(fileMenu);
newMenuItem = new JMenuItem("New");
fileMenu.add(newMenuItem);
newMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new Frame(new Board());
}
});
fileMenu.add(new JSeparator());
clearMenuItem = new JMenuItem("Clear Board");
fileMenu.add(clearMenuItem);
clearMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
board.setBoard(board.clearBoard());
}
});
randMenuItem = new JMenuItem("Random Board");
fileMenu.add(randMenuItem);
randMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
board.setBoard(board.randomBoard());
}
});
fileMenu.add(new JSeparator());
exitMenuItem = new JMenuItem("Exit");
fileMenu.add(exitMenuItem);
exitMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
runMenu = new JMenu("Run");
menuBar.add(runMenu);
runMenuItem = new JMenuItem("Run");
runMenu.add(runMenuItem);
runMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boardInterface.setIsActive(true);
}
});
pauseMenuItem = new JMenuItem("Pause");
runMenu.add(pauseMenuItem);
pauseMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boardInterface.setIsActive(false);
}
});
}
public void setToolbar() {
toolBar = new JToolBar();
toolBar.setLayout(new FlowLayout(FlowLayout.CENTER));
toolBar.setFloatable(false);
add(toolBar, BorderLayout.SOUTH);
runToolbar = new ImageIcon("src/playToolbar.png").getImage().getScaledInstance(25, 25, Image.SCALE_SMOOTH);
run = new JButton(new ImageIcon(runToolbar));
toolBar.add(run);
run.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boardInterface.setIsActive(true);
}
});
pauseToolbar = new ImageIcon("src/pauseToolbar.png").getImage().getScaledInstance(25, 25, Image.SCALE_SMOOTH);
pause = new JButton(new ImageIcon(pauseToolbar));
toolBar.add(pause);
pause.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boardInterface.setIsActive(false);
}
});
}
public static void main(String[] args) {
Frame frameInterface = new Frame(new Board());
}
}BoardInterface类:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Toolkit;
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;
public class BoardInterface extends JPanel implements ActionListener {
Timer animation = new Timer(500, this);
private Board board;
private boolean isActive;
public BoardInterface(final Board board) {
this.board = board;
setBackground(Color.BLACK);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (!isActive) {
board.getBoard()[e.getY() / board.getMultiplier()][e.getX() / board.getMultiplier()] = !board.getBoard()[e.getY() / board.getMultiplier()][e.getX() / board.getMultiplier()];
}
else {
Toolkit.getDefaultToolkit().beep();
}
}
});
}
public void setIsActive(boolean toSet) {
isActive = toSet;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < board.getHeight(); i++) {
for (int j = 0; j < board.getWidth(); j++) {
g.setColor(board.getBoard()[i][j] ? Color.GREEN : Color.GRAY);
g.fillRect(j * board.getMultiplier(), i * board.getMultiplier(), board.getMultiplier() - 1, board.getMultiplier() - 1);
}
}
if (isActive) {
animation.restart();
}
else {
animation.stop();
repaint();
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(animation)) {
board.nextGeneration();
repaint();
}
}
}Board类:
import java.util.Random;
public class Board {
private boolean[][] board;
private int height, width, multiplier = 10;
public Board() {
this(new boolean[60][60]);
}
public Board(final boolean[][] board) {
this.board = board;
height = board.length;
width = board[0].length;
}
public int getHeight() {
return height;
}
public void setHeight(int n) {
height = n;
}
public int getWidth() {
return width;
}
public void setWidth(int n) {
width = n;
}
public int getMultiplier() {
return multiplier;
}
public void setMultiplier(int n) {
multiplier = n;
}
public boolean[][] getBoard() {
return board;
}
public void setBoard(boolean[][] n) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
board[i][j] = n[i][j];
}
}
}
public boolean[][] randomBoard() {
Random rand = new Random();
boolean[][] randBoard = new boolean[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
randBoard[i][j] = rand.nextBoolean();
}
}
return randBoard;
}
public boolean[][] clearBoard() {
boolean[][] emptyBoard = new boolean[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
emptyBoard[i][j] = false;
}
}
return emptyBoard;
}
public int max(int i, int j) {
return i > j ? i : j;
}
public int countSurrounding(int a, int b) {
int count = 0;
int[][] surrounding = {{a - 1, b - 1},
{a - 1, b },
{a - 1, b + 1},
{a , b - 1},
{a , b + 1},
{a + 1, b - 1},
{a + 1, b },
{a + 1, b + 1}};
for (int[] i: surrounding) {
try {
if (board[i[0]][i[1]]) {
count++;
}
}
catch (ArrayIndexOutOfBoundsException e) {}
}
return count;
}
public void nextGeneration() {
boolean[][] nextBoard = new boolean[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
nextBoard[i][j] = board[i][j];
}
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (board[i][j] && !(countSurrounding(i, j) == 2 || countSurrounding(i, j) == 3)) {
nextBoard[i][j] = false;
}
else if (!board[i][j] && countSurrounding(i, j) == 3) {
nextBoard[i][j] = true;
}
}
}
board = nextBoard;
}
}我来这里是为了问一个标准的问题:有人能提供一个诚实的代码评审吗?谢谢。
发布于 2013-05-25 14:13:37
我不是Java专家,所以我现在说的不是每句话都是正确的,但以下是我的评论:
首先,您在封装方面做得很好。几乎所有的方法都只是几行代码,所以每个方法实际上只做它应该做的事情。此外,您的代码是一个很好的例子,如果代码编写得很好,就不需要注释来解释所做的事情。因为您应该从代码本身中看到所做的事情。
因此,负面的东西来了:
这就是我注意到的。只是出于好奇:你想给你的生活游戏程序增加更多的功能吗?例如,当我编写一个生命游戏程序时,我添加了一些功能,比如保存curent字段,或者在游戏中返回以查看旧的字段。您也可以实现一些功能,如加快游戏或有自定义的字段大小,而不是固定的60*60。
希望这对你有一点帮助。
发布于 2013-05-25 22:55:06
挺不错的。我同意“摩根斯坦”的评论。
然而,有一个大问题:您经常试图获取countSurrounding()中数组范围之外的元素,并且捕获异常。您不应该使用异常来处理标准条件,因为它们会影响性能。你可以用很多方法解决这个问题。提高效率的一种方法是在创建时预先计算每个单元的邻居。
https://codereview.stackexchange.com/questions/26602
复制相似问题