im doing a slot machine game , its a simple one , that basically it will roll the image in the picurebox into a random image. using this code
PictureBox[] PictureboxArray = new PictureBox[5];
the 5 picureboxes are assigned using this line of code
PictureboxArray[0] = pbxK;
PictureboxArray[1] = pbxQueen;
PictureboxArray[2] = pbxKing;
PictureboxArray[3] = pbxJoker;
PictureboxArray[4] = pbxAce;
Images are assigned like that
Image[] Rollimage = new Image[5];
Rollimage[0] = Properties.Resources.K;
Rollimage[1] = Properties.Resources.Queen;
Rollimage[2] = Properties.Resources.King;
Rollimage[3] = Properties.Resources.Joker;
Rollimage[4] = Properties.Resources.Ace;
and the intial image of the picturebox are assigned like that
pbxK.Image = Rollimage[0];
pbxQueen.Image = Rollimage[1];
pbxKing.Image = Rollimage[2];
pbxJoker.Image = Rollimage[3];
pbxAce.Image = Rollimage[4];
the actual code for the image rolling is as follows
for (int i = 0; i <= 4; i++)
{
if (PictureboxArray[i].Enabled == true)
{
Roll[i] = Rnd.Next(0, 4);
}
PictureboxImage(PictureboxArray[i], Roll[i]);
}
rnd is a new random
Random Rnd = new Random();
Roll in an int for saving the index of the roll
int[] Roll = new int[5];
everything works fine and the pictures rolls different image every second of the time , as I predefined that, now what im trying to do is to assign this
int[] PictureValues = new int[]{100, 225, 550, 775, 1000};
to the images
Image[] Rollimage = new Image[5];
meaning that the first roll image which is Properties.Resources.K;has the actual value of 100
and so on , is there a way to do that ?
So.. if I understand your issue correctly, once the image is selected, you need a way to reverse it back to associate it with a value. One method could be the following:
Note: It appears that each picturebox that is showing, is named king / joker etc.. so if you are looking at the front of the 'slot machine' you see 5 boxes which are named pbxk, pbxQueen, pbxKing, pbxJoker, pbxAce but they don't necessarily display the image associated with their name..
int total = 0;
for(int i=0;i<Rollimage.Length;i++)
{
if(pbxk.Image.Equals(Rollimage[i]))
{
total += PictureValues[i];
}
if(pbxQueen...)
{
//Do the same thing for each pbx
}
}
The only thing I'm not 100% on is the comparison method. Additionally, you could use the picturebox's ImageLocation property to store the path to the image whenever you assign it, and then compare that against a filename to figure out what image is showing.
Example on how to compare images: Stack Overflow Image Compare
Given that example, you may want to try == using your current Image array.. if that doesn't work, you may need to define an array of bitmaps to compare against. Seems like a waste of memory to me, but it should work.
Edit
The following code sums the values of the images correctly. I just put together a quick sample program with 2 pictureboxes, a control button and a label, with two resources. This should demonstrate all of the techniques required to perform what you are needing.
public partial class Form1 : Form
{
PictureBox[] PictureboxArray = new PictureBox[2];
Image[] Rollimage = new Image[2];
int[] pictureValues = new int[2];
public Form1()
{
InitializeComponent();
pictureValues[0] = 100;
pictureValues[1] = 200;
Rollimage[0] = Properties.Resources.TitleBar;
Rollimage[1] = Properties.Resources.Untitled;
PictureboxArray[0] = this.pictureBox1;
PictureboxArray[1] = this.pictureBox2;
PictureboxArray[1].Image = Rollimage[0];
PictureboxArray[0].Image = Rollimage[0];
}
private void button1_Click(object sender, EventArgs e)
{
int total = 0;
for(int i = 0;i<Rollimage.Length;i++)
{
foreach(var box in PictureboxArray)
{
if(box.Image == Rollimage[i])
{
total += pictureValues[i];
}
}
}
label1.Text = total.ToString();
}
}
Related
I've got myself into a little bit of a jam. As I tried to code the entire alphabet into my app, I didn't really feel like typing the letters in one by one, so I used ASCII characters and used a for-loop and inserted them as buttons. So, now I need those buttons to click according to my needs, but somehow I cant seem to figure out what is the problem with the issue. The code is as follows:
private void Hangman_OnLoaded()
{
const int btnSize = 35;
var c = 0;
for (var i = 65; i <= 90; i++)
{
var btn = new Button {
Content = (char) i,
Click += GuessClick()
};
btn.Width = btn.Height = btnSize;
var margin = btn.Margin;
margin.Left = c += 37;
btn.Margin = margin;
GridMain.Children.Add(btn);
}
}
private void GuessClick(object sender, EventArgs e) {
var choice = sender as Button;
if (choice == null || !copyCurrent.Contains(choice.DataContext.ToString())) return;
var temp = copyCurrent.ToCharArray();
var find = copyCurrent.ToCharArray();
var guessChar = choice.DataContext.ToString().ElementAt(0);
for (var index = 0; index < find.Length; index++) {
if (find[index] == guessChar) {
temp[index] = guessChar;
}
}
copyCurrent = new string(temp);
DisplayTheWord();
}
I will take a stab at "Psychic Debugging" this code. There are lots of things that can be improved, changed, etc, but I am guessing this is where you may be having an issue:
var temp = copyCurrent.ToCharArray();
var find = copyCurrent.ToCharArray();
var guessChar = choice.DataContext.ToString().ElementAt(0);
for (var index = 0; index < find.Length; index++) {
if (find[index] == guessChar) {
temp[index] = guessChar;
}
}
copyCurrent = new string(temp);
No matter what the guessChar is, at the end of this block of code copyCurrent will be unchanged (as far as what the actual string content of copyCurrent is). First you make two arrays that are identical. Then you are looping through the find array looking for the guessChar. If you find the guessChar then you are "modifying" the temp array to have guessChar at the very same index where you found it in find. Since both arrays are identical, the end result is that no "change" takes place. Once you have executed the loop you are creating a new string from the temp array, but since both find and temp are identical and unchanged after this loop, you effectively are making a new string that is identical to the one you started with. I don't know what you are expecting this code to do, but I am assuming this is not it.
I am going to assume (from the load method name) that this is a game of hangman and that at the outset of the game copyCurrent has some content like "????" and that you have some other variable, maybe called answer and it would have the content, for example, "food". If that is the case, then you would just need to modify these two lines:
var temp = copyCurrent.ToCharArray();
var find = answer.ToCharArray();
I want to make button array that include string and integer. I have 30 buttons and named B1, B2, ...., B30 and I want to change their color depend on the counter value. How can I do that? These are what I have done and I stuck
for(Cnt = 0; cnt < 30; cnt++)
{
Button[] Tombol = new Button[]{"B"+(cnt+1)};
Tombol[cnt].BackColor = Color.Red
}
The Control (custom) initialization in the Form (in your case, the Control being a Button) requires more than a simple declaration. Apart from giving name (which you do), two other important things to do are:
To add it to the Control parent
To locate it nicely
Thus, adding those considerations to the Button you are to create, you could do something like this
int noOfBtns = 30;
Button[] Tombols = new Button[30]; //actually, you may not need this at all
for (int cnt = 0; cnt < numOfBtns; cnt++)
{
Button tombol = new Button();
tombol.BackColor = Color.Red;
tombol.Location = new Point(5, cnt * 25); //Read (2) please formulate this more properly in your case
tombol.Name = "B" + (cnt + 1).ToString();
// others like size (maybe important depending on your need), color, etc
this.Controls.Add(tombol); //Read (1) this refers to the `Form` if the parent control you want to put your button to is `Form`. But change the `this` as you see fit
Tombols[cnt] = tombol; //again, actually you may not need this at all
}
Take care of how you formulate the location of your button, very important. The example I gave above is really simple formulation, which might not fit if your number of buttons grow large. But that gives you the basic idea on how important it is to set the location of the Button right.
You may need the array of Button at all, unless for some reason you want to list it. But even you want to list it, you should use List and List.Add instead of Array.
I suggest using Linq to generate the array:
Button[] Tombol = Enumerable
.Range(0, 30)
.Select(i => new Button() {
Text = String.Format("B{0}", i + 1),
BackColor = Color.Red,
//TODO: compute desired color as function of "i" like
// BackColor = Color.FromArgb(i * 8, 255 - i * 8, 128),
//TODO: assign Parent, Location, Size etc. like this:
// Parent = this,
// Location = new Point(10 + 40 * i, 10),
// Size = new Size(35, 20),
})
.ToArray();
I mean like this:
Button[] Tombol = new Button[30];
for(cnt = 0; cnt < 30; cnt++)
{
Tombol[cnt] = new Button
{
Text = "B" + (cnt+1),
BackColor = Color.Red
};
}
First you create the array and in the for loop you instantiate the actual buttons one by one.
You have to initialize the button array first
int numOfBtns = 30;
Button[] Tombol = new Button[numOfBtns];
and after you can fill required items
for (int cnt = 0; cnt < numOfBtns; cnt++)
{
// Name, Content, Foreground .. whatever
Tombol[cnt].Name = "B" + (cnt + 1);
}
At the moment you are recreating your array on each loop of your code rather than creating the array outside of the loop and then adding buttons to it in the loop.
In addition all your buttons are being created in the same position, so they are on top of each other meaning you can only see one of them.
Try something like this, based on a modified version of the code from this previous answer which creates the buttons, adds them to a list you can search and the sets the positions of the buttons too:
int top = 50;
int left = 100;
var buttons = new Dictionary<string, Button>();
for (int i = 0; i < 30; i++)
{
Button button = new Button();
buttons.Add("B"+i, button);
button.Left = left;
button.Top = top;
this.Controls.Add(button);
top += button.Height + 2;
button.BackColor = Color.Red;
}
You can then refer to an individual button later with the code:
buttons["B3"].BackColor= Color.Green;
I am working on an assignment for school (Assignment Here).
I am currently trying to shuffle a deck of cards. I have used PlayingCards from Codeplex (sorry, could only have two links...) to create a collection of cards to create a deck. Please help, when I click the Shuffle button, nothing happens. You can see my progress here it's easier to see the entire code: Github
public void Shuffle()
{
PlayingCards.Deck theDeck = new PlayingCards.Deck();
random = new Random();
for (int i = 0; i < theDeck.Cards.Count; i++)
{
int second = random.Next(NUMBER_OF_CARDS);
PlayingCards.Card temp = theDeck.Cards[i];
theDeck.Cards[i] = theDeck.Cards[second];
theDeck.Cards[second] = temp;
}
}
You are creating a new instance of PlayingCards.Deck, shuffling it, and then throwing it away at the end of the shuffle.
PlayingCards.Deck theDeck = new PlayingCards.Deck();
You need to change the call to Shuffle to include PlayingCards.Deck as a parameter, so you should be doing this:
public void Shuffle(PlayingCards.Deck theDeck)
{
random = new Random();
for (int i = 0; i < theDeck.Cards.Count; i++)
{
int second = random.Next(NUMBER_OF_CARDS);
PlayingCards.Card
temp = theDeck.Cards[i];
theDeck.Cards[i] = theDeck.Cards[second];
theDeck.Cards[second] = temp;
}
}
You should also move the new Random() outside of this method as you may find that if you tried to create two shuffled decks immediately after one another that they'll have the same order because the seed Random uses is based on the system clock.
I had a look at the code you've got for adding the cards to the deck. You should use this code instead:
foreach (var face in Enum.GetValues(typeof(PlayingCards.CardSuits)).Cast<PlayingCards.CardSuits>())
{
foreach (var value in Enum.GetValues(typeof(PlayingCards.CardValues)).Cast<PlayingCards.CardValues>())
{
theDeck.Cards.Add(new PlayingCards.Card(face, value));
}
}
I have a button event in which generates some random numbers based upon the number typed into a textbox (for example, if I type 5, it should generate 5 different random numbers). When I type in a number into the textbox, and click the btnGenerateScores button, it generates a single number and puts that number in the listbox 5 times (or however many times based upon the number in the textbox). This behavior is not correct, it should generate 5 different numbers and list each in the listbox. If I put a MessageBox.Show (I was using it for debugging) command anywhere in the code block, it works correctly. Commenting out the MessageBox.show breaks the code. Does anyone see any reason why it would not work correctly when I don't show the message box? The code is below:
private void btnGenerateScores_Click(object sender, EventArgs e)
{
strInput = txtInputNumber.Text;
intRandCount = Convert.ToInt16(strInput);
scoresArray = new int[intRandCount];
intArrayCount = scoresArray.Length;
btnGenerateScores.Enabled = false;
// Loop to generate random number
for (intRndCount = 0; intRndCount < intRandCount; intRndCount++)
{
GetRand(intRandCount);
scoresArray[intCount] = intRandomNum;
intGenRandom = intRandomNum;
intArrScores = scoresArray[intCount];
lstRdmScores.Items.Add(Convert.ToString(intArrScores));
insertionSortArray = new int[intArrayCount];
Array.Copy(scoresArray, insertionSortArray, intArrayCount);
// Instantiate an instance of the class
arraySort mySort = new arraySort();
// Get the number of elements to store in the array
string s = Convert.ToString(intCount);
mySort.x = Int16.Parse(s);
// Get array elements
for (int i = 0; i < mySort.x; i++)
{
intInsertionSort = insertionSortArray[intCount];
string s1 = Convert.ToString(intInsertionSort);
mySort.a[i] = Int16.Parse(s1);
}
// Sort the array and display in the second list box
mySort.sortArray();
intSortScores = insertionSortArray[intCount];
lstSortScores.Items.Add(Convert.ToString(intSortScores));
// This is the the MessageBox.Show command in question:
MessageBox.Show("The random number generated is: "); //+ Convert.ToString(intGenRandom));
}
}
ignore the fact that the array does not sort correctly, I will get to that later. I want to work on one thing at a time.
I am using VS 2013 and the code was originally created in VS 2005.
As your requirement, and view the source, I rewrite the app for short:
private void btnGenerateScores_Click_1(object sender, EventArgs e)
{
int genTimes;
if (Int32.TryParse(txtInputNumber.Text, out genTimes))
{
var ints = new List<int>();
for (var i = 0; i < genTimes; i++)
{
var r = new Random(Guid.NewGuid().GetHashCode());
var rInt = r.Next(0, int.MaxValue); //for ints
ints.Add(rInt);
}
var copyInts = ints.ToList();
copyInts.AddRange(this.listBox1.Items.Cast<int>());
copyInts = copyInts.Distinct().OrderBy(x => x).ToList();
this.listBox1.Items.Clear();
this.listBox1.Items.AddRange(copyInts.Cast<object>().ToArray());
MessageBox.Show("The random number generated is: " + String.Join(",", ints));
}
}
}
Hope this help.
When I say I'm a beginner, I really am as fresh as you can get so apologies up front!
What I am trying to do is in a form have two picture boxes and a button. When I click on the button it picks 2 new images from my image folder and it will do this a total of 5 times
Any ideas how I approach this - Here's what I have so far for the button click
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Load(#"C:\Resources\PICT01.JPG");
pictureBox2.Load(#"C:\Resources\PICT02.JPG");
}
Any answers really need to be basic as I am just learning ! Thanks in advance
You need to create a global int to keep track of how often you have switched pictures, and handle that number in your button1_click.
I'm no expert myself but here's how i would do it. A switch is ideal here because you need to check 5 different possibilities.
//global int
int count = 0;
private void button1_Click(object sender, EventArgs e)
{
count++;
switch(count)
{
case 1:
//load image 1 and 2
break;
case 2:
//load image 3 and 4
break;
case 3:
//load image 5 and 6
break;
case 4:
//load image 7 and 8
break;
case 5:
//load image 9 and 10
break;
default:
break;
}
}
This sample program will create a list of all jpg-files in MyPictures folder and pick random pictures from the list, when the list is empty it will raise an exception.
public Form1()
{
// Reading pictures from My Pictures:
string path = Environment.GetFolderPath(Environment.SpecialFolders.MyPictures);
DictionaryInfo myPictures = new DictionaryInfo(path);
FPictureFiles = myPictures.GetFiles("*.jpg", SearchOption.AllDirectories).ToList();
}
private List<FileInfo> FPictureFiles;
private Random FRandom = new Random();
private void button1_Click(object sender)
{
pictureBox1.Load(PickFile());
pictureBox2.Load(PickFile());
}
private string PickFile()
{
if (FPictureFiles.Count == 0) throw new Exception("No more picture files");
int index = FRandom.Next(FPictureFiles.Count);
string filename = FPictureFiles[index].FullName;
FPictureFiles.RemoveAt(index);
return filename;
}
I hope this will help you in your quest.
You may try to create a new List<string> which lists all files having a specific extension of your selection. Then, initialize a new Random class which gets a random number within a specific range considering that the range will not be more than our List<string>.Count value.
Example
Assuming that CurrentClicks identifies a new integer and MaximumClicks is our maximum value
public Form1()
{
InitializeComponent();
button1.Click += new EventHandler(button1_Click); //Link the Click event of button1 to button1_Click
}
const int MaximumClicks = 5; //Initialize a new constant int of value 5 named MaximumClicks
int CurrentClicks = 0; //Initialize a new variable of name CurrentClicks as an int of value 0
the following may apply
private void button1_Click(object sender, EventArgs e)
{
if (CurrentClicks < MaximumClicks) //Continue if CurrentClicks is less than 5
{
string FilesPath = #"D:\Resources\International"; //Replace this with the targeted folder
string FileExtensions = "*.png"; //Applies only to .png file extensions. Replace this with your desired file extension (jpg/bmp/gif/etc)
List<string> ItemsInFolder = new List<string>(); //Initialize a new Generic Collection of name ItemsInFolder as a new List<string>
foreach (string ImageLocation in Directory.GetFiles(FilesPath, FileExtensions)) //Get all files in FilesPath creating a new string of name ImageLocation considering that FilesPath returns a directory matching FileExtensions considering that FileExtensions returns a valid file extension within the targeted folder
{
ItemsInFolder.Add(ImageLocation); //Add ImageLocation to ItemsInFolder
}
Random Rnd = new Random(); //Initialize a new Random class of name Rnd
int ImageIndex = Rnd.Next(0, ItemsInFolder.Count); //Initialize a new variable of name ImageIndex as a random number from 0 to the items retrieved count
pictureBox1.Load(ItemsInFolder[ImageIndex]); //Load the random image based on ImageIndex as ImageIndex belongs to a random index in ItemsInFolder
CurrentClicks++; //Increment CurrentClicks by 1
}
else
{
//Do Something (MaximumClicks reached)
}
}
This will get the file locations within the provided folder matching a specified extension. Then, loads a random file from the file locations gathered into a PictureBox of name pictureBox1.
This will however not avoid files that were added previously to the PictureBox. If you would like to avoid duplicates, you may create a new int array or List<int> and add every ImageIndex that was applied to the PictureBox but it's recommended to go with List<int> because it seems easier to manage
Example
List<int> AlreadyAdded = new List<int>();
redo:
Random Rnd = new Random();
int ImageIndex = Rnd.Next(0, ItemsInFolder.Count);
if (AlreadyAdded.Contains(ImageIndex)) //Continue within this block if the item already exists in AlreadyAdded
{
goto redo;
}
AlreadyAdded.Add(ImageIndex); //Add ImageIndex to AlreadyAdded
Thanks,
I hope you find this helpful :)