Creating a game of Checkers - c#

I am creating this in regards to an issue I just ran in with. I am trying to create a primitive game of checkers using only buttons and so far I am just testing how to get the program to recognize selecting a button and moving the piece.
My Code:
private void Checkers_Load(object sender, EventArgs e)
{
}
string selectedChecker = "";
string currentButton = "";
int blankSpace = 0;
int[] Board = new int[64];
private void gameBoard()
{
foreach(var control in Controls)
{
var button = control as Button;
if(button != null)
{
if(button.Name == currentButton)
{
button.Image = System.Drawing.Image.FromFile("Red Checker.png");
}
else
{
MessageBox.Show("Dead.");
}
}
else
{
MessageBox.Show("Dead.");
}
}
}
private void attemptMove()
{
string substringChecker = null;
substringChecker = selectedChecker.Substring(0,2);
int selectedCheckerNumber = Convert.ToInt32(substringChecker);
string substringButton = null;
substringButton = currentButton.Substring(0,2);
int currentButtonNumber = Convert.ToInt32(substringButton);
if((selectedCheckerNumber + 3 == currentButtonNumber) || (selectedCheckerNumber + 4 == currentButtonNumber))
{
Board[currentButtonNumber] = Board[selectedCheckerNumber];
Board[selectedCheckerNumber] = blankSpace;
gameBoard();
}
}
private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
{
int w = pictureBox1.Size.Width;
int h = pictureBox1.Size.Height;
int count = 8;
Bitmap b = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
w /= count;
h /= count;
Graphics g = Graphics.FromImage(b);
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
Color c = (i + j) % 2 == 0 ? Color.Red : Color.Black;
Brush br = new SolidBrush(c);
g.FillRectangle(br, i * w, j * h, w, h);
br.Dispose();
}
}
g.Dispose();
pictureBox1.Image = b;
pictureBox1.Refresh();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
//Close form
this.Close();
}
private void howToPlayToolStripMenuItem_Click(object sender, EventArgs e)
{
//MessageBox.Show("How to play a game of Checkers: Step 1 - Don't play.");
}
private void informationToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void checkerSpace18_Click(object sender, EventArgs e)
{
}
private void checkerSpace17_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
string buttonClicked = btn.Name;
if (selectedChecker == "")
{
selectedChecker = buttonClicked;
}
else
{
currentButton = buttonClicked;
attemptMove();
}
}
}
My question goes with regards to my attemptMove() method. I run into a runtime error:
"An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll. Additional information: Input string was not in a correct format."
It seems to occur whenever I go to move the piece to the other cell adjacent to the piece after moving it once. It may be because my program is not updating the pictures of the buttons when the buttons switch, but I wanted to see if any guidance could be shed upon this issue.

You are setting the "selectedChecker" to the clicked button .Name property. Then you are using substring(0,2) to get the first 2 characters and try to convert that to an integer.
Since a Name property can't start with numbers, you are attempting to convert some random text to an integer property.
A better approach would be to use the Tag property to hold information about the number, this can be any value. You can then use the int.Parse to parse the Tag value of the button.

What is your naming convention for the buttons? Seems like you're trying to get a number from the name, but the conversion is failing.
If the button names are button00 through button63, then you should be able to get the number using Substring, starting at Name.Length - 2. Note that you must have all button names use a two digit number at the end (00, 01, 02, etc).
For example:
// Get the last two characters of the button name
string substringChecker = selectedChecker.Substring(selectedChecker.Length - 2);
// Convert the characters to an integer
int selectedCheckerNumber = Convert.ToInt32(substringChecker);

Related

Why wont my program draw the lines between 10 mouseclicks? [duplicate]

