Getting same numbers within two event methods on windows form - winforms

I have created a from which takes the user input and compares it to 100 randomly generated numbers. Once they click the guess button the result is shown. To aid the user I am supposed to give them a hint when they hover the mouse over a label, the hint should be either 3 higher or 3 lower than the actual number. I cannot figure out how to get the random number generated when the user hits the guess button to equal the number as the hover event. Sorry for all the code, any help would be appreciated.
Here is how I am creating my random number:
public partial class Form1 : Form
{
int[] rndArray = new int[100];
public void getNumbers()
{
Random random = new Random();
for (int x = 0; x < rndArray.Length; x++)
{
rndArray[x] = random.Next(1, 100);
}
}
Here is the guss button event:
private void Guess_Click(object sender, EventArgs e)
{
getNumbers();
for (int x = 0; x < rndArray.Length; x++)
{
if (Convert.ToInt32(textBox1.Text) == rndArray[x])
{
result.Text = "You Win!";
correct.Text = "Correct: ";
}
else
{
result.Text = "Sorry - you loose; the number is: " + rndArray[x];
incorrect.Text = "Incorrect: ";
}
}
And the mouse hover event:
private void mouseHere_MouseHover(object sender, EventArgs e)
{
getNumbers();
for (int x = 0; x < rndArray.Length; x++)
hint.Text = "It's not " + (rndArray[x] +- 3);
}

I see three possible issues.
First, at the beginning of your mouse hover and guess click functions, you call GetNumbers, which generates 100 numbers and assigns them to the array. You should only generate them once per game. I would recommend calling it once at the beginning of each game (perhaps in the FormShown or FormLoad event handlers), and not calling it again until the next game begins. Otherwise, the numbers will keep changing.
Second, inside your mouse hover function, you have a for loop that assigns the text to "hint" 100 times. The first 99 hints will probably not be accurate, as the end of your mouse hover event will display the hint for the very last number. You will need to identify which array element to give a hint for, and assign it to the appropriate hint display.
Third, the +- operator is not an actual operator in C#. If this is actually compiling and running, it's probably interpreting it in a manner such as hint.Text = "It's not " + (rndArray[x] + (-3); I would recommend using a Random object to generate a number, then using whether it's odd or even to determine whether to add or subtract. Just make sure you don't reassign the array.
EDIT: With regards to figuring out whether to add or subtract from the hint, make sure you don't randomly generate a hint each time you hover; do it once for that number and store the hint. Otherwise, hovering over it a few times will show both possible hints.

Related

Clearing output if input is changed

I have two text boxes on my form. The first text box calculates an amount when it is clicked and the amount total is displayed in the second text box. I'm trying to create an event handler that will clear the text in the second text box if the value entered in the first is changed.
For example, You can only go on the ride if you are 5 years old. The user enters 5 in 1st text box. The second text box displays "You can ride!". Now if the user changes the number 5, I want the "You can ride!" to be cleared.
I don't have any code, because I'm not sure which text box you create an event handler for, the one that takes input or the one that displays the output. Does anyone have any suggestions or what I can search on Microsoft's page to know more about clearing? The only thing I was about to find so far was this example: textBoxName.Clear(); but I'm not sure where to put that. Any suggestions? Thank you.
Yes, you can use TextBox.Clear Method to clear the text in a TextBox.
The following is a simple example to determine whether the value in TextBox1 is "5" and modify the value in TextBox2 in real time.
The demo uses Int32.TryParse Method to detect if the value in TextBox1 is a number.
public Form1()
{
InitializeComponent();
textBox1.TextChanged += textBox1_TextChanged;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
int number;
bool success = Int32.TryParse(textBox1.Text, out number);
// input is a number
if (success)
{
// if input is 5
if (number == 5)
{
textBox2.Text = "You can ride!";
}
// else clear TextBox2
else
{
textBox2.Clear();
}
}
// input is not a number, re-input
else if (!string.IsNullOrEmpty(textBox1.Text))
{
// Clear wrong input
textBox1.Clear();
MessageBox.Show("Please input a number!");
}
// input is empty
else
{
textBox2.Clear();
}
}

Unity3D - Playback object array of position (with dynamic velocity)

We own two objects in the scene. One follows the mouse position on the screen, and the object 2 in turn follows the route object 1 did. We are storing the positions covered by the object 1 and causing the object 2 play them.
When you run the game, an object follows the other quietly, reproducing the stored position ... but when one object's speed is changed (on mouse click increase velocity) the object 2 can not keep up, as this still following the positions already be cached in the array (including the calculations speed). Please, watch the shot video below:
YouTube: https://youtu.be/_HbP09A3cFA
public class Play : MonoBehaviour
{
public Transform obj;
private List<Recorder> recordList;
private float velocity = 10.0f;
private Transform clone;
void Start()
{
recordList = new List<Recorder>();
clone = obj;
}
void Update()
{
if (Input.GetMouseButton(0))
{
velocity = 20.0f;
}
else {
velocity = 10.0f;
}
var dir = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);
var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.AngleAxis(angle, Vector3.forward), 180 * Time.deltaTime);
transform.position += transform.right * Time.deltaTime * velocity;
Camera.main.transform.position = new Vector3(transform.position.x, transform.position.y, Camera.main.transform.position.z);
recordList.Insert(0, new Recorder
{
Position = transform.position,
Rotation = transform.rotation,
Velocity = velocity
});
var x = 8;
if (x < recordList.Count)
{
clone.position = recordList[x].Position;
clone.rotation = recordList[x].Rotation;
clone.position += clone.right * Time.deltaTime * velocity;
}
if (recordList.Count > x)
recordList.RemoveRange(x, recordList.Count - x);
}
}
public class Recorder
{
public Vector3 Position{get;set;}
public Quaternion Rotation{get;set;}
public float Velocity{get;set;}
}
How can we play the positions stored always with the speed of the object 1?
Summary:
If the object 1 is slowly moving object 2 as well;
If the object 2 is running, the object 2 should do the route at a faster speed to always follow the object 1;
Thanks in advance.
If i understood correctly you might want to consider using Queue<T> instead of List<T>. I think it would be a better suited datatype as it represents a FIFO collection (first in, first out), which is how you use List anyway. You can add elements with Enqueue(T) to the end of the queue and always get the first item with Dequeue() (it also removes it). As for Stack<T> (the opposite), there is also a Peek() function which lets you "preview" the next element.
Another thing, it depends on distance and speed, but i have the feeling that storing the position of every frame could become a bit excessive (maybe im just overly concerned though)
I think the issue with your code is that you always get the 8th element of the List.

