The following flowchart:
may be described by the following java code:
if (A == 1 && B ==1){
actionA();
}
if (B == 3 || (B == 1 && A == 2)){
actionB();
actionC();
}
if (B == 2){
actionC();
}
Is there a better way to translate a flowchart in java code? I am looking for some sort of general pattern to do this. My question arises from the fact that adding a single condition to the flowchart results in very significant changes to the code.
You could encapsulate ActionB and ActionC, while ActionC is being called after ActionB in ActionBC and make a new method for each cell in your flow chart. In general you should get something like:
void B1(){
if(B==1)
A1();
if (B==2)
actionC();
...
}
void A1(){
if(A1==2)
actionBC();
}
private void actionBC(){...}
And so on... In that way, expanding your flowchart won't explode you code.
This looks like a graph structure, each vertex is a condition or an action.
Finding the action will just be to follow the path given by the values of the conditions.
I'm using www.browxy.com to generate flowchart from code and vice-versa. There is a new feature to draw flawcharts that is activated with the button: "switch workspace"
Related
I'm creating an application which updates users on the score of a football match either in real time or as a final result. At least one score must be inputted in order for the TextView to be updated and the relevant score to be displayed. I'm checking that at least 1 of a pair of EditText fields is not empty using the following code:
if(!(et_current.getText().toString().isEmpty())||(!(et_final.getText().toString().isEmpty()))
&& (!(et_current2.getText().toString().isEmpty())||(!(et_final2.getText().toString().isEmpty()))){
if(!(et_final.getText().toString().isEmpty()))
tv_final.setText(et_final.getText().toString());
else
tv_current.setText(et_current.getText().toString());
if(!(et_final2.getText().toString().isEmpty()))
tv_final2.setText(et_final2.getText().toString());
else
tv_current2.setText(et_current2.getText().toString());
}
I want to be able to set the correct TextView so I have another if statement inside the original if statement to see ensure the correct score is being updated.
When I run the code, I do not seem to be getting past the first if statement. Am I using the correct format or is there an better way to complete these checks?
Thanks!
For readabilities sake, get some variables going
boolean currentEmpty = et_current.getText().toString().isEmpty();
boolean current2Empty = et_current2.getText().toString().isEmpty();
boolean finalEmpty = et_final.getText().toString().isEmpty();
boolean final2Empty = et_final2.getText().toString().isEmpty();
And then your code can be much cleaner. Something like
if( (!currentEmpty || !finalEmpty) || (!current2Empty || !final2Empty)) {
if(finalEmpty) {
tv_current.setText(et_current.getText());
}
else {
tv_final.setText(et_final.getText());
}
if(final2Empty) {
tv_current2.setText(et_current2.getText());
}
else {
tv_final2.setText(et_final2.getText());
}
}
I'm not sure if that is completely correct as the requirement is not entirely clear to me, but it should atleast be a good start to follow what's going on.
I have looked at other do while issues on StackOverflow, but I could not find the solution to my issue. I have variables initialized outside the do{ and they are being use within, but when the variables reach a certain value, the while method does not jump out.
Here is what I have:
int aiShotHit = 0;
int shotHit = 0;
do{
showBoard(board);
bAi.showAi(ai);
shoot(shoot,ships);
bAi.aiHit(aiShoot);
attempts++;
if(hit(shoot,ships)){
hint(shoot,ships,aiShips,attempts);
shotHit++;
System.out.println("\nShips Left on the Board: " + shotHit);
}
else
hint(shoot,ships,aiShips,attempts);
changeboard(shoot,ships,board);
if(bAi.aiHit(aiShoot,aiShips)){
hint(shoot,ships,aiShips,attempts);
aiShotHit++;
}
else
System.out.print("");
bAi.changeAi(aiShoot,aiShips,ai);
}while(shotHit !=3 || aiShotHit !=3);
if (shotHit == 3){
System.out.println("\n\n\nBattleship Java game finished! You Beat the Computer");
}
System.out.print("You lost! The Ai beat you");
You probably started out by saying, I want this to loop until shotHit is 3 or until aiHShotHit is 3.
That would be
while (!(shotHit == 3 || aiShotHit == 3));
which is "loop while it is not the case that either shotHit or aiShotHit contains the value 3", but it's kind of ugly so you wanted to apply the negation operator to each subexpression and get rid of some parens. The mistake was thinking you can move the negation operator without changing anything else to get
while (shotHit != 3 || aiShotHit != 3);
This exits the loop only in the event that shotHit is 3 at the same time that aiShotHit is 3. Not what you want.
The correct transformation is
while (shotHit != 3 && aiShotHit != 3);
This much was covered in the comments. The guidelines for how to safely transform this kind of expression are De Morgan's rules, which describe how to transform conjunctions and disjunctions in terms of each other. Following those rules lets you can move the negation operator and change the parenthesization without changing the meaning of the expression:
"not (A or B)" is the same as "(not A) and (not B)"
"not (A and B)" is the same as "(not A) or (not B)"
Needing to reorganize an expression to make it more readable comes up a lot in programming and this is a tool you need in order to do it safely. If you want to know more about De Morgan's rules you might want to read this answer.
Okay, I'm making this new game in Java. This might be a simple question, but can anyone please help me with this?
So, if the "Guy" collides with the platforms, he can't move right (obviously).
This is what I got:
if(Guy.x + Guy.width == (platform2.x ^ platform3.x)) {} else{
goRight();
}
The "^" is supposed to be "or".
I have a void called goRight();
so it would be like "if Guy's x plus Guy's width is the same as platform2 or platform3's x then go right. I don't want to have to do this:
if(Guy.x + Guy.width == platform2.x || Guy.x + Guy.width == platform3.x)) {} else{
goRight();
}
And plus, I have like 20 more platforms so it would be easier the first way if it's possible.
And I have to make the left collision detection too.
You will have to repeat the conditions.
One (better) solution would be to create a collection with your x variables and using the .contains() method on it. That would make your code a lot more readable.
Alternatively, put all your platforms in a collection, loop over it and check each value's x variable.
You need some more advanced structures to store information about your platforms. Consider having a Set of the x-coordinates of your platforms and performing the operation 'contains`
for example:
Set<Integer> xcoords = new HashSet<Integer>();
xcoords.add(platform2.x);
xcoords.add(platform3.x);
if (xcoords.contains(Guy.x + Guy.width)){
} else {
goRight();
}
If Platform is a class that has an x value, then I'd suggest putting put all of your platforms into a collection of some kind and iterating over it. Inside a loop, do something like
for(Platform p: platforms){
if(Guy.getX() + Guy.getWidth() == p.getX()){
//whatever
}else{
goRight()
}
}
That's the way the language is designed... So it is useless to fight against it.
All you can do is use auxiliary variables to shorten the expressions. But you will always have to right something like if(a == b || a == c).
New programmer here, writing a Tictactoe game using Java on Eclipse.
I have problems with my win conditions I think. It comes up with the error:
Exception in thread "main" java.lang.NullPointerException
at Game.NoughtsCrosses.(NoughtsCrosses.java:106)
at Game.Main.main(Main.java:5)
Here is my win conditions bit. It's not well made imo, but I'm having problems when compiling. Can anyone spot why? Ty!!
I have squares set up in a 3x3 grid, 0 -> 8. Each button has its own text which is set to X or O when clicked by each player.
winconditions code:
if (square[0].getText().equals(square[1].getText()) && square[1].getText().equals(square[2].getText()) != square[0].getText().isEmpty()) {
win = true;
}
Full Pastebin of code
Thanks again :) Any questions, I can elaborate :D
It looks like one of the squares text is null. One thing that is important to remember is that an empty string is not the same thing as null. In java, if you haven't specifically assigned a value to a String then it will be null. To fix this, you will want to explicitly set each squares text to "" (an empty string) when you set up your game board.
Well I took the code that you provided and after significant finagling was able to make a fully functioning Tic-Tac-Toe game. You were mostly on the right track with what you were doing you just needed to first begin with a design.
In my NoughtsCrosses class I have the following:
class Action implements ActionListener
This has a JButton attribute that I pass in through a constructor
In the actionPerformed
set the text
disable the button
increment the counter
check if someone wins
If there is a winner or draw game ends set the "Play again?" text
else call the changeTurn function
class Reset implements ActionListenter
This has a JButton attribute that I pass in through a constructor
In the actionPerformed
I call the resetGame function
function changeTurn
function resetGame
function checkForWinners
as a hint, this is my implementation of the Action class and an example of the constructor I mentioned
class Action implements ActionListener{
private JButton button;
public Action(JButton button){
this.button = button;
}
public void actionPerformed(ActionEvent e) {
button.setText(letter);
button.setEnabled(false);
counter++;
boolean gameOver = checkForWinners();
if(!gameOver)
changeTurn();
else{
newgame.setText("Play again?");
newgame.addActionListener(resetButton);
}
}
}
a call like new Action(square[i]) is what you need to make this work.
Note: the resetButton is of the Reset class I mention above much like the Action class it has the same construct that I passed newgame into.
It seems like your win-condition check is not within your actionPerformed code, but on the class level, hence it is possibly called before the window is populated with your buttons.
Try placing the check inside the actionPerformed like this: http://pastebin.com/xRViSUzy
What is the scope (most simply, which curly braces) is the problematic line inside of?
It was a bit tricky to tell based on your indentation, but it appears to me that your "if" was not inside a method (e.g. the constructor). I would guess that you intended this line and the ones around them to be executed after the lines in the body of your constructor where the squares are initialized. Instead, these lines are being run beforehand and therefore the call to "new" haven't been run yet.
I think that if you do some restructuring to move these conditions into your constructor or into another method that you call after construction then things will look a lot better.
Hope that helps.
If you're going to implement this type of solution, then simplify the job for yourself. Based on the tiny snippet of code I see above, it looks like you're really over-complicating the job you have to do.
char cell0 = //get that char, be it X or O
char cell1 = //
...
char cell8 = //
Now you can compare cells one by one to determine a victory. Your board game is set up as follows:
0 1 2
3 4 5
6 7 8
So you can just go in order:
Horizontal Solutions:
(cell0 == cell1 && cell0 == cell2)
(cell3 == cell4 && cell3 == cell5)
(cell6 == cell7 && cell6 == cell8)
Vertical Solutions
(cell0 == cell3 && cell0 == cell6)
//And so on
Cross Solutions:
(cell0 == cell4 && cell0 == cell8)
(cell2 == cell4 && cell2 == cell6)
This will check for your victory conditon.
The problem is that you have a surplus of braces in your code so that the statements in the question actually appear in an instance initializer block of the class NoughtsCrosses but none of the JButton components have been initialized yet as instance initializers are invoked before constructors which is where the JButton instantiated exist (but never called). When you attempt to invoke getText on the first element of the array square, a
NullPointerException is thrown.
To fix remove the additional braces to that the code is enclosed in the preceding ActionListener
class Action implements ActionListener {
public void actionPerformed(ActionEvent e) {
// existing code here
/// } remove
//} remove
// { remove
// win conditions. if true, set win==true; else set win
// here is where the compilation error is, next line
if (square[0].getText() == square[1].getText() ...) {
win = true;
} //etc
} <-- add this
I'm getting some peculiar output from a program in which I have a few if statements like this:
if((m.getLeft(position).state == position.state.wall || m.getLeft(position).state == position.state.border)
&& (m.getBelow(position).state == position.state.open || m.getBelow(position).state == position.state.visited)){
check = true;
}
where I have both && and || used in the same if condition. I want the boolean check to be made true if the cell at getLeft() is either a wall or a border AND the cell at getBelow() is either open or visited.
Does this code, the way I have it written now, perform this check properly? Perhaps more importantly, is it poor form to write a statement like this? Would it be better to break it up into two statements?
I'm not sure whether the peculiarities I'm seeing are resulting from these statements or something else, my question is more about general best practices.
EDIT: Thanks for all the input. I suspected as much (that it was too complicated), which was why I framed my question the way I did.
EDIT (a year later, looking back) (to restate the above more strenuously) for the love of god, don't write anything like the if statement above. If you find yourself with a similar line of code, remember occam's razor is perhaps nowhere more applicable than in programming.
Your complicated if statement can be refactored as:
if((m.getLeft(position).state == position.state.wall || m.getLeft(position).state == position.state.border)) {
if((m.getBelow(position).state == position.state.open || m.getBelow(position).state == position.state.visited)){
check = true;
}
}
Thanks to #Makoto:
check = ((m.getLeft(position).state == position.state.wall || m.getLeft(position).state == position.state.border)) && ((m.getBelow(position).state == position.state.open || m.getBelow(position).state == position.state.visited));
And your code, as well as this code "works".
But also, remember, stick to a naming convention that is mentioned in Java's Style Guidelines. I have no idea what m in your code is. This kind of naming an object reference must be avoided. Also, state seems to be a public field in your class (assuming). Such public access fields should also be avoided. Instead use getters() and setters().
It looks to me that it performs properly, however it is rather difficult to read.
If you're going to be using an && in an if statement, you may as well nest a new if statement instead, it is essentially the same thing in most cases.
Breaking down your boolean statement, it reads something like this:
(a == x_1 || a == x_2) && (b == x_3 || b == x_4)
Unfortunately, that's about as simple as that particular boolean statement will get. There are options to make the pain a lot easier:
Refactor your code to not need such complex statements, by breaking it up into two if-blocks (as shown in my refactor below), or
Extract that as a method and assign the return value to check. Honestly, it's either going to be true or false.
Here's an example of the refactor method. I don't know what m is precisely:
public boolean isCheck(M m, Position p) {
boolean retVal = false;
if(m.getLeft(p).state == p.state.wall || m.getLeft(p).state == p.state.border)) {
if((m.getBelow(p).state == p.state.open || m.getBelow(p).state == p.state.visited))
retVal = true;
}
}
return retVal;
}
// call it as such
check = isCheck(m, position);
Use another IF insted of using &&:
if(m.getLeft(position).state == position.state.wall ||
m.getLeft(position).state == position.state.border){
if(m.getBelow(position).state == position.state.open ||
m.getBelow(position).state == position.state.visited){
check = true;
}
}