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?
Related
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.
Ok so I finished my code n queens genetics in c# but I keep getting these compiler errors even though I changed the code several times
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NQueen1
{
class Program
{
private const int sSize = 75; // Population size at start.
private const int mTest = 1000; // Arbitrary number of test cycles.
private const double pMating = 0.7; // Probability of two chromosomes mating. Range: 0.0 < MATING_PROBABILITY < 1.0
private const double rMutation = 0.001; // Mutation Rate. Range: 0.0 < MUTATION_RATE < 1.0
private const int minS = 10; // Minimum parents allowed for selection.
private const int MaxS = 50; // Maximum parents allowed for selection. Range: MIN_SELECT < MAX_SELECT < START_SIZE
private const int offSpring = 20; // New offspring created per generation. Range: 0 < OFFSPRING_PER_GENERATION < MAX_SELECT.
private const int minRandom = 8; // For randomizing starting chromosomes
private const int maxShuffles = 20;
private const int maxPBC = 4; // Maximum Position-Based Crossover points. Range: 0 < PBC_MAX < 8 (> 8 isn't good).
private const int maxLength = 10; // chess board width.
private static int epoch = 0;
private static int childCount = 0;
private static int nextMutation = 0; // For scheduling mutations.
private static int mutations = 0;
private static List<Chromosome> population = new List<Chromosome>();
private static void algorithm()
{
int popSize = 0;
Chromosome thisChromo = null;
bool done = false;
initializeChromosomes();
mutations = 0;
nextMutation = getRandomNumber(0, (int)Math.Round(1.0 / rMutation));
while (!done)
{
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
if ((thisChromo.conflicts() == 0) || epoch == mTest)
{
done = true;
}
}
getFitness();
rouletteSelection();
mating();
prepNextEpoch();
epoch++;
// This is here simply to show the runtime status.
Console.WriteLine("Epoch: " + epoch);
}
Console.WriteLine("done.");
if (epoch != rMutation)
{
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
if (thisChromo.conflicts() == 0)
{
printSolution(thisChromo);
}
}
}
Console.WriteLine("Completed " + epoch + " epochs.");
Console.WriteLine("Encountered " + mutations + " mutations in " + childCount + " offspring.");
return;
}
private static void getFitness()
{
// Lowest errors = 100%, Highest errors = 0%
int popSize = population.Count;
Chromosome thisChromo = null;
double bestScore = 0;
double worstScore = 0;
// The worst score would be the one with the highest energy, best would be lowest.
worstScore = population[maximum()].conflicts();
// Convert to a weighted percentage.
bestScore = worstScore - population[minimum()].conflicts();
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
thisChromo.fitness((worstScore - thisChromo.conflicts()) * 100.0 / bestScore);
}
return;
}
private static void rouletteSelection()
{
int j = 0;
int popSize = population.Count;
double genT = 0.0;
double selT = 0.0;
int maximumToSelect = getRandomNumber(minS, MaxS);
double rouletteSpin = 0.0;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
bool done = false;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
genT += thisChromo.fitness();
}
genT *= 0.01;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
thisChromo.selectionProbability(thisChromo.fitness() / genT);
}
for (int i = 0; i < maximumToSelect; i++)
{
rouletteSpin = getRandomNumber(0, 99);
j = 0;
selT = 0;
done = false;
while (!done)
{
thisChromo = population[j];
selT += thisChromo.selectionProbability();
if (selT >= rouletteSpin)
{
if (j == 0)
{
thatChromo = population[j];
}
else if (j >= popSize - 1)
{
thatChromo = population[popSize - 1];
}
else
{
thatChromo = population[j - 1];
}
thatChromo.selected(true);
done = true;
}
else
{
j++;
}
}
}
return;
}
// This is where you can choose between options:
// To choose between crossover options, uncomment one of:
// partiallyMappedCrossover(),
// positionBasedCrossover(), while keeping the other two commented out.
private static void mating()
{
int getRand = 0;
int parentA = 0;
int parentB = 0;
int newIndex1 = 0;
int newIndex2 = 0;
Chromosome newChromo1 = null;
Chromosome newChromo2 = null;
for (int i = 0; i < offSpring; i++)
{
parentA = chooseParent();
// Test probability of mating.
getRand = getRandomNumber(0, 100);
if (getRand <= pMating * 100)
{
parentB = chooseParent(parentA);
newChromo1 = new Chromosome();
newChromo2 = new Chromosome();
population.Add(newChromo1);
newIndex1 = population.IndexOf(newChromo1);
population.Add(newChromo2);
newIndex2 = population.IndexOf(newChromo2);
// Choose either, or both of these:
partialCrossover(parentA, parentB, newIndex1, newIndex2);
//positionBasedCrossover(parentA, parentB, newIndex1, newIndex2);
if (childCount - 1 == nextMutation)
{
exchangeMutation(newIndex1, 1);
}
else if (childCount == nextMutation)
{
exchangeMutation(newIndex2, 1);
}
population[newIndex1].computeConflicts();
population[newIndex2].computeConflicts();
childCount += 2;
// Schedule next mutation.
if (childCount % (int)Math.Round(1.0 / rMutation) == 0)
{
nextMutation = childCount + getRandomNumber(0, (int)Math.Round(1.0 / rMutation));
}
}
} // i
return;
}
private static void partialCrossover(int chromA, int chromB, int child1, int child2)
{
int j = 0;
int item1 = 0;
int item2 = 0;
int pos1 = 0;
int pos2 = 0;
Chromosome thisChromo = population[chromA];
Chromosome thatChromo = population[chromB];
Chromosome newChromo1 = population[child1];
Chromosome newChromo2 = population[child2];
int crossPoint1 = getRandomNumber(0, maxLength - 1);
int crossPoint2 = getExclusiveRandomNumber(maxLength - 1, crossPoint1);
if (crossPoint2 < crossPoint1)
{
j = crossPoint1;
crossPoint1 = crossPoint2;
crossPoint2 = j;
}
// Copy Parent genes to offspring.
for (int i = 0; i < maxLength; i++)
{
newChromo1.data(i, thisChromo.data(i));
newChromo2.data(i, thatChromo.data(i));
}
for (int i = crossPoint1; i <= crossPoint2; i++)
{
// Get the two items to swap.
item1 = thisChromo.data(i);
item2 = thatChromo.data(i);
// Get the items// positions in the offspring.
for (j = 0; j < maxLength; j++)
{
if (newChromo1.data(j) == item1)
{
pos1 = j;
}
else if (newChromo1.data(j) == item2)
{
pos2 = j;
}
} // j
// Swap them.
if (item1 != item2)
{
newChromo1.data(pos1, item2);
newChromo1.data(pos2, item1);
}
// Get the items// positions in the offspring.
for (j = 0; j < maxLength; j++)
{
if (newChromo2.data(j) == item2)
{
pos1 = j;
}
else if (newChromo2.data(j) == item1)
{
pos2 = j;
}
} // j
// Swap them.
if (item1 != item2)
{
newChromo2.data(pos1, item1);
newChromo2.data(pos2, item2);
}
} // i
return;
}
private static void positionCrossover(int chromA, int chromB, int child1, int child2)
{
int k = 0;
int numPoints = 0;
int[] tempArray1 = new int[maxLength];
int[] tempArray2 = new int[maxLength];
bool matchFound = false;
Chromosome thisChromo = population[chromA];
Chromosome thatChromo = population[chromB];
Chromosome newChromo1 = population[child1];
Chromosome newChromo2 = population[child2];
// Choose and sort the crosspoints.
numPoints = getRandomNumber(0, maxPBC);
int[] crossPoints = new int[numPoints];
int negativeNancy = -1;
for (int i = 0; i < numPoints; i++)
{
crossPoints[i] = getRandomNumber(0, maxLength - negativeNancy, crossPoints);
} // i
// Get non-chosens from parent 2
k = 0;
for (int i = 0; i < maxLength; i++)
{
matchFound = false;
for (int j = 0; j < numPoints; j++)
{
if (thatChromo.data(i) == thisChromo.data(crossPoints[j]))
{
matchFound = true;
}
} // j
if (matchFound == false)
{
tempArray1[k] = thatChromo.data(i);
k++;
}
} // i
// Insert chosens into child 1.
for (int i = 0; i < numPoints; i++)
{
newChromo1.data(crossPoints[i], thisChromo.data(crossPoints[i]));
}
// Fill in non-chosens to child 1.
k = 0;
for (int i = 0; i < maxLength; i++)
{
matchFound = false;
for (int j = 0; j < numPoints; j++)
{
if (i == crossPoints[j])
{
matchFound = true;
}
} // j
if (matchFound == false)
{
newChromo1.data(i, tempArray1[k]);
k++;
}
} // i
// Get non-chosens from parent 1
k = 0;
for (int i = 0; i < maxLength; i++)
{
matchFound = false;
for (int j = 0; j < numPoints; j++)
{
if (thisChromo.data(i) == thatChromo.data(crossPoints[j]))
{
matchFound = true;
}
} // j
if (matchFound == false)
{
tempArray2[k] = thisChromo.data(i);
k++;
}
} // i
// Insert chosens into child 2.
for (int i = 0; i < numPoints; i++)
{
newChromo2.data(crossPoints[i], thatChromo.data(crossPoints[i]));
}
// Fill in non-chosens to child 2.
k = 0;
for (int i = 0; i < maxLength; i++)
{
matchFound = false;
for (int j = 0; j < numPoints; j++)
{
if (i == crossPoints[j])
{
matchFound = true;
}
} // j
if (matchFound == false)
{
newChromo2.data(i, tempArray2[k]);
k++;
}
} // i
return;
}
private static void exchangeMutation(int index, int exchanges)
{
int i = 0;
int tempData = 0;
Chromosome thisChromo = null;
int gene1 = 0;
int gene2 = 0;
bool done = false;
thisChromo = population[index];
while (!done)
{
gene1 = getRandomNumber(0, maxLength - 1);
gene2 = getExclusiveRandomNumber(maxLength - 1, gene1);
// Exchange the chosen genes.
tempData = thisChromo.data(gene1);
thisChromo.data(gene1, thisChromo.data(gene2));
thisChromo.data(gene2, tempData);
if (i == exchanges)
{
done = true;
}
i++;
}
mutations++;
return;
}
private static int chooseParent()
{
// Overloaded function, see also "chooseparent(ByVal parentA As Integer)".
int parent = 0;
Chromosome thisChromo = null;
bool done = false;
while (!done)
{
// Randomly choose an eligible parent.
parent = getRandomNumber(0, population.Count - 1);
thisChromo = population[parent];
if (thisChromo.selected() == true)
{
done = true;
}
}
return parent;
}
{
// Overloaded function, see also "chooseparent()".
int parent = 0;
Chromosome thisChromo = null;
bool done = false;
while (!done)
{
// Randomly choose an eligible parent.
parent = getRandomNumber(0, population.Count - 1);
if (parent != parentA)
{
thisChromo = population[parent];
if (thisChromo.selected() == true)
{
done = true;
}
}
}
return parent;
}
private static void prepNextEpoch()
{
int popSize = 0;
Chromosome thisChromo = null;
// Reset flags for selected individuals.
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
thisChromo = population[i];
thisChromo.selected(false);
}
return;
}
private static void printSolution(Chromosome bestSolution)
{
string[][] board = RectangularArrays.ReturnRectangularStringArray(maxLength, maxLength);
// Clear the board.
for (int x = 0; x < maxLength; x++)
{
for (int y = 0; y < maxLength; y++)
{
board[x][y] = "";
}
}
for (int x = 0; x < maxLength; x++)
{
board[x][bestSolution.data(x)] = "Q";
}
// Display the board.
Console.WriteLine("Board:");
for (int y = 0; y < maxLength; y++)
{
for (int x = 0; x < maxLength; x++)
{
if (string.ReferenceEquals(board[x][y], "Q"))
{
Console.Write("Q ");
}
else
{
Console.Write(". ");
}
}
Console.Write("\n");
}
return;
}
private static int getRandomNumber(int low, int high)
{
return (int)Math.Round((high - low) * (new Random()).NextDouble() + low);
}
private static int getExclusiveRandomNumber(int high, int except)
{
bool done = false;
int getRand = 0;
while (!done)
{
getRand = (new Random()).Next(high);
if (getRand != except)
{
done = true;
}
}
return getRand;
}
private static int getRandomNumber(int low, int high, int[] except)
{
bool done = false;
int getRand = 0;
if (high != low)
{
while (!done)
{
done = true;
getRand = (int)Math.Round((high - low) * (new Random()).NextDouble() + low);
for (int i = 0; i < except.Length; i++) //UBound(except)
{
if (getRand == except[i])
{
done = false;
}
} // i
}
return getRand;
}
else
{
return high; // or low (it doesn't matter).
}
}
private static int minimum()
{
// Returns an array index.
int popSize = 0;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
int winner = 0;
bool foundNewWinner = false;
bool done = false;
while (!done)
{
foundNewWinner = false;
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
if (i != winner)
{ // Avoid self-comparison.
thisChromo = population[i];
thatChromo = population[winner];
if (thisChromo.conflicts() < thatChromo.conflicts())
{
winner = i;
foundNewWinner = true;
}
}
}
if (foundNewWinner == false)
{
done = true;
}
}
return winner;
}
private static int maximum()
{
// Returns an array index.
int popSize = 0;
Chromosome thisChromo = null;
Chromosome thatChromo = null;
int winner = 0;
bool foundNewWinner = false;
bool done = false;
while (!done)
{
foundNewWinner = false;
popSize = population.Count;
for (int i = 0; i < popSize; i++)
{
if (i != winner)
{ // Avoid self-comparison.
thisChromo = population[i];
thatChromo = population[winner];
if (thisChromo.conflicts() > thatChromo.conflicts())
{
winner = i;
foundNewWinner = true;
}
}
}
if (foundNewWinner == false)
{
done = true;
}
}
return winner;
}
private static void initializeChromosomes()
{
int shuffles = 0;
Chromosome newChromo = null;
int chromoIndex = 0;
for (int i = 0; i < sSize; i++)
{
newChromo = new Chromosome();
population.Add(newChromo);
chromoIndex = population.IndexOf(newChromo);
// Randomly choose the number of shuffles to perform.
shuffles = getRandomNumber(minRandom, maxShuffles);
exchangeMutation(chromoIndex, shuffles);
population[chromoIndex].computeConflicts();
}
return;
}
private class Chromosome
{
internal int[] mData = new int[maxLength];
internal double mFitness = 0.0;
internal bool mSelected = false;
internal double mSelectionProbability = 0.0;
internal int mConflicts = 0;
public Chromosome()
{
for (int i = 0; i < maxLength; i++)
{
this.mData[i] = i;
}
return;
}
public virtual void computeConflicts()
{
int x = 0;
int y = 0;
int tempx = 0;
int tempy = 0;
//string[][] board = new string[MAX_LENGTH][MAX_LENGTH];
string[][] board = RectangularArrays.ReturnRectangularStringArray(maxLength, maxLength);
int conflicts = 0;
int[] dx = new int[] { -1, 1, -1, 1 };
int[] dy = new int[] { -1, 1, 1, -1 };
bool done = false;
// Clear the board.
for (int i = 0; i < maxLength; i++)
{
for (int j = 0; j < maxLength; j++)
{
board[i][j] = "";
}
}
for (int i = 0; i < maxLength; i++)
{
board[i][this.mData[i]] = "Q";
}
// Walk through each of the Queens and compute the number of conflicts.
for (int i = 0; i < maxLength; i++)
{
x = i;
y = this.mData[i];
// Check diagonals.
for (int j = 0; j <= 3; j++)
{
tempx = x;
tempy = y;
done = false;
while (!done)
{
tempx += dx[j];
tempy += dy[j];
if ((tempx < 0 || tempx >= maxLength) || (tempy < 0 || tempy >= maxLength))
{
done = true;
}
else
{
if (board[tempx][tempy].ToString().ToUpper().Equals("Q"))// ignore the case of 2 strings
{
conflicts++;
}
}
}
}
}
this.mConflicts = conflicts;
}
public virtual void conflicts(int value)
{
this.mConflicts = value;
return;
}
public virtual int conflicts()
{
return this.mConflicts;
}
public virtual double selectionProbability()
{
return mSelectionProbability;
}
public virtual void selectionProbability(double SelProb)
{
mSelectionProbability = SelProb;
return;
}
public virtual bool selected()
{
return mSelected;
}
public virtual void selected(bool sValue)
{
mSelected = sValue;
return;
}
public virtual double fitness()
{
return mFitness;
}
public virtual void fitness(double score)
{
mFitness = score;
return;
}
public virtual int data(int index)
{
return mData[index];
}
public virtual void data(int index, int value)
{
mData[index] = value;
return;
}
} // Chromosome
static void Main(string[] args)
{
algorithm();
return;
}
}
}
This is the second code here:
namespace NQueen1
{
internal static class RectangularArrays
{
internal static string[][] ReturnRectangularStringArray(int size1, int size2)
{
string[][] newArray = new string[size1][];
for (int array1 = 0; array1 < size1; array1++)
{
newArray[array1] = new string[size2];
}
return newArray;
}
}
}
THe Error:
Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.Collections.Generic.List`1.get_Item(Int32 index)
at NQueen1.Program.rouletteSelection() in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 143
at NQueen1.Program.algorithm() in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 56
at NQueen1.Program.Main(String[] args) in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 841
I have no clue why its throwing off these errors I tried about almost everything I could think of to fix it
This is just a random guess.
My Spidey Senses tells me thisChromo = population[j] is probably overrunning the size of array, i.e. its in a while loop with j++ and there is no real bounds checking
private static void rouletteSelection()
{
...
for (int i = 0; i < maximumToSelect; i++)
{
...
while (!done)
{
thisChromo = population[j];
...
j++;
If this is the problem, I'd consider the possibility that j will be larger than population.Length and therefore breaking out of the loop; using an if statement; or just refactoring this logic
Tips for your future questions
If you have a runtime error, show us the line of code it has the error on
Pasting code is vital, however pasting too much is annoying and hard to read
If you paste code, at least try to format it
Learn to use the debugger and breakpoints (see: How to use the Debugger, Using Breakpoints).
It shows more times than expected and when I add 1 item and it is stackable it adds to stack....but not once 2 times.
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ArenaRPG
{
public class Inventory
{
int slotWight;
int slotHeight;
int ItemsPerpage = 1;
int CurrentPage;
int Columns, Rows;
B_Item[,] items;
Backpack backpack;
Vector2 pos;
public Inventory(Backpack bpack,int itemsPerPage,int Columns,int Rows, int SlotWidth, int SlotHeight, Vector2 Pos)
{
this.backpack = bpack;
this.slotHeight = SlotHeight;
this.slotWight = SlotWidth;
this.pos = Pos;
this.Columns = Columns;
this.ItemsPerpage = itemsPerPage;
this.Rows = Rows;
items = new B_Item[Columns, Rows];
LoadItems(bpack);
}
public void Update(GameTime gameTime)
{
double Maxpages = Math.Ceiling((double)(items.Length - 1) / ItemsPerpage);
if (Input.KeyPressed(Keys.A))
{
CurrentPage++;
}
if (Input.KeyPressed(Keys.D))
{
CurrentPage--;
}
Input.Update(gameTime);
}
public void Draw(SpriteBatch spriteBatch)
{
var result = items.Cast<B_Item>().Skip(ItemsPerpage * (CurrentPage-1)).Take(ItemsPerpage);
foreach (var item in result)
{
for (int X = 0; X < Columns; X++)
{
for (int Y = 0; Y < Rows; Y++)
{
int DrawX = (int)pos.X + (X * (slotWight + 2));
int DrawY = (int)pos.Y + (Y * (slotWight + 2));
if(items[X,Y] != null)
{
spriteBatch.Draw(item.Texure, new Rectangle(DrawX, DrawY ,32, 32), new Rectangle(0, 0, 64, 64), Color.White);
if (items[X,Y].StackSize > 1)
{
spriteBatch.DrawString(AssetManager.GetInstance().font["Arial8"], items[X,Y].StackSize.ToString(), new Vector2(DrawX+ 20, DrawY+20), Color.DarkBlue);
}
spriteBatch.DrawString(AssetManager.GetInstance().font["Arial8"], CurrentPage.ToString(), new Vector2(50, 50), Color.DarkBlue);
}
}
}
}
}
public void LoadItems(Backpack BPack)
{
int itemIndex = 0;
for (int X = 0; X < Columns; X++)
{
for (int Y = 0; Y < Rows; Y++)
{
if (itemIndex < BPack.items.Count)
{
items[X, Y] = BPack.items[itemIndex];
itemIndex++;
}
}
}
}
}
}
Backpack is simple
public void AddItems(B_Item NewItem)
{
if (items.Count < MaxSlots)
{
foreach (var i in items.ToArray())
{
if (i.Item_Name == NewItem.Item_Name )
{
if (i.Is_Stackable == true && i.StackSize < 500)
{
i.StackSize += 1;
}
}
else
{
items.Add(NewItem);
}
}
}
else
{
items.Add(NewItem);
}
}
private void Remove(B_Item itemID)
{
for (int i = 0; i < items.Count; i++)
{
if (items.Count > 0)
{
items[i].StackSize -= 1;
}
items.RemoveAt(i);
}
}
Why does draw more items than specified by value itemsPerPage in inventory.
constructor
Inventory thiss = new Inventory(new PlayerBack(),2,1,32,32, 32, new Vector2(0, 0))
Ok, sorry for comment it's abit wrong. Here correct method:
public void AddItems(B_Item NewItem)
{
if (items.Count < MaxSlots)
{
foreach (var i in items.ToArray())
{
if (i.Item_Name == NewItem.Item_Name )
{
if (i.Is_Stackable == true && i.StackSize < 500)
{
i.StackSize += 1;
return;
}
}
}
}
items.Add(NewItem);
}
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;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to create a dungeon generator for a project I've been working on based off of this algorithm. I've gotten everything down, but my array (Fig. 1) doesn't seem to be holding giving the map data for some reason. I'm using three types of data to determine if a cell in the map is either empty (0), a space a character can be on (1), a hallway (2), or a wall (3).
I've gotten a bit stuck on this portion so any help is appreciated!
EDIT: The problem is the map object isn't storing the data in the loop shown in Fig. 1. Sorry for being so vague.
(Fig. 1)
for (int i = 0; i < roomList.Count; i++)
{
for (int x = roomList[i].X; x < (roomList[i].X + roomList[i].W); x++)
{
for (int y = roomList[i].Y; y < (roomList[i].Y + roomList[i].H); y++)
{
map[x, y] = 1;
}
}
}
(All of my relevant code)
namespace Project
{
}
public class Room
{
int xValue, yValue, widthValue, heightValue;
public int X
{
get { return xValue; }
set { xValue = value; }
}
public int Y
{
get { return yValue; }
set { yValue = value; }
}
public int W
{
get { return widthValue; }
set { widthValue = value; }
}
public int H
{
get { return heightValue; }
set { heightValue = value; }
}
}
public class DungeonGenerate
{
public int baseWidth = 513;
public int baseHeight = 513;
public int width = 64;
public int height = 64;
Color[,] arrayColor;
Random rand = new Random();
Room room = new Room();
Rectangle[,] rectMap;
public void Generate()
{
rectMap = new Rectangle[baseWidth, baseHeight];
//Creates a 2-D Array/Grid for the Dungeon
int[,] map = new int[baseWidth, baseHeight];
//Determines all the cells to be empty until otherwise stated
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
map[x, y] = 0;
}
}
//Determines the amount of rooms in the dungeon
int minRooms = (width * height) / 300;
int maxRooms = (width * height) / 150;
int amountOfRooms = rand.Next(minRooms, maxRooms);
//Room dimensions
int widthRoot = Convert.ToInt32(Math.Round(Math.Sqrt(width * 2)));
int heightRoot = Convert.ToInt32(Math.Round(Math.Sqrt(height * 2)));
int minWidth = Convert.ToInt32(Math.Round((width * .5) / widthRoot));
int maxWidth = Convert.ToInt32((width * 2) / widthRoot);
int minHeight = Convert.ToInt32(Math.Round(height * .5) / heightRoot);
int maxHeight = Convert.ToInt32((height * 2) / heightRoot);
//Creates the rooms
List<Room> roomList = new List<Room>(amountOfRooms);
for (int i = 0; i < amountOfRooms; i++)
{
bool ok = false;
do
{
room.X = rand.Next(width);
room.Y = rand.Next(height);
room.W = (rand.Next(maxWidth)) + minWidth;
room.H = (rand.Next(maxHeight)) + minHeight;
if (room.X + room.W >= width && room.Y + room.H >= height)
{
continue;
}
for (int q = 0; q < roomList.Count; q++)
{
if (room.X > roomList[q].X && room.X < roomList[q].X + room.W && room.Y > roomList[q].Y && room.Y < roomList[q].Y + room.H)
{
ok = false;
break;
}
}
ok = true;
roomList.Add(room);
} while (!ok);
}
//This will create hallways that lead to and from the rooms
int connectionCount = roomList.Count;
List<Point> connectedCells = new List<Point>((width * height));
for (int i = 0; i < connectionCount; i++)
{
Room roomA = roomList[i];
int roomNum = i;
while (roomNum == i)
{
roomNum = rand.Next(roomList.Count);
}
Room roomB = roomList[roomNum];
//Increasing this will make the hallway more straight, decreasing it will make the hallway more skewed
int sidestepChance = 10;
Point pointA = new Point(x: (rand.Next(roomA.W)) + roomA.X, y: (rand.Next(roomA.H)) + roomA.Y);
Point pointB = new Point(x: (rand.Next(roomB.W)) + roomB.X, y: (rand.Next(roomB.H)) + roomB.Y);
while (pointA != pointB)
{
int num = rand.Next() * 100;
if (num < sidestepChance)
{
if (pointB.X != pointA.X)
{
if (pointB.X > pointA.X)
{
pointB.X--;
}
else
{
pointB.X++;
}
}
}
else if(pointB.Y != pointA.Y)
{
if (pointB.Y > pointA.Y)
{
pointB.Y--;
}
else
{
pointB.Y++;
}
}
}
if (pointB.X < width && pointB.Y < height)
{
connectedCells.Add(pointB);
}
}
//Fills the room with data
for (int i = 0; i < roomList.Count; i++)
{
for (int x = roomList[i].X; x < (roomList[i].X + roomList[i].W); x++)
{
for (int y = roomList[i].Y; y < (roomList[i].Y + roomList[i].H); y++)
{
map[x, y] = 1;
}
}
}
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (map[x, y] == 0)
{
bool wall = false;
for (int yy = y - 2; yy < y + 2; yy++)
{
for (int xx = x - 2; xx < x + 2; xx++)
{
if (xx > 0 && yy > 0 && xx < width && yy < height)
{
if (map[xx, yy] == 1 || map[xx, yy] == 2)
{
map[x, y] = 3;
wall = true;
}
}
}
if (wall)
{
break;
}
}
}
}
}
//Rendering the Map and giving it some Color (Sort of)!
int scaler = baseWidth / width;
for (int x = 0; x < baseWidth; x++)
{
for (int y = 0; y < baseHeight; y++)
{
rectMap[x, y] = new Rectangle(x, y, 1, 1);
arrayColor = new Color[baseWidth, baseHeight];
switch (map[x, y])
{
case 0:
arrayColor[x, y] = new Color(0,0,0);
break;
case 1:
arrayColor[x, y] = new Color(0,0,0);
break;
case 2:
arrayColor[x, y] = new Color(0,0,0);
break;
case 3:
arrayColor[x, y] = new Color (0,0,0);
break;
}
}
}
}
public Rectangle[,] GetMap()
{
return rectMap;
}
public Color[,] GetColors()
{
return arrayColor;
}
}
In the for-loop where you're populating roomList, you're not instantiating a new Room each time. You're simply manipulating the same Room object and re-adding it to the list, so roomList will just contain many references to the same Room object. Try removing the room field from your DungeonGenerate class and use a local variable instead:
for (int i = 0; i < amountOfRooms; i++)
{
bool ok = false;
do
{
var room = new Room();
...
roomList.Add(room);
} while (!ok);
}