How to handle exceptions in games - java

I'm programming a game that has user interaction through the console. The user would enter a command followed by a space and then the parameters of said command. Example:
move-piece 5-right
The command is "move-piece" and the parameters are "5-right" (5 spots to the right). I have a method that checks if the command and parameters were entered in the correct format. The method then calls a move method with the parameters that moves the piece on the board. An example of an exception case could be that the game is already over, in which case the user is not allowed to move any pieces. Another exception case is moving the piece outside the board. I always read about how using exceptions for control flow is bad, but I don't really understand what that means.
if (gameOver){
throw new CustomGameException("you cannot move any pieces, because the game is over.");
}
Is the above considered controlling the flow with exceptions? Of course this isn't the only situation in which a game rule is broken. I have many more if statements that check for edge cases, but I'm not sure if that's a good thing or not. If the above is considered bad practice, how else should I handle such cases? I want to be able to print out a unique message for each edge case to inform the user about his/her mistake. I should note that this is for a school project and we are not allowed to have any System.out.print in our main code. The output gets printed to the user in the main method.
EDIT for clarity:
We are not allowed to have print methods within our code. Output is done in the main method. The suggested solution given to us by our teacher also used exceptions to handle such cases. An example of such usage in the solution is when the user attempts to roll a die twice in a row (which is not allowed according to the game rules). My teacher threw an exception in the roll method for such a scenario. The teacher also says that we are not supposed to use exceptions to control the flow, which is why I'm a bit confused.

Don't take the statement about not using exceptions for control flow too literally. There are many cases where exceptions work just fine.
One is where it's hard (or outside the responsibility) for the code that knows how to handle the error to detect whether the error will occur or not. Your situation might be an example of this: You want to handle all user interaction in the main method, but all kinds of things at various depth into your code can invalidate a command. So throw an exception and be done with it. Don't worry about the performance of something that will happen at most once every time a user enters some text.
Another reason to use exceptions would be where there are natural race conditions in checking if an operation might succeed or not. e.g. you want to create a file, but a common occurrence is that a file with the same name might already exist or you might be out of disk space or something similar. In that case it's no use to check if the operation will succeed as it might still fail later when you do the operation. Just try to do it and catch the right exceptions.
Advice on the form "never use X" is common in programming and almost never worthy of the zeal with witch it is presented.

Related

Drools Decision Table Action Execution Order

I have a Drools decision table (see below) whereby Rule 2 has a condition that checks whether a nutrient score is between a certain threshold and executes an action based on this condition. There is an initial rule (RULE 1) that performs a check and performs its action, which updates the overall scores that i want Rule2 to use when executing its conditions.
What i expect/need:
Rule 1 to run, if the condition is met then update the overall score on $model (by executing its action) and then rule 2 run and for it's conditions to use the updated score value that was updated by Rule 1's action running.
What's actually happening
Rule 1 runs it's condition, Rule 2 runs its condition, Rule 1's action is run, Rule 2's action is run. Rule 2 is running it's condition before Rule 1's action has run, and therefore uses an outdated score.
I've proven (i think) by changing the priority/salience value that i can change the order in which the rules run their conditions, but it seems that all rule conditions are running before actions. I expected Rule 1's action to run before the next rule.
Have i fundamentally mis-understood the concept? An obvious mistake? Or if anyone has a suggested workaround that would be great.
To clarify this is a stateless ki session.
Thanks in advance, this is driving me mad!
Drools works by taking all of the rules up front and evaluating whether their conditions are satisfied. Each of these rules is called a "match". When you fire the rules, Drools collects all of the matches, orders them (either naturally or by salience), and then iterates through and executes them one by one.
As the rules are executed, they might change working memory like your example does. Unless you explicitly tell Drools that you're doing so, however, it won't re-evaluate the matches. The match phase has already been completed by the time the rules are executed.
It is possible to tell Drools that you are modifying working memory and that you need it to re-evaluate its rules based on the new data. To do this, you need to use one of the built-in methods:
Method
Explanation
insert
Put a new fact into working memory.
delete or retract
Removes some information (object/s) from working memory.
update
Update/replace a fact in working memory.
modify
Change fields inside of a fact in working memory.
Which one you choose depends on what you're trying to do. Note that calling 'update' will call all matches to be re-evaluated ... it's the equivalent of calling "fire rules" a second time with the new data (so the same rule might hit multiple times, which may or may not be intentional). In comparison, insert will only evaluate subsequent rules to determine if they now match or don't based on the new conditions.
So if your intention is to cause other rules to fire or not by changing the data in working memory, you'll need to use one of these built-in methods to tell Drools that you're making a change that it should re-evaluate its matches for.
I discuss this concept in more detail in this answer specifically about DRL. The same concepts apply to decision tables.

