function Trainer:get_inputs()
local dists = self.player:get_distances(self.world)
- local inputs = {}
- for i = 1, 16 do
- local v1 = dists[i * 2]
- local v2 = dists[(i * 2 + 1) % 32]
- local v3 = dists[(i * 2 - 1) % 32]
+ local DIST = CONF.ENEMY_SIZE * CONF.PLAYER_VISION_DISTANCE
- inputs[i] = 1 - ((0.5 * v1 + 0.25 * v2 + 0.25 * v3) / (CONF.ENEMY_SIZE * CONF.PLAYER_VISION_DISTANCE))
+ local inputs = {}
+ for i = 0, 15 do
+ local v1 = dists[i * 2 + 1] / DIST
+ local v2 = dists[((i * 2 + 1) % 32) + 1] / DIST
+ local v3 = dists[((i * 2 - 1) % 32) + 1] / DIST
+
+ if v1 > 0 then v1 = 1 - v1 end
+ if v1 < 0 then v1 = -1 - v1 end
+ if v2 > 0 then v2 = 1 - v2 end
+ if v2 < 0 then v2 = -1 - v2 end
+ if v3 > 0 then v3 = 1 - v3 end
+ if v3 < 0 then v3 = -1 - v3 end
+
+ inputs[i + 1] = 0.5 * v1 + 0.25 * v2 + 0.25 * v3
end
return inputs
end
function Trainer:update(...)
- local inputs = self:get_inputs()
-
for _ = 1, self.speed do
+ local inputs = self:get_inputs()
+
self.population_step = self.population_step(
self.population,
inputs,
y = y;
vx = vx;
vy = vy;
- life = 80;
+ life = 1.5;
alive = true;
}
function Bullet:update(dt, world)
world:move_entity(self, self.vx * dt, self.vy * dt)
- self.life = self.life - 1
+ self.life = self.life - dt
if self.life <= 0 then
world:remove_entity(self)
end
local dx = 0
local dy = 0
- local SPEED = 150
+ local SPEED = CONF.PLAYER_SPEED
if input.move_up then dy = dy - SPEED end
if input.move_down then dy = dy + SPEED end
if input.fire_right then firex = firex + 1 end
if firex ~= 0 or firey ~= 0 then
- self.fire_cooldown = 6
+ self.fire_cooldown = .1
local d = math.sqrt(math.sqrDist(0, 0, firex, firey))
firex = FIRE_SPEED * firex / d
self:fire(firex, firey, world)
end
else
- self.fire_cooldown = self.fire_cooldown - 1
+ self.fire_cooldown = self.fire_cooldown - dt
end
self.distances = self:get_distances(world)
local ty = self.y + dy * j
for _, e in ipairs(world.entities) do
- if e.ENTITY_TYPE == "Enemy" and math.rectcontains(e:get_rect(), tx, ty) then
+ if (e.ENTITY_TYPE == "Enemy" or e.ENTITY_TYPE == "Wall") and math.rectcontains(e:get_rect(), tx, ty) then
local ent_rect = e:get_rect()
local toggle = false
end
end
- table.insert(ret, math.sqrt(math.sqrDist(self.x, self.y, tx, ty)))
+ local d = math.sqrt(math.sqrDist(self.x, self.y, tx, ty))
+
+ if e.ENTITY_TYPE == "Wall" then
+ d = -d
+ end
+
+ table.insert(ret, d)
hit_entity = true
break
end
self.y + dy * CONF.PLAYER_VISION_DISTANCE * CONF.ENEMY_SIZE
)
- if self.distances[i + 1] > 0 then
- local d = self.distances[i + 1]
+ if math.abs(self.distances[i + 1]) > 0 then
+ local d = math.abs(self.distances[i + 1])
love.graphics.circle("fill", self.x + dx * d, self.y + dy * d, 8)
end
end
local dx = math.cos(a)
local dy = math.sin(a)
- local SPEED = 80
+ local SPEED = CONF.ENEMY_SPEED
world:move_entity(self, dx * dt * SPEED, dy * dt * SPEED)
end
function World:spawn_enemies(count)
for _ = 1, count do
- local vert = math.random(2) > 1
- local tmp = math.random(2) > 1
- local x = math.random(vert and 100 or 800) + (vert and (tmp and 600 or 0) or 0)
-
- vert = not vert
- tmp = math.random(2) > 1
- local y = math.random(vert and 100 or 600) + (vert and (tmp and 400 or 0) or 0)
+ local found = false
+ local x, y
+ repeat
+ local vert = math.random(2) > 1
+ local tmp = math.random(2) > 1
+ x = math.random(vert and 100 or 800) + (vert and (tmp and 600 or 0) or 0)
+
+ vert = not vert
+ tmp = math.random(2) > 1
+ y = math.random(vert and 100 or 600) + (vert and (tmp and 400 or 0) or 0)
+
+ if math.sqrDist(self.player.x, self.player.y, x, y) > 80 * 80 then
+ found = true
+ end
+ until found
local enemy = Enemy.new(x, y)
self:add_entity(enemy)