Are empty loops okay to use? - java

I'm working on a text based game with a GUI as the "console" for input and output. My objective is to, when the game asks for it, submit a command I have typed in a JTextArea to another method.
To do this I have come up with this idea: when user.readLine() is called, it loops until the GUI receives an action event. Detection of this event is accomplished by the flipping of a boolean called commanded, toggled in the actionevent's method. readLine() then breaks the loop at this point and returns the text that was just entered, then flips the boolean back. Interestingly enough, this only works if I add a System.out.println(); or a Thread.sleep(1); before flipping the boolean back...
The readLine() method involves a lot of looping with no code between the braces, as it waits for the Action Event. Is it wrong to think of this as a "short circuit" and something to be avoided? Code is below. Thanks!
CommandInput.java:
public void waitForCommand() {
try {
processCommand(Parasite.user.readLine().toLowerCase());
} catch (Exception e) {
System.err.println(e);
}
}
UI.java (initialized as Parasite.user):
boolean commanded= false;
String command = "";
public final String readLine()
{
while(commanded == false)
{
System.err.print(command);
}
System.out.println("Submitting Command");
commanded = false;
return command;
}
private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {
commanded=true;
command=jTextField1.getText();
System.err.println(jTextField1.getText());
jTextField1.setText("");
}

The short circuit thing:
Loops that don't do much in words of other than looping like this:
while(true) {}
are not very CPU friendly, much better would be soemthing like this:
while(true) {
Thread.yield();
}
This says the CPU, that this thread can be stopped right now, so other threads can run now, it gets moved down in the Thread queue. You don't loose that much of precision doing this, but it prevents you from using all of your cpu. (look here for more information: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield() )
So in your case:
while(commanded == false)
{
System.err.print(command);
Thread.yield();
}

Read this article on how to use event driven programming to solve your problem. In short, your approach is inefficient and does not scale well

Related

