“熄灯”有效性检查器

时间:2014-12-19 14:05:27

标签: java solver

我一直在尝试编写“熄灯”游戏并对游戏及其机制进行编码。我唯一的问题是每个谜题都无法解决的问题。我试图编写一种方法来检查它为可解决性创建的难题,但是当我运行游戏时,现在什么都没有出现。游戏永远不会运行。我相信它被卡在checkValidity()方法的某个地方,但我不知道在哪里。有什么帮助吗?

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.GridLayout;
import java.awt.Dimension;
import java.awt.Color;

import java.util.Random;

public class buildBoard {
    public static JButton[][] board = new JButton[5][5];
    public static boolean[][] color = new boolean[5][5];;
    JFrame frame = new JFrame();

    public static UIManager UIManager = new UIManager();

    public static int boardWidth, boardHeight, numBlack, moves = 0;

    public static String bottomRow = "";
    public static boolean isSolvable = false;

    public buildBoard(final int width, final int height){

        boardWidth = width;
        boardHeight = height;

        frame.setLayout(new GridLayout(5, 5));

        boolean[][] color = new boolean[boardWidth][boardHeight];

        for(int a = 0; a < width; a++){
            for(int b = 0; b < height; b++){
                board[a][b] = new JButton();
            }
        }
        generateLights();
        while(isSolvable == false){
        generateLights();
        checkValidity();
        if(isSolvable == false){
                for(int c = 0; c < boardWidth; c++){
                    for(int d = 0; d < boardHeight; d++){
                        color[c][d] = false;
                    }
                }
            }
        }
        for(int a = 0; a < width; a++){
            for(int b = 0; b < height; b++){    
                board[a][b].addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        moves++;
                        for (int i = 0; i < width; i++) {
                            for (int j = 0; j < height; j++){
                                if(e.getSource()==board[i][j]){ //gameButtons[i][j] was clicked
                                    if(board[i][j].getBackground() == Color.BLUE){
                                        board[i][j].setBackground(Color.BLACK);
                                    }
                                    else{
                                        board[i][j].setBackground(Color.BLUE);
                                    }
                                    if(j > 0 && (board[i][j-1].getBackground() == Color.BLUE)){
                                        board[i][j-1].setBackground(Color.BLACK);
                                    }
                                    else if(j > 0){
                                        board[i][j-1].setBackground(Color.BLUE);
                                    }
                                    if(i > 0 && board[i-1][j].getBackground() == Color.BLUE){
                                        board[i-1][j].setBackground(Color.BLACK);
                                    }
                                    else if (i > 0){
                                        board[i-1][j].setBackground(Color.BLUE);
                                    }
                                    if(i < width-1 && board[i+1][j].getBackground() == Color.BLUE){
                                        board[i+1][j].setBackground(Color.BLACK);
                                    }
                                    else if(i < width-1){
                                        board[i+1][j].setBackground(Color.BLUE);
                                    }
                                    if(j < height-1 && board[i][j+1].getBackground() == Color.BLUE){
                                        board[i][j+1].setBackground(Color.BLACK);
                                    }
                                    else if(j < height-1){
                                        board[i][j+1].setBackground(Color.BLUE);
                                    }
                                    checkIfWon();
                                }
                            }
                        }
                    }
                });
            try {
                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
            } catch (Exception e) { } 
            frame.add(board[a][b]);
        }
    }

    frame.setTitle("Lights Out!");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setMinimumSize(new Dimension(250, 250));
    frame.pack();
    frame.setVisible(true);

}

public void checkIfWon(){
    int numBlack = 0;
    for(int i = 0; i < boardWidth; i++){
        for(int j = 0; j < boardHeight; j++){
            if(board[i][j].getBackground() == Color.BLACK){
                numBlack++;
            }
        }
    }
    if(numBlack == 25){
        JOptionPane.showMessageDialog(null, "Hooray! You Won!\nYou won in " + moves + " moves.");
        System.exit(0);
    }
}

