Dynamically programming a grid consisting of 64 buttons (8x8) - c#

I'm trying to create a chess game purely for my learning C# and chess. Just to start off with, I would like to create an 8x8 grid of buttons through code rather than the designer. This would save me hard coding each button individually.
A button array would seem a good way to start but I have no idea how to implement this.

You can create a "square" class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
class Square:PictureBox
{
private bool color;
private char piece;
}
and define an array to make place for 8x8 squares.
public partial class Form1 : Form
{
Square[,] square = new Square[8, 8];
public Form1()
{
InitializeComponent();
int i, j;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
this.square[i, j] = new Square();//Creating the chess object//
this.square[i, j].BackColor = System.Drawing.SystemColors.ActiveCaption;
this.square[i, j].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.square[i, j].Location = new System.Drawing.Point(57 + i * 40, 109 + j * 40);
this.square[i, j].Name = "chessBox1";
this.square[i, j].Size = new System.Drawing.Size(40, 40);
this.square[i, j].TabIndex = 2;
this.square[i, j].TabStop = false;
this.Controls.Add(this.square[i, j]);
}
}
}
}

int ButtonWidth = 40;
int ButtonHeight = 40;
int Distance = 20;
int start_x = 10;
int start_y = 10;
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
Button tmpButton = new Button();
tmpButton.Top = start_x + (x * ButtonHeight + Distance);
tmpButton.Left = start_y + (y * ButtonWidth + Distance);
tmpButton.Width = ButtonWidth;
tmpButton.Height = ButtonHeight;
tmpButton.Text = "X: " + x.ToString() + " Y: " + y.ToString();
// Possible add Buttonclick event etc..
this.Controls.Add(tmpButton);
}
}

May be you ca use the code below to solve your problem. This code is of Windows Form application in C#. And for the control Button.
for (int i = 0; i< 8; i++)
{
for (int j = 0; j < 8; j++)
{
Button BtnNew = new Button;
BtnNew.Height = 80;
BtnNew.Width = 80;
BtnNew.Location = new Point(80*i, 80*j);
this.Controls.Add(BtnNew);
}
}

Related

use a picture box on a panel

I need some help. I'm working on a chess game. I created my chess board on a panel, with pictureBox. As the code below
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
PictureBox boardcase = new PictureBox();
boardcase.Size = new Size(100, 100);
//if (i == j) { boardcase.BackColor = Color.White; }
if ((i + j) % 2 == 0) { boardcase.BackColor = Color.DarkBlue; }
else { boardcase.BackColor = Color.Gray; }
boardcase.Location = new Point(i * (boardcase.Width + 5) + 45, j * (boardcase.Height + 5) + 15);
panel1.Controls.Add(boardcase);
}
}
Then, I would like to know how I can use individually each pictureBox that i created, outside this block.
thanks a lot
Haha, ok.I used #TaW 's solution in comment section. and this is it… I just created a PictureBox List as : List<PictureBox> plateau = new List<PictureBox>(); and assigned each boardcase to the list in my For Loop. plateau.Add(boardcase); Then I can call plateau[i] in my code. :-) Thanks guys.

C# - 2d matrix - is guess left/right/up/down of point

Using a 2d array of buttons implemented and placed on a form.
Button[,] tmpButton = new Button[x, y];
private void DrawGrid()
{
int ButtonWidth = 48;
int ButtonHeight = 48;
int start_x = 88;
int start_y = 200;
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
tmpButton[i, j] = new Button();
tmpButton[i, j].Top = start_x + (i * ButtonHeight);
tmpButton[i, j].Left = start_y + (j * ButtonWidth);
tmpButton[i, j].Width = ButtonWidth;
tmpButton[i, j].Height = ButtonHeight;
tmpButton[i, j].Click += new EventHandler(BTN_Grid_Click);
this.Controls.Add(tmpButton[i, j]);
}
}
}
If a random location (x,y) is set true within the grid with the intention of guessing (by clicking on the surrounding grid buttons) it's location. If the location is !true it should return left right up down pointing to the random location we set earlier. If the true location is up and left, it should return whichever it is closest too.
What would be the best way to implement something like this?
This is getting close, but something I can't see is off a bit ...
public String GetDirection()
{
int xd = Guess.X - Clue.X;
int yd = Guess.Y - Clue.Y;
if(Math.Abs(xd) <= Math.Abs(yd))
return (xd <= 0) ? "Left" : "Right";
else
return (yd <= 0) ? "Down" : "Up";
}
Here is a visual representation of what is happening ...
Alright so you had most of it right however you made a easy mistake. When you create the buttons you're rendering from left to right then top to bottom which creates the height as the x position then the width as the y position. So when you go and correlate the guess to the correct position you forget that you did this and assume x is the width.
Here's my implementation which fixed this:
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;
namespace UpDownLeftRight {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.Load += new System.EventHandler(this.Form1_Load);
}
public int[] winner = new int[2];
public Button[,] tmpButton = new Button[10, 10];
private void Form1_Load(object sender, EventArgs e) {
Random r = new Random();
int ButtonWidth = 48;
int ButtonHeight = 48;
int start_x = 0;
int start_y = 0;
winner = new int[] { r.Next(0, 10), r.Next(0, 10) };
this.Size = new Size((ButtonWidth * 11), (ButtonHeight * 11));
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
tmpButton[i, j] = new Button();
tmpButton[i, j].Left = start_x + (i * ButtonWidth);
tmpButton[i, j].Top = start_y + (j * ButtonHeight);
tmpButton[i, j].Width = ButtonWidth;
tmpButton[i, j].Height = ButtonHeight;
tmpButton[i, j].Font = new Font(FontFamily.GenericMonospace, 17);
tmpButton[i, j].Click += new EventHandler(BTN_Grid_Click);
this.Controls.Add(tmpButton[i, j]);
}
}
}
public void BTN_Grid_Click(object o, EventArgs e) {
int[] guess = new int[2];
for (int i = 0; i != tmpButton.GetLength(1); i++) {
for (int j = 0; j != tmpButton.GetLength(0); j++) {
if (tmpButton[i, j] == o) {
guess = new int[] { i, j };
}
}
}
int xDist = guess[0] - winner[0];
int yDist = guess[1] - winner[1];
string possible = "˂˃˄˅";
if (xDist > 0) { possible = possible.Replace("˃", ""); }
if (xDist < 0) { possible = possible.Replace("˂", ""); }
if (xDist == 0) { possible = possible.Replace("˂", ""); possible = possible.Replace("˃", ""); }
if (yDist > 0) { possible = possible.Replace("˅", ""); }
if (yDist < 0) { possible = possible.Replace("˄", ""); }
if (yDist == 0) { possible = possible.Replace("˄", ""); possible = possible.Replace("˅", ""); }
((Button)o).Text = possible;
}
}
}

