I am working on a Percolation java program. I have implemented the following Percolation.java file and am running into an error when testing it with certain input files, as described below.
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private int n;
private WeightedQuickUnionUF verify;
private WeightedQuickUnionUF solution;
private int sink;
private int source = 0;
private boolean[][] grid;
private int openSites = 0;
private int length;
// creates n-by-n grid, with all sites initially blocked
public Percolation(int n) {
if (n <= 0) {
throw new IllegalArgumentException();
}
this.length = n;
this.grid = new boolean[length][length];
this.sink = (length * length) + 1;
verify = new WeightedQuickUnionUF(length * length + 2);
solution = new WeightedQuickUnionUF(length * length + 2);
for (int i = 0; i < length; i++) {
verify.union(encode(0, i), source);
solution.union(encode(0, i), source);
}
for (int j = 0; j < length; j++) {
verify.union(encode(n - 1, j), sink);
}
}
// opens the site (row, col) if it is not open already
public void open(int row, int col) {
grid[row][col] = true;
openSites++;
if ((row - 1) >= 0 && isOpen(row - 1, col)) {
verify.union(encode(row, col), encode(row - 1, col));
solution.union(encode(row, col), encode(row - 1, col));
}
if ((row + 1) < length && isOpen(row + 1, col)) {
verify.union(encode(row, col), encode(row + 1, col));
solution.union(encode(row, col), encode(row + 1, col));
}
if ((col - 1) >= 0 && isOpen(row, col - 1)) {
verify.union(encode(row, col), encode(row, col - 1));
solution.union(encode(row, col), encode(row, col - 1));
}
if ((col + 1) < length && isOpen(row, col + 1)) {
verify.union(encode(row, col), encode(row, col + 1));
solution.union(encode(row, col), encode(row, col + 1));
}
}
// is the site (row, col) open?
public boolean isOpen(int row, int col) {
return grid[row][col];
}
// is the site (row, col) full?
public boolean isFull(int row, int col) {
return solution.find(source) == solution.find(encode(row, col));
}
// returns the number of open sites
public int numberOfOpenSites() {
return openSites;
}
// does the system percolate?
public boolean percolates() {
return verify.find(0) == verify.find(sink);
}
// An integer ID (1...n) for site (i, j).
private int encode(int row, int col) {
int number = length * row + 1 + col;
return number;
}
// unit testing (required)
public static void main(String[] args) {
String filename = args[0];
In in = new In(filename);
int n = in.readInt();
Percolation perc = new Percolation(n);
while (!in.isEmpty()) {
int i = in.readInt();
int j = in.readInt();
perc.open(i, j);
}
StdOut.println(perc.numberOfOpenSites() + " open sites");
if (perc.percolates()) {
StdOut.println("percolates");
}
else {
StdOut.println("does not percolate");
}
// Check if site (i, j) optionally specified on the command line
// is full.
if (args.length == 3) {
int i = Integer.parseInt(args[1]);
int j = Integer.parseInt(args[2]);
StdOut.println(perc.isFull(i, j));
}
}
}
However, when I test the code using certain input files, I receive error messages such as the following:
java.lang.ArrayIndexOutOfBoundsException: Index 8 out of bounds for length 8
Percolation.isOpen(Percolation.java:63)
TestPercolation.checkIsOpen(TestPercolation.java:122)
TestPercolation.checkIsOpen(TestPercolation.java:105)
TestPercolation.check(TestPercolation.java:177)
TestPercolation.checkFile(TestPercolation.java:198)
TestPercolation.test1(TestPercolation.java:659)
TestPercolation.main(TestPercolation.java:963)
java.lang.ArrayIndexOutOfBoundsException: Index 25 out of bounds for length 25
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
What in my code could be causing this? In other words, where is the issue and how can I fix it?
Related
I have a question about my homework in scratching my head-on.
So I need to build a program that counts the number of areas of true value (near to each other) in the 2D array.
{0,1,0,0}
{1,0,0,1}
{1,1,0,1}
{1,0,0,1}
So the program needs to return 3 because there 3 places with trues.
If there are no true then to return 0.
The program needs to recursive and without loops.
Thanks in advance to the ones that will help me solve this one. I didn't even have any idea how to start it.
Ok, you do a dfs to record the cells you went and you can have a boolean[][] to record the cells you went. Then you just loop through the grid to see where you have not gone. If you did not go there yet, go there and also perform a dfs on nearby cells, but anyway, a code would be more clear.
public static int[][] grid;
public static boolean[][] went;
public static int r, c;
public static void dfs(int x, int y) {
if (x < 0 || x >= r || y < 0 || y >= c) {//out of the grid
return;
}
if (went[x][y]) {//I went here
return;
}
went[x][y] = true;
if (grid[x][y] == 0) {//It's false here so don't go
return;
}
dfs(x - 1, y);
dfs(x + 1, y);
dfs(x, y - 1);
dfs(x, y + 1);
}
public static void main(String[] args) throws IOException {
BufferedReader input =
new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(input.readLine());
//input reading
r = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
grid = new int[r][c];
went = new boolean[r][c];
for (int i = 0; i < r; i++) {
st = new StringTokenizer(input.readLine());
for (int j = 0; j < c; j++) {
grid[i][j] = Integer.parseInt(st.nextToken());
}
}
//end of input reading
int cnt = 0;//number of areas
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
// If I have not went have and the value
// must be true so I would perform a dfs
// (since I only care about the value of 1s)
if (!went[i][j] && grid[i][j] == 1) {
cnt++;//add to our counter
dfs(i, j);//have not went here
}
}
}
System.out.println(cnt);
}
This solution uses the only recursion. No loops.
public static void main(String... args) {
System.out.println(countTrueAreas(new int[][] {
{ 0, 1, 0, 0 },
{ 1, 0, 0, 1 },
{ 1, 1, 0, 1 },
{ 1, 0, 0, 1 } })); // 3
}
public static int countTrueAreas(int[][] grid) {
return countTrueAreas(grid, 0, 0, 10) - 10;
}
private static int countTrueAreas(int[][] grid, int row, int col, int num) {
if (row == grid.length)
return num;
if (col == grid[row].length) {
if (++row == grid.length)
return num;
col = 0;
}
if (grid[row][col] == 1)
dfs(grid, row, col, num++);
return countTrueAreas(grid, row, col + 1, num);
}
private static void dfs(int[][] grid, int row, int col, int num) {
if (row < 0 || row >= grid.length)
return;
if (col < 0 || col >= grid[row].length)
return;
if (grid[row][col] != 1)
return;
grid[row][col] = num;
dfs(grid, row, col - 1, num);
dfs(grid, row, col + 1, num);
dfs(grid, row - 1, col, num);
dfs(grid, row + 1, col, num);
}
I wrote a program for the percolation problem for the Coursera Algorithms course. Everything seems to compile successfully, but when I run it in terminal, it just freezes and no output is shown. Is my performance just way too slow, or is there a bug somewhere in my code? Code is posted below, the arguments I use are n = 200 and 100 trials. Thank you so much in advance!
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private WeightedQuickUnionUF grid;
private WeightedQuickUnionUF grid2;
private boolean[] openSites;
private int numOpenSites, gridLength, topIndex, bottomIndex;
public Percolation(int n) {
// create n-by-n grid, with all sites blocked
if (n <= 0) {
throw new IllegalArgumentException();
}
int numNodes = (n * n) + 2;
grid = new WeightedQuickUnionUF(numNodes);
grid2 = new WeightedQuickUnionUF(numNodes);
openSites = new boolean[n * n];
numOpenSites = 0;
gridLength = n;
topIndex = n * n;
bottomIndex = n * n + 1;
}
public void open(int row, int col) { // open site (row, col) if it is not open already
//check if row and col are valid
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
//if not open, then open
if (!isOpen(row, col)) {
openSite(row, col);
connectTopVirtualSite(row, col);
connectAdjacentSites(row, col);
connectBottomVirtualSite(row, col);
numOpenSites++;
}
}
private void openSite(int row, int col) {
int index = convertToIndex(row, col);
//set that site to true
openSites[index] = true;
}
private void connectTopVirtualSite(int row, int col) {
if (row == 1) {
grid.union(topIndex, convertToIndex(row, col));
grid2.union(topIndex, convertToIndex(row, col));
}
}
private void connectAdjacentSites(int row, int col) {
connectTop(row, col);
connectLeft(row, col);
connectRight(row, col);
connectBottom(row, col);
}
private void connectTop(int row, int col) {
if (row > 1 && isOpen(row - 1, col)) {
grid.union(convertToIndex(row - 1, col), convertToIndex(row, col));
grid2.union(convertToIndex(row - 1, col), convertToIndex(row, col));
}
}
private void connectLeft(int row, int col) {
if (col > 1 && isOpen(row, col - 1)) {
grid.union(convertToIndex(row, col - 1), convertToIndex(row, col));
grid2.union(convertToIndex(row, col - 1), convertToIndex(row, col));
}
}
private void connectRight(int row, int col) {
if (col < gridLength && isOpen(row, col + 1)) {
grid.union(convertToIndex(row, col), convertToIndex(row, col + 1));
grid2.union(convertToIndex(row, col), convertToIndex(row, col + 1));
}
}
private void connectBottom(int row, int col) {
if (row < gridLength && isOpen(row + 1, col)) {
grid.union(convertToIndex(row, col), convertToIndex(row + 1, col));
grid2.union(convertToIndex(row, col), convertToIndex(row + 1, col));
}
}
private void connectBottomVirtualSite(int row, int col) {
if (row == gridLength) {
grid2.union(convertToIndex(row, col), bottomIndex);
}
}
private int convertToIndex(int row, int col) {
return gridLength * (row - 1) + (col - 1);
}
public boolean isOpen(int row, int col) { // is site (row, col) open?
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
return openSites[convertToIndex(row, col)];
}
public boolean isFull(int row, int col) { // is site (row, col) full?
if (row < 1 || row > gridLength || col < 1 || col > gridLength) {
throw new IndexOutOfBoundsException();
}
return grid.connected(convertToIndex(row, col), topIndex);
}
public int numberOfOpenSites() { // number of open sites
return numOpenSites;
}
public boolean percolates() { // does the system percolate?
return grid2.connected(topIndex, bottomIndex);
}
//public static void main(String[] args) // test client (optional)
}
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
import static java.lang.Math.sqrt;
public class PercolationStats {
private double[] results;
public PercolationStats(int n, int trials) {
if (n <= 0 || trials <= 0) {
throw new IllegalArgumentException();
}
results = new double[trials];
//fill up results with the p values of every trial
runExperiments(n, trials);
}
private void runExperiments(int n, int trials) {
int row, col;
for (int i = 0; i < trials; i++) {
Percolation test = new Percolation(n);
while (!test.percolates()) {
//generate new random row and col
row = StdRandom.uniform(n - 1) + 1;
col = StdRandom.uniform(n - 1) + 1;
test.open(row, col);
}
results[i] = (double)(test.numberOfOpenSites()) / (n * n);
}
}
public double mean() {
//return sample mean of all the p values
return StdStats.mean(results);
}
public double stddev() {
//return sample standard deviation of percolation threshold
return StdStats.stddev(results);
}
public double confidenceLo() {
return mean() - ((1.96 * stddev()) / sqrt(results.length));
}
public double confidenceHi() {
return mean() + ((1.96 * stddev()) / sqrt(results.length));
}
public static void main(String[] args) {
PercolationStats test = new PercolationStats(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
System.out.println("mean = " + test.mean());
System.out.println("stddev = " + test.stddev());
System.out.println("95% confidence interval = [" + test.confidenceLo() + ", " + test.confidenceHi() + "]");
}
}
I cannot get my write to file code working the error message- writeFile cannot be resolved. I a trying to write the board positions to a text file so the game can be saved. If the user chooses to save the game then it should call a new subroutine that will write the pieces to the file.
/*
* Skeleton program code for the AQA COMP1 Summer 2016 examination
* This code to be used in conjunction with the Preliminary Material
* written by the AQA Programmer Team
* Developed in the NetBeans 7.3.1. programming environment
* Additional classes AQAConsole2016, AQAReadTextFile2016 and
* AQAWriteTextFile2016 may be used.
*
* A package name may be chosen and private and public modifiers added -
* permission to make these changes to the Skeleton Program does not need
* to be obtained from AQA or the AQA Programmer
*/
import java.util.Random;
public class Aaa {
AQAConsole2016 console = new AQAConsole2016();
Random random = new Random();
int boardSize;
public Aaa() {
char choice;
String playerName;
// int boardSize;
boardSize = 6;
playerName = "";
do {
displayMenu();
choice = getMenuChoice(playerName);
switch (choice) {
case 'p' : playGame(playerName, boardSize);
break;
case 'e' : playerName = getPlayersName();
break;
case 'c' : boardSize = changeBoardSize();
break;
}
} while (choice != 'q');
}
void setUpGameBoard(char[][] board, int boardSize) {
for (int row = 1; row <= boardSize; row++) {
for (int column = 1; column <= boardSize; column++) {
if (row == (boardSize + 1) / 2 && column == (boardSize + 1) / 2 + 1 || column == (boardSize + 1) / 2 && row == (boardSize + 1) / 2 + 1) {
board[row][column] = 'C';
} else {
if (row == (boardSize + 1) / 2 + 1 && column == (boardSize + 1) / 2 + 1 || column == (boardSize + 1) / 2 && row == (boardSize + 1) / 2) {
board[row][column] = 'H';
} else {
board[row][column] = ' ';
}
}
}
}
}
int changeBoardSize() {
int boardSize;
do {
console.print("Enter a board size (between 4 and 9): ");
boardSize = console.readInteger("");
} while (!(boardSize >= 4 && boardSize <= 9));
return boardSize;
}
int getHumanPlayerMove(String playerName) {
int coordinates;
console.print(playerName + " enter the coordinates of the square where you want to place your piece: ");
coordinates = console.readInteger("");
return coordinates;
}
int getComputerPlayerMove(int boardSize) {
return ((random.nextInt(boardSize) + 1) * 10 + (random.nextInt(boardSize) + 1));
}
boolean gameOver(char[][] board, int boardSize) {
for (int row = 1; row <= boardSize; row++) {
for (int column = 1; column <= boardSize; column++) {
if (board[row][column] == ' ')
return false;
}
}
return true;
}
String getPlayersName() {
String playerName;
console.print("What is your name? ");
playerName = console.readLine();
return playerName;
}
boolean checkIfMoveIsValid(char[][] board, int move) {
int row;
int column;
boolean moveIsValid;
row = move % 10;
column = move / 10;
moveIsValid = false;
if (((row<=boardSize) &&(row>0)) && ((column<=boardSize) && (column>0))){
if (board[row][column] == ' ') {
moveIsValid = true;
}
}
return moveIsValid;
}
int getPlayerScore(char[][] board, int boardSize, char piece) {
int score;
score = 0;
for (int row = 1; row <= boardSize; row++) {
for (int column = 1; column <= boardSize; column++) {
if (board[row][column] == piece) {
score = score + 1;
}
}
}
return score;
}
boolean checkIfThereArePiecesToFlip(char[][] board, int boardSize, int startRow, int startColumn, int rowDirection, int columnDirection) {
int rowCount;
int columnCount;
boolean flipStillPossible;
boolean flipFound;
boolean opponentPieceFound;
rowCount = startRow + rowDirection;
columnCount = startColumn + columnDirection;
flipStillPossible = true;
flipFound = false;
opponentPieceFound = false;
while (rowCount <= boardSize && rowCount >= 1 && columnCount >= 1 && columnCount <= boardSize && flipStillPossible && !flipFound ) {
if (board[rowCount][columnCount] == ' ') {
flipStillPossible = false;
} else {
if (board[rowCount][columnCount] != board[startRow][startColumn]) {
opponentPieceFound = true;
} else {
if (board[rowCount][columnCount] == board[startRow][startColumn] && !opponentPieceFound) {
flipStillPossible = false;
} else {
flipFound = true;
}
}
}
rowCount = rowCount + rowDirection;
columnCount = columnCount + columnDirection;
}
return flipFound;
}
void flipOpponentPiecesInOneDirection(char[][] board, int boardSize, int startRow, int startColumn, int rowDirection, int columnDirection) {
int rowCount;
int columnCount;
boolean flipFound;
flipFound = checkIfThereArePiecesToFlip(board, boardSize, startRow, startColumn, rowDirection, columnDirection);
if (flipFound) {
rowCount = startRow + rowDirection;
columnCount = startColumn + columnDirection;
while (board[rowCount][columnCount] != ' ' && board[rowCount][columnCount] != board[startRow][startColumn]) {
if (board[rowCount][columnCount] == 'H') {
board[rowCount][columnCount] = 'C';
} else {
board[rowCount][columnCount] = 'H';
}
rowCount = rowCount + rowDirection;
columnCount = columnCount + columnDirection;
}
}
}
void makeMove(char[][] board, int boardSize, int move, boolean humanPlayersTurn) {
int row;
int column;
row = move % 10;
column = move / 10;
if (humanPlayersTurn) {
board[row][column] = 'H';
} else {
board[row][column] = 'C';
}
flipOpponentPiecesInOneDirection(board, boardSize, row, column, 1, 0);
flipOpponentPiecesInOneDirection(board, boardSize, row, column, -1, 0);
flipOpponentPiecesInOneDirection(board, boardSize, row, column, 0, 1);
flipOpponentPiecesInOneDirection(board, boardSize, row, column, 0, -1);
}
void printLine(int boardSize) {
console.print(" ");
for (int count = 1; count <= boardSize * 2 - 1; count++) {
console.print("_");
}
console.println();
}
void displayGameBoard(char[][] board, int boardSize) {
console.println();
console.print(" ");
for (int column = 1; column <= boardSize; column++)
{
console.print(" ");
console.print(column);
}
console.println();
printLine(boardSize);
for (int row = 1; row <= boardSize; row++) {
console.print(row);
console.print(" ");
for (int column = 1; column <= boardSize; column++) {
console.print("|");
console.print(board[row][column]);
}
console.println("|");
printLine(boardSize);
console.println();
}
}
void displayMenu() {
console.println("(p)lay game");
console.println("(e)nter name");
console.println("(c)hange board size");
console.println("(q)uit");
console.println();
}
char getMenuChoice(String playerName) {
char choice;
console.print(playerName + " enter the letter of your chosen option: ");
choice = console.readChar();
return choice;
}
void playGame(String playerName, int boardSize) {
char[][] board = new char[boardSize + 1][boardSize + 1];
boolean humanPlayersTurn;
int move;
int humanPlayerScore;
int computerPlayerScore;
boolean moveIsValid;
setUpGameBoard(board, boardSize);
humanPlayersTurn = false;
int NoOfMoves=0;
do {
humanPlayersTurn = !humanPlayersTurn;
displayGameBoard(board, boardSize);
moveIsValid = false;
do {
if (humanPlayersTurn) {
move = getHumanPlayerMove(playerName);
} else {
move = getComputerPlayerMove(boardSize);
}
moveIsValid = checkIfMoveIsValid(board, move);
} while (!moveIsValid);
if (!humanPlayersTurn) {
NoOfMoves++;
console.println("The number of moves completed so far: " +NoOfMoves);
console.print("Press the Enter key and the computer will make its move");
console.readLine("");
}
makeMove(board, boardSize, move, humanPlayersTurn);
console.println();
String answer = console.readLine("Do you want to save the board? (y/n)");
if (answer.equalsIgnoreCase("y")){
writeBoard(board, boardSize);
console.println("Saved!");
}
} while (!gameOver(board, boardSize));
displayGameBoard(board, boardSize);
humanPlayerScore = getPlayerScore(board, boardSize, 'H');
computerPlayerScore = getPlayerScore(board, boardSize, 'C');
if (humanPlayerScore > computerPlayerScore) {
console.println("Well done, " + playerName + ", you have won the game!");
}
else {
if (humanPlayerScore == computerPlayerScore) {
console.println("that was a draw!");
} else {
console.println("The computer has won the game!");
}
console.println();
}
}
void writeBoard(char[][] board, int boardSize) {
String filename = "myFile.txt";
String piece = null;
writeFile.openFile(filename);
for(int row=1; row<=boardSize; row++){
for (int column = 1; column <= boardSize; column++) {
piece= Character.toString(board [row][column]);
writeFile.writeToTextFile(piece);
}
}
writeFile.closeFile();
}
public static void main(String[] args) {
new Aaa();
}
}
This Section contains the errors:
void writeBoard(char[][] board, int boardSize) {
String filename = "myFile.txt";
String piece = null;
writeFile.openFile(filename);
for(int row=1; row<=boardSize; row++){
for (int column = 1; column <= boardSize; column++) {
piece= Character.toString(board [row][column]);
writeFile.writeToTextFile(piece);
}
}
writeFile.closeFile();
}
The problematic section contains a variable named writeFile which can not be resolved. No where in the class Aaa that you have shared, neither this variable has been declared nor initialized with an instance of its type. So the method void writeBoard(char[][] board, int boardSize) gives compilation error.
From the usage of this variable it is clear that it belongs to a class which has following instance methods:
1) openFile(String filename)
2) writeToTextFile(String piece)
3) closeFile()
Please search the class which has the above methods and on finding create an instance of that as the first statement inside the method void writeBoard(char[][] board, int boardSize). Hope it helps.
I am having some issues with the following code. First I cant seem to figure how to stop the piece from going out of bounds. Second when the code does work its not adding the count the steps correctly.
package runknightstour;
public class RunKnightsTour
{
public static void main(String[] args)
{
KnightMoves tour = new KnightMoves();
tour.runTour();
}
}
package runknightstour;
public class ChessBoard
{
public final int ROWS = 8;
public final int COLS = 8;
public final int FRAMESIZE = 12;
private int[][] board = new int[FRAMESIZE][FRAMESIZE];
public ChessBoard()
{
for (int y = 0; y < board.length; y++) {
for (int x = 0; x < board[y].length; x++) {
board[y][x] = -1;
}
for (int r = 2; r < ROWS + 2; r++) {
for (int c = 2; c < COLS + 2; c++) {
board[r][c] = 0;
}
}
}
}
public String toString()
{
String output = "";
for (int r = 0; r < FRAMESIZE; r++) {
for (int c = 0; c < FRAMESIZE; c++) {
output += board[r][c];
output += "\t";
}
output += "\n\n";
}
return output;
}
/**
*
* #param row
* #param col
* #param inStep in the range of 1 - 64
*/
public void setSquare(int row, int col, int inStep)
{
// adjust input to match 2 - 9
row += 1;
col +=1;
if (row > 1 && row < 10 && col > 1 && col < 10)
{
board[row][col] = inStep;
}
}
public int getSquare (int row, int col)
{
return board[row][col];
}
}
package runknightstour;
import java.util.Random;
import java.util.Scanner;
public class KnightMoves
{
public final int COMPLETE_TOUR = 64;
private ChessBoard kBoard = new ChessBoard();
private int[][] moves = new int[8][2];
private int stepNumber;
private int currentRow;
private int currentCol;
private int startRow;
private int startCol;
public KnightMoves()
{
moves[0][0] = -2; // move 0 row offset
moves[0][1] = 1; // move 0 col offset
moves[1][0] = -1; // move 1 row offset
moves[1][1] = 2; // move 1 col offset
moves[2][0] = 1; // move 2 row offset
moves[2][1] = 2; // move 2 col offset
moves[3][0] = 2; // move 3 row offset
moves[3][1] = 1; // move 3 col offset
moves[4][0] = 2; // move 4 row offset
moves[4][1] = -1; // move 4 col offset
moves[5][0] = 1; // move 5 row offset
moves[5][1] = -2; // move 5 col offset
moves[6][0] = -1; // move 6 row offset
moves[6][1] = -2; // move 6 col offset
moves[7][0] = -2; // move 7 row offset
moves[7][1] = -1; // move 7 col offset
stepNumber = 0;
startRow = startCol = 1;
currentRow = currentCol = 1;
}
/**
* Description: Get the starting board Position (row, col) for the
* KNIGHT from program user
*/
public void getStartPosition()
{
Scanner input = new Scanner(System.in);
System.out.print("\n enter a starting location for the knight's row ");
startRow = input.nextInt();
System.out.print("\n enter a starting location for the knight's col ");
startCol = input.nextInt();
kBoard.setSquare(startRow, startCol, 1);
System.out.println(kBoard);
}
/**
* Mutator: runTour()
*/
public void runTour()
{
getStartPosition();
// if stepNumber is equal to COMPLETE_TOUR
// report that the knight made a complete tour
do {
takeStep();
}
while (stepNumber < 64 && takeStep()== true);
System.out.println(kBoard);
System.out.println(toString());
}
private boolean takeStep()
{
boolean stepTaken = true;
int random1;
Random rand = new Random();
random1 = rand.nextInt(8);
int tryStepRow =0;
int tryStepCol=0;
int attempts =0;
do {
tryStepRow = currentRow + moves[random1][0];
tryStepCol = currentCol + moves[random1][1];
if(kBoard.getSquare(tryStepRow,tryStepCol)==0)
{
kBoard.setSquare(tryStepRow,tryStepCol, stepNumber++);
currentRow= tryStepRow;
currentCol = tryStepCol;
}
else
{
attempts++;
}
} while (stepTaken == false && attempts < 200);
return stepTaken;
}
public String toString()
{
String whatHappened = "";
whatHappened += "Starting location: [" + startRow + ", "
+ startCol + "]\n";
whatHappened += " Tour ended after " + stepNumber + " steps\n";
whatHappened += "The knight got stuck in location ["
+ (currentRow ) + ", " + (currentCol ) + "]\n";
return whatHappened;
}
}
Sample message I get.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at runknightstour.ChessBoard.getSquare(ChessBoard.java:68)
at runknightstour.KnightMoves.takeStep(KnightMoves.java:101)
at runknightstour.KnightMoves.runTour(KnightMoves.java:80)
at runknightstour.RunKnightsTour.main(RunKnightsTour.java:22)
I:\CSC122\RunKnightsTour\nbproject\build-impl.xml:1039: The following error occurred while executing this line:
I:\CSC122\RunKnightsTour\nbproject\build-impl.xml:804: Java returned: 1
BUILD FAILED (total time: 2 seconds)
If you carefully see the function setSquare() you'll notice that it is going into an infinite loop as there is no increment conditions given on row or col.
Also, if your board size is not big enough then you can end up getting ArraysOutOfBounds exception.
public void setSquare(int row, int col, int inStep)
{
// adjust input to match 2 - 9
row += 1;
col += 1;
if (row > 1 && row < 10 && col > 1 && col < 10)
{
/* Where are you incrementing row/col? */
board[row][col] = inStep;
}
}
I'm trying to create a strategy that will play against human or another strategy for the game Gomoku. I already have some kind of minimax function, although i don't quite understand how does it work and i also have a getscore function, which should send back the best score to minimax ? But the problem is that my getScore function does not recognize if there are 4 or 5 circles in a row/col/diagonally.
Here is my code:
public class JarmoStrategyV1 implements ComputerStrategy {
public static int Lrow = 0;
public static int Lcol = 0;
public static int Drow = 0;
public static int Dcol = 0;
public static final int E = 0;
public static final int X = 1; // black
public static final int O = -1; // white
public static final int WINSCORE = 100;
private static final int WINCOUNT = 5;
public Location getMove(SimpleBoard board, int player) {
// let's operate on 2-d array
int[][] b = board.getBoard();
System.out.println(getScore(b, player));
for (int row = 0; row < b.length; row++) {
for (int col = 0; col < b[0].length; col++) {
if (b[row][col] == SimpleBoard.EMPTY) {
// first empty location
return new Location(row, col);
}
}
}
return null;
}
#Override
public String getName() {
return "Student name";
}
public static int minimax(int[][] board, int player, int depth) {
if (getScore(board, player) == WINSCORE) {
//
return WINSCORE;
}
if (depth == 2) {
return getScore(board, player);
}
int max = Integer.MIN_VALUE;
if (player == -1){
max = Integer.MAX_VALUE;
}
System.out.println(max);
List<Location> possibleMoves = getPossibleMoves(board);
for (Location loc : possibleMoves) {
board[loc.getRow()][loc.getColumn()] = player;
int newplayer = 0 - player;
if(newplayer == 1){
int value = minimax(board, newplayer,depth + 1);
if(value < max) {
max = value;
}
}
if (newplayer == -1){
int value = minimax(board, newplayer, depth + 1);
if (value > max) {
max = value;
}
}
board[loc.getRow()][loc.getColumn()] = E;
}
return max;
}
public static int getScore(int[][] board, int muutuja) {
//int yks = 0;
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
if (board[row][col] == muutuja) {
if (row <= (board.length - 5)) {
if (col <= board.length && getCount(board, row, col, 0, 1, muutuja, WINCOUNT) >= (WINCOUNT - 1) && getCount(board, row, (col + 4), 0, 1, E, 1 ) >= 1) return 1; // - 4 in a row
if (row >= 1 && getCount(board, row, col, 1, 0, muutuja, WINCOUNT) >= (WINCOUNT -1) && getCount(board, (row - 1), col, 1, 0, E, 1) == 1) return 1;
if (getCount(board, row, col, 1, 0, muutuja, WINCOUNT) >= WINCOUNT) return 100; // | 5 in a row
if (col <= WINCOUNT && getCount(board, row, col, 1, 1, muutuja, WINCOUNT) >= WINCOUNT) return 100; // \
if (col >= WINCOUNT && getCount(board, row, col, 1, -1, muutuja, WINCOUNT) >= WINCOUNT) return 100; // /
}
if (col <= WINCOUNT && getCount(board, row, col, 0, 1, muutuja, WINCOUNT) >= WINCOUNT) return 100; // -
}
}
}
return 0;
}
public static int getCount(int[][] board, int row, int col, int rowd, int cold, int player, int test) {
int count = 0;
for (int i = 0; i < test; i++) {
if (board[row + i * rowd][col + i * cold] == player) count++;
else break;
}
return count;
}
public static ArrayList<Location> getPossibleMoves(int[][] board) {
ArrayList<Location> availableMoves = new ArrayList<Location>();
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
if (board[row][col] == E) {
availableMoves.add(new Location(row, col));
}
}
}
return availableMoves;
}
}
There seems to be some kind of a problem with getScore, when i run this code then i can only play for a while until my Gomoku app crashes.
If you want to try this out yourself then you can open this via Eclipse.
Download the project file: http://www68.zippyshare.com/v/feWl2QwC/file.html
Import it to eclipse projects/workspace.
And you also have to build path to those 2 jar files in lib folder.
NOTE: I can only edit files in gomoku.strategies package.
the stacktrace shows an exception. add debug print or run with debugger
java.lang.IllegalArgumentException: It's computer's turn, pass the player to makeMove()
at gomoku.Game.makeMove(Game.java:476)