This question already has an answer here:
Why does my program draw all the lines from the top left corner? How to change this?
(1 answer)
Closed last month.
I am trying to make a program that will draw lines between 10 coordinates, determined by mouseclicks.
i can not get it to work.
code:
EDIT:
i figured out i have to define the coordinates making x and y values.
only it is still unclear how to do this.
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Point[] punten = new Point[2];
int index = 0;
int kliks = 0;
}
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
Point[] punten = new Point[2];
int index = 0;
int kliks = 0;
kliks = kliks + 1;
index = kliks;
punten[index] = e.Location;
if (index < 2)
{
punten[index] = e.Location;
}
else
{
Pen pen = new Pen(Color.Blue);
Graphics papier = pictureBox1.CreateGraphics();
papier.DrawLines(pen, punten);
}
}
I have re read the textbook 10 times.. its unclear where to create the variables intially, but if i dont create them under pictureBox1 mouse click, i also cant use them.
Any help is appreciated.
greetings, Stefan.
i got it to work!
i need to keep telling my damn self: its all in the textbook...
with the explanations given by you guys (declaring variables at class level)
the instructions in the textbook work..
code:
public partial class Form1 : Form
{
Point[] punten = new Point[10];
private int kliks = 0;
private int lijst = 0;
public Form1()
{
InitializeComponent();
}
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
kliks = kliks + 1;
lijst = kliks;
punten[lijst] = e.Location;
if (lijst < 5)
{
punten[lijst] = e.Location;
}
else
{
Pen pen = new Pen(Color.Blue);
Graphics papier = pictureBox1.CreateGraphics();
papier.DrawLines(pen, punten);
}
}
}
}
The Scope a variables is defined determines its accessibility within the process. You need to declare the punten array and the kliks int variables at the class level so they can be maintained across the button clicks.
public Form1()
{
InitializeComponent();
}
// create variables at class scope so they are
// accessible by all methods in this class and state is maintained
// across button clicks
private Point[] punten;
private int kliks;
private void Form1_Load(object sender, EventArgs e)
{
// initialize class level variables at form load
punten = new Point[10];
kliks = 0;
}
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
int index = kliks;
if(index == 9) // arrays are zero based so our 10 items are at indexes 0 through 9
{
// append last mouse point clicked to list of points
punten[index] = new Point(e.Location.X, e.Location.Y);
// draw lines between all points
Pen pen = new Pen(Color.Blue);
Graphics papier = pictureBox1.CreateGraphics();
papier.DrawLines(pen, punten);
punten = new Point[10];
kliks = 0;
}
else
{
// append mouse point clicked to list of points
punten[index] = new Point(e.Location.X, e.Location.Y);
kliks = kliks + 1;
}
}

Getting a variable from a Click event method and using it in another class

Im trying to make a chess board using classes from the first time. Im struggling with getting a variable from the first click event method and use it in the DrawRow method. I know its not finished but im really hung up on this bit and having a hard time continuing
private void ToolStripMenuItemDrawBoard_Click(object sender, EventArgs e)
{
//Prevents errors using try catch method
Graphics paper = pictureBoxDisplay.CreateGraphics();
try
{
int boardSize = int.Parse(ToolStripTextBoxBoardSize.Text);
if (boardSize > MIN_BOARD_SIZE || boardSize < MAX_BOARD_SIZE)
{
DrawRow();
}
else
{
MessageBox.Show("Between 2-10");
//Clears all textboxes
foreach (Control c in Controls)
{
if (c is TextBox)
{
c.Text = "";
}
}
}
}
}
public void DrawSquare()
{
Graphics paper = pictureBoxDisplay.CreateGraphics();
paper.DrawRectangle(penBlack, positionX, positionY, WIDTH, HEIGHT);
}
public void DrawRow(ToolStripMenuItemDrawBoard_Click(boardSize))
{
int columnNum = 0;
int counter = 0;
Graphics paper = pictureBoxDisplay.CreateGraphics();
while (boardSize < columnNum)
{
DrawSquare();
if ((counter % 2) == 0)
paper.FillRectangle(brDarkBrown, positionX, positionY, WIDTH, HEIGHT);
else if ((counter % 2) != 0)
paper.FillRectangle(brLightBrown, positionX, positionY, WIDTH, HEIGHT);
positionX = positionX + Width;
columnNum += 1;
}
}
Your question looks clear to me. I anyway can't believe it is what you're talking about.
private void ToolStripMenuItemDrawBoard_Click(object sender, EventArgs e)
{
//Prevents errors using try catch method
Graphics paper = pictureBoxDisplay.CreateGraphics();
try
{
int boardSize = int.Parse(ToolStripTextBoxBoardSize.Text);
if (boardSize > MIN_BOARD_SIZE || boardSize < MAX_BOARD_SIZE)
{
// Pass your board size to DrawRow()
DrawRow(boardSize);
}
else
{
// ..
}
}
}
// Declare your parameter (int boardsize)
public void DrawRow(int boardSize)
{
// boardSize accessable here
}
There you get it. As this got marked I advice you to read through the basics of C#-coding (or general coding).

