How to terminate while loop on Q press in java console application - java

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

Related

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.

How to run two thread periodically?

I am asked to make a Player class ( that implements runnable ) in which I implement a run method which generates a random number and waits for the method getchoice and a getchoice method which return the generated number and notifies run . then a RockPaperScissors class( that implements Runnable) which contains method run that containt two threads containing each a player object , these two threads should play against each other 1000 times , then they should be interrupted and then it will be displayed how many times each player won . . my problem is , when my code starts to run , at the beginning it is perfect , but at a random round it starts to just play many times player 1 before going to player 2 which defeats the purpose of the game : here is the code :
public class RockPaperScissors implements Runnable {
int result1 ;
int result2 ;
int result3 ;
private final Object lock = new Object();
public void run(){
synchronized(lock){
Player a = new Player() ;
Player b = new Player() ;
Thread a1 = new Thread(a) ;
Thread b1= new Thread (b) ;
a1.start();
b1.start();
int choice1 = -100 ;
int choice2 = -1066 ;
for (int i = 0 ; i < 1000 ; i++){
try {
choice1 = a.getChoice();
} catch (InterruptedException e1) {
}
try {
choice2 = b.getChoice();
} catch (InterruptedException e) {
}
if (choice1 == 1 && choice2==0)
result2++;
else if (choice2 == 1 && choice1==0)
result1++;
else if (choice1 == 1 && choice2==1)
result3++ ;
else if (choice1 == 1 && choice2==2)
result1++ ;
else if (choice1 == 2 && choice2==1)
result2++ ;
else if (choice1 == 0 && choice2==2)
result1++ ;
else if (choice1 == 2 && choice2==0)
result2++ ;
else if (choice1 == 2 && choice2==2)
result3++ ;
else if (choice1 == 0 && choice2==0)
result3++ ;
}
and this is class Player :
public class Player implements Runnable {
private final Object lockvalue = new Object();
private int a;
public void run() {
synchronized (lockvalue) {
for (int counter = 0; counter < 1000; counter++) {
java.util.Random b = new java.util.Random();
a = b.nextInt(3);
System.out.println(counter);
try {
lockvalue.wait();
} catch (InterruptedException e) {
System.out.println("Thread player was interrupted");
}
}
}
}
public int getChoice() throws InterruptedException {
synchronized (lockvalue) {
lockvalue.notify();
return a;
}
}
}
if my programm runs perfectly the counter display should always have the number starting from 0 to 1000 duplicated one after the other , but here it starts like that but then it gets messed up and it never reaches 1000 , it stops sometimes at 700 sometimes at 800 . all I am allowed to used is notify() , notifyAll() , wait() , start() , interrupt() and join() .
your help would be greatly appreciated . Thanks
Your implementation and approach show that you don't understand concurrency, how it works and when should be applied.
I recommend you to read corresponding chapter (Concurrency) in Bruce Eckel's "Thinking in Java" - http://www.mindview.net/Books/TIJ/
To make your code work You have to add one more wait-notify before return in Player.getChoise()
Here is fixed version:
RockPaperScissors.java
package game;
public class RockPaperScissors
{
static int player1wins = 0;
static int player2wins = 0;
static int draw = 0;
public static void main(String[] args) throws InterruptedException
{
int cycles = 1000;
Player player1 = new Player("Player-1", cycles);
Player player2 = new Player("Player-2", cycles);
new Thread(player1).start();
new Thread(player2).start();
for (int i = 0; i < cycles; i++)
{
Choice choice1;
Choice choice2;
choice1 = player1.getChoice();
System.out.println("Value 1 is definitely generated");
choice2 = player2.getChoice();
System.out.println("Value 2 is definitely generated");
System.out.printf("\n%3d\nPlayer1 - %8s\nPlayer2 - %8s\n", i, choice1.name(), choice2.name());
if (choice1 == choice2)
{
draw++;
System.out.println("Draw!");
}
else if (choice1 == Choice.ROCK)
{
if (choice2 == Choice.PAPER)
{
player2wins++;
System.out.println("2 wins!");
}
else
{
player1wins++;
System.out.println("1 wins!");
}
}
else if (choice1 == Choice.PAPER)
{
if (choice2 == Choice.SCISSORS)
{
player2wins++;
System.out.println("2 wins!");
}
else
{
player1wins++;
System.out.println("1 wins!");
}
}
else if (choice1 == Choice.SCISSORS)
{
if (choice2 == Choice.ROCK)
{
player2wins++;
System.out.println("2 wins!");
}
else
{
player1wins++;
System.out.println("1 wins!");
}
}
}
System.out.printf("Player 1 wins - %3d times;\n" +
"Player 2 wins - %3d times;\n" +
"Draw result - %3d times\n\n", player1wins, player2wins, draw);
System.out.printf("Player-1 cycles left = %d\n" +
"Player-2 cycles left = %d\n", player1.getCounter(), player2.getCounter());
}
}
Player.java
package game;
import java.util.Random;
public class Player implements Runnable
{
private Random random = new Random();
private int value;
private int counter;
private String name;
public Player(String name, int cycles)
{
this.name = name;
this.counter = cycles;
}
public synchronized void run()
{
while (true)
{
try
{
wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
value = random.nextInt(3);
System.out.println(name + " ... Value was generated = " + value);
notify();
// Otherwise your thread will never stop!
counter--;
if (counter <= 0)
{
System.out.println(name + " ... Limit of operations is exceeded.");
break;
}
}
}
public synchronized Choice getChoice() throws InterruptedException
{
System.out.println(name + " ... now can generate value");
notify();
System.out.println(name + " ... wait until value is generated");
wait();
Choice choice = Choice.values()[value];
System.out.println(name + " ... returning generated value: " + value);
return choice;
}
public int getCounter()
{
return counter;
}
}
Choise.java
package game;
public enum Choice
{
ROCK,
PAPER,
SCISSORS;
}
I would consider implementing your logic using a semaphore or a CountDownLatch for better synchronization
http://tutorials.jenkov.com/java-util-concurrent/semaphore.html
http://tutorials.jenkov.com/java-util-concurrent/countdownlatch.html

Mouse Pressed Event gets fired twice

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.

Why does this message print extra times (more than I want it to print)?

import java.util.ArrayList;
import java.lang.Math;
public class War {
ArrayList deck = new ArrayList(0);
ArrayList player1 = new ArrayList(0);
ArrayList player2 = new ArrayList(0);
int sum1 = 0;
int sum2 = 0;
int count = 0;
private void setup ()
{
for (int x = 1; x <= 13; x++)
{
for (int y = 1; y <= 4; y++)
{
deck.add(x);
}
}
while (deck.size() > 26)
{
double x = Math.random() * deck.size();
int y = (int) x;
player1.add(deck.remove(y));
}
while (deck.size() > 0)
{
double x = Math.random() * deck.size();
int y = (int) x;
player2.add(deck.remove(y));
}
for (int x = 0; x < 26; x++)
{
sum1 += (int) player1.get(x);
sum2 += (int) player2.get(x);
}
System.out.println("Player 1's starting power is " + sum1 + ".");
System.out.println();
System.out.println("Player 2's starting power is " + sum2 + ".");
System.out.println();
if (sum1 == sum2)
{
System.out.println("The two player's starting powers are equal! This'll be a good one, folks!");
}
}
public void play ()
{
if (hasSomeoneWon() || count == 0)
{
setup();
}
while (!player1.isEmpty() && !player2.isEmpty())
{
int a = (int) player1.get(0);
int b = (int) player2.get(0);
if (a > b)
{
player1.add(player1.remove(0)); // The winner's card is re-added to his deck before
player1.add(player2.remove(0)); // the loser's is added to the winner's deck.
}
if (a < b)
{
player2.add(player2.remove(0));
player2.add(player1.remove(0));
}
if (a == b)
{
war();
}
}
victory();
}
private void war ()
{
ArrayList temp1 = new ArrayList(0);
ArrayList temp2 = new ArrayList(0);
temp1.add(player1.remove(0));
temp2.add(player2.remove(0));
int x = 0;
while (!(player1.isEmpty() || player2.isEmpty()) && x < 3)
{
temp1.add(player1.remove(0));
temp2.add(player2.remove(0));
x++;
}
int a = (int) temp1.get(temp1.size() - 1);
int b = (int) temp2.get(temp2.size() - 1);
if (a == b)
{
if (temp1.size() != temp2.size())
{
if (temp1.size() > temp2.size())
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
else
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
}
else
{
if (player1.isEmpty() || player2.isEmpty())
{
if (player1.isEmpty())
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
else
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
}
else
{
war();
}
}
}
else
{
if (a > b)
{
while (!temp1.isEmpty())
{
player1.add(temp1.remove(0));
}
while (!temp2.isEmpty())
{
player1.add(temp2.remove(0));
}
}
else
{
while (!temp2.isEmpty())
{
player2.add(temp2.remove(0));
}
while (!temp1.isEmpty())
{
player2.add(temp1.remove(0));
}
}
play();
}
}
private void victory ()
{
if (player1.isEmpty() && sum2 > sum1)
{
System.out.println("Player 2 has won!");
}
if (player1.isEmpty() && sum1 > sum2)
{
System.out.println("Upset! Player 2 has won!");
}
if (player2.isEmpty() && sum1 > sum2)
{
System.out.println("Player 1 has won!");
}
if (player2.isEmpty() && sum2 > sum1)
{
System.out.println("Upset! Player 1 has won!");
}
hasSomeoneWon();
}
private boolean hasSomeoneWon ()
{
if (player1.isEmpty() || player2.isEmpty())
{
count++;
return true;
}
return false;
}
}
Sorry for including all of my code, but I don't know which part is causing the extra printing.
This is the card game War. It's supposed to play out the game between two players on its own and then print the winner. Whenever I've played it, though, the victory message (whichever one gets printed) is printed a variable number of times. I'm guessing this has something to do with either where and how often I've included my calls to some of the methods OR the recursive call to war within the war() method.
My only experience with Java is an AP Computer Science class I took this school year, so I'm for sure a noob by the standards of everyone reading this.
In the war() method you are recursively calling war() and war() will eventually end by recalling play(). So there will be multiple instances executing play(). Eventually when the cards run out for one player all this instances will comeback as the stack is unwound and continue executing play(). And finally of course calling victory() and printing it multiple times (should be the amount of times war() was called).
So each war() may print out a player has won once it reached the bottom of the recursion. I don't think the call to play() in war() is necessary, it will go back to the play() method after it finishes the war() method anyway.

Categories

Resources