How to use multiple boolean conditions in a single if statement? - c#

I was making a puzzle where the player must push boulders to their corresponding buttons/pressure plate. I'm using booleans in a hard code for the prototype, but found myself having difficulties in what punctuation should I use between booleans? &&, and || didn't work.
Thank you for your willingness to help.
Please ignore the mess, what I need help with is the bottom public void OpenDoor in the 'if' statement, the one between trigger_1 and trigger_2 (what to replace the comma). Any advices to better the code are also appreciated.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TriggerAllButtons : UsedOnceFieldButton
{
bool trigger_1 = false;
bool trigger_2 = false;
//bool trigger_3 = false;
//bool trigger_4 = false;
//bool trigger_5 = false;
//bool trigger_6 = false;
public string button_1 = "Button 1";
public string button_2 = "Button 2";
//public string button_3 = "Button 3";
//public string button_4 = "Button 4";
//public string button_5 = "Button 5";
//public string button_6 = "Button 6";
public string boulder_1 = "Boulder 1";
public string boulder_2 = "Boulder 2";
//public string boulder_3 = "Boulder 3";
//public string boulder_4 = "Boulder 4";
//public string boulder_5 = "Boulder 5";
//public string boulder_6 = "Boulder 6";
public void OnTriggerEnter(Collider other)
{
if (other.CompareTag(button_1) && other.CompareTag(boulder_1))
{
trigger_1 = true;
}
if (other.CompareTag(button_2) && other.CompareTag(boulder_2))
{
trigger_2 = true;
}
// if (other.CompareTag(button_3) && other.CompareTag(boulder_3))
// {
// trigger_3 = true;
// }
// if (other.CompareTag(button_4) && other.CompareTag(boulder_4))
// {
// trigger_4 = true;
// }
// if (other.CompareTag(button_5) && other.CompareTag(boulder_5))
// {
// trigger_5 = true;
// }
// if (other.CompareTag(button_6) && other.CompareTag(boulder_6))
// {
// trigger_6 = true;
// }
}
public void OpenDoor()
{
if (trigger_1 = true, trigger_2 = true) //&& (trigger_3 = true) && (trigger_4 = true) && (trigger_5 = true) && (trigger_6 = true))
{
UsedButton();
}
}
}

You are confusing assignment = and comparison == operator. Thats why you thought the boolean operators && and || did not work.
// this is wrong
// trigger_1 and trigger_2 get true ->assigned<- before && is evaluated
// thus the "if" is always true
if (trigger_1 = true && trigger_2 = true)
// should be like this
// trigger_1 and trigger_2 are only ->compared<- to true before && is evaluated
// this can give "if (false && true)" for example
if (trigger_1 == true && trigger_2 == true)
Same logic holds for other boolean operators (like ||). In the wrong if-statement you accidently changed the values of your bools.
Side note: it is really enough to write if (trigger_1 && trigger_2), they are bools anyway.

In my understanding you need to replace comma of open door with appropriate operator
there are two common operators OR || , AND &&
With OR operator if only one bool is true, the condition will return true, It only return False when both bool are false
With AND operator both bool need to be true in other for condition to return true.

Related

Visual Studio C# delay function for if statment