code improvement - naming textboxes generated form numericupdown & button click

I have a problem with a code that is regarding adding controls with numericUpDown ( for example- if numericUpDown value equals to 3, user recievs 3 textboxes).
Thanks to stackoverflow users I improved my code.
Before improvement it looked like this:
private void button1_Click(object sender, EventArgs e)
{
if (numericUpDown1.Value == 1)
{
txtbx1.AutoSize = true;
Controls.Add(txtbx1);
txtbx1.Location = new Point(70, 100);
}
else if (numericUpDown1.Value == 2)
{
txtbx1.AutoSize = true;
Controls.Add(txtbx1);
txtbx1.Location = new Point(70, 100);
txtbx2.AutoSize = true;
Controls.Add(txtbx2);
txtbx2.Location = new Point(70, 130);
}
else if (numericUpDown1.Value == 3)
{
txtbx1.AutoSize = true;
Controls.Add(txtbx1);
txtbx1.Location = new Point(70, 100);
txtbx2.AutoSize = true;
Controls.Add(txtbx2);
txtbx2.Location = new Point(70, 130);
txtx3.AutoSize = true;
Controls.Add(txtbx3);
txtbx3.Location = new Point(70, 160);
}
}
After improvement:
private void button1_Click(object sender, EventArgs e)
{
int y = 100;
int x = 70;
for (int i = 0; i < numericUpDown1.Value; i++)
{
var txtbx = new TextBox();
txtbx.AutoSize = true;
Controls.Add(txtbx);
txtbx.Location = new Point(x, y);
// Increase the y-position for next textbox.
y += 30;
}
}
Now the problem is that I don't know how assign names to genarated textboxes.
(before the improvement I could name them - txtbx1, txtbx2, txtbx3...)
Code to improve:
private void button3_Click(object sender, EventArgs e)
{
try
{
double a, b, c, sum;
a = double.Parse(txtbx1.Text);
b = double.Parse(txtbx2.Text);
c = double.Parse(txtbx3.Text);
sum = a + b + c;
label1.Text = sum.ToString();
}
catch (Exception ex)
{
MessageBox.Show("error");
}
Please note that I'm a beginner, learning c# by watching youtube tutorials ;) I do realize that my question might be silly but I couldn't handle this problem by myself.
In advance thank you for your time and help.
If you need to access them afterwards, you have some options.
I'll guess that your objective is to set label1's text to the sum of the values contained in the specified textbox(es).
On the ValueChanged event of your NumericUpDown, check the delta and consequentely add or remove the required number of TextBoxes to your Form's Controls. To obtain the delta, you'll need to store the previous value of the NumericUpDown, and then subtract it from the current value. (If it was 5, and now it's 4, 4 - 5 = -1. A textbox has been removed).
private int _oldNUDvalue = 0; //or assign it to the default value
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
int delta = (int)numericUpDown1.Value - _oldNUDvalue;
if (delta < 0)
{
for (int i = -delta; i > 0; i--)
{
var tbox = Controls.Find("ntextBox" + (_oldNUDvalue - i), false)[0];
Controls.Remove(tbox);
}
}
else if (delta > 0)
{
for (int i = _oldNUDvalue; i < _oldNUDvalue + delta; i++)
{
var tbox = new TextBox();
tbox.Location = new Point(15, 55 + (30 * i));
tbox.Name = "ntextBox" + i;
Controls.Add(tbox);
}
}
_oldNUDvalue = (int)numericUpDown1.Value;
}
If, however, you only have a maximum number of 3, you could take a slightly different approach. My solution works with n-textboxes.
Finally, to get the TextBoxes' values from code, you have three approaches:
Loop through your Form's controls, check for TextBoxes with their name starting with "ntextBox", and add their values together
Use LINQ to do the same
Access them singularly via "Controls.Find("ntextBoxX", false)", where X is the number of course.
I'll show the LINQ approach as I like it better.
int sum = Controls.Cast<Control>().Sum(c => c.Name.StartsWith("ntextBox") ? int.Parse(c.Text) : 0);
I haven't tested the code, but it should work. Tell me if there are any problems.
EDIT: Tested and it works. For the sake of completeness, I'll add some event logic to the TextBox-adding loop, to make sure that their input is actually numeric.
tbox.TextChanged += HandleNTextBoxInput; // add this line
And elsewhere, add this method:
void HandleNTextBoxInput(object sender, EventArgs e)
{
string text = ((TextBox)sender).Text;
if (!Regex.IsMatch(text, "^[1-9][0-9]*$")) //Text is NOT numeric. Remove [1-9] if you want to keep leading zeros.
{
//Set the Text to 0, for example. Or show a message box. Or whatever.
((TextBox)sender).Text = "0";
}
}
As I mentioned in a comment- this code seems to be maybe too advanced for me.
I have no problem with adding the controls, bu still there is a problem how to get the sum from a button click to a textbox.
I probably made some simple mistakes, or something is missing but I really don't know how to fix this problem.
My code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace testprogram
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) // I'm guessing something is missing over here
{
int sum = Controls.Cast<Control>().Sum(c => c.Name.StartsWith("ntextBox") ? int.Parse(c.Text) : 0);
}
void HandleNTextBoxInput(object sender, EventArgs e)
{
string text = ((TextBox)sender).Text;
if (!Regex.IsMatch(text, "^[1-9][0-9]*$")) //Text is NOT numeric. Remove [1-9] if you want to keep leading zeros.
{
//Set the Text to 0, for example. Or show a message box. Or whatever.
((TextBox)sender).Text = "0";
}
}
private int _oldNUDvalue = 0; //or assign it to the default value
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
{
int delta = (int)numericUpDown1.Value - _oldNUDvalue;
if (delta < 0)
{
for (int i = -delta; i > 0; i--)
{
var tbox = Controls.Find("ntextBox" + (_oldNUDvalue - i), false)[0];
Controls.Remove(tbox);
}
}
else if (delta > 0)
{
for (int i = _oldNUDvalue; i < _oldNUDvalue + delta; i++)
{
var tbox = new TextBox();
tbox.Location = new Point(15, 55 + (30 * i));
tbox.Name = "ntextBox" + i;
tbox.TextChanged += HandleNTextBoxInput;
Controls.Add(tbox);
}
}
_oldNUDvalue = (int)numericUpDown1.Value;
}
}
}
}

