-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPredatorPrey.py
182 lines (158 loc) · 5.96 KB
/
PredatorPrey.py
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
import random
import sys
import copy
random.seed(None)
class Node:
species = None
x = None
y = None
health = None
def __init__(self, spec=None):
if spec is not None:
self.species = spec
else:
self.species = 0
self.x = None
self.y = None
self.health = self.species*2
def set_location(self, pos_x, pos_y):
self.x = pos_x
self.y = pos_y
def set_species(self, num):
if num == 0 or num == 1 or num == 2:
self.species = num
if num is 0: # Blank
self.health = None
if num is 1: # Predator
self.health = 2
if num is 2: # Prey
self.health = 4
else:
sys.stderr.write('Species not correct, do not do math with them.')
self.species = 0
def move_here(self, species, health):
if species == 0 or species == 1 or species == 2:
self.species = species
if species is 0: # Blank
self.health = health
if species is 1: # Predator
self.health = health
if species is 2: # Prey
self.health = health
else:
sys.stderr.write('Species not correct, do not do math with them.')
self.species = 0
def prey_eat(self):
self.species = 1
def prey_reproduce(self):
self.species = 2
self.health = 1
class Map:
height = 100
width = 100
play_board = []
def __init__(self):
prey = 0
predator = 0
empty = 0
for x in range(self.width):
row = []
for y in range(self.height):
i = random.randint(0, 10)
if i <= 7:
row.append(Node(2))
prey += 1
elif i <= 9:
row.append(Node(1))
predator += 1
else:
row.append(Node(0))
empty += 1
self.play_board.append(row)
print('Map created')
print('Prey: ', prey)
print('Predator: ', predator)
print('Empty: ', empty)
print('Width: ', len(self.play_board))
print('Height of row 5: ', len(self.play_board[5]))
def get_board(self):
return self.play_board
def turn(self):
pb = self.play_board
[[self.check_neighbors(x, y, pb[x][y]) for y in range(0, self.height)] for x in range(0, self.width)]
# Returns the neighbors of a node, If node is on edge this wraps
def get_neighbors(self, x, y):
top = self.play_board[x][(y - 1) % self.height]
tr = self.play_board[(x + 1) % self.width][(y - 1) % self.height]
right = self.play_board[(x + 1) % self.width][y]
br = self.play_board[(x + 1) % self.width][(y + 1) % self.height]
bottom = self.play_board[x][(y + 1) % self.height]
bl = self.play_board[(x - 1) % self.width][(y + 1) % self.height]
left = self.play_board[(x - 1) % self.width][y]
tl = self.play_board[(x - 1) % self.width][(y - 1) % self.height]
neighbors = [top, tr, right, br, bottom, bl, left, tl]
return neighbors
#
# PREDATOR AND PREY CELLULAR AUTOMATON
# The world is grid of cells, with 3 possibilities: Predator(Red, 1), Prey(Green, 2), or Empty(Black, 0).
# Both predator and prey have a set health, that changes over time.
# The simulation works in steps, with the following rules:
# -For prey:
# -Tries to move in a random direction.
# -Health increases.
# -When health reaches a threshold:
# -They will reproduce, creating a new "Prey"
# -Their health resets to 1
# -For predator:
# -Tries to move in a random direction.
# -Health decreases.
# -When health reaches 0, they die and turn into "Nothing".
# -If the adjacent square is a prey:
# -They will eat it, turning it into a "predator" (reproducing)
# -Their health will increase by the amount of health the eaten prey had
def check_neighbors(self, x, y, node):
# If the node is empty no checks are performed
if node.species is 0:
return
if node.species is 1:
# This is a predator. Check for prey if no prey reduce health/die
neighbors = self.get_neighbors(x, y)
prey = []
open_ = []
for neigh in neighbors:
if neigh.species is 2:
prey.append(neigh)
if neigh.species is 0:
open_.append(neigh)
open_length = len(open_)
if len(prey) is 0:
if node.health > 0 and open_length > 0:
node.health -= 1
open_[random.randint(0, (open_length-1))].move_here(1, node.health)
node.set_species(0)
return
else:
target = prey[random.randint(0, (len(prey)-1))]
if node.health >= target.health:
target.prey_eat()
if node.health is None or node.health <= 0:
node.species = 0
return
if node.species is 2:
# Check for overpopulation/health This is prey
neighbors = self.get_neighbors(x, y)
open_spots = []
for neigh in neighbors:
if neigh.species is 0:
open_spots.append(neigh)
count = len(open_spots)
if count >= 7 or count < 1:
node.health -= 2
if node.health is None or node.health is 0:
node.species = 0
return
if node.health > 6 and len(open_spots) >= 1:
open_spots[random.randint(0, (len(open_spots))-1)].prey_reproduce()
node.health = 4
return
node.health += 1