React to console inputs (commands) - how to handle multiple options most efficient?

Some information (don't want to confuse you with a lot of shitty code):
I've done a pretty large console programm (my largest project so far) which helps me a lot with managing some accounts / assets and more. I'm constantly adding more features but at the same time I reshape the code to work on my shitty coding style.
The console program has a lot of commands the user can type and for every command different methods get called / objects get created / manipulated and so on.
My keywords which are saved in an ArrayList<String> and my commands have this type: [keyword] [...n more Strings]
DESIGN PROBLEM 1:
I have a method cmdProcessor(String[] arguments) which handles the input (command) of the user, and the [keyword] is always the first argument arguments[0]. That means I have a large number of if-statements of this type:
if(arguments[0].equalsIgnoreCase("keyword") callMethod(argmts); where in the String[] argmts the remaining arguments[1] ... [n] are.
Is this a good way to handle this or should I go with switch-case?
Or something else (what?)? Is it better to save the keywords in a HashMap<String, Method>?
DESIGN PROBLEM 2:
The methods (see above callMethod(argmts) ), which are triggered by the entered keyword look even more chaotic. Since the same method can have different numbers and forms of arguments saved in the String[] argmts the method is full of if(argmts.length == ...) to check length, and every of these if-blocks has a bunch of switch-case options which also have a lot of ifs and so on. The last else and the default-case in switch-case I always use for error-handling (throwing error codes and and explanation why the pattern doesn't match and so on).
Is this good or are there better ways?
I thought about using lots of submethods, which would also blow up
my program and cost a lot of time but maybe improve readability / overview. Is this okay, or what is the best
option in such cases (lots of ifs and switch-case)?
Since I want to build more and more around this program maybe I should start now to fix bad design before it's too late. :)
About Design-Problem 1:
My go-to would be to register a lot of Handlers, which you can base on a common interface and then implement the specific behavior individually. This is good, because the central method handling your input is slim, and you only need to register a lot of singletons once, on initialization. Disadvantage: if you forget one, it will not work. So maybe, you can register them automatically (reflection or something thelike).
Aside from that, a map is better than a List in this case, because (I assume) you don't need a sorting. You need a mapping from key to behavior, so a map seems better (though even a very large set of keywords would probably not be very inefficient, if you stick to a list).
About Design Problem 2:
If I was you, I'd use actual Regular-Expression patterns. Take a look at the java.util.regex.Pattern-class. You can isolate groups and validate the values you receive. Though it does not spare you the exception/error-handling, it does help a lot in segmentation and interpretation efforts.

Setting a delay on a one-character string looped user input that uses a bufferedreader in java (cmd program)

I'm writing a program that is a basic 2D command window game, that uses a bufferedreader with the .readline() method to get a WASD input to determine what direction the "Character" (asterisk) will move. However, if the player does nothing, I need the program to keep going and just keep the character in place. This all happens in a loop that goes roughly like
determine player movement needed
determine other needed changes to the board
change the board
rinse and repeat.
with the loop getting stopped at step 1 any time the user decides to not move.
I have read several other posts, and most of them seem to relate to client-server connections, which does not apply here. Another post I found seemed to have an answer, but as the context of the code was different and I did not understand the code due to my sparse experience programming, I can not make enough sense of it to use it.
Set timeout on user input
I am unfamiliar with what a "Future" and "Executor" do, although I have seen the term executor thrown around a lot in other code, so if someone could even just explain those two things in relation to the problem, that would be great! I apologize that I don't have any source code to post with this question, but I really have no clue where to start on this one other than to create a BufferedReader, which is fairly irrelevant.
Edit: to add a bit more information, I plan to take the output of the br.readline every half second or so and then update then update the board even if nothing has been entered. I think the first step to get this done is creating some kind of input stream, possibly other than a bufferedreader, that does not require the user to press enter every time they want to move or not move, so maybe that would be a better place to start.

Labels in Java - bad practice?

Why using labels in Java is a bad practice? I cant find a reason. All explanations - you shouldn't use it just because you shouldn't.
It's difficult to read code containing breaks to a label. Also, a label can be accidentally moved, or code inserted at an incorrect location with respect to a label. The compiler is not able to warn you of these effects since the code remains syntactically valid.
Code that's difficult to read is difficult to maintain. Bugs will inevitably creep in.
Other control structures (break, continue, while, for, etc.) don't suffer from this.
Note that a switch to a label doesn't suffer from these effects either: the structure of a switch block is well-defined.
The most sensible alternative to breaking out of a nested loop is to recast the code to a function and use return. You also get the added benefit of being able (potentially) to return a value back to the caller.
I think that you are referring to break and continue labeled.
The problem is that labeled break (and continue) is a construct of imperative languages that is absolutely not related to Object Oriented.
In Object Oriented programs the flows can be easily understood. It is not possible to jump from a part of code to another part of code, you can only call a method or continue current code or exit the current block of code.
Jumping from position to position is a probable point of break for your application where bugs can easily happens. Jumping creates what is called spaghetti code
Labelled breaks (and breaks, in a smaller way) are a more-modern equivalent to the old GOTO statements of older languages (FORTRAN, COBOL, Basic). Goto statements were found to be much more liable to contain an error than all other kinds of statements combined -- the study I'm remembering measured it as 9 times more likely. This gave rise to the "structured programming" movement in the 70s, and the banning of the goto statement from some software shops at the time.
It is more important to be able to read code easily than to be able to write it without restrictions.
Labels are fine to break out of nested for-loops. I'd suggest to put the nested loops in a separate method and then break out with return.
The problem is that the complex flows of processing becomes really hard to follow.

Use case modelling for calculator

i need help modelling a use case diagram from a topic, it will be in java GUI
Design a Calculator that
1.Allow user to key in a legitimate arithmetic statement that involves number, operator +, - and bracket '(' and ')' ;
2.When user press “Calculate” button, display result;
3.Some legitimate statement would be ((3+2)-4+2) (equals 3) and (-2+3)-(3-1) (equals -1);
4.You should NOT use a pre-existing function that just take in the statement as a parameter and returns the result but you should write the logic of parsing every character in your code.
5.Store the last statement and answer so it is displayed when user press the “Last calculation” button.
i have designed two use case diagrams using UML on netbeans 6.5.1, one of the use case i am not sure whether is it containing too much use cases etc, while the other is what i think could be too vague for the topic.i hope to get some feedback on whether the use case diagram are appropriate, thanks.i included a what it would be like in GUI
First thing you must know about use case diagrams is that its supposed to describe functionality of a system for which actor. It should be on such a high level that anyone without knowledge of programming can understand it. As a programmer, use cases might look very vague to you but thats fine. Its not supposed to say anything about the system, just what it can do.
Some more specific comments:
As i mentioned use cases should describe high level functions. Press Calculate is not a function, Calculate is. Press Last Calculation should be Store Last Calculation, etc
Its not clear what Press Backspace does. Backspace is just a key, not a use case.
The ParserSys package tries to describe internals of a system. This does not belong in a use case diagram. Other diagrams should be used for this.
Use case Store Result (first pic) should not be in this diagram. But if thats something User can do, it should be associated with User.
Edit:
..i believe the main problem is i am having trouble identifying use case..
A good way of identifying use cases is as simple as asking yourself the question: "[Actor] should be able to [what]" (or something similar). [What] is then your use case. If it doesn't fit in this sentence, its probably not a use case.
In the second use case diagram, you have user having use cases based on the sequence of actions performed to implement the use cases in the first. These would be better represented as either an activity diagram or state machine - the user cares about getting the results of a calculation, and it is incidental that to get these results expressions need to be keyed in buttons need to be pressed. When creating use cases concentrate on the goals that the originator of the use case has, rather than how the system might help them achieve these goals .
On another point, the spec you give says nothing about simulating a keyboard using a Java GUI, or a backspace key as in your mock-up. Check with the stakeholders whether 'allow the user to key in' just means giving them somewhere to type, or providing an on-screen keypad.

Categories

Resources