2D Array Buttons Display X and Y

I have a small program that hold 4 button in a 2D Array what I want to do is display its 'X' and 'Y' coordinates of the Array in a message box (when clicked)
I have tried a number of ways some don't work and some work but I cant get it to show the 'X' and 'Y' values
The image below shows what I have so far:
And This is the code i have come up with:
namespace _2DArray
{
public partial class Form1 : Form
{
private Button[,] b;
public Form1()
{
InitializeComponent();
b = new Button[2, 2];
b = new Button[,] { {button1,button2 },
{button3, button4}};
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (Button bt in b)
{
bt.Click += new System.EventHandler(this.ClickedButton);
}
}
private void ClickedButton(object sender, EventArgs e)
{
Button s = (Button)sender;
MessageBox.Show("you have clicked button:" + s);
}
}
}
Here is the answer to your question if i read it right. You are trying to get the X and Y coordinates of the button right?
Here is the code for a button click:
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show(button1.Location.ToString());
}
try assigning some sort of pointer like give name of the button to keep track of it coordinates
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
b[i, j].Click += new System.EventHandler(this.ClickedButton);
b[i, j].Name =i+" "+j;
}
}
}
private void ClickedButton(object sender, EventArgs e)
{
Button s = (Button)sender;
MessageBox.Show("you have clicked button:" + s.Name);
}
Use this code
private void Form1_Load(object sender, EventArgs e) {
for (int x = 0; x < 2; x++) {
for (int y = 0; x < 2; y++) {
b[x, y].Tag = new Point(x, y);
b[x, y].Click += new System.EventHandler(this.ClickedButton);
}
}
}
private void ClickedButton(object sender, EventArgs e) {
Button s = (Button) sender;
MessageBox.Show("you have clicked button:" + s.Tag.ToString());
}
then clicking on button1 will show the message "you have clicked button:{X = 0, Y = 0}" etc
Tag is a property that each control has, it's description is "User-defined data associated with the object" so you can set it to whatever object you like.
I know this is probably a bit late for the op but hopefully it will help someone else.

displaying line number in rich text box c#

