Rectangle ArgumentOutOfRangeException Per-Pixel Collision - c#

I've been trying to solve this problem but I really can't see what's wrong with the code. It's exactly the same as my other rectangles but it won't work.
Working Code: Everything in here works fine (more or less)
private void UpdateCollision()
{
// Uses built in rectangle intersect function to determine overlapping
Rectangle rectangle1;
Rectangle rectangle2;
Rectangle rectangle3;
// Creates 1 rectangle for player
rectangle1 = new Rectangle((int)player.Position.X, (int)player.Position.Y, player.Width, player.Height);
// Sets collision btw objs
for (int i = 0; i < enemies.Count; i++)
{
for (int j = 0; j < enemies2.Count; j++)
{
rectangle2 = new Rectangle((int)enemies[i].Position.X, (int)enemies[i].Position.Y, enemies[i].Width, enemies[i].Height);
rectangle3 = new Rectangle((int)enemies2[j].Position.X, (int)enemies2[j].Position.Y, enemies2[j].Width, enemies2[j].Height);
// Determines collision
if (IntersectPixels(rectangle1, playerTextureData, rectangle2, enemyTextureData) && player.PlayerAnimation.Active == true)
{
player.Health -= enemies[i].Damage;
enemies[i].Health = 0;
if (player.Health == 0)
AddMyExplosion(player.Position);
}
if (IntersectPixels(rectangle1, playerTextureData, rectangle3, enemy2TextureData) && player.PlayerAnimation.Active == true)
{
player.Health -= enemies2[j].Damage;
enemies2[j].Health = 0;
if (player.Health == 0)
AddMyExplosion(player.Position);
}
}
}
Non-working Code: The line where the exception pops up is where rectangle3 is defined
// Proj obj collision
for (int i = 0; i < projectiles.Count; i++)
{
for (int j = 0; j < enemies.Count; j++)
{
for (int k = 0; k < enemies2.Count; k++)
{
// Creates col det rectangles
rectangle1 = new Rectangle((int)projectiles[i].Position.X - projectiles[i].Width / 2, (int)projectiles[i].Position.Y - projectiles[i].Height / 2, projectiles[i].Width, projectiles[i].Height);
rectangle2 = new Rectangle((int)enemies[j].Position.X - enemies[j].Width / 2, (int)enemies[j].Position.Y - enemies[j].Height / 2, enemies[j].Width, enemies[j].Height);
rectangle3 = new Rectangle((int)enemies2[k].Position.X - enemies2[k].Width / 2, (int)enemies[k].Position.Y - enemies2[k].Height / 2, enemies2[k].Width, enemies2[k].Height);
//Rectangle 3 is not working//
// Determines col
if (IntersectPixels(rectangle1, projectileTextureData, rectangle2, enemyTextureData))
{
enemies[j].Health -= projectiles[i].Damage;
AddImpact(projectiles[i].Position);
impactSound.Play();
projectiles[i].Active = false;
}
if (IntersectPixels(rectangle1, projectileTextureData, rectangle3, enemy2TextureData))
{
enemies2[j].Health -= projectiles[i].Damage;
AddImpact(projectiles[i].Position);
impactSound.Play();
projectiles[i].Active = false;
}
}
}
}
}
So if anyone could help me solve this I would be very grateful.

Typo. Change this line:
rectangle3 = new Rectangle((int)enemies2[k].Position.X - enemies2[k].Width / 2, (int)enemies[k].Position.Y - enemies2[k].Height / 2, enemies2[k].Width, enemies2[k].Height);
to this:
rectangle3 = new Rectangle((int)enemies2[k].Position.X - enemies2[k].Width / 2, (int)enemies2[k].Position.Y - enemies2[k].Height / 2, enemies2[k].Width, enemies2[k].Height);

Related

c# How to determine possible horsesteps in a(2dim array)?

