-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathyodash.js
More file actions
120 lines (104 loc) · 3.69 KB
/
yodash.js
File metadata and controls
120 lines (104 loc) · 3.69 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
const yodash = {}
const math = require("mathjs")
const { Utils } = require("jtree/products/Utils.js")
const { ParserTypes } = require("./components/Types.js")
yodash.compare = (left, operator, right) => {
if (operator === "=") return left == right
if (operator === "<") return left < right
if (operator === ">") return left > right
if (operator === "<=") return left <= right
if (operator === ">=") return left >= right
return false
}
// Todo: why do we do this? Very confusing. Caught me by surprise.
// Is it because sometimes the class name is not valid JS?
yodash.compileAgentClassDeclarationsAndMap = program => {
const agentKeywordMap = {}
program.agentKeywordMap = agentKeywordMap // confusing
const agentDefs = program.filter(node => node.parserId === ParserTypes.agentDefinitionParser)
agentDefs.forEach((node, index) => (agentKeywordMap[node.firstWord] = `simAgent${index}`))
const compiled = agentDefs.map(node => node.compile()).join("\n")
const agentMap = Object.keys(agentKeywordMap)
.map(key => `"${key}":${agentKeywordMap[key]}`)
.join(",")
return `${compiled}
const map = {${agentMap}};
map;`
}
yodash.patchExperimentAndReplaceSymbols = (program, experiment) => {
const clone = program.clone()
// drop experiment nodes
clone.filter(node => node.parserId === ParserTypes.experimentParser).forEach(node => node.destroy())
// Append current experiment
if (experiment) clone.concat(experiment.childrenToString())
// Build symbol table
const symbolTable = {}
clone
.filter(node => node.parserId === ParserTypes.settingDefinitionParser)
.forEach(node => {
symbolTable[node.firstWord] = node.content
node.destroy()
})
// Find and replace
let withVarsReplaced = clone.toString()
Object.keys(symbolTable).forEach(key => {
withVarsReplaced = withVarsReplaced.replaceAll(key, symbolTable[key])
})
return withVarsReplaced
}
yodash.getClosest = (targets, subject) => {
let closest = Infinity
let target
targets.forEach(agent => {
if (agent === subject) return
const distance = math.distance([agent.y, agent.x], [subject.y, subject.x])
if (distance < closest) {
closest = distance
target = agent
}
})
return target
}
yodash.unitVector = (objA, objB) => {
// calculate direction vector (delta)
const delta = {
x: objB.x - objA.x,
y: objB.y - objA.y
}
// calculate magnitude of delta (distance between two points)
const magDelta = Math.sqrt(delta.x * delta.x + delta.y * delta.y)
// calculate unit vector (normalize direction vector by dividing by magnitude)
return {
x: delta.x / magDelta,
y: delta.y / magDelta
}
}
yodash.parsePercent = str => parseFloat(str.replace("%", "")) / 100
yodash.getRandomNumberGenerator = seed => () => {
const semiRand = Math.sin(seed++) * 10000
return semiRand - Math.floor(semiRand)
}
yodash.sampleFrom = (collection, howMany, randomNumberGenerator) =>
shuffleArray(collection, randomNumberGenerator).slice(0, howMany)
const shuffleArray = (array, randomNumberGenerator) => {
const clonedArr = array.slice()
for (let index = clonedArr.length - 1; index > 0; index--) {
const replacerIndex = Math.floor(randomNumberGenerator() * (index + 1))
;[clonedArr[index], clonedArr[replacerIndex]] = [clonedArr[replacerIndex], clonedArr[index]]
}
return clonedArr
}
yodash.pick = (tree, fields) => {
const newTree = tree.clone()
const map = Utils.arrayToMap(fields)
newTree.forEach(node => {
if (!map[node.firstWord]) node.destroy()
})
return newTree
}
yodash.flatten = tree => {
const newTree = new TreeNode()
tree.forEach(node => node.forEach(child => newTree.appendNode(child)))
return newTree
}
module.exports = { yodash }