Mouse Pressed Event gets fired twice - java
I am trying to have it so once my mouse is pressed its gets fired once and only once. However, it keeps getting fired twice. I am not sure if this is because I am going through a for loop, but I want the mouse listener to catch what index of the array that I am clicking on. That is why I assign it to each index in the 2d array, I am not sure if theres a better way of doing this.
Code:
public boolean firstClick = false;
public boolean secondClick = false;
for (int i = 7; i >= 0; i--) {
for (int j = 0; j < 8; j++) {
int tempi = i;
int tempj = j;
pnlCells[i][j].add(getPieceObject(str[(7 - i)][j]), BorderLayout.CENTER);
pnlCells[i][j].validate();
pnlCells[i][j].addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
try {
if (firstClick == false || secondClick == false) {
if (firstClick == false) {
mouseX = tempj;
mouseY = 7 - tempi;
System.out.println("First You pressed" + mouseX + ", " + mouseY);
firstClick = true;
sourceColor = pnlCells[mouseX][mouseY].getForeground();
pnlCells[mouseX][mouseY].setForeground(Color.yellow);
pnlCells[mouseX][mouseY].repaint();
pnlBoard.repaint();
pnlMain.repaint();
} else if (secondClick == false) {
newMouseX = tempj;
newMouseY = 7 - tempi;
System.out.println("Second You pressed" + newMouseX + ", " + newMouseY);
secondClick = true;
}
if (firstClick == true && secondClick == true) {
firstClick = false;
secondClick = false;
pnlCells[mouseX][mouseY].setForeground(sourceColor);
pnlCells[mouseX][mouseY].repaint();
pnlBoard.repaint();
pnlMain.repaint();
PlayerMove pM = turn(); //send turn to server
objectOut.writeObject(pM); //send turn to server
System.out.println(name + ": sent move to server");
s.suspend();
}
}
} catch (IOException ex) {
Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
//System.out.println(j+", "+(i)+":"+v.str[(7-i)][j]);
}
}
Once I click the mouse once it always prints
First You pressed xcoord1, ycoord1
Second You pressed xcoord2, ycoord2
I am assuming that Both firstClick and secondClick are false at the init. Then when we go in the loop, the firstClick will always fire and then you set it to true. In the next iteration, the secondClick will always fire because it is false and firstClick will not fire because it is true now.
Set Both firstClick and secondClick to true once any of these fire.
Related
How to terminate while loop on Q press in java console application
How can i terminate while loop when user press 'q' so program should exit? It is Simple Java Program and i am not using swing etc. while (flag) { int x = ran.nextInt(MaxValue - MinValue + 1); System.out.print(x); System.out.print(" enclosed by {"); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i][0]); if ((x >= arr[i][0]) && (x <= arr[i][1])) { System.out.print("(" + arr[i][0] + "," + arr[i][1] + ")"); } } System.out.print("}\n"); count++; }
import java.util.Scanner; public class test { public void testFunction() { listener threadobj = new listener();//create the object Thread thread = new Thread(threadobj);//create the thread thread.start();//start the thread. it runs asynchronously while (flag /*assuming flag is unrelated*/ && !threadobj.exit) { //when !threadobj.exit is false it means that q has been pressed. //so flag && !threadobj.exit will be false if at least one is false //so the loop will end int x = ran.nextInt(MaxValue - MinValue + 1); System.out.print(x); System.out.print(" enclosed by {"); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i][0]); if ((x >= arr[i][0]) && (x <= arr[i][1])) { System.out.print("(" + arr[i][0] + "," + arr[i][1] + ")"); } } System.out.print("}\n"); count++; } threadobj.killMe = true;//finish its loop incase it is still running :) } } class listener implements Runnable { public boolean exit; //if true then the q button has been pressed public boolean killMe; //set to true to kill this thread #Override public void run() { Scanner scanner = new Scanner(System.in); while (!killMe) { if(scanner.hasNext("q") || scanner.hasNext("Q")) { //Should trigger when a q is pressed. exit = true; //if not use 'scanner.nextLine()' //wait a bit for input, so less cpu is used for constant checks. try { this.wait(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } public listener() { exit = false; killMe = false; } }
Implementing a Timer in a Rummikub game in Java
I am making a rummikub game in java and I want to implement a timer that runs for 2 minutes. Within the 2 minutes, the user has to enter inputs for whether they want to play or skip or end turn if a tile has been played. If they choose play they need to choose whether they want to play an individual tile, play a meld, or exit the sequence (All of these inputs have to be done within 2 minutes). If they don't finish the turn withing 2 minutes, then the turn has to end and no input should be taken and the next player plays their turn. I will post some of the code below. How should I go about implementing this timer? I have 2 methods for playing in the Human class and the GameTimer class and the playTurn() method in the Game class. At the moment I am testing with 10 seconds package com.COMP3004.Rummikub.models; import java.util.Timer; import java.util.TimerTask; public class GameTimer { private int seconds; private boolean started; private boolean stopped; private Timer timer; private TimerTask task = new TimerTask() { public void run() { seconds++; System.out.print(seconds + ", "); if(seconds % 30 == 0) { System.out.println(); } if(seconds == 10) { stop(); } } }; public GameTimer() { started = false; stopped = true; seconds = 0; timer = new Timer(); } public void start() { started = true; stopped = false; //timer.schedule(task, 0, 1000); new Timer(true).schedule(task, 0, 1000); //System.out.println("Timer Started"); /*if(seconds == 10) { stop(); }*/ } public boolean isStarted() { return started; } public void stop() { task.cancel(); seconds = 0; //System.out.println("Timer Stopped"); stopped = true; } public boolean isStopped() { return stopped; } public int getSeconds() { return seconds; } public boolean stopsAtRightTime() { start(); /*System.out.println(seconds); int secondsPassed = 0; do { secondsPassed = seconds; System.out.println(seconds); } while(seconds <= 10); System.out.println(secondsPassed); this.stop(); if(secondsPassed == 10) { return true; }*/ int secondsPassed = 0; try { Thread.sleep(60000); secondsPassed = seconds; System.out.println(seconds); } catch(InterruptedException e) { } if(secondsPassed == 60 || secondsPassed == 0) { //stop(); return true; } return false; } } public boolean makeAPlay(Scanner reader) { returned = false; while(true) { System.out.println("Choose one of the following commands:"); System.out.println(" - 'M' to play a meld."); System.out.println(" - 'T' to play an individual tile."); System.out.println(" - 'B' to move an existing tile on the board."); System.out.println(" - 'L' to exit this sequence."); decision2 = 'K'; TimerTask timerTask = new TimerTask() { public void run() { if(decision2 == 'K') { decision2 = 'L'; return; } } }; try { Timer timer = new Timer(); timer.schedule(timerTask, 10000 - getTimer().getSeconds()*1000); decision2 = (decision2 == 'L')? 'L': reader.next().toUpperCase().charAt(0); timer.cancel(); } catch(Exception e) { } if (decision2 == 'M') { String tileChoice = ""; Meld meld = new Meld(); this.getHand().createMeld(); while (!tileChoice.equals("D")) { if (this.getHand().size == 0) { break; } System.out.println("Current Meld: " + meld.meldToString()); System.out.println("Hand: " + this.getHand().handToString()); System.out.println("Select a tile you'd like to add to your meld, type 'D' to exit."); tileChoice = reader.next().toUpperCase(); if (tileChoice.equals("D")) { break; } for (int i = 0; i < this.getHand().size; i++) { if (this.getHand().getTile(i).tileToString().equals(tileChoice)) { meld.addTile(this.getHand().getTile(i)); this.getHand().removeFromHand(i); break; } else if (i == (this.getHand().size - 1) && !(tileChoice.equals("D"))) { System.out.println("It seems that the tile " + tileChoice + " isn't in your posession. Please try again."); } } } if (tileChoice.equals("D")) { if (meld.getMeldSize() >= 3 && meld.checkIfValidMeld() == true) { for (int i = 0; i < meld.getMeldSize(); i++) { System.out.println(meld.getTileInMeld(i).tileToString()); } this.playMeld(meld, reader); turnValue = turnValue + meld.getMeldValue(); } else { System.out.println("Invalid meld. Please try again."); for (int i = 0; i < meld.getMeldSize(); i++) { this.getHand().addTile(meld.getTileInMeld(i)); } this.getHand().sortHand(); tileChoice = ""; } } } if (decision == 'T') { if (initialMeldPlayed == true) { String tileChoice = ""; System.out.println("Hand: " + this.getHand().handToString()); System.out.println("Which tile would you like to add to the board?"); tileChoice = reader.next().toUpperCase(); Tile tempTile = this.getHand().getTile(tileChoice); if (this.getHand().getPlayerHand().contains(tempTile)) { System.out.println("Where would you like to put " + tempTile.tileToString() + " ?"); System.out.println("X-Coordinate: "); int xTile = reader.nextInt(); System.out.println("Y-Coordinate: "); int yTile = reader.nextInt(); for (int i = 0; i < this.getHand().size; i++) { if (this.getHand().getTile(i).tileToString().equals(tileChoice)) { this.addTile(this.getHand().getTile(i), xTile, yTile); } } System.out.println("Board:"); board.boardToString(); } else { System.out.println("It seems that you don't have " + tileChoice + " isn't in your hand. Please try again."); } } else { System.out.println("You cannot play individual tiles on the board during your initial meld."); } } if (decision == 'B') { if (initialMeldPlayed == true) { while(true) { board.boardToString(); System.out.println("Which tile would you like to move on the board?"); System.out.println("Current X-Coordinate ('-1' to exit): "); int xTile = reader.nextInt(); if (xTile == -1) { break; } System.out.println("Current Y-Coordinate ('-1' to exit): "); int yTile = reader.nextInt(); if (yTile == -1) { break; } Spot oldSpot = board.getSpot(xTile, yTile); Tile tile = oldSpot.getTile(); System.out.println("Where would you like to move tile " + tile.tileToString() + " to?"); System.out.println("New X-Coordinate: "); int xTileNew = reader.nextInt(); System.out.println("New Y-Coordinate: "); int yTileNew = reader.nextInt(); Spot newSpot = board.getSpot(xTileNew, yTileNew); this.moveTile(tile, newSpot); } } else { System.out.println("You cannot manipulate the board during your initial meld."); } } if (decision == 'L') { if (board.checkIfValidMelds() == false) { System.out.println("That wasn't a valid move. Please try again."); this.setTilesBeenPlayed(false); this.undoTurn(); return false; } else { return false; } } return returned; } //return false; } public GameTimer getTimer() { return timer; } public void play(Scanner reader, Deck deck) /*throws InterruptedException*/ { turnValue = 0; timer = new GameTimer(); long startTime = System.currentTimeMillis(); while( /*(System.currentTimeMillis()-startTime)<10000 ||*/ myTurn == true /*||timer.getSeconds()!=10*/) { //reader = new Scanner(System.in); System.out.println("Choose one of the following commands:"); System.out.println(" - 'P' to play your turn."); System.out.println(" - 'S' to skip your turn & draw a tile."); System.out.println(" - 'E' to end your turn if you've already played atleast one tile."); if(timer.getSeconds() == 0) { timer.start(); } //while(timer.getSeconds() != 10) { System.out.print(timer.isStopped()); /*else if(timer.getSeconds() == 10) { //this.setHasInitialMeldBeenPlayed(false); this.setTilesBeenPlayed(false); this.undoTurn(); Tile t = this.getHand().dealTile(deck); System.out.println("Out of time"); System.out.println("Turn ended: Player drew " + t.tileToString() + "."); System.out.println("----------------------------------------"); this.setTurnStatus(false); timer.stop(); }*/ decision = 'N'; //'N' for no input TimerTask task = new TimerTask() { public void run() { if(decision == 'N') { Tile t = getHand().dealTile(deck); System.out.println("Timeout"); System.out.println("Turn ended: Player drew " + t.tileToString() + "."); System.out.println("----------------------------------------"); setTilesBeenPlayed(false); undoTurn(); setTurnStatus(false); //return; } if(timer.getSeconds() == 10) { } } }; try { Timer timer = new Timer(); timer.schedule(task, 10000); decision = reader.next().toUpperCase().charAt(0); timer.cancel(); } catch (Exception e) { } if (decision == 'P') { makeAPlay(reader); } else if (decision == 'S') { if (hasTileBeenPlaced == false) { Tile t = this.getHand().dealTile(deck); System.out.println("Turn ended: Player drew " + t.tileToString() + "."); System.out.println("----------------------------------------"); this.setTurnStatus(false); timer.stop(); } else { System.out.println("You've already made a play. Try typing 'E' to end your turn."); } } else if (decision == 'E') { if (initialMeldPlayed == false) { if (turnValue >= 1) { System.out.println("Initial Meld Completed."); System.out.println("----------------------------------------"); this.setHasInitialMeldBeenPlayed(true); this.setTilesBeenPlayed(true); this.setTurnStatus(false); timer.stop(); } else { System.out.println("Your Initial Meld total must be greater than or equal to 30 points."); System.out.println("You played: " + turnValue + ". Please try again."); this.setHasInitialMeldBeenPlayed(false); this.setTilesBeenPlayed(false); this.undoTurn(); turnValue = 0; } } else if (initialMeldPlayed == true) { if (hasTileBeenPlaced == true) { this.setTurnStatus(false); timer.stop(); } else { this.undoTurn(); System.out.println("You must either play your turn or draw a tile."); } } } else { System.out.println("You may have entered the wrong character. Please try again."); } //} } } public void playTurn(int i) { printAll(); // Play if human if (allPlayers.get(i).isAI() == false && allPlayers.get(i).myTurnStatus() == true) { System.out.println("Player " + (i+1) + "'s Hand[" + allPlayers.get(i).getHand().size + "]: " + allPlayers.get(i).getHand().handToString()); int oneMoreTile = allPlayers.get(i).getHand().getNumTiles() + 1; TimerTask timerTask = new TimerTask() { public void run() { if(allPlayers.get(i).getHand().getNumTiles() == oneMoreTile) { } else if(allPlayers.get(i).getHand().getNumTiles() == oneMoreTile - 1) { Tile t = allPlayers.get(i).getHand().dealTile(deck); System.out.println("ended: Player drew " + t.tileToString() + "."); System.out.println("----------------------------------------"); allPlayers.get(i).setTurnStatus(false); } } }; try { Timer timer = new Timer(); timer.schedule(timerTask, 10000); allPlayers.get(i).play(reader, deck); timer.cancel(); if(allPlayers.get(i).myTurnStatus() == false) { nextPlayersTurn(i); } } catch (InterruptedException e) { e.printStackTrace(); } } // Play if AI if (allPlayers.get(i).isAI() == true && allPlayers.get(i).myTurnStatus() == true) { allPlayers.get(i).play(reader); if (allPlayers.get(i).hasTilesBeenPlayed() == false) { Tile t = allPlayers.get(i).getHand().dealTile(deck); System.out.println("Turn ended: Player " + (i+1) + " has decided to draw a tile."); System.out.println("Tile drawn: " + t.tileToString()); nextPlayersTurn(i); } } // Sets next players turn nextPlayersTurn(i); }
Well this is very fast written code but I hope it can give you a better opinion about the event management. private GameTimer _task; // the object. // ..................... // Put these 2 lines wherever you call the event to start. _task.setStartTime(System.currentTimeMillis() + (60000L * eventTime)); // eventTime == 2 minutes ThreadPoolManager.getInstance().executeGeneral(_task); // ..................... class GameTimer implements Runnable { private long _startTime; public ScheduledFuture<?> nextRun; public GameTimer(long startTime) { _startTime = startTime; } public void setStartTime(long startTime) { _startTime = startTime; } #Override public void run() { int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0); if (delay == 0) { // start if (isStarted()) { stop(); // You can place a scheduler here to trigger an auto-start. } else { start(); nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, endEvent); // endEvent is the time you want the run() method to run again. // In this case, when the event is finished. // This line is triggering the jvm to auto run this method again in the given time. // So if the event is already started, the run() method will run again and it will close it again. } } } } Just to mention that the code is only an example of how you could rewrite better your event timer. Hope it helps!
Java maze won't print
I have to make a maze for a java assignment, and I was able to finish most of it. I was provided with an outline of the code that had all the methods. Can someone help me? My issue is that the maze wont print out, and I can't figure out why. package maze; public class Maze { private char direction; private int r; // x position of the mouse private int c; //y position of the mouse private boolean exitFound = false; public Maze(int[][] arrMaze) { this.r = arrMaze.length - 1; this.c = 0; } //Prints out the maze without solution public void displayMaze(int[][] arrMaze) { //display the maze putting blank spaces where there are 1's in the array and putting //another symbol where there are 0's to show the maze without the solution for(int i=0; i<arrMaze.length; i++){ System.out.println(" "); for(int j=0; j<arrMaze[i].length; j++){ if(arrMaze[i][j] == 0){ System.out.print("#"); } if(arrMaze[i][j] == 1) { System.out.print(" "); } if(arrMaze[i][j] == 2){ System.out.print("#"); } if(arrMaze[i][j] == 3){ System.out.println("~"); } } } } //displays the Maze with the path taken public void displayPath(int[][] arrMaze) { //show the user how far the mouse has gone since the start. //The path the mouse has gone will be filled in but the path ahead will not. for (int i = 0; i < arrMaze.length; i++) { System.out.println(" "); for (int j = 0; j < arrMaze[i].length; j++) { if (arrMaze[i][j] == 3) { System.out.print("#"); } else if (arrMaze[i][j] == 2) { System.out.print("~"); } else if (arrMaze[i][j] == 0) { System.out.print("#"); } else { } } } } public boolean takeStep(int[][] newMaze) { // moveNorth(newMaze) for (int i = 0; i < newMaze.length; i++) { System.out.println(" "); for (int j = 0; j < newMaze[i].length; j++) { if (newMaze[r][c] == 3) { moveNorth(newMaze); System.out.print("~"); } else if (newMaze[r][c] == 2) { System.out.print("#"); } else { } } } return isAnExit(newMaze); } public void moveNorth(int[][] arrMaze) { //complete the code here /*method will check for a 0 or a 1 in the position above the current position * and then if not a 0 will change the current position to the row above it, but in the same column. */ if (arrMaze[r][c - 1] != 0) { arrMaze[r][c - 1] = 3; arrMaze[r][c + 1] = 2; } else { moveSouth(arrMaze); } displayPath(arrMaze); } public void moveSouth(int[][] arrMaze) { //method will check for a 0 or a 1 in the position below the current position and then if not a 0 //it will change the current position to the row below it, but in the same column. if (arrMaze[r][c + 1] != 0) { arrMaze[r][c + 1] = 3; arrMaze[r][c + 1] = 2; } else { moveNorth(arrMaze); } displayPath(arrMaze); } public void moveEast(int[][] arrMaze) { //method will check for a 0 or a 1 in the position to the right of  the current position and then if //not a 0 will change the current position to the column to the right but the same row. if (arrMaze[r + 1][c] != 0) { arrMaze[r + 1][c] = 3; arrMaze[r - 1][c] = 2; } else { moveWest(arrMaze); } displayPath(arrMaze); } public void moveWest(int[][] arrMaze) { //method will check for a 0 or a 1 in the position to the left of  the current position and then if //not a 0 will change the current position to the column to the left but the same row. if (arrMaze[r - 1][c] != 0) { arrMaze[r - 1][c] = 3; arrMaze[r + 1][c] = 2; } else { } displayPath(arrMaze); } private boolean isAnExit(int[][] arrMaze) { //method will return true if the user arrives into the last column of the array because there is only one //location in the last column that is a 1, so if the user reaches the array[i].length then that means that it found an exit. if (arrMaze[r][c] > arrMaze.length) { exitFound = true; } else { exitFound = false; } return exitFound; } //finds the path without stopping at every step //method will show the complete path from start to finish of the maze and the suggested route to the end. public void findExit(int[][] arrMaze) { if (arrMaze[r][c] > arrMaze.length) { for (int i = 0; i < arrMaze.length; i++) { takeStep(arrMaze); } } } } This is the test code. I was provided the test code, and I haven't changed it. package maze; import java.util.Scanner; public class TestMaze { public static void main(String[] args) { int[][] mazeArray = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, {0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1}, {0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0}, {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; Maze myMaze = new Maze(mazeArray); boolean keepAsking = true; Scanner scan = new Scanner(System.in); String input = ""; myMaze.displayPath(mazeArray); System.out.println("Maze"); do { System.out.println("T = Take a step | S = Show path | Q = Quit"); System.out.print("Enter command: "); input = scan.nextLine(); input.trim(); input.toLowerCase(); if(input.equals("t")) { keepAsking = !myMaze.takeStep(mazeArray); System.out.println("Which direction would you like to go? N, S, E, W?"); String direction = scan.nextLine(); if(direction.equalsIgnoreCase("n")) myMaze.moveNorth(mazeArray); if(direction.equalsIgnoreCase("s")) myMaze.moveSouth(mazeArray); if(direction.equalsIgnoreCase("e")) myMaze.moveEast(mazeArray); if(direction.equalsIgnoreCase("w")) myMaze.moveWest(mazeArray); } else if(input.equals("s")) { myMaze.findExit(mazeArray); keepAsking = false; } else if(input.equals("q")) { keepAsking = false; } else { System.out.println("ERR: Invalid input"); } } while(keepAsking); System.out.println("Quitting program..."); scan.close(); } }
You need to call displayMaze() (in displayPath()) to print it. Currently, you're not calling the method, meaning that your code will never print the maze as it's no being instructed to. Also, where are you assigning values to r and c? I think you meant to use i and j in your displayPath() method ([i][j] instead of [r][c]).
I imagine you're throwing an error somewhere because your r and c values are undefined everywhere they are used. Try adding code to initialize and update these values, then you should see your maze print.
Only allow 2 Buttons to be pressed
I am creating a matching card application. That only allows the user to select two cards per round. Where you see the bricks are where the buttons are and so i have added them to an arraylist, but im not sure how to make it so that they can only press 2 buttons until they press the guess button where it checks if they are a match. https://pastebin.com/65NqJ0GK private void card1ButtonActionPerformed(java.awt.event.ActionEvent evt) { String temp = cards.get(0); if (temp.equals("0")) { card1Button.setIcon(a); } else if (temp.equals("1")) { card1Button.setIcon(b); } else if (temp.equals("2")) { card1Button.setIcon(c); } else if (temp.equals("3")) { card1Button.setIcon(d); } else if (temp.equals("4")) { card1Button.setIcon(e); } else if (temp.equals("5")) { card1Button.setIcon(f); } else if (temp.equals("6")) { card1Button.setIcon(g); } else if (temp.equals("7")) { card1Button.setIcon(h); } count++; if (count == 1) { c1 = Integer.parseInt(temp); change[0] = 0; } else if (count == 2) { c2 = Integer.parseInt(temp); change[0] = 0; } } ^^Here is an example of a button code. Could someone show me some way to do it.
Knight's Tour recursive algorithm
Okay everybody, I know the knight's tour problem is popular for all cs students and I am having trouble getting mine to work. I use this recursive algorithm to progress through the moves, however, once I get to around move 50 I have to backtrack since no moves are available and I end up never completing the tour. I pass a ChessNode (holds things like if node has been visited, move it was visited, etc...), next row, next column, and previous node's move count. private int moveRecur(ChessNode current, int row, int column, int moveV){ current.moveVisited = moveV+1; if(current.moveVisited > 63){ return 0; } if(current.position==13 && aboard[row-1][column+2].visited != 1){ current.visited = 1; moveRecur(aboard[row-1][column+2], row-1, column+2, current.moveVisited); } else if(current.position==22 && aboard[row-2][column+1].visited != 1){ current.visited = 1; moveRecur(aboard[row-2][column+1], row-2, column+1, current.moveVisited); } else if(current.position == 50 && aboard[row+1][column-2].visited != 1){ current.visited = 1; moveRecur(aboard[row+1][column-2], row+1, column-2, current.moveVisited); } else if(current.position == 41 && aboard[row+2][column-1].visited != 1){ current.visited =1; moveRecur(aboard[row+2][column-1], row+2, column-1, current.moveVisited); } else if(current.position == 46 && aboard[row+2][column+1].visited != 1){ current.visited = 1; moveRecur(aboard[row+2][column+1], row+2, column+1, current.moveVisited); } else if(current.position == 53 && aboard[row+1][column+2].visited != 1){ current.visited = 1; moveRecur(aboard[row+1][column+2], row+1, column+2, current.moveVisited); } else if(current.position == 10 && aboard[row-1][column-2].visited != 1){ current.visited = 1; moveRecur(aboard[row-1][column-2], row-1, column-2, current.moveVisited); } else if (current.position == 17 && aboard[row-2][column-1].visited != 1){ current.visited =1; moveRecur(aboard[row-2][column-1], row-2, column-2, current.moveVisited); } if(row+1>=0 && row+1<8 && column+2>=0 && column+2<8){ if(aboard[row+1][column+2].visited != 1){ current.visited = 1; moveRecur(aboard[row+1][column+2], row+1, column+2, current.moveVisited); } } if(row+2>=0 && row+2<8 && column+1>=0 && column+1<8){ if(aboard[row+2][column+1].visited != 1){ current.visited = 1; moveRecur(aboard[row+2][column+1], row+2, column+1, current.moveVisited); } } if(row-1>=0 && row-1<8 && column-2>=0 && column-2<8){ if(aboard[row-1][column-2].visited != 1){ current.visited = 1; moveRecur(aboard[row-1][column-2], row-1, column-2, current.moveVisited); } } if(row-2>=0 && row-2<8 && column-1>=0 && column-1<8){ if(aboard[row-2][column-1].visited != 1){ current.visited = 1; moveRecur(aboard[row-2][column-1], row-2, column-1, current.moveVisited); } } if(row+1>=0 && row+1<8 && column-2>=0 && column-2<8){ if(aboard[row+1][column-2].visited != 1){ current.visited = 1; moveRecur(aboard[row+1][column-2], row+1, column-2, current.moveVisited); } } if(row+2>=0 && row+2<8 && column-1>=0 && column-1<8){ if(aboard[row+2][column-1].visited != 1){ current.visited = 1; moveRecur(aboard[row+2][column-1], row+2, column-1, current.moveVisited); } } if(row-1>=0 && row-1<8 && column+2>=0 && column+2<8){ if(aboard[row-1][column+2].visited != 1){ current.visited = 1; moveRecur(aboard[row-1][column+2], row-1, column+2, current.moveVisited); } } if(row-2>=0 && row-2<8 && column+1>=0 && column+1<8){ if(aboard[row-2][column+1].visited != 1){ current.visited = 1; moveRecur(aboard[row-2][column+1], row-2, column+1, current.moveVisited); } } //System.out.println(current.position + " "+current.moveVisited); current.visited = 0; return 0; } So, initially I check for the spots that can move to the corner board positions, and then I just make recursive calls based on available moves. So I guess my main question is am I doing something wrong? or is there another condition I can used to make the tour a little more intuitive? Thanks in advance!
This is the Knight's tour code in java and has a brilliant layout. I did this using backtracking using recursion. This was my class assignment. Do contact me if you have any problem understanding or running this code. package knights.tour; import java.awt.*; import java.awt.event.*; import java.util.logging.*; import javax.swing.*; public class KnightsTour extends JFrame implements ActionListener{ //All the static variables used between action listeners and functions. public static String path; public static int btnPressed = 0; public static int rowSelected; public static String[] pathArray; public static int[][] coordinatesArray; public static int columnSelected; public static int flag =0; public static int increment = 0; public static JPanel panel1 = new JPanel(); public static JPanel panel3 ; public static JButton btnStart = new JButton("Start Animation"); public static JButton btnClear = new JButton("Clear"); public static JTextArea lblPath = new JTextArea(); public static JLabel lblStartRow = new JLabel(); public static JLabel lblStartColumn = new JLabel(); public static JButton[][] button; public static int variableForIncrement=0; static int row ; static int column ; static int[][] array = new int[row][column]; public static int count = 1; KnightsTour(){ //Setting layout of the frame in the constructor and adding buttons to the panel and the frame. getContentPane().setLayout(new GridLayout(2,1)); lblPath.setLineWrap(true); lblPath.setColumns(10); lblPath.setSize(700, 100); lblPath.setEditable(false); panel1.add(btnStart); panel1.add(btnClear); panel1.add(lblStartRow); panel1.add(lblStartColumn); panel1.add(lblPath); panel3 = new JPanel(new GridLayout(row,column)); // Initializing Array of buttons for the user to click on the chess board. button= new JButton[row][column]; array = new int[row][column]; coordinatesArray = new int[row*column][2]; // This array stores the coordinates as the Knight for(int i=0;i<row;i++){ for(int j=0;j<column;j++){ button[i][j] = new JButton(); } } //Setting background of the buttons to black and white for chessboard layout. for(int i=0;i<row;i++){ for(int j=0;j<column;j++){ if(i%2 ==j%2){ button[i][j].setBackground(Color.BLACK); button[i][j].setForeground(Color.WHITE); } else{ button[i][j].setBackground(Color.WHITE); } panel3.add(button[i][j]); button[i][j].addActionListener(this); } } btnClear.addActionListener(this); btnStart.addActionListener(this); add(panel3); add(panel1); setDefaultCloseOperation(EXIT_ON_CLOSE); } public static void main(String[] args) { // TODO code application logic here String input =JOptionPane.showInputDialog("Enter the rows and columns in the format (row,column)"); String[] ar = input.split(","); row = Integer.parseInt(ar[0]); // Finding out row and column from the user input. column = Integer.parseInt(ar[1]); pathArray = new String[row*column]; // This array is kept to store the path of the knight. JFrame frame = new KnightsTour(); frame.setVisible(true); frame.setSize(700,700); } //All the computation takes place in this function. It checks the neighbour and recursively calls itself. public static void neighbourRecursion(int a,int b){ pathArray[increment] = Integer.toString(a) + "," + Integer.toString(b); // Storing the path of the Knight increment++; array[a][b] = count; //Stroing value of count. button[a][b].setText(String.valueOf(count)); coordinatesArray[variableForIncrement][0] = button[a][b].getX(); //Finding coordinates of buttons to show animation coordinatesArray[variableForIncrement][1] = button[a][b].getY(); count++; variableForIncrement++; //Checking for valid neighbours and calling itself recursively. if(a <= row-3 && b<=column-2){ if(alreadyVisited(a+2,b+1)){ neighbourRecursion(a+2,b+1); } } if(a<=row-3 && b>=1){ if(alreadyVisited(a+2,b-1)){ neighbourRecursion(a+2,b-1); } } if(a>=2 && b<=column-2){ if(alreadyVisited(a-2,b+1)){ neighbourRecursion(a-2,b+1); } } if(a>=2 && b>=1){ if(alreadyVisited(a-2,b-1)){ neighbourRecursion(a-2,b-1); } } if(a<=row-2 && b>=2){ if(alreadyVisited(a+1,b-2)){ neighbourRecursion(a+1,b-2); } } if(a<=row-2 && b<=column-3){ if(alreadyVisited(a+1,b+2)){ neighbourRecursion(a+1,b+2); } } if(a>=1 && b>=2){ if(alreadyVisited(a-1,b-2)){ neighbourRecursion(a-1,b-2); } } if(a>=1 && b <=column-3){ if(alreadyVisited(a-1,b+2)){ neighbourRecursion(a-1,b+2); } } //Breaking condition of the function. if(count == (row*column)+1){ } // Backtracking condition if there is no neighbour. else{ button[a][b].setText(""); array[a][b]=0; count--; variableForIncrement--; if(increment >0){ increment--; } return ; } } //This function checks if the neighbour is already visited. public static boolean alreadyVisited(int a,int b){ if(array[a][b] != 0){ return false; } else{ return true; } } #Override public void actionPerformed(ActionEvent e) { //when clear is pressed all arrays and global variables are set to initial conditon. if(e.getSource() == btnClear){ for(int i =0;i<row;i++){ for(int j=0;j<column;j++){ array[i][j] = 0; button[i][j].setText(""); count = 1; lblPath.setText(""); lblStartRow.setText(""); lblStartColumn.setText(""); flag =0; variableForIncrement=0; increment =0; path =" "; } } } //If start animation button is pressed animation is started. else if(e.getSource() == btnStart){ animate(); } // When the button is pressed. else{ for(int i=0;i<row;i++){ for(int j=0;j<column;j++){ if(e.getSource() == button[i][j]){ if(flag == 1){ lblPath.setText(" Please press clear before clicking again"); // Button pressed twice without reset. } else{ rowSelected = i; columnSelected =j; // If odd * odd board and selected postion is odd then No path is possible. if(row%2 ==1 && column%2 == 1 && rowSelected%2 ==0 && columnSelected%2 == 1 || row%2 ==1 && column%2 == 1 && rowSelected%2 ==1 && columnSelected%2 == 0){ lblPath.setText(" Path not possible from this point"); } else{ int count; lblStartRow.setText("Starting Row : "+String.valueOf(rowSelected + 1)); lblStartColumn.setText("Starting Column : "+String.valueOf(columnSelected + 1)); count = 1; flag = 1; startTour(); //Start tour function called. for(int q=0;q<row;q++){ for(int w=0;w<column;w++){ if(array[i][j] == 0){ count++; } } } if(count > 2){ lblPath.setText(" No Path found"); } //Printing path of the knight here. else{ for(int k=0;k<pathArray.length;k++){ path = path+"->"+ pathArray[k]; } lblPath.setText(" Path : \n"+ path.substring(5)); } btnPressed = 1; break; } } } } } } } //Function for the animation. void animate(){ if(btnPressed == 1){ btnPressed =0; Graphics g = getGraphics(); for(int i=0;i<(row*column)-1;i++){ try { Thread.sleep(600); // this function slows down drawing of lines. } catch (InterruptedException ex) { } g.setColor(Color.RED); // setting colour or line to red. g.drawLine((coordinatesArray[i][0]+65),(coordinatesArray[i][1]+50),(coordinatesArray[i+1] [0]+65),(coordinatesArray[i+1][1]+50)); } } else{ lblPath.setText(" Please clear, select a button to see the animation again"); //Animate button pressed twice without clear. } } //This function calls the neighbour function with the selected row and column by the user. static void startTour(){ neighbourRecursion(rowSelected,columnSelected); for(int i=0;i<row;i++){ for(int j=0;j<column;j++){ System.out.print(array[i][j]+" "); } System.out.println(); } } }
I have an implementation of this program in C#. You can find it here: http://github.com/danieltian/KnightBoard It will only find the first solution though. I'm not saying to copy it, but you can take a look at it and see if it helps.