Game logic issue - java

i am making a noughts and crosses game (tic tac toe) and in my logic class i represent the state of the game with a 2d array, but this is the problem, im checking the array like so
if(gameModel[0][0] == gameModel[1][1] && gameModel[0][0] == gameModel[2][2]){
return true;
}
if(gameModel[2][0] == gameModel[1][1] && gameModel[2][0] == gameModel[0][2]){
return true;
}
and so on for all 8 conditions, however, the array is initialised with all values of 0 at the beginning, so it always finds three matching values, how can i get round this problem without having to change the whole of my code
thanks

In that case you just have to add a check if a value is set:
if ( gameModel[0][0] == gameModel[1][1]
&& gameModel[0][0] == gameModel[2][2]
&& gameModel[0][0] != 0) {
return true;
}

One thing that jumps out at me with this is... why are you using ints instead of a class to represent this? True this is a simple game, but a Piece class seems to jump out as a fairly obvious class to have.
Also, with int you really have 3 states, presumably something like:
0 = empty
1 = X
2 = Y
So you should check for 0 (empty) before bothering to check for if they are the same value, it will be quicker (who really cares though, this doesn't need to be fast), and make more logical sense (is the square empty? if so then do not bother checking if the squares hold the same values).
Even for simple things like this, especially when you are just starting out, try to embrace OOP, it is a different way of thinking, and it takes practice, so practice as much as you can!

Related

How to make battleship boat spawner in java?

Essentially, it is my big grade 12 code project in java to make a battleship. I have most of the mechanics finished I just am struggling with a random boat generator. It seems to almost work sometimes with variation in sizes, however, I often find random clumps that do not resemble the boats I want. Basically, each spot on a 2d grid is an object that has an int variable named status. If status=0, it is a water spot. if status=1, it is a boat spot. Any errors in my code or is there possibly a better way? Thank you for the help I really appreciate it :)
Haven't done any other method because nothing else has come to my head.
void addBoat(int x) {
int c=floor(random(4));//picks a random direction
int tx, ty;//target location in array
tx=floor(random(xs));//xs is x size of the array
ty=floor(random(ys));//ys is the y size of the array
for (int i=0; i<x; i++) {
//paramaters for conditions
if (c==0 && tx>=x-1 && sqr[tx-i][ty].status==0) {
sqr[tx-i][ty].status=1; //to the left of the target block, status is whether it is water or boat. water is status=0, boat is status=1.
} else if (c==1 && tx<=xs-x && sqr[tx+i][ty].status==0) {
sqr[tx+i][ty].status=1; //to the right of the target block
} else if (c==2 && ty>=x-1 && sqr[tx][ty-i].status==0) {
sqr[tx][ty-i].status=1; //above the target block
} else if (c==3 && ty<=ys-x && sqr[tx][ty+i].status==0) {
sqr[tx][ty+i].status=1; //below the target block
} else {
c=floor(random(4));
i=0;
//if position is not possible, run again
}
}
}
void makeBoat() {
addBoat(2);
addBoat(3);
addBoat(3);
addBoat(4);
addBoat(5);
}
I want boats to be the proper size and either vertical or horizontal, however I usually just get strange clumps.
It seems to me like you are placing your boat pieces before checking whether your boat can be fully placed. The moment it detects it can't properly place the boat it starts over without deleting the already generated pieces. Another thing is that you don't seem to have anything in place for the case that it is impossible to place a boat at a chosen starting position, at which point it probably runs into an infinite loop.
All in all, I'd recommend you to first generate a set of a position, a direction and a length, then check whether this is a valid boat placement and only then place it (or generate a new set), i.e. split it up into three methods. There's still a slim chance of infinite loops if boats are generated such that it is impossible to place the next one so you may want to have some checks in place to prevent that (maybe deleting the state completely and starting over if it does >10,000 attempts for a single boat or something).
You should also use enums instead of integers for your states/directions to make it more readable. You could also use boolean values for your states if they only store whether there's water or a boat.

Java search a string for a substring UNLESS preceded by specific character