AndEngine TimerHandler - onTimePassed

I am using AndEngine to create Physics Simulations of projectiles being launched. As it simulates, I want to draw the parable's track.
To do so, I am drawing a square every second according to the position of the projectile(sPlayer).
time_handler=new TimerHandler(1, true, new ITimerCallback() {
#Override
public void onTimePassed(TimerHandler pTimerHandler) {
if(simulationOn){ // every 1 second if the simulation is on
int px=(int)sPlayer.getSceneCenterCoordinates()[0];
int py=(int)sPlayer.getSceneCenterCoordinates()[1];
parabola_point=new Rectangle(px, py,4, 4,getVertexBufferObjectManager());
parabola_point.setColor(Color.WHITE);
if(!highest_point_found){ //if highest point not found, check it
float difY = (float) Math.floor(Math.abs(body.getLinearVelocity().y)) ;
if(Float.compare(0f, difY) == 0){ // if it is the highest point
highest_point_found=true;
drawPointText(); //draw the positions on the scene
parabola_point=new Rectangle(px, py,16, 16,getVertexBufferObjectManager());
parabola_point.setColor(Color.RED); // paint this point red
}
}
parabola.add(parabola_point);
scene.attachChild(parabola_point);
}
// pTimerHandler.reset();
}
});
I am using a FixedStepEngine:
#Override
public Engine onCreateEngine(final EngineOptions pEngineOptions) {
return new FixedStepEngine(pEngineOptions, 50);
}
THE PROBLEM IS:
I don't know why onTimePassed is being called faster than 1 second interval.It happens after some seconds.
I read that problaby the FixedStepEngine is changing the interval that 'onTimePassed' is called. How to fix it?
It seems to me that you are not unregistering your timer handlers which causes them to intersect with one another. Try unregistering pTimerHandler

get data point when user click a line graph using DataVisualization.Charting.Chart

I am using DataVisualization.Charting.Chart (winform), I need to get the data point index when user clicks on a line graph in MouseDown event.
I know there is a HitTest function accepting x & y, but for a line graph, we only need to verify x, if we scan the y (0 to height of graph), it will work, but the performance is too bad.
One way to do this is to enable the cursor
chartArea1.CursorX.IsUserEnabled = true;
chartArea1.CursorX.IsUserSelectionEnabled = true;
// set selection color to transparent so that range selection is not drawn
chartArea1.CursorX.SelectionColor = System.Drawing.Color.Transparent;
and handle the CursorPositionChanged event.
private void chart1_CursorPositionChanged(object sender, CursorEventArgs e)
{
// find a point (this series only has Y values, so using position as index works
// for a series with actual X values, you'd need to Find the closest point
DataPoint pt = chart1.Series[0].Points[(int)Math.Max(e.ChartArea.CursorX.Position - 1, 0)];
// do what is need with the data point
pt.MarkerStyle = MarkerStyle.Square;
}
This obviously assumes a single Series in your ChartArea.
if you are use HitTestResult's ChartElementType.
HitTestResult result = chart.HitTest(e.X, e.Y);
if (result.ChartElementType == ChartElementType.DataPoint)
{
int index = result.PointIndex;
// todo something...
}

