Why aren't my images loading and moving as expected? - c#

I'm working on a project where I can load a fixed set of data into a listbox. Each line of data is tied to an image in a picturebox. When I click on my load button, the data should be loaded into the listbox and each image should be loaded, and begin to move on the screen.
When I click load, initially 4 images are briefly loaded. Then the fourth disappears and only the first three of my images begin to move around the screen. However, when I create a new object the data is added to the listbox, but the image isn't the relevant new object image, instead it's my fourth image that should have loaded. So my loaded images are always one step behind, but my listbox is up to date.
I am very new to coding and struggling to understand the bigger picture at this stage. A lot of the code are examples that I've taken from places, and I vaguely understand what is going on, but not enough to troubleshoot this issue.
Does anyone have any tips on why this would be happening? Any advice or ideas on where I'm going wrong would be much appreciated.
MyClass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
namespace ACarter_A1_New
{
class MyClass
{
//private variables
private string animalId;
private int typeId; //Animal type id
private string typeName;
private int xPosition;
private int yPosition;
private int width;
private int height;
private int xStep; //move speed
private int yStep;
private PictureBox animalPic; //Picture
//public variables
public string AnimalId { get => animalId; set => animalId = value; }
public int TypeId { get => typeId; set => typeId = value; }
public string TypeName { get => typeName; set => typeName = value; }
public int XPosition { get => xPosition; set => xPosition = value; }
public int YPosition { get => yPosition; set => yPosition = value; }
public int Width { get => width; set => width = value; }
public int Height { get => height; set => height = value; }
public int XStep { get => xStep; set => xStep = value; }
public int YStep { get => yStep; set => yStep = value; }
public PictureBox AnimalPic { get => animalPic; set => animalPic = value; }
public MyClass(string id, PictureBox iniPic, int seed)
{
AnimalId = id; //the string id is now equal to AnimalId
TypeId = seed; //the int seed is now equal to TypeId
//set up type name
switch (TypeId) //TypeId = seed
{
case 1:
TypeName = "Angry Dog"; //= seed 1
break;
case 2:
TypeName = "Sleepy Dog"; //= seed 2
break;
case 3:
TypeName = "Dirty Dog"; //= seed 3
break;
case 4:
TypeName = "Happy Dog"; //= seed 4
break;
}
AnimalPic = iniPic; //load picture
//set up picture location by (X, Y, W, H)
XPosition = seed * 20;
YPosition = seed * 10;
Width = animalPic.Width;
Height = animalPic.Height;
XStep = seed * 5; //moving speed
YStep = seed * 5 / 3;
}
//Method DrawPic(...) displays an object image on the screen
public void DrawPic(Graphics canvas)
{
Image pic; //Image variable called pic
pic = AnimalPic.Image; //that image pic is now equal to the public picturebox AnimalPic
canvas.DrawImage(pic, XPosition, YPosition, Width, Height);
}
//Method move() changes the position of the object - simulates moving
public void Move()
{
if ((XPosition + Width >= 503 || (XPosition <= 0)))
{//change direction if on the edge
XStep = -XStep;
}
XPosition = XPosition + XStep; //move one step on x direction
if ((YPosition + height >= 421 || (YPosition <= 0)))
{//change direction if on the edge
YStep = -YStep;
}
YPosition = YPosition + YStep; //move one step on Y direction
}
//Method ToString() enables the object to be displayed as a string in the Listbox
public override string ToString()
{
return AnimalId + ", " + TypeId + ", " + TypeName + ", " + "x speed: " + XStep.ToString() + ", Y speed: " + YStep.ToString();
}
}
}
FileManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
namespace ACarter_A1_New
{
class FileManager
{
public List<MyClass> LoadAnimals(string fn)
{
StreamReader sr = new StreamReader(fn); //create a new instance of streamreader to use to read our .txt file, called sr and pass in the string fn
List<MyClass> loaddogs = new List<MyClass>(); //create a list based on the MyClass.cs class object, call the list loadDogs
//declare variables for object parameters from the MyClass class
string animalId; //we want the animalId, pic and seed info
PictureBox pic = new PictureBox();
int seed;
while (!sr.EndOfStream) //use a while loop to read through the file until the end - while not at the end, continue
{
string temp = sr.ReadLine(); //create a temp string called temp to store each read line that the sr reads
string[] values = temp.Split(','); //create a string array called value to store the information stored in temp, and split the indexed info on each line by commas
animalId = values[0]; //state that the animal id will be the first index at index 0 in our string array values
seed = int.Parse(values[1]); //state that seed will be the second index at index 1 in our string array values, we have to use int.Parse to convert int to string
//create new object, picture will be setup in form application
MyClass d = new MyClass(animalId, pic, seed); //create an object from MyClass called d, with properties for animalId, pic and seed
loaddogs.Add(d); //add what is stored in d to loaddogs list
}
sr.Dispose(); //finish using the sr streamreader
return loaddogs; //return a list loaddogs to the SaveAnimal method
}
}
}
Form1.cs - code for Loading/Creating New Object
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;
using System.IO;
using System.Collections;
namespace ACarter_A1_New
{
public partial class Form1 : Form
{
Random seed = new Random();
int animalTypeId;
int animalId;
List<MyClass> animals = new List<MyClass>();
Graphics screen;
public Form1()
{
InitializeComponent();
//setup screen and initialize animal id
screen = picScreen.CreateGraphics(); //declare and initialise the screen to equal the
animalId = 0; //declare and initalise the animalId variable
}
private void MoveAndShowAnimals() //MoveAndShowAnimals method to call the public Move() and DrawPic methods
{
try //use try/catch incase any exceptions are thrown to the code block
{
//initally the graphics screen is cleared and is the color dark olive green
screen.Clear(Color.DarkOliveGreen);
foreach (MyClass dog in animals) //foreach object that is stored in animals
{
dog.DrawPic(screen);
dog.Move();
//call the public DrawPic method from the MyClass class for each object
//call the public move method from the MyClass class for each object
}
}
catch (Exception ex)
{
MessageBox.Show("Error with MoveAndShowAnimals method" + ex);
}
}
private void btnLoadInit_Click(object sender, EventArgs e)
{
try //use try/catch incase any exceptions are thrown to the code block
{
animals.Clear(); //clear the animals list
List<MyClass> d = new List<MyClass>(); //create a new list using the MyClass class called d
lbxObjs.Items.Clear(); //clear the listbox lbxObjs
FileManager fm = new FileManager(); //create a new instance of FileManger called fm
//retrieve a list of dog information, without image
d = fm.LoadAnimals("dogs.txt"); //use the file manager fm, specifically the LoadAnimals(dogs.txt) in FileManager class and store in the list called d
//declare variables to use Id and seed
string Id;
int seed;
int count = 0; //count used to increment through in foreach loop, initialised to start at 0
// PictureBox Pic;
foreach (MyClass dog in d) //foreach loop to loop through each object "dog" that is put into the list d. The object being made up of id, seed and a picturebox
{
Id = dog.AnimalId; //specifying that the string Id is equal to the AnimalId specified in the MyClass class
seed = dog.TypeId; //specifying that the int seed is equal to the TypeId specified in the MyClass class
PictureBox Pic = null; //We need a picturebox, which initially will be null as we need the Pic to be one of four
//we can determine which pic should be first, second, third and fourth by using the count variable and if, if else statements
if (count == 0)
{
Pic = picDog1;
}
else if (count == 1)
{
Pic = picDog2;
}
else if (count == 2)
{
Pic = picDog3;
}
else if (count == 3)
{
Pic = picDog4;
}
//make an active object from retrieved file data
MyClass dogfromFile = new MyClass(Id, Pic, seed);
// use the active object and add it to the list animals which is our object list
animals.Add(dogfromFile);
MoveAndShowAnimals();
count++; //count++ increment count by 1 each time the foreach loop increments, which will be 4 times as we have four initial objects to load
}
if (animals == null) //if animal list is null, then show the error message below
{
MessageBox.Show("Error loading animals");
}
else //otherwise, clear the listbox, and add the objects that we have loaded into animals to the listbox
{
lbxObjs.Items.Clear();
lbxObjs.Items.AddRange(animals.ToArray());
/*MoveAndShowAnimals();*/ //implement the MoveAndShowAnimals() method to animate images
timer1.Enabled = true;//start the timer
}
}
catch (Exception ex) //exception ex shows a detailed error message as well as the initial message "Error loading"
{
MessageBox.Show("Error loading" + ex); //if an exception is thrown to the above code, display error loading
}
}
private void btnNewObj_Click(object sender, EventArgs e)
{
try
{
animalId++; //start animal id at 1, has been initialised to 0 already
//animalTypeId now equals the random seed which will choose from 4 objs and start at 1
string fullAnimalId = animalId.ToString(); //pass in string New Dog + the animal id to a string called fullAnimalId
animalTypeId = seed.Next(4) + 1;
PictureBox Pic = null; //initially this will be null as we need to choose from 1 of four pictureboxes. we can differentiate which picture to choose by using the animalTypeId
//which is equal to the seed number and give each seed the relevant image name, so Pic can have four variables depending on which seed is chosen
if (animalTypeId == 1)
{
Pic = picDog1;
}
else if (animalTypeId == 2)
{
Pic = picDog2;
}
else if (animalTypeId == 3)
{
Pic = picDog3;
}
else if (animalTypeId == 4)
{
Pic = picDog4;
}
//make an active object from retrieved file data
MyClass dogfromNew = new MyClass(fullAnimalId, Pic, animalTypeId);
animals.Add(dogfromNew); //add the active object to the animals object list
lbxObjs.Items.Clear(); //clear the listbox
lbxObjs.Items.AddRange(animals.ToArray()); //take the objects stored in animals list and add them to the listbox
MoveAndShowAnimals(); //call the MoveAndShowAnimals() method to animate the new images
timer1.Enabled = true; //start the timer
}
catch (Exception ex) //exception ex shows a detailed error message as well as the initial message "Error creating new object"
{
MessageBox.Show("Error creating new object" + ex);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
try
{
MoveAndShowAnimals();
}
catch (Exception)
{
MessageBox.Show("Error with timer");
}
}
dogs.txt file contents:
1,1
2,2
3,3
4,4

For anyone who's interested. The fourth image that kept disappearing was actually to do with the images themselves. I tried resizing the images and it worked first time through. I figured this out by using a smaller program that just had the load button and new object button and used different pictures, which when I compared to the images I was using, were a third of the size. So I changed the image size and in this project, and it worked first time. I'm guessing it was having trouble rendering the images so frequently that it just lagged out on the fourth. As the images were moving pretty slowly across the screen, and now are moving a lot quicker.

Related

Detect and process only unique images

The problem I'm having is that I have an image that appears on two pages in the same book.
I wish my program to react (trigger a side-effect) only when encountering new images and ignore duplicates.Once it has done that I want it to reset so the process is repeated.
namespace testpad
{
class Interaction: Scene
{
public override string Name => "Interaction";
public static RectMap imageone = new RectMap()
{
X = 239,
Y = 199,
Width = 125,
Height = 18
};
public static RectMap imagetwo = new RectMap()
{
X = 217,
Y = 317,
Width = 428,
Height = 12
public override bool Match(ScriptBase script)
{
return script.Match(imageone, 90),
|| script.Match(imagetwo, 90);
}
public override void OnMatched(ScriptBase script)
{
if (script.Match(imageone, 90))
{
script.PressKey() { A = true });
Thread.Sleep(100);
}
else if (script.Match(imagetwo, 90))
{
script.Press() { B = true });
Thread.Sleep(1000);
}
}
}
If you expect a collection of objects and you want to take actions based upon their frequency of apparition the best solution would be a Dictionary<[Key],int> where the Key is the identifier (in your case a String with the name of the image) and the value represents the frequency of your key.Whenever you encounter an object (in your case lets call it image)with a given Key you increment the value stored at that key.Afterwards you can take decisions based upon resulting frequencies.
However in your case you just need to react only once , the first time you encounter a new image , so a HashSet<String> would be your best bet.
So your code would look like:
public void Iterate(IEnumerable<(string,object)>images)
{
HashSet<string>set=new HashSet<string>();
foreach(var item in images)
{
if(!set.TryGetValue(item.item1,out object obj))
{
set.Add(item.item1);
//React(item.item2) ---do something the first time you encounter the image
}
}
}

Multiple Images for Animation Using for loop C#

I am trying to make a rudimentary, very simple animation function using a simple manager. The issue is that, as of right now, when the user clicks "Go" on the main form, it will display the first image then jump to the last image.
I have also tried to insert a delay which delays the thing going from 1 to the last frame but it just jumps to the last frame. I'm utilizing several PNG files in order to make this thing work instead of trying to use a "sprite sheet" which would be a larger pain in the arse I would imageine...
Here's the code for the AnimationManager class...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
namespace Animation
{
public class AnimationManager
{
public PictureBox AnimationBox;
public float widthX, heightY;
public string ImageDirectory, ImageName;
public int frame, maxFrames;
public int speed; // in milliseconds
public bool isLooping;
public AnimationManager()
{
AnimationBox = new PictureBox();
widthX = 0;
heightY = 0;
ImageName = null;
frame = 1;
speed = 0;
maxFrames = 0;
isLooping = false;
}
public async void CycleThrough(string ImageDirectory, int FPMS, int maxFrames, bool isLooping)
{
for (int i = frame; i < maxFrames + 1; i++)
{
ImageName = ImageDirectory + #"\" + frame.ToString() + ".png";
AnimationBox.Image = Image.FromFile(ImageName);
AnimationBox.Refresh();
await Task.Delay(FPMS);
switch (isLooping)
{
case false:
default:
{
frame = maxFrames;
break;
}
case true:
{
frame = 1;
break;
}
}
}
}
}
}
That's as far as I was able to get. If anyone has any insight or can point me in the right direction to get this to work, that would be awesome.
You had some problems in your code so i write it again and i comment out where you had problem
public async void CycleThrough(string ImageDirectory, int FPS, int maxFrames, bool isLooping)
{
for (int i = frame; i < maxFrames + 1; i++) // frame and maxFrames must not change. counter is i
{
ImageName = ImageDirectory + #"\" + i.ToString() + ".png"; // Get the i-th png using counter.
AnimationBox.Image = Image.FromFile(ImageName);
AnimationBox.Refresh();
await Task.Delay(TimeSpan.FromSeconds(1/FPS)); // delay in seconds.
if(isLooping && i == maxframes) // if must Loop and counter is in last iteration then start over
{
i = frame - 1; // set the counter to the first frame
}
}
}
While waiting for the answer, I went ahead and attempted to do it myself... :) Thank you for your answers and comments...
This was my final solution...
private async void CycleThrough(string ImageDirectory, int FPMS, int maxFrames, bool isLooping)
{
this.speed = FPMS;
for (int i = frame; i < maxFrames + 1; i++)
{
ImageName = ImageDirectory + #"\" + i.ToString() + ".png";
Console.WriteLine(frame.ToString());
AnimationBox.Refresh();
AnimationBox.Image = Image.FromFile(ImageName);
await Task.Delay(FPMS);
if (isLooping)
{
if (i >= maxFrames) i = 1;
}
}
}
I made an elementary mistake and didn't use "i" that was setup. Instead I manipulated a bunch of other things that had no bearing on the loop's intent itself.
I agree with the person above - I didn't use a switch in my solution. It didn't make sense since I only have one conditional that would reset the loop (manipulating i back to 1) if isLooping was true.
This works beautifully so I'll offer this solution to anyone who wants a rudimentary animator for their code :)
Thanks all for your answers and time.

Why is the text file's information not being read into my array and then listbox?

I am relatively new to C# and am experiencing a problem. My program keeps throwing an error per my try catch. I have looked over everything and changed things, but nothing seems to work. Could it be the reading of the text file? or the array? or the transfer into the listbox? I really need some help with this. It has become nothing but a headache.
............................................................................................................................................................................................................................................................................................................................................................................................................................................................................
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;
using System.IO;
namespace Total_Sales_BBrantley
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCalc_Click(object sender, EventArgs e)
{
try
{
// Declare variable to hold the amount of sales
// Declare variable to act as the accumulator
const int SIZE = 100;
double[] allSales = new double[SIZE];
double total = 0.0;
double average;
double highest = allSales[0];
double lowest = allSales[2000];
int count = 0;
// Declare a StreamReader variable.
StreamReader readFile;
// Open the file and get a StreamReader object using a relative path
readFile = File.OpenText("Sales.txt");
while (!readFile.EndOfStream && count < allSales.Length)
{
allSales[count] = int.Parse(readFile.ReadLine());
// Increment count
count++;
}
// Close the file
readFile.Close();
lstSales.Items.Add("The file contains " + count + " items:");
for (int index = 0; index < count; index++)
{
lstSales.Items.Add(allSales[index]);
}
// Display the total
double sum = allSales.Sum();
lblTotal.Text = sum.ToString();
total += sum;
average = total / allSales.Length;
lblAverage.Text = average.ToString();
for (int index = 1; index < allSales.Length; index++)
{
if (allSales[index] > highest)
{
highest = allSales[index];
}
lblHighest.Text = highest.ToString();
}
for (int index = 1; index < allSales.Length; index++)
{
if (allSales[index] < lowest)
{
lowest = allSales[index];
}
lblLowest.Text = lowest.ToString();
}
}
catch (Exception)
{
// Display an error message on bad input from file
MessageBox.Show("Error calculating the sales.");
}
}
private void btnExit_Click(object sender, EventArgs e)
{
//Closes the application
this.Close();
}
}
}
I didn't read all your code, but there's an error just at the start:
const int SIZE = 100;
double[] allSales = new double[SIZE];
<snip>
double lowest = allSales[2000];
You've declared the array to have 100 elements, but you're trying to access the 2,000th. Your array isn't that big, so you'll get an IndexOutOfRangeException on that line.
Arrays have fixed sizes in C# once declared. If you need the size to change, use the generic List class.
Bulding on martin_costello's answer, perhaps you could initialize lowest and highest like this:
double highest = double.MinValue;
double lowest = double.MaxValue;
Or at the very least, initialize these values after you have loaded your data!
Also, a tip for debugging: if you're getting an error, either display the error returned by the catch or comment out the try/catch so that you can see the error.
An example of the former:
catch (Exception ex)
{
// Display an error message on bad input from file
MessageBox.Show(string.Concat("Error calculating the sales: ", ex.Message, "\r\n", ex.StackTrace));
}

