argument out of range exception in a memory puzzle game - c#

I'm following along a course on udemy which is for free it's a memory game (https://www.udemy.com/xamarin-native-ios-memory-game-csharp/learn/v4/overview)
Now with the randomizer method i get a new problem with the same out of range error
using System;
using System.Collections;
using System.Collections.Generic;
using UIKit;
namespace iOSMemoryGame
{
public partial class ViewController : UIViewController
{
#region vars
List<String> imgArr = new List<String>();
float gameViewWidth;
int gridSize = 6;
ArrayList tilesArr = new ArrayList();
ArrayList coordsArr = new ArrayList();
#endregion
public ViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
// make sure Game View is Laid Out
gameView.LayoutIfNeeded();
gameViewWidth = (float)gameView.Frame.Size.Width;
// let's load all of our images into an array
for (int i = 1; i <= 18; i++)
{
imgArr.Add("img_" + i.ToString() + ".png");
}
// let's make a call to tileMaker
tileMaker();
// let's call the randomizer
randomizer();
}
private void randomizer()
{
// we are gonna go through our tiles in ORDER
// and we are gonna assign a new center to them RANDOMLY
foreach (UIView any in tilesArr)
{
// UIImageView thisTile = (UIImageView)tilesArr[i];
Random myRand = new Random();
int randomIndex = myRand.Next(0, coordsArr.Count);
CoreGraphics.CGPoint newRandCenter = (CoreGraphics.CGPoint)coordsArr[randomIndex];
any.Center = newRandCenter;
coordsArr.RemoveAt(randomIndex);
}
}
private void tileMaker()
{
float tileWidth = gameViewWidth / gridSize;
float xCenter = tileWidth / 2;
float yCenter = tileWidth / 2;
int imgCounter = 0;
for (int h = 0; h < gridSize; h++)
{
for (int v = 0; v < gridSize; v++)
{
UIImageView tileImgView = new UIImageView();
CoreGraphics.CGPoint newCenter = new CoreGraphics.CGPoint(xCenter, yCenter);
tileImgView.Frame = new CoreGraphics.CGRect(0, 0, tileWidth - 5, tileWidth - 5);
String imgName = imgArr[imgCounter];
tileImgView.Image = new UIImage(imgName);
tileImgView.Center = newCenter;
// user CAN interact with this image view
tileImgView.UserInteractionEnabled = true;
// adding the new image view to the array
tilesArr.Add(tileImgView);
gameView.AddSubview(tileImgView);
xCenter = xCenter + tileWidth;
imgCounter++;
if (imgCounter == gridSize * gridSize / 2)
{
imgCounter = 0;
}
}
xCenter = tileWidth / 2;
yCenter = yCenter + tileWidth;
}
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
partial void Rst4Button_TouchUpInside(UIButton sender)
{
throw new NotImplementedException();
}
partial void Rst6Button_TouchUpInside(UIButton sender)
{
throw new NotImplementedException();
}
}
}
Something is wrong with the randomizer method but i dont know what.
it gives me again a out of range error.
without the randomizer method it works fine

This line
for (int i = 1; i < 18; i++)
creates 17 images, not 18 as expected by the following loops.
// 0-5 = 6 loops
for (int h = 0; h < gridSize; h++)
{
// 0-5 = 6 loops (h*v=18)
for (int v = 0; v < gridSize; v++)
{
....
You need to write
for (int i = 0; i < 18; i++)
imgArr.Add("img_" + (i+1).ToString() + ".png");

Related

Mendelbrot Calculation Code Keeps Returning 2 for IterationCount

I'm working on writing a Mendelbrot renderer in C# to practice multithreading, but am having an issue where my calculation code maxes out at 2 iterations. I don't really understand why since the online references I've been looking at seem to calculate it the same way as me. No matter what coordinates of pixels I provide, it always returns 2 (aside from 0,0 and 0,1).
`
using System;
using System.Numerics;
using SkiaSharp;
namespace Mandelbrot
{
internal class Program
{
const int MaxIterations = 100;
static void Main(string[] args)
{
int size = 250;
int[,] grid = Run(size, 0, 0, 1);
// Console.WriteLine("Please specify a square size for the image.");
// try
// {
// Console.Write("Length: ");
// height = Int32.Parse(Console.ReadLine());
// }
// catch (FormatException e)
// {
// Console.WriteLine(e);
// throw;
// }
using (var surface = SKSurface.Create(width: size, height: size, SKColorType.Rgba8888, SKAlphaType.Premul))
{
SKCanvas canvas = surface.Canvas;
canvas.DrawColor(SKColors.Coral);
for (int i = 0; i < grid.GetLength(0); i++)
{
for (int j = 0; j < grid.GetLength(1); j++)
{
if (grid[i, j] >= MaxIterations)
canvas.DrawPoint(new SKPoint(i, j), SKColors.Black);
}
}
canvas.DrawPoint(new SKPoint(250, 250), SKColors.Chartreuse);
OutputImage(surface);
}
Console.WriteLine("Program successfully completed.");
}
public static int[,] Run(int size, int fromX, int fromY, int h)
{
int[] oulltput = new int[size * size];
int[,] output = new int[size, size];
for (int i = 0; i < output.GetLength(0); i += 1)
{
for (int j = 0; j < output.GetLength(1); j += 1)
{
float x = fromX + i * h;
float y = fromY + j * h;
output[i, j] = IterCount(x, y, MaxIterations);
}
}
return output;
}
public static int IterCount(float constX, float constY, int maxIterations)
{
const float maxMagnitude = 2f;
const float maxMagnitudeSquared = maxMagnitude * maxMagnitude;
int i = 0;
float x = 0.0f, y = 0.0f;
float xSquared = 0.0f, ySquared = 0.0f;
while (xSquared + ySquared <= maxMagnitudeSquared && i < maxIterations)
{
xSquared = x * x;
ySquared = y * y;
float xtmp = xSquared - ySquared + constX;
y = 2.0f * x * y + constY;
x = xtmp;
i++;
}
return i;
}
private static void OutputImage(SKSurface surface)
{
Console.WriteLine("Attempting to write .png to disk...");
using (var image = surface.Snapshot())
using (var data = image.Encode(SKEncodedImageFormat.Png, 80))
using (var stream = File.OpenWrite("out.png"))
{
// save the data to a stream
data.SaveTo(stream);
Console.WriteLine("Success!");
}
}
}
}
`
I tried to use breakpoints and writeline statements to debug but I can't figure out where my math is going wrong. I keep getting 2 for my iteration count.

Size issues when creating a procedural mesh generator in Unity

I've been working on building a procedural generator for Unity, that takes in noise and uses it to build a height map.
So far, everything seems to work as long as I limit the size of the mesh to around 250x250. If I attempt to make a larger mesh, the script won't calculate it.
The puzzling thing is that I get no memory errors or anything of that nature. I've implemented a Regenerate button that allows me to generate a new mesh in Unity and as long as I remain in the range of 250x250 or less, it works fine. If I pick a larger value, the mesh simply remains unchanged.
How I calculate the Mesh:
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(Noise))]
public class CustomTerrain : MonoBehaviour {
//Note: sizeX*sizeZ determines mesh size.
public int sizeX = 4; //These values are public so they can be
public int sizeZ = 4; //modified in the Unity Editor.
public float noiseSize = 1.0f;
public float cellSize = 1.0f;
private string mPath = "Assets/Generated/";
Noise noise;
void Start() {
noise = GetComponent<Noise>();
this.LoadMesh();
if (!GetComponent<MeshFilter>().sharedMesh) {
this.Regenerate();
}
}
public void LoadMesh() {
Mesh mesh = Instantiate(AssetDatabase.LoadMainAssetAtPath(mPath + gameObject.name + ".asset") as Mesh);
if (mesh) {
GetComponent<MeshFilter>().mesh = mesh;
}
recalculateMeshCollider(mesh);
}
Vector3[] GenVertices() {
float x, z;
int w = (sizeX+1);
int l = (sizeZ+1);
Vector3[] vertices = new Vector3[w*l];
for (int gx = 0; gx < w; gx++) {
for (int gz = 0; gz < l; gz++) {
x = gx*cellSize;
z = gz*cellSize;
float height = (noiseSize * noise.Get(x,z));
vertices[gx*l+gz] = new Vector3(x, height, z);
}
}
return vertices;
}
int[] GenTriangles() {
int vertciesPerTriangle = 3;
int trianglesPerCell = 2;
int numberCells = sizeX * sizeZ;
int[] triangles = new int[vertciesPerTriangle * trianglesPerCell * numberCells];
int tIndeX = 0;
for (int cX = 0; cX < sizeX; cX++) {
for (int cZ = 0; cZ < sizeZ; cZ++) {
int n = cX*(sizeZ+1)+cZ;
triangles[tIndeX] = n;
triangles[tIndeX+1] = n+1;
triangles[tIndeX+2] = n+sizeZ+2;
triangles[tIndeX+3] = n;
triangles[tIndeX+4] = n+sizeZ+2;
triangles[tIndeX+5] = n+sizeZ+1;
tIndeX +=6;
}
}
return triangles;
}
Vector2[] GenUVs() {
int w = (sizeX + 1);
int l = (sizeZ + 1);
Vector2[] uvs = new Vector2[w * l];
for (int uX = 0; uX < w; uX++) {
for (int uZ = 0; uZ < l; uZ++) {
uvs[uX*l+uZ] = new Vector2((float)uX/sizeX, (float)uZ/sizeZ);
}
}
return uvs;
}
}
My Regenerate function:
public void Regenerate() {
noise.Init();
Mesh mesh = GetComponent<MeshFilter>().sharedMesh;
if(!mesh) {
mesh = new Mesh();
GetComponent<MeshFilter>().sharedMesh = mesh;
}
mesh.vertices = GenVertices();
mesh.triangles = GenTriangles();
mesh.uv = GenUVs();
mesh.RecalculateNormals();
recalculateMeshCollider(mesh);
}
public void recalculateMeshCollider(Mesh mesh) {
if (GetComponent<MeshCollider>()) {
DestroyImmediate(GetComponent<MeshCollider>());
}
transform.gameObject.AddComponent<MeshCollider>();
transform.GetComponent<MeshCollider>().sharedMesh = mesh;
}
By "250x250" do you mean there's 62.400 triangles?
Unity has a vertex limit of 65535 count - just use more than one mesh, no trouble.

C# XNA Tile engine drawing wrong tiles

I'm building a tile engine for my first game ever and i've been following a guide step by step (can't link it because i'm limited to 2). I have however, made a few modifications to the tilemap so that i can continue with my project.
And while testing my program a noticed a bug that i was hoping you guys could help me resolve...
...The tile engine is drawing the wrong tiles!
This is my TileMap (with numbers assigned to each tile) and this is what my engine draws.
While it should follow the order as seen below (the code is self-explanatory)
rows[0].columns[3].tileID = 0;
rows[0].columns[4].tileID = 1;
rows[0].columns[5].tileID = 2;
rows[0].columns[6].tileID = 3;
rows[0].columns[7].tileID = 4;
rows[1].columns[3].tileID = 5;
rows[1].columns[4].tileID = 6;
rows[1].columns[5].tileID = 7;
rows[1].columns[6].tileID = 8;
rows[1].columns[7].tileID = 9;
rows[2].columns[3].tileID = 10;
rows[2].columns[4].tileID = 11;
rows[2].columns[5].tileID = 12;
rows[2].columns[6].tileID = 13;
rows[2].columns[7].tileID = 14;
rows[3].columns[3].tileID = 15;
rows[3].columns[4].tileID = 16;
rows[3].columns[5].tileID = 17;
rows[3].columns[6].tileID = 18;
rows[3].columns[7].tileID = 19;
rows[4].columns[3].tileID = 20;
rows[4].columns[4].tileID = 21;
rows[4].columns[5].tileID = 22;
rows[4].columns[6].tileID = 23;
rows[4].columns[7].tileID = 24;
rows[5].columns[3].tileID = 25;
rows[5].columns[4].tileID = 26;
rows[5].columns[5].tileID = 27;
rows[5].columns[6].tileID = 28;
rows[5].columns[7].tileID = 29;
Code Essentials
The Important parts of my code
Tile.class
Where i define the tile size and have a function which navigates the tilemap to find my deiserd tile.
namespace TileEngine
{
static class Tile
{
static public Texture2D tileSetTexture;
static public int tileWidth = 48;
static public int tileHeight = 48;
static public Rectangle getSourceRectangle(int tileIndex)
{
int tileY = tileIndex / (tileSetTexture.Width / tileWidth);
int tileX = tileIndex % (tileSetTexture.Height / tileHeight);
return new Rectangle(tileX * tileWidth, tileY * tileHeight, tileWidth, tileHeight);
}
}
}
MapCell
Where i define the tileID
class MapCell
{
public List<int> baseTiles = new List<int>();
public int tileID
{
get { return baseTiles.Count > 0 ? baseTiles[0] : 0; }
set
{
if (baseTiles.Count > 0)
baseTiles[0] = value;
else
addBaseTile(value);
}
}
public void addBaseTile(int tileID)
{
baseTiles.Add(tileID);
}
public MapCell(int tileID)
{
this.tileID = tileID;
}
}
TileMap
Where i build the map
class MapRow
{
public List<MapCell> columns = new List<MapCell>();
}
class TileMap
{
public List<MapRow> rows = new List<MapRow>();
public int mapWidth = 50;
public int mapHeight = 50;
public TileMap()
{
for (int y = 0; y < mapHeight; y++)
{
MapRow thisRow = new MapRow();
for (int x = 0; x < mapWidth; x++)
{
thisRow.columns.Add(new MapCell(0));
}
rows.Add(thisRow);
}
}
}
Draw
And lastly my draw code.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
Vector2 firstSquare = new Vector2(Camera.location.X / Tile.tileWidth, Camera.location.Y / Tile.tileHeight);
int firstX = (int)firstSquare.X;
int firstY = (int)firstSquare.Y;
Vector2 squareOffset = new Vector2(Camera.location.X % Tile.tileWidth, Camera.location.Y % Tile.tileHeight);
int offsetX = (int)squareOffset.X;
int offsetY = (int)squareOffset.Y;
for (int y = 0; y < squaresDown; y++)
{
for (int x = 0; x < squaresAcross; x++)
{
foreach (int tileID in myMap.rows[y + firstY].columns[x + firstX].baseTiles)
{
spriteBatch.Draw(
Tile.tileSetTexture,
new Rectangle(
(x * Tile.tileWidth) - offsetX, (y * Tile.tileHeight) - offsetY,
Tile.tileWidth, Tile.tileHeight),
Tile.getSourceRectangle(tileID),
Color.White);
}
}
}
spriteBatch.End();
base.Draw(gameTime);
}

