je suis en train de coder un programme qui simule l'évolution d'un groupe de bestioles en fonction des mutations de leur génome.
Et puis, là, je désespère de tomber tout le temps sur le même bug:
dans une fonction dist (a, b) qui retourne la distance entre les deux objets, ça me dit tout le temps que b.x n'existe pas (alors qu'aucun objet déclaré au cour de mon programme ne peut ne pas avoir de coordonnées).
voilà le code, avec l'espoir que quelqu'un connaisse la solution: ( attention : il est très long et très bordélique)
- Code: Select all
function on.resize (ww, hh)
w, h = ww, hh
cx,cy = 0, 0
clonagespeed = 20
consomationspeed = 2000
signlive = 64
obj = {}
for n = 1, 8 do
obj[#obj+1] = anim ( math.random (0, w)
, math.random (0, h)
, math.random (4, 8)
, randomgenom ()
)
end
for a = 1, 3 do
table.insert (obj, {t="food", x=math.random (1, w), y=math.random (1, h), energy=256})
end
timer.start (0.01)
end
function randomgenom ()
local g = {}
for a, b in pairs (limitstatus) do
g[a] =math.random (b[1], b[2])
end
return g
end
entities = {
[1] = "food"
, [2] = "poison"
, [3] = "anim"
, [4] = "signal"
}
genlist = {
"color"
, "capacity"
, "speed"
, "clonagerate"
, "range"
, "energyconsume"
, "feelsecurit"
, "imunity"
, "vampiric"
, "toxinecost"
, "producetoxine"
, "canfix"
, "canemitsignal"
, "candetect"
, "canreceivesignal"
, "attractby"
, "repulseby"
, "dowheneating"
, "dowheneated"
, "dowhenreceive"
, "dowhendetect"
}
comportementslist = {
[0] = "nothing"
, [1] = "go"
, [2] = "runaway"
, [3] = "clone"
, [4] = "emitsignal"
, [5] = "producetoxine"
, [6] = "fix"
}
limitstatus = {
color = {0, 16777215}
, capacity = {4, 16}
, speed = {1, 4}
, clonagerate = {-8, -4}
, range = {4, 64}
, energyconsume = {-9, -1}
, feelsecurit = {4, 256}
, imunity = {0, 9}
, producetoxine = {0, 9}
, vampiric = {0, 1}
, canfix = {0, 1}
, candetect = {0, 4}
, attractby = {0, 4}
, repulseby = {0, 4} -- valeur representant l'entite
, canemitsignal = {0, 1}
, canreceivesignal = {0, 1}
, toxinecost = {-99, 0}
, dowheneating = {0, #comportementslist}
, dowheneated = {0, #comportementslist}
, dowhenreceive = {0, #comportementslist}
, dowhendetect = {0, #comportementslist}
}
comportements = {
nothing = function () end
, go = function (o, x, y)
o.target = {x=x, y=y}
end
, runaway = function (o, x, y)
o.runfrom = {x=x, y=y}
end
, clone = function (o)
if o.cool < o.genom.clonagerate*clonagespeed then
o.energy = o.energy/2
table.insert (obj, anim (o.x+math.random (-4, 4), o.y+math.random (-4, 4), o.energy, mute (o.genom)))
o.cool = o.genom.clonagerate
end
end
, emitsignal = function (o, x, y)
table.insert (obj, {t="signal", x=x, y=y, signlive})
end
, producetoxine = function (o, x, y, lvl)
table.insert (obj, {t=toxin, lvl = lvl, x=x, y=y})
end
, fix = function (o, x, y)
end
}
anim = class ()
function anim: init (x, y, energy, genom)
self.t = "anim"
self.x = x
self.y = y
self.energy = energy
self.genom = genom
self.cool = self.genom.clonagerate
end
function anim: paint (gc)
gc: setColorRGB (self.genom.color)
gc: fillArc (self.x-self.energy/2, self.y-self.energy/2, self.energy, self.energy, 0, 360)
if iseating then
setColorRGB (255, 0, 0)
else
gc: setColorRGB (0)
end
gc: drawArc (self.x-self.genom.capacity/2, self.y-self.genom.capacity/2, self.genom.capacity, self.genom.capacity, 0, 360)
end
function anim: move ()
if self.target and not self.runfrom then
if dist (self, self.target) < self.genom.range then
self.target = false
else
if self.target.x > self.x then
self.x = self.x+self.genom.speed
elseif self.target.x < self.x then
self.x = self.x-self.genom.speed
end
if self.target.y > self.y then
self.y = self.y+self.genom.speed
elseif self.target.y < self.y then
self.y = self.y-self.genom.speed
end
end
end
if self.runfrom then
if dist (self, self.runfrom) < self.genom.feelsecurit then
self.runfrom = false
else
if self.runfrom.x > self.x then
self.x = self.x+self.genom.speed
elseif self.runfrom.x < self.x then
self.x = self.x-self.genom.speed
end
if self.runfrom.y > self.y then
self.y = self.y+self.genom.speed
elseif self.runfrom.y < self.y then
self.y = self.y-self.genom.speed
end
end
end
if not self.target and not self.runfrom then
self.target = {x=math.random (1, w), y = math.random (1, h)}
end
end
function anim: eat ()
local f = false
for a, b in pairs (obj) do
if b.t == "food"
and dist (self, b) < self.genom.range*10 then
f = b
break
end
end
if not f and self.genom.vampiric then
for a, b in pairs (obj) do
if b ~= self
and b.t == "anim"
and dist (self, b) < self.genom.range*10 then
f = b
break
end
end
end
if f then
f.energy = f.energy-1
self.energy = self.energy+1
self.iseating = true
end
end
function anim: reaction ()
if self.iseating then
comportements[comportementslist[self.genom.dowheneating]] (self)
end
if self.iseated then
comportements[comportementslist[self.genom.dowheneated]] (self)
end
if self.genom.canreceivesignal ~= 0 then
for a, b in pairs (obj) do
if b.t == "signal" then
comportements[comportementslist[self.genom.dowhenreceive]] (self, b.x, b.y)
end
end
end
if self.genom.candetect ~= 0 then
for a, b in pairs (obj) do
if entities[self.genom.candetect] == b.t
and dist (self, b) < self.genom.range then
comportements[comportementslist[self.genom.dowhendetect]] (self, b.x, b.y)
end
end
end
end
function dist (a, b)
return math.sqrt(math.pow (
a.x
-b.x, 2) + math.pow (
a.y
-b.y, 2))
end
function mute (genom)
local gen = {}
for a, b in pairs (genom) do
gen[a] = b
end
local n = genlist[math.random (1, #genlist)]
local m = math.random (-1, 1)
gen[n] = gen[n] + m
if gen[n] < limitstatus[n][1]
or gen[n] > limitstatus[n][2] then
gen[n] = genom[n]
else
while true do
local r = genlist[math.random (1, #genlist)]
if limitstatus[r][1] <= gen[r] then
break
else
gen[r] = gen[r]-1
end
end
end
return gen
end
function on.paint (gc)
for a, b in pairs (obj) do
if b.t == "anim" then
b.cool = b.cool-1
b: eat ()
b: move ()
b: reaction ()
die (a, b)
b: paint (gc)
b.energy = b.energy+b.genom.energyconsume/consomationspeed
elseif b.t and b.x and b.y then
die (a, b)
draw[b.t] (gc, b.x, b.y)
if b.t == "signal" then
table.remove (obj, a)
end
end
end
end
draw = {
food = function (gc, x, y)
gc: setColorRGB (255, 255, 0)
gc: fillRect (x-4, y-4, 4, 4)
end
, poison = function (gc, x, y)
gc: setColorRGB (0, 255, 0)
gc: fillRect (x-4, y-4, 4, 4)
end
, signal = function (gc, x, y)
gc: setColorRGB (0)
gc: drawRect (x-4, y-4, 4, 4)
end
}
function on.timer ()
platform.window: invalidate ()
end
function on.mouseMove (xx, yy)
cx, cy = xx, yy
end
function on.mouseDown ()
table.insert (obj, {t="food", x=cx, y=cy, energy = 256})
end
function die (a, b)
if b.energy and b.energy < 1 then
table.remove (obj, a)
end
end