Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to try making a state machine, but I am fairly new to programming. I read something about a state transition table to switch between states if you input something. I do not quite understand how that works and how it translates to Java code. Can anyone please explain?
A state machine refers to a program that tracks states relative to user input.
I want to be able to input a string and then the progam gives a
message and the state changes. For example: "do work", the program
says:"going to work" and changes state. after a while it says"done
with working" and the state changes back. kind of like a very small
game
Using your example from the comments, we could do something like;
import java.util.Scanner;
enum GoingState {
TO_HOME,
TO_WORK,
TO_SHOP,
}
public class StateGame{
public static GoingState state = GoingState.TO_WORK;
public static void main(String args[]){
Scanner scanIn = new Scanner(System.in);
System.out.println("Where do you want to go?");
if(scanIn.nextLine().toLowerCase().contains("home")){
state = GoingState.TO_HOME;
System.out.println("Going home.");
}
else if(scanIn.nextLine().toLowerCase().contains("work")){
state = GoingState.TO_WORK;
System.out.println("Going to work.");
}
else if(scanIn.nextLine().toLowerCase().contains("shop")){
state = GoingState.TO_SHOP;
System.out.println("Going to the shop.");
}
else{
System.out.println("No valid input");
}
}
}
In the above example I am using enums to track state, but it could just as easily be an int or String, or an Object that tracks the state. This, of course, is an incredibly over simplified example.
State machines usually track which state transitions are possible (which I haven't done) using a state transition map (or table), which tell the program whether it can or should change from one type of state to another type of state.
A very simple example of a state map could be where there is only a linear progression to your states, ie in the example above only being able to go from home to work, work to the shops, and back again without being able to go directly from the shops to home or vice versa. Tracking this could be fairly simple, because you could put the states in an array and check if where the user wanted to go was one above or below the current state in the array.
I hope this helps.
It is not actually a machine. In the simplest case it is a program which simply has an integer variable called state. The program reads an integer input and depending upon the input and the current value of the state, it sets a new value of state.
if (state == 0 && input == 0) {
state = 1;
}
if (state == 1 && input == 1) {
state = 2;
}
if (state == 2 && input == 2) {
state = 3;
}
if (state == 3 && input == 4) {
state = 4;
}
if (state == 4 && input == 8) {
state = 5;
}
// many more such statements to cover all combinations of state and input values
Instead of such a long chain of if statements, you can use switch-case, or more sophisticatedly a class hierarchy or enums etc. But the concept should be clear based on the above.
Related
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 3 months ago.
Improve this question
I'm beginner in Java, so hope you'll understand it. I tried a few different ways, but it always has a problem with the logic: it cannot save a variable and check it in while loop or cannot go right through the if else statements. There is supposed to be some trick and I cannot find it.
For example:
If input is 1, 47, 89, 98, 165,256,300 0, it stops and prints "End of the program, numbers been entered in regular order".
If input is 86,75,32,11,0, it stops and prints "End of the program, numbers been entered in reversed order".
If input is 43, 54,11,6,7,45,44,44,44,56,330, it stops and prints "End of the program, numbers been entered in mixed or same order"
Here is the updated version of the code(2):
boolean mixed;
boolean up =true;
boolean down =true;
int numToAdd;
System.out.println("Enter a Number:");
int previousNum = input.nextInt();
do {
System.out.println("Enter a Number:");
numToAdd = input.nextInt();
if (numToAdd == 0) break;
if (numToAdd > previousNum ) {
up = true;
}
if (numToAdd < previousNum) {
down = true;
}
mixed = !up && !down;
previousNum = numToAdd;
} while (numToAdd != 0);
if (up = true ) {
System.out.println("End of the program, numbers been entered in regular order");
}
if (down = true) {
System.out.println("End of the program, numbers been entered in reversed order");
}
if (mixed = true) {
System.out.println("End of the program, numbers been entered in mixed or same order");
}
We don't want to give the O/P a complete answer. If we did that, the O/P could hand in code he / she didn't write and doesn't understand. Instead, we want to guide the O/P toward a solution. We feel the O/P will learn more that way.
I'm looking at the 2nd version of the O/P code.
There are at least 3 problems with the 2nd attempt.
(1) It appears the code intends zero to be a sentinel value. When the user enters zero, the program is supposed to exit the loop and print the results. The problem is, the code processes the sentinel value before the terminating condition in the do { } while () loop is reached. This could make a strictly ascending sequence appear to be a mixed sequence.
There are several ways this can be fixed, but one has already been suggested in the comments:
do {
System.out.println("Enter a Number:");
numToAdd = input.nextInt();
if (numToAdd == 0) break;
(2) The variable loopFor is written as if it is a sum of the numbers entered. The sum of the numbers entered is irrelevant to what the program is supposed to be doing. From the rest of the code, it seems loopFor is intended to be the previous value entered.
To fix this, the loopFor += numToAdd; statement should be deleted. The statement loopFor = numToAdd should be added to the code, but in a different place. The proper place is after all comparison of loopFor with numToAdd has been completed.
Refactor suggestion: Rename loopFor to previousNum.
However, that change still leaves a problem. The variable loopFor needs an initial value. Because the programmer doesn't know if the user will enter an increasing sequence or a decreasing sequence, the initial value can be neither an artificially high value nor an artificially low value.
I'll leave it to the O/P to figure out how to solve that.
(3) The way the boolean values up, down, mixed are managed is not reliable. If, for example, up is set to true, it can later be set to false. Still later, it can be set to true again.
These should each be set to an initial value. Upon detection of an appropriate condition, the value is flipped, and is never set to the initial value again.
My suggestion is set up and down to true only at the beginning of the program. When a sequence of numbers is detected that shows one of them to be false, set that one to false.
Note that "mixed" can be detected at the end by something like this:
boolean mixed = !up && !down;
So, that variable isn't really needed.
Again, I'll leave it to the O/P how to make the change.
I just started learning how to program in Java a month ago. I am trying to make my robot (karel) put a beeper the amount of times that is indicated in the "put" integer only, not the total amount the object has. However, it is not a set number and karel.putBeeper(put); does not get accepted in the compiler due to the class not being applied to given types. Any help would be greatly appreciated, and I am starting to understand why Stack Overflow is a programmer's best friend lol. Note: I might not respond to to any helpful tips until tomorrow.
import java.io.*;
import java.util.*;
public class Lab09 {
public static void main(String[]args) {
Scanner input = new Scanner(System.in);
System.out.println("Which world?");
String filename = input.nextLine();
World.readWorld(filename);
World.setSize(10,10);
World.setSpeed(6);
Robot karel = new Robot(1,1,World.EAST,0);
int pick=0;
int put=0;
for(int i=0; i<8; i++) {
while(karel.onABeeper()) {
karel.pickBeeper();
pick++;
karel.move();
}
for(i=0; pick>i; pick--) {
put++;
}
if(!karel.onABeeper()) {
karel.move();
}
while(karel.onABeeper() && put>0) {
karel.putBeeper(put);
}
}
}
}
If I got your question right, you're trying to putBeeper put times, which is done by the following code:
while (karel.onABeeper() && put > 0) {
karel.putBeeper(put);
}
The issue I see here is that you're not changing the value of put after calls to putBeeper, hence this while loop will never terminate: for instance, if the value of put was 5 during the first loop iteration, it will always remain 5, which is larger than 0. Also, as you've mentioned, putBeeper doesn't take any arguments, hence trying to pass put as an argument won't work - the compiler catches that error for you.
If your intent is to call putBeeper put times then what you can do is decrement put after every invocation of putBeeper - put will eventually reach 0, at which point you've called putBeeper exactly put times. And since you're just learn to program in Java, I'll leave the actual implementation to you as an exercise. Good luck!
Disclaimer: I'm really new at this and I apologize in advance if:
1) my question has already been asked (I've tried searching and had a lot of trouble finding what I needed)
or 2) if I'm not asking the question correctly.
Basically, I'm trying to make a game where pressing the spacebar triggers a sort of "super-power" that will perform a set of actions just once. Afterwards, if they try to press it again, it'll run up some sort of dialogue box that says their one-time super-power has already been used.
What I have:
try {
Key move = canvas.getLastKey();
int space = 0;
if(move == Key.SPACE) {
if (space == 0) {
space = 1;
}
if (space == 2){
JOptionPane.showMessageDialog(null, "superpower already used");
}
}
if( space == 1 ) {
//action here
canvas.resetKey();
space = 2;
}
}
Right now, the super-hero action is on an endless loop but if I reset the key here:
if(move == Key.SPACE) {
if (space == 0) {
space = 1;
canvas.resetKey();
}
the user can just use the super-power over and over again. Any help would be appreciated!
In the third line, you have written int space=0 so your variable is constantly reset to 0...
You have to initialize it elsewhere (the beginning of your program is a good place for any global variable).
You should consider moving int space = 0, outside of the try block. I suppose your try block gets invoked repeatedly, so you should declare this variable under a global scope.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
So slowly relearning java since I've forgotten all of it from college. I've always wondered if I do my loops in a weird way. I feel there has to be a better way to do loops. I'm pretty sure I always make them far longer than they should be. Anyways I'm following http://programmingbydoing.com/a/twenty-questions.html as it makes me have to google a lot and forces me to come to an understanding rather than just copying code. I'm on this 20 questions part (the link). Here is the code I wrote for it, which works. But is there a better way I could do this? Or what are the other possible ways I could have done this. Does && count as a nested if statement.
edit* Come to think of it. Any critiques at all are welcome. Not necessarily just my loops. If there is anything I am doing the long version of or anything that I'm doing a strange way please let me know.
*edit2. Whoops sorry. Did not know there was a codereview area. Would have posted there if I knew it existed.
import java.util.Scanner;
public class TwoQuestions
{
public static void main (String [] args)
{
Scanner keyboard = new Scanner (System.in);
String answerOne, answerTwo;
System.out.println("Two questions game!");
System.out.println("Think of an object, and I'll try to guess it");
System.out.println("");
System.out.println("");
System.out.println("Question 1 - Is it an animal, vegetable, or random thing?");
answerOne = keyboard.next();
System.out.println("");
System.out.println("Question 2 - Is it bigger than a breadbox?");
answerTwo = keyboard.next();
if (answerOne.equals("animal") && answerTwo.equals("yes"))
{
System.out.println("You are thinking of a moose!");
}
else if (answerOne.equals("animal") && answerTwo.equals("no"))
{
System.out.println("You are thinking of a squirrel");
}
else if (answerOne.equals("mineral") && answerTwo.equals("yes"))
{
System.out.println("You are thinking of a Camaro");
}
else if (answerOne.equals("mineral") && answerTwo.equals("no"))
{
System.out.println("You are thinking of a paper clip");
}
else if (answerOne.equals("vegetable") && answerTwo.equals("yes"))
{
System.out.println("You are thinking of a watermelon");
}
else if (answerOne.equals("vegetable") && answerTwo.equals("no"))
{
System.out.println("You are thinking of a carrot");
}
else
{
System.out.println("Please make sure you are spelling correctly, no caps");
}
}
}
There is nothing wrong with your conditional statements, but those aren't loops.
Read this for information on loops: http://www.tutorialspoint.com/java/java_for_loop.htm
For your else case, you should ask the user for another input so they don't have to rerun the program if they make a typo.
An assignment we were given recently had us building a basic, console-based, 'Tax Calculator', as it is something that got us to implement the things we'd learnt so far - variables, constants, loops etc.
One part of it had us present the user with a menu, where they would enter a letter - be it a,b,c,d or x - depending on what they wanted to do next.
That was no drama, as our assignment didn't ask for us to account for what happened if a user entered a choice not on the menu.
Now, for my own personal interest, I went back to it today, wanting to put some validation in there.
I defined the 'menuChoiceRule':
(menuChoice being a String)
boolean menuChoiceRule = (menuChoice.equalsIgnoreCase("A"))
|| (menuChoice.equalsIgnoreCase("B"))
|| (menuChoice.equalsIgnoreCase("C"))
|| (menuChoice.equalsIgnoreCase("D"))
|| (menuChoice.equalsIgnoreCase("X"));
And here is what should happen for as long as the rule is being broken: (The program should keep asking until it gets something that is in keeping with the rule, and then stop asking)
while (menuChoiceRule == false) {
System.out.print(menuChoiceString);
System.out.print("Enter Your Selection");
menuChoice = SCANNER.nextLine();
}
And what happens if the user is doing the right thing:
// As long as the user input is 'A','B','C' or 'D', they'll be able to
// keep doing stuff.
while (menuChoiceRule == true) {
*All the various menu options go here*
}
At the moment the while(menuChoiceRule == true) block (is that the right term?) works fine but while(menuChoiceRule == false) does not; Once the user inputs something that is in violation of the menuChoiceRule, the loop repeats endlessly no matter what is input (inputted?)
If someone could provide some insight as to why I'm having trouble here, it'd be much appreciated.
Regards,
AUS_Doug.
Looks like the boolean test is not being changed within the loop, place the code again at the bottom of the while loop.
Also, boolean tests do not need the ==, while(menuChoiceRule){ ... is the preferred coding style.
I would also consider creating a method to test for your rule:
private boolean testChoice(String menuChoice) {
return ((menuChoice.equalsIgnoreCase("A"))
|| (menuChoice.equalsIgnoreCase("B"))
|| (menuChoice.equalsIgnoreCase("C"))
|| (menuChoice.equalsIgnoreCase("D"))
|| (menuChoice.equalsIgnoreCase("X")));
}
This would give rise to the code:
boolean validChoice = false;
while (!validChoice) {
System.out.print(menuChoiceString);
System.out.print("Enter Your Selection");
menuChoice = SCANNER.nextLine();
validChoice = testChoice(menuChoice);
}