-
Notifications
You must be signed in to change notification settings - Fork 0
/
HexNode.go
160 lines (137 loc) · 4.08 KB
/
HexNode.go
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
package dvonn
import (
"errors"
)
type HexNode struct {
identifier string
stackLength int // TODO: remove dependency from stackLength, coz this should be calculated dynamically and
// updating this filed on every action isn't a good design
chipsStack []Chip
childNodes map[EdgeType]*HexNode
}
func GetHexNode(id string) *HexNode {
return &HexNode{id, 0, make([]Chip, 0), make(map[EdgeType]*HexNode)}
}
func (hn *HexNode) GetIdentifier() string {
return hn.identifier
}
func (hn *HexNode) GetChildNodes() map[EdgeType]*HexNode {
return hn.childNodes
}
func (hn *HexNode) SetChildNode(edgeType EdgeType, node *HexNode) {
hn.childNodes[edgeType] = node
}
func (hn *HexNode) traverse() {
// TODO: implement it
}
func (hn *HexNode) GetPossibleMovements() {
// TODO: implement it
}
func (hn *HexNode) IsEmpty() bool {
return len(hn.chipsStack) == 0
}
func (hn *HexNode) GetStackLength() int {
return len(hn.chipsStack)
}
func (hn *HexNode) GetChipsStack() []Chip {
return hn.chipsStack
}
func (hn *HexNode) GetTopChips() (Chip, error) {
var res Chip
if len(hn.chipsStack) > 0 {
return hn.chipsStack[len(hn.chipsStack)-1], nil
}
return res, errors.New("no chips available on this node")
}
func (hn *HexNode) HasRedChips() bool {
for _, chip := range hn.chipsStack {
if chip.GetColor() == RED {
return true
}
}
return false
}
/*
To Add chips on the box, accepts slice of chips (stack of chips)
*/
func (hn *HexNode) AddChips(chips []Chip) {
hn.chipsStack = append(hn.chipsStack, chips...)
}
/*
To make the Hex Box empty, this operation will be performed when player moves to other box
*/
func (hn *HexNode) Empty() {
hn.chipsStack = make([]Chip, 0)
}
// changes: since, this method doesn't have a hard check on the length of chip stack for surroundings
// this, making this method for only internal uses only.
func (hn *HexNode) isCompletelySurrounded() bool {
return !(len(hn.GetChildNodes()) < 6)
}
/*
returns true if any of the surrounding node is empty
NOTE: empty means here, there can be hexagonal node present but that hexagonal node
should not have any chip kept on it, i.e. stack length should be zero
*/
func (hn *HexNode) HasFreeEdge() bool {
if hn.isCompletelySurrounded() {
for _, node := range hn.GetChildNodes() {
if node.GetStackLength() == 0 {
return true
}
}
} else { // as its not completely surrounded, definitely it has free edge
return true
}
return false
}
/*
returns: the list of Adjacent nodes which are in straight line from the current Node
Adjacent nodes in straight line means: As there can be six adjacent nodes in a hexagonal node and those nodes
can have another six adjacent nodes, but if you see not all of them will be in straight line.
*/
func (hn *HexNode) GetStraightAdjacentOnLevel(level int) []*HexNode {
if level <= 0 {
return nil
}
res := make([]*HexNode, 0)
for edgeType, nodePtr := range hn.GetChildNodes() {
_adjNode := _traverseInDirection(edgeType, level-1, nodePtr)
if _adjNode != nil {
res = append(res, _adjNode)
}
}
return res
}
/*
Summary: traverses the graph nodes only in a particular direction and returns the node which is exactly at
`depth` depth from the node passed in the argument. If it couldn't find any such node then it returns
nil.
NOTE: the logic written here is strictly for getting adjacent nodes at some depth from some particular node,
it should not be confused for finding possible moves from one HexNode to another HexNode coz movement of
chips can be done across empty spaces.
*/
func _traverseInDirection(edgeType EdgeType, depth int, node *HexNode) *HexNode {
if depth == 0 {
return node
}
currentNode := node
for depth > 0 {
if val, ok := currentNode.childNodes[edgeType]; ok {
currentNode = val
} else { // return nil coz as we couldn't find node for that particular edge type even before depth is reached
// so it's not possible to find it anyway after this point
return nil
}
depth = depth - 1
}
return currentNode
}
func (hn *HexNode) presentIn(master []*HexNode) bool {
for _, item := range master {
if hn == item {
return true
}
}
return false
}