I'm attempting to write a Java program that searches for a specific substring (xyz) within a user-entered string, and keeping a running count, unless that substring is preceded by a period. At this point in the class, we've only used charAt and length, so if possible I need to stick to that. Additionally, we haven't used regular expressions at all, so that's out the window too.
I've managed to get the program working as desired, with one notable exception: if the String entered begins with a period, it fails to count any successive matches. This is what I've got so far:
System.out.println("Give me a String:");
String s1 = kb.nextLine();
int index = 0;
int count = 0;
while(index <= s1.length() - 1 && s1.charAt(index) != '.')
{
if(s1.charAt(index) == 'x' && s1.charAt(index + 2) == 'z')
{
count++;
}
index++;
}
System.out.println(count);
You can simply check the input string whether it starts with period. If so then you can use the following piece of code to handle the validation.
if(s1.charAt(0)!='.')
{
while(index <= s1.length() - 1 && s1.charAt(index) != '.')
{
if(s1.charAt(index) == 'x' && s1.charAt(index + 2) == 'z')
{
count++;
}
index++;
}
}
else
{
index=1;
while(index <= s1.length() - 1 && s1.charAt(index) != '.')
{
if(s1.charAt(index) == 'x' && s1.charAt(index + 2) == 'z')
{
count++;
}
index++;
}
}
System.out.println(count);
}
As this seems like a homework type of question I will attempt to guide you in the right direction first and provide a solution at a later time. I strongly encourage you to work through the problem on your own first to the best of your ability before you look at my solution (once I post it) and to read this page before going ANY further
First, consider the kinds of inputs you could receive. Since you didn't specify any limitations you could get things like:
"" (empty string)
"\n" (whitespace)
"x" (a single character)
"xx" (two characters string)
"abc" (string of correct length, but not containing your substring)
".xyz" (the substring to be ignored)
I could go on, but I'm sure you can come up with all the various combinations of weird things you might receive. These are just a few examples to get you started (along with those I posted in the comments already)
Next, think about what you need your algorithm to do. As I said in the comments it sounds like you want to count the occurrences of the substring "xyz" while ignoring the occurrences of the substring ".xyz". Now consider how you're going to look for these substrings - you're going to advance one character at a time from left to right across the String looking for a substring that matches one of these two possibilities. When you find one of them you'll either ignore it or count it.
Hopefully this helps and as I said, I will post a solution later after you've had some time to wrestle with the code. If you do solve it go ahead and post your solution (maybe edit your question to add the new code or add an answer) Finally I once again strongly urge you to read this page if you have not already.
EDIT #1:
I wanted to add a little more information and that is: you already have a pretty good idea of what you need to do in order to count your "xyz" substring at this point - despite the small flaw in the logic for inputs like "xaz", which is easily fixable. What you need to focus on is how to ignore the substring ".xyz" so think about how you could implement the ignore logic, what does it mean to ignore it? Once you answer that it should start coming together for you.
EDIT #2:
Below you will find my solution to the problem. Once again it's important to understand how the solution works not just copy and paste it. If you simply copy my code without understanding it you're cheating yourself out of the education that you're trying to gain. I don't have time at the moment to describe in detail why and how this code works, but I do plan to edit again later to add those details.
import java.util.Scanner;
public class Main {
private static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Give me a String:");
String s1 = scan.nextLine();
System.out.println(countSubstrings(s1));
}
public static int countSubstrings(String s1){
int index = 0;
int count = 0;
while (index < s1.length()-2) {
if(s1.charAt(index) == '.' && s1.charAt(index+1) != '.'){
index++;
}
else if (index+2 < s1.length() && s1.charAt(index) == 'x' && s1.charAt(index + 1) == 'y'
&& s1.charAt(index + 2) == 'z') {
count++;
index+=2;
}
index++;
}
return count;
}
}
EDIT #3:
Here is the nuts and bolts of why the above code does what it does. First, we think about the fact that we're looking for 3 items (a triple) in a specific order within an array and if we see a fourth item (a period) immediately preceding the first item of the triple then we need to ignore the triple.
Per my previous edit we need to define what it means to ignore. In this case what we mean is to simply not count it and move on with our search for valid substrings to count. The simplest way to do that is to advance the index without incrementing the count.
So, ask yourself the following:
When should my loop stop? Since we're looking for triples we know we can stop if the length of the input String is less than 3 or when there are less than 3 characters left in the String that we have not examined yet. For example if the input is "xyzab" by the time we get to index 3 we know there's no possible way to form a triple where "a" is the first character in the triple and that therefore our counting is done.
Is there ever a time when I would not want to skip the next 3 characters after a period? After all the goal is to look for triples so wouldn't I want to skip 3 characters not just 1? Yes there is a time when you do NOT want to skip 3 characters and that's when you have something like ".axyz" because a valid triple could start as soon as the 2nd character past the period. So in fact you want to skip only 1 character.
This, and the fact that index is always incremented by 1 at the end of the loop (more on this later), is why the first condition inside the while only advances the index by 1:
if(s1.charAt(index) == '.' && s1.charAt(index+1) != '.'){
index++;
}
Is there ever a time when I would see a period and not wish to ignore (skip) the next character? Yes, when the next character is another period because it could indicate that another triple needs to be skipped. Consider the input "..xyz" which would result in a wrong answer if you encounter the first period and skip the second period since your algorithm could see the next three characters as a valid triple but in fact it is invalid because of the second period.
This is why the second half of the above condition exists:
`&& s1.charAt(index+1) != '.'`
Now ask yourself how to identify a valid triple. I'm sure by now you can see how to do this - check the current character, the next character, and the character after that for the values you want. This logic is the latter portion of the second if condition within the while:
s1.charAt(index) == 'x' && s1.charAt(index + 1) == 'y'
&& s1.charAt(index + 2) == 'z'
Whenever you're using calculations like index +1 or index +2 inside of a loop that is incrementing the index until it reaches a boundary you have to consider the possibility that your calculation will exceed the boundary because you can't rely on the loop to check this for you as the loop will not perform that check until either the end or beginning of the loop (depending on which kind of loop it is)
Considering the above you must ask yourself: How do I prevent out of boundary scenarios when I use these index+1, index+2, etc types of calculations? The answer is to add another piece to your condition:
index+2 < s1.length()
You may be wondering - why not add two checks since we're using index+1 and index+2? We only need one check to see if the greatest index we use will exceed the boundary in this case. If index +2 is beyond the bounds we don't care if index+1 is or is not because it won't matter we can't possibly have a matching substring.
Next, inside of the second if inside the while you see there is code to increment the index by 2: index+=2; This is done for efficiency since once we have identified a triple we know there is no way to form another triple with characters that are already part of another triple. Therefore we want to skip over them and just like the first bullet point we take advantage of the loop incrementing the index so we only need to increment by 2 and let the loop add the extra 1 later.
Finally we reach the end of the logic within the loop. This part you're already familiar with and that's the index++; which simply increments the position within the String that we're currently examining. Note that this works in tandem with the first bullet point. Take the example from the first bullet point of ".axyz". There is a period in index 0 and the character in index 1 is not another period so the logic from the first bullet point will increment index by 1, making it 1. At the end of the loop index is incremented again making it 2 thereby skipping over the period - at the start of the next loop index is 2, it was never 1 at the start of the loop.
Well, I hope this helps to explain how it all works and illustrate how to think about these sorts of problems. The basic principle is to visualize where your current element is and how you can use that to achieve your goal. At the same time think about what kinds of properties the different elements of your program have and how you can take advantage of them - such as the fact that once you identify a triple it is safe to skip over those characters because they have the property of only being usable once. As with any program you always want to try to create as many test inputs as you can to test all the weird boundary cases that might occur to ensure the correctness of your code. I realize you probably are not familiar with JUnit but it is a very useful tool and you might try researching the basics of using it when you have a little spare time, and the bonus is that if you use the Eclipse IDE it has integrated JUnit functionality you can use.

