the problem i'm facing right now is that i don't know how to check on the opponent's move which ships it sinks so i can display a message saying "Your ____ has sunk".
this is the code i have written
namespace Naval
{
public partial class Form2 : Form
{
const int Size_grid = 10;
const int picturebox = 50;
PictureBox[,] playerBoard = new PictureBox[Size_grid, Size_grid];
PictureBox[,] opponentBoard = new PictureBox[Size_grid, Size_grid];
int[,] playerShips = new int[Size_grid, Size_grid];
int[,] opponentShips = new int[Size_grid, Size_grid];
int[] Lengths = new int[] { 5, 4, 3, 2 };
//string[] Names = new string[] { "Αεροπλανοφόρο", "Αντιτορπιλικό", "Πολεμικό", "Υποβρύχιο" };
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
for (int row = 0; row < Size_grid; row++)
{
for (int col = 0; col < Size_grid; col++)
{
PictureBox playerPictureBox = new PictureBox();
playerPictureBox.Size = new Size(picturebox, picturebox);
playerPictureBox.Location = new Point(col * (picturebox + 10) + 185, row * (picturebox + 10) + 245);
playerPictureBox.Click += PictureBox_Click;
playerPictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
playerPictureBox.BackColor = Color.Gray;
panel1.Controls.Add(playerPictureBox);
playerBoard[row, col] = playerPictureBox;
}
}
for (int row = 0; row < Size_grid; row++)
{
for (int col = 0; col < Size_grid; col++)
{
PictureBox opponentPictureBox = new PictureBox();
opponentPictureBox.Size = new Size(picturebox, picturebox);
opponentPictureBox.Location = new Point(col * (picturebox + 10) + 1145, row * (picturebox + 10) + 245);
opponentPictureBox.Click += PictureBox_Click;
opponentPictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
opponentPictureBox.BackColor = Color.Gray;
panel1.Controls.Add(opponentPictureBox);
opponentBoard[row, col] = opponentPictureBox;
}
}
PlacePlayerShips(playerShips, Lengths);
PlaceOpponentShips(opponentShips, Lengths);
}
private void PictureBox_Click(object sender, EventArgs e)
{
PictureBox pictureBox = (PictureBox)sender;
int row = (pictureBox.Location.Y - 245) / (picturebox + 10);
int col = (pictureBox.Location.X - 1145) / (picturebox + 10);
if (pictureBox.Location.X >= 1145 && pictureBox.ImageLocation == null) // opponent board
{
if (row >= 0 && row < opponentShips.GetLength(0) && col >= 0 && col < opponentShips.GetLength(1))
{
if (opponentShips[row, col] > 0)
{
pictureBox.ImageLocation = "x.png";
}
else
{
pictureBox.ImageLocation = "-.png";
}
ComputerMove();
}
}
}
private void ComputerMove()
{
Random random = new Random();
int row = random.Next(Size_grid);
int col = random.Next(Size_grid);
while (playerBoard[row, col].ImageLocation != null)
{
row = random.Next(Size_grid);
col = random.Next(Size_grid);
}
if (playerShips[row, col] > 0)
{
playerBoard[row, col].ImageLocation = "x.png";
}
else
{
playerBoard[row, col].ImageLocation = "-.png";
}
}
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
private void PlacePlayerShips(int[,] playerShips, int[] shipLengths)
{
Random random = new Random(DateTime.Now.Millisecond);
foreach (int shipLength in shipLengths)
{
int row, col;
int direction = random.Next(2);
int placed = 0;
while (placed == 0)
{
if (direction == 0) // Horizontal
{
row = random.Next(Size_grid);
col = random.Next(Size_grid - shipLength + 1);
// Check if ship overlaps with other ships
int overlap = 0;
for (int i = 0; i < shipLength; i++)
{
if (playerShips[row, col + i] == 1)
{
overlap = 1;
}
}
// Place ship if no overlap
if (overlap == 0)
{
placed = 1;
for (int i = 0; i < shipLength; i++)
{
playerShips[row, col + i] = 1;
playerBoard[row, col + i].BackColor = Color.LightBlue;
}
}
}
else // Vertical
{
row = random.Next(Size_grid - shipLength + 1);
col = random.Next(Size_grid);
// Check if ship overlaps with other ships
int overlap = 0;
for (int i = 0; i < shipLength; i++)
{
if (playerShips[row + i, col] == 1)
{
overlap = 1;
}
}
// Place ship if no overlap
if (overlap == 0)
{
placed = 1;
for (int i = 0; i < shipLength; i++)
{
playerShips[row + i, col] = 1;
playerBoard[row + i, col].BackColor = Color.LightBlue;
}
}
}
// Change direction if ship couldn't be placed
if (placed == 0)
{
direction = (direction + 1) % 2;
}
}
}
}
private void PlaceOpponentShips(int[,] opponentShips, int[] shipLengths)
{
Random random = new Random(DateTime.Now.Millisecond);
;
foreach (int shipLength in shipLengths)
{
int row, col;
int direction = random.Next(2);
int placed = 0;
while (placed == 0)
{
if (direction == 0) // Horizontal
{
row = random.Next(Size_grid);
col = random.Next(Size_grid - shipLength + 1);
// Check if ship overlaps with other ships
int overlap = 0;
for (int i = 0; i < shipLength; i++)
{
if (opponentShips[row, col + i] == 1)
{
overlap = 1;
}
}
// Place ship if no overlap
if (overlap == 0)
{
placed = 1;
for (int i = 0; i < shipLength; i++)
{
opponentShips[row, col + i] = 1;
}
}
}
else // Vertical
{
row = random.Next(Size_grid - shipLength + 1);
col = random.Next(Size_grid);
// Check if ship overlaps with other ships
int overlap = 0;
for (int i = 0; i < shipLength; i++)
{
if (opponentShips[row + i, col] == 1)
{
overlap = 1;
}
}
// Place ship if no overlap
if (overlap == 0)
{
placed = 1;
for (int i = 0; i < shipLength; i++)
{
opponentShips[row + i, col] = 1;
}
}
}
// Change direction if ship couldn't be placed
if (placed == 0)
{
direction = (direction + 1) % 2;
}
}
}
}
private void label1_Click(object sender, EventArgs e)
{
}
int time = 0;
private void timer1_Tick(object sender, EventArgs e)
{
time++;
label42.Text= time.ToString();
}
private void timer2_Tick(object sender, EventArgs e)
{
label44.Text = " ";
timer2.Enabled = false;
}
}
}
i tried adding a switch with choices 1-4 but it didn't work i've also tried having a int[] ship Hits = new int[] {0,0,0,0} and just adding 1 every time a ship was hit but that didn't go as planned because i didn't know how to bind each item of the array to a ship . and i think that's about it
One approach that you might find helpful would be to bundle up all the information about a Ship into a class. This is an abstraction that could make it easier for displaying ship names when they are sunk. At the same time, use inheritance so that a Ship is still a PictureBox with all the functionality that implies.
Ship minimal class example
Member properties tell us what we need know about a ship. Use enum values to make the intent perfectly clear.
class Ship : PictureBox
{
#region P R O P E R T I E S
[Description("Type")]
public τύπος τύπος
{
get => _τύπος;
set
{
if (!Equals(_τύπος, value))
{
_τύπος = value;
switch (_τύπος)
{
case τύπος.Αεροπλανοφόρο: Image = Image.FromFile(Path.Combine(_imageDir, "aircraft-carrier.png")); break;
case τύπος.Αντιτορπιλικό: Image = Image.FromFile(Path.Combine(_imageDir, "destroyer.png")); break;
case τύπος.Πολεμικό: Image = Image.FromFile(Path.Combine(_imageDir, "military.png")); break;
case τύπος.Υποβρύχιο: Image = Image.FromFile(Path.Combine(_imageDir, "submarine.png")); break;
}
}
}
}
τύπος _τύπος = 0;
public bool Sunk { get; set; }
[Description("Flag")]
public σημαία σημαία
{
get => _σημαία;
set
{
_σημαία = value;
onUpdateColor();
}
}
σημαία _σημαία = σημαία.Player;
#endregion P R O P E R T I E S
private void onUpdateColor()
{
var color =
Sunk ? Color.Red :
σημαία.Equals(σημαία.Player) ?
Color.Navy :
Color.DarkOliveGreen;
for (int x = 0; x < Image.Width; x++) for (int y = 0; y < Image.Height; y++)
{
Bitmap bitmap = (Bitmap)Image;
if (bitmap.GetPixel(x, y).R < 0x80)
{
bitmap.SetPixel(x, y, color);
}
}
Refresh();
}
public Point[] Hits { get; set; } = new Point[0];
public override string ToString() =>
$"{σημαία} {τύπος} # {((TableLayoutPanel)Parent)?.GetCellPosition(this)}";
private readonly static string _imageDir =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images");
}
Where enum values are:
enum Direction
{
Horizontal,
Vertical,
}
enum τύπος
{
[Description("Aircraft Carrier")]
Αεροπλανοφόρο = 5,
[Description("Destroyer")]
Αντιτορπιλικό = 4,
[Description("Military")]
Πολεμικό = 3,
[Description("Submarine")]
Υποβρύχιο = 2,
}
/// <summary>
/// Flag
/// </summary>
enum σημαία
{
Player,
Opponent,
}
Displaying ships names when they are sunk
When the inherited Ship version of PictureBox is clicked the information is now available.
private void onAnyShipClick(object sender, EventArgs e)
{
if (sender is Ship ship)
{
MessageBox.Show(ship.ToString());
}
}
Images credit: Robuart
Used under license.
Related
I'm trying to give the letters in my richtextbox different colors for my subnet calculator, but the richtextbox doesn't change the colors until the 26th letter.
How it looks:
int iValueSm = trackBarSmMask.Value;
rtbScroll.Text = "";
rtbScroll.SelectionStart = rtbScroll.TextLength;
rtbScroll.SelectionLength = 0;
for (int i = 1; i <= iValueSm; i++)
{
rtbScroll.SelectionColor = Color.Blue;
rtbScroll.AppendText("N");
if (i%8==0 && i != 32)
{
rtbScroll.Text = rtbScroll.Text + ".";
}
}
for (int i = iValueSm+1; i <= 32; i++)
{
rtbScroll.SelectionColor = Color.Red;
rtbScroll.AppendText("H");
if (i % 8 == 0 && i != 32)
{
rtbScroll.Text = rtbScroll.Text + ".";
}
}
labelAmountNetID.Text = "/" + iValueSm.ToString();
Well, can be a lot of approaches to deal with this problem but here is one suggestion:
// Track bar definitions...
private void SetTrackBarVals()
{
trackBar1.Minimum = 0;
trackBar1.Maximum = 31;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
var counter = 0;
var dotsCounter = 0;
rtbScroll.Text = "";
int iValueSm = trackBar1.Value + 1; // +1 because we start counting from 0
for (int i = 1; i <= 32; i++)
{
if (counter > 0 && counter % 8 == 0)
{
// new octet
rtbScroll.AppendText(".");
dotsCounter++;
}
if (i > iValueSm)
{
// It is red
rtbScroll.AppendText("H");
rtbScroll.SelectionStart = (i - 1) + dotsCounter;
rtbScroll.SelectionLength = 1 ;
rtbScroll.SelectionColor = Color.Red;
}
else
{
rtbScroll.AppendText("N");
}
counter++;
}
}
Anytime you set the .Text() property, you RESET all formatting back to black and white.
Here is how I'd write it using SelectedText:
private void Form1_Load(object sender, EventArgs e)
{
updateRTB();
}
private void trackBarSmMask_ValueChanged(object sender, EventArgs e)
{
updateRTB();
}
private void trackBarSmMask_Scroll(object sender, EventArgs e)
{
updateRTB();
}
private void updateRTB()
{
rtbScroll.Text = "";
rtbScroll.SelectionStart = 0;
rtbScroll.SelectionLength = 0;
int iValueSm = trackBarSmMask.Value;
labelAmountNetID.Text = "/" + iValueSm.ToString();
for (int i = 1; i <= 32; i++)
{
rtbScroll.SelectionColor = (i <= iValueSm) ? Color.Blue : Color.Red;
rtbScroll.SelectedText = (i <= iValueSm) ? "N" : "H";
if (i % 8 == 0 && i != 32)
{
rtbScroll.SelectionColor = Color.Black;
rtbScroll.SelectedText = ".";
}
}
}
I have a combobox which has values 4-9, and according to that value I want generate runtime labels and textboxes. When I click on 6 then the code can generate 6 labels and textboxes as required, but when I click on 5 again one label and textbox should disappear or if I click on 4 again 2 labels and textboxes should disappear....which is not happening. I have this code in c#. What changes should I make in this code? Is there any other way that I can do this code?
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.Text == "4")
{
checkBox1.Visible = true;
for (int i = 0; i < 4; i++)
{
addlabel(i);
}
for (int i1 = 0; i1 < 4; i1++)
{
addlabel1(i1);
}
}
if (comboBox1.Text == "5")
{
checkBox1.Visible = true;
for (int i = 0; i < 5; i++)
{
addlabel(i);
}
for (int i1 = 0; i1 < 5; i1++)
{
addlabel1(i1);
}
}
if (comboBox1.Text == "6")
{
checkBox1.Visible = true;
for (int i = 0; i < 6; i++)
{
addlabel(i);
}
for (int i1 = 0; i1 < 6; i1++)
{
addlabel1(i1);
}
}
}
void addlabel(int i)
{
int left = 70;
int top = 100;
int step_x = 80;
int step_y = 30;
new Label()
{
Name = $"label{i}",
Text = "Enter Subject:",
Location = new Point(left, top + step_y * i),
Parent = this,
};
left += step_x;
int left1 = 357;
int top1 = 100;
int step_x1 = 80;
int step_y1 = 30;
new Label()
{
Name = $"label{i}",
Text = "Total Marks:",
Location = new Point(left1, top1 + step_y1 * i),
Parent = this,
};
left1 += step_x1;
}
void addlabel1(int i1)
{
int left = 200;
int top = 100;
int step_x = 80;
int step_y = 30;
new TextBox()
{
Name = $"textbox{i1}",
Text = "",
Size = new Size(122, 20),
Location = new Point(left, top + step_y * i1),
Parent = this,
};
left += step_x;
int left1 = 480;
int top1 = 100;
int step_x1 = 80;
int step_y1 = 30;
new TextBox()
{
Name = $"textbox{i1}",
Text = "",
Size = new Size(122, 20),
Location = new Point(left1, top1 + step_y1 * i1),
Parent = this,
};
left1 += step_x1;
}
Any Suggestions? Help me out.
Try the following code:
public partial class Form1 : Form
{
private int prev = 0;
private Point lblLocation = new Point(70, 100);
private Point tbLocation = new Point(170, 100);
public Form1()
{
InitializeComponent();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
int cur = Convert.ToInt32(comboBox1.SelectedItem);
int tmp = cur - prev;
if (tmp > 0)
{
// add new controls
for (int i = 1; i <= tmp; i++)
{
AddLabel(prev + i);
AddTextBox(prev + i);
lblLocation.Y += 30;
tbLocation.Y += 30;
}
prev = cur;
}
else
{
// remove controls
tmp = Math.Abs(tmp);
for(int i= 0; i < tmp; i++)
{
RemoveControl($"lbl{prev}");
RemoveControl($"tb{prev}");
lblLocation.Y -= 30;
tbLocation.Y -= 30;
prev--;
}
}
}
private void AddLabel(int i)
{
new Label()
{
Name = $"lbl{i}",
Text = $"lbl{i}",
Location = lblLocation,
Parent = this
};
}
private void AddTextBox(int i)
{
new TextBox()
{
Name = $"tb{i}",
Text = $"tb{i}",
Location = tbLocation,
Parent = this
};
}
private void RemoveControl(string name)
{
foreach (Control item in Controls.OfType<Control>())
{
if (item.Name == name)
{
Controls.Remove(item);
}
}
}
}
This question already has answers here:
How to determine 5 labels in a row of the same backcolor in a C# array?
(3 answers)
Closed 7 years ago.
I created a two dimensional array [19,19] of labels. On click a user changes the color of a label to either black or white depending on the iteration. I want a message box to pop up when there are five labels of the same color lined up horizontally. This is to be done without recursion. Any help would be much appreciated.
public partial class Form1 : Form
{
int labelCount = 0;
int iteration = 0;
public Label[,] board = new Label[19,19];
const int WinLength = 5;
const int BoardWidth = 19;
const int BoardHeight = 19;
gamePlay obj = new gamePlay();
public Form1()
{
InitializeComponent();
}
private void labelClick (object sender, EventArgs e)
{
Label x = (Label)sender;
if (x.BackColor == Color.Transparent)
{
if (iteration % 2 == 0)
{
x.BackColor = Color.Black;
}
else
{
x.BackColor = Color.White;
}
iteration++;
}
else
{
}
for (int r = 0; r < BoardHeight; r++)
{
for (int c = 0; c < BoardWidth; c++)
{
if (board[r, c] == x)
{
Color? winner = obj.CheckForWinner(board, r, c);
if (winner == Color.Black)
{
MessageBox.Show("Black is the winner!");
}
else if (winner == Color.White)
{
MessageBox.Show("White is the winner!");
}
// else winner is null, meaning no winner yet.
}
}
}
private int[] FindClickedLabelCoordinates(Label[,] board, Label label)
{
for (int r = 0; r < BoardHeight; r++)
{
for (int c = 0; c < BoardWidth; c++)
{
if (board[r, c] == label)
return new int[] { r, c };
}
}
return null;
}
}
class gamePlay
{
const int WinLength = 5;
const int BoardWidth = 19;
const int BoardHeight = 19;
private Color? CheckForWinner(Label[,] board, int r, int c)
{
Color startColor = board[r, c].BackColor;
for (int c1 = c - WinLength + 1; c1 <= c; c1++)
{
if (c1 >= 0 && c1 < BoardWidth && board[r, c1].BackColor == startColor)
{
MessageBox.Show("you win!");
bool win = true;
for (int c2 = c1 + 1; c2 < c1 + WinLength; c2++)
{
if (c2 < 0 || c2 >= BoardWidth || board[r, c2].BackColor != startColor)
{
win = false;
break;
}
}
if (win)
{
return startColor;
}
}
}
return null;
}
You just pass it in the method call:
new abc().checkWin(board);
You also need to fix your checkWin() method signature:
public void checkWin(Label[,] board)
{
...
}
BTW, checkWin() seems like a method that should return a bool (true if won, otherwise false) instead of void.
int iteration = 0;
public Label[,] board = new Label[19,19];
const int WinLength = 5;
const int BoardWidth = 19;
const int BoardHeight = 19;
gamePlay obj = new gamePlay();
public Form1()
{
InitializeComponent();
}
private void labelClick (object sender, EventArgs e)
{
Label x = (Label)sender;
if (x.BackColor == Color.Transparent)
{
if (iteration % 2 == 0)
{
x.BackColor = Color.Black;
}
else
{
x.BackColor = Color.White;
}
iteration++;
}
else
{
}
for (int r = 0; r < BoardHeight; r++)
{
for (int c = 0; c < BoardWidth; c++)
{
if (board[r, c] == x)
{
Color? winner = obj.CheckForWinner(board, r, c);
if (winner == Color.Black)
{
MessageBox.Show("Black is the winner!");
}
else if (winner == Color.White)
{
MessageBox.Show("White is the winner!");
}
// else winner is null, meaning no winner yet.
}
}
}
private int[] FindClickedLabelCoordinates(Label[,] board, Label label)
{
for (int r = 0; r < BoardHeight; r++)
{
for (int c = 0; c < BoardWidth; c++)
{
if (board[r, c] == label)
return new int[] { r, c };
}
}
return null;
}
}
class gamePlay
{
const int WinLength = 5;
const int BoardWidth = 19;
const int BoardHeight = 19;
private Color? CheckForWinner(Label[,] board, int r, int c)
{
Color startColor = board[r, c].BackColor;
for (int c1 = c - WinLength + 1; c1 <= c; c1++)
{
if (c1 >= 0 && c1 < BoardWidth && board[r, c1].BackColor == startColor)
{
MessageBox.Show("you win!");
bool win = true;
for (int c2 = c1 + 1; c2 < c1 + WinLength; c2++)
{
if (c2 < 0 || c2 >= BoardWidth || board[r, c2].BackColor != startColor)
{
win = false;
break;
}
}
if (win)
{
return startColor;
}
}
}
return null;
}
So Im making tetris and I need to make 7 blocks. The problem is is that I have to copy paste the code in 7 different classes(and then changing the grid) so I thought maybe using subclass would be much easier. The problem is I dont know how to do that.
this is my general block class:
public class Block
{
Color Color;
const int x = 4;
const int y = 4;
bool[,] vorm;
Texture2D block;
float FallTimer;
public bool FallingBlock = false;
Random Random = new Random();
ZBlock zBlock = new ZBlock();
TBlock tBlock = new TBlock();
SBlock sBlock = new SBlock();
OBlock oBlock = new OBlock();
JBlock jBlock = new JBlock();
LBlock lBlock = new LBlock();
IBlock iBlock = new IBlock();
public void HandleInput()
{
if (Tetris.inputHelper.KeyPressed(Keys.Down))
{
FallTimer = 0;
for (int i = 0; i < blokvorm.GetLength(0); i++)
{
for (int j = 0; j < blokvorm.GetLength(1); j++) ;
// blokvorm[i, j] += 15;
}
}
}
public void speed(GameTime gameTime)
{
double SpeedCounter = 3;
int LevelCounter = 1;
if (LevelCounter < Tetris.GameWorld.level)
{
SpeedCounter -= 0.5;
LevelCounter++;
}
FallTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (Math.Round(FallTimer, 1) == SpeedCounter)
{
FallTimer = 0;
//BlockPosition.Y += 15;
}
}
public bool[,] blokvorm
{
get
{
vorm = new bool[x, y];
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
{
vorm[i, j] = false;
}
int r = Random.Next(7);
if (r == 0)
{
vorm = ZBlock.zblock();
}
else if (r == 1)
{
vorm = TBlock.tblock();
}
else if (r == 2)
{
vorm = SBlock.sblock();
}
else if (r == 3)
{
vorm = OBlock.oblock();
}
else if (r == 4)
{
vorm = JBlock.jblock();
}
else if (r == 5)
{
vorm = LBlock.lblock();
}
else if (r == 6)
{
vorm = IBlock.iblock();
}
return vorm;
}
}
public TBlock TBlock
{
get { return tBlock; }
}
public ZBlock ZBlock
{
get { return zBlock; }
}
public SBlock SBlock
{
get { return sBlock; }
}
public OBlock OBlock
{
get { return oBlock; }
}
public JBlock JBlock
{
get { return jBlock; }
}
public LBlock LBlock
{
get { return lBlock; }
}
public IBlock IBlock
{
get { return iBlock; }
}
public void Draw(SpriteBatch spriteBatch, ContentManager Content)
{
block = Content.Load<Texture2D>("Block");
spriteBatch.Begin();
if (!FallingBlock)
{
for (int i = 0; i < blokvorm.GetLength(0); i++)
{
for (int j = 0; j < blokvorm.GetLength(1); j++)
if (blokvorm[i, j])
spriteBatch.Draw(block, new Vector2(30 + (i * 15), 30 + (j * 15)), Color.White);
}
spriteBatch.End();
}
}
}
}
So How can I use this class to create other 7 block classes(T, L, I, O etc) easily?
Edit: My block all looks like this:
{
const int x = 4;
const int y = 4;
public bool[,] tblock()
{
vorm = new bool[x, y];
for (int i = 0; i < x; i++)
for (int j = 0; j <y; j++)
{
vorm[i, j] = false;
vorm[0, 1] = true;
vorm[1, 1] = true;
vorm[1, 0] = true;
vorm[2, 1] = true;
}
Color = Color.Indigo;
return vorm;
}
public void RotationLinks(InputHelper inputhelper)
{
bool[,] nieuw = new bool[x, y];
if (inputhelper.KeyPressed(Keys.Left))
{
for (int a = 0; a < 4; ++a)
for (int b = 0; b < 4; ++b)
nieuw[a, b] = vorm[x - a - 1, b];
vorm = nieuw;
}
}
}
}
So to make other 6 I copied theh whole code and change the grid value. Is there a possible way to make it easier using bock class?
How can I copy the values from dynamic textboxes to a jagged array? I tried with a for cycle but I constantly get this error message:"Object reference not set to an instance of an object." What can be the problem?(the textboxes are also made with jagged arrays) Here is the full code, you can find the problematic lines in the first lines of the button1 event handler link
for (int a = 0; a < nr; a++)
{
for (int b = 0; b < nr+ 1; b++)
{
array[a][b] =int.Parse(TB[a][b].Text);
}
}
(Here's the full code:)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
int ismeretlen = 2;
TextBox[][] TB;
string file = "3ismeretlen.dat";
private void Form2_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
int[][] egyenletek = new int[ismeretlen][];
for (int a = 0; a < ismeretlen; a++)
{
for (int b = 0; b < ismeretlen + 1; b++)
{
egyenletek[a][b] =int.Parse(TB[a][b].Text);
}
}
int változószám = TB[0].Length;
for (int i = 0; i < változószám - 1; i++)
{
for (int j = i; j < változószám - 1; j++)
{
int[] d = new int[változószám];
for (int x = 0; x < változószám; x++)
{
if (i == j && egyenletek[j][i] == 0)
{
bool changed = false;
for (int z = egyenletek.Length - 1; z > i; z--)
{
if (egyenletek[z][i] != 0)
{
int[] temp = new int[változószám];
temp = egyenletek[z];
egyenletek[z] = egyenletek[j];
egyenletek[j] = temp;
changed = true;
}
}
if (!changed)
{
textBox1.Text += "Az egyenletrendszernek nincs megoldása!\r\n";
return;
}
}
if (egyenletek[j][i] != 0)
{
d[x] = egyenletek[j][x] / egyenletek[j][i];
}
else
{
d[x] = egyenletek[j][x];
}
}
egyenletek[j] = d;
}
for (int y = i + 1; y < egyenletek.Length; y++)
{
int[] f = new int[változószám];
for (int g = 0; g < változószám; g++)
{
if (egyenletek[y][i] != 0)
{
f[g] = egyenletek[y][g] - egyenletek[i][g];
}
else
{
f[g] = egyenletek[y][g];
}
}
egyenletek[y] = f;
}
}
double val = 0;
int k = változószám - 2;
double[] eredmény = new double[egyenletek.Length];
for (int i = egyenletek.Length - 1; i >= 0; i--)
{
val = egyenletek[i][változószám - 1];
for (int x = változószám - 2; x > k; x--)
{
val -= egyenletek[i][x] * eredmény[x];
}
eredmény[i] = val / egyenletek[i][i];
if (eredmény[i].ToString() == "NaN" || eredmény[i].ToString().Contains("Végtelen sok megoldás."))
{
textBox1.Text += "Az egyenletrendszernek nincs megoldása!\n";
return;
}
k--;
TextBox[] megoldás = new TextBox[ismeretlen];
for (int b = 0; b < ismeretlen; i++)
{
megoldás[b] = new TextBox();
megoldás[b].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
megoldás[b].Left = 536+ b * 36;
megoldás[b].Top = 36 * b + 10;
megoldás[b].Width = 35;
megoldás[b].Font = new Font(megoldás[b].Font.FontFamily, 16);
megoldás[b].BackColor = Color.Cyan;
megoldás[b].TextAlign = HorizontalAlignment.Center;
megoldás[b].Text = eredmény[ismeretlen - 1].ToString();
this.panel1.Controls.Add(megoldás[b]);
}
FileStream fs = new FileStream(file, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
for (int r = 0; r < ismeretlen; r++)
for (int t = 0; t < ismeretlen + 1; t++)
bw.Write(egyenletek[r][t]);
bw.Close();
fs.Close();
}
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
numericUpDown1.Maximum = 6;
numericUpDown1.Minimum = 2;
}
private void Generál_Click(object sender, EventArgs e)
{
this.panel1.Controls.Clear();
ismeretlen = (int)numericUpDown1.Value;
TB = new TextBox[ismeretlen][];
for(int i = 0; i < ismeretlen; i++)
TB[i] = new TextBox[ismeretlen + 1];
int height = 20;
int width = 40;
int curX = 10;
int curY = 10;
for(int i = 0; i < ismeretlen; i++)
{
for(int j = 0; j < ismeretlen + 1; j++)
{
TextBox txtbox = new TextBox();
txtbox = new TextBox();
txtbox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
txtbox.Left = curX;
txtbox.Top = curY;
txtbox.Width = width;
txtbox.Height = height;
txtbox.Font = new Font(txtbox.Font.FontFamily, 16);
txtbox.BackColor = Color.Azure;
txtbox.TextAlign = HorizontalAlignment.Center;
TB[i][j] = txtbox;
this.panel1.Controls.Add(TB[i][j]); // Add as a child of panel
curX += width + 15;
}
curX = 10;
curY = curY + height + 20;
}
}
private void Ment_Click(object sender, EventArgs e)
{
}
}
}
In this line of code, you only initialize the first dimension of your array:
int[][] egyenletek = new int[ismeretlen][];
But you then use it before initializing the second dimension a handful of lines later (so this dimension is null (an object not set to a reference)):
egyenletek[a][b] =int.Parse(TB[a][b].Text);
Before that line, you should initialize the 2nd dimension in some way. You did this at another part of your code, in the lines of 172-173 in your jsfiddle link.
In general, when you see this error you should evaluate what objects you are reading from and assigning to and ensure they have been initialized (ie. they are not null).