creating a group of controls - c#

I ran into little problem today as I was working on my game...
The problem is I have this condition running on 1 milisecond timer :
if (jump == true &&
jumped == 0 &&
(Player.Location == new Point(Player.Location.X, Block1.Location.Y - Player.Height) ||
Player.Top == this.Height - Player.Height))
{
do something...
}
The "Block1" is one object in the game (Picturebox) and I need like 10 or 20 or even 100 more of these blocks with the same condition, so how could I simplify it? It would be 50 or even more lines of one condition. Basically I would like to know if there is a way of mixing all "Blocks" (pictureboxes) into a group (named Blocks) or something I could still access with Blocks.Location.Y etc

There are too many conditions in this single check, IMO. I'd break them down and then work on each condition in a stand-alone manner which will make things easier to debug as well as to read/comprehend in the future.
// Too much going on here; let's refactor.
if (jump == true
&& jumped == 0
&& (Player.Location == new Point(Player.Location.X, Block1.Location.Y - Player.Height)
|| Player.Top == this.Height - Player.Height))
{
//do something...
}
Instead of creating a large if statement, pull the conditions into a single method:
// first refactor
private bool IsValidForSomeAction()
{
if(!jump)
{
return false;
}
if(jumped != 0)
{
return false;
}
if(Player.Top == this.Height - Player.Height)
{
return true;
}
if (Player.Location == new Point(Player.Location.X, Block1.Location.Y - Player.Height))
{
return true;
}
return false;
}
After the first refator, it becomes clear that there is no need to create a new Point for the final comparison:
// second refactor
private bool IsValidForSomeAction()
{
if(!jump)
{
return false;
}
if(jumped != 0)
{
return false;
}
if(Player.Top == this.Height - Player.Height)
{
return true;
}
// only the Y location matters, no need to create a new Point for the comparison.
if (Player.Location.Y == Block1.Location.Y - Player.Height)
{
return true;
}
return false;
}
Now, let's focus on what really matters: if (Player.Location.Y == Block1.Location.Y - Player.Height). The condition boils down to the difference between the Block's Y location and the Player's Height.
Given that there may be 10, 20, 50, or 100+ Blocks to compare, then create a private field containing a collection of all the Blocks.
// override the onload event and find all the picture boxes:
private readonly List<PictureBox> _boxes = new List<PictureBox>();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_boxes.AddRange(this.Controls.OfType<PictureBox>()
}
The _boxes field can then be used for the final validation:
// third refactor
private bool IsValidForSomeAction()
{
if(!jump)
{
return false;
}
if(jumped != 0)
{
return false;
}
if(Player.Top == this.Height - Player.Height)
{
return true;
}
// only the Y location matters, no need to create a new Point for the comparison.
if(_boxes.Any(x => x.Location.Y - Player.Height == Player.Location.Y)
{
return true;
}
return false;
}

Related

Multiple Correct If Statements from a Mouse Click Event

I'm trying to do waste collection program and these are part of codes. My problem is if the picturebox shows image that on second if statements (magazine), there is no problem. But if shows first image that on first if statements (newspaper) and if NewWaste(); gives magazine then there is a problem. Because it adds both of them to listbox but I don't see the second image on picturebox. How can I solve that?
private void NewWaste()
{
Image[] images = new Image[] { newspaper.Image, magazine.Image, glass.Image };
int wastes = rnd.Next(images.Length);
wastePictureBox.Image = images[wastes];
}
//(part of class)
public bool Add(Waste waste)
{
if (FilledVolume + waste.Volume <= Capacity)
return true;
else
return false;
}
private void addPaperWasteBtn_Click(object sender, EventArgs e)
{
if (paperWasteBox.Add(newspaper) == true && wastePictureBox.Image == newspaper.Image)
{
paperWasteListBox.Items.Add("Newspaper");
NewWasteImage();
}
if (paperWasteBox.Add(magazine) == true && wastePictureBox.Image == magazine.Image)
{
paperAtikListBox.Items.Add("Magazine");
NewWasteImage();
}
}
If you only want the second if statement to run if the first one didn't, then you want an else if statement before the second conditional check.
Change:
if (paperWasteBox.Add(newspaper) == true && wastePictureBox.Image == newspaper.Image)
{
paperWasteListBox.Items.Add("Newspaper");
NewWasteImage();
}
if (paperWasteBox.Add(magazine) == true && wastePictureBox.Image == magazine.Image)
{
paperAtikListBox.Items.Add("Magazine");
NewWasteImage();
}
To:
if (paperWasteBox.Add(newspaper) == true && wastePictureBox.Image == newspaper.Image)
{
paperWasteListBox.Items.Add("Newspaper");
NewWasteImage();
}
else if (paperWasteBox.Add(magazine) == true && wastePictureBox.Image == magazine.Image)
{
paperAtikListBox.Items.Add("Magazine");
NewWasteImage();
}
Notice the difference in the SIXTH line!

How to build a exclude condition in C#

I'm coding a trading system using C#.Most of my logic is if some conditions occur at the same time,enter buy.
But in some scenario,I need an exclude logic:if some conditions occur at the same time not buy.
I tried to set a variable named Falling1 = true; and set Falling1=false; while the not buy conditions occur at the same time.
And then in my buy logic I need Falling1=true;.
namespace NinjaTrader.NinjaScript.Strategies
{
public class JJcrossCode : Strategy
{
private bool Falling1;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = #"Enter the description for your new custom Strategy here.";
Name = "JJcrossCode";
Falling1 = true;
}
else if (State == State.Configure)
{
}
else if (State == State.DataLoaded)
{
SetProfitTarget(#"Short", CalculationMode.Ticks, 20);
}
}
protected override void OnBarUpdate()
{
if (BarsInProgress != 0)
return;
if (CurrentBars[0] < 7)
return;
// Set 1
if (Open[0] > Close[0] && High[0] < High[1] && Low[0] < Low[1])
{
Falling1 = false;
}
// Set 2
// 01-crossabovelower
if (((CrossAbove(JurbolBBmacd1.Macd, JurbolBBmacd1.BollingerLower, 3))
&& (RSI1.Avg[0] < 67)&& (Falling1=true)
{
EnterLong(Convert.ToInt32(Size), #"Long");
}
}
}
The issue is that it seems the system can't recognize && (Falling1=true) in // 01-crossabovelower,I guess there are some structure issues in my code.
you want
&& (Falling1==true)
The way you wrote it you are doing an assignment

I get a wrong resultset of a List<> when using Linq's Where with lambda

I am programming a simulation thingy that I can use as a basis for a game or something later. I am programming in C# and with Unity. Unity is up to date on version 2017.1.0f3 (or 3.3.0.2 ?).
The simulation just spawns some random people and when they get older they may search for a partner and reproduce themselves.
Now I have some weird behaviour in that "search for a partner"-method. I will show the code below in a second. The method takes a list of people as an argument and validates that list to filter out every person that is older than 15 years and don't have a partner already. Also related persons get filtered out because I don't really want incest inside my simulation .. (yet? ^^)
To clarify my problem: in the List<> called potentialPartners are somehow people already having a partner. I am sure that it is no multithreading-caused problem because those partners were not set in the same frame. Also I by myself don't do any multithreading stuff yet, there're just the threads Unity creates as default.
public void SearchForPartner(List<PawnLogic> pawnsInRange)
{
if (!this.PartnerAllowed)
return;
System.Random rnd = new System.Random();
List<PawnLogic> potentialPartners = new List<PawnLogic>();
var pP = pawnsInRange.Where(x => x.PartnerAllowed && x.Gender != this.Gender && !this.IsKindred(x) && !x.IsKindred(this));
if (pP.Count() > 0)
potentialPartners.AddRange(pP);
if (potentialPartners.Count == 0)
return;
this.Partner = potentialPartners[rnd.Next(0, potentialPartners.Count)];
if (this.Partner.IsAlive)
{
this.Partner.Partner = this;
if (this.News != null)
{
this.News.Invoke(this, new NewsEventArgs(this, this.FirstLastName + " and " + this.Partner.FirstLastName + " become a couple."));
}
if (Gender == 'M')
this.Partner.SetNewLastname(this.thisPawn.LastnameNumber);
else
this.SetNewLastname(Partner.thisPawn.LastnameNumber);
}
else
this.Partner = null;
}
I guess my problem comes from the property "PartnerAllowed" because if I remember correctly the &&-operator only validates the right hand side if the left hand side returns true.
public bool PartnerAllowed
{
get
{
return this.partner == null && this.Age >= 16;
}
}
Just to be complete here is the IsKindred-method.. I don't really think that my problem comes outside of this but maybe I am not seeing something important.
public bool IsKindred(PawnLogic check)
{
if (Generation <= check.Generation - 4)
return false;
if ((Father == null || Mother == null || check.Father == null || check.Mother == null) && Siblings.Count == 0)
return false;
if (check == Mother || check == Father)
return true;
if (Siblings.Contains(check))
return true;
for (int i = 0; i < Siblings.Count; i++)
{
if (Siblings[i].Children.Contains(check))
return true;
}
if (Father != null && Father.IsKindred(check))
return true;
if (Mother != null && Mother.IsKindred(check))
return true;
return false;
}
My Partner-property looks like this:
public PawnLogic Partner
{
get
{
if (this.partner == null && this.thisPawn.PartnerNumber != null)
{
int indexOfPartner = this.thisPawn.PartnerNumber.ToInt();
if (indexOfPartner != -1)
this.partner = new PawnLogic(indexOfPartner);
else
this.partner = null;
}
return this.partner;
}
private set
{
if (value == null)
this.thisPawn.PartnerNumber = null;
else
{
this.thisPawn.PartnerNumber = value.Number;
this.partner = value;
}
}
}
I have no idea how to fix this. Especially because it works in another program which I wrote first. But I needed to transfer the code to this new project because Unity doesn't use .Net 4.6 yet. Maybe there was a change in Linq's behaviour between the framework-versions? Do someone can help me?
It is just a private project, but I want it to work properly anyway. :P
Let me know if you need more code or explanation to understand what is happening, what is supposed to happen or how something works.
Thank you for your time and effort :)

Why does my function tell me there's an unreachable code detected? c#

I created this function:
public bool checkFunds(int x)
{
if(checksBox.CheckState == CheckState.Checked && OriginalMain.temporaryChecks >= x)
{
return true;
}
else
{
MessageBox.Show("Error! Insufficient funds");
return false;
}
if(savingsBox.CheckState == CheckState.Checked && OriginalMain.temporarySavings >= x)
{
return true;
}
else
{
MessageBox.Show("Error! Insufficient funds!");
return false;
}
}
This code is for a windows form application. I'm making a bank simulator where you can choose from two different accounts to take your money out. This function in particular checks which checkbox you picked and checks if there are enough funds available on the chosen account. However C# keeps telling me that the second if is an unreachable code. Why is that? How can I fix it?
You get a warning, because your function will necessarily exit at one of these places:
if(checksBox.CheckState == CheckState.Checked && OriginalMain.temporaryChecks >= x)
{
return true; // <-- if the condition is true, your function will exit here
}
else
{
MessageBox.Show("Error! Insufficient funds");
return false; // <-- if the condition is false, your function will exit here
}
// this means this place in code is NEVER reached, so you get the warning
if(savingsBox.CheckState == CheckState.Checked && OriginalMain.temporarySavings >= x)
Most likely you need logic similar to this:
if(checksBox.CheckState == CheckState.Checked)
{
if(OriginalMain.temporaryChecks >= x)
{
return true;
}
else
{
MessageBox.Show("Error! Insufficient funds");
return false;
}
}
if(savingsBox.CheckState == CheckState.Checked)
{
if(OriginalMain.temporarySavings >= x)
{
return true;
}
else
{
MessageBox.Show("Error! Insufficient funds!");
return false;
}
}

How to disable more than one NumericUpDown controls using one method?

i have a form with more than one NumericUpDown as controls to input answer. i want every input is true for an operation (multiplication, sum etc), NumericUpDown for that operation will be disable. i have used the code below (just for sum operation), but i think its not efficient because i have to make a method to check every operation.
private void IsSumTrue() {
if (add1 + add2 == sum.Value)
{
sum.Enabled = false;
}
}
private void IsDifferenceTrue()
{
if (add1 - add2 == difference.Value)
{
difference.Enabled = false;
}
}
private void IsProductTrue()
{
if (add1 * add2 == product.Value)
{
product.Enabled = false;
}
}
private void IsQuotientTrue()
{
if (add1 / add2 == quotient.Value)
{
quotient.Enabled = false;
}
}
anyone have idea how to make it more efficient with just a method for all operation?
below is my idea, but to check the value is true for every NumericUpDown i don't know how.
private void DisableIfValueIsTrue()
{
foreach(Control control in this.Controls)
{
NumericUpDown value = control as NumericUpDown;
// if(value [NEED HELP]
}
}
Considering your situtaion, you can set a tag for each NumericUpDown in design mode like this:
sum.Tag=1;
square.Tag=2;
etc
Then define some int variables:
int iSum=add1+add2;
int iSquare= //Whatever you want
etc
And finally loop through your controls this way:
foreach (NumericUpDown control in this.Controls.OfType<NumericUpDown>())
{
int intCondition = Convert.ToInt32(control.Tag) == 1
? iSum
: Convert.ToInt32(control.Tag) == 2
? iSquare
: Convert.ToInt32(control.Tag) == 3
? i3
: i4; //You should extend this for your 8 controls
control.Enabled = intCondition == control.Value;
}
OK! Second way I offer
Since you will have to always check 8 different conditions, you could simply forget about looping through the controls and just change your method like this:
private void DisableIfValueIsTrue()
{
sum.Enabled = add1 + add2 != sum.Value;
difference.Enabled= add1 - add2 != difference.Value;
product.Enabled= add1 * add2 != product.Value;
quotient.Enabled= (add2 !=0) && (add1 / add2 != quotient.Value);
//etc
}
I came across this while doing some research and would like to give my solution I used for my situation and hope it helps people. I needed minimum and maximum numbers for a calculation, so mine are named appropriately and I correlated these with some CheckBoxes. I used null in beginning of minimum and end of maximum to account for empty. I also had to create an event handler SubscribeToEvents() shown below.
In my load event for my form:
SubscribeToEvents();
_checkBoxs = new[] { cbXLight, cbLight, cbMedium, cbHeavy, cbXHeavy, cbXXHeavy, cbXXXHeavy };
_minimumsNumericUpDowns = new[] { null, nLightMin, nMediumMin, nHeavyMin, nXHeavyMin, nXXHeavyMin, nXXXHeavyMin };
_maximumsNumericUpDowns = new[] { nXLightMax, nLightMax, nMediumMax, nHeavyMax, nXHeavyMax, nXXHeavyMax, null };
then I created a method:
private void DisableNumericUpDowns()
{
// disable everything:
foreach (var n in _minimumsNumericUpDowns)
{
if (n != null)
n.Enabled = false;
}
foreach (var n in _maximumsNumericUpDowns)
{
if (n != null)
n.Enabled = false;
}
}
The event handler:
private bool _eventsSubscribed;
private void SubscribeToEvents()
{
if (_eventsSubscribed)
return;
_eventsSubscribed = true;
cbXXHeavy.CheckedChanged += CheckBox_NumericState;
cbXHeavy.CheckedChanged += CheckBox_NumericState;
cbXLight.CheckedChanged += CheckBox_NumericState;
cbHeavy.CheckedChanged += CheckBox_NumericState;
cbLight.CheckedChanged += CheckBox_NumericState;
cbMedium.CheckedChanged += CheckBox_NumericState;
cbXXXHeavy.CheckedChanged += CheckBox_NumericState;
}
Now I can used this to check when they are enabled and if they are greater than or less than 0 if needed in the method CheckBox:
private void CheckBox_NumericState(object sender, EventArgs e)
{
// disable everything
DisableNumericUpDowns();
// see if more than one checkbox is checked:
var numChecked = _checkBoxs.Count((cb) => cb.Checked);
// enable things if more than one item is checked:
if (numChecked <= 1) return;
// find the smallest and enable its max:
var smallest = -1;
for (var i = 0; i < _checkBoxs.Length; i++)
{
if (!_checkBoxs[i].Checked) continue;
if (_maximumsNumericUpDowns[i] != null)
{
_maximumsNumericUpDowns[i].Enabled = true;
}
smallest = i;
break;
}
// find the largest and enable its min:
var largest = -1;
for (var i = _checkBoxs.Length - 1; i >= 0; i--)
{
if (!_checkBoxs[i].Checked) continue;
if (_minimumsNumericUpDowns[i] != null)
{
_minimumsNumericUpDowns[i].Enabled = true;
}
largest = i;
break;
}
// enable both for everything between smallest and largest:
var tempVar = largest - 1;
for (var i = (smallest + 1); i <= tempVar; i++)
{
if (!_checkBoxs[i].Checked) continue;
if (_minimumsNumericUpDowns[i] != null)
{
_minimumsNumericUpDowns[i].Enabled = true;
}
if (_maximumsNumericUpDowns[i] != null)
{
_maximumsNumericUpDowns[i].Enabled = true;
}
}
}
So I can check each state as required:
I want to check if Extra Light is check:
// Extra Light
if (!cbXLight.Checked) return;
if (nXLightMax.Enabled == false)
{
_structCategoryType = XLight;
CheckStructureSheets();
}
else
{
if (nXLightMax.Value > 0)
{
_dMax = nXLightMax.Value;
_structCategoryType = XLight;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Extra Light Max cannot be zero (0)");
}
}
and next light checks both:
// Light
if (cbLight.Checked)
{
if (nLightMin.Enabled == false && nLightMax.Enabled == false)
{
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
if (nLightMin.Enabled && nLightMin.Value > 0)
{
if (nXLightMax.Enabled && nLightMin.Enabled && nLightMax.Enabled == false)
{
_dMin = nLightMin.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
if (nLightMax.Value > 0)
{
_dMin = nLightMin.Value;
_dMax = nLightMax.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Light Max cannot be zero (0)");
return;
}
}
}
else if (nLightMin.Enabled == false && nLightMax.Enabled)
{
if (nLightMax.Value > 0)
{
_dMax = nLightMax.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Light Max cannot be zero (0)");
}
}
else
{
MessageBox.Show(#"Light Min cannot be zero (0)");
return;
}
}
}
Hope this helps someone.
Tim
thanks for #AlexJoliq and #BrettCaswell. just want to inform that before Alex edited his answer from using "==" to "!=", i (thought) already solved the problem. but i don't know where is the more effective and efficient way, alex's or mine.
below is my code for DisableIfValueIsTrue():
if (add1 + add2 == sum.Value) sum.Enabled = false;
if (add1 - add2 == difference.Value) difference.Enabled = false;
if (add1 * add2 == product.Value) product.Enabled = false;
if (add1 / add2 == quotient.Value) quotient.Enabled = false;

Categories

Resources