2013-09-30 26 views
-1

对于一个项目,我们必须编写一个程序来生成一个数独板,并允许我们完成它。我编写了大部分项目,我觉得我从逻辑的角度来看它,但是我找不到出现在交互窗格中的编码错误。与错误有一点帮助,将不胜感激数独生成器交互面板错误

java.lang.ArrayIndexOutOfBoundsException: 0 
    at Sudoku.main(Sudoku.java:341) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272) 

这似乎当我点击运行

import java.util.Scanner; 
import java.io.File; 
import java.io.FileNotFoundException; 

public class Sudoku 
{ 
    // The dimension of the game grid 
    public static final int SIZE = 9; 

    // The dimension of a subgrid 
    public static final int SUBGRID = 3; 

    // The game grid 
    public int[][] game; 

    // The original game grid, unmodified by the player 
    public int[][] originalGame; 

    /** 
    * The Constructor. Reads from file puzzleFile, 
    * which contains a whitespace delimited 9x9 grid of 
    * ints whose values are either 1-9 or -1 (to denote 
    * an empty block, but store -1). Store the values in the 
    * internal game grids game and originalGame. 
    * 
    * Use .nextInt() to read the values in. This will read the 
    * files in the same order you read text in a book: top to bottom, 
    * left to right. 
    * 
    * @param puzzleFile: is the name of the file with the puzzle 
    **/ 
    public Sudoku(String puzzleFile) 
    { 
    // Don't worry about the try {} and catch {} blocks 
    // they are necessary for creating the Scanner on a File. 
    // Will be covered later. 
    try 
    { 
     int a; 
     game = new int[SIZE][SIZE]; 
     originalGame = new int[SIZE][SIZE]; 
     // Create a new array of dimensions SIZE x SIZE and assign it to game. 
     // Repeate for originalGame. 

     //The next two lines are magic 
     File file = new File(puzzleFile); 
     Scanner in = new Scanner(file); 
     for(int i = 0; i<SIZE; i++){ 
     for (int j = 0; j<SIZE; j++){ 
      a=in.nextInt(); 
      game[i][j] = a; 
      originalGame[i][j] = a; 
     } 
     } 

     // Write ONE nested loop (one loop inside another) to traverse both 
     // game and originalGame (outer loop: rows, inner loop: columns). 
     // Assign the value from the scanner to the correct game[i][j] and 
     // originalGame[i][j] 
    } 
    // See above, you do not need to understand this code yet. Will 
    // be covered later. 
    catch (FileNotFoundException e) 
    { 
     System.out.println("FileNotFound: " + e.getMessage()); 
    } 
    } 

    /** 
    * Sets each entry in array to 0. Returns void because arrays are 
    * passed by reference, so the changes are visible to anyone with a copy 
    * of array. 
    * 
    * @param array: the array to be modified 
    **/ 
    public void setZero(int[] array) 
    { 
    for(int i = 0; i<array.length; i++) 
     array[i]=0; 
    // Write a loop to traverse array and assign each entry 0. 
    } 

    /** 
    * This method determines whether the ints 1-9 are present exactly 
    * once in each row. Sets valSeen[i] = 1 if it sees i. If at any 
    * point valSeen[i] is already 1, the rows are not complete because of 
    * duplicate entries. 
    * 
    * If game[x][y] == -1, there is a blank entry so the row cannot be complete. 
    * 
    * @param valSeen: an array of ints that serve as flags to indicate whether 
    *     their entry has been seen before or not. 
    * 
    * returns: true if each digit 1-9 is present in the row exactly once, else false 
    **/ 
    public boolean rowsComplete(int[] valSeen) 
    { 
    int temp; 
    for(int rows = 0; rows<SIZE; rows++){ 
     for(int cols = 0; cols<SIZE; cols++){ 
     if(game[rows][cols]==-1) 
      return false; 
     temp= game[rows][cols]; 
     valSeen[temp-1]++; 
     } 
     for(int k=0; k<valSeen.length; k++){ 
     if(valSeen[k]!=1) 
      return false; 
     } 
     setZero(valSeen); 

    } 


    // Write the appropriate nested loops to check the rows. 
    // Remember to reset valSeen to 0 after each row. 

    return true; // Change this, placeholder so your code will compile 
    } 

