Comma misplaced on RightToLeft label - c#

I'm trying to partially recreate the Windows 10 calculator but have run into some trouble. I have a code that looks like this for when the user enters a comma:
if (label_number.Text != null)
{
label_number.Text += ",";
}
else
{
label_number.Text = "0,";
}
So if the user enters the comma while the string is null I want the string to read out "0," but it only adds the "," to the label. And when I add a comma to a number, it comes out like this ",07839" instead of "07839,". Why is this happening? Like the title says my label is RightToLeft, but this also happens when that option is false.
Edit, here is the entire MouseClick EventHandler
'''
private void MouseClickEvent(object sender, MouseEventArgs e)
{
var obj = (sender as Label);
// Left click
if (e.Button == MouseButtons.Left)
{
if (obj.Name == "button_quit") // Quit
{
Application.Exit();
}
else if (obj.Name == "button_minimize") // Minimize
{
this.WindowState = FormWindowState.Minimized;
}
else if (obj.Name == "button_c") // Reset calc
{
label_input.Text = String.Empty;
label_number.Text = String.Empty;
}
else if (obj.Name == "button_ce") // Clear number
{
label_number.Text = String.Empty;
}
else if (obj.Name == "button_delete") // Delete
{
if (label_number.Text.Length == 1)
{
label_number.Text = String.Empty;
}
else if (label_number.Text.Length > 1)
{
label_number.Text = label_number.Text.Remove(label_number.Text.Length - 1, 1);
}
}
else if (obj.Name == "button_divide" || obj.Name == "button_multiply" || obj.Name == "button_subtract" || obj.Name == "button_add") // / * - +
{
switch (obj.Name)
{
case "button_divide":
break;
case "button_multiply":
break;
case "button_subtract":
break;
case "button_add":
break;
}
}
else if (obj.Name == "button_comma") // Comma
{
if (label_number.Text != String.Empty)
{
label_number.Text += ",";
}
else
{
label_number.Text = "0,";
}
}
else if (obj.Name == "button_equals") // Calculate equation
{
}
else // Number input
{
if (label_number.Text.Length < 13)
{
if (obj.Name != "button_0")
{
if (label_number.Text.Length == 1 && label_number.Text == "0")
{
label_number.Text = obj.Name[obj.Name.Length - 1].ToString();
}
else
{
label_number.Text += obj.Name[obj.Name.Length - 1].ToString();
}
}
else
{
label_number.Text += obj.Name[obj.Name.Length - 1].ToString();
}
}
}
}
}
'''

Related

Are switch-case statements allowed for multiple conditions?

