I am following a tutorial on how to make a recursive maze in c#.
this is the tutorial: http://www.c-sharpcorner.com/uploadfile/4a950c/solving-mazes-using-recursion/
i was following these steps,but I can't get any further because when I run this code, the picture boxes won't show up as in the tutorial.
this is the part where they should be made:
private void createNewMaze()
{
mazeTiles = new PictureBox[XTILES, YTILES];
//Loop for getting all tiles
for (int i = 0; i < XTILES; i++)
{
for (int j = 0; j < YTILES; j++)
{
//initialize a new PictureBox array at cordinate XTILES, YTILES
mazeTiles[i, j] = new PictureBox();
//calculate size and location
int xPosition = (i * TILESIZE) ; //13 is padding from left
int yPosition = (j * TILESIZE) ; //45 is padding from top
mazeTiles[i, j].SetBounds(xPosition, yPosition, TILESIZE, TILESIZE);
//make top left and right bottom corner light blue. Used for start and finish
if ((i == 0 && j == 0) || (i == XTILES - 1 && j == YTILES - 1))
mazeTiles[i, j].BackColor = Color.LightBlue;
else
{
//make all other tiles white
mazeTiles[i, j].BackColor = Color.White;
//make it clickable
EventHandler clickEvent = new EventHandler(PictureBox_Click);
mazeTiles[i, j].Click += clickEvent; // += used in case other events are used
}
//Add to controls to form (display picture box)
this.Controls.Add(mazeTiles[i, j]);
}
}
}
this is what i get:
Maze
i can't find the solution, maybe someone can, thanks in advance.
Related
I wrote a function that checks for a given cell in a grid if it is a legal move following the rules of the board-game called Reversi otherwise known as Othello. The rules are that a circle can only be placed on the grid whenever the newly placed circle and a previous placed circle bounds one of the opponents circles. The majority of the time the function gives the right output (i.e. true when it is a legal move and false when it is a legal move), but some moves that are legal by the previously stated rules are not deemed as a legal move by the function.
I've tried to use the console to check at every step at which cell the function is currently looking and what the value of the cell is to determine what goes wrong. This has only led me to being even more confused.
The following code is the doomed-function:
bool legalMove(int row, int col)
{
// Check if the cell is occupied
if (board[row,col] != 0)
return false;
// Check if there's an opponents circle somewhere around it
for (int i = -1; i<=1; i++)
for (int j = -1; j<=1; j++)
{
if (i == 0 && j == 0)
continue;
int currentRow = row + i;
int currentCol = col + j;
if (currentRow >= 0 && currentRow < board.GetLength(0) && currentCol >= 0 && currentCol < board.GetLength(1) && board[currentRow,currentCol] == -turn)
{
// Now we know that there's an opponents circle somewhere around this space, we now check if it can be captured
while(true)
{
currentRow += i;
currentCol += j;
Console.WriteLine($"currentRow: {currentRow}, currentCol: {currentCol}, value: {board[currentRow,currentCol]}");
if (currentRow < 0 || currentRow >= board.GetLength(0) || currentCol < 0 || currentCol >= board.GetLength(1) || board[currentRow, currentCol] == 0)
return false; // Outside of the board or an empty space
else if (board[currentRow,currentCol] == turn)
return true; // No empty spaces between our cell and another cell of ours
}
}
}
return false; // No cell found around ours
}
What am I missing here?
Thanks in advance!
EDIT:
The entire program is the following (hope it can help):
/* TO-DO
* Make function out of no legal move and tidy up
* Calculate amount of circles of player to determine the winner
* Make victory label better
!!!Tidy up flipCircles method and fix legalMove method
Create a slider and make it change the gridSize
Make GUI change empty space when board gets smaller or bigger
Tidy up the 2x calling to check what the score is
*/
// Library imports
using System;
using System.Drawing;
using System.Security.Policy;
using System.Windows.Forms;
// Game class
class Game : Form
{
// Declare variables
private Board board;
private Button newGame, help;
private Font font;
private Label countRed, countBlue, gameState;
private TrackBar sizeBoard;
public int gridSize = 6;
public Game()
{
// Set the form properties
ClientSize = new Size(520, 670); Text = "Reversi";
// Creating the GUI and adding it to the form
newGame = new Button(); Controls.Add(newGame);
help = new Button(); Controls.Add(help);
font = new Font("Arial", 14);
countBlue = new Label(); Controls.Add(countBlue); countBlue.Font = font;
countRed = new Label(); Controls.Add(countRed); countRed.Font = font;
gameState = new Label(); Controls.Add(gameState); gameState.Font = font;
board = new Board(gridSize); Controls.Add(board);
// Settings of the GUI
newGame.Size = new Size(100, 30); newGame.Location = new Point(150, 10); newGame.Text = "New Game"; newGame.BackColor = Color.LightSlateGray;
help.Size = new Size(100, 30); help.Location = new Point(270, 10); help.Text = "Help"; help.BackColor = Color.LightSlateGray;
countBlue.Size = new Size(110, 30); countBlue.Location = new Point(150, 50); countBlue.Text = $"{board.countBlue} stones"; countBlue.ForeColor = Color.CornflowerBlue;
countRed.Size = new Size(110, 30); countRed.Location = new Point(150, 90); countRed.Text = $"{board.countRed} stones"; countRed.ForeColor = Color.Firebrick;
gameState.Size = new Size(150, 30); gameState.Location = new Point(270, 90); gameState.Text = $"{board.playersTurn}";
// Events //
// Label events
newGame.Click += reset;
help.Click += calculateHelp;
// Board events
board.MouseClick += clicked;
//Paint event
Paint += paint;
}
// Event-handlers //
// Label event-handlers
private void reset(object e, EventArgs ea)
{
board.Reset();
countBlue.Text = $"{board.countBlue} stones";
countRed.Text = $"{board.countRed} stones";
gameState.Text = $"{board.playersTurn}";
}
private void calculateHelp(object e, EventArgs ea)
{
board.SetHelp();
}
// Board event-handlers
private void clicked(object e, MouseEventArgs mea)
{
board.Clicked(mea.Location);
countBlue.Text = $"{board.countBlue} stones";
countRed.Text = $"{board.countRed} stones";
gameState.Text = $"{board.playersTurn}";
// Now check if there's a legalMove if not
//if (timesNoLegalMove > 1)
gameState.Text = $"{board.playersTurn}";
}
// Paint event-handler
private void paint(object e, PaintEventArgs pea)
{
Graphics gr = pea.Graphics;
gr.FillEllipse(Brushes.CornflowerBlue, 100, 45, 31, 31);
gr.FillEllipse(Brushes.Firebrick, 100, 85, 31, 31);
}
}
// Board class
class Board : Label
{
// Declare all global variables used in this class
private int[,] board;
private int size;
private int turn = 1; // 1 is blue, -1 is red
private bool legalMoveExists = true;
public int timesNoLegalMove = 0;
private bool help = false;
// Create the board and set settings + events
public Board(int gridSize)
{
size = gridSize;
Size = new Size(size * 50, size * 50);
Location = new Point(10 + (25 * (10 - size)), 120 + (25 * (10 - size)));
BackColor = Color.White;
board = new int[size, size];
startingState();
Paint += Draw;
}
// Sets the values of the center 4 squares to that of the starting circles
private void startingState()
{
board[(size / 2)-1, (size / 2)-1] = 1;
board[(size / 2), (size / 2)] = 1;
board[(size / 2), (size / 2) - 1] = -1;
board[(size / 2) - 1, (size / 2)] = -1;
}
// Resets the board when New Game is clicked
public void Reset()
{
for (int row = 0; row < board.GetLength(0); row++)
for (int col = 0; col < board.GetLength(1); col++)
board[row, col] = 0;
startingState();
turn = 1;
Invalidate();
}
public void SetHelp()
{
if (help)
help = false;
else
help = true;
Invalidate();
}
public string playersTurn
{
get
{
if (turn == 1)
return "It's Blue's turn";
if (turn == -1)
return "It's Red's turn";
else
{
if (countBlue > countRed)
return "Blue has won the game!";
if (countRed > countBlue)
return "Red has won the game!";
else
return "It's a draw!";
}
}
}
public int countRed
{
get
{
return board.Cast<int>().Count(n => n == -1);
}
}
public int countBlue
{
get
{
return board.Cast<int>().Count(n => n == 1);
}
}
bool legalMove(int row, int col)
{
// Check if the cell is occupied
if (board[row,col] != 0)
return false;
// Check if there's an opponents circle somewhere around it
for (int i = -1; i<=1; i++)
for (int j = -1; j<=1; j++)
{
if (i == 0 && j == 0)
continue;
int currentRow = row + i;
int currentCol = col + j;
if (currentRow >= 0 && currentRow < board.GetLength(0) && currentCol >= 0 && currentCol < board.GetLength(1) && board[currentRow,currentCol] == -turn)
{
// Now we know that there's an opponents circle somewhere around this space, we now check if it can be captured
while(true)
{
currentRow += i;
currentCol += j;
if (currentRow < 0 || currentRow >= board.GetLength(0) || currentCol < 0 || currentCol >= board.GetLength(1) || board[currentRow, currentCol] == 0)
return false; // Outside of the board or an empty space
else if (board[currentRow,currentCol] == turn)
return true; // No empty spaces between our cell and another cell of ours
}
}
}
return false; // No cell found around ours
}
private void flipCircles(int row, int col)
{
// Check all eight directions from the current position
for (int r = row - 1; r <= row + 1; r++)
{
for (int c = col - 1; c <= col + 1; c++)
{
// Skip the current position
if (r == row && c == col)
continue;
int rr = r;
int cc = c;
// Check if the next position in this direction is a valid position on the board
// and if it is occupied by the opponent's piece
if (rr >= 0 && rr < board.GetLength(0) && cc >= 0 && cc < board.GetLength(1) && board[rr, cc] == -turn)
{
// Keep moving in this direction until we find the current player's piece or an empty cell
while (true)
{
rr += r - row;
cc += c - col;
// If we have reached an invalid position or an empty cell, break out of the loop
if (rr < 0 || rr >= board.GetLength(0) || cc < 0 || cc >= board.GetLength(1) || board[rr, cc] == 0)
break;
// If we have found the current player's piece, flip all the pieces between the current position and the player's piece
if (board[rr, cc] == turn)
{
while (rr != r || cc != c)
{
rr -= r - row;
cc -= c - col;
board[rr, cc] = turn;
}
break;
}
}
}
}
}
}
// Sets the value of a clicked cell to either 1 (Blue), or -1 (Red)
public void Clicked(Point mea)
{
int rowClicked = mea.X / 50;
int colClicked = mea.Y /50;
if (legalMove(rowClicked, colClicked))
{
board[rowClicked, colClicked] = turn;
flipCircles(rowClicked, colClicked);
help = false;
turn = -turn;
legalMoveExists = false;
Invalidate();
}
}
// Draws the entire board and all circles
void Draw(object e, PaintEventArgs pea)
{
Graphics gr = pea.Graphics;
legalMoveExists = false;
for (int row = 0; row < board.GetLength(0); row++)
for (int col = 0; col < board.GetLength(1); col++)
{
// Draw the background tiles
if (row % 2 == 0 && col % 2 == 0 || row % 2 != 0 && col % 2 != 0)
gr.FillRectangle(Brushes.DarkGray, 50 * row, 50 * col, 50, 50);
// Draw circles
if (board[row, col] == 1) // Blue circles
gr.FillEllipse(Brushes.CornflowerBlue, 50 * row - 1, 50 * col - 1, 51, 51);
else if (board[row, col] == -1) // Red circles
gr.FillEllipse(Brushes.Firebrick, 50 * row - 1, 50 * col - 1, 51, 51);
// Check for legal moves and draw help circles if the help button has been pressed
else if (legalMove(row, col))
{
legalMoveExists = true;
timesNoLegalMove = 0;
if (help) // Help circles
gr.DrawEllipse(Pens.Black, 50 * row + 9, 50 * col + 9, 31, 31);
}
}
// Make this a function
if (!legalMoveExists)
{
turn = -turn;
timesNoLegalMove++;
Invalidate();
if (timesNoLegalMove > 1)
turn = 0;
}
}
}
// Main run
class Program
{
static void Main()
{
Application.Run(new Game());
}
}
Your question states that the function you wrote to scan the surrounding cells is failing sporadically and that it's difficult to diagnose. It was easy to reproduce the failures by running your code, but I wasn't able to see an obvious way to effectively debug it.
It "might" be more effective to improve the algorithm where it's more methodical in how it inspects the surrounding cells in the first place, which would also be easier to debug if necessary. One solid way to do this would be to use custom Iterators where you could use a standard foreach pattern to inspect virtual "lines" radiating in the eight directions. At each 'yield' you can check to see whether a determination can be made in terms of either a "legal move" or a "capture".
Here's a proof-of-concept grid that is intended to demonstrate how the iterators work. It doesn't evaluate the cells in terms of game play in any way but you can see how it would lend itself to doing that. The idea here is to click any cell and observe the markup of U-R-D-L. It may also help to see it working so you can clone this sample and set breakpoints.
Left, Right, Up, Down iterator examples are shown - diagonals would follow the same pattern. The mouse down control passes the starting cell coordinate position as a Point:
public IEnumerable<Point> CellsUp(Point point)
{
while (true)
{
point = new Point(point.X, point.Y - 1);
if (point.Y < 0) break;
yield return point;
}
}
public IEnumerable<Point> CellsRight(Point point, int max)
{
while (true)
{
point = new Point(point.X + 1, point.Y);
if (point.X == max) break;
yield return point;
}
}
public IEnumerable<Point> CellsDown(Point point, int max)
{
while (true)
{
yield return point;
point = new Point(point.X, point.Y + 1);
if (point.Y == max) break;
}
}
public IEnumerable<Point> CellsLeft(Point point)
{
while (true)
{
yield return point;
point = new Point(point.X - 1, point.Y);
if (point.X < 0) break;
}
}
The code lays the groundwork for a methodical scan outward from any given point.
private void legalMoveIterationStub(object? sender, EventArgs e)
{
clear();
if(sender is Control control)
{
control.BackColor = Color.Blue;
control.Refresh();
var pos = board.GetCellPosition(control);
var pt = new Point(pos.Column, pos.Row);
Control ctrl;
foreach (var point in CellsUp(pt))
{
ctrl = board.GetControlFromPosition(point.X, point.Y);
ctrl.Text = "U";
ctrl.Refresh();
Thread.Sleep(DEMO_DELAY_MS);
// This is where the cell inspects e.g. for "empty square"
// or color. Chances are, some condition will be met
// and you will break from here rather than iterate
// all the way to the edge of the board each time.
}
foreach (var point in CellsRight(pt, board.ColumnCount))
{
ctrl = board.GetControlFromPosition(point.X, point.Y);
ctrl.Text = "R";
ctrl.Refresh();
Thread.Sleep(DEMO_DELAY_MS);
}
foreach (var point in CellsDown(pt, board.ColumnCount))
{
ctrl = board.GetControlFromPosition(point.X, point.Y);
ctrl.Text = "D";
ctrl.Refresh();
Thread.Sleep(DEMO_DELAY_MS);
}
foreach (var point in CellsLeft(pt))
{
ctrl = board.GetControlFromPosition(point.X, point.Y);
ctrl.Text = "L";
ctrl.Refresh();
Thread.Sleep(DEMO_DELAY_MS);
}
}
}
The demo board has been mocked like this for testing purposes:
public partial class Game : Form
{
public Game()
{
InitializeComponent();
for (int col = 0; col < board.ColumnCount; col++)
{
for (int row = 0; row < board.RowCount; row++)
{
var tile = new Label
{
BorderStyle = BorderStyle.FixedSingle,
Anchor = (AnchorStyles)0xF,
Margin = new Padding(1),
TextAlign = ContentAlignment.MiddleCenter
};
board.Controls.Add(tile, col, row);
tile.MouseDown += legalMove;
}
}
}
void clear()
{
foreach (Control control in board.Controls)
{
control.Text = string.Empty;
control.BackColor = SystemColors.Control;
}
board.Refresh();
}
.
.
.
}
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.
So I have been trying to find an answer for this since two days now, i'm still a student and I don't know if couldn't understand the other posts, or if my case is too specific to be solved with anything I found on the internet.
As I said in my title I have a 2D array of class called "piece", anytime I start the game it'll create a 2D array with random rows and columns (to explain quickly the goal is to connect all the pieces to win, you rotate the pieces to make the connections). It was going fine with the OnMouseClick(); function but since I need to use the arrows of my keyboard to archieve this, I'm encountering some troubles.
I've got a function which is generating the puzzle each time I start or reset it (So it's called in Start(); and the Update(); when I'm pressing a "clear" button) which is going like this :
public piece[,] pieces;
public GameObject Cursor;
void GeneratePuzzle()
{
pieces = new piece[width, height];
int[] auxValues = { 0, 0, 0, 0 };
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
//width restrictions
if (w == 0)
auxValues[3] = 0;
else
auxValues[3] = pieces[w - 1, h].values[1];
if (w == width - 1)
auxValues[1] = 0;
else
auxValues[1] = Random.Range(0, 2);
//heigth resctrictions
if (h == 0)
auxValues[2] = 0;
else
auxValues[2] = pieces[w, h - 1].values[0];
if (h == height - 1)
auxValues[0] = 0;
else
auxValues[0] = Random.Range(0, 2);
//tells piece type
int valueSum = auxValues[0] + auxValues[1] + auxValues[2] + auxValues[3];
if (valueSum == 2 && auxValues[0] != auxValues[2])
valueSum = 5;
go = (GameObject)Instantiate(piecesPrefabs[valueSum], new Vector3(origin.position.x + w, origin.position.y, origin.position.z + h), Quaternion.identity);
go.transform.parent = gameObject.transform;
while (go.GetComponent<piece>().values[0] != auxValues[0] ||
go.GetComponent<piece>().values[1] != auxValues[1] ||
go.GetComponent<piece>().values[2] != auxValues[2] ||
go.GetComponent<piece>().values[3] != auxValues[3])
{
go.GetComponent<piece>().RotatePiece();
}
pieces[w, h] = go.GetComponent<piece>();
instantiatedPieces.Add(go.gameObject);
}
}
}
So far I've been trying something like this to make my cursor move in this array :
public void Update()
{
for (int h = 0; h < height; h++)
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
h++;
if (h > height)
h = 0;
}
for (int w = 0; w < width; w++)
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
w++;
if (w > width)
w = 0;
}
// Cursor.transform.position = pieces[w, h].transform.position; ==> I suppose this is where it should be
}
}
}
But I end up being out of range or the cursor is so fast I can't see it going over each piece. So to be clear I'd like to be able to move my cursor over each pieces in this 2D array, by row and column (I suppose this is the way to go), after that I'll need to call the function from the piece class for the specific piece my cursor is over but I think I will be able to find this out.
English is not my native language so sorry and I'll try my best if you need any more informations to help me.
Thank you very much any help will be really appreciated !
Here is an example of my comment:
If you want to move a cursor over the elements of your array in update based off of keypress, there is no need for a for loop.
// Declared outside of your update makes these class variables that
// will live as long as this object exists.
int w = 0; // May be better to change this to cursorXPos
int h = 0; // May be better to name this cursorYPos
public void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
w--;
if (w < 0)
w = width -1;
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
w++;
if (w >= width)
w = 0;
}
if (Input.GetKeyDown(KeyCode.UpArrow))
{
h--;
if (h < 0)
h = height -1;
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
h++;
if (h >= height)
h = 0;
}
Cursor.transform.position = pieces[w, h].transform.position;
}
I am not sure exactly what you're trying to do with your code but.
I don't get what you're using the following line in update for.
for (int h = 0; h < height; h++)
try removing that line.
try this:
public void Update()
{
for (int h = 0; h < height; h++)
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
h++;
if (h > height)
h = 0;
}
}
for (int w = 0; w < width; w++)
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
w++;
if (w > width)
w = 0;
}
// Cursor.transform.position = pieces[w, h].transform.position; ==> I suppose this is where it should be
}
}
or this:
public void Update()
{
for (int h = 0; h < width; h++)
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
h++;
if (h > height)
h = 0;
}
}
for (int w = 0; w < height; w++)
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
w++;
if (w > width)
w = 0;
}
// Cursor.transform.position = pieces[w, h].transform.position; ==> I suppose this is where it should be
}
}
with WindowsForms I would use the KeyDown event and increase/decrease h or w and set them to zero or max when reaching an edge.
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
So I'm creating a 2d grid with drawings of rectangles and circles inside of a
flowLayoutPanel. The problem I'm getting however is that they are not being drawn completely.
This is the code of the event when a button is pushed.
private void DrawIt()
{
System.Drawing.Graphics graphics = flowLayoutPanel1.CreateGraphics();
graphics.Clear(Form1.ActiveForm.BackColor);
int row = Convert.ToInt32(textBox1.Text);
int column = Convert.ToInt32(textBox2.Text);
flowLayoutPanel1.Width = (row * 50) + 30;
flowLayoutPanel1.Height = (column * 50) + 1;
for (int j = 0; j < column; j++)
{
for (int i = 0; i < row; i++)
{
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(50 * i, 50*j, 50, 50);
graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
}
}
}
I make each rectangle the size of 50 px so I know how big to calculate the width and height. I even added some extra in case I messed up. But in the end I get the following:
Any ideas on what could be the problem?
You create the graphics from the panel and then change its size. The graphics object therefore clips to the previous size.
Change the size before you create the graphics object:
int row = Convert.ToInt32(textBox1.Text);
int column = Convert.ToInt32(textBox2.Text);
flowLayoutPanel1.Width = (row * 50) + 30;
flowLayoutPanel1.Height = (column * 50) + 1;
System.Drawing.Graphics graphics = flowLayoutPanel1.CreateGraphics();
graphics.Clear(Form1.ActiveForm.BackColor);
for (int j = 0; j < column; j++)
{
for (int i = 0; i < row; i++)
{
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(50 * i, 50 * j, 50, 50);
graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
}
}