MAJOR bug fixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 17 Mar 2019 05:48:58 +0000 (00:48 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 17 Mar 2019 05:48:58 +0000 (00:48 -0500)
conf.lua
main.lua
src/stats.lua
src/trainer.lua
src/world.lua

index d0e6318ddb9886559ab610425d4e064d3b2d8cfb..97fab4ed454b5f99109f29d65f228dd019aef1e1 100644 (file)
--- a/conf.lua
+++ b/conf.lua
@@ -63,6 +63,9 @@ return {
 
        -- BEHAVIOR PROPERTIES
 
+       PLAYER_SPEED = 150;
+       ENEMY_SPEED = 100;
+
        PLAYER_VISION_SEGMENTS = 32;
        PLAYER_VISION_DISTANCE = 20;
 
@@ -86,8 +89,8 @@ return {
 
        -- REWARD / PUNISHMENT PROPERTIES
 
-       POINTS_PER_KILL = 100;
-       POINTS_PER_ROUND_END = 1000;
-       POINTS_PER_BULLET = -1;
-       POINTS_PER_MOVEMENT = 1;
+       POINTS_PER_KILL = -100;
+       POINTS_PER_ROUND_END = 0;
+       POINTS_PER_BULLET = -5;
+       POINTS_PER_MOVEMENT = 10;
 }
index ebd675aac516ad31878e18261b204bfbc76865ef..32f5a2db926f48bc0016d79820361e55ad50eb7b 100644 (file)
--- a/main.lua
+++ b/main.lua
@@ -139,7 +139,7 @@ local function draw_network(net, x, y, scale)
 
        for _, v in pairs(net.neurons) do
                local c = v.value
-               local r = c < 0 and c or 0
+               local r = c < 0 and -c or 0
                local b = c > 0 and c or 0
                local g = 0
 
@@ -164,7 +164,7 @@ local function draw_network(net, x, y, scale)
                        local y2 = other.y + 12
 
                        local col = { 1, 0, 0 }
-                       if conn.weight > 0 then
+                       if conn.weight * other.value> 0 then
                                col = { 0, 0, 1 }
                        end
 
index 907b34cdc19cb588168b55322be8d858832a2186..ddf6b21d0e6cd10a546dfb5e2f31bd10fa21241f 100644 (file)
@@ -85,7 +85,7 @@ function Stats:get_points(x, y, w, h)
        local points = {}
 
        for i, v in ipairs(self.data) do
-               table.insert(points, { (i - 1) * delta + x, low - h * (v / self.rng) })
+               table.insert(points, { (i - 1) * delta + x, low - h * ((v - self.min) / self.rng) })
        end
 
        return points
index afbe84123203f994db6cfcd77a82f28e8a2002de..51bf5c542e66cab7a05d25870ab9d0a2214d2afe 100644 (file)
@@ -43,13 +43,22 @@ end
 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
@@ -118,9 +127,9 @@ function Trainer:post_evolution(_, _, gen_stats)
 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,
index 15ea87499b4768477cc9dd585fb352414215526c..973a8922e7c14d86e8cd3ee1014813d0b86d65bf 100644 (file)
@@ -14,7 +14,7 @@ function Bullet.new(x, y, vx, vy)
                y = y;
                vx = vx;
                vy = vy;
-               life = 80;
+               life = 1.5;
                alive = true;
        }
 
@@ -25,7 +25,7 @@ end
 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
@@ -102,7 +102,7 @@ function Player:update(dt, world, input)
        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
@@ -123,7 +123,7 @@ function Player:update(dt, world, input)
                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
@@ -132,7 +132,7 @@ function Player:update(dt, world, input)
                        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)
@@ -171,7 +171,7 @@ function Player: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
@@ -188,7 +188,13 @@ function Player:get_distances(world)
                                                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
@@ -219,8 +225,8 @@ function Player:draw()
                        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
@@ -251,7 +257,7 @@ function Enemy:update(dt, world)
        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
 
@@ -436,13 +442,21 @@ 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)