Files
2026-04-19 00:43:27 +02:00

79 lines
2.1 KiB
C#

using System;
using System.Numerics;
namespace RobotAndDonkey.Game.Utils;
public record struct Hex(int X, int Y)
{
public static int Distance(Hex a, Hex b)
{
var (acx, acy, acz) = OffsetToCube(a);
var (bcx, bcy, bcz) = OffsetToCube(b);
return Math.Max(Math.Max(Math.Abs(acx - bcx), Math.Abs(acy - bcy)), Math.Abs(acz - bcz));
static (int, int, int) OffsetToCube(Hex hex)
{
var x = hex.X - (hex.Y - (hex.Y & 1)) / 2;
var z = hex.Y;
var y = -x - z;
return (x, y, z);
}
}
public static Hex FromWorld(Vector2 coords)
{
var cx = coords.X * MathF.Sqrt(3) / 3 - coords.Y / 3;
var cz = coords.Y * 2 / 3;
var cy = -cx - cz;
var rx = (int)MathF.Round(cx);
var ry = (int)MathF.Round(cy);
var rz = (int)MathF.Round(cz);
var xDiff = MathF.Abs(rx - cx);
var yDiff = MathF.Abs(ry - cy);
var zDiff = MathF.Abs(rz - cz);
if (xDiff > yDiff && xDiff > zDiff)
rx = -ry - rz;
else if (yDiff > zDiff)
ry = -rx - rz;
else
rz = -rx - ry;
var col = rx + (rz - (rz & 1)) / 2;
var row = rz;
return new(col, row);
}
public static Hex FromPixel(Vector2 coords, float size)
{
return FromWorld(new(coords.X / size, coords.Y / size));
}
public Hex GetNeighbour(EDirection direction)
{
var parity = Y & 1;
var dir = offsetDirections[parity, (int)direction];
return new(X + dir.X, Y + dir.Y);
}
public Vector2 ToWorld()
{
var x = MathF.Sqrt(3) * (X + 0.5f * (Y & 1));
var y = 3.0f / 2 * Y;
return new(x, y);
}
public Vector2 ToPixel(float size)
{
var w = ToWorld();
return new(w.X * size, w.Y * size);
}
public override string ToString()
{
return $"({X}, {Y})";
}
private static readonly Hex[,] offsetDirections = { { new(+1, 0), new(0, -1), new(-1, -1), new(-1, 0), new(-1, +1), new(0, +1) }, { new(+1, 0), new(+1, -1), new(0, -1), new(-1, 0), new(0, +1), new(+1, +1) } };
}