I want to design a function that checks whether Player A or B wins.
Right now I'm just reusing a bunch of code. I would like to use the same function for each if possible. Right now I have two different if statements, one for A and for B. Any tips on how I should merge them?
Can I create a function which takes in both A and B values and use some kind of tenary function with just one if statement?
if (label[x,0].theValue() == A && label[x,1].theValue() == A && label[x,2].theValue) == A)
{
MessageBox.Show("A Wins!");
}
if (label[x,0].theValue() == B && label[x,1].theValue() == B && label[x,2].theValue) == B)
{
MessageBox.Show("B wins!");
}
I think you can do something like this:
public string CheckWinner(int x){
if( "your code" ) { return "A wins"; }
if( "your code" ) { return "B wins"; }
}
And then on your main function (form)
MessageBox.Show(CheckWinner(1));
I Hope this helps.
You can write a funktion to check if a given player has won like this (assuming A and B in your code are Player-objects)
private bool HasWon(Player player)
{
if (label[x,0].theValue() == player && label[x,1].theValue() == player && label[x,2].theValue() == player)
{
return true;
}
return false;
}
You can use this function like so:
if(HasWon(A))
{
MessageBox.Show("A Wins!");
}
or, if you have a List or something like this of all playing players, do like so:
foreach(var player in players)
{
if(HasWon(player))
{
MessageBox.Show(player.Name + " Wins!");
}
}
Add a method to check if A is the winner:
public bool IsAWinner(string x0value, string x1value, string x2value)
{
if (x0value == "A" && x1value == "A" && x2value == "A")
return true;
return false;
}
Call this one from your UI code to check if A is the winner, if it isn't, B is the winner.
The idea is to NOT use windows controls in this method; so that it can be tested (loose coupling from UI).
So from your UI:
if (IsAWinner(label[x,0].theValue(), label[x,1].theValue(),label[x,2].theValue))
MessageBox.Show("A Wins!");
else
MessageBox.Show("B wins!");
Also, don't forget to add some exception handling.
While I've never used C# I would imagine the second If statement is not needed. If A wins, then B loses whereas if B Wins A loses.
If A wins ... else B wins!
Sorry I can't give you a code sample, C# isn't my thing.
Related
I have the two following pieces of code, in one I initialize the isSpclChar bool as false, in the other one I catch the false state later in an else statement:
static bool CheckSpclChar(char _letter)
{
bool isSpclChar = false;
if(_letter == '!' || _letter == '#')
{
isSpclChar = true;
}
return isSpclChar;
}
And:
static bool CheckSpclChar(char _letter)
{
bool isSpclChar;
if(_letter == '!' || _letter == '#')
{
isSpclChar = true;
}
else
{
isSpclChar = false;
}
return isSpclChar;
}
Which of them is best practice or less prone to errors in this type of case?
Does it not matter at all?
No need for an else at all:
bool isSpecialChar = _letter == '!' || _letter == '#';
In fact, your whole method can be simplified to:
static bool CheckSpecialChar(char letter) => letter == '!' || letter == '#';
I've expanded "Spcl" to "Special" for better readability, and removed the leading prefix from the parameter name to follow .NET conventions. You might also want to consider using Is instead of Check.
Finally, you might want to avoid using the word "special" in the method name too. I tend to wince when I hear the phrase "special character" because without more specific context, it's meaningless. What do ! and # mean in this context? Is there a more useful description you could give, such as IsEscapePrefix or something similar?
We should use variables when we need to use that values, otherwise you just need to write your method as follows. Let me know, if that makes sense?
static bool CheckSpclChar(char _letter)
{
if(_letter == '!' || _letter == '#')
{
return true;
}
return false;
}
i have a project in which i have assigned some functions to single characters(e.g. Keyboard Key "H" will do high pass filtering).
Now To get "H" as an output i have created a down event which hopefully pick up the keys are down and calls the function with an integer value. However I get an error when i try to compare the input value with an integer value in the function. The following is my code...
public static event DownEventHandler Down;
public static delegate void DownEventHandler(string Key);
Down(FunctionChar((Keys)lParam.Code)); // lParam.code is an integer value.
private string FunctionChar(Keys e)
{
if(e >=65 && e<=90){
if (Control.IsKeyLocked(Keys.CapsLock) || ((Control.ModifierKeys !=0) && (Keys.Shift) != 0))
{
return e.ToString;
}
else
{
return e.ToString.ToLower;
}
}
I assume that this function will give me the output a string either "G" or "g". as mentioned before i want to use it in further functionality.
However it gives me error as following.
Operator '>=' cannot be applied to operands of type 'System.Windows.Forms.Keys' and 'int'
I know one of the solution is to use SWITCH statement but i want to use if statement and not switch.
Can some one tell me - what is the problem? What values does "e" posses and how can i convert it to (Int) so i can use it in the IF statement.
You can't compare System.Windows.Forms.Key with and Integer so you have to convert the key has been converted to an integer before you compare them. here is an example for you:
Keys e = Keys.A;
int keyVal= (int)e;// return 65
So you can do like this:
if((int)e >=65 && (int)e<=90)
{
// your code goes here
}
Another way for doing this is:
if(e >= Keys.A&& e<= Keys.Z)
{
// your code goes here
}
Update :
You can return the corresponding character using : return ((char)e).ToString();
Hence the whole function signature will be like the following:
private string FunctionChar(Keys e)
{
if ((int)e >= 65 && (int)e <= 90)
{
if (Control.IsKeyLocked(Keys.CapsLock) || ((Control.ModifierKeys != 0) && (Keys.Shift) != 0))
{
return ((char)e).ToString();
}
else
{
return ((char)e).ToString().ToLower();
}
}
return "";
}
When working with an enum, such as Keys, it's better design to express any conditions in terms of the enum's values, rather than casting back to ints.
So I'd recommend replacing:
if(e >=65 && e<=90)
with
if (e >= Keys.A && e <= Keys.Z).
This should compile fine - and your intention is clearer to anyone reading your code!
I'd rather not use magic numbers but actual chacraters, and I'd write an extension method(s) for this:
public static class KeysExtensions
{
public static Boolean IsLetter(this Keys value)
{
return value >= Keys.A && value <= Keys.Z;
}
}
So when handling events you can put readable code:
private void Something_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.IsLetter())
{
// Do your operations here...
}
}
-I cannot change int values created in main using a class function-
I am making a game and I have a function called sideCollision that checks if the player is touching a pictureBox,and if the player is touching the pictureBox,an integer called Score is incremented by 1.
Here is the function:
public void sideCollision(Control player,Control pointRadius,Control topPipe,Control bottomPipe,Control gameOver,int force,bool timer,int score,int pointRadiusCounter)
{
if (player.Right > pointRadius.Left && player.Left < pointRadius.Right - player.Width / 2 && player.Bottom > pointRadius.Top)
{
if (timer == true && pointRadiusCounter == 0)
{
pointRadiusCounter = 1;
score++;
}
}
}
The function detects the player touching the wall,but it does not increment the score by 1. I also have a message in my main saying "score has not been assigned to,and will always have its default value of 0".
I need to know how to change the score value using the function,because the function isn't changing the value of Score
You shouldn't use pass-by-reference in situations like this. Instead, you could in this situation use something like this.
private void SomeMethod()
{
var score = 0;
var pointRadiusCounter = 0;
if (CollisionOccurred(...))
{
score++;
pointRadiusCounter++;
}
...
...
...
}
public bool CollisionOccurred(Control player,Control pointRadius,Control topPipe,Control bottomPipe,Control gameOver,int force,bool timer)
{
if (player.Right > pointRadius.Left && player.Left < pointRadius.Right - player.Width / 2 && player.Bottom > pointRadius.Top)
{
if (timer == true && pointRadiusCounter == 0)
{
return true;
}
}
return false;
}
Forgive me for this being a little bit offtopic but this might help you avoiding problems like the one you have at the moment:
I would consider to think about what variables need to be passes as a
parameter and what variables could also be accessible from all your
classes because their value will, whether it is changed or not, be the
same at any point of your code (for example lifepoints of the player,
score of the player, position of the player).
Then you could transfer them into a own class (for this example the
"player" class), make those variables attributes of this class, and
make those accessible for your other classes via making the attributes
public static or an Singleton-class if there is just 1 player in
the game.
Passing an amount of variables as high as you do to
sideCollision(...) can cause a lot of trouble when your project
becomes bigger. Arranging and prioritizing your variables, methods,
classes etc. can help you to prevent this. So take your time and think
about what is important and where you need it and stuff like that.
int is a value type. That means it's passed by-value and inside the function you have a copy of your original variable. You can solve this by passing it by-reference explicitly:
public void sideCollision(Control player,Control pointRadius,Control topPipe,Control bottomPipe,Control gameOver,int force,bool timer, ref int score, ref int pointRadiusCounter)
{
if (player.Right > pointRadius.Left && player.Left < pointRadius.Right - player.Width / 2 && player.Bottom > pointRadius.Top)
{
if (timer == true && pointRadiusCounter == 0)
{
pointRadiusCounter = 1;
score++;
}
}
}
I want to do something like Google does in its search: if the user write some special char, like - or * the results are filtered.
What I have now: a filter that filters objects Name property with Contains method, and two special characters:
for leaving only the names that don't contain the typed text -
for searching a different property of my object (in my case it is Units) *
Ok, what I need is to combine above logic and be able to first filter with "-" or "*" and then be able to type and continue filtering the remaining results.
It's all about the logic I think, but it's getting complicated and I might need a little help.
item.View.Filter = delegate(object o)
{
//Lógica de filtrado
if ((item.FilterText.Length > 0) && ((item.FilterText[0] == '*') || (item.FilterText[0] == '-')))
{
//If the first char is *
if ((item.FilterText[0] == '*')
&& (((MyObject)o).Units[0].ToString().ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture).Substring(1))
|| ((MyObject)o).Units[1].ToString().ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture).Substring(1))))
{
return true;
}
//If the first char is -
if ((item.FilterText[0] == '-')
&& (!((MyObject)o).Name.ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture).Substring(1))
|| !((MyObject)o).Name.ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture).Substring(1))))
{
return true;
}
}
else
{
if (((MyObject)o).Name.ToUpper(CultureInfo.InvariantCulture)
.Contains(item.FilterText.ToUpper(CultureInfo.InvariantCulture)))
{
return true;
}
}
return false;
};
I have two conditions, ShouldCheckForErrors and HasErrors
My code is
if(ShouldCheckForErrors && HasErrors)
{
//Do nothing
}
else
{
PassTest()
}
I feel like this is a very longwinded check. Isn't there a way that I can do a single check without having to use else?
For example:
if(!ShouldCheckForErrors && !HasErrors)
{
PassTest()
}
does not work, because that would fail to call PassTest() when ShouldCheckforErrors is true, but HasErrors is false. (And vice versa)
I just feel like I am forgetting something with my Logical Operators.
You're looking for De Morgan's Law:
if (!ShouldCheckForErrors || !HasErrors)
To put it differently:
You should pass either if there are no errors, or if we aren't checking errors.
Use not operator ! after you get result of both conditions
if(!(ShouldCheckForErrors && HasErrors))
{
PassTest();
}
Your logic is a bit off
!ShouldCheckForErrors && !HasErrors
is not the same as
!(ShouldCheckForErrors && HasErrors)
which is what I believe you want
Simpler case -
if(theOnlyCheck) {
}
else {
do();
}
You seem to be savvy enough to shorten this check -
if(!theOnlyCheck) {
do();
}
But you simply mess up your order of operations.
Substitute (check1 && check2) for theOnlyCheck. Don't forget parentheses:
if(!(check1 && check2)) {
do();
}
Now if you don't like dealing with these parentheses you can follow De Morgan's Law: !(a && b) is the same as !a || !b. Think it through yourself to see -
if(!check1 || !check2) {
do();
}