-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexpectimax_strategy.cpp
More file actions
85 lines (74 loc) · 2.59 KB
/
Copy pathexpectimax_strategy.cpp
File metadata and controls
85 lines (74 loc) · 2.59 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
/*
Copyright (C) 2016 Meritxell Jordana
Copyright (C) 2016 Marc Sanchez
*/
#include <math.h>
#include "expectimax_strategy.h"
ExpectimaxStrategy::ExpectimaxStrategy(Map *map) : Strategy(map) {}
Direction ExpectimaxStrategy::getAction() {
return minimax_decision(2);
}
double ExpectimaxStrategy::utility(Map &map) {
return evaluationFunction(map);
}
bool ExpectimaxStrategy::terminalTest(Map &map, int depth) {
return depth == 0 || !map.isFoodAvailable();
}
Map ExpectimaxStrategy::result(Map &map, CellType agent, Direction action) {
return map.generateSuccessor(agent, action);
}
double ExpectimaxStrategy::max_value(Map map, CellType agent, int depth) {
if (terminalTest(map, depth)) {
return utility(map);
}
list<Direction> legalMoves = map.getLegalMoves(agent);
double v = -30000000;
for (list<Direction>::iterator a = legalMoves.begin(); a != legalMoves.end(); ++a) {
v = fmax(v, min_value(result(map, agent, *a), Player, depth));
}
return v;
}
double ExpectimaxStrategy::min_value(Map map, CellType agent, int depth) {
if (terminalTest(map, depth)) {
return utility(map);
}
list<Direction> legalMoves = map.getLegalMoves(agent);
double v = 0;
for (list<Direction>::iterator a = legalMoves.begin(); a != legalMoves.end(); ++a) {
if (agent == Player) {
v += max_value(result(map, agent, *a), Enemy, depth-1);
} else {
v += min_value(result(map, agent, *a), Player, depth);
}
}
return v/legalMoves.size();
}
Direction ExpectimaxStrategy::minimax_decision(int depth) {
double v = -3000000;
list<Direction> legalMoves = map->getLegalMoves(Enemy);
list<Direction> moves;
for (list<Direction>::iterator a = legalMoves.begin(); a != legalMoves.end(); ++a) {
double u = min_value(result(*map, Enemy, *a), Player, depth);
if (u == v) {
moves.push_back(*a);
} else if (u > v) {
v = u;
moves.clear();
moves.push_back(*a);
}
}
return getRandomDirection(moves);
}
double ExpectimaxStrategy::evaluationFunction(Map &map) {
double totalScore = map.getEatedFoodByEnemy() * 10;
Position enemyPosition = map.getEnemyPosition();
set<Position> foodCells = map.getFoodCells();
for (set<Position>::iterator a = foodCells.begin(); a != foodCells.end(); ++a) {
double d = minDistance(*a, enemyPosition);
totalScore += 1.0/(d*d);
}
return totalScore;
}
double ExpectimaxStrategy::minDistance(Position p1, Position p2) {
return Strategy::manhattanDistance(p1, p2);
}