Get properties from object in tag

For a School assignment we are making a Chess game in C#, in which we have to learn to work in a Object-Oriented way. The board is made out of a 2D picturebox array in a nested for loop
//Create the Board Pattern out of PictureBoxes
#region Checkerboard
PictureBox[,] Vak = new PictureBox[8, 8];
for (int i = 0; i < 8; i++)
{
for (int x = 0; x < 8; x++)
{
Vak[i, x] = new PictureBox();
Vak[i, x].Name = String.Format("{0},{1}", i, x);
Vak[i, x].Width = 50;
Vak[i, x].Height = 50;
Vak[i, x].Location = new Point(xpos, ypos);
Vak[i, x].SizeMode = PictureBoxSizeMode.Zoom;
Vak[i, x].Click += Chess_Click;
if ((i + x) % 2 == 0)
{
Vak[i, x].BackColor = ColorTranslator.FromHtml("#e5e5e5"); //white ColorTranslator.FromHtml("#e5e5e5");
}
else
{
Vak[i, x].BackColor = ColorTranslator.FromHtml("#545454"); //black ColorTranslator.FromHtml("#545454");
}
xpos += 50;
this.Controls.Add(Vak[i, x]);
}
xpos = 50;
ypos += 50;
this.Controls.Add(border);
}
#endregion
On other posts i have found that i can Refer to a class (via the picturebox) using the .Tag property like so:
Vak[i,x].Tag = new Tower();
However, i cannot figure out a way to call properties from the Tower class from withing the tag
Say the Tower class has a property "name", how would i go about calling that
string objectname = Vak[i,x].Tag.(name?)
Sorry If this is a stupid question, but i am very new to programming.
Thanks!
You have to cast it, since Tag is an Object type:
Tower tower = Vak[i,x].Tag as Tower;
if(tower!=null)
{
//do stuff
}
However, i would avoid storing data structures in Tag properties like this.

Place a grid of labels on a form