I'm looking for a way to create a delay in my code without stopping the rest of the code in this time frame. It has to work as follows. If a condition is true for X amount of seconds, set the alarm bool High. The code below is a part of code where I set the alarms but there needs to be a delay.
I'm very new to C# so try to dumb it down a bit, maybe a small example or links.
if (Valve.Parameter.NormallyOpen == false)
{
if (Valve.Status.Output == true & Valve.Status.Opened == false)
{
Valve.Alarm.NotOpened = true;
}
if (Valve.Status.Output == false & Valve.Status.Closed == false)
{
Valve.Alarm.NotClosed = true;
}
}
Some background info: this will be a valve control block in PLCNext written in C#. The control block should give a alarm if the valve is send open but does not give open feedback within X seconds (takes time to open).
using System;
using System.Threading;
using System.Iec61131Lib;
using Iec61131.Engineering.Prototypes.Types;
using Iec61131.Engineering.Prototypes.Variables;
using Iec61131.Engineering.Prototypes.Methods;
using Iec61131.Engineering.Prototypes.Common;
namespace EclrFirmwareLibrary1
{
[FunctionBlock]
public class Valve_Test
{
[InOut]
public Valve Valve;
[Output]
public bool Output;
double seconds = 1.00; // 1 Second Interval
[Initialization]
public void __Init()
{
//
// TODO: Initialize the variables of the function block here
//
}
[Execution]
public void __Process()
{
Valve.Status.Interlock = Valve.Control.Interlock;
Valve.Status.Opened = Valve.Control.FB_Open;
Valve.Status.Closed = Valve.Control.FB_Closed;
if (Valve.Control.Manual_Mode == true){
Valve.Status.Manual_Mode = true;
Valve.Status.Auto_Mode = false;
}
if (Valve.Control.Auto_Mode == true & Valve.Control.Manual_Mode == false){
Valve.Status.Manual_Mode = false;
Valve.Status.Auto_Mode = true;
}
if(Valve.Status.Interlock == false & Valve.Alarm.General == false)
{
if (Valve.Status.Manual_Mode & Valve.Control.Manual_Control)
{
Output = true;
Valve.Status.Output = true;
}
else if (Valve.Status.Auto_Mode & Valve.Control.Auto_Control)
{
Output = true;
Valve.Status.Output = true;
}
else
{
Output = false;
Valve.Status.Output = false;
}
}
else
{
Output = false;
Valve.Status.Output = false;
}
//Alarms---------------------------------------------------
var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromSeconds(seconds);
var timer = new System.Threading.Timer((e) =>
{
CheckValve();
}, null, startTimeSpan, periodTimeSpan);
}
private void CheckValve()
{
if (Valve.Parameter.NormallyOpen == false)
{
if (Valve.Status.Output == true & Valve.Status.Opened == false)
{
Valve.Alarm.NotOpened = true;
}
if (Valve.Status.Output == false & Valve.Status.Closed == false)
{
Valve.Alarm.NotClosed = true;
}
}
else
{
if (Valve.Status.Output == false & Valve.Status.Opened == false)
{
Valve.Alarm.NotOpened = true;
}
if (Valve.Status.Output == true & Valve.Status.Closed == false)
{
Valve.Alarm.NotClosed = true;
}
}
if (Valve.Status.Opened == true & Valve.Status.Closed == true)
{
Valve.Alarm.OpenedAndClosed = true;
}
if (Valve.Alarm.NotClosed || Valve.Alarm.NotOpened || Valve.Alarm.OpenedAndClosed)
{
Valve.Alarm.General = true;
}
}
}
}
The important thing to note in this case is that the device you are using includes a .NET runtime implementation that is a subset and specialisation of the complete .NET runtime. This "eCLR" (Embedded CLR) is designed to operate in the deterministic real-time context required for many industrial control applications.
The details of this implementation can be seen in the PLCnext Info Center
When you create a PLCnext C# project in Visual Studio, the project includes a Programming Reference (.chm file). You will see from this reference that the Timer class is not included in the eCLR.
To your question:
There are a number of ways you can implement a delay function in a PLCnext C# function. Perhaps the simplest is to use the DateTime.Now property to get the current system time when the alarm condition is first seen, and remember this value. Then, on each call to the Process method, you can compare the current time to the time when the alarm condition was first seen. When the time period exceeds the preset time, then the output is set.
For more help with questions related to PLCnext Control devices, you can visit the PLCnext Community. There is an active forum there, where you can discuss these sorts of issues with other PLCnext users.
To call a method each x seconds you can use the TimeSpan Method provided by C# and just pass a method called CheckValve, where you put all your code into.
TimeSpan Example:
double seconds = 1.00; // 1 Second Interval
var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromSeconds(seconds);
var timer = new System.Threading.Timer((e) =>
{
CheckValve();
}, null, startTimeSpan, periodTimeSpan);
I would also advise you to refactor some of your code:
You can replace bool == true checks with just the bool and bool == false checks with just the bool and a ! before the name.
I would also add an else if so if the if is true you don't need to check the other statement.
CheckValve Method:
private void CheckValve() {
if (!Valve.Parameter.NormallyOpen) {
if (Valve.Status.Output && !Valve.Status.Opened) {
Valve.Alarm.NotOpened = true;
}
else if (!Valve.Status.Output && !Valve.Status.Closed)
{
Valve.Alarm.NotClosed = true;
}
}
}