//Make a method: void MogelijkePaardenSprongen(int[,] schaakbord, Positie positie) This method determines the possible positions where the Horse can jump (value 2). Of course, you do this in a smart way ( with a LOOP). Please note, there are not always 8 possibilities! The parameter position indicates where the horse is located. Test the methods (call from the Start method like the image below?
// this is the code that i have got for so far,
static void Main(string[] args)
{
Program myProgram = new Program();
myProgram.Start();
Console.ReadKey();
}
void Start()
{
int [,] schaakbord = new int [8, 8];
InitSchaakbord(schaakbord);
ToonSchaakBord(schaakbord);
}
void InitSchaakbord(int[,] schaakbord)
{
int leeg = 0;
int bezet = 1;
int mogelijkbezet = 2;
for (int i=0; i<schaakbord.GetLength(0); i++)
{
for (int j=0; j<schaakbord.GetLength(1); j++)
{
schaakbord[i, j] = leeg;
}
}
}
void ToonSchaakBord(int[,] schaakbord)
{Positie positie = new Positie();
for (int i = 0; i < schaakbord.GetLength(0); i++)
{Plaatspaard(schaakbord);
for (int j = 0; j < schaakbord.GetLength(1); j++)
{
if (schaakbord[i, j] == 0)
{
Console.Write(".");
}
else if (schaakbord[i, j] == 1)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("*");
Console.ResetColor();
}
else if (schaakbord[i, j]==2)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("*");
Console.ResetColor();
}
Console.Write(" ");
}
Console.WriteLine();
MogelijkePaardenSprongen(schaakbord, positie);
}
}
Positie Plaatspaard(int [,] schaakbord)
{Positie x = new Positie();
Random rnd = new Random();
x.waarde1 = rnd.Next(1, 8);
x.waarde2 = rnd.Next(1, 8);
for (int i = 0; i<schaakbord.GetLength(0);i++ )
{
for (int j=0; j<schaakbord.GetLength(1); j++)
{
if (x.waarde1 == i && x.waarde2 == j)
schaakbord[i, j] = 1;
}
}
return x;
}
class Positie
{
public int waarde1;
public int waarde2;
}
void MogelijkePaardenSprongen(int[,] schaakbord, Positie positie)
{
for (int i =0; i<schaakbord.GetLength(0); i++)
{
for (int j=0; j<schaakbord.GetLength(1); j++)
{
/// possible horsesteps?
/// call from void start method
if (schaakbord[i, j] == 0)
{
}
}
}
Because its assignment I don't want to give you straight whole solution. Please don't hesitate to comment if you need more help.
My suggestion is to create object
class MoveOffset
{
public int OffsetX { get; set; }
public int OffsetY { get; set; }
}
then create collection of them with possible moves
var moves = new List<MoveOffset>()
{
new MoveOffset(){OffsetX = -1, OffsetY = -2},
new MoveOffset(){OffsetX = -2, OffsetY = -1},
new MoveOffset(){OffsetX = 1, OffsetY = -2},
new MoveOffset(){OffsetX = -2, OffsetY = 1},
new MoveOffset(){OffsetX = -1, OffsetY = 2},
new MoveOffset(){OffsetX = 2, OffsetY = -1},
new MoveOffset(){OffsetX = 1, OffsetY = 2},
new MoveOffset(){OffsetX = 2, OffsetY = 1},
};
then cycle through collection and check conditions if its possible to move there from 'horse' location .
Please note that horsestep actually means that the sum of the distances
between that point and the horse should exactly be 3.
Example:
var distanceX = abs(Horse.Position.X - i);
var distanceY = abs(Horse.Position.Y - j);
bool isHorseStep = distanceX + distanceY == 3;
So you can use that assumption in your code to check if it's a horse step or not.
Here is some quickly-written code for your method.
I have not tested it but I guess you'll get the point and do adjustments if needed:
void MogelijkePaardenSprongen(int[,] schaakbord, Positie positie)
{
for (int i =0; i<schaakbord.GetLength(0); i++)
{
for (int j=0; j<schaakbord.GetLength(1); j++)
{
/// possible horsesteps?
/// call from void start method
if (schaakbord[i, j] == 0)
{
var deltaX = waarde1 - i;
var deltaY = waarde2 - j;
if (deltaX < -2 || deltaX > 2
|| deltaY < -2 || deltaY > 2 )
{
// TODO: Write logic here for out of bounds.
}
else
{
if (abs(deltaX) + abs(deltaY) == 3)
{
// TODO: Horse Step. Write your logic here.
}
}
}
}
}
}
P.S. Also for deltaY you might need to reverse the number and use something like this deltaY = j - waarde2, as the Y axis is opposite in the array.

It's possible to write neural network for different size of training data inputs and outputs

It's possible to write neural network for different size of training data inputs and outputs
for example:
inputs are 1. (1,2,3,4) , 2. (2,3,1), 3. (1,2,3,4,5) and so on...
and the same for outputs 1. (0,0,1,1) 2. (1,1,1) 3. (0,0,1,1,1)
So far I have managed to write the one which only works with the same size of training data which mean that all my training data needs to have the same length.
So far I'm stuck with this
NeuralNetwork net;
int[] layers = new int[3]
{
3/*Always the same*/,
1/*Always the same*/,
3 /*Always the same*/
};
string[] activation = new string[2] { "leakyrelu", "leakyrelu" };
net = new NeuralNetwork(layers, activation);
What I need
NeuralNetwork net1;
int[] layers1 = new int[3]
{
input.Length /*Based on input's Length*/,
1/*Always the same*/,
output.Length /*Based on output's Length*/
};
string[] activation1 = new string[2] { "leakyrelu", "leakyrelu" };
net = new NeuralNetwork(layers, activation);
// BackPropagate
public void BackPropagate(float[] inputs, float[] expected)
{
float[] output = FeedForward(inputs);
cost = 0;
for (int i = 0; i < output.Length; i++) cost += (float)Math.Pow(output[i] - expected[i], 2);
cost = cost / 2;
float[][] gamma;
List<float[]> gammaList = new List<float[]>();
for (int i = 0; i < layers.Length; i++)
{
gammaList.Add(new float[layers[i]]);
}
gamma = gammaList.ToArray();
int layer = layers.Length - 2;
for (int i = 0; i < output.Length; i++)
gamma[layers.Length-1][i] = (output[i] - expected[i]) * activateDer(output[i],layer);
for (int i = 0; i < neurons[layers.Length - 1].Length; i++)
{
biases[layers.Length - 1][i] -= gamma[layers.Length - 1][i] * learningRate;
for (int j = 0; j < neurons[layers.Length - 2].Length; j++)
{
weights[layers.Length - 2][i][j] -= gamma[layers.Length - 1][i] * neurons[layers.Length-2][j] * learningRate;
}
}
for (int i = layers.Length - 2; i > 0; i--)
{
layer = i - 1;
for (int j = 0; j < neurons[i].Length; j++)
{
gamma[i][j] = 0;
for (int k = 0; k < gamma[i+1].Length; k++)
{
gamma[i][j] = gamma[i + 1][k] * weights[i][k][j];
}
gamma[i][j] *= activateDer(neurons[i][j],layer);
}
for (int j = 0; j < neurons[i].Length; j++)
{
biases[i][j] -= gamma[i][j] * learningRate;
for (int k = 0; k < neurons[i-1].Length; k++)
{
weights[i - 1][j][k] -= gamma[i][j] * neurons[i-1][k] * learningRate;
}
}
}
}

How can I generate Blanking and sync signal based on my code?

I do not know how to generate the Blanking and Sync signal for my PAL signal. I am working directly with pixel values from an image, and putting them into the formulas from the standard.
I took the pixel R, G and B values and computed the luminance Y.
I tried to make the sync and blanking signal manual but with no results.
//load values
float[,] rValues = new float[picture1.Width, picture1.Height];
float[,] gValues = new float[picture1.Width, picture1.Height];
float[,] bValues = new float[picture1.Width, picture1.Height];
using (Bitmap bmp = new Bitmap(picture1))
{
for (int i=0;i<bmp.Width;i++)
{
for(int j=0;j<bmp.Height;j++)
{
Color clr = bmp.GetPixel(i, j);
rValues[i, j] = clr.R;
gValues[i, j] = clr.G;
bValues[i, j] = clr.B;
}
}
}
//changing the matrices into 1d arrays
----------
double[] r = new double[picture1.Height * picture1.Width];
double[] g = new double[picture1.Height * picture1.Width];
double[] b = new double[picture1.Height * picture1.Width];
int k = 0;
for (int i = 0; i < picture1.Height; i++)
{
for (int j = 0; j < picture1.Width; j++)
{
r[k] = rValues[j, i];
g[k] = gValues[j, i];
b[k] = bValues[j, i];
k++;
}
}
// calculating the luminance Y
double[] Y = new double[picture1.Height * picture1.Width];
for (int i=0; i < Y.Length; i++)
{
Y[i] = 0.3 * r[i] + 0.59 * g[i] + 0.11 * b[i];
}
// trying to make a manual signal
double[] sync = new double[135];
for (int i = 0; i < 135; i++)
{
if (i < 17)
{
sync[i] = 0;
}
if (i > 16 && i < 70)
{
sync[i] = -0.3;
}
if (i > 69)
{
sync[i] = 0;
}
}

How to make this more clean

I have a big part of code like this that iterate trough an array
void GetSpawnablePosition() {
Vector2[] coordX = { Vector2.up, Vector2.down };
Vector2[] coordY = { Vector2.left, Vector2.right };
for (int i = 0; i < coordY.Length; i++)
{
Vector2[] newArray = new Vector2[enemyGrid.grid[0].Length - 2];
if (coordY[i] == Vector2.left)
{
for (int j = 0; j < enemyGrid.grid[0].Length - 2; j++)
{
newArray[j] = new Vector2(0, j+1);
}
}
if (coordY[i] == Vector2.right)
{
for (int j = 0; j < enemyGrid.grid[0].Length - 2; j++)
{
newArray[j] = new Vector2(enemyGrid.grid[0].Length - 1, j + 1);
}
}
spawnablePosition.Add(coordY[i], newArray);
}
for (int i = 0; i < coordY.Length; i++)
{
Vector2[] newArray = new Vector2[enemyGrid.grid.Length - 1];
if (coordX[i] == Vector2.down)
{
for (int j = 0; j <= enemyGrid.grid.Length - 2; j++)
{
newArray[j] = new Vector2(j+1,0);
}
}
if (coordX[i] == Vector2.up)
{
for (int j = 0; j <= enemyGrid.grid.Length - 2; j++)
{
newArray[j] = new Vector2(j + 1, enemyGrid.grid[0].Length - 1);
}
}
spawnablePosition.Add(coordX[i], newArray);
}
}
The snippet is supposed to take the index x and y of a grid
and
put it in a dictionary like this
Vector2.up => [[0][1],[0][2],[0][3],[0][4],[0][5]]
Vector2.left=> [[1][0],[2][0],[3][0],[4][0],[5][0]]
Vector2.right=> [[1][6],[2][6],[3][6],[4][6],[5][6]]
Vector2.down=> [[6][1],[6][2],[6][3],[6][4],[6][5]]
I tried to refactor it to make it smaller or more clear, but really, I honestly can't find a good solution that make that big thing smaller.
Can someone help me ?
Something like:
var yLength = enemyGrid.grid[0].Length;
var xLength = enemyGrid.grid.Length;
spawnablePosition.Add(Vector2.left, Enumerable.Range(1, yLength).Select(y => new Vector2(0, y)).ToArray());
spawnablePosition.Add(Vector2.right, Enumerable.Range(1, yLength).Select(y => new Vector2(xLength - 1, y)).ToArray());
spawnablePosition.Add(Vector2.up, Enumerable.Range(1, xLength).Select(x => new Vector2(x, 0)).ToArray());
spawnablePosition.Add(Vector2.down, Enumerable.Range(1, xLength).Select(x => new Vector2(x, yLength - 1)).ToArray());
Ensure that I don't mess with corresponding array lengths.

Neural network [ocr]

I come looking for general tips about the program I'm writing now.
The goal is:
Use neural network program to recognize 3 letters [D,O,M] (or display "nothing is recognized" if i input anything other than those 3).
Here's what I have so far:
A class for my single neuron
public class neuron
{
double[] weights;
public neuron()
{
weights = null;
}
public neuron(int size)
{
weights = new double[size + 1];
Random r = new Random();
for (int i = 0; i <= size; i++)
{
weights[i] = r.NextDouble() / 5 - 0.1;
}
}
public double output(double[] wej)
{
double s = 0.0;
for (int i = 0; i < weights.Length; i++) s += weights[i] * wej[i];
s = 1 / (1 + Math.Exp(s));
return s;
}
}
A class for a layer:
public class layer
{
neuron[] tab;
public layer()
{
tab = null;
}
public layer(int numNeurons, int numInputs)
{
tab = new neuron[numNeurons];
for (int i = 0; i < numNeurons; i++)
{
tab[i] = new neuron(numInputs);
}
}
public double[] compute(double[] wejscia)
{
double[] output = new double[tab.Length + 1];
output[0] = 1;
for (int i = 1; i <= tab.Length; i++)
{
output[i] = tab[i - 1].output(wejscia);
}
return output;
}
}
And finally a class for a network
public class network
{
layer[] layers = null;
public network(int numLayers, int numInputs, int[] npl)
{
layers = new layer[numLayers];
for (int i = 0; i < numLayers; i++)
{
layers[i] = new layer(npl[i], (i == 0) ? numInputs : (npl[i - 1]));
}
}
double[] compute(double[] inputs)
{
double[] output = layers[0].compute(inputs);
for (int i = 1; i < layers.Length; i++)
{
output = layers[i].compute(output);
}
return output;
}
}
Now for the algorythm I chose:
I have a picture box, size 200x200, where you can draw a letter (or read one from jpg file).
I then convert it to my first array(get the whole picture) and 2nd one(cut the non relevant background around it) like so:
Bitmap bmp2 = new Bitmap(this.pictureBox1.Image);
int[,] binaryfrom = new int[bmp2.Width, bmp2.Height];
int minrow=0, maxrow=0, mincol=0, maxcol=0;
for (int i = 0; i < bmp2.Height; i++)
{
for (int j = 0; j < bmp2.Width; j++)
{
if (bmp2.GetPixel(j, i).R == 0)
{
binaryfrom[i, j] = 1;
if (minrow == 0) minrow = i;
if (maxrow < i) maxrow = i;
if (mincol == 0) mincol = j;
else if (mincol > j) mincol = j;
if (maxcol < j) maxcol = j;
}
else
{
binaryfrom[i, j] = 0;
}
}
}
int[,] boundaries = new int[binaryfrom.GetLength(0)-minrow-(binaryfrom.GetLength(0)-(maxrow+1)),binaryfrom.GetLength(1)-mincol-(binaryfrom.GetLength(1)-(maxcol+1))];
for(int i = 0; i < boundaries.GetLength(0); i++)
{
for(int j = 0; j < boundaries.GetLength(1); j++)
{
boundaries[i, j] = binaryfrom[i + minrow, j + mincol];
}
}
And convert it to my final array of 12x8 like so (i know I could shorten this a fair bit, but wanted to have every step in different loop so I can see what went wrong easier[if anything did]):
int[,] finalnet = new int[12, 8];
int k = 1;
int l = 1;
for (int i = 0; i < finalnet.GetLength(0); i++)
{
for (int j = 0; j < finalnet.GetLength(1); j++)
{
finalnet[i, j] = 0;
}
}
while (k <= finalnet.GetLength(0))
{
while (l <= finalnet.GetLength(1))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * (k - 1); i < (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * k; i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * (l - 1); j < (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * l; j++)
{
if (boundaries[i, j] == 1) finalnet[k-1, l-1] = 1;
}
}
l++;
}
l = 1;
k++;
}
int a = boundaries.GetLength(0);
int b = finalnet.GetLength(1);
if((a%b) != 0){
k = 1;
while (k <= finalnet.GetLength(1))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * finalnet.GetLength(0); i < boundaries.GetLength(0); i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * (k - 1); j < (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * k; j++)
{
if (boundaries[i, j] == 1) finalnet[finalnet.GetLength(0) - 1, k - 1] = 1;
}
}
k++;
}
}
if (boundaries.GetLength(1) % finalnet.GetLength(1) != 0)
{
k = 1;
while (k <= finalnet.GetLength(0))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * (k - 1); i < (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * k; i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * finalnet.GetLength(1); j < boundaries.GetLength(1); j++)
{
if (boundaries[i, j] == 1) finalnet[k - 1, finalnet.GetLength(1) - 1] = 1;
}
}
k++;
}
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * finalnet.GetLength(0); i < boundaries.GetLength(0); i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * finalnet.GetLength(1); j < boundaries.GetLength(1); j++)
{
if (boundaries[i, j] == 1) finalnet[finalnet.GetLength(0) - 1, finalnet.GetLength(1) - 1] = 1;
}
}
}
The result is a 12x8 (I can change it in the code to get it from some form controls) array of 0 and 1, where 1 form the rough shape of a letter you drawn.
Now my questions are:
Is this a correct algorythm?
Is my function
1/(1+Math.Exp(x))
good one to use here?
What should be the topology? 2 or 3 layers, and if 3, how many neurons in hidden layer? I have 96 inputs (every field of the finalnet array), so should I also take 96 neurons in the first layer? Should I have 3 neurons in the final layer or 4(to take into account the "not recognized" case), or is it not necessary?
Thank you for your help.
EDIT: Oh, and I forgot to add, I'm gonna train my network using Backpropagation algorythm.
You may need 4 layers at least to get accurate results using back propagation method. 1 input, 2 middle layers, and an output layer.
12 * 8 matrix is too small(and you may end up in data loss which will result in total failure) - try some thing 16 * 16. If you want to reduce the size then you have to peel out the outer layers of black pixels further.
Think about training the network with your reference characters.
Remember that you have to feed back the output back to the input layer again and iterate it multiple times.
A while back I created a neural net to recognize digits 0-9 (python, sorry), so based on my (short) experience, 3 layers are ok and 96/50/3 topology will probably do a good job. As for the output layer, it's your choice; you can either backpropagate all 0s when the input image is not a D, O or M or use the fourth output neuron to indicate that the letter was not recognized. I think that the first option would be the best one because it's simpler (shorter training time, less problems debugging the net...), you just need to apply a threshold under which you classify the image as 'not recognized'.
I also used the sigmoid as activation function, I didn't try others but it worked :)

Categories

Resources