I'm trying to place a grid of labels on my winforms app. First, I'm populating a list of label objects of size (200 x 50) and then trying to place them so that when x reaches the width of the form (581), I increment y by 50 + 1
Here is my code:
private List<Label> _labels;
private int xOffset = 10;
private int yOffset = 10;
public Form1()
{
InitializeComponent();
_labels = new List<Label>();
for(var i = 0; i <= 20; i++)
_labels.Add(new Label() { Name = "lbl" + i, Height = 50, Width = 200, MinimumSize = new Size(200, 50), BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D, Text = "Label "+i});
// 581, 517
var x = 0;
var y = 0;
foreach (var lbl in _labels)
{
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
lbl.Location = new Point(x, y);
}
this.Controls.Add(lbl);
x += x + lbl.Width;
}
}
It's only placing the even labels from the list on new lines. I'm not sure what I'm doing wrong.
I'm trying to place all of the labels in a grid like design. When one row is full, go to the next row and continue placing labels from the list on that new "row"
You need to move the Location setting code out of the resetting loop:
foreach (var lbl in _labels)
{
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
}
lbl.Location = new Point(x, y);
this.Controls.Add(lbl);
x += lbl.Width;
}
The problematic part is here
x += x + lbl.Width; //+= x
change it to
x += lbl.Width;
Get the
lbl.Location = new Point(x, y);
out of the if statement
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
//lbl.Location = new Point(x, y);
}
lbl.Location = new Point(x, y);
this.Controls.Add(lbl);
x += lbl.Width;
Try this using a Docked FlowLayoutPanel:
public partial class Form1 : Form
{
List<Label> labels;
public Form1()
{
InitializeComponent();
this.labels=new List<Label>();
AddLabelsToFrom(20);
}
void AddLabelsToFrom(int count)
{
for (int i=0; i<count; i++)
{
var lbl=new Label() { Name="lbl"+i, Height=50, Width=200, MinimumSize=new Size(200, 50), BorderStyle=System.Windows.Forms.BorderStyle.Fixed3D, Text="Label "+i };
labels.Add(lbl);
flowLayoutPanel1.Controls.Add(lbl);
}
}
}
void SetGridLabel()
{
for (int i = 0; ; i++)
{
for (int j = 0; ; j++)
{
Label L = new Label();
L.TextAlign = ContentAlignment.MiddleCenter;
L.AutoSize = false;
L.Size = new Size(70, 70);
L.Text = "Test_" + j + "_" + i;
L.Location = new Point(j * L.Size.Width, i * L.Size.Height);
if ((i + 1) * L.Size.Height > this.Size.Height)
return;
if ((j + 1) * L.Size.Width > this.Size.Width)
break;
this.Controls.Add(L);
}
}
}
private List<Label> _labels;
public Form1()
{
InitializeComponent();
_labels = new List<Label>();
for (var i = 0; i <= 20; i++)
_labels.Add(new Label()
{
Name = "lbl" + i, Height = 50,Width = 200,
Size = MinimumSize = new Size(200, 50),
Location = new Point(i * 200 % 600, 50 * (i * 200 / 600)),
BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D,
Text = "Label " + i
});
foreach (var lbl in _labels) this.Controls.Add(lbl);
}

Trying to create a grid of pictureboxes in an array for a board in c#

I'm trying to make a board for a Naughts and crosses (tic tac toe) game using pictureboxes in an array and what I've come up with is this. This starts when I press a button.
for (int i = 0; i <= 3; i++)
{
for (int j = 0; j <= 3; j++)
{
PictureBox[,] pb = new PictureBox[i, j];
pb[i, j].Location = new Point(i * 150 + 100, j * 150 + 100);
pb[i, j].Width = 150;
pb[i, j].Height = 150;
pb[i, j].Visible = true;
pb[i, j].BorderStyle = BorderStyle.FixedSingle;
pb[i, j].BringToFront();
this.Controls.Add(pb[i, j]);
}
}
this throws me a "System.IndexOutOfRangeException" on the line
pb[i, j].Location = new Point(i * 150 + 100, j * 150 + 100);
Whats wrong here?
You're not far off - you need to declare the array outside of the loop, and create a picture with each iteration - this works (tested):
PictureBox[,] pb = new PictureBox[3, 3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
pb[i,j] = new PictureBox();
pb[i, j].Location = new Point(i * 150 + 100, j * 150 + 100);
pb[i, j].Width = 150;
pb[i, j].Height = 150;
pb[i, j].Visible = true;
pb[i, j].BorderStyle = BorderStyle.FixedSingle;
pb[i, j].BringToFront();
this.Controls.Add(pb[i, j]);
}
}
(Note the logic in the loop was wrong too, it should be < 3 not <= 3 as you're starting at 0)
You have declared and instantiated your multidimennsional array within your for loops. Try the following:
PictureBox[,] pb = new PictureBox[3, 3];
for (int i = 0; i <= 3; i++)
{
for (int j = 0; j <= 3; j++)
{
pb[i, j] = new PictureBox();
pb[i, j].Location = new Point(i * 150 + 100, j * 150 + 100);
pb[i, j].Width = 150;
pb[i, j].Height = 150;
pb[i, j].Visible = true;
pb[i, j].BorderStyle = BorderStyle.FixedSingle;
pb[i, j].BringToFront();
this.Controls.Add(pb[i, j]);
}
}
Well i would say your approach of creating picture box array to create the Ticktack Toe game is wrong.Plus your code is inefficient
In your code you are repeatedly creating redundant arrays
PictureBox[,] pb = new PictureBox[i, j];
You are wasting Runtime memory here.
What i would recommend is creating a new Picturebox Class Inherited from the PictureBox class.
Divide this rectangular area into 3X3 Matrix(in terms of dimension)
Then you need to Capture the click event and get the point
private void pictureBox1_Click(object sender, EventArgs e)
{
MouseEventArgs eM = (MouseEventArgs)e;
//eM.X -X Coordinate eM.Y -Y Coordinate
}
Using this Coordinate identify the matrix location,where the user clicked.Then redraw the whole picture-box to reflect the input made by user.
This will separate the need for maintaining a picturebox array you can concentrate just to maintain a 3X3 Integer or Boolean array(0 or 1).When a win condition occurs you just need to draw a line across the matching array entries.
Use the Graphics.DrawLine method to do this

Categories