I'm creating a BlackJack game in C#, everything (I'm pretty sure) works, before it gets to my Do-While loop(where everything in the actual game happens.) and when it does, it just either freezes or nothing happens at all. I noticed when I get rid of my Do-While loop the game doesn't freeze, so I'm guessing it's in an infinite loop or something, but I'm not sure what to do here.
namespace Blackjack
{
public partial class Form1 : Form
{
public Boolean standClicked = false;
public Boolean hitClicked = false;
public Boolean over;
public Cards[] cardSet = new Cards[5];
public PictureBox[] picArray = new PictureBox[5];
public int points;
public int i;
public Form1()
{
InitializeComponent();
//Makes all card images hidden
Card1.Hide();
Card2.Hide();
Card3.Hide();
Card4.Hide();
Card5.Hide();
//Makes the win-lose label blank
winOrLoseLabel.Text = " ";
buttonHit.Hide();
buttonStand.Hide();
}
private void buttonExit_Click(object sender, EventArgs e)
{
//Closes the application
this.Close();
}
private Image SetImage(int cardValue)
{
Image _ = null;
if (cardValue >= 0)
{
for (int check = 0; check >= 50; check++)
{
if (cardValue == check)
{
_ = imageList1.Images[check];
}
}
}
if (_ == null)
{
_ = imageList1.Images[0];
}
return _;
}
public void buttonHit_Click(object sender, EventArgs e)
{
hitClicked = true;
if (hitClicked == true)
{
picArray[i].Image = SetImage(cardSet[i].GetValue());
points += cardSet[i].CardValue();
pointCounter.Text = points.ToString();
}
points += Convert.ToInt32(pointCounter.Text);
if (points >= 21)
over = true;
else
over = false;
i++;
}
private void buttonStand_Click(object sender, EventArgs e)
{
standClicked = true;
buttonHit.Enabled = false;
}
private void buttonPlay_Click_2(object sender, EventArgs e)
{
// Reveals all cards on the form
Card1.Show();
Card2.Show();
Card3.Show();
Card4.Show();
Card5.Show();
//Hides the logo as well as the play and exit buttons
pictureBox3.Hide();
buttonPlay.Hide();
buttonExit.Hide();
//Sets both hit and stand buttons to be enabled again
buttonHit.Show();
buttonStand.Show();
buttonHit.Enabled = true;
buttonStand.Enabled = true;
//Makes the win-lose label blank
winOrLoseLabel.Text = " ";
//Sets the "standClicked boolean value to false - to not automatically end the game
pointCounter.Text = "0";
points = Convert.ToInt32(pointCounter.Text);
//Makes the cardset values randomized
cardSet[0] = new Cards(0);
cardSet[0].Value = 0;
cardSet[0].SetCards();
cardSet[1] = new Cards(0);
cardSet[1].Value = 0;
cardSet[1].SetCards();
cardSet[2] = new Cards(0);
cardSet[2].Value = 0;
cardSet[2].SetCards();
cardSet[3] = new Cards(0);
cardSet[3].Value = 0;
cardSet[3].SetCards();
cardSet[4] = new Cards(0);
cardSet[4].Value = 0;
cardSet[4].SetCards();
// PictureBox array to allow changes to different PictureBoxes
PictureBox[] picArray = new PictureBox[5];
// Card thing
for (int x = 0; x > picArray.Length; x++)
{
picArray[x] = new PictureBox();
}
picArray[0] = Card1;
picArray[1] = Card2;
picArray[2] = Card3;
picArray[3] = Card4;
picArray[4] = Card5;
// Will automatically show you your first card, while the rest will stay hidden until you press the Hit button.
picArray[0].Image = SetImage(cardSet[0].GetValue());
points += cardSet[0].CardValue();
pointCounter.Text = points.ToString();
i = 1;
//Sets over boolean to false - to not automatically end the game
over = false;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void pictureBox7_Click(object sender, EventArgs e)
{
}
private void Card2_Click(object sender, EventArgs e)
{
}
private void pictureBox3_Click(object sender, EventArgs e)
{
}
private void buttonPlay_Click(object sender, EventArgs e)
{
}
private void buttonPlay_Click_1(object sender, EventArgs e)
{
}
}
}
And my Card Class if you need it as well
using System;
public class Cards
{
Random rand = new Random();
public int Value = 0;
public Cards(int value)
{
this.Value = value;
}
public int GetValue()
{
return Value;
}
public int CardValue()
{
if (Value == 0 || Value == 1 || Value == 2 || Value == 3)
return 2;
else if (Value == 4 || Value == 5 || Value == 6 || Value == 7)
return 3;
else if (Value == 8 || Value == 9 || Value == 10 || Value == 11)
return 4;
else if (Value == 12 || Value == 13 || Value == 14 || Value == 15)
return 5;
else if (Value == 16 || Value == 17 || Value == 18 || Value == 19)
return 6;
else if (Value == 20 || Value == 21 || Value == 22 || Value == 23)
return 7;
else if (Value == 24 || Value == 25 || Value == 26 || Value == 27)
return 8;
else if (Value == 28 || Value == 29 || Value == 30 || Value == 31)
return 9;
else if (Value == 32 || Value == 33 || Value == 34 || Value == 35)
return 10;
else if (Value == 36 || Value == 37 || Value == 38 || Value == 39)
return 1;
else if (Value == 40 || Value == 41 || Value == 42 || Value == 43 || Value == 44 || Value == 45 || Value == 46 || Value == 47)
return 10;
else
return 2;
}
public void SetCards()
{
//Adds a random value to card
int ranumber = rand.Next(0, 47);
Value = ranumber;
}
}
I'm still sort of new at programming, and this is my first real project. Any help on how I can make my code better and or fix the problem would mean a million to me.
Related
I want to use .NET MAUI compass data inside if statement, but I can't use it just by it's self. I need to convert it to int or double.
Code:
namespace MauiApp1;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void ToggleCompass()
{
if (Compass.Default.IsSupported)
{
if (!Compass.Default.IsMonitoring)
{
// Turn on compass
Compass.Default.ReadingChanged += Compass_ReadingChanged;
Compass.Default.Start(SensorSpeed.UI);
}
else
{
// Turn off compass
Compass.Default.Stop();
Compass.Default.ReadingChanged -= Compass_ReadingChanged;
}
}
}
private void Compass_ReadingChanged(object sender, CompassChangedEventArgs e)
{
// Update UI Label with compass state
this.north.Text = $"Compass: {Convert.ToInt32(e.Reading)}";
//if (value >= 355 || value <= 5) this.arrow.RotateTo(0);
//if (value >= 5 || value <= 85) this.arrow.RotateTo(45);
//if (value >= 85 || value <= 95) this.arrow.RotateTo(90);
//if (value >= 95 || value <= 175) this.arrow.RotateTo(135);
//if (value >= 175 || value <= 185) this.arrow.RotateTo(180);
//if (value >= 185 || value <= 265) this.arrow.RotateTo(225);
//if (value >= 265 || value <= 275) this.arrow.RotateTo(270);
//if (value >= 275 || value <= 355) this.arrow.RotateTo(315);
}
private void Button_Clicked(object sender, EventArgs e)
{
ToggleCompass();
}
}
I tried ".Convert", ".Int32.Parse", "Double.Parse" - nothing works! Is there any others ways to parse it?
I need it to be Int to use in if statement.
var heading = e.Reading.HeadingMagneticNorth;
int value = (int)heading;
I am developing a winform application using c# I have successfully implemented a way to restrict textbox to two decimal places. How can I do it to one decimal place. ?
My code for two decimal places.\
private void txtHraRep_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsNumber(e.KeyChar) || e.KeyChar == '.')
{
if (Regex.IsMatch(
txtHraRep.Text,
"^\\d*\\.\\d{2}$")) e.Handled = true;
}
else e.Handled = e.KeyChar != (char)Keys.Back;
}
Changing to "^\d*\.\d{1}$")) e.Handled = true;
output
You can do this without regex by just checking where the decimal separator is in your text and then making sure that is 2 less than the length of the string (1 decimal place and 1 less for array length)
var decSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
var idx = txtBasic.Text.IndexOf(decSeparator);
if(idx + 2 >= txtBasic.Text.Length)
...
Instead of using a TextBox control for the input, look at using a MaskedTextbox control for your input. This will alleviate any self validation of the input and can show the users what input can be expected of them with messages as to why their input was not correct.
More information about the MaskedTextbox control:
MaskedTextbox
MaskedTextbox.Mask property
MSDN Walkthrough: Working with the MaskedTextBox Control
I just tried
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
{
if (char.IsNumber(e.KeyChar) || e.KeyChar == '.')
{
if (Regex.IsMatch(
textBox1.Text,
"^\\d*\\.\\d{1}$")) e.Handled = true;
}
else e.Handled = e.KeyChar != (char)Keys.Back;
}
}
and it worked as it should. It restricted the input to one digit after the decimal point.
But you could enter more than one decimal point and then also more digits.
So you can either try
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsNumber(e.KeyChar) || ((e.KeyChar == '.') && (textBox1.Text.IndexOf('.')== -1 )))
{
if (Regex.IsMatch(
textBox1.Text,
"^\\d*\\.\\d{1}$")) e.Handled = true;
}
else e.Handled = e.KeyChar != (char)Keys.Back;
}
or something like
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsNumber(e.KeyChar) || ((e.KeyChar == '.') && (textBox1.Text.IndexOf('.')== -1 )))
{
if (textBox1.Text.IndexOf('.') > 0)
{
if (textBox1.Text.IndexOf('.') < textBox1.Text.Length - 1)
e.Handled = true;
}
}
else e.Handled = e.KeyChar != (char)Keys.Back;
}
Create A new TextBox that inherit TextBox like
[DefaultBindingProperty("Text")]
[DefaultProperty("Text")]
[DefaultEvent("ValueChanged")]
public class SpecializedTextBox : TextBox
{
private bool _allowNegativeSign = false;
public bool AllowNegativeSign
{
get { return _allowNegativeSign; }
set { _allowNegativeSign = value; }
}
public decimal? DecimalValue
{
get
{
decimal k;
if (decimal.TryParse(this.Text, out k))
return k;
else
return null;
}
set
{
if (value.HasValue)
this.Text = value.Value.ToString();
else
this.Text = "";
}
}
private void This_TextChanged(object sender, EventArgs e)
{
string s = base.Text;
int cursorpos = base.SelectionStart;
bool separatorfound = false;
for (int i = 0; i < s.Length; )
{
if (char.IsNumber(s[i]))
i++;
else if (AllowNegativeSign && i < System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NegativeSign.Length && s.StartsWith(System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NegativeSign))
i++;
else if (!separatorfound && s[i].ToString() == System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)
{
separatorfound = true;
i++;
}
else
{
s = s.Remove(i, 1);
if (i < cursorpos)
cursorpos--;
}
}
if (base.Text != s)
{
base.Text = s;
base.SelectionStart = cursorpos;
base.SelectionLength = 0;
}
if (ValueChanged != null)
ValueChanged(this, EventArgs.Empty);
}
public event EventHandler ValueChanged;
private void InitializeComponent()
{
this.SuspendLayout();
//
// SpecializedTextBox
//
this.TextChanged += new System.EventHandler(this.This_TextChanged);
this.ResumeLayout(false);
}
public SpecializedTextBox()
: base()
{
InitializeComponent();
}
}
now use this text box and use DecimalValue to set or get your value
try:
List<string> doubleList = new List<string>(new string[]
{
"12345",
"1234.5",
"123.45",
"12.345",
"1.2345",
"1.2",
"1.23",
"1.234",
"1.23.45",
"12.3",
"123.4",
}) { };
private void button1_Click(object sender, EventArgs e)
{
foreach (var x in doubleList)
{
int countNumber = Regex.Matches(x, #"[0-9]").Count;
int countOfDot = Regex.Matches(x, #"\.").Count;
if (countOfDot == 1 && countNumber != 0) //contains "." and any digit
{
Console.WriteLine(x);
}
else if (countOfDot == 0 && countNumber != 0) //not contains "." and any digit
{
Console.WriteLine(x);
}
else
{
//do nothing . . .
}
}
}
output:
all except for **1.23.45** (2dots)
I am using the following code in order to implement undo/redo into my application:
public struct UndoSection
{
public string Undo;
public int Index;
}
--
public UndoSection(int index, string undo)
{
Index = index;
Undo = undo;
}
--
Stack<UndoSection> UndoStack = new Stack<UndoSection>();
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.None && e.KeyCode == Keys.Delete)
UndoStack.Push(new UndoSection(richTextBoxPrintCtrl1.SelectionStart, richTextBoxPrintCtrl1.SelectedText));
else if (e.Control && e.KeyCode == Keys.Z)
{
e.Handled = true;
undo_Click(richTextBoxPrintCtrl1, new EventArgs());
}
}
public string[] RTBRedoUndo;
public int StackCount = 0;
public int OldLength = 0;
public int ChangeToSave = 5;
public bool IsRedoUndo = false;
--
public void RTBTextChanged()
{
if (richTextBoxPrintCtrl1.TextLength - OldLength >= ChangeToSave | richTextBoxPrintCtrl1.TextLength - OldLength <= ChangeToSave)
{
StackCount += 1;
RTBRedoUndo[StackCount] = richTextBoxPrintCtrl1.Text;
}
}
public void UndoCode()
{
IsRedoUndo = true;
if (StackCount > 0 && RTBRedoUndo[StackCount - 1] != null)
{
StackCount = StackCount - 1;
richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount];
}
}
public void RedoCode()
{
if (IsRedoUndo == false && richTextBoxPrintCtrl1.Text.Substring(richTextBoxPrintCtrl1.Text.Length - 1, 1) == " ")
IsRedoUndo = true;
if (StackCount > 0 && RTBRedoUndo[StackCount + 1] != null)
{
StackCount = StackCount + 1;
richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount];
}
However, if I type some text in my rich text box such as: "Hello. This is my application.", It will only let me redo up to "my". It won't let me redo "application.". And if I undo all text, I then cannot redo and restore the text.
What is causing this to behave in this manner? I really need to get this undo/redo code working correct. Could somebody help point me in the right direction, please?
--EDIT--
Redo code:
public void RedoCode()
{
if (IsRedoUndo == false && richTextBoxPrintCtrl1.Text.Substring(richTextBoxPrintCtrl1.Text.Length - 1, 1) == " ")
IsRedoUndo = true;
if (StackCount > 0 && RTBRedoUndo[StackCount + 1] != null)
{
StackCount = StackCount + 1;
richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount];
}
}
It is called by a button click, using RedoCode();
Can you show how to call the Redo function?
as from what I can see you've missed out the below code
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.None && e.KeyCode == Keys.Delete)
UndoStack.Push(new UndoSection(richTextBoxPrintCtrl1.SelectionStart, richTextBoxPrintCtrl1.SelectedText));
else if (e.Control && e.KeyCode == Keys.Z)
{
e.Handled = true;
undo_Click(richTextBoxPrintCtrl1, new EventArgs());
}
else if (e.Control && e.KeyCode == Keys.Y)
{
e.Handled = true;
redo_Click(richTextBoxPrintCtrl1, new EventArgs());
}
I got 2 datagrid views, First datagrid 1st col or Index 0 & the Second datagrid 1st col or Index 0.
How can i loop through a specific col in the datagridviews and look for the string values,if it matches with the list then go to a function.
My approach is not working. How can i do this?
private void b_calculate_Click(object sender, EventArgs e)
{
List<string> value = new List<String>() { "AE0", "AT1", "AT2", "AT3"};
value = new List<string>(datagridview1.Columns[0].Index);
List<string> value2 = new List<String>() { "BE0", "BT1", "BT2", "BT3"};
value2 = new List<string>(datagridview2.Columns[0].Index);
//First Combination
if((value.ToString() == "AT1" || value.ToString() == "AE0" ||
value.ToString() == "AT2")
&&
(value2.ToString() == "BT1" || value2.ToString() == "BE0"))
{
gottoFunction1();
}
//Second Combination
if((value.ToString() == "AT1" || value.ToString() == "AT2" )
&&
(value2.ToString() == "BT1" || value2.ToString() == "BT2"))
{
gottoFunction2();
}
}
Here's a routine that iterates through all available rows in both DataGridViews and does the processing shown in your method:
private void b_calculate_Click(object sender, EventArgs e)
{
for (var i = 0; i < dataGridView1.RowCount; i++)
{
if (dataGridView2.RowCount <= i)
break;
var cellFromDG1 = dataGridView1.Rows[i].Cells[0];
var cellFromDG2 = dataGridView1.Rows[i].Cells[0];
if (cellFromDG1.Value == null || cellFromDG2.Value == null)
{
// this could be the empty row that allows you to
// enter a new record
continue;
}
var value = cellFromDG1.Value.ToString();
var value2 = cellFromDG2.Value.ToString();
if ((value == "AT1" || value == "AE0" || value == "AT2") &&
(value2 == "BT1" || value2 == "BE0"))
{
gottoFunction1();
}
if ((value == "AT1" || value == "AT2") &&
(value2 == "BT1" || value2 == "BT2"))
{
gottoFunction2();
}
}
}
My program opens a series of forms all over the screen, am I able to code in an escape method, so on typing of the word "test" the program will close?
I was looking at the msdn keypress and how they use a switch, would I use something similar to check for the pressed key and if the correct key is pressed, a counter will increment of the correct key presses until, for "test", 4 will be reached, and if the pressed key is incorrect reset the counter and start over until the right order of keys are entered.
I hope that makes sense :P
public partial class TrollFrm : Form
{
int number = 1; //change to 2 and have the first instance of troll count = number - 1
System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
public TrollFrm()
{
InitializeComponent();
this.Text = "Trololol - Troll Count: " + number;
startTimer();
}
private void TrollFrm_Load(object sender, EventArgs e)
{
//this.Enabled = false;
}
private void TrollFrm_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
public void startTimer()
{
myTimer.Tick += new EventHandler(createForm);
//myTimer.Interval = 500;
myTimer.Start();
}
public void createForm(Object myObject, EventArgs myEventArgs)
{
Form frm = new TrollChildFrm();
Random randomX = new Random();
Random randomY = new Random();
frm.Text = "Trololol - Troll Count: " + number;
int xValue;
int yValue;
number++;
if (number % 2 == 0) //number is even.
{
xValue = (Convert.ToInt32(randomX.Next(1, 1920))) + 200;
yValue = (Convert.ToInt32(randomY.Next(1, 1080))) - 200;
}
else //number is not even.
{
xValue = (Convert.ToInt32(randomX.Next(1, 1920))) - 200;
yValue = (Convert.ToInt32(randomY.Next(1, 1080))) + 200;
}
frm.Show();
frm.Location = new Point(xValue, yValue);
if (number == 20)
{
myTimer.Stop();
}
}
It is an implementation you could use for scenario you described (not tested though):
int exitKeysCount = 0;
private void TrollFrm_KeyDown(object sender, KeyEventArgs e)
{
if (exitKeysCount == 0 && e.KeyCode == Keys.T)
exitKeysCount = 1;
else if (exitKeysCount == 1 && e.KeyCode == Keys.E)
exitKeysCount = 2;
else if (exitKeysCount == 2 && e.KeyCode == Keys.S)
exitKeysCount = 3;
else if (exitKeysCount == 3 && e.KeyCode == Keys.T)
this.Close();
else exitKeysCount = 0;
}
I assumed TrollFrm is your parent form, if they are all invoked somewhere else replace this.Close() with some function in main program function, also TrollFrm needs focus during key presses.
try this parent on your parent form.
int trollCount = 0;
private void TrollFrm_KeyDown(object sender, KeyEventHandler e)
{
if (trollCount == 0 && e.KeyCode == Keys.T)
{
trollCount = 1;
frm.Text = "Trololol - Troll Count:" + trollCount
}
else if (trollCount == 1 && e.KeyCode== Keys.E)
{
trollCount = 2;
frm.Text = "Trololol - Troll Count:" + trollCount
}
else if (trollCount == 2 && e.KeyCode== Keys.S)
{
trollCount = 3;
frm.Text = "Trololol - Troll Count:" + trollCount
}
else if (trollCount == 4 && e.KeyCode== Keys.T)
{
trollCount = 4;
this.Close();
}
else
trollCount = 0;
tell me if you need anything else.