-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAgent.c
More file actions
200 lines (169 loc) · 5.34 KB
/
Agent.c
File metadata and controls
200 lines (169 loc) · 5.34 KB
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
https://powcoder.com
代写代考加微信 powcoder
Assignment Project Exam Help
Add WeChat powcoder
// Implementation of the Agent ADT
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Agent.h"
#include "Map.h"
// This struct stores information about an individual agent and can be
// used to store information that the agent needs to remember.
struct agent {
char *name;
int startLocation;
int location;
int maxStamina; // max stamina
int stamina; // current stamina
int strategy;
Map map;
// TODO: Add more fields here as needed
};
static Move chooseRandomMove(Agent agent, Map m);
static int filterRoads(Agent agent, Road roads[], int numRoads,
Road legalRoads[]);
/**
* Creates a new agent
*/
Agent AgentNew(int start, int stamina, int strategy, Map m, char *name) {
if (start >= MapNumCities(m)) {
fprintf(stderr, "error: starting city (%d) is invalid\n", start);
exit(EXIT_FAILURE);
}
Agent agent = malloc(sizeof(struct agent));
if (agent == NULL) {
fprintf(stderr, "error: out of memory\n");
exit(EXIT_FAILURE);
}
agent->startLocation = start;
agent->location = start;
agent->maxStamina = stamina;
agent->stamina = stamina;
agent->strategy = strategy;
agent->map = m;
agent->name = strdup(name);
// TODO: You may need to add to this
return agent;
}
/**
* Frees all memory associated with the agent
* NOTE: You should not free the map because the map is owned by the
* main program, and the main program will free it
*/
void AgentFree(Agent agent) {
// TODO: You may need to update this to free any extra memory you use
free(agent->name);
free(agent);
}
////////////////////////////////////////////////////////////////////////
// Making moves
/**
* Calculates the agent's next move
*/
Move AgentGetNextMove(Agent agent, Map m) {
switch (agent->strategy) {
case STATIONARY: return (Move){agent->location, 0};
case RANDOM: return chooseRandomMove(agent, m);
// TODO: Implement more strategies here
default:
printf("error: strategy not implemented yet\n");
exit(EXIT_FAILURE);
}
}
static Move chooseRandomMove(Agent agent, Map m) {
Road *roads = malloc(MapNumCities(m) * sizeof(Road));
Road *legalRoads = malloc(MapNumCities(m) * sizeof(Road));
// Get all roads to adjacent cities
int numRoads = MapGetRoadsFrom(m, agent->location, roads);
// Filter out roads that the agent does not have enough stamina for
int numLegalRoads = filterRoads(agent, roads, numRoads, legalRoads);
Move move;
if (numLegalRoads > 0) {
// Sort the roads using insertion sort
for (int i = 1; i < numLegalRoads; i++) {
Road r = legalRoads[i];
int j = i;
while (j > 0 && r.to < legalRoads[j - 1].to) {
legalRoads[j] = legalRoads[j - 1];
j--;
}
legalRoads[j] = r;
}
// nextMove is randomly chosen from the legal roads
int k = rand() % numLegalRoads;
move = (Move){legalRoads[k].to, legalRoads[k].length};
} else {
// The agent must stay in the same location
move = (Move){agent->location, 0};
}
free(legalRoads);
free(roads);
return move;
}
// Takes an array with all the possible roads and puts the ones the agent
// has enough stamina for into the legalRoads array
// Returns the number of legal roads
static int filterRoads(Agent agent, Road roads[], int numRoads,
Road legalRoads[]) {
int numLegalRoads = 0;
for (int i = 0; i < numRoads; i++) {
if (roads[i].length <= agent->stamina) {
legalRoads[numLegalRoads++] = roads[i];
}
}
return numLegalRoads;
}
/**
* Executes a given move by updating the agent's internal state
*/
void AgentMakeNextMove(Agent agent, Move move) {
if (move.to == agent->location) {
agent->stamina = agent->maxStamina;
} else {
agent->stamina -= move.staminaCost;
}
agent->location = move.to;
// TODO: You may need to add to this to handle different strategies
}
////////////////////////////////////////////////////////////////////////
// Gets information about the agent
// NOTE: It is expected that these functions do not need to be modified
/**
* Gets the name of the agent
*/
char *AgentName(Agent agent) {
return agent->name;
}
/**
* Gets the current location of the agent
*/
int AgentLocation(Agent agent) {
return agent->location;
}
/**
* Gets the amount of stamina the agent currently has
*/
int AgentStamina(Agent agent) {
return agent->stamina;
}
////////////////////////////////////////////////////////////////////////
// Learning information
/**
* Tells the agent where the thief is
*/
void AgentGainInfo(Agent agent, int thiefLocation) {
// TODO: Stage 3
}
////////////////////////////////////////////////////////////////////////
// Displaying state
/**
* Prints information about the agent (for debugging purposes)
*/
void AgentShow(Agent agent) {
// TODO: You can implement this function however you want
// You can leave this function blank if you want
}
////////////////////////////////////////////////////////////////////////