I'm trying to get my program to start the user with 20 lives and while Lives is greater than 0, flip a coin (random number generator 0(Tails) or 1(Heads)). Every time the user gets Heads it adds 1 to Heads counter and 1 to Flips counter. Every time the user gets Tails it takes 1 from Lives and adds 1 to Flips counter. I think my only problem is my random number generator!? Please be kind, total n00b :)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Coin_Flip_2015
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Random r = new Random(1);
private void cmdFlipCoin_Click(object sender, EventArgs e)
{
int rand = r.Next(1);
int Heads;
int counterFlips;
int Lives;
Lives = 20;
Heads = 0;
counterFlips = 0;
while (Lives > 0)
if (rand == 0)
{
Lives = Lives -= 1;
counterFlips++;
}
else if (rand == 1)
{
Heads = Heads += 1;
counterFlips++;
}
lblFlips.Text = "Flips = " + counterFlips.ToString();
lblHeads.Text = "Heads = " + Heads.ToString();
lblLivesLeft.Text = "Lives Left = " + Lives.ToString();
MessageBox.Show("sorry you are out of lives m8");
}
}
}
The Random.Next(int) method
Returns a non-negative random integer that is less than the specified maximum.
So r.Next(1) is always 0. Use r.Next(2) to get 0 or 1.
You should also move the rand = r.Next(1); inside the while loop. Now it's only assigned once, at the beginning of the method.
I'll take a swing at fixing all the issues:
public partial class Form1 : Form
{
int Heads, counterFlips, Lives;
public Form1()
{
InitializeComponent();
Lives = 20;
Heads = 0;
counterFlips = 0;
}
private Random r = new Random();
private void cmdFlipCoin_Click(object sender, EventArgs e)
{
int rand = r.Next(2);
if (Lives > 0)
{
if (rand == 0)
{
Lives -= 1;
counterFlips++;
}
else
{
Heads += 1;
counterFlips++;
}
}
else
MessageBox.Show("sorry you are out of lives m8");
lblFlips.Text = "Flips = " + counterFlips.ToString();
lblHeads.Text = "Heads = " + Heads.ToString();
lblLivesLeft.Text = "Lives Left = " + Lives.ToString();
}
}
Issues:
The Heads, counterFlips and Lives variables were stored locally, they need to be global
The code was changed so that you flip a coin each time you click the button (changed the while to an if). while loops that have the capability of never exiting should not be used in UI threads.
private Random r = new Random() notice removed the 1, use the default constructor to seed it properly.
Added an "else" to show when the lives were used, it shows your message
Changed the Lives = Lives -= 1 (same with Heads) to proper code
Used r.Next(2) to get either 0 or 1, since the upper bound is exclusive.
Other than that, I'm not sure what you are doing with the Lives and Heads numbers, so I'll leave that up to you to fix.
Here one that is a bit different.. snap beat me by a few seconds!
public partial class Form1 : Form
{
// Leave the seed alone on this line
private readonly Random _r = new Random();
// these need to be outside of your Click event
private int _counterFlips;
private int _heads;
private int _lives = 20;
public Form1()
{
InitializeComponent();
}
private void cmdFlipCoin_Click(object sender, EventArgs e)
{
// x = starting number, y = ending number + 1
// This should be either a zero or one:
int rand = _r.Next(0, 2);
switch (rand)
{
default:
_lives --;
_counterFlips++;
break;
case 1:
_heads ++;
_counterFlips++;
break;
}
if (_lives < 1)
{
MessageBox.Show(#"sorry you are out of lives m8");
button1.Enabled = false;
return;
}
lblFlips.Text = #"Flips = " + _counterFlips;
lblHeads.Text = #"Heads = " + _heads;
lblLivesLeft.Text = #"Lives Left = " + _lives;
}
}
Related
I am currently creating a CPU scheduling simulator program for my school project. Currently I'm stock with the error:
CS0122 Form1.AvgWaiting is inaccessible due to its protection level
And when i change TextBox to public from Form1Designer.cs, I get the error below:
CS0120 C# An object reference is required for the non-static field, method, or property
I have Form1.cs and a separate class for my algorithms. I will be using my algorithms to display output for my datagridview and textbox.
My Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CPU_Scheduling_Simulator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// set default values to comboBox
foreach (Control cont in this.Controls)
{
if (cont is ComboBox)
{
((ComboBox)cont).SelectedIndex = 0;
}
}
}
public void Form1_Load(object sender, EventArgs e)
{
}
public void groupBox2_Enter(object sender, EventArgs e)
{
}
public void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
public void button1_Click(object sender, EventArgs e)
{
Close();
}
public void buttonGenerate_Click(object sender, EventArgs e)
{
dataGridView1.Rows.Clear();
int count = int.Parse(comboBoxProcess.GetItemText(comboBoxProcess.SelectedItem));
if (comboBoxProcess.SelectedIndex == -1)
MessageBox.Show("Please select num of Process");
else
{
dataGridView1.Rows.Add(count);
for (int i = 0; i < count; i++)
{
dataGridView1.Rows[i].Cells["Processes"].Value = "" + (i+1);
}
}
}
public void buttonClear_Click(object sender, EventArgs e)
{
foreach (Control control in this.Controls)
{
if (control is TextBox)
((TextBox)control).Text = null;
}
dataGridView1.Rows.Clear();
}
public void groupBox5_Enter(object sender, EventArgs e)
{
}
public void buttonSimulate_Click(object sender, EventArgs e)
{
int count = int.Parse(comboBoxProcess.GetItemText(comboBoxProcess.SelectedItem));
int index = comboBoxAlgorithm.SelectedIndex;
switch (index)
{
case 0:
// Process id's
int[] processes = new int[count];
int n = processes.Length;
// Burst time of all processes
int[] burst_time = new int[n];
for (int x = 0; x < n; x++)
burst_time[x] = int.Parse((string)dataGridView1.Rows[x].Cells["BurstTime"].Value);
// Arrival time of all processes
int[] arrival_time = new int[n];
for (int x = 0; x < n; x++)
arrival_time[x] = int.Parse((string)dataGridView1.Rows[x].Cells["ArrivalTime"].Value);
FCFS.findavgTime(processes, n, burst_time, arrival_time);
break;
default:
MessageBox.Show("Please select an Algorithm");
break;
}
}
}
}
My FCFS.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CPU_Scheduling_Simulator
{
public class FCFS
{
// Function to find the waiting time for all
// processes
public static void findWaitingTime(int[] processes, int n, int[] bt, int[] wt, int[] at)
{
int[] service_time = new int[n];
service_time[0] = 0;
wt[0] = 0;
// calculating waiting time
for (int i = 1; i < n; i++)
{
// Add burst time of previous processes
service_time[i] = service_time[i - 1] + bt[i - 1];
// Find waiting time for current process =
// sum - at[i]
wt[i] = service_time[i] - at[i];
// If waiting time for a process is in negative
// that means it is already in the ready queue
// before CPU becomes idle so its waiting time is 0
if (wt[i] < 0)
wt[i] = 0;
}
}
// Function to calculate turn around time
public static void findTurnAroundTime(int[] processes, int n, int[] bt,
int[] wt, int[] tat)
{
// Calculating turnaround time by adding bt[i] + wt[i]
for (int i = 0; i < n; i++)
tat[i] = bt[i] + wt[i];
}
// Function to calculate average waiting and turn-around
// times.
public static void findavgTime(int[] processes, int n, int[] bt, int[] at)
{
int[] wt = new int[n]; int[] tat = new int[n];
// Function to find waiting time of all processes
findWaitingTime(processes, n, bt, wt, at);
// Function to find turn around time for all processes
findTurnAroundTime(processes, n, bt, wt, tat);
// Display processes along with all details
//Console.Write("Processes " + " Burst Time " + " Arrival Time "
// + " Waiting Time " + " Turn-Around Time "
// + " Completion Time \n");
int total_wt = 0, total_tat = 0;
for (int i = 0; i < n; i++)
{
total_wt = total_wt + wt[i];
total_tat = total_tat + tat[i];
int compl_time = tat[i] + at[i];
//Console.WriteLine(i + 1 + "\t\t" + bt[i] + "\t\t"
// + at[i] + "\t\t" + wt[i] + "\t\t "
// + tat[i] + "\t\t " + compl_time);
Form1.dataGridView1.Rows[i].Cells["Processes"].Value = i + 1;
Form1.dataGridView1.Rows[i].Cells["BurstTime"].Value = bt[i];
Form1.dataGridView1.Rows[i].Cells["ArrivalTime"].Value = at[i];
Form1.dataGridView1.Rows[i].Cells["WaitingTime"].Value = wt[i];
}
//Console.Write("Average waiting time = "
// + (float)total_wt / (float)n);
//Console.Write("\nAverage turn around time = "
// + (float)total_tat / (float)n);
Form1.AvgWaiting.Text = ""+(float)total_wt / (float)n);
Form1.AvgTurnaround.Text ""+(float)total_tat / (float)n);
}
// Driver code
}
}
Also can someone link me to a working gantt chart and ready queue source code in C# so I can study it. I found one on youtube but its in Java link
Btw, thank you so much for helping a newbie like me. I know i have much to learn and it was easier to learn with all your help.
Form1 is the class name not an instance of that class. If you want to refer to an existing instance you need to pass the instance where is needed or retrieve it from the Application.OpenForms collection
So for example you can write this before using Form1
var f1 = Application.OpenForms.OfType<Form1>().FirstOrDefault();
if(f1 != null)
{
// use f1 wherever you use Form1.
}
this will work if you have just one instance of Form1 opened in the same timeframe. If you have more than one instance then you need to pass the instance of the current Form1 to the FCFS method
FCFS.findavgTime(processes, n, burst_time, arrival_time, this);
break;
and
public static void findavgTime(int[] processes, int n, int[] bt, int[] at, Form1 f1)
{
// and again use f1 instead of Form1
For my code, it is a number guessing game. They get 10 guesses before they lose, and it tells them if it is too low, too high etc. In my output when I'm telling them if they are too high or too low, I also wanted to display how many guesses they have left. But currently it tells them they have 9 guesses left every time and I'm not sure why.
The rest of the program works. So after 10 guesses it will tell them they lost, just every guess up until then it says they have 9 guesses left.
namespace NumberGuessingGame
{
public class GuessingGame
{
int myGuess = 0;
int guessesLeft = 10;
int gamesPlayed = 0;
int gamesWon = 0;
int gamesLost = 0;
Random rand;
int number = 0;
public GuessingGame()
{
rand = new Random();
number = rand.Next(1, 100);
}
public void ResetGame()
{
number = rand.Next(1, 100);
guessesLeft = 10;
}
public int CheckGuess(int newGuess)
{
myGuess = newGuess;
if (guessesLeft < 1)
{
gamesLost++;
gamesPlayed++;
ResetGame();
return 2;
}
else if (myGuess > number)
{
guessesLeft--;
return 1;
}
else if (myGuess < number)
{
guessesLeft--;
return -1;
}
else
{
gamesPlayed++;
gamesWon++;
ResetGame();
return 0;
}
}
}
}
Code for form class
namespace NumberGuessingGame
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
GuessingGame myGuess = new GuessingGame();
private void btnCheck_Click(object sender, EventArgs e)
{
int inputGuess = Convert.ToInt32(txtGuess.Text);
int result = myGuess.CheckGuess(inputGuess);
int guessesLeft = 10;
if(result == 2)
{
MessageBox.Show("You ran out of guesses and lost!");
}
else if(result == 1)
{
guessesLeft--;
MessageBox.Show("Your guess was too high, try again!" + "\n You have " + guessesLeft + " guesses left");
}
else if(result == -1)
{
guessesLeft--;
MessageBox.Show("Your guess was too low, try again!" + "\n You have " + guessesLeft + " guesses left");
}
else if(result == 0)
{
MessageBox.Show("You won!");
}
}
}
}
Every time the button is clicked, you set guessesLeft to 10, which causes the issue. If you make guessesLeft a private field it will be fixed.
Like this:
public partial class frmMain : Form
{
private int guessesLeft = 10;
etc.
private void btnCheck_Click(object sender, EventArgs e)
{
int guessesLeft = 10;
This guessesLeft is a local variable on the stack of btnCheck_Click(). It is destroyed when the function returns, and is re-created and reinitialized to 10 every time the button is pressed and the function is called.
You need to expose the guessesLeft from your GuessingGame class. The best way would be via a read-only property:
public class GuessingGame
{
// ...
public int GuessesRemaining
{
get { return guessesRemaining; }
}
You have 2 separate guessesLeft variables - one in your btnCheck_Click event method, and one in your GuessingGame class. Every time you click the button, it initializes a new guessesLeft and sets it to 10, decrements it, and then the variable goes out of scope. You should only have one variable that holds that information, and the best place would be in your guessingGame class as a public property:
public class GuessingGame
{
public int GuessesLeft { get; private set; }
}
and use that in your click event:
MessageBox.Show("Your guess was too high, try again!" + "\n You have "
+ myGuess.GuessesLeft + " guesses left");
You are re-initializing the guessesLeft variable to 10 everytime the button is clicked. You instead want to query the variable from the GuessingGame object you created called myGuess.
The program is a simple number guessing game however when i randomize the guesses unity tends to pick the same number multiple times is there a way to have it know what numbers it already picked? an also is there a way to make it automatically go to the lose scene if it can't pick another number? any help is appreciated ^_^
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class NumberGuesser : MonoBehaviour {
int min;
int max;
int guess;
int maxGuessesAllowed = 15;
public Text text;
//guess = (max + min) / 2;
// Use this for initialization
void Start () {
min = 1;
max = 1000;
NextGuess();
max = max + 1;
}
// Update is called once per frame
public void guessHigher () {
min = guess;
NextGuess ();
}
public void guessLower() {
max = guess;
NextGuess();
}
void NextGuess(){
guess = (max + min) / 2;
//guess = Random.Range (min,max);//Randomizes Guesses
//print (guess);
text.text = guess.ToString ();
maxGuessesAllowed = maxGuessesAllowed - 1;
if (maxGuessesAllowed <= 0) {
Application.LoadLevel ("Win");
}
}
}//main
Try this:
List<int> alreadyGuessed = new List<int>();
...
int NextGuess()
{
int theGuess = Random.Range(min, max);
while(alreadyGuessed.Contains(theGuess))
theGuess = Random.Range(min, max);
alreadyGuessed.Add(theGuess);
return theGuess;
}
It keeps track of what has been guessed and keeps on guessing until the guess has not been guessed before.
Just add this at top of your code
List<int> used = new List<int>();
you may want to add this using too
using System.Collections.Generic;
and then change your NextGuess function to this
void NextGuess()
{
guess = Random.Range (min,max);
while(used.Contains(guess))
guess = Random.Range (min,max);
used.Add (guess);
text.text = guess.ToString ();
maxGuessesAllowed = maxGuessesAllowed - 1;
if (maxGuessesAllowed <= 0) {
Application.LoadLevel ("Win");
}
}
This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 8 years ago.
This WP8 quiz app (questions ommited for obvious reasons) keeps repeating the questions as if it's generating the same random numbers over and over. There's a list creation function that shuffles the questions and the generator itself.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Media;
namespace GamingQuiz
{
public partial class GamePage : PhoneApplicationPage
{
public GamePage()
{
InitializeComponent();
ques();
// PotterGay();
}
int MyNumber = 0;
question[] q = new question[101];
public void ques()
{
//questions are here e.g. q[0]=new question("question","a1","a2","a3","a4",correctanswer)
}
// int[] murica = new int[101];
// int MyNumber = 0;
List<int> murica = new List<int>();
public void PotterGay()
{
int hue = 0;
Random a = new Random(100);
while (hue<100){
MyNumber = a.Next(0,100);
if (!murica.Contains(MyNumber))
{
murica.Add(MyNumber);
hue++;
}
}
}
int vCorect = 0;
public void end()
{
intrebare.Visibility = Visibility.Collapsed;
vd.Text = "DICKY DICKY";
var1.Visibility = Visibility.Collapsed;
var2.Visibility = Visibility.Collapsed;
var3.Visibility = Visibility.Collapsed;
var4.Visibility = Visibility.Collapsed;
}
int j = 0;
int fatista = 0;
public void right()
{
fatista = murica[j];
// Random asdf = new Random();
/// j = asdf.Next(100);
intrebare.Text = q[fatista].quest;
var1.Content = q[fatista].v1;
var2.Content = q[fatista].v2;
var3.Content = q[fatista].v3;
var4.Content = q[fatista].v4;
vCorect = q[fatista].gj;
j++;
}
public void start_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
PotterGay();
right();
start.Visibility = Visibility.Collapsed;
}
int scor = 0;
int baba = 0;
private void var_tap(object sender, System.Windows.Input.GestureEventArgs e)
{
{
switch ((string)((Button)sender).Name)
{
case "var1":
if (vCorect == 1)
{
scor++;
vd.Text = "Correct!";
baba++;
}
else
{
scor--;
vd.Text = "Wrong!";
baba++;
}
break;
case "var2":
if (vCorect == 2)
{
scor++;
vd.Text = "Correct!";
baba++;
}
else
{
scor--;
vd.Text = "Wrong!";
baba++;
}
break;
case "var3":
if (vCorect == 3)
{
scor++;
vd.Text = "Correct!";
baba++;
}
else
{
scor--;
vd.Text = "Wrong!";
baba++;
}
break;
case "var4":
if (vCorect == 4)
{
scor++;
vd.Text = "Correct!";
baba++;
}
else
{
scor--;
vd.Text = "Wrong!";
baba++;
}
break;
}
}
if (baba < 101)
{
right();
puncte.Text = Convert.ToString(scor);
}
else
{
murica.Clear();
end();
}
}
}
}
Your problem is here
Random a = new Random(100);
The 100 in there is what is known as the SEED. Randoms which have the same seed will always give the same permutations of numbers.
You'll either want the default
Random a = new Random();
or a seed which is 'random'
Random a = new Random(DateTime.Now.Miliseconds);
To quote the actual documentation
Providing an identical seed value to different Random objects causes
each instance to produce identical sequences of random numbers.
If your application requires different random number sequences, invoke
this constructor repeatedly with different seed values. One way to
produce a unique seed value is to make it time-dependent.
You should only call new Random once and keep re-using the Random Number Generator. If you keep newing it up with the same seed 100, then the sequence of numbers you get will always be the same.
Firstly, the 100 in the call to generate the RNG is called a seed and by specifying it, you will get a known series of pseudo-random numbers.
Secondly, remove the Random a = new Random(100); line out of the PotterGay() method and make it a class member instead (private Random a = new Random();). You should only need one RNG for this. Fast, repeated calls to the PotterGay() method could wind up generating the same random sequence, even without the specified seed.
I'm working on a small programme for booking seats on an airplane - And I keep getting this error. i want the programme to show me which seats on the plane (flysaeder) are being booking by what passenger (passagerer). Only, If I enter in more seats than I have passengers, it won't run - I need it to allow open seats (less "passagerer" than "flysaeder"). What am I doing wrong?
I'm kinda new at this, so I apologize for poor explanation.
Error occurs on "listeOverPassagerer[index] = listeOverPassagerer[i];".
namespace eksamenvingerne
{
public partial class Form1 : Form
{
int flysaeder;
int passagerer;
Random tilfældighed = new Random();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
listBox2.Items.Clear();
{
int.TryParse(txtsaeder.Text, out flysaeder);
int.TryParse(txtantalpassagere.Text, out passagerer);
if (passagerer > flysaeder)
{
MessageBox.Show("Ingen frie pladser!");
}
else
{
int[] listeOverPassagerer = Enumerable.Range(0, passagerer).ToArray();
int[] flypladser = new int[flysaeder];
for (int i = 0; i < flysaeder; i++)
{
int index = tilfældighed.Next(0, passagerer);
flypladser[i] = tilfældighed.Next(i, passagerer);
flypladser[i] = listeOverPassagerer[index];
listeOverPassagerer[index] = listeOverPassagerer[i];
}
for (int i = 0; i < flypladser.Length; i++)
{
listBox1.Items.Add("Sæde #" + i + ": Passagernr.:" + flypladser[i]); //listboxen udskriver indholdet af hver eneste plads.
}
}
}
}
}
}
Your logic actually is causing this problem:
First you make sure that passagerer <= flysaeder
if (passagerer > flysaeder)
{
MessageBox.Show("Ingen frie pladser!");
}
Then you do a for loop from 0 to flysaeder -1
for (int i = 0; i < flysaeder; i++)
But flysaeder might be larger than passagerer hence your access of listeOverPassagerer[i] will throw an exception since listeOverPassagerer is of length passagerer