-
Notifications
You must be signed in to change notification settings - Fork 8
/
node.h
124 lines (114 loc) · 4.22 KB
/
node.h
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
extern unsigned int nodesGenerated; //declared from main.c
/**
* DESCRIPTION: Defines the node structure used to create a search tree
**/
typedef struct Node Node;
struct Node {
unsigned int depth; //depth of the node from the root. For A* search,
//this will also represent the node's path cost
unsigned int hCost; //heuristic cost of the node
State *state; //state designated to a node
Node *parent; //parent node
NodeList *children; //list of child nodes
};
/**
* DESCRIPTION:
* This function creates a node, initializes it with the
* following parameters, and sets its children to NULL.
* PARAMETERS:
* d - depth of the node
* h - heuristic value of the node
* s - state assignated to the node
* p - parent node
* RETURN:
* Returns a `Node` pointer to the dynamically allocated node,
* or NULL on failure.
**/
Node* createNode(unsigned int d, unsigned int h, State *s, Node *p) {
Node *newNode = malloc(sizeof(Node));
if(newNode) {
newNode->depth = d;
newNode->hCost = h;
newNode->state = s;
newNode->parent = p;
newNode->children = NULL;
++nodesGenerated; //update counter
}
return newNode;
}
/**
* DESCRIPTION:
* This function is used to deallocate all nodes in a tree, including
* the root node.
* PARAMETER:
* node - the root node of the tree to deallocate
**/
void destroyTree(Node *node) {
if(node->children == NULL) {
free(node->state);
free(node);
return;
}
ListNode *listNode = node->children->head;
ListNode *nextNode;
while(listNode) {
nextNode = listNode->nextNode;
destroyTree(listNode->currNode);
listNode = nextNode;
}
//free(node->state);
free(node->children);
free(node);
}
/**
* DESCRIPTION:
* This function 'expands' the node, links it to its children, and updates the
* expansion counter.
* PARAMETER:
* parent - the node to expand and search children for
* goalState - pointer to the goal state where heuristic values of each child will
* be based on
* RETURN:
* Returns a pointer to `NodeList` on success, NULL on failure.
**/
NodeList* getChildren(Node *parent, State *goalState) {
NodeList *childrenPtr = NULL;
State *testState = NULL;
Node *child = NULL;
//attempt to create states for each moves, and add to the list of children if true
if(parent->state->action != DOWN && (testState = createState(parent->state, UP))) {
child = createNode(parent->depth + 1, manhattanDist(testState, goalState), testState, parent);
pushNode(child, &parent->children);
pushNode(child, &childrenPtr);
}
if(parent->state->action != UP && (testState = createState(parent->state, DOWN))) {
child = createNode(parent->depth + 1, manhattanDist(testState, goalState), testState, parent);
pushNode(child, &parent->children);
pushNode(child, &childrenPtr);
}
if(parent->state->action != RIGHT && (testState = createState(parent->state, LEFT))) {
child = createNode(parent->depth + 1, manhattanDist(testState, goalState), testState, parent);
pushNode(child, &parent->children);
pushNode(child, &childrenPtr);
}
if(parent->state->action != LEFT && (testState = createState(parent->state, RIGHT))) {
child = createNode(parent->depth + 1, manhattanDist(testState, goalState), testState, parent);
pushNode(child, &parent->children);
pushNode(child, &childrenPtr);
}
return childrenPtr;
}
/**
* DESCRIPTION:
* This simply evaluates the node's total cost, i.e. path cost + heuristic value.
* Created to abstract the proccess and reduce code cluttering. Note that
* a node's path cost in a tree depends purely on the node's depth, so the node's
* depth will be representing the path cost (to save space).
* PARAMETER:
node - the node to get its total cost
* RETURN:
* Retuns the integer sum of the node's path cost and heuristic value
**/
int totalCost(Node * const node) {
return node->depth + node->hCost;
}