Skip to content

Commit 0244ede

Browse files
author
adrian
committed
Added unique names, added click start, stop, running total, various cleanup.
1 parent 05a0ac5 commit 0244ede

File tree

3 files changed

+164
-72
lines changed

3 files changed

+164
-72
lines changed

src/backend/universe.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ def toJSON(obj):
2222
return result
2323

2424
def buildAgentState(self, agent):
25-
return AgentState(agent.name, agent.alive(), agent.x, agent.y, agent.health)
25+
return AgentState(agent.id, agent.alive(), agent.x, agent.y, agent.health)
2626

2727
class AgentState:
28-
def __init__(self, name, alive, x, y, health):
29-
self.name = name
28+
def __init__(self, uuid, alive, x, y, health):
29+
self.id = uuid
3030
self.alive = alive
3131
self.x = x
3232
self.y = y
@@ -41,16 +41,16 @@ def __init__(self, x, y):
4141
self.type = "Food"
4242

4343
class Agent(object):
44-
def __init__(self, name, environment):
44+
def __init__(self, environment):
4545
#self.size = 1
4646
self.environment = environment
4747

4848
# should check whether there are surrounding agents by some threshold
49-
self.name = name
49+
self.id = uuid.uuid4().hex
5050
self.x = random.randint(0, environment.size)
5151
self.y = random.randint(0, environment.size)
5252
self.health = 10
53-
self.state = AgentState(self.name, self.alive(), self.x, self.y, self.health)
53+
self.state = AgentState(self.id, self.alive(), self.x, self.y, self.health)
5454
self.foods = []
5555
self.logger = logging.getLogger(__name__)
5656
self.type = "Agent"
@@ -63,7 +63,7 @@ def step(self):
6363
foods, agents = self.see()
6464
self.move(foods)
6565
self.health = self.health - self.environment.decayRate
66-
self.state = AgentState(self.name, self.alive(), self.x, self.y, self.health)
66+
self.state = AgentState(self.id, self.alive(), self.x, self.y, self.health)
6767
return self.state
6868

