我的Java程序只循环一次

时间:2015-12-06 21:59:19

标签: java android debugging

我一直在研究这个程序大约一天,我无法弄清楚它为什么不起作用我只能发现程序中检查代码是否已被使用的部分不起作用完美。

该程序的目标是选择随机数,直到它与您输入的代码相匹配。它模拟Android手机上的模式锁定,所以为了让我更高效,我添加了一个数组列表来跟踪它所做的所有猜测,以便它不会重复。

我的代码

import java.util.*;
public class CrackerMain {
public static void main(String[] args) {

    //Instances
    Scanner scan=new Scanner(System.in);
    Random gen=new Random();
    //Variables
    long endTime=0;
    long startTime=0;
    boolean solved=false;
    boolean newnumb=false;
    int ran=0;
    int correct=0;
    boolean running=true;
    int dots;
    int codex;
    int codey;
    int zero;
    int x;
    int y;
    ArrayList<int[][]>  UsedCodes = new ArrayList<int[][]>();
    int[][] code={{0,0,0},
                  {0,0,0},
                  {0,0,0}};
    int[][] guess={{0,0,0},
                   {0,0,0},
                   {0,0,0}};
    UsedCodes.add(guess);
    //Program

    //Enter Code
    System.out.println("Enter a Code to Crack: ");
    System.out.println("1 for 1st etc. 0 for Not Used");
    System.out.println("y x0  1  2");
    System.out.println("0 {x}{x}{x}");
    System.out.println("1 {x}{x}{x}");
    System.out.println("2 {x}{x}{x}");
    System.out.println("Enter Number for 0,0");
    code[0][0]=scan.nextInt();
    System.out.println("Enter Number for 0,1");
    code[0][1]=scan.nextInt();
    System.out.println("Enter Number for 0,2");
    code[0][2]=scan.nextInt();
    System.out.println("Enter Number for 1,0");
    code[1][0]=scan.nextInt();
    System.out.println("Enter Number for 1,1");
    code[1][1]=scan.nextInt();
    System.out.println("Enter Number for 1,2");
    code[1][2]=scan.nextInt();
    System.out.println("Enter Number for 2,0");
    code[2][0]=scan.nextInt();
    System.out.println("Enter Number for 2,1");
    code[2][1]=scan.nextInt();
    System.out.println("Enter Number for 2,2");
    code[2][2]=scan.nextInt();

    System.out.println("Entered");
    System.out.println("{"+code[0][0]+"}{"+code[0][1]+"}{"+code[0][2]+"}");
    System.out.println("{"+code[1][0]+"}{"+code[1][1]+"}{"+code[1][2]+"}");
    System.out.println("{"+code[2][0]+"}{"+code[2][1]+"}{"+code[2][2]+"}");
    //guessing
    startTime = System.nanoTime();
    while(solved==false){
        correct=0;
        newnumb=false;
        while(newnumb==false){
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=1;
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=2;
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=3;
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=4;
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=5;
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=6;
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=7;
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=8;
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=9;
            //Enter Zeros Randomly
            zero=gen.nextInt(100);
            if(zero==0){
                x=gen.nextInt(3);
                y=gen.nextInt(3);
                guess[x][y]=0;  
            }
            zero=gen.nextInt(100);
            if(zero==0){
                x=gen.nextInt(3);
                y=gen.nextInt(3);
                guess[x][y]=0;  
            }
        zero=gen.nextInt(100);
        if(zero==0){
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=0;  
        }
        zero=gen.nextInt(100);
        if(zero==0){
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=0;  
        }
        zero=gen.nextInt(100);
        if(zero==0){
            x=gen.nextInt(3);
            y=gen.nextInt(3);
            guess[x][y]=0;  
        }

        //Check if New
        for(int i=0; i>ran; i++){
            if(guess!=UsedCodes.get(i)){
                correct++;
            }
        }

        if(correct==ran){
            newnumb=true;
            ran++;  
        }
    }
    //Add Guess to ArrayList
    UsedCodes.add(guess);
    //Say What Guessed
    System.out.println(" ");
    System.out.println("{"+guess[0][0]+"}{"+guess[0][1]+"}{"+guess[0][2]+"}");
    System.out.println("{"+guess[1][0]+"}{"+guess[1][1]+"}{"+guess[1][2]+"}");
    System.out.println("{"+guess[2][0]+"}{"+guess[2][1]+"}{"+guess[2][2]+"}");

    //Check if Worked
    if(code[0][0]==guess[0][0]&&code[0][1]==guess[0][1]&&code[0][2]==guess[0][2]&&code[1][0]==guess[1][0]&&code[1][1]==guess[1][1]&&code[1][2]==guess[1][2]&&code[2][0]==guess[2][0]&&code[2][1]==guess[2][1]&&code[2][2]==guess[2][2]){
        solved=true;
        endTime = System.nanoTime();
        ran++;
    }
    else{
        guess[0][0]=0;
        guess[0][1]=0;
        guess[0][2]=0;
        guess[1][0]=0;
        guess[1][1]=0;
        guess[1][2]=0;
        guess[2][0]=0;
        guess[2][1]=0;
        guess[2][2]=0;
    }

}   
System.out.println("Solution");
System.out.println("{"+guess[0][0]+"}{"+guess[0][1]+"}{"+guess[0][2]+"}");
System.out.println("{"+guess[1][0]+"}{"+guess[1][1]+"}{"+guess[1][2]+"}");
System.out.println("{"+guess[2][0]+"}{"+guess[2][1]+"}{"+guess[2][2]+"}");
System.out.println("Broke Your Passcode in: "+((endTime - startTime)/1000000000) + " seconds"); 

} }

