对于一个项目,我们必须编写一个程序来生成数独板并允许我们完成它。我已经编写了大部分项目的代码,我觉得从逻辑的角度来看我已经完成了它,但我找不到交互窗格中出现的编码错误。对错误的一点帮助将不胜感激
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() 和主要方法有问题……我假设它们都是类似的错误,但不知道在哪里我错了!