6969
def size(self):
@@ -144,7 +144,7 @@ def __init__(self, size, agentVelocity, agentVisibility, foodSpawnRate, numberOf
144144
self.decayRate = decayRate
145145
self.foods = []
146146
self.agents = []
147-
self.agents = [Agent(uuid.uuid4().hex, self) for i in range(self.numberOfAgents)]
147+
self.agents = [Agent(self) for i in range(self.numberOfAgents)]
148148
self.logger = logging.getLogger(__name__)
149149
self.type = "Environment"
150150

src/frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
},
1010
"dependencies": {
1111
"core-js": "^3.4.3",
12+
"unique-names-generator": "^4.1.1",
1213
"vue": "^2.6.10",
1314
"vue-p5": "^0.8.3",
1415
"vuex": "^3.1.2"

src/frontend/src/components/Environment.vue

Lines changed: 155 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,165 @@
11
<template>
2-
<div class="hello">
3-
<p>
4-
For a guide and recipes on how to configure / customize this project,<br>
5-
check out the
6-
</p>
7-
<vue-p5
8-
@setup="setup"
9-
@draw="draw"
10-
>
11-
</vue-p5>
2+
<div>
3+
<div :class="{ count: currentCycle > 0, start: currentCycle == 0 }">
4+
<p>
5+
{{ currentCycle == 0 ? "Double click to start" : "Current Cycle:" + currentCycle }}
6+
</p>
7+
</div>
8+
<div class="simulation">
9+
<div class="canvas">
10+
<vue-p5
11+
@setup="setup"
12+
@draw="draw"
13+
@mouseclicked="mouseClicked"
14+
>
15+
</vue-p5>
16+
</div>
17+
<div class="side-bar">
18+
<div v-if="cycles.length > 0 && currentAgents.length > 0">
19+
<div v-for="agent in currentAgents" v-bind:key="agent.id">
20+
<p>{{namesMap[agent.id] + " - " + agent.health }}</p>
21+
</div>
22+
</div>
23+
</div>
24+
</div>
1225
</div>
1326
</template>
1427

28+
<style scoped>
29+
.start {
30+
text-align: center;
31+
}
32+
33+
.count {
34+
text-align: right;
35+
}
36+
37+
.simulation {
38+
display: flex;
39+
align-items: center;
40+
justify-content: center;
41+
border-color: darkorange;
42+
border-style: solid;
43+
border-width: 0.1em;
44+
padding-top: 0.25em
45+
}
46+
47+
.side-bar {
48+
min-width: 12em;
49+
max-height: 50em;
50+
}
51+
52+
h3 {
53+
margin: 40px 0 0;
54+
}
55+
ul {
56+
list-style-type: none;
57+
padding: 0;
58+
}
59+
li {
60+
display: inline-block;
61+
margin: 0 10px;
62+
}
63+
a {
64+
color: #42b983;
65+
}
66+
</style>
67+
1568
<script>
69+
const { uniqueNamesGenerator, names, adjectives, colors } = require('unique-names-generator');
70+
71+
class Food {
72+
constructor(food, sketch) {
73+
this.sketch = sketch;
74+
this.x = food.x * 100 + 25;
75+
this.y = food.y * 100 + 25;
76+
this.id = food.id;
77+
}
78+
79+
run(sketch) {
80+
this.display(sketch);
81+
}
82+
83+
// Method to display
84+
display(sketch) {
85+
sketch.fill("yellow")
86+
sketch.strokeWeight(2);
87+
sketch.ellipse(this.x, this.y, 10, 10);
88+
}
89+
}
90+
1691
class Agent {
17-
constructor(agent, sketch) {
92+
constructor(agent, sketch, namesMap) {
1893
this.sketch = sketch;
19-
this.name = agent.name
20-
this.alive = agent.alive
21-
this.x = agent.x
22-
this.y = agent.y
23-
this.health = agent.health
94+
this.id = agent.id;
95+
this.alive = agent.alive;
96+
this.x = (agent.x * 100) + 25;
97+
this.y = (agent.y * 100) + 25;
98+
this.health = agent.health;
99+
this.namesMap = namesMap;
100+
this.generateDisplayName();
24101
}
102+
103+
generateDisplayName(namesMap) {
104+
if (!this.namesMap[this.id]) {
105+
this.namesMap[this.id] = uniqueNamesGenerator({
106+
dictionaries: [adjectives, colors],
107+
separator: '-',
108+
length: 2,
109+
});
110+
}
111+
}
25112
26113
run(sketch) {
27114
this.display(sketch);
28115
}
29116
30-
// Method to update position
31-
update(agent) {
32-
this.alive = agent.alive;
33-
this.health = agent.health;
34-
this.x = agent.x;
35-
this.y = agent.y;
36-
}
37-
38117
// Method to display
39118
display(sketch) {
40-
sketch.stroke(200, this.health * 10);
119+
if (this.health == 0) {
120+
sketch.text(this.health, this.x, this.y)
121+
return;
122+
}
123+
sketch.fill("blue");
41124
sketch.strokeWeight(2);
42-
sketch.fill(127, this.health * 5);
43-
sketch.ellipse(this.x * 100, this.y * 100, 5, 5);
44-
sketch.text(this.health, this.x * 100 + 5, this.y * 100 + 5)
125+
let radius = Math.max(5, this.health);
126+
sketch.ellipse(this.x, this.y, radius, radius);
127+
sketch.fill("black");
128+
sketch.text(this.namesMap[this.id] + "::" + this.health, this.x, this.y)
45129
}
46130
47131
// Is the particle still useful?
48-
isDead(){
132+
isDead() {
49133
return this.health <= 0;
50134
}
51135
}
52136
53137
class Cycle {
54138
55-
constructor(cycle, agents, food, sketch) {
139+
constructor(cycle, agents, foods, sketch, namesMap) {
56140
this.sketch = sketch;
57141
this.cycle = cycle;
58142
this.agents = agents;
59-
this.food = food;
143+
this.foods = foods;
144+
this.namesMap = namesMap;
145+
}
146+
147+
getAgents() {
148+
return this.agents || [];
60149
}
61150
62151
run(sketch) {
63-
if (!this.agents || this.agents.length == 0) {
64-
return;
152+
if (this.foods && this.foods.length > 0) {
153+
for (let i = this.foods.length-1; i >= 0; i--) {
154+
let food = new Food(this.foods[i], sketch);
155+
food.run(sketch);
156+
}
65157
}
66-
for (let i = this.agents.length-1; i >= 0; i--) {
67-
let agent = new Agent(this.agents[i], sketch);
68-
agent.run(sketch);
69-
if (agent.isDead()) {
70-
this.agent.splice(i, 1);
158+
159+
if (this.agents && this.agents.length > 0) {
160+
for (let i = this.agents.length-1; i >= 0; i--) {
161+
let agent = new Agent(this.agents[i], sketch, this.namesMap);
162+
agent.run(sketch);
71163
}
72164
}
73165
}
@@ -84,46 +176,45 @@ export default {
84176
data: () => ({
85177
system: {},
86178
cycles: [],
87-
currentCycle: 1,
88-
cycleSocket: {}
179+
currentCycle: 0,
180+
currentAgents: {},
181+
cycleSocket: {},
182+
paused: false,
183+
sketch: {},
184+
namesMap: {}
89185
}),
90186
computed: {
91187
92188
},
93189
methods: {
190+
mouseClicked(sketch) {
191+
sketch.ellipse(sketch.mouseX, sketch.mouseY, 5, 5);
192+
this.paused = !this.paused;
193+
if (this.paused) {
194+
sketch.noLoop();
195+
} else {
196+
sketch.loop();
197+
}
198+
},
94199
setup(sketch) {
95-
sketch.createCanvas(500, 500);
200+
sketch.noLoop();
201+
sketch.createCanvas(650, 550);
96202
this.cycleSocket = new Cycles(this.cycles);
203+
this.sketch = sketch;
97204
},
98205
draw(sketch) {
99-
sketch.frameRate(1)
206+
sketch.frameRate(1);
100207
sketch.background(51);
101-
sketch.text(this.currentCycle, 480, 480)
102-
console.log(this.cycles)
208+
103209
if (this.cycles && this.cycles[this.currentCycle]) {
104210
let cycle = this.cycles[this.currentCycle];
105-
new Cycle(cycle.cycle, cycle.agents, cycle.food, sketch).run(sketch);
106-
this.currentCycle = (this.currentCycle < this.cycles.length -1) ? this.currentCycle + 1 : 0;
211+
this.cycles[this.currentCycle].display = this.cycles[this.currentCycle].display || new Cycle(cycle.cycle, cycle.agents, cycle.foods, sketch, this.namesMap);
212+
this.currentAgents = this.cycles[this.currentCycle].display.agents;
213+
this.cycles[this.currentCycle].display.run(sketch);
214+
215+
this.currentCycle = (this.currentCycle < this.cycles.length - 1) ? this.currentCycle + 1 : 0;
107216
}
108217
},
109218
}
110219
};
111220
</script>
112-
113-
<!-- Add "scoped" attribute to limit CSS to this component only -->
114-
<style scoped>
115-
h3 {
116-
margin: 40px 0 0;
117-
}
118-
ul {
119-
list-style-type: none;
120-
padding: 0;
121-
}
122-
li {
123-
display: inline-block;
124-
margin: 0 10px;
125-
}
126-
a {
127-
color: #42b983;
128-
}
129-
</style>

0 commit comments

Comments
 (0)