谢谢!

2 个答案:

答案 0 :(得分:0)

为什么随意? 它永远找不到秘密模式。你想要做的是尝试所有可能的组合(暴力方法)。

有两种情况:

  • 如果模式具有固定的已知长度,例如4,则可以在我们的示例4中对一些嵌套的for循环进行硬编码。
  • 否则你需要一个递归方法:你选择一个单元格,将它从“可拾取”单元格中删除,将它存放在某处,然后重复该过程。当没有任何东西可供选择或你选择了你想要的单元格数量时,你会测试这是否是你的秘密模式,在这种情况下你将它返回。

在下面的(草率编写)代码中,我用一个数字列表(从1到9(不需要矩阵))为屏幕锁定板建模。秘密模式也是一个只选择了一些单元格的列表,顺序很重要。方法print()打印板并放置.,如果单元格不在秘密模式中,否则它以秘密模式输出单元格的位置。

例如,我按此顺序选择秘密4 5 1 9。输出将是:

3..
12.
..4

因为电路板表示为

123
456
789

代码如下:

import java.util.*;

public class Cracker {
    static List<Integer> secret = new ArrayList<Integer>() {{
        add(4); add(5); add(1); add(9);
    }};

    static final int MIN_DIGITS = 1;
    static final int MAX_DIGITS = 9;

    static List<Integer> crack(List<Integer> left, List<Integer> choosen, 
            int depth) {
        if (left.isEmpty() || depth == 0) {
            return choosen.equals(secret) ? choosen : null;
        }
        for (int i = 0; i < left.size(); i++) {
            int choice = left.get(i);
            left.remove(i);
            choosen.add(choice);
            List<Integer> res = crack(left, choosen, depth - 1);
            left.add(i, choice);
            if (res != null) return res;
            choosen.remove(choosen.size() - 1);
        }
        return null;
    }

    public static List<Integer> crack() {
        for (int i = MIN_DIGITS; i <= MAX_DIGITS; i++) {
            List<Integer> left = new ArrayList<Integer>() {{
                add(1); add(2); add(3);
                add(4); add(5); add(6);
                add(7); add(8); add(9);
            }};
            List<Integer> choosen = new ArrayList<Integer>();
            List<Integer> res = crack(left, choosen, i);
            if (res != null) return res;
        }
        return null;
    }

    public static void print(List<Integer> board) {
        for (int i = 1; i < 10; i++) {
            System.out.print(board.contains(i) ? board.indexOf(i) + 1 : ".");
            if (i % 3 == 0) System.out.println();
        }
    }

    public static void main(String[] args) {
        print(secret);
        System.out.println();
        print(crack()); // should be the same!
    }
}

答案 1 :(得分:0)

  

我的Java程序只能循环一次

这是因为在猜测循环k-danger does not have any style in kendo css, 的第二次迭代中,内循环while(solved==false){是无限循环,因为:

  • 小错字 - 而不是

    while(newnumb==false){

    你的意思

            for(int i=0; i>ran; i++){
    
  • 主要错误 - 变量 for (int i=0; i<ran; i++)… 只是数组的引用,所以声明

    guess

    不会将猜测的副本添加到 //Add Guess to ArrayList UsedCodes.add(guess); ,而只会将参考的副本添加,因此对原始UsedCodes的后续更改会明显改变{{1}所引用的值

    中的更多内容
    guess

    比较总是产生UsedCodes,因为 //Check if New for(int i=0; i… if(guess!=UsedCodes.get(i)){ false是相同的引用。要纠正这些问题,请在循环的每个循环开始时分配guess猜测

    UsedCodes.get(i)

    并比较数组值:

    new