Issues loading different levels randomly in Unity-3D

I need to create a class (or classes, if need be) that loads levels randomly every time the user clicks on the "Next Button" and once all levels have been loaded, we stop loading and close the application. I got the code set up but I am still not getting the result I am looking for which is:
User clicks on a button.
Load a random level
That levels gets stored in an array list
Once the user is done with that level he/she presses the "Load Next Level" button
Load the next random level
But first, we check if the random level is not the same as before.
If it's not, then we repeat steps 2-5, else we go to step 8
If the levels have all been visited then we quit the application
The problem I am having is that my game loads the same level every time I hit play and it doesn't go to the next scene after I am done with the current one. This is what I have so far:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class SceneManager : MonoBehaviour
{
public static bool userClickedNextButton; //This flag is raised by the other classes that have the GUI button logic
protected const int MAX = 2;
private ArrayList scenesWereAlreadyLoaded = new ArrayList();
void Update()
{
if (userClickedNextButton)
{
//by default the game starts at 0 so I want to be able to
//randomly call the next two scenes in my game. There will
//be more levels but for now I am just testing two
int sceneToLoad = Random.Range(1, 2);
if (!scenesWereAlreadyLoaded.Contains(sceneToLoad))
{
scenesWereAlreadyLoaded.Add(sceneToLoad);
Application.LoadLevel(sceneToLoad);
}
userClickedNextButton = false;
}
if (scenesWereAlreadyLoaded.Count > MAX) { Application.Quit(); }
}
}
You create a list with your level numbers, then remove the currently loaded level. You repeat that until the list is empty.
Also don't use ArrayList, it's very old and deprecated type, from the ages before .NET/Mono had Generic support. Better use a Generic List<T>, which is type safe and faster than ArrayList.
using UnityEngine;
using System.Collections;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
public class SceneManager : MonoBehaviour
{
// not best idea to have it static
public static bool userClickedNextButton;
protected const int MAX = 50;
private List<int> scenes = new List<int>();
void Start() {
// Initialize the list with levels
scenes = new List<int>(Enumerable.Range(1,MAX)); // This creates a list with values from 1 to 50
}
void Update()
{
if (userClickedNextButton)
{
if(scenes.Count == 0) {
// No scenes left, quit
Application.Quit();
}
// Get a random index from the list of remaining level
int randomIndex = Random.Range(0, scenes.Count);
int level = scenes[randomIndex];
scenes.RemoveAt(randomIndex); // Removes the level from the list
Application.LoadLevel(level);
userClickedNextButton = false;
}
}
}
As per the Unity3D documentation (http://docs.unity3d.com/Documentation/ScriptReference/Random.Range.html), range returns an integer between min (included) and max (excluded), so, in your case, Random.Range(1,2) will always returns 1.
Try with this
int = sceneToLoad = Random.Range(1,3)
There is an easier way to do so. You can prepare an array with random unique numbers. When you want to load a new level just increment the index of the array.
Here's a code that can help:(Attach this script to an empty gameobject in your first scene)
using UnityEngine;
using System.Collections;
public class MoveToRandomScene : MonoBehaviour {
public Texture nextButtonTexture; // set this in the inspector
public static int[] arrScenes;
public static int index;
void Start () {
index = 0;
arrScenes = GenerateUniqueRandom (10, 0, 10); //assuming you have 10 levels starting from 0.
}
void OnGUI {
// Load the first element of the array
if (GUI.Button(new Rect (0,0,Screen.width/4,Screen.height/4),nextButtonTexture))
{
int level = arrScenes [0] ;
Application.LoadLevel (level);
}
}
//Generate unique numbers (levels) in an array
public int[] GenerateUniqueRandom(int amount, int min, int max)
{
int[] arr = new int[amount];
for (int i = 0; i < amount; i++)
{
bool done = false;
while (!done)
{
int num = Random.Range(min, max);
int j = 0;
for (j = 0; j < i; j++)
{
if (num == arr[j])
{
break;
}
}
if (j == i)
{
arr[i] = num;
done = true;
}
}
}
return arr;
}
}
For the other scenes you just need to create this script and attach it to an empty game object whenever you want to load a new random scene:
void OnGUI {
if (GUI.Button(new Rect (0,0,Screen.width/4,Screen.height/4),nextButtonTexture))
{
if (MoveToRandomScene.index == 9) {
// Load again your first level
Application.LoadLevel(0);
}
// else you continue loading random levels
else {
MoveToRandomScene.index++;
int level = MoveToRandomScene.arrScenes[MoveToRandomScene.index];
Application.LoadLevel(level);
}
}
}

Cannot convert from int to system.collections.generic.icomparer<int>

New to C# Just wondering what the error is, can't understand the error. No need to correct, just want to know the mistake.
ERROR:
The best overloaded method match for 'Systems.Collections.Generic.List.BinarySearch(int,System.Collections.Generic.Icomparer)' has some invalid arguments
Argument1: Cannot convert from system.collections.generic.list to int
Argument2: Cannot convert from int to system.collections.generic.icomparer
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;enter code here
using System.Windows.Forms;
namespace LotoNumbers
{
public partial class FrmLotto : Form
{
// declare class level variables
List<int> player = new List<int>(7);
List<int> computer = new List<int>(6);
public FrmLotto()
{
InitializeComponent();
}
// event method to generate player's numbers
private void btnPlayer_Click(object sender, EventArgs e)
{
// declare and initalize local variables
string display = "";
// reset the winning number label before generating the player's numbers
lblComputerNumber.Text = "00 00 00 00 00 00";
// generate unique random numbers
GenerateRandomNumbers(player);
player.Sort();
// build display string
display = BuildDisplayString(player);
// display winning number in label
lblPlayerNumber.Text = display;
}
// method to generate computer's random numbers (the 'winning numbers')
// and determine how many winning numbers
private void btnComputer_Click(object sender, EventArgs e)
{
// declare and initalize local variables
int winCount = 0;
string display = "";
// generate unique random numbers
GenerateRandomNumbers(computer);
// sort the array in ascending order
computer.Sort();
// build display string
display = BuildDisplayString(computer);
// display winning number in label
lblComputerNumber.Text = display;
// determine if this number matches any of the players numbers
winCount = CompareTwoList(player, computer);
// display the total winning numbers
lblMatching.Text = winCount.ToString("D2");
}
private void GenerateRandomNumbers(List<int> numberList)
{
Random lucky = new Random();
// generate unique random numbers
for (int index = 0; index < numberList.Capacity; index++)
{
int temp = lucky.Next(1, 50);
if (numberList.IndexOf(temp) < 0)
{
numberList.Add(temp);
}
else
{
index--;
}
}
}
private string BuildDisplayString(List<int> numberList)
{
// declare method variable
string display = " ";
// loop through the array and build a display string
foreach (int number in numberList)
display += number.ToString("D2") + " ";
// return display string
return display;
}
private int CompareTwoList(List<int> list1, List<int> list2)
{
// declare method variable
int numberMatching = 0;
// loop through each element in the first array looking for a match in the second array
foreach (int value in list1)
{
if (player.BinarySearch(list2, value) >= 0)
numberMatching++; // a matching value is found
}
return numberMatching;
}
}
}
It looks like you want:
if (list2.BinarySearch(value) >= 0)
numberMatching++; // a matching value is found
You are calling List<int>.BinarySearch(int, IComparer<int>) at the moment. Since value is an int you are getting a type error.
Note you can also do:
int numberMatching = list2.Intersect(list1).Count();
There is no overload for List<int>.BinarySearch() which accepts a List<int> and int as the parameters. See MSDN
You need to use player.BinarySearch(value)

Categories

Resources