C# - Control cannot fall through from one case label to another [duplicate]

This question already has answers here:
Control cannot fall through from one case label
(8 answers)
Closed 2 years ago.
So I'm trying to code an escort command for my game using case switch. Basically I have tons of other commands but I've never done one where it makes a target user follow the session user. Basically the person using the command would type :escorts username and it would make the other user stand either in front of the person using the command. or behind them. Any help would be amazing.
#region Escorts User
case "escorting":
{
#region Generate Instances / Sessions / Vars
if (!RoleplayManager.ParamsMet(Params, 1))
{
Session.SendWhisper("Invalid syntax: :stun x");
return true;
}
string Target = Convert.ToString(Params[1]);
GameClient TargetSession = null;
RoomUser Actor = null;
RoomUser Targ = null;
TargetSession = RoleplayManager.GenerateSession(Target);
if (TargetSession == null)
{
Session.SendWhisper("The user was not found in this room!");
return true;
}
if (TargetSession.JobManager() == null)
{
Session.SendWhisper("The user was not found in this room!");
return true;
}
if (TargetSession.JobManager().GetRoomUser() == null)
{
Session.SendWhisper("The user was not found in this room!");
return true;
}
if (TargetSession.JobManager().GetRoomUser().RoomId != Session.JobManager().GetRoomUser().RoomId)
{
Session.SendWhisper("The user was not found in this room!");
return true;
}
Targ = TargetSession.JobManager().GetRoomUser();
Actor = Session.JobManager().GetRoomUser();
int MyJobId = Session.GetRoleplay().JobId;
int MyJobRank = Session.GetRoleplay().JobRank;
Vector2D Pos1 = new Vector2D(Actor.X, Actor.Y);
Vector2D Pos2 = new Vector2D(Targ.X, Targ.Y);
#endregion
#region Police Conditions
if (Params.Length == 1)
{
Session.SendWhisper("Opa, você esqueceu de inserir um nome de usuário!");
return true;
}
GameClient TargetClient = Plus.GetGame().GetClientManager().GetClientByUserName(Params[1]);
if (TargetClient == null)
{
Session.SendWhisper("Ocorreu um erro ao tentar encontrar esse usuário, talvez ele esteja offline.");
return true;
}
RoomUser RoomUser = Session.JobManager().CurrentRoom.GetRoomUserManager().GetRoomUserByHabbo(Session.JobManager().UserName);
if (!JobManager.validJob(Session.GetRoleplay().JobId, Session.GetRoleplay().JobRank) && Session.GetRoleplay().inCR == false)
{
Session.SendWhisper("Your job cannot do this!", false, 34);
return true;
}
bool isclose = false;
if (!Session.GetRoleplay().JobHasRights("police")
&& !Session.GetRoleplay().JobHasRights("gov")
&& !Session.GetRoleplay().JobHasRights("swat")
&& !Session.GetRoleplay().JobHasRights("service")
&& RoleplayManager.CR == false)
{
Session.SendWhisper("Your job cannot do this!");
return true;
}
if (!Session.GetRoleplay().Working && RoleplayManager.CR == false)
{
Session.SendWhisper("You must be working to do this!");
return true;
}
if (Session.GetRoleplay().Dead)
{
Session.SendWhisper("You cannot do this while you are dead!");
return true;
}
if (Session.GetRoleplay().Jailed)
{
Session.SendWhisper("You cannot do this while you are in jail!");
return true;
}
if (Targ.Frozen)
{
Session.SendWhisper("This user is already stunned!");
return true;
}
if (Session.JobManager().CurrentRoom.RoomData.Description.Contains("NOCOP"))
{
Session.SendWhisper("Can't do this in 'NOCOP' rooms.");
return true;
}
if (JobManager.validJob(Session.GetRoleplay().JobId, Session.GetRoleplay().JobRank))
{
if (Session.JobManager().CurrentRoom.RoomData.Description.Contains("WESTERN") && Session.GetRoleplay().JobHasRights("police"))
{
Session.SendWhisper("Can't do this in 'WESTERN' rooms.");
return true;
}
if (!Session.JobManager().CurrentRoom.RoomData.Description.Contains("WESTERN") && Session.GetRoleplay().JobHasRights("western"))
{
Session.SendWhisper("Can only do this in 'WESTERN' rooms.");
return true;
}
}
#endregion
#region Execute
Point ClientPos = new Point(RoomUser.X, RoomUser.Y);
double Distance = RoleplayManager.Distance(Pos1, Pos2);
if (Distance <= 1)
{
if (Session.GetRoleplay().Cop == true && Session.GetRoleplay().inCR == true)
{
RoleplayManager.Shout(Session, "*Fires their stun-gun at " + TargetSession.JobManager().UserName + "*");
TargetSession.GetRoleplay().EffectSeconds = 10;
TargetSession.GetRoleplay().StunnedSeconds = 10;
Targ.ApplyEffect(590);
Targ.CanWalk = true;
Targ.Frozen = false;
Targ.ClearMovement();
LevelManager.AddLevelEXP(Session, 30);
Session.GetRoleplay().SaveQuickStat("currentxp", +30);
return true;
}
}
else
{
Session.SendWhisper("Você deve se aproximar desse cidadão para escoltá-lo!");
return true;
}
}
#endregion
#endregion
The error says that each case block cannot fall through another one.
This means that each case must have a return or break at their ending.
Keep in mind that you may group multiple cases into one (technically this is falling through) when they contain no code.
For more information, see MSDN.
Your switch statement is massive and probably needs some refactoring.