How to check both conditions met at the same time

I'm extremely new to Java, and I'm currently using a Jar allowing the use of some 'Robots learning system'. However, there's one problem I've encountered.
while(robot.getX()!=1 && robot.getY()!=5) {
// blah
}
Here, I want the robot to prefer blah while both the X isn't 1, and the Y isn't 5 at the same time. When I use it in the provided format, however, it will only do as I instruct while neither his X is 1 or Y is 5, which isn't what I desire.
How can I pull this off? I've tried looking around on the internet, not sure how well I did not knowing the most technical keywords, and in the back of my mind I couldn't think of any double-indented if situation where it'd do as I wish. How can I do this?
Your condition becomes false as soon as either of its two parts becomes false. You need to invert the whole AND, like this:
while(!(robot.getX()==1 && robot.getY()==5))
...
or use an OR, like this:
while(robot.getX()!=1 || robot.getY()!=5)
...
(both loops use the same logical condition transformed using De Morgan's Law).
Use
while (!(X == 1 && Y == 5)) {
blah
}

Java boolean int comparable

hi can anyone tell me why this isn't working or point me in the right direction all i am trying to do is take a users input of 3 numbers compare them if they are the same which would be 3 of a kind or whether they are all different which would make it all different or if it is a run of 1 2 3 etc
error code i get is incomparable types boolean and int
public boolean different() {
do {
System.out.println ("All results are different" + "\n" + rollone + "\n" +
rolltwo + "\n" + rollthree);
}
while (rollone != rolltwo && != rollthree) ;
}
any ideas much appreciated in advance
Probably the best way to do this would be a set of if statements. Usage of a do/while loop is a bit confusing in your example code. I would start by breaking up the logic into multiple parts. So for example: Let's say I want to know if a number is even or odd.
What would I normally do if I didn't know how to tell if a number was even or odd just by looking at it? Well, I know that any number that's a multiple of 2 is even. And anything that isn't is odd. How can I translate that into code?
if(x % 2 == 0) { return true; }
This is using the modulo operator. It's essentially, "Given that I have the number x, what remains if I divide it by 2?" If this is 0, x is divisible by 2. Ergo, even.
else { return false; }
If it's not even, it must be odd. Simple stuff.
Now for your problem, you've described a lot of use cases. I would say write down each use case and try to think of the logic in your mind of how -you- would manually do it. (i.e. Someone hands you 3 numbers on pieces of paper. How would determine if they were the same? If they were a run? If they had no relationship?) And then think of how you can apply that logic with if / else statements.
Good Luck.

Is it bad to explicitly compare against boolean constants e.g. if (b == false) in Java?

Is it bad to write:
if (b == false) //...
while (b != true) //...
Is it always better to instead write:
if (!b) //...
while (!b) //...
Presumably there is no difference in performance (or is there?), but how do you weigh the explicitness, the conciseness, the clarity, the readability, etc between the two?
Update
To limit the subjectivity, I'd also appreciate any quotes from authoritative coding style guidelines over which is always preferable or which to use when.
Note: the variable name b is just used as an example, ala foo and bar.
It's not necessarily bad, it's just superfluous. Also, the actual variable name weights a lot. I would prefer for example if (userIsAllowedToLogin) over if (b) or even worse if (flag).
As to the performance concern, the compiler optimizes it away at any way.
As to the authoritative sources, I can't find something explicitly in the Java Code Conventions as originally written by Sun, but at least Checkstyle has a SimplifyBooleanExpression module which would warn about that.
You should not use the first style. I have seen people use:
if ( b == true )
if ( b == false )
I personally find it hard to read but it is passable. However, a big problem I have with that style is that it leads to the incredibly counter-intuitive examples you showed:
if ( b != true )
if ( b != false )
That takes more effort on the part of the reader to determine the authors intent. Personally, I find including an explicit comparison to true or false to be redundant and thus harder to read, but that's me.
This is strongly a matter of taste.
Personally I've found that if (!a) { is a lot less readable (EDIT: to me) than if (a == false) { and hence more error prone when maintaining the code later, and I've converted to use the latter form.
Basically I dislike the choice of symbols for logic operations instead of words (C versus Pascal), because to me a = 10 and not b = 20 reads easier than a == 10 && !(b==20), but that is the way it is in Java.
Anybody who puts the "== false" approach down in favour of "!" clearly never had stared at code for too long and missed that exclamation mark. Yes you can get code-blind.
The overriding reason why you shouldn't use the first style is because both of these are valid:
if (b = false) //...
while (b = true) //...
That is, if you accidentally leave out one character, you create an assignment instead of a comparison. An assignment expression evaluates to the value that was assigned, so the first statement above assigns the value false to b and evaluates to false. The second assigns true to b, so it always evaluates to true, no matter what you do with b inside the loop.
I've never seen the former except in code written by beginners; it's always the latter, and I don't think anyone is really confused by it. On the other hand, I think
int x;
...
if(x) //...
vs
if(x != 0) //...
is much more debatable, and in that case I do prefer the second
IMHO, I think if you just make the bool variable names prepended with "Is", it will be self evident and more meaningful and then, you can remove the explicit comparison with true or false
Example:
isEdited // use IsEdited in case of property names
isAuthorized // use IsAuthorized in case of property names
etc
I prefer the first, because it's clearer. The machine can read either equally well, but I try to write code for other people to read, not just the machine.
In my opinion it is simply annoying. Not something I would cause a ruckus over though.
The normal guideline is to never test against boolean. Some argue that the additional verbosity adds to clarity. The added code may help some people, but every reader will need to read more code.
This morning, I have lost 1/2 hour to find a bug. The code was
if ( !strcmp(runway_in_use,"CLOSED") == IPAS_FALSE)
printf(" ACTIVE FALSE \n"); else
printf(" ACTIVE TRUE \n");
If it was coded with normal convention, I would have seen a lot faster that it was wrong:
if (strcmp(runway_in_use, "CLOSED"))
printf(" ACTIVE FALSE \n"); else
printf(" ACTIVE TRUE \n");
I prefer the long approach, but I compare using == instead of != 99% of time.
I know this question is about Java, but I often switch between languages, and in C#, for instance, comparing with (for isntance) == false can help when dealing with nullable bool types. So I got this habbit of comparing with true or false but using the == operator.
I do these:
if(isSomething == false) or if(isSomething == true)
but I hate these:
if(isSomething != false) or if(isSomething != true)
for obvious readability reasons!
As long as you keep your code readable, it will not matter.
Personally, I would refactor the code so I am not using a negative test. for example.
if (b == false) {
// false
} else {
// true
}
or
boolean b = false;
while(b == false) {
if (condition)
b = true;
}
IMHO, In 90% of cases, code can be refactored so the negative test is not required.
This is my first answer on StackOverflow so be nice...
Recently while refactoring I noticed that 2 blocks of code had almost the exact same code but one used had
for (Alert alert : alerts) {
Long currentId = alert.getUserId();
if (vipList.contains(currentId)) {
customersToNotify.add(alert);
if (customersToNotify.size() == maxAlerts) {
break;
}
}
}
and the other had
for (Alert alert : alerts) {
Long currentId = alert.getUserId();
if (!vipList.contains(currentId)) {
customersToNotify.add(alert);
if (customersToNotify.size() == maxAlerts) {
break;
}
}
}
so in this case it made sense to create a method which worked for both conditions like this using boolean == condition to flip the meaning
private void appendCustomersToNotify(List<Alert> alerts
List<Alert> customersToNotify, List<Long> vipList, boolean vip){
for (Alert alert : alerts) {
Long currentId = alertItem.getUserId();
if (vip == vipList.contains(currentId)) {
customersToNotify.add(alertItem);
if (customersToNotify.size() == maxAlerts) {
break;
}
}
}
}
I would say it is bad.
while (!b) {
// do something
}
reads much better than
while (b != true) {
// do something
}
One of the reasons the first one (b==false) is frowned upon is that beginners often do not realize that the second alternative (!b) is possible at all. So using the first form may point at a misconception with boolean expressions and boolean variables. This way, using the second form has become some kind of a sjiboleth: when someone writes this, he/she probably understands what's going on.
I believe that this has caused the difference to be considered more important than it really is.
While both are valid, to me the first feels like a type error.
To me b == false looks as wrong as (i == 0) == false. It is like: huh?
Booleans are not an enum with 2 possible values. You don't compare them. Boolean are predicates and represent some truth. They have specific operators like &, |, ^, !.
To reverse the truth of an expression use the operator '!', pronounch it as "not".
With proper naming, it becomes natural: !isEmpty reads "not is empty", quite readable to me.
While isEmpty == false reads something like "it is false that it is empty", which I need more time to process.
I won't go into all of the details at length because many people have already answered correctly.
Functionality-wise, it gives the same result.
As far as styling goes, it's a matter of preference, but I do believe !condition to be more readable.
For the performance argument, I have seen many say that it makes no difference, but they have nothing to justify their claims. Let's go just a bit deeper into that one. So what happens when you compare them?
First, logically:
if(condition == false)
In this case, if is comparing its desired value to execute with the value between the parentheses, which has to be computed.
if(!condition)
In this case, if is directly compared to the opposite(NOT) of the condition. So instead of 2 comparisons, it is one comparison and 1 NOT operation, which is faster.
I wouldn't just say this without having tested it of course. Here is a quick screenshot of the test I did. !condition is nearly twice as fast over 10 million iterations.
https://imgur.com/a/jrPVKMw
EDIT: I tested this in C#, compiled with visual studio. Some compilers may be smarter and optimize it properly, which would make the performance the same.

Categories

Resources