Drawing polygon

I want to realize method "Draw" of class Polygon
I have WindForms project, form, and the pictureBox1,
I want that "Draw" drawing polygon in pictureBox1 and I have opportunity to move image
I don't konw how to realize it. Help, please.
public class Polygon
{
public Point[] vertexes { get; protected set; }
public Polygon(params int[] vertex)
{
if (vertex == null || vertex.Length <= 2)
throw new Exception("someText");
if (vertex.Length % 2 != 0)
throw new Exception("someText");
vertexes = new Point[vertex.Length / 2];
ColorContour = System.Drawing.Color.DarkRed;
Priming = false;
for (int i = 0, j = 0; i < vertexes.Length; i++, j += 2)
vertexes[i] = new Point(vertex[j], vertex[j + 1]);
vertexes = Point.Sort(vertexes);
if (vertexes == null || vertexes.Length <= 2)
throw new Exception("someText");
}
public double Perimetr
{
get
{
double res = 0;
for (int i = 1; i < vertexes.Length; i++)
res += Point.Length(vertexes[i - 1], vertexes[i]);
return res;
}
}
public override void Move(int deltax, int deltay)
{
vertexes[0].x = deltax;
vertexes[0].y = deltay;
for (int i = 1; i < vertexes.Length; i++)
{
vertexes[i].x -= deltax;
vertexes[i].y -= deltay;
}
}
public void Zoom(double size)
{
if (size == 0)
return;
Point firstP = new Point(vertexes[0].x, vertexes[0].y);
Point Center = Point.CentrMass(vertexes);
for (int i = 0; i < vertexes.Length; ++i)
{
vertexes[i].x = Convert.ToInt32(size * (vertexes[i].x - Center.x) + Center.x);
vertexes[i].y = Convert.ToInt32(size * (vertexes[i].y - Center.y) + Center.y);
}
Move(firstP.x, firstP.y);
}
public void Draw( ??)
{
**????**
}
publicabstract double Square { get; }
You need to take in a System.Drawing.Graphics as a parameter, and call Graphics.DrawPolygon() function. Then in the picturebox, override or implement the OnPaint() event, and call your draw function with the Graphics you receive as a parameter (child of the eventargs) in OnPaint().

c# xna how to copy an object array as different array?

I'm trying to make a drag and drop from an array of object. At first, they will copied in another array. But, when i try to updating the original array, the copy has updating too.
here my codes:
namespace drop_test2
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
InputManager input;
Texture2D texure;
DragableObject[] dragObjects, copyDragObjects;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
this.IsMouseVisible = true;
this.input = new InputManager(this);
this.dragObjects = new DragableObject[6 * 6];
}
protected override void LoadContent()
{
this.spriteBatch = new SpriteBatch(this.GraphicsDevice);
this.input.Load();
this.texure = new Texture2D(this.GraphicsDevice, 50, 50, false, SurfaceFormat.Color);
Color[] c = new Color[this.texure.Width * this.texure.Height];
for (int i = 0; i < c.Length; i++) c[i] = Color.White;
this.texure.SetData(c);
for (int x = 0; x < 6; x++)
{
for (int y = 0; y < 6; y++)
{
var obj = new DragableObject();
obj.Size = new Vector2(50);
obj.Position = new Vector2(35) + new Vector2(x, y) * obj.Size;
this.dragObjects[x + y * 6] = obj;
}
}
this.copyDragObjects = this.dragObjects;
}
protected override void Update(GameTime gameTime)
{
this.input.Update(gameTime);
for (int i = 0; i < this.dragObjects.Length; i++)
{
if (this.dragObjects[i].CheckHover(input.CurrentCursorPost))
{
this.copyDragObjects[i].Position += new Vector2(.5f, 0);
}
}
}
Color c = Color.Blue;
protected override void Draw(GameTime gameTime)
{
this.GraphicsDevice.Clear(Color.CornflowerBlue);
this.spriteBatch.Begin();
for (int x = 0; x < 6; x++)
{
for (int y = 0; y < 6; y++)
{
if ((x + y) % 2 == 0)
c = Color.DarkGreen;
else
c = Color.LightGreen;
if (this.dragObjects[x + y * 6].IsHover)
c = Color.DarkOrchid * .5f;
if (this.dragObjects[x + y * 6].IsSelected)
c = Color.DarkRed * .75f;
this.spriteBatch.Draw(this.texure, this.dragObjects[x + y * 6].Position, null, c,
0f, new Vector2(texure.Width, texure.Height) * .5f, 1f, SpriteEffects.None, 0);
}
}
this.spriteBatch.End();
}
}
}
this is the dragableobject class
namespace drop_test2
{
struct DragableObject
{
public Vector2 Position
{
get;
set;
}
public Vector2 Size
{
get;
set;
}
public bool IsSelected
{
get;
set;
}
public bool IsHover
{
get;
set;
}
public bool CheckHover(Vector2 vector2)
{
Rectangle r = new Rectangle((int)(this.Position.X - this.Size.X * .5), (int)(this.Position.Y - this.Size.Y * .5f),
(int)this.Size.X, (int)this.Size.Y);
if (r.Contains((int)vector2.X,(int)vector2.Y))
{
this.IsHover = true;
return true;
}
this.IsHover = false;
return false;
}
}
}
Anyone wanna help me to solving this problem?
If you use CopyTo() c# internally refers to the original array. If you want to create a new instance you have to use Clone().
Example:
object[] src = { "a", "b" };
var dest = src.Clone() as object[];
src[0] = "c";
//// dest still contains "a","b"
Also see: Difference between the System.Array.CopyTo() and System.Array.Clone()

Categories