How do I return to the main method from another method in the same class (break didn't work)

So I've seen a bunch of other posts about this, but they didn't apply since a) I'm trying to return to the main method while SKIPPING a while loop inside of the main. I'm making a text adventure game and it works in steps (separate methods), by calling the next step from within the step at the end. for example, the first step is EastStoryline1(), and the second is EastStoryline2(), and at the end of the code for EastStoryline1(), it says "EastStoryline2()".
So the actual main is pretty small, since it's just one method looping into the next. There are also 2 while loops in the main. The first comes right after I establish the scanner and boolean playagain, which basically surrounds the rest of the main starts the game while playagain = true. the second loop comes right after the first, which basically says while def (the players health) > 0, play the events of the game. After the second loop, but still in the first loop, the code calls the method Die(), and then asks the player whether they want to play the game.
SO basically, what code do I put inside Die() in order to break out of any existing loop chain and bring it to the next code after Die() is called in the main. The problem is that I also use Die() in other methods, and each time it's called I want it to return to the code after Die() in the main. Here's the code for the main (sorry for bad formatting):
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
boolean playagain = true;
while(playagain == true)
{
while(def > 0)
{
TitleScreen("TXT ADVENTURE!");
System.out.println("Pick a character: Rogue, Paladin, or Priest
(capitals DO matter!)");
String character = keyboard.next();
CharacterChoice(character);
System.out.println("You wake up on a dusty road, with no memory of who
you are or how you got here. You can only remember your name, and how to
fight. To the east lies a small dock with a boat. To the west, there seems
to be a sand-scarred mountain range. Do you go east, or west?");
String ew = keyboard.next();
EastWest(ew);
}
Die();
System.out.println("Do you want to play again?");
String playornah = keyboard.next();
if(playornah.equals("yes") || playornah.equals("Yes"))
{
playagain = true;
}
else
{
playagain = false;
}
}
}
And this was the code for Die I used system.exit(0), but now I want it to return to the main after Die is called there instead of just ending the program):
public static void Die()
{
System.out.println("GAME OVER");
System.exit(0); //I tried using break but it wouldn't compile
}
So what to I code in Die() in order for (no matter where it's called) return to the main after the spot where Die() is called.
public static void Die()
{
System.out.println("GAME OVER");
System.exit(0); //I tried using break but it wouldn't compile
}
System.exit(0); ends the program. If you want to just end the method either:
Let the method end naturally when it has no more statements. (Just remove System.exit(0);)
Replace System.exit(0); with a return; statement
From the docs:
A method returns to the code that invoked it when it
completes all the statements in the method,
reaches a return statement, or
throws an exception (covered later),
whichever occurs first.
You can't return from an external method, How ever you can use a try-finally to return it once you have run your code.

Checking for integer and creating error message in terminal - not crash the program

I am working on a program that allows me to move a pen, making a mark on a canvas. At the moment, I have a method called convertToInteger in class "MyInput" (which in the class with my methods I've referred to as "reader"), which converts a string into an integer.
public int convertToInteger(String word)
{
return Integer.parseInt(word);
}
I've then tied this into my method, converting a string input into an integer.
case "move":
int distance = reader.convertToInteger(command.get(1));
brush.move(distance);
break;
Thus, in my program I can type "move 100" and the brush move 100 pixels. The code, in its current state, crashes with an exception error if I tried typing a non-integer; e.g. "move here".
In "MyInput" class, I created a boolean method that checks to see if it's a integer or not using 'try' and 'catch':
public boolean isAnInteger(String word)
{
boolean ok;
try {
Integer.parseInt(word);
ok = true;
}
catch(NumberFormatException ex) {
// Non-integer string.
ok = false;
}
return ok;
}
Then tried implementing it in my code:
case "move":
int distance = reader.convertToInteger(command.get(1));
if (reader.isAnInteger(command.get(1)) == true){
brush.move(distance);
}
else {
printError();
}
break;
When I run the code and type something like "move here" in the terminal, it throws an exception so clearly its bypassing my code - but typing "move 100" or any other valid integer works.
Any suggestions? Thanks in advance.
Your instructions are in the wrong order. Your are attempting to parse, then checking if it can be parsed. You should really check first, then try to parse.

Restarting program from a certain point after an if

I started studying Java not too long ago, I am currently trying to make a little game to see if I got the things I saw right.
I want to make a "game" that let's you choose between two dialogue options which have different consequences.
This is the code I used:
package programs;
import java.util.Scanner;
public class Programma1_0 {
public static void main(String[] args) {
System.out.println(
"You wake up in a laboratory. You don't remember ever being there. You actually don't remember anything.");
System.out.println("A door opens, a girl comes towards you.");
System.out.println("Girl:<<Hi, I see you woke up. How are you feeling?>>");
System.out.println("(Write Good or Bad)");
Scanner first = new Scanner(System.in);
String firstch = first.nextLine();
if (firstch.equals("Good")) {
System.out.println("Great, we have a lot to explain.");
} else if (firstch.equals("Bad")) {
System.out.println("You should be alright in an hour or so. You've slept for a long time.");
} else {
System.out.println("(I told you to write Good or Bad)");
}
}
}
So far it's working as intended. The only problem is that if I write something other than Good or Bad i get the message "(I told you to write Good or Bad)" and the program terminates. Is there a way to automatically restart it? If i put more choices in, I want the program to automatically restart from the question where it terminated (So I don't play through half of the game, get a question wrong and have to restart the program from the start), is that possible?
Thanks.
You can accomplish this by putting this before your if statement.
while (true) {
if (firstch.equals("Good") || firstch.equals("Bad"))
break;
else {
System.out.println("(I told you to write Good or Bad)");
firstch = first.nextLine();
}
}
Then you can also remove the last else part of your if statement.
Now it will continue asking for a new input till it gets either "Good" or "Bad"
You can simply put your if-else statement inside the do-while loop, that way you can loop through until you get correct response
int i = 0;
do {
System.out.println("(Write Good or Bad)");
firstch = first.nextLine();
if (firstch.equals("Good")) {
System.out.println("Great, we have a lot to explain.");
i = 0;
} else if (firstch.equals("Bad")) {
System.out.println("You should be alright in an hour or so. You've slept for a long time.");
i = 0
} else {
System.out.println("(I told you to write Good or Bad)");
i = 1;
}
} while (i == 1);
You can partition your program into separate methods. Here I created a method called retrieveAnswer() which its only task to create a Scanner and get input. This method will return a String as seen in the public static String header.
Another method I created was entitled getResult() which takes a String argument and will now compare the String passed from
String firstch = retrieveAnswer();
getResult(firstch);
If the result goes to the else block, it will call retrieveAnswer() and pass the value returned to getResult() as seen in getResult(retrieveAnswer()) which will then restart the whole process.
There are multiple solutions to this, but I just took the recursion route instead. Good luck with Java! If you are confused, look more into methods as they are VERY essential in programming.
import java.util.Scanner;
public class Source {
public static void main(String[] args) {
System.out.println(
"You wake up in a laboratory. You don't remember ever being there. You actually don't remember anything.");
System.out.println("A door opens, a girl comes towards you.");
System.out.println("Girl:<<Hi, I see you woke up. How are you feeling?>>");
System.out.println("(Write Good or Bad)");
String firstch = retrieveAnswer();
getResult(firstch);
}
public static String retrieveAnswer(){
Scanner first = new Scanner(System.in);
String firstch = first.nextLine();
return firstch;
}
public static void getResult(String firstch){
if (firstch.equals("Good")) {
System.out.println("Great, we have a lot to explain.");
} else if (firstch.equals("Bad")) {
System.out.println("You should be alright in an hour or so. You've slept for a long time.");
} else {
System.out.println("(I told you to write Good or Bad)");
getResult(retrieveAnswer());
}
}
}

java cli running indicator

I want some ascii characters periodically changing to indicate my CLI program is running, like -|\/-|/.... The old character is replaced by the new, which looks like an animation. Is there any library approaching that?
Kejia
You might want to use the carriage return(CR) character ('\r' in java) to do this. I would do it this way (assuming you are doing the animation at the beginning of the row):
My solution (Test.java):
public class Test
{
public static void main(String[] args)
{
try
{
System.out.print("\\");
Thread.sleep(1000);
System.out.print("\r|");
Thread.sleep(1000);
System.out.print("\r/");
}catch(Exception e)
{
}
}
}
Simplest idea: try replace all console (rows & cols) with new view (frame) of your animation.
I once wrote a test program and part of it worked like curl/wget to download a file. To print the progress I just used System.err.print(n); System.err.print('\r'); which moves the cursor to the start of the line ready for the next progress update. But in your case you could probably print each one of "\\\b" "-\b" "/\b" (\b is backspace) in order repetitively to get the spinning effect.
In Scala:
"-|\\/-|/".toCharArray ().foreach {c => print ("\b" + c); Thread.sleep (250); }
Analog, but more Code in Java, but not tested:
for (c : "-|\\/-|/".toCharArray ())
{
System.out.print ("\b" + c);
Thread.sleep (250);
}

Break an infinite loop

i have an infinite loop something like that:
while(true) {
//do something
}
I would like to be able to break the loop using a key for exaple escape key. I think it could be done using events but as i am new to java i cant do that.
Can anyone help me? Thank you in advance!
In the while loop the program reads a value from usb and then send it over the network using sockets. My program is the server and sends bytes to a client. I want to be able to stop that server with a key!
In the while loop the program reads a value from usb and then send it over the network using sockets. My program is the server and sends bytes to a client. I want to be able to stop that server with a key!
Pure java, by itself, does not have a notion of a key input. You usually get them from a specific IO module (e.g., console based, AWT based, Swing based, etc.).
You would then check for the condition or break.
If your notification of a press is asynchronous, you would probably set some flag (e.g., breakRequested), and check for this flag and break if it has changed.
For Console access, take a look at http://download.oracle.com/javase/6/docs/api/java/io/Console.html
but pay attention to the many questions about this facility here on Stackoverflow.
Use the break keyword. For example:
try {
Console console = new Console();
while(true)
{
String input = console.readLine();
if("quit".equals(input))
{
break;
}
// otherwise do stuff with input
}
catch(IOException e)
{
// handle e
}
Many programmers think the following would be more readable:
try
{
Console console = new Console();
for(String input = console.readLine(); !"quit".equals(input); input = console.readLine())
{
// do stuff with input
}
}
catch(IOException e)
{
// handle e
}
change while(true) to something like while(!isStopped()){...}
Keep in mind, while your application is in that block, and is spinning, no other portion of your application will be able to process instructions. That is unless you spin off your worker process into a new thread and share a variable/flag between the two. That way, when a key is pressed, through whatever means you have in capturing it, you can modify a boolean variable which will carry over to your thread. So you can set your loop up like the following:
while(_flag)
{
//Spin
}
I have created this program that terminates an infinite loop if a specific key is pressed:
class terminator {
public static void main(String args[]) throws java.io.IOException {
char press, clear;
for(;;) {
System.out.print("Press any key to get display, otherwise press t to terminate: ");
press = (char)System.in.read();
System.out.println("You Pressed: "+ press);
do {
clear = (char)System.in.read();
} while(clear != '\n');
System.out.println("\n");
if (press=='t'|press=='T') {
System.out.println("Terminating Program......Program Terminated!");
break;
}
}
}
}
To break infinite loop with a condition.
public class WhileInf {
public static void main(String[] args) {
int i = 0;
while (true) {
if (i == 10) {
break;
}
System.out.println("Hello");
i++;
}
}
}
You can force quit the console if you are in infinite loops.
Window = Ctrl + Shift + Esc
Mac = Option + Command + Esc
while(true)
{
if( )
{
break;
}
else if()
{
break;
}
else
{
do something;
break;
}
}

Categories

Resources