Selecting an object on a WPF Canvas?

I have a WPF Canvas with some Ellipse objects on it (displayed as circles). Each circle is from a collection class instance which is actually a custom hole pattern class. Each pattern has a certain number of circles, and each circle then gets added to the canvas using an iteration over the collection using the code below.
So, the canvas is populated with a bunch of circles and each circle belongs to a certain pattern instance. You can see a screenshot here: http://twitpic.com/1f2ci/full
Now I want to add the ability to click on a circle on the canvas, and be able to determine the collection it belongs to, so that I can then do some more work on the selected pattern to which that circle belongs.
public void DrawHoles()
{
// Iterate over each HolePattern in the HolePatterns collection...
foreach (HolePattern HolePattern in HolePatterns)
{
// Now iterate over each Hole in the HoleList of the current HolePattern...
// This code adds the HoleEntity, HoleDecorator, and HoleLabel to the canvas
foreach (Hole Hole in HolePattern.HoleList)
{
Hole.CanvasX = SketchX0 + (Hole.AbsX * _ZoomScale);
Hole.CanvasY = SketchY0 - (Hole.AbsY * _ZoomScale);
canvas1.Children.Add(Hole.HoleEntity);
}
}
}
All FrameworkElements have a Tag property which is of type object that can be used to hold arbitrary information. You could assign the HolePattern to the Tag property and easily use that later to get the associated collection.
i.e.:
...
Hole.HoleEntity.Tag = HolePattern as object;
canvas1.Children.Add(Hole.HoleEntity);
later on in the click event:
event(object sender,....)
{
Ellipse e = sender as Ellipse;
HolePattern hp = e.Tag as HolePattern;
...
}
So you probably already read my reply where I said I had it working. And it does work perfectly, (except that it requires great precision with the mouse), but I want to ask this: is it really smart to add an event handler to EVERY ellipse that gets added to a canvas? Now I don't know what kind of memory bog that could be, or maybe it is a piece of cake for WPF and Windows to handle.
In a practical case, I guess there would be not more that 30-50 holes even on a screen that had multiple patterns, but still; FIFTY event handlers? It just seems scary. And actually, each "Hole" is visually represented by two concentric circles and a text label (see the screenshow here: http://twitpic.com/1f2ci/full ), and I know the user would expect to be able to click on any one of those elements to select a hole. That means an event handler on 3 elements for every hole. Now we could be talking about 100 or more event handlers.
It seems like there should be a solution where you could have just one event handler on the Canvas and read the element reference under the mouse, then work off of that to get the .Tag property of that elment, and so on.
I thought I'd post my final and more refined solution in case it helps anyone else.
void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
int ClickMargin = 2;// Adjust here as desired. Span is in both directions of selected point.
var ClickMarginPointList = new Collection<Point>();
Point ClickedPoint = e.GetPosition(canvas1);
Point ClickMarginPoint=new Point();
for (int x = -1 * ClickMargin; x <= ClickMargin; x++)
{
for (int y = -1 * ClickMargin; y <= ClickMargin; y++)
{
ClickMarginPoint.X = ClickedPoint.X + x;
ClickMarginPoint.Y = ClickedPoint.Y + y;
ClickMarginPointList.Add(ClickMarginPoint);
}
}
foreach (Point p in ClickMarginPointList)
{
HitTestResult SelectedCanvasItem = System.Windows.Media.VisualTreeHelper.HitTest(canvas1, p);
if (SelectedCanvasItem.VisualHit.GetType().BaseType == typeof(Shape))
{
var SelectedShapeTag = SelectedCanvasItem.VisualHit.GetValue(Shape.TagProperty);
if (SelectedShapeTag!=null && SelectedShapeTag.GetType().BaseType == typeof(Hole))
{
Hole SelectedHole = (Hole)SelectedShapeTag;
SetActivePattern(SelectedHole.ParentPattern);
SelectedHole.ParentPattern.CurrentHole = SelectedHole;
return; //Get out, we're done.
}
}
}
}

Resources