8 拼图的第二次迭代不起作用
Second Iteration of 8 Puzzle is Not Working
这是我第一次使用 Java Swing,所以至少可以说我的程序有点混乱。目标是让一个 8 拼图拍摄一张图像,将其分成 9 个扇区,然后按特定顺序放置其中的 8 个扇区(丢弃 1 以进行移动)。该程序第一次运行良好。一旦它被解决,它应该随机化 JButton
组件并允许你解决 again.The 按钮随机化,但不允许我移动它们。任何帮助是极大的赞赏。
通常我 post 只是我认为有问题的代码,但由于代码的混乱性质,我正在 post 整个 class。
编辑:
逐行查看代码后,问题似乎出在 Order() 方法中。如果我一起删除第二个 "if" 语句,该程序可以正常工作,只是不会随机化组件。 (如果我对该语句使用 "else" & "else if" 也是一样)
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class JEightPuzzleFrame extends JFrame implements ActionListener {
JButton[] buttons = new JButton[9];
JButton[][] format = new JButton[3][3];
JPanel puzzle = new JPanel();
JPanel jp = new JPanel();
String path = null;
int h;
int w;
public JEightPuzzleFrame(String Title, String Path) {
super();
path = Path;
add(puzzle);
makeFrame();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(w + 10, h + 10);
setTitle(Title);
setResizable(false);
jp.setVisible(true);
}
public void makeFrame() {
puzzle.setVisible(true);
puzzle.setBounds(100, 100, 612, 519);
makeBtnImg();
puzzle.setLayout(new GridLayout(3, 3));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
puzzle.add(format[i][j]);
if (format[i][j] == buttons[8]) {
puzzle.remove(format[i][j]);
puzzle.add(jp);
}
}
}
}
public void makeBtnImg() {
try {
BufferedImage pic = ImageIO.read(new File(path));
jp.setSize(h, w);
h = pic.getHeight();
w = pic.getWidth();
int count = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
BufferedImage bimg = pic.getSubimage(i * w / 3, j * h / 3, w / 3, h / 3);
if (count < 9) {
buttons[count] = new JButton(new ImageIcon(bimg));
buttons[count].addActionListener(this);
}
count++;
}
}
order(true);
} catch (IOException e) {
}
}
public void order(boolean initial) {
if (initial == true) {
format[0][0] = buttons[8];
format[1][0] = buttons[4];
format[2][0] = buttons[1];
format[0][1] = buttons[0];
format[1][1] = buttons[7];
format[2][1] = buttons[2];
format[0][2] = buttons[3];
format[1][2] = buttons[6];
format[2][2] = buttons[5];
}
if (initial == false) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int rd = (int) Math.random() * (9 - 0);
JButton temp = buttons[rd];
format[i][j] = temp;
}
}
}
refresh();
}
public void refresh() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
puzzle.remove(format[i][j]);
}
}
puzzle.remove(jp);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
puzzle.add(format[i][j]);
if (format[i][j] == buttons[8]) {
puzzle.remove(format[i][j]);
puzzle.add(jp);
}
}
}
getContentPane().validate();
if (format[0][0] == buttons[0] && format[0][1] == buttons[3] && format[0][2] == buttons[6]
&& format[1][0] == buttons[1] && format[1][1] == buttons[4] && format[1][2] == buttons[7]
&& format[2][0] == buttons[2] && format[2][1] == buttons[5] && format[2][2] == buttons[8]) {
JOptionPane.showMessageDialog(null, "YOU WON!");
order(false);
}
}
@Override
public void actionPerformed(ActionEvent e) {
JButton temp;
JButton button = (JButton) e.getSource();
Dimension size = button.getSize();
int buttonX = button.getX();
int buttonY = button.getY();
int buttonPosX = buttonX / size.width;
int buttonPosY = buttonY / size.height;
int leftNeighbor = buttonPosX - 1;
int rightNeighbor = buttonPosX + 1;
int topNeighbor = buttonPosY - 1;
int bottomNeighbor = buttonPosY + 1;
int c = 0;
if (leftNeighbor >= 0 && format[buttonPosY][leftNeighbor] == buttons[8]) {
c = 1;
} else if (rightNeighbor < 3 && format[buttonPosY][rightNeighbor] == buttons[8]) {
c = 2;
} else if (topNeighbor >= 0 && format[topNeighbor][buttonPosX] == buttons[8]) {
c = 3;
} else if (bottomNeighbor <= 2 && format[bottomNeighbor][buttonPosX] == buttons[8]) {
c = 4;
} else {
c = 0;
}
switch (c) {
case 0:
break;
case 1:
temp = format[buttonPosY][buttonPosX];
format[buttonPosY][buttonPosX] = format[buttonPosY][leftNeighbor];
format[buttonPosY][leftNeighbor] = temp;
refresh();
break;
case 2:
temp = format[buttonPosY][buttonPosX];
format[buttonPosY][buttonPosX] = format[buttonPosY][rightNeighbor];
format[buttonPosY][rightNeighbor] = temp;
refresh();
break;
case 3:
temp = format[buttonPosY][buttonPosX];
format[buttonPosY][buttonPosX] = format[topNeighbor][buttonPosX];
format[topNeighbor][buttonPosX] = temp;
refresh();
break;
case 4:
temp = format[buttonPosY][buttonPosX];
format[buttonPosY][buttonPosX] = format[bottomNeighbor][buttonPosX];
format[bottomNeighbor][buttonPosX] = temp;
refresh();
break;
}
}
}
首先,由于以下几个原因,这段代码很难阅读:
- 变量名没有意义。 "c" 之类的名称可能对您有某种意义,但当其他人阅读它时,我们只能猜测它可能代表什么。
- 您正在使用 Java 提供的基元和 类,尽管它会简化您的代码以创建您自己设计的自定义对象。
- 代码中没有注释
至于你的具体问题,问题确实出在你所怀疑的order
方法上。就是这一行:
int rd = (int) Math.random() * (9 - 0);
转换为 int
发生在乘法之前,因此您在这里得到的结果总是 0。这会导致 format
数组中的所有按钮都相同。
但是,还有一个更大的问题。即使你通过这样做修复了上面的行:
int rd = (int) (Math.random() * (9 - 0));
您仍然会遇到问题,因为您永远无法确保每个按钮只使用一次。换句话说,rd
可以在当前循环中为 3,然后在下一个循环中再次为 3,因为它是随机的——没有记忆之前使用过和未使用过的内容。您需要的是一种防止重复的机制,以便每个按钮都是唯一的。
所以,像这样的东西应该可以解决问题:
if (initial == false) {
boolean[] isUsed = new boolean[buttons.length];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int rd = -1;
do{
rd = (int) (Math.random() * (9 - 0));
}while(isUsed[rd]);
isUsed[rd] = true;
JButton temp = buttons[rd];
format[i][j] = temp;
}
}
}
这是我第一次使用 Java Swing,所以至少可以说我的程序有点混乱。目标是让一个 8 拼图拍摄一张图像,将其分成 9 个扇区,然后按特定顺序放置其中的 8 个扇区(丢弃 1 以进行移动)。该程序第一次运行良好。一旦它被解决,它应该随机化 JButton
组件并允许你解决 again.The 按钮随机化,但不允许我移动它们。任何帮助是极大的赞赏。
通常我 post 只是我认为有问题的代码,但由于代码的混乱性质,我正在 post 整个 class。
编辑: 逐行查看代码后,问题似乎出在 Order() 方法中。如果我一起删除第二个 "if" 语句,该程序可以正常工作,只是不会随机化组件。 (如果我对该语句使用 "else" & "else if" 也是一样)
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class JEightPuzzleFrame extends JFrame implements ActionListener {
JButton[] buttons = new JButton[9];
JButton[][] format = new JButton[3][3];
JPanel puzzle = new JPanel();
JPanel jp = new JPanel();
String path = null;
int h;
int w;
public JEightPuzzleFrame(String Title, String Path) {
super();
path = Path;
add(puzzle);
makeFrame();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(w + 10, h + 10);
setTitle(Title);
setResizable(false);
jp.setVisible(true);
}
public void makeFrame() {
puzzle.setVisible(true);
puzzle.setBounds(100, 100, 612, 519);
makeBtnImg();
puzzle.setLayout(new GridLayout(3, 3));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
puzzle.add(format[i][j]);
if (format[i][j] == buttons[8]) {
puzzle.remove(format[i][j]);
puzzle.add(jp);
}
}
}
}
public void makeBtnImg() {
try {
BufferedImage pic = ImageIO.read(new File(path));
jp.setSize(h, w);
h = pic.getHeight();
w = pic.getWidth();
int count = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
BufferedImage bimg = pic.getSubimage(i * w / 3, j * h / 3, w / 3, h / 3);
if (count < 9) {
buttons[count] = new JButton(new ImageIcon(bimg));
buttons[count].addActionListener(this);
}
count++;
}
}
order(true);
} catch (IOException e) {
}
}
public void order(boolean initial) {
if (initial == true) {
format[0][0] = buttons[8];
format[1][0] = buttons[4];
format[2][0] = buttons[1];
format[0][1] = buttons[0];
format[1][1] = buttons[7];
format[2][1] = buttons[2];
format[0][2] = buttons[3];
format[1][2] = buttons[6];
format[2][2] = buttons[5];
}
if (initial == false) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int rd = (int) Math.random() * (9 - 0);
JButton temp = buttons[rd];
format[i][j] = temp;
}
}
}
refresh();
}
public void refresh() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
puzzle.remove(format[i][j]);
}
}
puzzle.remove(jp);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
puzzle.add(format[i][j]);
if (format[i][j] == buttons[8]) {
puzzle.remove(format[i][j]);
puzzle.add(jp);
}
}
}
getContentPane().validate();
if (format[0][0] == buttons[0] && format[0][1] == buttons[3] && format[0][2] == buttons[6]
&& format[1][0] == buttons[1] && format[1][1] == buttons[4] && format[1][2] == buttons[7]
&& format[2][0] == buttons[2] && format[2][1] == buttons[5] && format[2][2] == buttons[8]) {
JOptionPane.showMessageDialog(null, "YOU WON!");
order(false);
}
}
@Override
public void actionPerformed(ActionEvent e) {
JButton temp;
JButton button = (JButton) e.getSource();
Dimension size = button.getSize();
int buttonX = button.getX();
int buttonY = button.getY();
int buttonPosX = buttonX / size.width;
int buttonPosY = buttonY / size.height;
int leftNeighbor = buttonPosX - 1;
int rightNeighbor = buttonPosX + 1;
int topNeighbor = buttonPosY - 1;
int bottomNeighbor = buttonPosY + 1;
int c = 0;
if (leftNeighbor >= 0 && format[buttonPosY][leftNeighbor] == buttons[8]) {
c = 1;
} else if (rightNeighbor < 3 && format[buttonPosY][rightNeighbor] == buttons[8]) {
c = 2;
} else if (topNeighbor >= 0 && format[topNeighbor][buttonPosX] == buttons[8]) {
c = 3;
} else if (bottomNeighbor <= 2 && format[bottomNeighbor][buttonPosX] == buttons[8]) {
c = 4;
} else {
c = 0;
}
switch (c) {
case 0:
break;
case 1:
temp = format[buttonPosY][buttonPosX];
format[buttonPosY][buttonPosX] = format[buttonPosY][leftNeighbor];
format[buttonPosY][leftNeighbor] = temp;
refresh();
break;
case 2:
temp = format[buttonPosY][buttonPosX];
format[buttonPosY][buttonPosX] = format[buttonPosY][rightNeighbor];
format[buttonPosY][rightNeighbor] = temp;
refresh();
break;
case 3:
temp = format[buttonPosY][buttonPosX];
format[buttonPosY][buttonPosX] = format[topNeighbor][buttonPosX];
format[topNeighbor][buttonPosX] = temp;
refresh();
break;
case 4:
temp = format[buttonPosY][buttonPosX];
format[buttonPosY][buttonPosX] = format[bottomNeighbor][buttonPosX];
format[bottomNeighbor][buttonPosX] = temp;
refresh();
break;
}
}
}
首先,由于以下几个原因,这段代码很难阅读:
- 变量名没有意义。 "c" 之类的名称可能对您有某种意义,但当其他人阅读它时,我们只能猜测它可能代表什么。
- 您正在使用 Java 提供的基元和 类,尽管它会简化您的代码以创建您自己设计的自定义对象。
- 代码中没有注释
至于你的具体问题,问题确实出在你所怀疑的order
方法上。就是这一行:
int rd = (int) Math.random() * (9 - 0);
转换为 int
发生在乘法之前,因此您在这里得到的结果总是 0。这会导致 format
数组中的所有按钮都相同。
但是,还有一个更大的问题。即使你通过这样做修复了上面的行:
int rd = (int) (Math.random() * (9 - 0));
您仍然会遇到问题,因为您永远无法确保每个按钮只使用一次。换句话说,rd
可以在当前循环中为 3,然后在下一个循环中再次为 3,因为它是随机的——没有记忆之前使用过和未使用过的内容。您需要的是一种防止重复的机制,以便每个按钮都是唯一的。
所以,像这样的东西应该可以解决问题:
if (initial == false) {
boolean[] isUsed = new boolean[buttons.length];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int rd = -1;
do{
rd = (int) (Math.random() * (9 - 0));
}while(isUsed[rd]);
isUsed[rd] = true;
JButton temp = buttons[rd];
format[i][j] = temp;
}
}
}