    /** 
    * This method determines whether the ints 1-9 are present exactly 
    * once in each column. Sets valSeen[i] = 1 if it sees i. If at any 
    * point valSeen[i] is already 1, the rows are not complete because of 
    * duplicate entries. 
    * 
    * If game[x][y] == -1, there is a blank entry so the row cannot be complete. 
    * 
    * @param valSeen: an array of ints that serve as flags to indicate whether 
    *     their entry has been seen before or not. 
    * 
    * returns: true if each digit 1-9 is present in the column exactly once, else false 
    **/ 
    public boolean columnsComplete(int[] valSeen) 
    { 
    int temp; 
    for(int cols = 0; cols<SIZE; cols++){ 
     for(int rows = 0; rows<SIZE; rows++){ 
     if(game[rows][cols]==-1) 
      return false; 
     temp= game[rows][cols]; 
     valSeen[temp-1]++; 
     } 
     for(int k=0; k<valSeen.length; k++){ 
     if(valSeen[k]!=1) 
      return false; 
     } 
     setZero(valSeen); 



    } 
    // Write the appropriate nested loops to check the columns. 
    // Remember to reset valSeen to 0 after each column. 

    return true; // Change this, placeholder so your code will compile 
    } 
    /** 
    * This method determines whether the ints 1-9 are present exactly 
    * once in each subgrid. Sets valSeen[i] = 1 if it sees i. If at any 
    * point valSeen[i] is already 1, the rows are not complete because of 
    * duplicate entries. 
    * 
    * If game[x][y] == -1, there is a blank entry so the row cannot be complete. 
    * 
    * @param valSeen: an array of ints that serve as flags to indicate whether 
    *     their entry has been seen before or not. 
    * 
    * returns: true if each digit 1-9 is present in each subgrid exactly once, else false 
    **/ 
    public boolean subgridsComplete(int[] valSeen) 
    { 
    int temp; 
    for(int rows=0; rows<SIZE; rows+=3){ 
     for (int cols=0; cols<SIZE; cols+=3){ 
     for(int subrows=0; subrows<SUBGRID; subrows++){ 
      for (int subcols=0; subcols<SUBGRID; subcols++){ 
      temp= game[rows+subrows][cols+subcols]; 
      if(temp==-1) 
       return false; 
      else 
       valSeen[temp-1]++; 
      } 
     } 
     for(int k=0; k<valSeen.length; k++){ 
      if(valSeen[k]!=1) 
      return false; 
     } 
     setZero(valSeen); 
     } 
    } 









    // This will be four nested loops. The outer two will 
    // loop over the rows and columns of subgrids. The inner 
    // two will loop over the rows and columns in each 3x3 subgrid. 

    return true; // Change this, placeholder so your code will compile 
    } 

    /** 
    * Calls rowsComplete(), columnsComplete(), and subgridsComplete() 
    * and returns true if they are all true. 
    * 
    * returns: true if each row, column, and subgrid is complete, 
    *   else false 
    **/ 
    public boolean isComplete() 
    { 
    int[] placeholder = new int[SIZE]; 
    setZero(placeholder); 
    if(rowsComplete(placeholder) && columnsComplete(placeholder) && subgridsComplete(placeholder)) 
     return true; 
    else 
     return false; 
    // Create the array valSeen here. I suggest making it = new int[SIZE+1]. 
    // That way, it will have indexes 0-9, so the ints 1-9 can go into indexes 
    // 1-9 instead of mapping them to 0-8 by subtracting 1. 

    // Call rowsComplete(), columnsComplete(), and subgridsComplete(). 
    // Be SURE to initialize valSeen to 0 before each method call by using setZero(). 

    // Change this, placeholder so code will compile 
    } 

    /** 
    * This is a helper method for print(). It returns a string which contains 
    * the first line of the printed grid, " | a | b | c | d | e | f | g | h | i ". 
    * This is useful because the first line is unique in that it only has column 
    * headers, no row headers, so its string is different than the other rows 
    * which are created in the print() method. 
    * 
    * returns: a String containg the first row of the printed grid: 
    *   " | a | b | c | d | e | f | g | h | i " 
    **/ 
    public String makeHeader() 
    { 
    return " | a | b | c | d | e | f | g | h | i "; 
    // Create the initial string (will not be "", note that the first entry is blank). 

    // Use a loop to add each character in turn to the string, remembering that 'a' + 1 = 'b'. 

    // Change this, placeholder so code will compile 
    } 

