C# visual studio error use of unassigned local variable - c#

I am making a simple program that when a button is clicked it displays a card in the label
Using random number generator to create a number between 1-4 (and set to either hearts, diamonds, clubs or spades)
also another generator to create a number between 1-13 (and then set to either ace, 1,2,3,4,5,6,7,8,9,10,jack,queen,king)
then using if statement to set the suit to which is called
then using switch statement to set the card to its respective card
but i am receiving an error:
Error CS0165 when trying to build my program
here is my program:
program form1
here is my code:
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Random myRandom = new Random();
int suitNo, cardNo;
string suit, card;
suitNo = myRandom.Next(1, 4);
cardNo = myRandom.Next(1, 13);
if (suitNo == 1)
{
suit = "Hearts";
}
if (suitNo == 2)
{
suit = "Diamonds";
}
if (suitNo == 3)
{
suit = "Clubs";
}
if (suitNo == 4)
{
suit = "Spades";
}
switch (cardNo)
{
case 1:
card = "Ace";
break;
case 2:
card = "Two";
break;
case 3:
card = "Three";
break;
case 4:
card = "Four";
break;
case 5:
card = "Five";
break;
case 6:
card = "Six";
break;
case 7:
card = "Seven";
break;
case 8:
card = "Eight";
break;
case 9:
card = "Nine";
break;
case 10:
card = "Ten";
break;
case 11:
card = "Jack";
break;
case 12:
card = "Queen";
break;
case 13:
card = "King";
break;
}
label1.Text = "Your card is a " + card + " of " + suit;
}
any ideas as to why its giving me an error?

Your switch clause does not provide a default case and therefore the compiler can not statically deduce that a value will always be assigned to card. Even though in practice cardNo will be between 1 and 13, this can not be verified without running the program.
The same goes for suit of course.
Either initialize the values of suit and card before the switch clause or create a default case.
a good practice for when you do not expect any other value than those you have coded for is to provide a default case in which you simply throw an exception or Debug.Assert(false).
A simpler structure altogether would be to define
private static readonly string[] suits = { "Hearts", "Diamonds", "Clubs", "Spades" };
private static readonly string[] cards = { "Ace", ... , "King" };
And then your method could basically be reduced to:
int suitNo = myRandom.Next(suits.Length);
int cardNo = myRandom.Next(cards.Length);
string suit = suits[suitNo];
string card = cards[cardNo];
And absolve yourself from the verbose ifs and switches.

