reading 2D array text file java - java

I am trying to develop a GUI-based program to read the entries of a matrix from a text file. The first number is the number of rows; the second number is the number of columns. The remaining numbers are integers between 1 and 9 in row by row order. Scan the matrix, highlight (display the entries in different color) all cells that form a group of five cells with the same value horizontally, vertically or diagonally.
My program below is NOT reading the file correctly I don't think because every time I click Process in my menu I get in return a matrix of 0's. PLEASE HELP.
CLASS:
// GUI-related imports
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Scanner;
// File-related imports
import java.io.FileReader; // both needed
import java.io.BufferedReader; // for line input
import java.io.IOException;
public class FiveInARow
{
byte[][] tag = new byte[100][100];
int[][] matrix = new int[100][100];
int row;
int col;
String filePath, fileName;
// Constructor
public FiveInARow()
{
row = 0;
col = 0;
}
public void ReadFile()
{
// Initialize TAG(s) to 0
for(int i =0; i< tag.length; i++)
for(int j =0; i< tag.length; j++)
tag[i][j] = 0;
//Place open dialogue here
String filePath = null;
String fileName = null;
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
chooser.setDialogTitle("Open Data File");
int returnVal = chooser.showOpenDialog(null);
if( returnVal == JFileChooser.APPROVE_OPTION)
{
filePath = chooser.getSelectedFile().getPath();
fileName = chooser.getSelectedFile().getName();
}
// Define & Instantiate File
Scanner inputStream = new Scanner(filePath);
row = inputStream.nextInt();
col = inputStream.nextInt();
for(int i =0; i< row; i++) // rows
{
for(int j = 0; j < col; j++) //columns
{
matrix[i][j] = inputStream.nextInt();
}
}
} // End of ReadFile method
public void Process()
{
// Go through the matrix
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
// Checking the matrix horizantally
if(j <= col-5) // Checks the boundaries of horizantal elements
if (matrix[i][j] == matrix[i][j+1]
&&(matrix[i][j+1] == matrix[i][j+2])
&&(matrix[i][j+2] == matrix[i][j+3])
&&(matrix[i][j+3] == matrix[i][j+4]))
tag[i][j] = 1;
// Checking the matrix vertically
if(i <= row-5) // Checks the boundaries of vertical elements
if (matrix[i][j] == matrix[i+1][j]
&&(matrix[i+1][j] == matrix[i+2][j])
&&(matrix[i+2][j] == matrix[i+3][j])
&&(matrix[i+3][j] == matrix[i+4][j]))
tag[i][j] = 2;
// Checking the matrix's right diagnol CHANGEEEEE
if (matrix[i][j] == matrix[i+1][j]
&&(matrix[i+1][j] == matrix[i+2][j])
&&(matrix[i+2][j] == matrix[i+3][j])
&&(matrix[i+3][j] == matrix[i+4][j]))
tag[i][j] = 3;
// Checking the matrix's left diagnol CHANGEEE
if (matrix[i][j] == matrix[i+1][j]
&&(matrix[i+1][j] == matrix[i+2][j])
&&(matrix[i+2][j] == matrix[i+3][j])
&&(matrix[i+3][j] == matrix[i+4][j]))
tag[i][j] = 4;
}
}
} // End of Process method
}
DRIVER:
// GUI-related imports
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Scanner;
// File-related imports
import java.io.FileReader; // both needed
import java.io.IOException;
public class Project3Main extends Frame implements ActionListener
{
// File Parameters
FiveInARow f = new FiveInARow();
String dataFilePath = null;
String dataFileName = null;
int[][] Data = new int[100][100];
int[][] Tag = new int [100][100];
int row = 0;
int column = 0;
// Retrieved command code
String command = "";
public static void main(String[] args)
{
Frame frame = new Project3Main();
frame.setResizable(true);
frame.setSize(1000,700);
frame.setVisible(true);
}
public Project3Main()
{
setTitle("2D Arrays");
// Create Menu Bar
MenuBar mb = new MenuBar();
setMenuBar(mb);
// Create Menu Group Labeled "File"
Menu fileMenu = new Menu("File");
// Add it to Menu Bar
mb.add(fileMenu);
// Create Menu Items
// Add action Listener
// Add to "File" Menu Group
MenuItem miReadData = new MenuItem("Read Data");
miReadData.addActionListener(this);
fileMenu.add(miReadData);
MenuItem miProcess = new MenuItem("Process");
miProcess.addActionListener(this);
fileMenu.add(miProcess);
MenuItem miExit = new MenuItem("Exit");
miExit.addActionListener(this);
fileMenu.add(miExit);
// End program when window is closed
WindowListener l = new WindowAdapter()
{
public void windowClosing(WindowEvent ev)
{
System.exit(0);
}
public void windowActivated(WindowEvent ev)
{
repaint();
}
public void windowStateChanged(WindowEvent ev)
{
repaint();
}
};
ComponentListener k = new ComponentAdapter()
{
public void componentResized(ComponentEvent e)
{
repaint();
}
};
// register listeners
this.addWindowListener(l);
this.addComponentListener(k);
}
//******************************************************************************
// called by windows manager whenever the application window performs an action
// (select a menu item, close, resize, ....
//******************************************************************************
public void actionPerformed (ActionEvent ev)
{
// figure out which command was issued
command = ev.getActionCommand();
// take action accordingly
if("Read Data".equals(command))
{
///////////////////////////////////////////////////////////////// call readfile method in your class to do this
f.ReadFile();
dataFilePath = null;
dataFileName = null;
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
chooser.setDialogTitle("Open Data File");
int returnVal = chooser.showOpenDialog(null);
if( returnVal == JFileChooser.APPROVE_OPTION)
{
dataFilePath = chooser.getSelectedFile().getPath();
dataFileName = chooser.getSelectedFile().getName();
}
try
{
/*
* Scan the file and place it's contents into an array of Integers.
*/
Scanner inputStream = new Scanner(new FileReader(dataFilePath));
int intLine;
row = inputStream.nextInt();
column = inputStream.nextInt();
for (int i=0; i < row; i++)
{
for (int j = 0 ; j < column; j++)
{
intLine = inputStream.nextInt();
}
}
}
catch(IOException ioe)
{
System.exit(0);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
repaint();
}
else
if("Process".equals(command))
{
// call process method in your class
f.Process();
// determine if cells form a 5-cell same-valued block, mark them true in Tags array
repaint();
}
else
if("Exit".equals(command))
{
System.exit(0);
}
}
//********************************************************
// called by repaint() to redraw the screen
//********************************************************
public void paint(Graphics g)
{
int ww = (int)this.getWidth();
int wh = (int)this.getHeight() -40;
if("Read Data".equals(command))
{
// Acknowledge that file was opened
if (dataFileName != null)
{
g.drawString("File -- "+dataFileName+" -- was successfully opened", ww/2-150, wh/2);
}
else
{
g.drawString("NO File is Open", 400, 400);
}
return;
}
else
if("Process".equals(command))
{
// Display the results
int x = (ww-column*20)/2;
int y = (wh-row*20)/2;
for (int i=0; i<row; i++)
{
for (int j=0; j<column; j++)
{
g.setColor(Color.BLACK);
if (Tag[i][j] == 1)
g.setColor(Color.RED);
//******* set color for the other directions
g.drawString( ((Integer)Data[i][j]).toString(), x, y);
x=x+20;
}
x = (ww-column*20)/2;
y=y+20;
}
return;
}
}
}

The problem is this line:
Scanner inputStream = new Scanner(filePath);
filePath is a String. Scanner accepts a String in its constructor, but then it treats the String as the source. It'll never load the file.
You need to pass it an InputStream or a File or something else as you do in the Driver.

Your file chooser will give you a file you can use directly with your scanner:
File chosenFile = null;
int returnVal = chooser.showOpenDialog(null);
if( returnVal == JFileChooser.APPROVE_OPTION)
{
chosenFile = chooser.getSelectedFile();
}
Scanner inputStream;
// Define & Instantiate File
if (chosenFile != null) {
inputStream = new Scanner(chosenFile);
}
else {
// handle appropriately
}

Change your use of the scanner to be like this:
Scanner inputStream = = new Scanner(new File("filename"));;
String line = scanner.nextLine();
String[] numbers = line.split(" ");
for(String str : numbers){
int nunber = Interger.parseInt(str);
}
This will read one line of the file at a time, split it on spaces (getting the numbers by themselves) then changing them from a string to a int. I think its getting strings and thus nextInt() has no values and picks up the default.

Related

How to keep BestScores in a File JAVA

I developed a game and I want to keep track of the Top-3 Best Scores in a file, so that we don't lose the Scores after closing the game. It's not working properly and I don't know why.
- The Best Scores are Integers, and the lowest it is the better. The Best Score is the lowest.
- It is not saving the Scores in ascending Order
It does create a file and it appears to work with the main tests but after a few Scores being add, it does not sort the array in ascending order, so the file is in the wrong way.
package pt.iscte.dcti.poo.sokoban.starter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
import pt.iul.ista.poo.utils.Point2D;
public class BestScores {
public int[] bestScore = new int[3];
public final int level;
public BestScores(int level) {
this.level = level;
}
public int[] getBestScore() {
return bestScore;
}
//Register BestScores
public void setBestScore(int score) {
for(int i = 0; i < bestScore.length; i++) {
if(bestScore[i] == 0) {
bestScore[i] = score;
return;
}
}
Arrays.sort(bestScore);
for (int i = 0; i < bestScore.length-1; i++) {
if(bestScore[i] == 0) {
int box1 = bestScore[i];
bestScore[i] = bestScore[i+1];
bestScore[i+1] = box1;
}
}
addBestScore(score);
}
public void addBestScore(int score) {
if(score < bestScore[bestScore.length - 1])
bestScore[bestScore.length - 1] = score;
Arrays.sort(bestScore);
for (int i = 0; i < bestScore.length-1; i++) {
if(bestScore[i] == 0) {
int box1 = bestScore[i];
bestScore[i] = bestScore[i+1];
bestScore[i+1] = box1;
}
}
}
public int getTopOne() {
return bestScore[0];
}
public int getLevel() {
return level;
}
//Check if the file exists, else create it
public void searchFile() {
File tmpDir = new File("bestScores/BestScore_" + level + ".txt");
if (!tmpDir.exists())
createOrAddScore();
else {
checkScores(tmpDir);
createOrAddScore();
}
}
//Create file with Scores if they exist.
public void createOrAddScore() {
try {
PrintWriter writer = new PrintWriter(new File("bestScores/BestScore_" + level + ".txt"));
writer.println("BestScores: ************Level:" + level + "************");
for(int i = 0; i < bestScore.length; i++) {
if(bestScore[i] != 0)
writer.println((i+1) + "ยบ " + bestScore[i] + " " + "moves.");
}
writer.close();
}
catch (FileNotFoundException e) {
System.err.println("problema a escrever o ficheiro");
}
}
//Read File and return Best Scores, so that we don't lose the bestScores even after closing the game :D.
public void checkScores(File file) {
int[] array = new int[3];
try {
Scanner scanner = new Scanner(file);
String title_line = scanner.nextLine();
int i = 0;
while(scanner.hasNextLine()) {
String[] line = scanner.nextLine().split(" ");
array[i] = Integer.parseInt(line[1]);
i++;
}
}
catch (FileNotFoundException e) {
System.err.println("problema a escrever o ficheiro");
}
for (int i = 0; i < array.length; i++)
if(array[i] != 0)
setBestScore(array[i]);
}
public static void main(String[] args) {
// BestScores bS = new BestScores(4);
//test1 No BEstScores
// bS.searchFile();
//test2 WithBestScores
// bS.setBestScore(40);
// bS.setBestScore(15);
bS.setBestScore(50);
// bS.setBestScore(30);
// bS.setBestScore(10);
// bS.searchFile();
// int[] test = bS.getBestScore();
// for(int i = 0; i < test.length; i++)
// System.out.println(test[i]);
//test3 With file with Scores
// bS.searchFile();
// int[] test = bS.getBestScore();
// for(int i = 0; i < test.length; i++)
// System.out.println(test[i]);
}
}

Memory game does not call compare function correctly

I have coded a simple memory game. Card values are added to two arrays and after that, a compare function is called. But there is a problem with the logic of the compare function.
The specific problem seems related to the fact that the compare function is called on the third button click. So on first click it adds first value to first array , on second click second value to second array. But I must click for yet a third time to call the compare function to compare the match of two arrays.
The main problem is that after all cards are inverted (10 matches in 5x4 memory game), it does not show the result.
I have uploaded full code here : http://uloz.to/xcsJkYUK/memory-game-rar .
public class PEXESO5x4 extends JFrame implements ActionListener {
private JButton[] aHracieTlactika = new JButton[20];
private ArrayList<Integer> aHodnoty = new ArrayList<Integer>();
private int aPocitadlo = 1;
private int[] aTlacitkoIden = new int[2];
private int[] aHodnotaTlac = new int[2];
private JButton aTlacitkoExit;
private JButton aTlacitkoReplay;
private JButton[] aHracieTlacitko = new JButton[20];
private int aPocetTahov = 0;
public void vkladanieHodnot() {
for (int i = 0; i < 2; i++) {
for (int j = 1; j < (this.aHracieTlactika.length / 2) + 1; j++) {
this.aHodnoty.add(j);
}
}
Collections.shuffle(this.aHodnoty);
}
public boolean zhoda() {
if (this.aHodnotaTlac[0] == this.aHodnotaTlac[1]) {
return true;
}
return false;
}
public void zapisCislaDoSuboru() {
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Semestralka.txt", true)))) {
out.println("haha");
//more code
out.println("hahahahha");
//more code
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
}
public void actionPerformed(ActionEvent e) {
int match = 0;
if (this.aTlacitkoExit == e.getSource()) {
System.exit(0);
}
if (this.aTlacitkoReplay == e.getSource()) {
}
for (int i = 0; i < this.aHracieTlactika.length; i++) {
if (this.aHracieTlactika[i] == e.getSource()) {
this.aHracieTlactika[i].setText("" + this.aHodnoty.get(i));
this.aHracieTlactika[i].setEnabled(false);
this.aPocitadlo++;
this.aPocetTahov += 1;
if (this.aPocitadlo == 3) {
if (this.zhoda()) {
match+=1;
if (match==10)
{
System.out.println("You win");
}
this.aHracieTlactika[this.aTlacitkoIden[0]].setEnabled(false);
this.aHracieTlactika[this.aTlacitkoIden[1]].setEnabled(false);
} else {
this.aHracieTlactika[this.aTlacitkoIden[0]].setEnabled(true);
this.aHracieTlactika[this.aTlacitkoIden[0]].setText("");
this.aHracieTlactika[this.aTlacitkoIden[1]].setEnabled(true);
this.aHracieTlactika[this.aTlacitkoIden[1]].setText("");
}
this.aPocitadlo = 1;
}
if (this.aPocitadlo == 1) {
this.aTlacitkoIden[0] = i;
this.aHodnotaTlac[0] = this.aHodnoty.get(i);
}
if (this.aPocitadlo == 2) {
this.aTlacitkoIden[1] = i;
this.aHodnotaTlac[1] = this.aHodnoty.get(i);
}
}
}
}
}

Analysing word frequencies in applet

i am writing a program in applet to measure the frequencies of word lengths in a given amount of text and display these frequencies during applet. i have written the program and it debugs without error.
however the output says i have 255 words of every length in the text i input, i have been staring at this for hours with no luck, i am aware that the drawstring method lists these outputs horizontally which i will be fixing at a later time.
i am assuming the problem resides in the analyseText method.
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.awt.Graphics;
import java.util.*;
public class StringAnalysis extends Applet implements MouseListener, ActionListener {
Font arielBold;
Label pr_Label;
TextField pr_txt;
int textFieldSize = 15;
Button pr_input1, pr_input2, pr_input3;
String textToAnalyse = ("Nothing has been entered.");
boolean output = false;
String testing ="";
//create array to show respective lengths of words
int [] lengthsOfWords = new int[textFieldSize];
//first we must separate strings from spaces and populate array for comparison
String [] arrayOfWords = new String[textFieldSize];
public void init() {
pr_Label = new Label("Enter the text you wish to analise: ");
add(pr_Label);
pr_txt = new TextField(textFieldSize);
add(pr_txt);
pr_input1 = new Button("Analyse");
pr_input2 = new Button("Reset");
add(pr_input1);
add(pr_input2);
pr_input1.addActionListener(this);
pr_input2.addActionListener(this);
}
public void start (){
setSize(1000, 500);
arielBold = new Font ("Ariel", Font.BOLD, 20);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == pr_input2) {
showStatus("Resseting....");
reset();
}
else if (e.getSource() == pr_input1){
showStatus("Analysing...a");
textToAnalyse = pr_txt.getText();
analyseText(textToAnalyse);
}
}
public void paint(Graphics g) {
String statsToOutput = ("There are:" + "\n" );
int counter = 1;
for (int lengths: lengthsOfWords) {
statsToOutput = statsToOutput +lengthsOfWords[0] + " words of length " + counter + "\n ";
counter ++;
}
if (output = true){
g.drawString(statsToOutput, 25, 200);
g.drawString("The text to be analysed is: " + textToAnalyse, 25, 100);
showStatus("Finished.");
}
else if (output = false){
g.setFont(arielBold);
g.drawString(textToAnalyse,50, 100);
showStatus("Finished.");
}
}
public void analyseText(String text){
///////////////////////////////////////////////////////////////////////////////////////////////////////
int position1 = 0, position2 = 0;
String newWord = "";
String currentLetter;
int pos1 = 0, pos2 = 0;
for ( pos1 = 0; pos1 <= arrayOfWords.length-1; pos1++) {
//Initializes a string object for each address in array
for (position1 = 0; position1 <= text.length()-1; position1++){
//steps through each character in text
currentLetter = Character.toString(text.charAt(position1));
if (currentLetter.matches("[A-Z][a-z][0-9]")) {
//checks if character is alphanumeric using regular expressions (regex)
newWord = newWord + currentLetter;
//if passes regex then ads character to word
}
}
if (newWord.length() > 0) {
pos1 = arrayOfWords.length;
}
arrayOfWords[pos1] = newWord;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
emptyArrayInt(lengthsOfWords);
//now compare each word with rest of array\
for ( pos2 = 0; pos2 <= arrayOfWords.length-1; pos2++) {
position2 = 0;
for (position2 = 0; position2 <= arrayOfWords.length-1; position2++){
if (arrayOfWords[pos2].length() == arrayOfWords[position2].length());
lengthsOfWords[arrayOfWords[pos2].length()] = lengthsOfWords[arrayOfWords[pos2].length()] + 1;
}
}
showStatus("finished analysing.");
output = true;
repaint();
}
public void emptyArrayInt(int[] array) {
int position = 0;
for (position = 0; position <= array.length-1; position ++)
array[position] = 0;
}
public void emptyArrayStr(String[] array) {
int position = 0;
for (position = 0; position <= array.length-1; position ++)
array[position] = "";
}
public void reset() {
pr_txt.setText("");
textToAnalyse = ("Nothing has been entered.");
emptyArrayInt(lengthsOfWords);
emptyArrayStr(arrayOfWords);
//repaint();
showStatus("Reset Successful.");
repaint();
}
public void mouseClicked(MouseEvent arg0) {}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
i would appreciate any help on this please, (I'm desperate).
Let's try section of code :
private Map<String, int> freqWords = new HashMap<String, int>();
public void analyzeText(String text) {
// You can split with another type of delimiter
String regex = ....
String[] inputs = text.split(regex);
for (String s : inputs) {
if(freqWords.containtsKey(s)) {
int frequency = inputs.get(s);
frequency++;
inputs.put(s, frequency);
} else {
inputs.put(s, 1);
}
}
}
Hope that it can help you. The main point here is you should use data structure Map to store the frequency words.

Program never ends [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm not sure what's going on, but in the console I have a red 'stop' square that i can click to stop my program from running (Eclipse IDE) and my program is just running and the square stays red..?
EDIT:
my maze:
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WSOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOWOOOOOOW
WWOOOOOOOOOOOOOWWWWWWWWWWWWWOOOOOOOOOOWWWWWWWWWWWWWOOOOOOW
WWWWWWOOOOOOOOOOOOWWWWWWWOOOOOOOOOOOOWWWWWWWWWWWWWWWWOOOOW
WOOOOOOWWWWWWWWWWWWWWOOOOOOOOOOOWWWWWWWWOOOOOOOOOOOOOOOWWW
WOOOOWWWWWWWOOOOOOWWWWOOOOOOWWWWWWWWWWWOOOOWWWWWWWWWOWWWWW
WOOOWWWWWWWWWWWWOOWWWWWWWWWWWWOOOOOOOOOOOOWWWWWWWWWOOOOOWW
WOOWWWWWWWWWWWWWOOWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWWOOOW
WOWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWOOW
WOWWWWWWWWWWWWWOOOOOOOOOOOOOOOOOOOOOOOOOOOOWWWWWWWWWWWWOOW
WOOOOOOOOOOOOOOOOWWWWOOOOOOOOWWWWWWWOOOOOOWWWWWWWWWWWWWWFW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
EDIT: here is my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Stack;
import java.awt.Point;
public class MazeExplorer {
static Point startPoint = new Point();
static Point finishPoint = new Point();
final static int mazeHeight = 12;
final static int mazeWidth = 58;
static char[][] mazePoints = new char[mazeHeight][mazeWidth];
Stack<Point> pointsNotTraversed = new Stack<Point>();
Point pt = new Point();
static HashSet<Point> previousLocations = new HashSet<Point>();
static Stack<Point> nextPoints = new Stack<Point>();
public static void main(String[] args) throws FileNotFoundException{
System.out.println("Please enter the file name of your Maze");
Scanner console = new Scanner(System.in);
File f = new File(console.nextLine());
Scanner sc = new Scanner(f);
if(!sc.hasNextLine()){
System.out.println("Sorry, please enter a file name with the extension, that contains a maze!");
}
System.out.println("So, you want to know if your maze is solvable.....?");
for (int row = 0; row < mazeHeight && sc.hasNext(); row++) {
final String mazeRow = sc.next(); //Get the next row from the scanner.
mazePoints[row] = mazeRow.toCharArray(); //Convert the row into a char[].
}
//identify the finish point
for(int i = 0; i < mazeHeight; i++){
for(int j = 0; j<mazeWidth; j++){
if(mazePoints[i][j] == 'F'){
finishPoint = new Point(i, j);
}
}
}
// Identify the start point
for(int i = 0; i< mazeHeight; i++){
for(int j = 0; j < mazeWidth; j++){
if(mazePoints[i][j] == 'S'){
startPoint = new Point(i , j);
}
}
}
isTraversable(startPoint);
}
public static boolean isTraversable(Point current){
boolean isSolvable = false;
nextPoints.push(current);
do {
if(current.y < 11) {
if((mazePoints[current.y + 1][current.x] != ' ') && (mazePoints[current.y + 1][current.x] != 'W') ){ // below direction
nextPoints.push(new Point(current.y + 1, current.x));
mazePoints[current.y + 1][current.x] = ' ';
isTraversable(nextPoints.pop());
}
}
if(current.y > 0){
if (mazePoints[current.y - 1][current.x] != ' ' && mazePoints[current.y - 1][current.x] != 'W' ){ //up dir
nextPoints.push(new Point(current.y - 1, current.x));
mazePoints[current.y - 1][current.x] = ' '; //'X' marks where you've already been
isTraversable(nextPoints.pop());
}
}
if(current.x < 57){
if(mazePoints[current.y][current.x + 1] != ' ' && mazePoints[current.y][current.x + 1] != 'W'){ // to the right
nextPoints.push(new Point(current.y, current.x + 1));
mazePoints[current.y][current.x + 1] = ' ';
isTraversable(nextPoints.pop());
}
}
if(current.x > 0){
if(mazePoints[current.y][current.x - 1] != ' ' && mazePoints[current.y][current.x - 1] != 'W') { // to the left
nextPoints.push(new Point(current.y, current.x - 1));
mazePoints[current.y][current.x - 1] = ' ';
isTraversable(nextPoints.pop());
}
}
if(current.equals(finishPoint)){
isSolvable = true;
System.out.println("MAZE IS SOLVABLE, YAHOOOOOO!!!!");
}
} while(!current.equals('F') && !nextPoints.isEmpty());
return isSolvable;
}
}
As I suggested before, you just need to reconfigure your recursive method. I took the liberty of doing this but if you ever want to learn how to program you'll want to try and solve problems like these on your own. Or try to understand the logic of your solution before you start coding.
Your main problem is that you don't know what direction you want to go in with the method before you just jumped in and that was causing all sorts of errors with different things not being compatible with each other.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Stack;
import java.awt.Point;
public class TestCode {
static Point startPoint = new Point();
static Point finishPoint = new Point();
final static int mazeHeight = 12;
final static int mazeWidth = 58;
static char[][] mazePoints = new char[mazeHeight][mazeWidth];
Stack<Point> pointsNotTraversed = new Stack<Point>();
Point pt = new Point();
static HashSet<Point> previousLocations = new HashSet<Point>();
static Stack<Point> nextPoints = new Stack<Point>();
public static void main(String[] args) throws FileNotFoundException{
System.out.println("Please enter the file name of your Maze");
Scanner console = new Scanner(System.in);
File f = new File(console.nextLine());
Scanner sc = new Scanner(f);
if(!sc.hasNextLine()){
System.out.println("Sorry, please enter a file name with the extension, that contains a maze!");
}
System.out.println("So, you want to know if your maze is solvable.....?");
for (int row = 0; row < mazeHeight && sc.hasNext(); row++) {
final String mazeRow = sc.next(); //Get the next row from the scanner.
mazePoints[row] = mazeRow.toCharArray(); //Convert the row into a char[].
}
//identify the finish point
for(int i = 0; i < mazeHeight; i++){
for(int j = 0; j<mazeWidth; j++){
if(mazePoints[i][j] == 'F'){
finishPoint = new Point(i, j);
}
}
}
// Identify the start point
for(int i = 0; i< mazeHeight; i++){
for(int j = 0; j < mazeWidth; j++){
if(mazePoints[i][j] == 'S'){
startPoint = new Point(i , j);
}
}
}
System.out.println(isTraversable(startPoint));
}
public static boolean isTraversable(Point current){
mazePoints[current.x][current.y] = ' ';
if(current.y < 56 && current.y > 0 && current.x > 0 && current.x < 11){
if (mazePoints[current.x - 1][current.y] == 'O'){ // Up dir
Point upPoint = new Point(current.x-1, current.y);
nextPoints.push(upPoint);
}
if(mazePoints[current.x+1][current.y] == 'O'){ // Down dir
Point downPoint = new Point(current.x+1, current.y);
nextPoints.push(downPoint);
}
if(mazePoints[current.x][current.y + 1] == 'O'){ // to the right
Point rightPoint = new Point(current.x, current.y+1);
nextPoints.push(rightPoint);
}
if(mazePoints[current.x][current.y - 1] == 'O'){ // to the left
Point leftPoint = new Point(current.x, current.y-1);
nextPoints.push(leftPoint);
}
if(mazePoints[current.x - 1][current.y] == 'F' ||
mazePoints[current.x + 1][current.y] == 'F' ||
mazePoints[current.x][current.y - 1] == 'F' ||
mazePoints[current.x][current.y + 1] == 'F'){
System.out.println("MAZE IS SOLVABLE, YAHOOOOOO!!!!");
return true;
}
}
if(nextPoints.isEmpty()){
return false;
}
else{
current = nextPoints.pop();
}
return(isTraversable(current));
}
}
With the maze input:
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WSOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOWOOOOOOW
WWOOOOOOOOOOOOOWWWWWWWWWWWWWOOOOOOOOOOWWWWWWWWWWWWWOOOOOOW
WWWWWWOOOOOOOOOOOOWWWWWWWOOOOOOOOOOOOWWWWWWWWWWWWWWWWOOOOW
WOOOOOOWWWWWWWWWWWWWWOOOOOOOOOOOWWWWWWWWOOOOOOOOOOOOOOOWWW
WOOOOWWWWWWWOOOOOOWWWWOOOOOOWWWWWWWWWWWOOOOWWWWWWWWWOWWWWW
WOOOWWWWWWWWWWWWOOWWWWWWWWWWWWOOOOOOOOOOOOWWWWWWWWWOOOOOWW
WOOWWWWWWWWWWWWWOOWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWWOOOW
WOWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWOOW
WOWWWWWWWWWWWWWOOOOOOOOOOOOOOOOOOOOOOOOOOOOWWWWWWWWWWWWOOW
WOOOOOOOOOOOOOOOOWWWWOOOOOOOOWWWWWWWOOOOOOWWWWWWWWWWWWWOFW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
Yields the following output:
So, you want to know if your maze is solvable.....?
MAZE IS SOLVABLE, YAHOOOOOO!!!!
true
I imported the file a different way, but you can change that back to whatever method you use previously.
Might be that you've started multiple programs and you have the "Show Console When Standard Output Changes" Not sure, but that explains one scenario. If you start task manager and find the program there you could try terminating it that way.
If it's stuck running and never completes you could try running your program in the Eclipse debugger, without any breakpoints.
Open the Debug tab (Open in from Window > Show View > Debug), suspend the thread by right clicking 'Thread [main] (Running)' and selecting 'Suspend'.
Then work your way up from the bottom of the stack, hopefully this will narrow it down enough for you to find where it blocks.
import java.util.Scanner;
import java.util.Stack;
public class test5 {
private int numRows;
private int numCols;
public test5(){
Scanner input = new Scanner(System.in);
System.out.println("Enter number of rows: ");
numRows = input.nextInt();
System.out.println("Enter number of cols: ");
numCols = input.nextInt();
Stack<Point>stack = new Stack<Point>();
stack.push(new Point(0,0));
while(!stack.isEmpty()){
if(currentPath(stack.pop(),stack)){
System.out.println("Maze is solvable");
}
}
}
public static void main(String[]args){
new test5();
}
private boolean currentPath(Point point, Stack<Point>stack){
int currentRow = point.getRow();
int currentCol = point.getCol();
while(currentRow!=numRows-1 || currentCol!=numCols-1){
boolean canGoRight = canGoRight(currentRow,currentCol);
boolean canGoUp = canGoUp(currentRow,currentCol);
boolean canGoDown = canGoDown(currentRow,currentCol);
if(canGoRight){
if(canGoUp){
stack.push(new Point(currentRow-1,currentCol));
}
if(canGoDown){
stack.push(new Point(currentRow+1,currentCol));
}
currentCol = currentCol+1;
}
else{
if(canGoUp){
if(canGoDown){
stack.push(new Point(currentRow+1,currentCol));
}
currentRow = currentRow-1;
}
else if(canGoDown){
currentRow = currentRow+1;
}
else{
return false;
}
}
}
return true;
}
private boolean canGoUp(int row, int col){
return row-1>=0;
}
private boolean canGoRight(int row, int col){
return col+1<numCols;
}
private boolean canGoDown(int row, int col){
return row+1<numRows;
}
class Point{
private int row;
private int col;
public Point(int row, int col){
this.row = row;
this.col = col;
}
public int getRow(){
return row;
}
public int getCol(){
return col;
}
}
}

Java exception handling with multiple classes

I need to make the following exceptions: NoSuchRowException if the row is not between 1 and 3, IllegalSticksException if the number of sticks taken is not between 1 and 3, and NotEnoughSticksException if the number of sticks taken is between 1 and 3, but more than the number of sticks remaining in that row. My issue is I really don't understand the syntax. If someone could help me get started with one exception, I think I can figure the others out.
So far I have the main class:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package nimapp;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
*
* #author jrsullins
*/
public class NimApp extends JFrame implements ActionListener {
private static final int ROWS = 3;
private JTextField[] gameFields; // Where sticks for each row shown
private JTextField rowField; // Where player enters row to select
private JTextField sticksField; // Where player enters sticks to take
private JButton playButton; // Pressed to take sticks
private JButton AIButton; // Pressed to make AI's move
private NimGame nim;
public NimApp() {
// Build the fields for the game play
rowField = new JTextField(5);
sticksField = new JTextField(5);
playButton = new JButton("PLAYER");
AIButton = new JButton("COMPUTER");
playButton.addActionListener(this);
AIButton.addActionListener(this);
AIButton.setEnabled(false);
// Create the layout
JPanel mainPanel = new JPanel(new BorderLayout());
getContentPane().add(mainPanel);
JPanel sticksPanel = new JPanel(new GridLayout(3, 1));
mainPanel.add(sticksPanel, BorderLayout.EAST);
JPanel playPanel = new JPanel(new GridLayout(3, 2));
mainPanel.add(playPanel, BorderLayout.CENTER);
// Add the fields to the play panel
playPanel.add(new JLabel("Row: ", JLabel.RIGHT));
playPanel.add(rowField);
playPanel.add(new JLabel("Sticks: ", JLabel.RIGHT));
playPanel.add(sticksField);
playPanel.add(playButton);
playPanel.add(AIButton);
// Build the array of textfields to display the sticks
gameFields = new JTextField[ROWS];
for (int i = 0; i < ROWS; i++) {
gameFields[i] = new JTextField(10);
gameFields[i].setEditable(false);
sticksPanel.add(gameFields[i]);
}
setSize(350, 150);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
nim = new NimGame(new int[]{3, 5, 7});
draw();
}
// Utility function to redraw game
private void draw() {
for (int row = 0; row < ROWS; row++) {
String sticks = "";
for (int j = 0; j < nim.getRow(row); j++) {
sticks += "| ";
}
gameFields[row].setText(sticks);
}
rowField.setText("");
sticksField.setText("");
}
public void actionPerformed(ActionEvent e) {
// Player move
if (e.getSource() == playButton) {
// Get the row and number of sticks to take
int row = Integer.parseInt(rowField.getText())-1;
int sticks = Integer.parseInt(sticksField.getText());
// Play that move
nim.play(row, sticks);
// Redisplay the board and enable the AI button
draw();
playButton.setEnabled(false);
AIButton.setEnabled(true);
// Determine whether the game is over
if (nim.isOver()) {
JOptionPane.showMessageDialog(null, "You win!");
playButton.setEnabled(false);
}
}
// Computer move
if (e.getSource() == AIButton) {
// Determine computer move
nim.AIMove();
// Redraw board
draw();
AIButton.setEnabled(false);
playButton.setEnabled(true);
// Is the game over?
if (nim.isOver()) {
JOptionPane.showMessageDialog(null, "You win!");
playButton.setEnabled(false);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
NimApp a = new NimApp();
}
}
The support class:
package nimapp;
import java.util.Random;
import javax.swing.JOptionPane;
import java.io.*;
import java.lang.*;
public class NimGame {
int x = 1;
int[] Sticks; //creating an array of sticks
int totalSticks = 0;
public NimGame(int[] initialSticks){
Sticks = initialSticks;}
public int getRow(int r){
return Sticks[r];}
public void play(int r, int s) throws IllegalSticksException {
try {
Sticks[r]=Sticks[r]-s;
if(s < 0 || s > 3)
throw new IllegalSticksException();
} catch (IllegalSticksException ex){
JOptionPane.showMessageDialog(null, "Not a valid row!");
} catch (IndexOutOfBoundsException e){
JOptionPane.showMessageDialog(null, "Too Many Sticks!");
}
}
public boolean isOver(){
int theTotal = 0;
for (int i = 0; i< Sticks.length; i++){
theTotal = Sticks[i];
System.out.println(Sticks[i]);
System.out.println(theTotal);
}
totalSticks = theTotal;
if (totalSticks <= 0){
return true;
}
else return false;
}
public void AIMove(){
Random randomInt = new Random ();
boolean tryRemove = true;
while(tryRemove && totalSticks >= 1){
int RandomRow = randomInt.nextInt(3);
if(Sticks[RandomRow] <= 0)//the computer can't remove from this row
continue;
//the max number to remove from row
int size = 3;
if( Sticks[RandomRow] < 3)//this row have least that 3 cards
size = Sticks[RandomRow];//make the max number to remove from the row be the number of cards on the row
int RandomDiscard = randomInt.nextInt(size) + 1;
Sticks[RandomRow] = Sticks[RandomRow] - RandomDiscard;
//I don't know if this is needed, but since we remove a RandomDiscard amount lest decrease the totalSticks
totalSticks = totalSticks - RandomDiscard;
//exit loop
tryRemove = false;
}
if(totalSticks <= 1){
int RandomRow = 0;
Sticks[RandomRow] = Sticks[RandomRow]-1;
isOver();
}
}
}
My issue is I really don't understand the syntax.
There is nothing wrong with the syntax as you have written it.
The problem is that you are catching the exception at the wrong place. You are (apparently) intending play to propagate the IllegalSticksException to its caller. But that won't happen because you are catching it within the play method.
There are two possible fixes depending on what you actually intent to happen.
You could remove the throws IllegalSticksException from the play signature.
You could remove the catch (IllegalSticksException ex){ ... } in play and catch/handle the exception at an outer level.

Categories