I was going to do a complex number class, and I appear to have too many conditionals involving multiple statements on one of my functions. Here is a snippet of my program with a ToString() function:
public override string ToString()
{
if (this.real == 0 && this.imaginary == 0)
{
return "0";
}
else if (this.real == 0 && this.imaginary == 1)
{
return "i";
}
else if (this.real == 0 && this.imaginary == -1)
{
return "-i";
}
else if (this.real == 0 && (this.imaginary != 1 && this.imaginary != -1))
{
return String.Concat(this.imaginary.ToString(), "i");
}
else if (this.real != 0 && this.imaginary == 0)
{
return String.Concat(this.real.ToString());
}
else if (this.real != 0 && this.imaginary == 1)
{
return String.Concat(this.real.ToString(), " + i");
}
else if (this.real != 0 && this.imaginary == -1)
{
return String.Concat(this.real.ToString(), " - i");
}
else if (this.real != 0 && this.imaginary < -1)
{
this.imaginary = -this.imaginary;
return String.Concat(this.real.ToString(), " - ", this.imaginary.ToString(), "i");
}
return String.Concat(this.real.ToString(), " + ", this.imaginary.ToString(), "i");
}
Would switch statements be helpful for multiple conditions?
Make code more readable with eliminating redundant checks.
Use string interpolation instead of String.Concat
public override string ToString()
{
if (real == 0)
{
if (imaginary == 0)
{
return "0";
}
if (imaginary == 1)
{
return "i";
}
if (imaginary == -1)
{
return "-i";
}
if (imaginary != 1)
{
return $"{imaginary}i";
}
}
else
{
if (imaginary == 0)
{
return real.ToString();
}
if (imaginary == 1)
{
return $"{real} + i";
}
if (imaginary == -1)
{
return $"{real} - i";
}
if (imaginary < -1)
{
imaginary = -imaginary;
return $"{real} - {imaginary}i";
}
}
return $"{real} + {imaginary}i";
}
You cannot have more than one condition in switch, but it looks like this.real has only two possibilities, 0 or 1, so you can take that out an use a switch for this.imaginary.
Also it is probably better to use String.Format() or String Interpolation instead of String.Concat().
public override string ToString() {
if (this.real == 0) {
switch(this.imaginary) {
case 0:
return "0";
case 1:
return "i";
case -1:
return "-i";
default:
return $"{this.imaginary}i";
}
else {
switch(this.imaginary) {
case 0:
return this.real.ToString();
case 1:
return $"{this.real} + i";
case -1:
return $"{this.real} - i";
default:
if (this.imaginary < -1) {
this.imaginary = -this.imaginary;
return $"{this.real} - {this.imaginary}i";
}
}
}
return $"{this.real} + {this.imaginary}i";
}
Your code is overcomplicated and redundant because you've come up with a separate branch for each possible situation. Your code will be a lot simpler if you break it down and do the following:
Get the real part (if there is one) and the imaginary part (if there is one)
Combine them together if there are two parts
The following will do this:
private string RealPartString()
{
if (real == 0) { return imaginary == 0 ? "0" : null; }
return real.ToString();
}
private string ImaginaryPartString()
{
if (imaginary == 0) { return null; }
var abs = Math.Abs(imaginary);
var number = abs == 1 ? "" : abs.ToString();
// Only include the sign here if there is no real part
var sign = real == 0 && imaginary < 0 ? "-" : "";
return sign + number + "i";
}
public override string ToString()
{
var parts = new[] { RealPartString(), ImaginaryPartString() }.Where(s => s != null);
var sign = imaginary < 0 ? " - " : " + ";
return string.Join(sign, parts);
}

C# replace do..while with for loop

I usually know how to replace a do..while loop with a for loop, but in this case variable check2 is used 2 times for different loops with got me confused on how to correctly replace it with for loop.
public static void RelayChat(ref int con, ref string Message)
{
string temp_SubName = "relaychat";
WriteSub(ref temp_SubName);
int check2 = 0;
if (Message.Length == 0) return;
var check = UserConToCheck(con);
if (CheckMute(get_UserName(check)) || get_UserChat(check) > 4) return;
if (get_UserChat(check) < 8) set_UserChat(check, get_UserChat(check) + 1);
if (Message.Length > 100) Message = Message.Substring(0, 99);
if (Message[0] == '!')
{
if (UserCommand(con, Message.Substring(1).Split(" ".ToCharArray()))) return;
}
if (PlayerAdapter.get_Reference(check).get_IsAdmin(1))
{
if (Message.Substring(0, 1) == "#")
{
string[] temp_cmds = Message.Substring(1).Split(",".ToCharArray());
admin.AdminCommand(PlayerAdapter.get_Reference(check), ref temp_cmds);
return;
}
}
if (Message.StartsWith(":g::", true, null))
{
do
{
check2++;
var guild1 = get_UserGuild(check);
var guild2 = get_UserGuild(check2);
if (guild1 == null || guild2 == null || guild1.ToLower() != guild2.ToLower()) continue;
var thisuser = get_UserName(check);
var targetuser = get_UserName(check2);
var found = targetuser != null && thisuser != null &&
IgnoreUserList.ContainsKey(targetuser) &&
IgnoreUserList[targetuser].Contains(thisuser);
if (found == false)
{
Winsock.PrivMsg(get_UserCon(check2), "14,1,[ " + get_UserGuild(check2) + " ] Chat - " + get_UserName(check) + " : " + Message.Substring(4));
}
} while (check2 != UserMax);
return;
}
if (check <= 0) return;
do
{
check2++;
bool found = false;
var user = get_UserName(check2);
if (user != null && IgnoreUserList.ContainsKey(user))
{
found = Convert.ToBoolean(IgnoreUserList[get_UserName(check2)].Contains(get_UserName(check)));
}
if (found) return;
if (get_UserLanded(check2) != get_UserLanded(check)) return;
if (get_UserLanded(check2))
{
if (get_UserInBar(check2) == false &&
get_UserInUniversalBar(check2) == false) return;
if (get_UserInUniversalBar(check2) && get_UserInUniversalBar(check))
{
Winsock.PrivMsg(get_UserCon(check2), "13,0,[ " + get_UserName(check) + " ] : " + Message);
}
else if (get_UserInBar(check2) && get_UserInBar(check))
{
if (get_UserLastPlanet(check2) !=
get_UserLastPlanet(check)) return;
Winsock.PrivMsg(get_UserCon(check2), "13,0,[ " + get_UserName(check) + " ] : " + Message);
}
}
else if (get_UserLanded(check2) == false)
{
if (get_UserSector(check2) != get_UserSector(check)) return;
if (get_UserZone(check2) != get_UserZone(check)) return;
Winsock.PrivMsg(get_UserCon(check2), "13,0,[ " + get_UserName(check) + " ] : " + Message);
}
} while (check2 != UserMax);
}
I know that the function might be a lot complex, but please ignore that fact and focus on just the do..while loops. Thank you!
Just declare the for loop to use the existing variable.
int check2 = 0;
if (Message.StartsWith(":g::", true, null))
{
for (; check2 < UserMax; check2++)
{
// Do stuff
}
return;
}
if (check <= 0) return;
for (; check2 < 200; check2++)
{
// Do stuff
}

C# - Condition which is true if 3/9 buttons have the same text

I'm trying to make a basic noughts and crosses game in c#.
So far I've made the grid using buttons which's text changes when it is pressed depending which player's turn it is.
The part which I am stuck on is checking if any of the players has won, I've written this however it doesn't seem to do anything.
private void Form1_Load(object sender, EventArgs e)
{
if (button1.Text == "X" && button5.Text == "X" && button9.Text == "X")
{
MessageBox.Show("Player", player_turntxt.Text + " wins");
Application.Restart();
}
}
private void button1_Click(object sender, EventArgs e)
{
int Player_Turn = Convert.ToInt32(player_turntxt.Text);
if (Player_Turn == 1)
{
button1.Text = "X";
player_turntxt.Text = "2";
button1.Enabled = false;
return;
}
else
{
button1.Text = "O";
player_turntxt.Text = "1";
button1.Enabled = false;
return;
}
(The Application.Restart(); is just a temporary method of checking if it works.)
This is just one of 8 statements which I'll have to make as conditions for victory, any idea where I'm going wrong?
Update:
public void CheckForWinner(int x)
{
if (button1.Text == "X" && button5.Text == "X" && button9.Text == "X")
{
x = 1;
}
else if (button3.Text == "X" && button5.Text == "X" && button7.Text == "X")
{
x = 1;
}
else if (button1.Text == "X" && button4.Text == "X" && button7.Text == "X")
{
x = 1;
}
else if (button2.Text == "X" && button5.Text == "X" && button8.Text == "X")
{
x = 1;
}
else if (button3.Text == "X" && button6.Text == "X" && button9.Text == "X")
{
x = 1;
}
else if (button1.Text == "X" && button2.Text == "X" && button3.Text == "X")
{
x = 1;
}
else if (button4.Text == "X" && button5.Text == "X" && button6.Text == "X")
{
x = 1;
}
else if (button7.Text == "X" && button8.Text == "X" && button9.Text == "X")
{
x = 1;
}
if (button1.Text == "O" && button5.Text == "O" && button9.Text == "O")
{
x = 2;
}
else if (button3.Text == "O" && button5.Text == "O" && button7.Text == "O")
{
x = 2;
}
else if (button1.Text == "O" && button4.Text == "O" && button7.Text == "O")
{
x = 2;
}
else if (button2.Text == "O" && button5.Text == "O" && button8.Text == "O")
{
x = 2;
}
else if (button3.Text == "O" && button6.Text == "O" && button9.Text == "O")
{
x = 2;
}
else if (button1.Text == "O" && button2.Text == "O" && button3.Text == "O")
{
x = 2;
}
else if (button4.Text == "O" && button5.Text == "O" && button6.Text == "O")
{
x = 2;
}
else if (button7.Text == "O" && button8.Text == "O" && button9.Text == "O")
{
x = 2;
}
}
You should create a method to check if any player has won, and run it at the end of everyone of your "button clicks".
I algo suggest you to remove the "return"'s from your button clicks. They can introduce unexpected behaviors sometimes, like ending the function before you execute the line of code that calls the method to check if someone has won.
Something like this:
private void button1_Click(object sender, EventArgs e)
{
int Player_Turn = Convert.ToInt32(player_turntxt.Text);
if (Player_Turn == 1)
{
button1.Text = "X";
player_turntxt.Text = "2";
button1.Enabled = false;
}
else
{
button1.Text = "O";
player_turntxt.Text = "1";
button1.Enabled = false;
}
CheckIfSomeoneHasWon();
}
Let's discuss the implementation of CheckIfSomeoneHasWon. I figure that there are several ways of doing it. We could create a bidimensional array with the values of the buttons, and iterate it. In fact, I will do it that way. Your way works too, but we would have to write a lot. This is what I came up with:
static readonly string _player1_symbol = "X";
static readonly string _player2_symbol = "O";
static void CheckIfSomeoneHasWon()
{
string[,] userChoices = BuildUserChoices();
string winner = CheckWhoWon(userChoices);
if (winner != null)
{
// Somebody won! Display message and start over
}
}
private static string CheckWhoWon(string[,] values)
{
// Horizontal checks
for (int i = 0; i < 3; i++)
{
if (values[i, 0] == values[i, 1] && values[i, 1] == values[i, 2])
{
return (values[i, 0] == _player1_symbol) ? "player 1" : "player 2";
}
}
// Vertical checks
for (int i = 0; i < 3; i++)
{
if (values[0, i] == values[1, i] && values[1,i] == values[2,i])
{
return (values[i, 0] == _player1_symbol) ? "player 1" : "player 2";
}
}
// Diagonal checks
if (values[0, 0] == values[1, 1] && values[1, 1] == values[2, 2])
{
return (values[0, 0] == _player1_symbol) ? "player 1" : "player 2";
}
if (values[0, 2] == values[1, 1] && values[1, 1] == values[2, 0])
{
return (values[1, 1] == _player1_symbol) ? "player 1" : "player 2";
}
// No one has won yet
return null;
}
private static string[,] BuildUserChoices()
{
var values = new string[3, 3];
values[0, 0] = button1.Text;
values[0, 1] = button2.Text;
values[0, 2] = button3.Text;
// and so on...
// If a button has not been click, they must have a unique text, like a number
return values;
}
You need to check if a player wins after each turn. Right now you are checking it once, after the form loaded.

How to prevent stack overflow error in javascript?

I have a javascript function called MakeInput.
It has got approximately 150 lines.
And I have to call that function about 300 times in my code.
My C# code called that function through webbrowser control.
It has to call that function 300 times, until DataTable in C# finishes looping.
But maybe javascript in webbrowser thinks that I am calling an infinite recursive function, so when it comes to about 60 times, it always throws an error called stack overflow at line 38.
How can I prevent this error?
How can I do a long time function in javascript?
EDIT
OK.
I am posting my code.
Here it goes.
C#
ieBrowser.Document.InvokeScript("setPageIndex", new object[] { currentPage });
ieBrowser.Document.InvokeScript("fnSearch");
JavaScript
function fnSearch() {
var frm = document.searchFrm;
var str = encryptData(frm, _currentPage);
}
function encryptData(form, _currentPage) {
var retValue = "";
try {
var crypto = document.getElementById("SomeActiveX");
var resultVal = MakeInput(form);
var inputStr = "";
if (resultVal[0] != "" && resultVal[1] != "") {
inputStr = resultVal[0] + "&" + resultVal[1];
}
else if (resultVal[0] == "") {
inputStr = resultVal[1];
}
else if (resultVal[1] == "") {
inputStr = resultVal[0];
}
else {
inputStr = "";
}
retValue = crypto.Encrypt(inputStr);
}
catch (e) {
alert(e);
}
return retValue;
}
function MakeInput(form) {
var result = new Array(2);
try {
var keyProc = document.getElementById("SomeActiveX");
var name = new Array(form.elements.length);
var value = new Array(form.elements.length);
var enc_name = new Array();
var enc_value = new Array();
var enc_idx = 0;
var j = 0;
var len = form.elements.length;
for (i = 0; i < len; i++) {
if ((form.elements[i].type != "button") && (form.elements[i].type != "reset") &&
(form.elements[i].type != "submit")) {
if ((form.elements[i].type == "radio") || (form.elements[i].type == "checkbox")) {
if (form.elements[i].checked == true) {
name[j] = form.elements[i].name;
value[j] = form.elements[i].value;
j++;
}
}
else if ((form.elements[i].type == "text") || (form.elements[i].type == "password")) {
name[j] = form.elements[i].name;
value[j] = form.elements[i].value;
j++;
if (keyProc != null && (form.elements[i].getAttribute("enc") == "on")) {
enc_name[enc_idx] = "_E2E_" + form.elements[i].name;
enc_value[enc_idx] = keyProc.GetEncData("", form.name, form.elements[i].name);
enc_idx++;
}
}
else {
if (form.elements[i].type == "select-one") {
var ind = form.elements[i].selectedIndex;
var singleLen = form.elements[i].length;
if (singleLen > 0) {
if (ind >= 0) {
name[j] = form.elements[i].name;
value[j] = form.elements[i].options[ind].value;
j++;
}
else {
}
}
else {
}
}
else if (form.elements[i].type == "select-multiple") {
var multiLen = form.elements[i].length;
for (k = 0; k < multiLen; k++) {
if (form.elements[i].options[k].selected) {
name[j] = form.elements[i].name;
value[j] = form.elements[i].options[k].value;
j++;
}
}
}
else {
name[j] = form.elements[i].name;
value[j] = form.elements[i].value;
j++;
}
}
}
}
var flag1 = false;
var flag2 = false;
var signed_text = "";
var unsigned_text = "";
for (i = 0; i < j; i++) {
if (name[i].charAt(0) != "_") {
if (flag1) {
signed_text += "&";
}
else {
flag1 = true;
}
signed_text += name[i];
signed_text += "=";
signed_text += escape_url(value[i]);
}
else {
if (flag2) {
unsigned_text += "&";
}
else {
flag2 = true;
}
unsigned_text += name[i];
unsigned_text += "=";
unsigned_text += escape_url(value[i]);
}
}
for (i = 0; i < enc_idx; i++) {
if (flag2) {
unsigned_text += "&";
}
else {
flag2 = true;
}
unsigned_text += enc_name[i];
unsigned_text += "=";
unsigned_text += enc_value[i];
}
if (enc_idx > 0) {
if (flag2) {
unsigned_text += "&";
}
else {
flag2 = true;
}
unsigned_text += "_ENCSEED";
unsigned_text += "=";
unsigned_text += keyProc.GetEncData(serverCert, "", "");
}
result[0] = signed_text;
result[1] = unsigned_text;
}
catch (e) {
throw e;
}
return result;
}
And the error message was captured.
Sorry, the error message is written in Korean.
But it says, "Stack overflow(at line 38)".
But I think the number is not pointing at the line number, coz I've changed lines but the error message is always 38.
It doesn't think you are in a continuous loop. It fails when memory runs out in stack. The same code might work on a computer with higher memory. Each time a function is called a stack entry is kept in stack to move to calee once the function is done, so in your case the stack space runs out after 60 calls. The line 38 is not line number in your code.
Why dont you try same code on a high end PC

create a random loop until a statement is true

What should I do if I wanted the program to generate a random number then re-read/loop the else if statement until it finds a statement that is similar to this if (button1.Text == ""), The random number only needs to go up to 9.
This is my code,
private void button1_Click(object sender, EventArgs e)
{
var rc = new Random();
storeRI = rc.Next(1, 9);
if (storeRI == 1)
{
if (button1.Text == "")
{
button1.Text = "X";
}
else
{
//Need to generate another random number
//And read the else if statement again... how?
}
}
else if (storeRI == 2)
{
if (button1.Text == "")
{
button1.Text = "X";
}
else
{
//Need to generate another random number
//And read the else if statement again... how?
}
}
private void button1_Click(object sender, EventArgs e)
{
var rc = new Random();
do
{
storeRI = rc.Next(1, 9);
if (storeRI == 1)
{
if (button1.Text == "")
{
button1.Text = "X";
}
}
else if (storeRI == 2)
{
if (button1.Text == "")
{
button1.Text = "X";
}
}
} while (button1.Text == "");
}
put the if statements in a while() loop. Then have a contidion that executes a break; statement to terminate the loop:
while(button1.Text == "")
{
if (storeRI == 1)
{
if (button1.Text == "")
{
button1.Text = "X";
}
else
{
//Need to generate another random number
storeRI = rc.Next(1, 9);
}
}
else if (storeRI == 2)
{
...
}
else
break;
}
var rc = new Random();
int[] numbers = { 1, 2 }; // numbers from your if..else blocks
do {
storeRI = rc.Next(1, 9);
if (!numbers.Contains(storeRI))
break; // not matched any if..else block
if (button1.Text == "")
{
button1.Text = "X";
break; // set text and break loop
}
} while(true); // generate new number and do check again

Categories