Can't get the correct Bool result in C#

I have a form where I would like to check for validation before processing the form. My form has 2 sections so I want to make sure that at least one item from each section is selected when they press submit button, and if they did then go to Dashboard.aspx. Even if I put all the required info when it checks for result1 and result2, I get false. Result1 and Result2 won't get the correct value. Even if the values are True again it passes false.
Here is my code:
protected void btnSumbit_Click(object sender, EventArgs e)
{
if (!Page.IsValid)
return;
bool result1 = false;
bool result2 = false;
CheckWireFromValidation(result1);
CheckWireToValidation(result2);
if (result1 == true && result2 == true)
{
Response.Redirect("~/DashBoard.aspx");
}
}
public bool CheckWireFromValidation (bool result1)
{
if (drpFromCoporate.SelectedIndex != 0 || drpFromCapital.SelectedIndex != 0 || drpFromProperty.SelectedIndex != 0)
{
result1 = true;
}
else
{
result1 = false;
ShowAlertMessage("You need to choose at least one filed from Wire From drop downs!!");
}
return result1;
}
public bool CheckWireToValidation(bool result2)
{
if (drpToCapital.SelectedIndex != 0 || drpToCoporate.SelectedIndex != 0 || drpToProperty.SelectedIndex != 0 || drpToTemplate.SelectedIndex != 0 || txtCorpAmt.Text != "" || txtCapAmt.Text != "" || txtPropAmt.Text != "" || txtTempelateAmt.Text != "")
{
result2 = true;
}
else
{
ShowAlertMessage("You need to choose at least one filed from Wire To drop downs!!");
}
return result2;
}
You're not using the results of CheckWireToValidation. You're using the false value you allocate initially.
Try this
bool result1 = false;
bool result2 = false;
if (CheckWireFromValidation(result1) && CheckWireToValidation(result2))
{
Response.Redirect("~/DashBoard.aspx");
}
Edit
The behavior you're expecting is that of the out parameter modifier. But please don't write code that way ...
I edited your code to get rid of .. em .. cruft. This should be more readable.
protected void btnSumbit_Click(object sender, EventArgs e)
{
if (!Page.IsValid)
return;
if (CheckWireFromValidation() && CheckWireToValidation())
{
Response.Redirect("~/DashBoard.aspx");
}
}
public bool CheckWireFromValidation ()
{
if (drpFromCoporate.SelectedIndex != 0 || drpFromCapital.SelectedIndex != 0 || drpFromProperty.SelectedIndex != 0)
{
return true;
}
else
{
ShowAlertMessage("You need to choose at least one filed from Wire From drop downs!!");
return false;
}
}
public bool CheckWireToValidation ()
{
if (drpToCapital.SelectedIndex != 0 || drpToCoporate.SelectedIndex != 0 || drpToProperty.SelectedIndex != 0 || drpToTemplate.SelectedIndex != 0 || txtCorpAmt.Text != "" || txtCapAmt.Text != "" || txtPropAmt.Text != "" || txtTempelateAmt.Text != "")
{
return true;
}
else
{
ShowAlertMessage("You need to choose at least one filed from Wire To drop downs!!");
return false;
}
}
Since you are passing Result1 and Result2 in as parameters instead assigning them. The results will never be set.
Here's one correct way of doing this
bool result1 = CheckWireFromValidation(result1);
bool result2 = CheckWireToValidation(result2);
if (result1 == true && result2 == true)
{
Response.Redirect("~/DashBoard.aspx");
}
and also a side note. I think we can safely remove the boolean parameter from the CheckWireFromValidation methods. Since the return value doesn't depends on the input variable.
Hope this helps.

