using Godot; using System.Collections.Generic; namespace Rokojori; public struct HexagonCoord { public readonly int q; public readonly int r; public HexagonCoord( int q, int r ) { this.q = q; this.r = r; } public readonly static HexagonCoord Center = new HexagonCoord( 0, 0 ); public HexagonCoord Middle => Center; public readonly static HexagonCoord East = new HexagonCoord( 1, 0 ); public HexagonCoord Left => East; public readonly static HexagonCoord NorthEast = new HexagonCoord( 1, -1 ); public HexagonCoord LeftUp => NorthEast; public readonly static HexagonCoord NorthWest = new HexagonCoord( 0, -1 ); public HexagonCoord RightUp => NorthWest; public readonly static HexagonCoord West = new HexagonCoord( -1, 0 ); public HexagonCoord Right => West; public readonly static HexagonCoord SouthWest = new HexagonCoord( -1, 1 ); public HexagonCoord RightDown => SouthWest; public readonly static HexagonCoord SouthEast = new HexagonCoord( 0, 1 ); public HexagonCoord LeftDown => SouthEast; static readonly HexagonCoord[] directions = new HexagonCoord[] { new HexagonCoord( 1, 0 ), new HexagonCoord( 1, -1 ), new HexagonCoord( 0, -1 ), new HexagonCoord( -1, 0 ), new HexagonCoord( -1, 1 ), new HexagonCoord( 0, 1 ) }; public static HexagonCoord Direction( int direction ) { RJLog.Log( direction ); return directions[ direction ]; } public HexagonCoord Neighbor( int direction ) { var d = directions[ direction ]; return this + directions[ direction ]; } public void ForEachNeighbor( System.Action callback ) { for ( int i = 0; i < directions.Length; i++ ) { callback( Neighbor( i ) ); } } public Vector3 ToWorldPosition( float size ) { var x = size * 1.5f * q; var z = size * ( Mathf.Sqrt( 3f ) * 0.5f * q + Mathf.Sqrt( 3f ) * r ); return new Vector3( x, 0, z ); } public static HexagonCoord operator +(HexagonCoord a, HexagonCoord b) { return new HexagonCoord( a.q + b.q, a.r + b.r ); } public static HexagonCoord operator -(HexagonCoord a, HexagonCoord b) { return new HexagonCoord( a.q - b.q, a.r - b.r ); } public static HexagonCoord operator -(HexagonCoord a) { return new HexagonCoord( -a.q, -a.r ); } public static HexagonCoord operator *(HexagonCoord a, int scalar) { return new HexagonCoord( a.q * scalar, a.r * scalar ); } public static HexagonCoord operator *(int scalar, HexagonCoord a) { return a * scalar; } public static HexagonCoord operator /(HexagonCoord a, int scalar) { return new HexagonCoord( a.q / scalar, a.r / scalar ); } public static bool operator ==(HexagonCoord a, HexagonCoord b) { return a.q == b.q && a.r == b.r; } public static bool operator !=(HexagonCoord a, HexagonCoord b) { return !(a == b); } public override bool Equals( object obj ) { return obj is HexagonCoord other && other.q == q && other.r == r; } public override int GetHashCode() { return q * 397 ^ r; } public static List Ring( int radius ) { return Ring( HexagonCoord.Center, radius ); } public static List Ring( HexagonCoord center, int radius ) { var results = new List(); if ( radius == 0 ) { results.Add( center ); return results; } var hex = center; for ( int i = 0; i < radius; i++ ) { hex = hex.Neighbor( 4 ); } for ( int side = 0; side < 6; side++ ) { for ( int step = 0; step < radius; step++ ) { results.Add( hex ); hex = hex.Neighbor( side ); } } return results; } }