-
Notifications
You must be signed in to change notification settings - Fork 0
/
Controller.js
128 lines (103 loc) · 3.31 KB
/
Controller.js
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
var Util = require('./Util');
var PF = require('./PathFinding');
var choice = require('mout/random/choice');
var goalPosition = null;
var goalItem = null;
function shortestPathToPosition(toPosition, toItem, gameState) {
var currentPosition = {
x: gameState.position[1],
y: gameState.position[0]
};
var pfIndex = Util.indexLayout(gameState.layout);
var matrix = pfIndex.matrix;
return PF.takeStep(currentPosition, toPosition, matrix);
}
function shortestPathToItems(interestingItems, gameState, stupidness) {
var position = {
x: gameState.position[1],
y: gameState.position[0]
};
var pfIndex = null;
if (interestingItems[0] === 'user') {
pfIndex = Util.indexLayout(gameState.layout, true);
} else {
pfIndex = Util.indexLayout(gameState.layout);
}
var matrix = pfIndex.matrix;
var tileTypes = pfIndex.types;
var paths = interestingItems.reduce(function (paths, tileType) {
(tileTypes[tileType] || []).forEach(function (tilePosition) {
paths.push(PF.takeStep(position, tilePosition, matrix));
});
return paths;
}, []);
var shortest = null;
if (Math.random() < stupidness) {
shortest = choice(paths);
} else {
paths.forEach(function (path) {
// For some reason we store undefined paths
if (!path) return;
if (!shortest || path.distance < shortest.distance) {
shortest = path;
}
});
}
return shortest;
}
function isMusicItem(tile) {
return tile === 'song' || tile === 'album' || tile === 'playlist';
}
function shouldFindNewGoal(gameState, goalPosition) {
if (!goalPosition) return true;
var layout = gameState.layout;
var inventory = gameState.inventory;
var goalTile = layout[goalPosition.y][goalPosition.x];
var noMusicInInventory = inventory.filter(isMusicItem).length === 0;
return goalTile === 'empty' || goalTile === 'monkey' ||
(goalTile === 'user' && noMusicInInventory);
}
function findNewGoal(gameState, stupidness) {
var inventorySize = gameState.inventorySize;
var inventory = gameState.inventory;
if (inventory.length >= inventorySize) {
return shortestPathToItems(['user'], gameState, stupidness);
} else {
return shortestPathToItems(['song', 'album', 'playlist'], gameState, stupidness);
}
}
function randomDirection() {
return ['up', 'down', 'left', 'right'][Math.floor(Math.random() * 3)];
}
/**
* [chooseDirection description]
* @param {[type]} layout
* @param {[type]} position
* @param {[type]} pickedUpItems
* @return {[type]}
*/
exports.chooseDirection = function chooseDirection(gameState, stupidness) {
var monkeyPosition = {
x: gameState.position[1],
y: gameState.position[0]
};
// If we're very stupid
if (Math.random() < stupidness / 5) {
return randomDirection();
}
if (!shouldFindNewGoal(gameState, goalPosition)) {
var path = shortestPathToPosition(goalPosition, goalItem, gameState);
if (path) {
return Util.calculateDirection(monkeyPosition, path.nextStep);
}
}
var goalPath = findNewGoal(gameState, stupidness);
// Chicken out if we don't know what we're doing
if (!goalPath) {
return randomDirection();
}
goalPosition = goalPath.position;
goalItem = gameState.layout[goalPosition.y][goalPosition.x];
var direction = Util.calculateDirection(monkeyPosition, goalPath.nextStep);
return direction;
};