I have a Multiline richtextbox control into which i want to integrate the feature of adding a line number. i have considered many approaches
Add a label and updating the line numbers as the line count changes
Add a picturebox along with to draw string on it.
Add another textbox along with and show line numbers on it
Add listbox along and display line numbers in it.
I got two doubts.
The richtextbox which i'm using is a custom made control and derieves from RichTextBox class. How can i add multiple controls to it.
What is the best approach to show line numbers for the multiline text in c#
My own example. All is fine, but wordwrap must be disabled :(
int maxLC = 1; //maxLineCount - should be public
private void rTB_KeyUp(object sender, KeyEventArgs e)
{
int linecount = rTB.GetLineFromCharIndex( rTB.TextLength ) + 1;
if (linecount != maxLC)
{
tB_line.Clear();
for (int i = 1; i < linecount+1; i++)
{
tB_line.AppendText(Convert.ToString(i) + "\n");
}
maxLC = linecount;
}
}
where rTB is my richtextbox and tB is textBox next to rTB
J.T. jr
this code helped me thank you, needed to convert visual basic but could:
Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp
Dim maxlc As Integer = 1
Dim linecount As Integer = TextBox1.GetLineFromCharIndex(TextBox1.Height) + 1
If linecount <> maxlc Then
TextBox2.Clear()
For i = 0 To linecount - 1 Step 1
TextBox2.AppendText(Convert.ToString(i) + vbNewLine)
Next i
maxlc = linecount
End If
End Sub
public int getWidth()
{
int w = 25;
// get total lines of richTextBox1
int line = richTextBox1.Lines.Length;
if (line <= 99)
{
w = 20 + (int)richTextBox1.Font.Size;
}
else if (line <= 999)
{
w = 30 + (int)richTextBox1.Font.Size;
}
else
{
w = 50 + (int)richTextBox1.Font.Size;
}
return w;
}
public void AddLineNumbers()
{
// create & set Point pt to (0,0)
Point pt = new Point(0, 0);
// get First Index & First Line from richTextBox1
int First_Index = richTextBox1.GetCharIndexFromPosition(pt);
int First_Line = richTextBox1.GetLineFromCharIndex(First_Index);
// set X & Y coordinates of Point pt to ClientRectangle Width & Height respectively
pt.X = ClientRectangle.Width;
pt.Y = ClientRectangle.Height;
// get Last Index & Last Line from richTextBox1
int Last_Index = richTextBox1.GetCharIndexFromPosition(pt);
int Last_Line = richTextBox1.GetLineFromCharIndex(Last_Index);
// set Center alignment to LineNumberTextBox
LineNumberTextBox.SelectionAlignment = HorizontalAlignment.Center;
// set LineNumberTextBox text to null & width to getWidth() function value
LineNumberTextBox.Text = "";
LineNumberTextBox.Width = getWidth();
// now add each line number to LineNumberTextBox upto last line
for (int i = First_Line; i <= Last_Line + 2; i++)
{
LineNumberTextBox.Text += i + 1 + "\n";
}
}
private void Form1_Load(object sender, EventArgs e)
{
LineNumberTextBox.Font = richTextBox1.Font;
richTextBox1.Select();
AddLineNumbers();
}
private void richTextBox1_SelectionChanged(object sender, EventArgs e)
{
Point pt = richTextBox1.GetPositionFromCharIndex(richTextBox1.SelectionStart);
if (pt.X == 1)
{
AddLineNumbers();
}
}
private void richTextBox1_VScroll(object sender, EventArgs e)
{
LineNumberTextBox.Text = "";
AddLineNumbers();
LineNumberTextBox.Invalidate();
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
if (richTextBox1.Text == "")
{
AddLineNumbers();
}
}
private void richTextBox1_FontChanged(object sender, EventArgs e)
{
LineNumberTextBox.Font = richTextBox1.Font;
richTextBox1.Select();
AddLineNumbers();
}
private void LineNumberTextBox_MouseDown(object sender, MouseEventArgs e)
{
richTextBox1.Select();
LineNumberTextBox.DeselectAll();
}
private void Form1_Resize(object sender, EventArgs e)
{
AddLineNumbers();
}
WORKS 100%!!! But you need to add richTextBox2 for line numbers, if you want change it to other
form like listbox, anyway it served me well.
private void richTextBox1_keyDown(object sender, KeyEventArgs e)
{
for (int i = 0; i <= richTextBox1.Lines.Count(); i++)
{
if (!(e.KeyCode == Keys.Back))
{
if (!richTextBox2.Text.Contains(i.ToString()))
{
richTextBox2.Text += i.ToString() + "\n";
}
}
else
{
richTextBox2.Clear();
}
}
}

Categories

Resources