Loop not recognizing statement - c#

So I'm working on this dice game for school but I've stumbled upon this problem:
First, let me give some context.
I have an array called diceResults[] in which the amount of thrown dice is saved in the array (i.e. you rolled two one's, so the first index of the array is 2)
Now One pair, Two pair, Three of a kind and Full house are all working fine.
But when a Full house is rolled it recognizes a pair, three of a kind, and a full house. But it doesn't recognize the second pair in the three of a kind.
I've tried several solutions but none seem to work.
for (int i = 0; i < diceResults.Length; i++)
{
if (diceResults[i] == 2)
{
onePair = true;
for (int j = i + 1; j < diceResults.Length; j++)
{
if (diceResults[j] == 2 || diceResults[j] == 3)
{
twoPair = true;
}
}
}
}
for (int i = 0; i < diceResults.Length; i++)
{
if (diceResults[i] == 3)
{
threeKind = true;
for (int k = 0; k < diceResults.Length; k++)
{
if (diceResults[k] == 2)
{
fullHouse = true;
}
}
}
I've tried setting 2 different if statements containing (diceResults[j] == 2) and (diceResults[j] == 3) in below each-other too, but this didn't seem to work either.
I'm checking what values are set using the following method.
private void CheckBoolValues()
{
if (onePair == true)
MessageBox.Show("pair yes");
if (twoPair == true)
MessageBox.Show("2 pair yes");
if (threeKind == true)
MessageBox.Show("3 of a kind yes");
if (fourKind == true)
MessageBox.Show("4 of a kind yes");
if (yahtzee == true)
MessageBox.Show("yahtzee yes");
if (lowStraight == true)
MessageBox.Show("lowstraight yes");
if (highStraight == true)
MessageBox.Show("high straight yes");
if (fullHouse == true)
MessageBox.Show("full house yes");
}
Would appreciate some help!

Shouldn't your first few lines of code be:
for (int i = 0; i < diceResults.Length; i++)
{
if ((diceResults[i] == 2) || (diceResults[i] == 3))
{
onePair = true;
...

If you roll 3 1s and 2 2s, you'll never detect the "second pair", because first loop only looks at dice totals over 2. But it's correct to set twoPair = true at the point you set fullHouse = true. Also you don't actually needed a nested loop to implement this.
BTW I'm not sure what the rules of Yahtzee are, but is 4 of a kind considered "two pairs"?

I personaly see no sense you want to detect a pair in a three of a kind but anyways. You could just check if there's already a pair of two in the results like this. Also doing multiple for-loops would be kind of superfluous.
bool onePair = false;
bool twoPair = false;
bool threeKind = false;
bool fullHouse = false;
for (int i = 0; i < diceResults.Length; i++)
{
if (diceResults[i] >= 2)
{
if(onePair == true) {
twoPair = true;
}
onePair = true;
}
if (diceResults[i] >= 3)
{
threeKind = true;
for (int j = 0; j< diceResults.Length; j++)
{
if (diceResults[k] == 2)
{
fullHouse = true;
}
}
}
}

Related

C# - Basic hangman game lives issue

I'll make it short: Basic hangman game, it loops through player 2 letter choice and if it doesn't match the first character of player 1's word, it'll remove a life, the the second, until it either finds a match or just removed however many lives the player 1 word length is.
I obviously don't want that, I want it to check the array - if none match then remove a life.
for (int i = 0; i < playerTwoGuesses.Length; i++)
{
Thread.Sleep(1400);
Console.Write("Guess: ");
count = 0;
do
{
try
{
playerTwoGuesses[i] = char.Parse(Console.ReadLine());
validGuess = true;
}
catch (Exception)
{
Console.WriteLine("Please enter a single character only.");
}
} while (validGuess == false);
for (int j = 0; j < playerOneDisguised.Length; j++)
{
if (playerOneCharacters[j] == playerTwoGuesses[i])
{
playerOneDisguised[j] = playerTwoGuesses[i];
}
else
{
lives = lives - 1;
}
}
if (lives == 0)
{
Console.WriteLine("Oh no! It seems you've lost. Closing game in 5 seconds.");
Thread.Sleep(5000);
Environment.Exit(0);
}
Console.WriteLine(playerOneDisguised);
for (int k = 0; k < playerOneDisguised.Length; k++)
{
if (playerOneDisguised[k] != '*')
{
count = count + 1;
if (count == playerOneDisguised.Length)
{
Console.WriteLine("Congratulations you've won!");
Thread.Sleep(1000);
Console.WriteLine("Closing game in 5 seconds.");
Thread.Sleep(5000);
Environment.Exit(0);
}
}
}
}
Try this:
bool match = false;
for (int j = 0; j < playerOneDisguised.Length; j++)
{
for (int y = 0; y < playerTwoGuesses.Length; y++)
{
if (playerOneCharacters[j] == playerTwoGuesses[y])
{
playerOneDisguised[j] = playerTwoGuesses[y];
match = true;
}
}
}
if (match == false) {
lives = lives - 1;
}
// Reset it back to false
match = false;
Rather than looping over the array yourself, you can just ask if the guessed char is present in it. You then only need an if statement to handle a guess
if (Array.Exists(playerTwoGuesses, element => element == lastGuess) {

PictureBox.bounds.intersectswith doesn't seem to work

i am writing a game and i have a simple enemy AI that only follows you, i need the enemys to not go on top of each other so i tried this code but it doesn't work they stil going on top of each other (except of maybe 2 who don't and i have no idea why).
here is the code that check's if they intersects
for (int i = 0; i < z.Length ; i++)
{
for (int j = 0; j < z.Length ; j++)
{
if (zombie[i].Bounds.IntersectsWith(zombie[j].Bounds) && i != j)
{
z[i].setAllowed(false);
}
else
{
z[i].setAllowed(true);
}
}
}
The code is inside a timer and setAllowed tells the zombie class weather the zombie can move or not.
Your "allowed" values are being overriden during the loop. For instance:
(1) i == 2, j == 1 => let's say that SetAllowed(false) is executed (collision, expected behavior)
(2) (next iteration) i == 2, j == 2 => i == j so SetAllowed(true) is executed (overriding correct behavior)
(3) Even when i != j, you can override the "allowed" value when a next zombie does not collide.
Try something like that:
for (int i = 0; i < z.Length ; i++)
{
bool allowed = true;
for (int j = 0; j < z.Length ; j++)
{
if (i == j)
continue;
if (zombie[i].Bounds.IntersectsWith(zombie[j].Bounds))
{
allowed = false;
break;
}
}
z[i].setAllowed(allowed);
}
Of course there can be other problems somewhere else in your logic, but this is a start from the code you provide.

Smooth display of a grid without jerks on console

I'm making this pacman console based game, in which there is a 40x40 board. There are pacmans and enemies on the board eating food. pacman is represented by 0 and enemy by #. Everytime there position changes the display function gets called, which in current logic, after every second clears the whole console and reprints each element on the board.. but this way, there are these jerks whenever whole board gets displayed. Kindly tell me a better way to achieve a smooth motion of paacman and enemy, ideally i should only change only the position of pacman and enemy, but i need to clear the console in order to show the grid on the same spot, otherwise it will just keep scrolling down. The code for display function is below:
public static void display()
{
Console.Clear();
for (int i = 0; i < 40; i++)
{
for (int j = 0; j < 40; j++)
{
bool packFound = false;
bool enmFound = false;
foreach (Packman element in myVers.packmans)
{
if (element.x == i && element.y == j)
{
packFound = true;
break;
}
}
foreach (Packman element in myVers.enemys)
{
if (element.x == i && element.y == j)
{
enmFound = true;
break;
}
}
if (packFound == true)
{
Console.Write('0');
myVers.board[i, j] = ' ';
}
else if (enmFound == true)
{
myVers.board[i, j] = ' ';
Console.Write('#');
}
else
{
Console.Write(myVers.board[i, j]);
}
}
Console.Write('\n');
}
//Console.Write("\nFood Count " + myVers.foodCount + "\n");
}
What if you would only redraw the characters that really changed? Maybe with use of Console.SetCursorPosition
Try building the String for the board first then pass the whole thing to the console at one time. Still perform the clear operation.
This would be a job for:
String Builder
public static void display()
{
var boardStr = new StringBuilder();
for (int i = 0; i < 40; i++)
{
for (int j = 0; j < 40; j++)
{
bool packFound = false;
bool enmFound = false;
foreach (Packman element in myVers.packmans)
{
if (element.x == i && element.y == j)
{
packFound = true;
break;
}
}
foreach (Packman element in myVers.enemys)
{
if (element.x == i && element.y == j)
{
enmFound = true;
break;
}
}
if (packFound == true)
{
boardStr.Append("0");
myVers.board[i, j] = ' ';
}
else if (enmFound == true)
{
myVers.board[i, j] = ' ';
boardStr.Append("#");
}
else
{
boardStr.Append(myVers.board[i, j].ToString());
}
}
boardStr.Append("\n");
}
//Console.Write("\nFood Count " + myVers.foodCount + "\n");
Console.Clear();
Console.Write(boardStr.ToString());
}

List/Array member can't be addressed - Euler 14

I have the below code. I create a list (tried with array as well) with one million and one members. All of them has the value 0 by default. It should work like a multidimensional array, but it's not necessary as the first 'column' has to be numbers from 1-1.000.000. To make life easier I made 1.000.001 members to avoid using the 0th place.
At a certain point I have to use a member of this list addressed by a variable: list[n], and to avoid issues this only happens if n < 1.000.000. As there are members from 0-1.000.000 I think it's OK, but still my program crashes after a while with error code ArgumentOutOfRangeException.
What am I missing here?
int highestCount = 0;
int highestNum = 0;
List<int> list = new List<int>();
for(int j = 0; j <= 1000001; j++)
{
list.Add(0);
}
for (int i = 2; i < 1000000; i++)
{
int count = 0;
int number = i;
do
{
if (i % 2 == 0)
{
number = number / 2;
if (number < 1000000)
{
if (list[number] != 0)
{
count += list[number];
break;
}
else
{
count++;
}
}
else { count++; };
}
else
{
number = (number * 3) + 1;
if (number < 1000000)
{
if (list[number] != 0) //program dies here
{
count += list[number];
break;
}
else
{
count++;
}
}
else { count++; };
}
} while (number > 1);
list[i] = count;
if (count > highestCount)
{
highestCount = count;
highestNum = i;
}
}
MessageBox.Show(highestNum.ToString());
I think it's just a problem with your logic.
When i == 3 (on the second run), it will go into the do-while block.
Since i % 2 != 0 at that point, it will hit the else.
The number is multiplied by 3 and you add 1.
It is less than 1000000, but....
if(list[number] != 0)
never evaluates to true and you are stuck in an infinite do-while loop and it never breaks out because A) number will always be greater than 1 (satisfying the while condition); and B) you set every element of the array to zero in the code above this loop (thus never satisfying the above if condition):
for(int j = 0; j <= 1000001; j++)
{
list.Add(0);
}

How to reset or restart nested loops

loop one
{
looptwo
{
if(condition=true)
{
reset values//restart both loops
}
}
}
and possibilities for reset values is 3
basically i want to compair two matrices
a= 1 2 3 4
1 2 3 4
b= 3 4 5 6
4 6 7 8
and when row 1 of a[] is matched with row 1 of b[].....i will add these rows and a[]
become = 2 4 6 8
for(i=0;i<rows;i++)
for(j=0;j<columns;j++)
{
a[i]=a[i]+b[i,j]
}
and again find my maches from restart with new a[] Matrix
and i have to insure that all rows of b[] matrix are checked with a[] which are 3 in this case
You have to use goto to break out of multiple loop levels in C#. For example:
RESTART:
while (a) {
while (b) {
if (that_other_thing)
goto RESTART;
}
}
Well, you don't have to use goto but the alternative might be using a bunch of flag variables to indicate that a restart is required. And that code will probably be pretty hard to follow.
The best choice here is to move the loops into their own method, and return from inside the inner loop. Example:
public void MyMehod(){
loop one{
looptwo{
if(condition=true){
return;
}
}
}
}
If this is not possible for some reason, you can use a bool value that you set in the inner loop to bail out of all of them, but this is a bit more messy:
bool endloop = false;
while(!endloop){
while(!endloop){
if(condition){
endloop = true;
}
}
}
For a while loop it looks ok, but even more messy for a for loop or a foreach loop.
Start:
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if(j == 5)
goto Start;
}
}
Although structuring your code in a way to not use a goto is a much better approach...
If you can guarantee that you will have a condition that will tell you that you don't need to restart, you could wrap the whole thing in one more loop.
bool keepLooping = true;
while (keepLooping)
{
keepLooping = false;
for (int x = 0; x < maxx; x++)
{
for (int y = 0; y < maxy; y++)
{
if (DoSomething(x, y))
{
keepLooping = true;
break;
}
}
if (keepLooping)
{
break;
}
}
}
If you are checking a list for duplicates and modifying them do make all entries unique, you might do something like this (assuming string values):
List<string> a = GetNamesFromeSomewhere();
bool duplicateFound = true;
while (duplicateFound )
{
duplicateFound = false;
for (int x = 0; x < a.Length; x++)
{
for (int y = x + 1; y < a.Length; y++)
{
if (a[x].Equals(a[y]))
{
//Change a[y], but now we have to recheck for duplicates...
a[y] += "_";
duplicateFound = true;
break;
}
}
if (duplicateFound)
{
break;
}
}
}
if you use numeric loop variables like i and j you can just reset the values
e.g.
for (i=0; i<10; i++) {
for (j=0; j<10; j++) {
if (var[i][j] == 'x') {
i=0; j=0; break;
}
}
}
you can also use the method approach as suggested earlier
void someFunction(params) {
for (i=0; i<10; i++) {
for (j=0; j<10; j++) {
if (var[i][j] == 'x') {
someFunction(params)
return;
}
}
}
}

Categories

Resources