-
Notifications
You must be signed in to change notification settings - Fork 0
/
HexagonalGrid.cs
173 lines (143 loc) · 4.02 KB
/
HexagonalGrid.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
public class Hexagonal
{
public int x;
public int y;
public int z;
public static int[][,] OffsetDirections = new int[2][,] { // { col, row }
// 0,1,2,3,4,5
new int[,] { {+1, 0}, { 0, -1}, {-1, -1}, {-1, 0}, {-1, +1}, { 0, +1} }, // for even line
new int[,] { {+1, 0}, {+1, -1}, { 0, -1}, {-1, 0}, { 0, +1}, {+1, +1} } }; // for odd line
public Hexagonal( int _x, int _y, int _z )
{
x = _x;
y = _y;
z = _z;
}
// convert cube to odd-r offset
public Offset GetOffset( int x, int y, int z )
{
int col = x + ( z - ( z & 1 ) ) / 2;
int row = z;
return new Offset( row, col );
}
public int GetDistance( Hexagonal other )
{
return ( Math.Abs( other.x - x ) + Math.Abs( other.y - y ) + Math.Abs( other.z - z ) ) / 2;
}
public static int GetDistance( Hexagonal a, Hexagonal b )
{
return ( Math.Abs( a.x - b.x ) + Math.Abs( a.y - b.y ) + Math.Abs( a.z - b.z ) ) / 2;
}
static Hexagonal[] rotations = new Hexagonal[6] {
new Hexagonal( +1, -1, 0 ), new Hexagonal( +1, 0, -1 ), new Hexagonal( 0, +1, -1 ),
new Hexagonal( -1, +1, 0 ), new Hexagonal( -1, 0, +1 ), new Hexagonal( 0, -1, +1 )
};
public static int GetRotation( Hexagonal from, Hexagonal to )
{
int x = to.x - from.x;
int y = to.y - from.y;
int z = to.z - from.z;
for( int i = 0; i < 6; ++i )
{
if( rotations[i].x == x && rotations[i].y == y && rotations[i].z == z )
return i;
}
return 0;
}
}
public class Offset
{
public int row;
public int col;
public Offset()
{
}
public Offset( Offset other )
: this( other.row, other.col )
{
}
public Offset( int _row, int _col )
{
row = _row;
col = _col;
}
// convert odd-r offset to cube
public Hexagonal GetHex()
{
int x = col - ( row - ( row & 1 ) ) / 2;
int z = row;
int y = -x - z;
return new Hexagonal( x, y, z );
}
static Hexagonal GetHex( Offset other )
{
int x = other.col - ( other.row - ( other.row & 1 ) ) / 2;
int z = other.row;
int y = -x - z;
return new Hexagonal( x, y, z );
}
public int GetDistance( Offset other )
{
Hexagonal a = GetHex();
Hexagonal b = Offset.GetHex( other );
return Hexagonal.GetDistance( a, b );
}
public static int GetDistance( Offset a, Offset b )
{
Hexagonal ac = a.GetHex();
Hexagonal bc = b.GetHex();
return Hexagonal.GetDistance( ac, bc );
}
public override bool Equals( object obj )
{
return Equals( obj as Offset );
}
public bool Equals( Offset other )
{
return ( other.row == row && other.col == col );
}
public override int GetHashCode()
{
return row ^ col;
}
public override string ToString()
{
return "[" + row + ", " + col + "]";
}
public static int GetRotation( Offset from, Offset to )
{
return Hexagonal.GetRotation( from.GetHex(), to.GetHex() );
}
}
public class HexSearchNode : IEquatable<HexSearchNode>
{
public Offset Pos { get; set; }
public int Rotation { get; set; }
public int CostSoFar { get; set; }
public int CostToEnd { get; set; }
public HexSearchNode Parent { get; set; }
public HexSearchNode( Offset pos, int rotation, int costFrom, int costEnd )
{
Pos = pos;
Rotation = rotation;
CostSoFar = costFrom;
CostToEnd = costEnd;
}
public override bool Equals( object obj )
{
return Equals( obj as HexSearchNode );
}
public bool Equals( HexSearchNode other )
{
return ( other.Pos.Equals( Pos ) );
}
public override int GetHashCode()
{
return Pos.row ^ Pos.col;
}
public override string ToString()
{
return "[" + Pos.row + " " + Pos.col + " : " + ( CostSoFar + CostToEnd ) + "]";
}
};