-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.
  }
}

先感谢您!

编辑:我发现 print()、subgridsComplete()、columnsComplete()、rowsComplete() 和主要方法有问题……我假设它们都是类似的错误,但不知道在哪里我错了!

4

1 回答 1

-1

如果我复制并粘贴了你的数独类代码,你的问题就在第 341 行: int vall= scan.nextInt(); 尝试使用 IDE(调试为 -> Java 应用程序)在调试模式下查看您在做什么,在您想要停止应用程序的代码中放置断点

于 2013-09-30T15:24:10.367 回答