    /** 
    * Prints out the grid. Each entry has a space to either side, columns are separated by '|' 
    * within the grid/between the header and the grid but not externally. See the specification 
    * for a detailed example. -1 is replaced with '_'. 
    * 
    * Remember that 'a' + 1 = 'b' 
    * 
    * Prints the grid to standard out. 
    **/ 
    public void print() 
    { 
    // Print the string returned by makeHeader(). 
    System.out.println(makeHeader()); 
    for(int rows=0; rows<SIZE; rows++){ 
     System.out.print(" "+(char)('a'+rows)); 
     for (int cols=0; cols<SIZE; cols++){ 
     if (game[rows][cols]==-1) 
      System.out.print(" | _"); 
     else 
      System.out.print(" | "+game[rows][cols]); 
     } 
     System.out.println(); 
    } 

    // Write a nested loop to print out each entry in the grid 
    // in the specified format. Remember that -1 is printed '_'. 
    } 

    /** 
    * Checks originalGrid row, col if it is equal to -1, the move is allowed. 
    * In which case, it update game row, col to val. Prints a message: 
    * "Fixed location. Cannot change value!" if row, col is a fixed value, 
    * ie 1-9 in originalGrid. 
    * 
    * You do not have to check for valid input, assume that row and col will 
    * be a-i, and val will be 1-9 
    * 
    * Hint: the String.charAt(x) method returns the characted at index x in 
    *  the string (strings are 0 indexed). 
    * Hint2: 'b' - 'a' = 1; 'a' - 'a' = 0 etc. 
    * 
    * @param row: a string with the row ID in it, ex: "a" 
    * @param col: a string with the col ID in it, ex: "b" 
    * @param val: the new value of row, col 
    * 
    * Does not return, simply updates game[][] if legal. 
    **/ 
    public void move(String row, String col, int val) 
    { 
    int rownum = ((int)(row.charAt(0)-97)); 
    int colnum = ((int)(col.charAt(0)-97)); 
    if(originalGame[rownum][colnum]==-1) 
     game[rownum][colnum]=val; 
    // Your code here. 
    } 

    /** 
    * The main method. Creates an object of class Sudoku, passing args[0] to the constructor. 
    * args[0] is the first commanline argument, in this case the name of a file containing a 
    * 9x9 grid of whitespaced delimited ints of values -1,1-9. 
    * 
    * Prints the existing puzzle, and a puzzle status, either "Puzzle Incomplete!" or 
    * "Puzzle Complete" based on whether or the puzzle is complete. 
    * 
    * While the puzzle is incomplete, it then prompts the user for input: "Enter new value <row col val> :" 
    * and reads in two strings using Scanner.next() and an int using Scanner.nextInt(). 
    * These must all be on the same line. It then makes the specified move and repeats. 
    * 
    * @param String[] args: the command line argument, the name of a file containing a puzzle in the 
    *      specified format. 
    * Doesn't return 
    **/ 
    public static void main(String[] args) 
    { 
    System.out.println(""); 
    Scanner scan = new Scanner(System.in); 
    Sudoku s = new Sudoku(args[0]); 
    boolean playing=true; 
    while (playing){ 
     s.print(); 
     if(s.isComplete()){ 
     System.out.println("puzzle complete!"); 
     playing=false; 
     } else { 
     System.out.println("puzzle incomplete!"); 
     System.out.println("Enter new value <row col val> :"); 
     String roww = scan.nextLine(); 
     String coll = scan.nextLine(); 
     int vall= scan.nextInt(); 
     s.move(roww, coll, vall); 
     } 
    } 

    // Create an object of class Sudoku, giving it args[0] as an argument. You will also need a 
    // Scanner and some other variables. 

    // replace null with an instantiation of Sudoku (e.g. new Sudoku(...)) 

    // Print the puzzle, then create a loop prompting for moves while the puzzle is incomplete. 
    } 
} 

预先感谢您! (),subgridsComplete(),columnsComplete(),rowsComplete()和主要方法...我假设他们都是类似的错误,但是,不知道我出错的地方!

+3

您是否传入任何参数? – Reimeus

回答

-1

如果我有复制&粘贴完全你的Sudoku类的代码你的问题是在行341: int vall = scan.nextInt(); 尝试使用您的IDE在调试模式下执行什么操作(调试为 - > Java应用程序) 在要停止应用程序的代码中添加断点

+1

因为'nextInt'什么时候抛出'ArrayIndexOutOfBoundsException'? – Dukeling