using System;
using System.Collections.Generic;

namespace InfiniMap
{
    public class Map
    {
        public IDictionary<Tuple<int, int>, Chunk> Chunks;

        private int _chunkWidth;
        private int _chunkHeight;

        public Map(int chunkHeight, int chunkWidth)
        {
            _chunkHeight = chunkHeight;
            _chunkWidth = chunkWidth;
            Chunks = new Dictionary<Tuple<int, int>, Chunk>(64);
        }

        public Block this[int x, int y]
        {
            get
            {
                int xChunk = (x/_chunkHeight);
                int yChunk = (y/_chunkWidth);

                Chunk chunk;
                var foundChunk = Chunks.TryGetValue(Tuple.Create(xChunk, yChunk), out chunk);
                if (foundChunk)
                {
                    return chunk[x, y];
                }

                var newChunk = new Chunk(_chunkHeight, _chunkWidth);
                Chunks.Add(Tuple.Create(xChunk, yChunk), newChunk);
                return newChunk[x, y];
            }
            set
            {
                // Block is a reference type, so we just discard a local pointer after
                // alterting the object
                var block = this[x, y];
                block = value;
            }
        }

    }
}
using System;
using System.Collections.Generic;

namespace InfiniMap
{
    public class Map
    {
        public IDictionary<Tuple<int, int>, Chunk> Chunks;

        private int _chunkWidth;
        private int _chunkHeight;

        public Map(int chunkHeight, int chunkWidth)
        {
            _chunkHeight = chunkHeight;
            _chunkWidth = chunkWidth;
            Chunks = new Dictionary<Tuple<int, int>, Chunk>(64);
        }

        public Block this[int x, int y]
        {
            get
            {
                var xChunk = (int) Math.Floor(x/(float) _chunkHeight);
                var yChunk = (int) Math.Floor(y/(float) _chunkWidth);

                Chunk chunk;
                var foundChunk = Chunks.TryGetValue(Tuple.Create(xChunk, yChunk), out chunk);
                if (foundChunk)
                {
                    return chunk[x, y];
                }

                var newChunk = new Chunk(_chunkHeight, _chunkWidth);
                Chunks.Add(Tuple.Create(xChunk, yChunk), newChunk);
                return newChunk[x, y];
            }
            set
            {
                // Block is a reference type, so we just discard a local pointer after
                // alterting the object
                var block = this[x, y];
                block = value;
            }
        }

    }
}
Fix chunk loading for negative co-ordinates.
Fix chunk loading for negative co-ordinates.

A negative number divided by a negative number is negative, except
when it's an integer and rounds upwards.

Given the x co-ordinate of -64 and a chunkHeight of 128

-64 / 128 == 0
-64 / 128.0 == -0.5
Floor(-64/128.0) == -1

The fix is to floor a division by a floating point number.