public static void checkValidity(){     
    for(int j = 0; j < boardHeight - 1; j++){
        for(int i = 0; i < boardWidth; i++){
            if(color[i][j] == true){
                if(color[i][j] == true){
                    color[i][j] = false;
                }
                else{
                    color[i][j] = true;
                }
                if(j > 0 && color[i][j+1] == true){
                    color[i][j+1] = false;
                }
                else if(j > 0){
                    color[i][j+1] = true;
                }
                if(i > 0 && color[i-1][j+1] == true){
                    color[i-1][j+1] = false;
                }
                else if (i > 0){
                    color[i-1][j+1] = true;
                }
                if(i < boardWidth-1 && color[i+1][j+1] == true){
                    color[i+1][j+1] = false;
                }
                else if(i < boardWidth-1){
                    color[i+1][j+1] = true;
                }
                if(j < boardHeight-2 && color[i][j+2] == true){
                    color[i][j+2] = false;
                }
                else if(j < boardHeight-2){
                    color[i][j+2] = true;
                }
            }
        }
    }
    for(int c = 0; c < boardWidth; c++){
        if(color[4][c] == true){
            bottomRow += "1";
        }
        else{
            bottomRow += "0";
        }
    }
    if(bottomRow.equals("10001") || bottomRow.equals("01010") || bottomRow.equals("11100") || bottomRow.equals("00111") || bottomRow.equals("10110") || bottomRow.equals("01101") || bottomRow.equals("11011")){
        isSolvable = true;
    }
    else{
        isSolvable = false;
    }
}

public static void generateLights(){
    Random random = new Random();

    for(int a = 0; a < boardWidth; a++){
        for(int b = 0; b < boardHeight; b++){
            if(random.nextInt(99)+1 > 75){
                board[a][b].setBackground(Color.BLUE);
                color[a][b] = true;
            }else{
                board[a][b].setBackground(Color.BLACK);
                color[a][b] = false;
            }
        }
    }
}

    public static void main(String []args){
        new buildBoard(5, 5);
    }
}

checkValidity()方法是问题,并在此处发布(方法的其余部分在上面,以防万一):

public static void checkValidity(){     
    for(int j = 0; j < boardHeight - 1; j++){
        for(int i = 0; i < boardWidth; i++){
            if(color[i][j] == true){
                if(color[i][j] == true){
                    color[i][j] = false;
                }
                else{
                    color[i][j] = true;
                }
                if(j > 0 && color[i][j+1] == true){
                    color[i][j+1] = false;
                }
                else if(j > 0){
                    color[i][j+1] = true;
                }
                if(i > 0 && color[i-1][j+1] == true){
                    color[i-1][j+1] = false;
                }
                else if (i > 0){
                    color[i-1][j+1] = true;
                }
                if(i < boardWidth-1 && color[i+1][j+1] == true){
                    color[i+1][j+1] = false;
                }
                else if(i < boardWidth-1){
                    color[i+1][j+1] = true;
                }
                if(j < boardHeight-2 && color[i][j+2] == true){
                    color[i][j+2] = false;
                }
                else if(j < boardHeight-2){
                    color[i][j+2] = true;
                }
            }
        }
    }
    for(int c = 0; c < boardWidth; c++){
        if(color[4][c] == true){
            bottomRow += "1";
        }
        else{
            bottomRow += "0";
        }
    }
    if(bottomRow.equals("10001") || bottomRow.equals("01010") || bottomRow.equals("11100") || bottomRow.equals("00111") || bottomRow.equals("10110") || bottomRow.equals("01101") || bottomRow.equals("11011")){
        isSolvable = true;
    }
    else{
        isSolvable = false;
    }
}

public static void generateLights(){
    Random random = new Random();

    for(int a = 0; a < boardWidth; a++){
        for(int b = 0; b < boardHeight; b++){
            if(random.nextInt(99)+1 > 75){
                board[a][b].setBackground(Color.BLUE);
                color[a][b] = true;
            }else{
                board[a][b].setBackground(Color.BLACK);
                color[a][b] = false;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

问题确实在于您的有效性检查,特别是您的bottowRow 从不有效。

在第一次运行时,您生成一个无效的5个字符的字符串,然后您重新开始,但是您从不重置该字符串,而是继续追加它以使其不断增长。我修改了你的程序,输出它检查的每一个底行,这就是我得到的......

Checking bottom row: 00001
Checking bottom row: 0000100000
Checking bottom row: 000010000000000
Checking bottom row: 00001000000000000000
Checking bottom row: 0000100000000000000000000
Checking bottom row: 000010000000000000000000000000
Checking bottom row: 00001000000000000000000000000000001

重新生成电路板时,需要将数据结构重置为空。

作为一种风格,你过度使用类级别变量会损害你在这里调试的能力,你应该尽量保持你的数据在本地。例如,放弃使用静态并改为使用实例变量,让你的方法返回数据而不仅仅是设置它