I have a program meant to simulate some probability problem (A variation of the monty hall problem if your interested).
The code is expected to produce 50% after enough iterations but in java it always comes to 60% (even after 1000000 iterations) while in C# it comes out to the expected 50% is there some thing different I do not know about java's Random maybe?
Here is the code:
import java.util.Random;
public class main {
public static void main(String args[]) {
Random random = new Random();
int gamesPlayed = 0;
int gamesWon = 0;
for (long i = 0; i < 1000l; i++) {
int originalPick = random.nextInt(3);
switch (originalPick) {
case (0): {
// Prize is behind door 1 (0)
// switching will always be available and will always loose
gamesPlayed++;
}
case (1):
case (2): {
int hostPick = random.nextInt(2);
if (hostPick == 0) {
// the host picked the prize and the game is not played
} else {
// The host picked the goat we switch and we win
gamesWon++;
gamesPlayed++;
}
}
}
}
System.out.print("you win "+ ((double)gamesWon / (double)gamesPlayed )* 100d+"% of games");//, gamesWon / gamesPlayed);
}
}
At the very least, you have forgotten to end each case block with a break statement.
So for this:
switch (x)
{
case 0:
// Code here will execute for x==0 only
case 1:
// Code here will execute for x==1, *and* x==0, because there was no break statement
break;
case 2:
// Code here will execute for x==2 only, because the previous case block ended with a break
}
You forgot to put breaks at the end of the case statements, so the case (1) continues to case (3).
Related
I have like 20 objects with the same script. And the problem that when I want to set a value for every each object only one respond to the script. here is the objects main script
[SerializeField]
private int Id = 0;
public void SetId(int num)
{
Id = num;
}
public int ReturnId()
{
return Id;
}
And here where they are called:
private void DeterminedWallColor()
{
for (int i = 0; i < _colorType.Length; i++)
{
switch (_colorType[i])
{
case 1:
_wId.SetId(_colorType[i]);
break;
case 2:
_wId.SetId(_colorType[i]);
break;
case 3:
_wId.SetId(_colorType[i]);
break;
case 4:
_wId.SetId(_colorType[i]);
break;
}
}
}
The problem is you shouldn't be using a switch statement. The code you have right now will always match the first case because all the cases below it are the same as the first case and will always be the same as the firsts case because it is the same code/expression in all the cases you are checking for.
Also since you want to set a value for each gameObject(assuming you want to set the Id), you would need to loop thru all the gameObjects first, and then set each _colorType per gameObject, according to what you want/need. (I cannot provide code example because your question was vague, and you did not provide context for your code examples such as "_colorType". I cannot tell where that variable came from since you did not provide the variable implementation)
I'm developing a kind of remote controller car.
I'm using a window CE device and Compact Framework 2.0 C#.
When Remote controller adjust the speed of car,
I'm using a sequential way like stairs.
However, It is sometimes going up and down 2 steps, 4 steps.
I would like to make only one step up and down from now step.
For example, now step is 4 then I just go to 3 or 5 not 8 or 1.
// Dealing with GPIO Input signal (detect push button)
private void smartGPIO1_EvtPortADatasChange(object sender, EventArgs e)
{
int iPortDatas;
SmartX.PORTDataEvtArgs PortDatas;
PortDatas = (SmartX.PORTDataEvtArgs)e;
iPortDatas = PortDatas.iPortDatas;
if (!test_start_Flag)
{
// User push the down button
if ((iPortDatas & 0x08) == 0x00)
{
motor_step = (motor_step <= -2) ? -2 : motor_step -= 1;
motor_handler(motor_step);
}
// User push the up button
if ((iPortDatas & 0x05) == 0x01)
{
motor_step = (motor_step >= 12) ? 12 : motor_step += 1;
motor_handler(motor_step);
}
}
}
// When button is pushed, send a command to car depends on the step
public int motor_handler(int step)
{
switch (step)
{
case 0:
// send command
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
break;
case -1:
break;
case -2:
break;
}
return step;
}
That code is for sure looped through on every update. Meaning that the single push of up or down button gets registered tens of times every second, so it seems like it goes more than one step at a time. You need to somehow register only new button presses.
//define something like this to the class level
Bool downIsPressed;
Bool upIsPressed;
//and then check and modify those values
if ((iPortDatas & 0x08) == 0x00 && downIsPressed == false)
{
motor_step = (motor_step <= -2) ? -2 : motor_step -= 1;
motor_handler(motor_step);
downIsPressed = true;
}
else
{
downIsPressed = false;
}
That should only register the button once and enable it once the button is released. There might be some cleaner and nicer looking way too, but hope that is of some help :)
Is it Recursive?
motor_handler(motor_step);
Calls private void smartGPIO1_EvtPortADatasChange(object sender, EventArgs e)
That's why each button push you get two steps.
The solution is a Private Boolean, typically I name IsRecursive:
class RacingCar {
private bool IsRecursive = false;
private void smartGPIO1_EvtPortADatasChange(object sender, EventArgs e)
{
if (IsRecursive) return;
IsRecursive = true;
....
IsRecursive = false;
}
}
Your code only ever increments or decrements the motor_step by 1 so if you're finding that the variable value jumps up by 2 etc then the code must have run twice in quick succession.
You have to find a way to "debounce" two events arriving at the same time. For example, when you step, record the current time. If the next event occurs less than one second since the previous event, ignore the event
//declare var and set to min value
private DateTime last_event_time = DateTime.MinValue;
private void smartGPIO1_EvtPortADatasChange(object sender, EventArgs e)
{
//debounce
if((DateTime.Now - last_event_time).TotalSeconds < 1)
return;
last_event_time = DateTime.Now;
int iPortDatas;
SmartX.PORTDataEvtArgs PortDatas;
Note: I've no idea if using DateTime will work on your platform, please take this code as pseudocode to demonstrate the concept
Debouncing like this will rely on the fact that the math on the time now vs time then needs to execute faster than events happen
If you want it to be so that step never changes as long as the button is held down you need to flip the logic around a bit so that as long as events keep arriving quickly, the code keeps returning - for that. You would update the time every time you return and only let the code proceed if more than X time has passed since the last event arrived
So I'm working on a Switch-Case menu for my program but I'm having multiple issues (I'm probably missing something real obvious here)
So first off I'm trying to implement a while loop to make it possible to return to the menu after executing any of the case methods. However when trying to implement a while loop it doesn't seem to recognise my bool variable for some reason.
Secondly I'm not quite sure how to make it so the user can return to the start menu after they've done what they want to do in the case they've chosen, this probably has a real easy solution, but I just can't find one.
[code]
private string[] säten = new string[24];
private int Antal_passagerare = 0;
public void Run()
{
bool continue = true;
while(continue)
{
string menu = (Console.ReadLine());
int tal = Convert.ToInt32(menu);
switch(tal)
{
case 1:
Add_passagerare;
break;
case 2:
break;
case 3:
break;
}
}
}
[/code]
Your problem is that your local variable name conflicts with the C# keyword (or statement) continue which controls the flow of a loop (e.g. for, foreach, while, etc). Another control flow keyword is break.
You must rename the local variable. But because of the flow control keywords you can drop the local variable (see below). Also use Int32.TryParse to avoid your program from crashing, if the user inputs a non numeric value. In this context you can see the statements continue and break at work:
// Start an infinite loop. Use the break statement to leave it.
while (true)
{
string userInput = Console.ReadLine();
// Quit if user pressed 'q' or 'Q'
if (userInput.Equals("Q", StringComparison.OrdinalIgnoreCase)
{
// Leave the infinite loop
break;
}
// Check if input is valid e.g. numeric.
// If not show message and ask for new input
if (!(int.TryParse(userInput, out int numericInput))
{
Console.WriteLine("Only numbers allowed. Press 'q' to exit.");
// Skip remaining loop and continue from the beginning (ask for input)
continue;
}
switch (numericInput)
{
case 1:
break;
case 2:
Add_passagerare();
break;
case 3:
break;
}
}
I'm trying to make a test which is faster in code executing.
Situation 1
int a=2;
if(a==1)
{
//code here
}
if(a==2)
{
//code here
}
if(a==3)
{
//code here
}
Situation 2
int a=2;
if(a==1)
{
//code here
}
else if(a==2)
{
//code here
}
else if(a==3)
{
//code here
}
In situation 1, 'int a' is always different value inside if statements
If you have a lot of if or if else statements I would recommend a switch statement like this:
int a = 2;
switch (a)
{
case 1:
break;
case 2:
break;
case 3:
break;
}
Reference: http://www.blackwasp.co.uk/SpeedTestIfElseSwitch.aspx
The second code block can be faster because the first one always tests every condition. The second one stops testing after it finds a match.
So this loop is my first attempt at changing many things. I'm not sure I'm going about it the right way. This is for a rught/wrong answer game. Each time they answer wrong, the loop is called.
In my head it would go to the if related to numAttempts. So if numAttempts ==4 you would see "Wrong Answer 2 tries left!" But each time until the fifth attempt, when the loop is called it always starts at the top regardless of the numattempts.
To mitigate this I also tried adding numAttempts++ in the message check (wrong) code block.
I like the idea of the four loop, because based on each wrong answer a different image will appear, based on HangmanImage() --not currently defined--
I've tried break and return between the for if statements but it isn't working. Can you help me when the loop is called to start the loop where numAttempts =. EX. start at numAttempts==2? And stop the loop after the specific instance is completed?
I'm new to coding and trying to make it work. I appreciate your Patience if my work is 100% wrong or that I shouldn't have done a four look. reading a book and the web is great, but every now again, especially in the beginning people need guidance. Please take a moment and push me in the right direction.
Thank you for your time.
int numAttempts = (0); // global variable, at the start of the class. This allows the variable to be used anywhere with the current value
int maxAttempts = (5);
static void UpdateImage()
{
for (int numAttempts = 0; numAttempts < 6; numAttempts++)
{
if (numAttempts == (1))
{
MessageBox.Show("Wrong Answer 4 tries left!");
{
// HangmanImage();
}
}
else
if (numAttempts == (2))
{
MessageBox.Show("Wrong Answer 3 tries left!");
{
// HangmanImage();
}
}
else
if (numAttempts == (3))
{
MessageBox.Show("Wrong Answer 2 tries left!");
{
// HangmanImage()
}
}
else
if (numAttempts == (4))
{
MessageBox.Show("Wrong Answer 1 try left!");
{
// HangmanImage()
}
}
else
if (numAttempts == (5))
{
MessageBox.Show("You Lose!");
{
// HangmanImage();
}
}
}
}
Here is a working answer: https://dotnetfiddle.net/Z2BaYs
This is the code. Basically, you use the for loop to keep the game in play until the user either runs out of attempts or answers correctly.
using System;
public class Program
{
public static void Main()
{
var maxAttempts = 5;
var correctAnswer = "Edam";
for(int actualAttempts = 1; actualAttempts <= maxAttempts; ++actualAttempts)
{
Console.WriteLine("What is the only cheese that's made backwards?");
Console.WriteLine("Attempt #" + actualAttempts);
var answer = Console.ReadLine();
if(answer.Equals(correctAnswer))
{
Console.WriteLine("Correct!");
break;
}
switch(actualAttempts)
{
case 1:
Console.WriteLine("Whoa. Nice try.");
break;
case 2:
Console.WriteLine("Nope. Wrong.");
break;
case 3:
Console.WriteLine("Incorrect sir!");
break;
case 4:
Console.WriteLine("Still not the correct answer.");
break;
case 5:
Console.WriteLine("...and your done.");
break;
default :
break;
}
}
}
}
This is some example output/input.
What is the only cheese that's made backwards?
Attempt #1
Cheddar
Whoa. Nice try.
What is the only cheese that's made backwards?
Attempt #2
Mozarella
Nope. Wrong.
What is the only cheese that's made backwards?
Attempt #3
Havarti
Incorrect sir!
What is the only cheese that's made backwards?
Attempt #4
Swiss
Still not the correct answer.
What is the only cheese that's made backwards?
Attempt #5
Edam
Correct!
I can tell that you are doing this for school, so I don't want to give much away. But too your question, you are wanting to keep the same iteration in the loop, if I am understanding you. Just to try and stick to your code, you would need to pass in a variable and return one on the function. Like this
int updateImage(int count)
{
for(count < 6; count++)
{
Do what you need;
}
return count;
}
That way you can pass your iteration in and out of the function. Hope this helps.