Both suit and card can be left unassigned as far as the compiler is concerned. You'll say "no way" since you always have 4 suits and 13 cards, but the compiler does not know how to play the game. Simple workaround is to initialize the variable in its declaration. – Hans Passant 9 hours ago
initializing the variables string suit and card at the beginning fixed my error,
You also have an error in your arguments for Random.Next. Due to this error, you will never get the King of Spades :-( (Check the documentation: learn.microsoft.com/en-gb/dotnet/api/…) – elgonzo 9 hours ago
also changing the myRandom.Next from 1,4 and 1,13 to 1,5 and 1,14 meant i now get all cards displayed, as #elgonzo pointed out, 1,4 and 1,13 would mean no king of spades would be drawn, not only just the king of spades but king from all suits and the entire spade suit would not be drawn - until i changed the upper limit to 1,5 and 1,14
see the working code below:
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Random myRandom = new Random();
int suitNo, cardNo;
string suit = "", card = "";
suitNo = myRandom.Next(1, 5);
cardNo = myRandom.Next(1, 14);
if (suitNo == 1)
{
suit = "Hearts";
}
if (suitNo == 2)
{
suit = "Diamonds";
}
if (suitNo == 3)
{
suit = "Clubs";
}
if (suitNo == 4)
{
suit = "Spades";
}
switch (cardNo)
{
case 1:
card = "Ace";
break;
case 2:
card = "Two";
break;
case 3:
card = "Three";
break;
case 4:
card = "Four";
break;
case 5:
card = "Five";
break;
case 6:
card = "Six";
break;
case 7:
card = "Seven";
break;
case 8:
card = "Eight";
break;
case 9:
card = "Nine";
break;
case 10:
card = "Ten";
break;
case 11:
card = "Jack";
break;
case 12:
card = "Queen";
break;
case 13:
card = "King";
break;
}
label1.Text = "Your card is a " + card + " of " + suit;

Related

Memory game doesn't open all cards upon starting

I'm making a memory game in C#. It has 10 pairs of cards, total 20. It's supposed to work like this: When pressing the Start button, the game shuffles randomly the cards and reveals all cards. After 3 seconds it flips them. Then, the player has to find all pairs.
I'm having a problem with shuffling. I wrote this code. It's being executed when I press the Start button:
foreach (String icon in icons)
{
int x1 = r.Next(1, 21);
int x2 = r.Next(1, 21);
if (!num.Contains(x1))
{
num.Add(x1);
}
else
{
do
{
x1 = r.Next(1, 21);
} while (!num.Contains(x1));
num.Add(x1);
}
if (!num.Contains(x2))
{
num.Add(x2);
}
else
{
do
{
x2 = r.Next(1, 21);
} while (!num.Contains(x2));
num.Add(x2);
}
switch (x1)
{
case 1:
pictureBox1.Image = Image.FromFile(icon);
break;
case 2:
pictureBox2.Image = Image.FromFile(icon);
break;
case 3:
pictureBox3.Image = Image.FromFile(icon);
break;
case 4:
pictureBox4.Image = Image.FromFile(icon);
break;
case 5:
pictureBox5.Image = Image.FromFile(icon);
break;
case 6:
pictureBox6.Image = Image.FromFile(icon);
break;
case 7:
pictureBox7.Image = Image.FromFile(icon);
break;
case 8:
pictureBox8.Image = Image.FromFile(icon);
break;
case 9:
pictureBox9.Image = Image.FromFile(icon);
break;
case 10:
pictureBox10.Image = Image.FromFile(icon);
break;
case 11:
pictureBox11.Image = Image.FromFile(icon);
break;
case 12:
pictureBox12.Image = Image.FromFile(icon);
break;
case 13:
pictureBox13.Image = Image.FromFile(icon);
break;
case 14:
pictureBox14.Image = Image.FromFile(icon);
break;
case 15:
pictureBox15.Image = Image.FromFile(icon);
break;
case 16:
pictureBox16.Image = Image.FromFile(icon);
break;
case 17:
pictureBox17.Image = Image.FromFile(icon);
break;
case 18:
pictureBox18.Image = Image.FromFile(icon);
break;
case 19:
pictureBox19.Image = Image.FromFile(icon);
break;
case 20:
pictureBox20.Image = Image.FromFile(icon);
break;
}
switch (x2)
{
case 1:
pictureBox1.Image = Image.FromFile(icon);
break;
case 2:
pictureBox2.Image = Image.FromFile(icon);
break;
case 3:
pictureBox3.Image = Image.FromFile(icon);
break;
case 4:
pictureBox4.Image = Image.FromFile(icon);
break;
case 5:
pictureBox5.Image = Image.FromFile(icon);
break;
case 6:
pictureBox6.Image = Image.FromFile(icon);
break;
case 7:
pictureBox7.Image = Image.FromFile(icon);
break;
case 8:
pictureBox8.Image = Image.FromFile(icon);
break;
case 9:
pictureBox9.Image = Image.FromFile(icon);
break;
case 10:
pictureBox10.Image = Image.FromFile(icon);
break;
case 11:
pictureBox11.Image = Image.FromFile(icon);
break;
case 12:
pictureBox12.Image = Image.FromFile(icon);
break;
case 13:
pictureBox13.Image = Image.FromFile(icon);
break;
case 14:
pictureBox14.Image = Image.FromFile(icon);
break;
case 15:
pictureBox15.Image = Image.FromFile(icon);
break;
case 16:
pictureBox16.Image = Image.FromFile(icon);
break;
case 17:
pictureBox17.Image = Image.FromFile(icon);
break;
case 18:
pictureBox18.Image = Image.FromFile(icon);
break;
case 19:
pictureBox19.Image = Image.FromFile(icon);
break;
case 20:
pictureBox20.Image = Image.FromFile(icon);
break;
}
There is also an auxiliary list "num" and a list "icons", which contains the names of the icons' files.
List<int> num = new List<int>();
List<String> icons = new List<String>() { "agelada.png", "elefantas.png", "gata.png", "gatopardos.png", "kamilopardali.png", "liontari.png", "lykos.png", "skylos.png", "tigris.png", "zebra.png" };
This code is supposed to work like this:
~It generates two random numbers, from 1 to 20 (the game has 20 cards), and stores them into x1 and x2 respectively.
~For each icon, member of the "icons" list: If x1 isn't found in the list num, it gets added in it. If x1 is found, a new number is being generated, until generating one that isn't in "num". Then it gets stored in "num". Same for x2. This process repeats for all the member of the list "icons".
~Then, depending of the randomly generated numbers, the icon gets inserted into the respective pictureBoxes, for example, if the numbers are 6 and 17, the picture is entered into pictureBox6 and pictureBox17.
The goal of this process is to make sure that all 10 pictures are displayed exactly twice, to make pairs.
However, I have a problem. When I click on Start, not all cards are flipped (The question mark is the "back side" of the cards). It looks like this:
Picture
It's supposed to show animal pictures in all cards.
Any ideas?
In addition to the recommendations around managing the PictureBox controls in arrays, I would recommend you change the line (not shown) where you create the Random object to something like this:
Random r = new Random(10);
Setting the seed like this while you're debugging will let you predict the output, and as you step through code from one run to the next run, it's easier to follow what's happening.
That said, if you stepped through this code:
do
{
x1 = r.Next(1, 21);
} while (!num.Contains(x1));
num.Add(x1);
If you stopped the code on adding the value to your array, you would have seen the value already exists in the array, which is the opposite of the intended action. That means your loop is exiting at the wrong time.
In this case, it's because your check is the opposite logic of what it should be, you want to keep running through this loop while the value is in the array. In other words, changing both loops to look like this:
do
{
x1 = r.Next(1, 21);
} while (num.Contains(x1));
num.Add(x1);
You will end up filling up your array with 20 unique values.

c# how to refer to current button

I am trying to make a minesweeper game using Windows Application. I would like to use a switch inside a method.
The problem:
public void switcher()
{
switch (x)
{
case 0:
A1.BackgroundImage = Image.FromFile("empty.jpg"); // look at A1
break;
case 1:
A1.BackgroundImage = Image.FromFile("1.jpg");
break;
case 2:
A1.BackgroundImage = Image.FromFile("2.jpg");
break;
case 3:
A1.BackgroundImage = Image.FromFile("3.jpg");
break;
case 4:
A1.BackgroundImage = Image.FromFile("4.jpg");
break;
case 5:
A1.BackgroundImage = Image.FromFile("5.jpg");
break;
case 6:
A1.BackgroundImage = Image.FromFile("6.jpg");
break;
case 7:
A1.BackgroundImage = Image.FromFile("7.jpg");
break;
case 8:
A1.BackgroundImage = Image.FromFile("8.jpg");
break;
}
}
As you can see, each of them says "A1. ....." A1 is my first button's name, but there are many other buttons as well. Is there a way I can refer to the button's properties, such as background image, without having to use its name? It would make programming so much easier.
Here's a simplified part of the button, if it helps:
private void A1_Click(object sender, EventArgs e) // < - I want to refer to this without using A1 name.
{
x = bombcount[0, 0];
switcher();
}
edit: One of the answers worked. I don't know much about these things, but I'll try to learn more about them! Thank you!
You need to refactor this code altogether. Don't rely on private members such as x like that, use method parameters:
private void SetButtonImage(Button button, int number)
{
string imagePath;
if (number == 0)
{
imagePath = "empty.jpg";
}
else
{
imagePath = number + ".jpg";
}
button.BackgroundImage = Image.FromFile(imagePath);
}
Then call it like this:
private void Button_Click(object sender, EventArgs e)
{
var button = sender as Button;
int number = bombcount[0, 0];
SetButtonImage(button, number);
}
Now you can hook up all button click events to that single event handler, and you can remove the x member, and you can remove the switch altogether.
Get a reference in switcher to the button being clicked like this:
private void A1_Click(object sender, EventArgs e)
{
Button myB = (Button) sender;
x = bombcount[0,0];
switcher(myB);
}
private void switcher(Button button)
{
switch (x)
{
case 0:
button.BackgroundImage = Image.FromFile("empty.jpg"); // look at A1
break;
case 1:
button.BackgroundImage = Image.FromFile("1.jpg");
break;
case 2:
button.BackgroundImage = Image.FromFile("2.jpg");
break;
case 3:
button.BackgroundImage = Image.FromFile("3.jpg");
break;
case 4:
button.BackgroundImage = Image.FromFile("4.jpg");
break;
case 5:
button.BackgroundImage = Image.FromFile("5.jpg");
break;
case 6:
button.BackgroundImage = Image.FromFile("6.jpg");
break;
case 7:
button.BackgroundImage = Image.FromFile("7.jpg");
break;
case 8:
button.BackgroundImage = Image.FromFile("8.jpg");
break;
}
}

How to display a variable mantissa length

I have a label on a form that displays a float (_DataFloat) with a variable (_Digits) that sets the number of digits to show to the right of the decimal point. Assuming that _Digits can be any value from 0 through 6, is there a better way of formatting the text other than using a switch statement as below?
switch (_Digits) {
case 0:
label1.Text = _DataFloat.ToString("0");
break;
case 1:
label1.Text = _DataFloat.ToString("0.0");
break;
case 2:
label1.Text = _DataFloat.ToString("0.00");
break;
case 3:
label1.Text = _DataFloat.ToString("0.000");
break;
case 4:
label1.Text = _DataFloat.ToString("0.0000");
break;
case 5:
label1.Text = _DataFloat.ToString("0.00000");
break;
case 6:
label1.Text = _DataFloat.ToString("0.000000");
break;
default:
label1.Text = _DataFloat.ToString("0.00");
break;
}
How about:
var format = String.Format("0.{0}", new string('0', _Digits));
label1.Text = _DataFloat.ToString(format);

c# Switch issue. Homework

This is what I have so far. My problem is that none of the cases are responding when you enter either the correct or incorrect answer. I'm not really sure where to go from here. The program asks you answer two random numbers being multiplied. And then it should give you one of the eight responses.
int result = 0;
int caseSwitch = 0;
string question = DoMultiplication(out result);
Console.WriteLine(question);
int answer = Convert.ToInt32(Console.ReadLine());
if (answer == result)
{
switch (caseSwitch)
{
case 1:
Console.WriteLine("Very Good");
break;
case 2:
Console.WriteLine("Excellent");
break;
case 3:
Console.WriteLine("Nice Work");
break;
case 4:
Console.WriteLine("Keep up the good work!");
break;
}
}
else
{
switch (caseSwitch)
{
case 1:
Console.WriteLine("No, Please Try Again.");
break;
case 2:
Console.WriteLine("Wrong, Try Once More");
break;
case 3:
Console.WriteLine("Don't Give Up!");
break;
case 4:
Console.WriteLine("No, Keep Trying!");
break;
caseSwitch is always 0, so your switch will always fall through without writing anything to console.
If you want a random response you could do something like this:
int result = 0;
int caseSwitch = new Random().Next(1, 4);
string question = DoMultiplication(out result);
Console.WriteLine(question);
int answer = Convert.ToInt32(Console.ReadLine());
if (answer == result)
{
switch (caseSwitch)
{
case 1:
Console.WriteLine("Very Good");
break;
case 2:
Console.WriteLine("Excellent");
break;
case 3:
Console.WriteLine("Nice Work");
break;
case 4:
Console.WriteLine("Keep up the good work!");
break;
}
}
else
{
switch (caseSwitch)
{
case 1:
Console.WriteLine("No, Please Try Again.");
break;
case 2:
Console.WriteLine("Wrong, Try Once More");
break;
case 3:
Console.WriteLine("Don't Give Up!");
break;
case 4:
Console.WriteLine("No, Keep Trying!");
break;
CaseSwitch is always = 0.
You need to assign a value to it, and-or add a default case to your switch.
You have your int caseSwitch = 0; and I don't see you changing it in your code to any of 1-4. So what do you expect it to do if you dont have the caseSwitch changed...

Switch case statement

I am trying to create an application in C# that converts numbers in a text box to roman numerals in a label control and need to use a case statement. However one of my variable Roman gets the error message: Use of unassigned local variable 'Roman'.
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Roman_Numeral_Converter
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCalc_Click(object sender, EventArgs e)
{
int Number=int.Parse(txtNum.Text); // To hold Number
string Roman; // To hold Roman Numeral
if (Number>=1 && Number <=10)
{
switch (Roman)
{
case "Number==1":
lblRoman.Text = "I";
break;
case "Number==2":
lblRoman.Text = "II";
break;
case "Number==3":
lblRoman.Text = "III";
break;
case "Number==4":
lblRoman.Text = "IV";
break;
case "Number==5":
lblRoman.Text = "V";
break;
case "Number==6":
lblRoman.Text = "VI";
break;
case "Number==7":
lblRoman.Text = "VII";
break;
case "Number==8":
lblRoman.Text = "VIII";
break;
case "Number==9":
lblRoman.Text = "IX";
break;
case "Number==10":
lblRoman.Text = "X";
break;
}
}
else
{
MessageBox.Show("Error: Invalid Input");
}
}
private void btnExit_Click(object sender, EventArgs e)
{
// Close the form.
this.Close();
}
private void btnClear_Click(object sender, EventArgs e)
{
txtNum.Text = "";
lblRoman.Text = "";
}
}
}
Your structure is a little off.
private void btnCalc_Click(object sender, EventArgs e)
{
var Number = int.Parse(txtNum.Text); // To hold Number
switch (Number)
{
case 1:
lblRoman.Text = "I";
break;
case 2:
lblRoman.Text = "II";
break;
case 3:
lblRoman.Text = "III";
break;
case 4:
lblRoman.Text = "IV";
break;
case 5:
lblRoman.Text = "V";
break;
case 6:
lblRoman.Text = "VI";
break;
case 7:
lblRoman.Text = "VII";
break;
case 8:
lblRoman.Text = "VIII";
break;
case 9:
lblRoman.Text = "IX";
break;
case 10:
lblRoman.Text = "X";
break;
default:
MessageBox.Show("Error: Invalid Input");
break;
}
}
You're using the lblRoman to hold your result, thus your Roman variable is unnecessary. Additionally, since you're interrogating every possible valid number in your switch, you can just use the default to replace your if/else structure.
I'm assuming you're doing this as an academic exercise. That being said, I would be remiss not to point to you Mosè Bottacini's solution to this problem.
This is because Roman variable is really unassigned. You should assign it before you enter the statement
try this,
when your number value like 1 so roman number is I.
private void btnCalc_Click(object sender, EventArgs e)
{
int Number = int.Parse(txtNum.Text); // To hold Number
string Roman; // To hold Roman Numeral
if (Number >= 1 && Number <= 10)
{
switch (Number)
{
case 1:
lblRoman.Text = "I";
break;
case 2:
lblRoman.Text = "II";
break;
case 3:
lblRoman.Text = "III";
break;
case 4:
lblRoman.Text = "IV";
break;
case 5:
lblRoman.Text = "V";
break;
case 6:
lblRoman.Text = "VI";
break;
case 7:
lblRoman.Text = "VII";
break;
case 8:
lblRoman.Text = "VIII";
break;
case 9:
lblRoman.Text = "IX";
break;
case 10:
lblRoman.Text = "X";
break;
}
}
else
{
MessageBox.Show("Error: Invalid Input");
}
}
Instead of switch, You can do other way using Linq which is even better.
int Number=int.Parse(txtNum.Text);
var romanList = new List<string> {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"};
if (Number >= 1 && Number <= 10)
lblRoman.Text = romanList.Select((r, i) => new { Roman = r, Index = i+1}).FirstOrDefault(x=> x.Index == Number).Roman;
you can replace your switch statement this way. and of course you need to assign a variable before using it.
public string GetNum(string val)
{
string res = ""; // Assign it an empty string.
var numToRom = new Dictionary<string, string>
{
{"1","I"},
{"2","II"}
//so on
};
numToRom.TryGetValue(val, out res);
return res;
}

Categories

Resources