Class member is being changed unexpectedly [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I'm making a dice of the Royal Game of Ur in C#. It needs 4 4-sided pyramids that have 2 out of 4 peaks colored white. This means that a single dice gives 50/50 chance of being either 0 or 1.
Now look at this code and tell me why it sometimes gives me 5 and 6.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ButtonScript : MonoBehaviour {
public Button rollButton;
public int result;
void Start()
{
rollButton.onClick.AddListener(onClick);
}
void resultReset()
{
Debug.Log("Setting result from " + result + " to 0");
result = 0;
}
public int Calculate()
{
for (int i = 0; i < 4; i++)
{
int num = Random.Range(0,2); // Either 1 or 0.
result = result + num; // num is added to total result
if (result > 4)
{
Debug.Log("Rolling " + result + " not possible!!");
}
}
return result;
}
void onClick()
{
resultReset();
int iRolled = Calculate();
Debug.Log("I rolled " + iRolled); // Sometimes gives 5+ and skips the for loop (like, goes 1-2 times and gives out an impossible number)
}
}

I can't reproduce this, but my best guess would be that the onClick method is tied to two different objects that are both being triggered simultaneously? Or maybe the event handler is added to a single object multiple times somehow. Either might explain why it is being fired twice. You might have a race conditions where both objects reset the [shared] result and then both start adding to it at the same time. Try running your loop against non-shared local variables instead, like this:
public int Calculate()
{
int thisRoll = 0; // only accessible from inside the method
for (int i = 0; i < 4; i++)
{
int num = Random.Range(0,2); // Either 1 or 0.
thisRoll = thisRoll + num; // num is added to total result
if (thisRoll > 4)
{
Debug.Log("Rolling " + thisRoll + " not possible!!");
}
}
return thisRoll;
}
void onClick()
{
//resultReset(); // not necessary anymore
int iRolled = Calculate();
Debug.Log("I rolled " + iRolled); // Sometimes gives 5+ and skips the for loop (like, goes 1-2 times and gives out an impossible number)
// set result here if you actually need it in addition to iRolled:
result = iRolled;
}

At least one of OnClick and Calculate is being called twice.
One time is accounted for by the call to AddListener when Unity calls Start() on ButtonScript. Any additional calls on a click would create a race condition that could produce unexpected output.
Make sure that neither of those methods are included in the button's list of On Click events in the inspector before you run the scene.

Related

Incrementing a variable in c# not working [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
So I currently have the problem that I am unable to increment my variables. Using 'i++' in my code seems to do nothing and using any other form of incrementing a value does nothing too.
static void Main(string[] args)
{
Console.WriteLine("Enter a number to see its times tables");
int number = Convert.ToInt16(Console.ReadLine());
int i;
for (i = 10; i == 10; ++i)
{
int output;
output = i * number;
Console.WriteLine(output);
}
Console.ReadKey();
}
All I am trying to do is create a basic loop but it is just stuck in an infinite loop, setting my variable 'i' to 10 causes the loop to work like its supposed to but it only executes once. The loop part becomes irrelevant.
Try
for (i = 0; i <= 10; i++)
Your condition means that the loop executed an incorrect number of times.
By incorrect number looking at your post and various attempts this means anything from zero to 'a positive' (but incorrect) number of times.
An if statement is a compound statement. In your case your if statement is composed of three sub-statements - an initialization, a test and an increment.
When the if statement is executed these three statements are executed in order.
If the test returns false the loop is not entered so when the condition is 'i==10' and the initialization is 'i=1' the loop is not executed at all. When the initialization is 'i=10' then the loop executes once.
Sub-statements 2 and 3 are executed after each execution of the content of the loop and as long as statement 2 resolves to true the loop will continue being executed.
In our example using a condition 'i <= 10' would cause the code within the loop to be executed 11 times. 'i<10' would cause it to be run ten times. Care has to be taken when choosing sub-statement 2 (i.e. the loop condition). You have to make sure that the initial value in statement 1 and the increment in statement 3 (or alternatively a change to the value made within the body of the loop itself) guarantee that the condition will eventually fail.
If not then code has to be added to the loop to ensure that the loop will exit.
This will loop indefinitely
for (int x=0; x==0; ) {
}
This will NOT loop indefinitely
for (int x=0; x==0; ) {
x++;
}
A test and break out of a loop could be done like shown in the following.
for (int x=0; x==0; ) {
if (x==0) {
break;
}
}
If you do not ensure that the loop is guaranteed to terminate it could potentially never exit.
By Using
(i = 0; i < 10; i++)
The range of i will be from 0 to 9
By using
(i = 0; i <= 10; i++)
The range of i will be from 0 to 10
By using
(i = 1; i <= 10; i++)
The range of i will be from 1 to 10

MinHeap implementation in c# [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am working on a MinHeap implementation for school and I have encountered a problem. The code typically works well but sometimes generates an argument out of range exception in my heapify method. I have tried to isolate the problem but I am a terrible debugger.
Here is my code for the function:
private void Heapify(int i)
{
int least;
int leftchild = 2 * (i + 1) - 1;
int rightchild = 2 * (i + 1);
if (leftchild < heap.Count && (heap[rightchild].CompareTo(heap[i]) < 0))
{
least = 1;
}
else
{
least = i;
}
if (rightchild < heap.Count && (heap[rightchild].CompareTo(heap[least]) < 0))
{
least = rightchild;
}
if (least != i)
{
T temp = heap[i];
heap[i] = heap[least];
heap[least] = temp;
this.Heapify(least);
}
Out of range exceptions are generally easy to track down. Basically, you have to make sure that whenever you're accessing an item in an array via indexes, said array's count / length is greater than the index. In other words, ensure that in every call to heap[#index], #index < heap.Count (either by straight checking it or by your method's logic)
if (leftchild < heap.Count && (heap[rightchild].CompareTo(heap[i]) < 0))
If rightchild >= heap.Count, this will give you an exception.

Windows freezes in C# [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am writing C# program in Visual Studio 2010, to build a windows application.
I have created a class named Store. And inside Store class, I have created a method named StoreLength(Store ob)
public int StoreLength(Store ob)
{
int i = 0, L = 0;
while (i < 100)
{
if (ob.a[i] != null)
L += 1;
}
return L;
Now from other class I have created an object of Store class. And using that object I am trying to use the StoreLength method.
private void buttonEqual_Click(object sender, EventArgs e)
{
int l = ob.StoreLength(ob);
DisplayUnit.Text = Convert.ToString(l);
}
Now when I am running the program, everythign is working properly but as soon as I am clicking on buttonEqual, the window freezes. I think there is some problem with in buttonEqual1_Click mothod, or in StoreLength method.
Please help.
It's because the while loop's condition is always satisfied.
Every time it evaluates i, it'll always be less than 100 because you set it to 0 and its value does not change.
The typical approach would be to increment i by 1 on every iteration:
while (i < 100)
{
i++;
if (ob.a[i] != null)
L += 1;
}
The reason this causes it to freeze is because your UI is 'waiting' (in a roundabout way) for this while loop to complete.
Also, consider using a for loop for scenarios like this. It suggests the declaration, initialisation, condition and increment all on the one line for readability and consistency sake:
for(int i = 0; i < 100; i++)
{
if (ob.a[i] != null)
L += 1;
}

Find maximum sum leaf to root path in a Binary Tree [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
I have created a recursive function to calculate the max path of a binary tree. I got as feedback that it does not work, but according to me test it provide the correct result. Can someone help me please?
private long PathSum(int row, int column, Pyramid pyramid)
{
// Base case, stop recurse when first row is reached.
if (row == 0) return pyramid[row, column];
// Set level to the current cell and add to the end result.
long value = pyramid[row, column];
// Continue to the next row.
if (row != 0)
{
// Continue to the next left level.
long left = pyramid[row - 1, column];
// Continue to the next right level.
long right = pyramid[row - 1, column + 1];
// Get the highest of the left and right.
long highest = Math.Max(left, right);
// Get the index of the hightest path.
int nextColumn = highest == left ? column : column + 1;
// Recurse to the next level and add results together.
value += GetTotal(row – 1, nextColumn, pyramid);
}
// Return result to the caller.
return value;
}
You have a critical mistake in your algorithm: you only walk through the 'pyramid' once and select the based case based on the next result, without looking at underlying nodes.
To illustrate what you are doing, consider the following pyramid:
1
2 3
311 6 3
Assuming that you start at 1, the following will be executed:
Look at the max out of the underlying nodes (2 and 3).
Go down to the next node (3) and repeat.
Your algorithm will return 10 (1 + 3 + 6) while the maximum value in my example is 311 + 2 + 1, because it doesn't look ahead.
You require a strategy to look further than one step ahead in order to determine the best path.
Edit: look at Euler project #18 approach for more hints.
I think what you are describing is not a binary tree but a pyramid of numbers, and the problem is best solved using dynamic programming instead of tree traversal. Here is a sample code for dynamic programming. It is not compiled and I don't know C# by the way:
private long DP(int maxRow, Pyramid pyramid)
{
int maxColumn = maxRow;
Pyramid result;
clear_pyramid(result);
for (int j=0; i<maxColumn; i++) {
result[0, j] = pyramid[0, j];
}
for (int i=1; i<maxRow; i++) {
for (int j=0; j<maxColumn-i; j++) {
result[i,j] = Math.max(result[i-1,j], result[i-1,j+1]) + pyramid[i,j];
}
}
return result[maxRow-1, 0];
}

Knuth's algorithm for solving MasterMind with 5 guesses [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I read knuth's algorithm in wikipedia and I wonder about the 3rd step. If I understand correct for each option (even if not removed in step 2), we calculate how many possible guesses would have removed for every ffedback. for that step we take minimum. after, we find the maximum on the minimums and take the code the max belong to it. that will be our second guess. Im not sure what can be done next because,each time we dont change the max on the minimums (or what is the minimum). In addition, how can I implement this step in c# for example. How can I procceed and how can I implement that step? What does the minimum on the feedbacks really mean?
You need a constant collection of all possible outcomes, a collection of the remaining alternatives, and a method that can compute the outcome given a guess and a solution.
First, model the relevant domain objects:
public class Outcome
{
public int White { get; set; }
public int Black { get; set; }
}
public class Combination
{
// however you like to model this
}
Then, create the method that checks the guess against the secret:
public static Outcome Check(Combination guess, Combination solution)
{
// your implementation
}
Now the algorithm is as follows:
Outcome[] outcomes = new[] { new Outcome { White = 0, Black = 0 },
new Outcome { White = 1, Black = 0 },
// ... all other possibilities
};
// assume we have some list of combinations
int min = Integer.MaxValue;
Combination minCombination = null;
foreach (var guess in combinations)
{
int max = 0;
foreach (var outcome in outcomes)
{
var count = 0;
foreach (var solution in combinations)
{
if (Check(guess, solution) == outcome)
count++;
}
if (count > max)
max = count;
}
if (max < min)
{
min = max;
minCombination = guess;
}
}
At the end of the loop, minCombination is your next guess.
EDIT I messed up min and max in the first version, that is fixed now. The inner count gives the number of remaining options, provided the chosen combination and the assumed outcome. We want the maximum over the outcomes (the worst possible result for the chosen combination is the one that leaves most options remaining). After that we want the minimum over the combinations (the best possible combination is the one that leaves least options remaining in the worst case).
If you like Linq, you could also write the algorithm as
combinations.MaxBy(guess =>
outcomes.Min(outcome =>
combinations.Count(solution =>
Check(guess, solution) == outcome)));
in which I used MaxBy from the MoreLinq project.

Categories