How to handle NoNullAllowedException in try/catch?

I have a form in C# for inputting some data into a List.
The form consists of text boxes and up and down numeric boxes. Everything works fine but I want to have an error handler (try/catch) in my code so it will check if any of the text boxes are empty or the numeric boxes are left to 0, if thats the case it should pop up an error message.
I tried :
try
{
//code
}
catch (NoNullAllowedException e) //tried it without the e as well
{
//code
}
The code I was having in the brackets its the following one. Sometimes the GetItemDetails() was throwing me an error saying that not all code paths returns a value.
Any thoughts why is doing this or how can I fix it?
public iRepairable GetItemDetails()
{
Shirt shirt = null;
TShirt tshirt = null;
Trouser trouser = null;
Shoe shoe = null;
Boolean isShirt = true;
Boolean isTshirt = true;
Boolean isTrouser = true;
Boolean isShoe = true;
if (rdoShirt.Checked == true)
{
shirt = new Shirt(txtBrand.Text, Convert.ToDouble(txtPrice.Text), Convert.ToInt32(txtAmount.Text), txtCollection.Text);
isTshirt = false;
isTrouser = false;
isShoe = false;
}
else if (rdoTShirt.Checked == true)
{
tshirt = new TShirt(txtBrand.Text, Convert.ToDouble(txtPrice.Text), Convert.ToInt32(txtAmount.Text), txtCollection.Text);
isShirt = false;
isTrouser = false;
isShoe = false;
}
else if (rdoTrouser.Checked == true)
{
trouser = new Trouser(txtBrand.Text, Convert.ToDouble(txtPrice.Text), Convert.ToInt32(txtAmount.Text), txtCollection.Text);
isShirt = false;
isTshirt = false;
isShoe = false;
}
else
{
shoe = new Shoe(txtBrand.Text, Convert.ToDouble(txtPrice.Text), Convert.ToInt32(txtAmount.Text), txtCollection.Text);
isShirt = false;
isTrouser = false;
isTshirt = false;
}
if (isShirt)
{
return shirt;
}
else if (isTshirt)
{
return tshirt;
}
else if (isTrouser)
{
return trouser;
}
else //if(isShoe)
{
return shoe;
}
First of all, the NoNullAllowedException is not for list or just null values. Is the exception that throws when you want to insert null values in a column that doesn't allow them (for more info, MSDN).
For your code, place at the bottom of your code a default return value (but as far as i can see, your code shouldnt break at all)

FormatException 0 is not a valid value for Boolean

I am getting a formatexception with the following code. Any one know how to make BooleanConverter convert from 0/1 to true/false.
bool bVal=true;
string sVal = "0";
Console.WriteLine(TypeDescriptor.GetConverter(bVal).ConvertFrom(sVal));
Thanks for the help!
Try the following
public static bool ConvertToBasedOnIntValue(string value) {
// error checking omitted for brevity
var i = Int32.Parse(value);
return value == 0 ? false : true;
}
Or you could use the following which won't throw exceptions but it will consider everything that is quite literally not 0 to be true
public static bool ConvertToBasedOnIntValue(string value) {
if ( 0 == StringComparer.CompareOrdinal(value, "0") ) {
return false;
}
return true;
}
If you're going to use Int32.Parse, use Int32.TryParse instead. It doesn't throw if the conversion fails, instead returning true or false. This means that it's more performant if all you're doing is checking to see if your input is a value. Example:
public static bool ConvertToBool(string value)
{
int val = 0;
return (int.TryParse(value, out val) && val == 0) ? false : true;
}
I have a tendency to go overboard on the ternary operator (x ? y : z), so here's a slightly easier-to-read version:
public static bool ConvertToBool(string value)
{
int val = 0;
if (int.TryParse(value, out val))
{
return val == 0 ? false : true;
}
return false;
}
(I tested them both. "1" returns true, "0" returns false.)
There are only two cases so can just check for them explicitly.
I just built a helper function that will handle the special case of booleans:
Private Shared Function StringConverter(ByVal colValue As String, ByVal propertyType As Type) As Object
Dim returnValue As Object
'Convert the string value to the correct type
Select Case propertyType
Case GetType(Boolean)
'Booleans need to be coded separately because by default only "True" and "False" will map to a Boolean
'value. SQL Server will export XML with Booleans set to "0" and "1". We want to handle these without
'changing the xml.
Select Case colValue
Case "0"
returnValue = False
Case "1"
returnValue = True
Case "False"
returnValue = False
Case "True"
returnValue = True
Case Else
Throw New ArgumentException("Value of '" & colValue & "' cannot be converted to type Boolean.")
End Select
Case Else
'Let .Net Framework handle the conversion for us
returnValue = TypeDescriptor.GetConverter(propertyType).ConvertFromString(colValue)
End Select
Return returnValue
End Function
Your original code was good enough, only you can't set the string value to "0" and "1". In your code, TypeConverter.ConvertFrom() will eventually invoke Boolean.TryParse(), the code for which looks like this (thanks Reflector!)
public static bool TryParse(string value, out bool result)
{
result = false;
if (value != null)
{
if ("True".Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = true;
return true;
}
if ("False".Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = false;
return true;
}
if (m_trimmableChars == null)
{
char[] destinationArray = new char[string.WhitespaceChars.Length + 1];
Array.Copy(string.WhitespaceChars, destinationArray, string.WhitespaceChars.Length);
destinationArray[destinationArray.Length - 1] = '\0';
m_trimmableChars = destinationArray;
}
value = value.Trim(m_trimmableChars);
if ("True".Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = true;
return true;
}
if ("False".Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = false;
return true;
}
}
return false;
}
So make the following change to your code and you should be good:
bool bVal = true;
string sVal = "false";
Console.WriteLine(TypeDescriptor.GetConverter(bVal).ConvertFrom(sVal));
string _sOne = "1";
string _sTrue = "TrUe";
bool _bRandom = !Convert.ToBoolean(__sTrue);
string _sResult = Convert.ToBoolean(_sOne);
string _sResultB = Convert.ToBoolean(_sTrue);
string _sResultC = _bRandom.ToString();

Categories