So I am coding a small program that takes a users input ie their name and compares what they type to a list of bitmap images that represent the alphabet and are named accordingly ie "A.bmp","B.bmp" and so on. To do the comparison I decided to use a Data Dictionary to hold the image's name and the image itself so that when it found a match to the character of the string it sends the relevant image back to be stored in an bitmap array.
However when i run my "Process" class that does the comparison I get an Index out of bounds exception even though i have my 2 for loops set to stop when they reach the end of their respective data arrays.
I get the error on this line:
pics.Add(namesAndImages[namesAndImages.Keys.ElementAt(i)]);
I have all the images referenced in the solution resources so i dont know if its not actually adding them using the resource manager or if ive missed something.
This is my code for my process class
private void Process()
{
fullName = lblFirst.Text.ToString() + lblLast.Text.ToString();
var nameString = fullName.ToCharArray();
List<System.Drawing.Bitmap> pics = new List<Bitmap>();
Boolean converted = false;
int i, x;
var namesAndImages = new Dictionary<String, Bitmap>();
var resourcesSet = Properties.Resources.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true);
foreach (System.Collections.DictionaryEntry myResource in resourcesSet)
{
if (myResource.Value is Bitmap) //is this resource is associated with an image
{
String resName = myResource.Key.ToString(); //get resource's name
Bitmap resImage = myResource.Value as Bitmap; //get the Image itself
namesAndImages.Add(resName, resImage);
}
}
while (converted == false)
{
for (x = 0; x <= nameString.Length; x++)
{
for (i = 0; i < namesAndImages.Count; i++)
{
if (nameString[x].Equals(namesAndImages.Keys.ElementAt(i)))
{
pics.Add(namesAndImages[namesAndImages.Keys.ElementAt(i)]);
}
}
}
converted = true;
}
String[] imageData = new String[pics.Count];
for (int y = 0; y <= pics.Count; y++)
{
imageData[y] = ConvertImage(pics[y]);
}
output = CombineBitmap(imageData);
}
the combine bitmap class is one that i found that stitches multiple bitmaps together into one single bitmap.
I am guessing this is the line that causes the exception :
for (x = 0; x <= nameString.Length; x++)
it should be
for (x = 0; x < nameString.Length; x++)
You are trying to access one character beyond the length of the string.
Similarly here :
for (int y = 0; y <= pics.Count; y++)
change
for (x = 0; x <= nameString.Length; x++)
to
for (x = 0; x < nameString.Length; x++)
and
for (int y = 0; y <= pics.Count; y++)
to
for (int y = 0; y < pics.Count; y++)
Related
Hello i have a realy strange behavior in this piece of code:
public class IGraphics
{
public int[,] screen;
private int[,] world;
private int[,] entitys;
private int[,] buffer;
private int screenW;
private int screenH;
public IGraphics(int screenW, int screenH) {
this.screenH = screenH;
this.screenW = screenW;
screen = new int[screenW + 1, screenH];
buffer = new int[screenW + 1, screenH];
}
public void loadWorld(int[,] world) {
this.world = world;
}
public void clear() {
screen = new int[screenW + 1, screenH];
world = new int[screenW, screenH];
for (int y = 0; y < world.GetLength(1); y++) {
for (int x = 0; x < world.GetLength(0); x++) {
world[x, y] = 0;
}
}
}
private void loadScreen() {
}
private void updateEntitys()
{
entitys = new int[screenW, screenH];
List<GameObject> EntRow = Common.world.getEntitys();
for (int i = 0; i < EntRow.Count(); i++)
{
entitys[EntRow[i].x, EntRow[i].y] = EntRow[i].Icon;
}
}
public void draw() {
updateEntitys();
for (int y = 0; y < screen.GetLength(1); y++)
{
for (int x = 0; x < screen.GetLength(0) - 1; x++)
{
if (entitys[x, y] == 0)
{
screen[x, y] = world[x, y];
}
else
{
screen[x, y] = entitys[x, y];
}
}
screen[screen.GetLength(0) - 1, y] = 123;
}
if (buffer.Cast<int>().SequenceEqual(screen.Cast<int>()))
{
return;
}
Console.Clear();
buffer = screen;
for (int y = 0; y < screen.GetLength(1); y++) {
for (int x = 0; x < screen.GetLength(0); x++) {
if (screen[x, y] == 123)
{
Console.WriteLine();
}
else {
Console.Write(objectStore.getIcon(screen[x, y]));
}
}
}
}
}
the problem comes in the Draw() function where i set the value of the screen[,] array for some reason it also change the value of the buffer[,] array before the control also tried moving the buffer[,] in a seperate class but i had the same problem.
Someone as an explanation?
When you assign a reference variable to another variable, you copy the pointer to that variable, instead of copying the content, so what you end up with is two variables that point to the same array.
Try to instead copy the array using Clone or copy or something. I think its screen.CopyTo
screen.CopyTo(buffer, 0);
If you look at the body of the method called draw, you will notice this assignment:
buffer = screen;
This is might the cause of the change you noticed.
See the other answers for possible reasons for your problem. However, the following code shows that changing screen[] does not change buffer[]. This kind of effort on your part would allow you to focus your investigation elsewhere. The principle is to first simply.
int counter = 1;
public void draw()
{
for (int y = 0; y < screen.GetLength(1); y++)
{
for (int x = 0; x < screen.GetLength(0) - 1; x++)
{
screen[x, y] = counter++;
}
screen[screen.GetLength(0) - 1, y] = 123;
}
if (buffer.Cast<int>().SequenceEqual(screen.Cast<int>()))
{
MessageBox.Show("Help!");
return;
}
// check again
for (int y = 0; y < screen.GetLength(1); y++)
{
for (int x = 0; x < screen.GetLength(0) - 1; x++)
{
if (screen[x, y] == buffer[x, y])
{
MessageBox.Show("Help two!");
return;
}
}
}
How to assign value in two dimensional array in c#
My Code is
int[,] matarix = new int[4, 5];
for (int x = 0; x < 4; x++)
{
for (int y = 0; y < 5; y++)
{
matarix[x, y] = x+"-"+y;
}
}
i tried above code but its showing error "can't implicitly convert string to int"
How to do it ? Thanks
You're on the right track. Just assign a value.
int[,] matarix = new int[4, 5];
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 5; y++) {
matarix[x, y] = VALUE_HERE;
}
}
One recommendation I would make, would be to use Array.GetLength instead of hard coding your for loops. Your code would become:
int[,] matarix = new int[4, 5];
for (int x = 0; x < matarix.GetLength(0); x++) {
for (int y = 0; y < matarix.GetLength(1); y++) {
matarix[x, y] = VALUE_HERE;
}
}
You pass in one of the array's dimensions, and it tells you how many indices exist for that dimension.
This is a template I usually use for filling up two dimensional arrays.
Its one line and easy to change.
int[,] Foo = new int[4,5];
for(int i=0;i < Foo.Length; i++, Foo[i % Foo.GetLength(0),i / Foo.GetLength(1)] = 0; // Or value to assign
Also please do note that your array is holding integers while you are giving it strings (the "" converts it to a string, while x - y keeps it integer)
Hope it helps
I'm trying to make a 2D RPG game, and would like to use a List< List< Object > > to make a grid in which I store world objects of different types. Only problem is, that I don't know how to get stuff out of this multidimensional List.
The code below creates a multidimensional List and fills it with 'Dirt' Objects (though objects[i] doesnt work, which is my problem).
public List<List<Object>> objects;
this.mapWidth = 36;
this.mapHeight = 21;
this.objects = new List<List<Object>>();
for (int y = 0; y < mapHeight; y++)
{
objects.Add(new List<Object>());
}
for (var i = 0; i < mapWidth; i++)
{
for (var j = 0; j < mapHeight; j++)
{
objects[i].Add(new Dirt());
}
}
The players has a position, e.g. 18,11, which is in the middle of this map/multidimensional List. I would like to check which 'tiles' are around him so I only have to update those things on the map. List[y][x] doesnt work.
I think your initial construction code is incorrect. Looks like you're building your grid to have mapHeight rows and mapheight columns. Rewrite the construction code to be this:
for (var y = 0; y < mapHeight; y++)
{
objects.Add(new List<Object>());
for (var x = 0; x < mapWidth; x++)
{
objects[y].Add(new Dirt());
}
}
EDIT: And I think this will produce a table where your lookup can be achieved by: Object gridEntry = objects[y][x];
EDITx2: If you like, you can rewrite the creation code to this:
for (var y = 0; y < mapHeight; y++)
{
List<Object> currentRow = new List<Object>();
objects.Add(currentRow);
for (var x = 0; x < mapWidth; x++)
{
currentRow.Add(new Dirt());
}
}
Currently working on writing a Conways life in C# for class. I've been taking small steps to get a hang out the language and game programming in general and have hit a snag in printing my 2D char array. Currently I'm using GetLength - 1 to not go over the bound but it fails to print out the last chars in the array.
What my initial file looks like
+*++
++*+
****
After its read into placed into Char (i believe)
*
*
****
What ends up printed
*
**
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
namespace ConwaysLife
{
class Program
{
static char[,] universe;
static void bigBang(int h, int w, List<string> grid)
{
universe = new char[h,w];
int row = 0;
foreach (string line in grid)
{
for (int i = 0; i < line.Length; i++)
{
if (line.ToCharArray()[i] == '*')
{
universe[row, i] = '*';
}
}
row++;
}
}
//How I'm attempting to print out my 2D char array
static void offspring()
{
StringBuilder cellLine = new StringBuilder();
for (int y = 0; y < universe.GetLength(1)-1; y++)
{
for (int x = 0; x < universe.GetLength(0)-1; x++)
{
Console.Write(universe[y, x]);
}
Console.WriteLine();
}
//pause
Console.ReadLine();
}
static void Main(string[] args)
{
List<string> tempLine = new List<string>();
//Console.WriteLine("File Path?");
int width = 0;
int height = 0;
//read file into List
using (StreamReader r = new StreamReader("life.txt"))
{
while (r.Peek() >= 0)
{
tempLine.Add(r.ReadLine());
//compare current width to new width
if (tempLine[height].Length >= width) { width = tempLine[height].Length; }
//increase height when going to next row
height++;
}
bigBang(height, width, tempLine);
}
offspring();
}
}
}
Update Offspring()
static void offspring()
{
StringBuilder cellLine = new StringBuilder();
for (int x = 0; x <= universe.GetLength(1); x++)
{
for (int y = 0; y <= universe.GetLength(0); y++)
{
Console.Write(universe[x, y]);
}
Console.WriteLine();
}
//pause
Console.ReadLine();
}
You have an off-by-one error in your offspring function. Note that you're doing it correctly in the bigBang function.
You are looping while x < GetLength()-1. You just need x < GetLength(), because that excludes the case when x == GetLength().
An analagous loop:
for (i = 0; i < 4; i++)
Console.WriteLine(i);
Output:
0
1
2
3
I'm not familiar with the game principles, but there's a problem in your offspring method.
y < universe.GetLength(1)-1
This translates to y < 3 - 1 or y < 2, making your iteration go from y = 0 to 1.
To fix, simply remove the two occurences of -1.
for (int y = 0; y < universe.GetLength(1); y++)
{
for (int x = 0; x < universe.GetLength(0); x++)
{
In addition, you have your indices reversed when you access universe.
Console.Write(universe[y, x]);
There you're using the y variable to access the row, and x for the column. The inverse should be done like this:
Console.Write(universe[x, y]);
Giving a final output of
++*
*+*
+**
++*
While I'll delve deeper as to why it wasn't working as I expected it to I simply passed the sizes of the array when I created it to my offspring() and used those values when printing. Once that small change was the done the output came out as expected.
*
*
****
I need help with my map editor, I'm stuck on saving it. When I save, after I put some grass on map, it gets grass everywhere in map file.
Here's variables:
mapMaximumX: maximum of the map in X (it is set as 500)
mapMaximumY: maximum of the map in Y (it is also set as 500)
mapTiles[index]: this is a list with class, each class has ID (0 = empty, 1 = grass, 2 = water), X and Y
if (Keyboard.GetState().IsKeyDown(Keys.F1))
{
for(int y = 0; y < mapMaximumY; y++)
{
for (int x = 0; x < mapMaximumX; x++)
{
if (MapTiles[i3].X == x && MapTiles[i3].Y == y)
{
}
else
{
MapTiles.Add(new Class1(0, x * 32, y * 32));
}
if (i3 < MapTiles.Count)
{
i3++;
}
}
}
TextWriter file = new StreamWriter("map1.MAP");
for (int y = 0; y < mapMaximumY; y++)
{
for (int x = 0; x < mapMaximumX; x++)
{
file.Write(MapTiles[i2].ID + ", ");
}
file.Write(file.NewLine);
}
i2 = 0;
System.Windows.Forms.MessageBox.Show("Saved!");
file.Close();
}
Full code is here, if u need it:
http://pastebin.com/qrWbuPtb
Thanx.
file.Write(MapTiles[i2].ID + ", ");
i2 never changes within your loop, so whatever i2 is will always be what's used to write your output.
You need to be using X and Y from your loops in determining which cell to write out.