I have been googling for two days now, but can't figure this out and it seems to be basic.
Within the void OnTick(), I would like to create a variable int a;. Lets say it starts out with no value int a;, then I test condition if a is NULL or || equals 1 like this if (a == NULL || a == 1) which should always return true the first time the if statement runs due to NULL. I then assign a value to the variable a = 0;, so now a should equal 0.
This should trigger the else if(a == 0) the next time OnTick() is called, at this point I assign a = 1; resulting in the if being triggered next time round, etc and infinitum, constantly checking and assigning values switching between 0 and 1.
void OnTick()
int a;
if (PositionsTotal() < 1)
{
if(a == NULL || a == 1)
{
a = 0;
}
else if(a == 0)
{
a = 1;
}
}
I do not know what is going on, but during Testing in Strategy tester, I am getting a long string of numbers which switches between negatives and positives always with the same number -123456789 or 123456789, always 9 digits long.
Or during Debugging from Meta Editor. A random positive 3 digit number which never changes!
So far I have had both 303 and 597.
Beyond frustrating and most likely answered somewhere else.
Just not sure how to phrase the search term.
Thanks for you help.
I think the problem is that you declare your variable a inside the method OnTick, so it starts with an arbitrary value every time you call this method. Try declaring it outside this method.
Related
I'm working through a practice problem for one of my classes and I'm having a bit of trouble with part of the prompt.
We need to:
Write code to go through number -20 - 20 (but skip 5-15 inclusively)
If the number is negative, the line should start with an "*"
If the number is divisible by 2, add "#" to the end of the current line
If the number is divisible by 3, add "!" to the front of the line
If the previous line has both "!" and "#", then add "wow" to the end of the current line (Hint: use bool)
With the code I've written so far, I've managed to complete the first two tasks on the list, but I run into trouble starting with the third task. In my code I'm using
if (num%2==0)
{
Console.WriteLine(num+"#");
}
but all it's doing is outputting another number with "#" instead of putting "#" on the current line. How do I make it so "#" is appended to the end of the current line?
Here's my code for reference:
static void Main(string[] args)
{
int num = -20;
while (num <= 20)
{
if (num < 5 || num > 15)
{
if (num < 0)
{
Console.WriteLine("*" + num);
}
if (num%2==0)
{
Console.WriteLine(num+"#");
}
else
{
Console.WriteLine(num);
}
}
num++;
}
}
Since we are only working with the first 3 points in this question (try the other 2 yourself), I will only address those.
The main problem with the code is that it will always write the number more than once if more than one rule applies to it. There's 2 ways to tackle this. Also note I cleaned up the code a bit and I'll explain why later since it's secondary.
Fix
Method 1 : Incremental Writing
This method uses incremental writing to apply rules and then write a new line at the end before going to the next iteration.
// More succinct than a while loop for this particular scenario
for (int num = -20; num <=20; num++)
{
//Skip while avoiding nested if
if (num >= 5 && num <= 15)
continue;
//Since it needs to start with * in this case we prioritize it
if (num < 0)
Console.Write("*");
Console.Write(num);
// Since this would need to be appended at the end if it's true
if (num % 2 == 0)
Console.Write("#");
Console.Write(Environment.NewLine);
}
Method 2: Store the line then print before next iteration
In this case you would build the line that you want to print and then use one Console.WriteLine statement to write it while avoiding duplication. The writing would need to be done before moving to the next iteration.
You can use string concatenation instead of StringBuilder which would generally be more costly but in this case performance doesn't really matter (string are really small and amount of concatenation is minimal). However this would be a typical use case for a StringBuilder.
Also, since we know we know that we will always print out num when we aren't skipping then we can start off with num. But we could also do it like Method 1 where we add it in the middle. I'll illustrate both ways.
StringBuilder constructor with number
// More succinct than a while loop for this particular scenario
for (int num = -20; num <= 20; num++)
{
//Skip while avoiding nested if
if (num >= 5 && num <= 15)
continue;
// Create and update your string in a string builder, apply rules thereafter
// (this constructor usage means we don't need to add the number later)
var line = new StringBuilder(num.ToString());
//Since it needs to start with * in this case we prioritize it
if (num < 0)
line.Insert(0, "*");
// No need to add the number, already present
// Since this would need to be appended at the end if it's true
if (num % 2 == 0)
line.Append("#");
Console.WriteLine(line.ToString());
}
StringBuilder constructor without number
// More succinct than a while loop for this particular scenario
for (int num = -20; num <= 20; num++)
{
//Skip while avoiding nested if
if (num >= 5 && num <= 15)
continue;
// Create and update your string in a string builder, apply rules thereafter
// (this constructor usage means we must add the number later)
var line = new StringBuilder();
//Since it needs to start with * in this case we prioritize it
if (num < 0)
line.Append("*"); // NOTICE: This is now Append instead of Insert since line is empty
// Since we didn't add the number before
line.Append(num);
// Since this would need to be appended at the end if it's true
if (num % 2 == 0)
line.Append("#");
Console.WriteLine(line.ToString());
}
Additional Changes
for loop is better suited for this situation since you have an int with a clear start, end and an incrementor supported by the structure.
Avoid unnecessary nesting of conditions, common newbie mistake. If you have a condition to skip in certain cases, simply check and skip and otherwise the rest of the code will apply. This could otherwise lead to really annoying duplication and condition checks that are unnecessary (most of the time).
use string.concat but first save the string into variable and reach the end and finally do the concatenation
So the assignment is as follows: you can enter all sorts of numbers but when you enter 0 two times in a row it needs to stop. The first time you enter a number your not allowed to enter 0.
This is the code I have setup:
class MainClass
{
public static void Main (string[] args)
{
int givenNumber, prevNumber;
Console.WriteLine ("Enter a number: ");
int.TryParse (Console.ReadLine (), out givenNumber);
// I've set the prevNumber to givenNumber because the variable has to be initialized
// before I can use it in the condition below. I thought setting it to the giveNumber
// wouldn't harm. Note that the first time your not allowed to enter 0
prevNumber = givenNumber;
while (givenNumber != 0 && prevNumber != 0) {
prevNumber = givenNumber; //Here is where they both are 0 at a given moment, but only after the condition.
Console.WriteLine ("Enter a number: ");
int.TryParse (Console.ReadLine (), out givenNumber);
}
Console.WriteLine ("Tada");
}
}
The problem is that it already stops when you've only entered one 0. For example if I'd first enter a 7 to start with, and my next number would be 0. When I debug it it says that my givenNumber is 0 and prevNumber is 7, when it goes back to the while condition it stops and finishes. When the program finishes the debug clearly says prevNumber = 7 and givenNumber = 0. I am using the conditional AND correct am I not?
Any clue? I'm not allowed to use arrays for this matter.
Thanks in advance
Ooh, right, you've got the logic wrong. It should be this:
while ((givenNumber != 0) || (prevNumber != 0)) {
Look up DeMorgan's laws to see why...
Your problem is with your conditional statement.
Right now you're checking whether both the givenNumber and the PrevNumber DO NOT equal 0.
So, if neither of them equals 0 then the statement will evaluate to TRUE. However, if either one of the numbers is 0 then the statement will evaluate to FALSE, since (TRUE) && (FALSE) evaluates to FALSE.
There are two ways to fix this: You can either use || (the "OR" operator) with the two "!=" statements, or you can negate the whole thing and use regular equality rather than "!=" as such: !(givenNumber == 0 && prevNumber == 0)
while (givenNumber != 0 && prevNumber != 0)
For first read value from console - number 7
givenNumer will be 7
prevNumber will be 7 too (because of assignment prevNumber = givenNumber;)
Thus while (7 != 0 && 7 != 0) will pass
Second read from Console - number 0
Thus while (0 != 0 && 7 != 0) will not pass because 0 != 0 is FALSE and while loop ends if condition is result is FALSE
Relevant misc info:
Project = Tic Tac Toe (console app)
My issue is the following:
I have an array that initially is filled with 0's which MUST stay as 0's unless the user takes a move (then it'll become a 1) or the computer makes a move then it becomes a 2.
Example code:
else if (posStatus[2] != 0 && posStatus[5] != 0 && posStatus[8] != 0 && (posStatus[2] + posStatus[5] + posStatus[8] % 2 == 0))
{
if (posStatus[2] == 0)
{
posStatus[2] = 2;
return;
}
else if (posStatus[5] == 0)
{
posStatus[5] = 2;
return;
}
else if (posStatus[8] == 0)
{
posStatus[8] = 2;
return;
}
issue:
There is a grid that is 9 long which three rows, 3 columns and two diagonals. Initially all values are set to 0 and this is used to determine if the space is free so changing to another type would cause issues. If the value 1 is held player 1 has played there. If the value 2 is held the computer has played there.
So originally I had put in
posStatus[0] + posStatus[1] + posStatus[2] % 2 == 0)
Which decides where the computer will play in this case it will be the first row if the enemy player has put 2 values there which logically should work perfectly and it does apart from my issue which is as follows:
When nothing is played on a row the values are: 0, 0 ,0 if you do 0 + 0 + 0 % 2 you'll discover that equals 0 which is the parameter for the above condition. This means it will attempt to make sure there is a value in each row/column/diagonal which of course is not good as it means the player can win in 3 turns..
So to combat this I added in (I'm aware I can refactor it) I added:
posStatus[0] != 0 && posStatus[1] != 0 && posStatus[2] != 0
Which means if a row/column/diagonal is empty do not play there which means it never plays in empty rows/columns/diagonals which is an issue.
Suggestions?
You have to check few conditions for each time, need not to consider the sequence. Possible cases of win for any player would be:
0,1,2
0,3,6
0,4,8
1,4,7
2,4,6
2,5,8
3,4,5
AND 6,7,8
I am assuming that numbering is row wise and started from 0.
Now you have to tell computer based on the input of user.
For example:
User has selected 2, so you have posStatus[2] = 1 Now the only cells you have to check are 0,1,4,5 and 6 as these are the only possible cells for win.
To handle the beginning of game situation, you have two options:
Let the user start always.
Start anyone from 0,2,6 and 8 as these are part of the maximum solutions.
Another Approach:
There are 3 possibilities of success:
A. Row wise : Add or substitute number by 1 and check status ,
B. Column wise : Add or substitute number by 3 and check status ,
C. Diagonally : Add or substitute number by 2 AND 4 then check status
For example if user has selected i cell. Your check should be:
A. See the status of (i-2),(i-1),(i+1) AND (i+2) - Obviously this should be in range of 0-8
B. See the status of (i-6),(i-3),(i+3) AND (i+6)
C. See the status of (i-8),(i-4),(i-2),(i+2),(i+4) AND (i+8)
I have a simple while loop in C# and basically I'm testing two conditions
while (opponentOne.HP >= 0 || opponentTwo.HP >= 0)
Which when I read this means, while the first opponents HP is more than equal to 0 OR the seconds opponents HP is more than equal to 0, exit. So when only one of them are true, exit the while loop?
However this does not do what I want it to do, it waits for both of them to become true before exiting the loop, however if I change || to && it will work
while (opponentOne.HP >= 0 && opponentTwo.HP >= 0)
Which now says while the firsts opponents HP is more than 0 and the seconds opponent is more than 0, exit...
Have I got something mixed up here?
I thought the loop should break when both conditions are met.
The condition isn't the condition "to exit", it's the condition to continue
So first one says "continue looping as long as either oponents have >0HP" and the second one says "continue as long as both opponents have >0HP"
A while loop will keep looping until the condition BECOMES FALSE.
So in the first case :
NOT (1.HP >= 0 || 2.HP >= 0)
if we apply DeMorgan's equivalency to it:
It will break when
NOT 1.HP >= 0 AND NOT 2.HP >= 0
Have I got something mixed up here?
Yes, && means that both sides must be true(both oppponents must be alive), otherwise the loop is exited.
|| means that one of both sides must be true, so only one opponent must be alive.
Replace the while-loop with an if-statement(for demonstration purposes only):
if(opponentOne.lives && opponentTwo.lives)
{
// do something
}
else // one is dead
{
// exit
}
I don't understand how 's' is being used in '(+s[i])'. What is the '+' for? Also I do not understand the use of the || symbol in this way, what is it doing?
var draw = function(s){
...
if (+s[i]) a = (a+90)%360||360; // Right
else a = (a-90||360); // Left
In the code below I do not understand what 'while (n--)' does?
var getS = function(n){
var s = '';
while (n--) s += getNext(0);
return s;
};
If you want to look at this code in context go to http://fractal.qfox.nl/ and press F12 to get the developer tools up and look for dragon.js in the scripts. Please feel entirely free to post a complete translation to C# as well if you fancy the challenge.
Putting + in front of an expression coerces it into a number, e.g. from a string.
The || operator has the value of its left side if that can convert to true, otherwise the value of its right side. And so a||b would mean "use a if it's not null, false, zero or an empty string, otherwise use b".
And n-- will have boolean value false when n reaches zero.
if (+s[i]) is checking if s[i] exists and is a number != 0. In C# it would be the same as
int n;
if (int.TryParse(s[i], out n) && n != 0) { }
a = (a-90||360); is basically saying if leftside of || is null, undefined, false or zero, then take rightside. In C# it would look something like
a = (a-90 > 0)? a-90 : 360;
but a would have to be declared prior to that line.
while (n--){ } keeps repeating itself until n is 0. n must be declared prior to running that code though such as var n = 10;. In C# it would be
int n = 10;
while (n >= 0)
{
n--;
}