parser: fix `for i, mut val in vals {; examples: vfmt flappybird
parent
bcdf3ca0cf
commit
0d43ff2453
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
module main
|
module main
|
||||||
|
|
||||||
import gg
|
import gg
|
||||||
|
@ -7,26 +6,24 @@ import os
|
||||||
import time
|
import time
|
||||||
import math
|
import math
|
||||||
import rand
|
import rand
|
||||||
|
|
||||||
import neuroevolution
|
import neuroevolution
|
||||||
|
|
||||||
const (
|
const (
|
||||||
win_width = 500
|
win_width = 500
|
||||||
win_height = 512
|
win_height = 512
|
||||||
timer_period = 24 // ms
|
timer_period = 24 // ms
|
||||||
)
|
)
|
||||||
|
|
||||||
struct Bird {
|
struct Bird {
|
||||||
mut:
|
mut:
|
||||||
x f64 = 80
|
x f64 = 80
|
||||||
y f64 = 250
|
y f64 = 250
|
||||||
width f64 = 40
|
width f64 = 40
|
||||||
height f64 = 30
|
height f64 = 30
|
||||||
|
alive bool = true
|
||||||
alive bool = true
|
gravity f64
|
||||||
gravity f64
|
|
||||||
velocity f64 = 0.3
|
velocity f64 = 0.3
|
||||||
jump f64 = -6
|
jump f64 = -6
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut b Bird) flap() {
|
fn (mut b Bird) flap() {
|
||||||
|
@ -43,12 +40,8 @@ fn (b Bird) is_dead(height f64, pipes []Pipe) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for pipe in pipes {
|
for pipe in pipes {
|
||||||
if !(
|
if !(b.x > pipe.x + pipe.width ||
|
||||||
b.x > pipe.x + pipe.width ||
|
b.x + b.width < pipe.x || b.y > pipe.y + pipe.height || b.y + b.height < pipe.y) {
|
||||||
b.x + b.width < pipe.x ||
|
|
||||||
b.y > pipe.y + pipe.height ||
|
|
||||||
b.y + b.height < pipe.y
|
|
||||||
) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,11 +50,11 @@ fn (b Bird) is_dead(height f64, pipes []Pipe) bool {
|
||||||
|
|
||||||
struct Pipe {
|
struct Pipe {
|
||||||
mut:
|
mut:
|
||||||
x f64 = 80
|
x f64 = 80
|
||||||
y f64 = 250
|
y f64 = 250
|
||||||
width f64 = 40
|
width f64 = 40
|
||||||
height f64 = 30
|
height f64 = 30
|
||||||
speed f64 = 3
|
speed f64 = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut p Pipe) update() {
|
fn (mut p Pipe) update() {
|
||||||
|
@ -74,28 +67,25 @@ fn (p Pipe) is_out() bool {
|
||||||
|
|
||||||
struct App {
|
struct App {
|
||||||
mut:
|
mut:
|
||||||
gg &gg.Context
|
gg &gg.Context
|
||||||
background gg.Image
|
background gg.Image
|
||||||
bird gg.Image
|
bird gg.Image
|
||||||
pipetop gg.Image
|
pipetop gg.Image
|
||||||
pipebottom gg.Image
|
pipebottom gg.Image
|
||||||
|
pipes []Pipe
|
||||||
pipes []Pipe
|
birds []Bird
|
||||||
birds []Bird
|
score int
|
||||||
score int
|
max_score int
|
||||||
max_score int
|
width f64 = win_width
|
||||||
width f64 = win_width
|
height f64 = win_height
|
||||||
height f64 = win_height
|
spawn_interval f64 = 90
|
||||||
spawn_interval f64 = 90
|
interval f64
|
||||||
interval f64
|
nv neuroevolution.Generations
|
||||||
|
gen []neuroevolution.Network
|
||||||
nv neuroevolution.Generations
|
alives int
|
||||||
gen []neuroevolution.Network
|
generation int
|
||||||
alives int
|
|
||||||
generation int
|
|
||||||
|
|
||||||
background_speed f64 = 0.5
|
background_speed f64 = 0.5
|
||||||
background_x f64
|
background_x f64
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut app App) start() {
|
fn (mut app App) start() {
|
||||||
|
@ -104,7 +94,6 @@ fn (mut app App) start() {
|
||||||
app.pipes = []
|
app.pipes = []
|
||||||
app.birds = []
|
app.birds = []
|
||||||
app.gen = app.nv.generate()
|
app.gen = app.nv.generate()
|
||||||
|
|
||||||
for _ in 0 .. app.gen.len {
|
for _ in 0 .. app.gen.len {
|
||||||
app.birds << Bird{}
|
app.birds << Bird{}
|
||||||
}
|
}
|
||||||
|
@ -118,14 +107,12 @@ fn (app &App) is_it_end() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut app App) update() {
|
fn (mut app App) update() {
|
||||||
app.background_x += app.background_speed
|
app.background_x += app.background_speed
|
||||||
mut next_holl := f64(0)
|
mut next_holl := f64(0)
|
||||||
|
|
||||||
if app.birds.len > 0 {
|
if app.birds.len > 0 {
|
||||||
for i := 0; i < app.pipes.len; i += 2 {
|
for i := 0; i < app.pipes.len; i += 2 {
|
||||||
if app.pipes[i].x + app.pipes[i].width > app.birds[0].x {
|
if app.pipes[i].x + app.pipes[i].width > app.birds[0].x {
|
||||||
|
@ -134,8 +121,7 @@ fn (mut app App) update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for j, mut bird in app.birds {
|
||||||
for mut j, bird in app.birds {
|
|
||||||
if bird.alive {
|
if bird.alive {
|
||||||
inputs := [
|
inputs := [
|
||||||
bird.y / app.height,
|
bird.y / app.height,
|
||||||
|
@ -145,9 +131,7 @@ fn (mut app App) update() {
|
||||||
if res[0] > 0.5 {
|
if res[0] > 0.5 {
|
||||||
bird.flap()
|
bird.flap()
|
||||||
}
|
}
|
||||||
|
|
||||||
bird.update()
|
bird.update()
|
||||||
|
|
||||||
if bird.is_dead(app.height, app.pipes) {
|
if bird.is_dead(app.height, app.pipes) {
|
||||||
bird.alive = false
|
bird.alive = false
|
||||||
app.alives--
|
app.alives--
|
||||||
|
@ -156,10 +140,8 @@ fn (mut app App) update() {
|
||||||
app.start()
|
app.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for k := 0; k < app.pipes.len; k++ {
|
for k := 0; k < app.pipes.len; k++ {
|
||||||
app.pipes[k].update()
|
app.pipes[k].update()
|
||||||
if app.pipes[k].is_out() {
|
if app.pipes[k].is_out() {
|
||||||
|
@ -167,44 +149,35 @@ fn (mut app App) update() {
|
||||||
k--
|
k--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.interval == 0 {
|
if app.interval == 0 {
|
||||||
delta_bord := f64(50)
|
delta_bord := f64(50)
|
||||||
pipe_holl := f64(120)
|
pipe_holl := f64(120)
|
||||||
holl_position := math.round(rand.f64() * (app.height - delta_bord * 2.0 - pipe_holl)) + delta_bord
|
holl_position := math.round(rand.f64() *
|
||||||
|
(app.height - delta_bord * 2.0 - pipe_holl)) + delta_bord
|
||||||
app.pipes << Pipe{
|
app.pipes << Pipe{
|
||||||
x: app.width
|
x: app.width
|
||||||
y: 0
|
y: 0
|
||||||
height: holl_position
|
height: holl_position
|
||||||
}
|
}
|
||||||
|
|
||||||
app.pipes << Pipe{
|
app.pipes << Pipe{
|
||||||
x: app.width
|
x: app.width
|
||||||
y: holl_position + pipe_holl
|
y: holl_position + pipe_holl
|
||||||
height: app.height
|
height: app.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.interval++
|
app.interval++
|
||||||
|
|
||||||
if app.interval == app.spawn_interval {
|
if app.interval == app.spawn_interval {
|
||||||
app.interval = 0
|
app.interval = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
app.score++
|
app.score++
|
||||||
app.max_score = if app.score > app.max_score {
|
app.max_score = if app.score > app.max_score { app.score } else { app.max_score }
|
||||||
app.score
|
|
||||||
} else {
|
|
||||||
app.max_score
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
mut app := &App{
|
mut app := &App{
|
||||||
gg: 0
|
gg: 0
|
||||||
}
|
}
|
||||||
app.gg = gg.new_context({
|
app.gg = gg.new_context(
|
||||||
bg_color: gx.white
|
bg_color: gx.white
|
||||||
width: win_width
|
width: win_width
|
||||||
height: win_height
|
height: win_height
|
||||||
|
@ -215,7 +188,7 @@ fn main() {
|
||||||
user_data: app
|
user_data: app
|
||||||
init_fn: init_images
|
init_fn: init_images
|
||||||
font_path: os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')
|
font_path: os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')
|
||||||
})
|
)
|
||||||
app.nv = neuroevolution.Generations{
|
app.nv = neuroevolution.Generations{
|
||||||
population: 50
|
population: 50
|
||||||
network: [2, 2, 1]
|
network: [2, 2, 1]
|
||||||
|
@ -248,26 +221,28 @@ fn frame(app &App) {
|
||||||
fn (app &App) display() {
|
fn (app &App) display() {
|
||||||
for i := 0; i < int(math.ceil(app.width / app.background.width) + 1.0); i++ {
|
for i := 0; i < int(math.ceil(app.width / app.background.width) + 1.0); i++ {
|
||||||
background_x := i * app.background.width - math.floor(int(app.background_x) % int(app.background.width))
|
background_x := i * app.background.width - math.floor(int(app.background_x) % int(app.background.width))
|
||||||
app.gg.draw_image(f32(background_x), 0, app.background.width, app.background.height, app.background)
|
app.gg.draw_image(f32(background_x), 0, app.background.width, app.background.height,
|
||||||
|
app.background)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, pipe in app.pipes {
|
for i, pipe in app.pipes {
|
||||||
if i % 2 == 0 {
|
if i % 2 == 0 {
|
||||||
app.gg.draw_image(f32(pipe.x), f32(pipe.y + pipe.height - app.pipetop.height), app.pipetop.width, app.pipetop.height, app.pipetop)
|
app.gg.draw_image(f32(pipe.x), f32(pipe.y + pipe.height - app.pipetop.height),
|
||||||
|
app.pipetop.width, app.pipetop.height, app.pipetop)
|
||||||
} else {
|
} else {
|
||||||
app.gg.draw_image(f32(pipe.x), f32(pipe.y), app.pipebottom.width, app.pipebottom.height, app.pipebottom)
|
app.gg.draw_image(f32(pipe.x), f32(pipe.y), app.pipebottom.width, app.pipebottom.height,
|
||||||
|
app.pipebottom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for bird in app.birds {
|
for bird in app.birds {
|
||||||
if bird.alive {
|
if bird.alive {
|
||||||
app.gg.draw_image(f32(bird.x), f32(bird.y), app.bird.width, app.bird.height, app.bird)
|
app.gg.draw_image(f32(bird.x), f32(bird.y), app.bird.width, app.bird.height,
|
||||||
|
app.bird)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.gg.draw_text_def(10 ,25, 'Score: $app.score')
|
app.gg.draw_text_def(10, 25, 'Score: $app.score')
|
||||||
app.gg.draw_text_def(10 ,50, 'Max Score: $app.max_score')
|
app.gg.draw_text_def(10, 50, 'Max Score: $app.max_score')
|
||||||
app.gg.draw_text_def(10 ,75, 'Generation: $app.generation')
|
app.gg.draw_text_def(10, 75, 'Generation: $app.generation')
|
||||||
app.gg.draw_text_def(10 ,100, 'Alive: $app.alives / $app.nv.population')
|
app.gg.draw_text_def(10, 100, 'Alive: $app.alives / $app.nv.population')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (app &App) draw() {
|
fn (app &App) draw() {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
module neuroevolution
|
module neuroevolution
|
||||||
|
|
||||||
import rand
|
import rand
|
||||||
|
@ -19,7 +18,7 @@ fn round(a int, b f64) int {
|
||||||
|
|
||||||
struct Neuron {
|
struct Neuron {
|
||||||
mut:
|
mut:
|
||||||
value f64
|
value f64
|
||||||
weights []f64
|
weights []f64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ fn (mut n Neuron) populate(nb int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Layer {
|
struct Layer {
|
||||||
id int
|
id int
|
||||||
mut:
|
mut:
|
||||||
neurons []Neuron
|
neurons []Neuron
|
||||||
}
|
}
|
||||||
|
@ -49,12 +48,10 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut n Network) populate(network []int) {
|
fn (mut n Network) populate(network []int) {
|
||||||
|
|
||||||
assert network.len >= 2
|
assert network.len >= 2
|
||||||
input := network[0]
|
input := network[0]
|
||||||
hiddens := network.slice(1, network.len - 1)
|
hiddens := network.slice(1, network.len - 1)
|
||||||
output := network[network.len - 1]
|
output := network[network.len - 1]
|
||||||
|
|
||||||
mut index := 0
|
mut index := 0
|
||||||
mut previous_neurons := 0
|
mut previous_neurons := 0
|
||||||
mut input_layer := Layer{
|
mut input_layer := Layer{
|
||||||
|
@ -62,7 +59,6 @@ fn (mut n Network) populate(network []int) {
|
||||||
}
|
}
|
||||||
input_layer.populate(input, previous_neurons)
|
input_layer.populate(input, previous_neurons)
|
||||||
n.layers << input_layer
|
n.layers << input_layer
|
||||||
|
|
||||||
previous_neurons = input
|
previous_neurons = input
|
||||||
index++
|
index++
|
||||||
for hidden in hiddens {
|
for hidden in hiddens {
|
||||||
|
@ -74,7 +70,6 @@ fn (mut n Network) populate(network []int) {
|
||||||
n.layers << hidden_layer
|
n.layers << hidden_layer
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
|
|
||||||
mut output_layer := Layer{
|
mut output_layer := Layer{
|
||||||
id: index
|
id: index
|
||||||
}
|
}
|
||||||
|
@ -83,7 +78,6 @@ fn (mut n Network) populate(network []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (n Network) get_save() Save {
|
fn (n Network) get_save() Save {
|
||||||
|
|
||||||
mut save := Save{}
|
mut save := Save{}
|
||||||
for layer in n.layers {
|
for layer in n.layers {
|
||||||
save.neurons << layer.neurons.len
|
save.neurons << layer.neurons.len
|
||||||
|
@ -97,11 +91,9 @@ fn (n Network) get_save() Save {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut n Network) set_save(save Save) {
|
fn (mut n Network) set_save(save Save) {
|
||||||
|
|
||||||
mut previous_neurons := 0
|
mut previous_neurons := 0
|
||||||
mut index := 0
|
mut index := 0
|
||||||
mut index_weights := 0
|
mut index_weights := 0
|
||||||
|
|
||||||
n.layers = []
|
n.layers = []
|
||||||
for save_neuron in save.neurons {
|
for save_neuron in save.neurons {
|
||||||
mut layer := Layer{
|
mut layer := Layer{
|
||||||
|
@ -123,13 +115,10 @@ fn (mut n Network) set_save(save Save) {
|
||||||
pub fn (mut n Network) compute(inputs []f64) []f64 {
|
pub fn (mut n Network) compute(inputs []f64) []f64 {
|
||||||
assert n.layers.len > 0
|
assert n.layers.len > 0
|
||||||
assert inputs.len == n.layers[0].neurons.len
|
assert inputs.len == n.layers[0].neurons.len
|
||||||
|
|
||||||
for i, input in inputs {
|
for i, input in inputs {
|
||||||
n.layers[0].neurons[i].value = input
|
n.layers[0].neurons[i].value = input
|
||||||
}
|
}
|
||||||
|
|
||||||
mut prev_layer := n.layers[0]
|
mut prev_layer := n.layers[0]
|
||||||
|
|
||||||
for i in 1 .. n.layers.len {
|
for i in 1 .. n.layers.len {
|
||||||
for j, neuron in n.layers[i].neurons {
|
for j, neuron in n.layers[i].neurons {
|
||||||
mut sum := f64(0)
|
mut sum := f64(0)
|
||||||
|
@ -140,13 +129,11 @@ pub fn (mut n Network) compute(inputs []f64) []f64 {
|
||||||
}
|
}
|
||||||
prev_layer = n.layers[i]
|
prev_layer = n.layers[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
mut outputs := []f64{}
|
mut outputs := []f64{}
|
||||||
mut last_layer := n.layers[n.layers.len - 1]
|
mut last_layer := n.layers[n.layers.len - 1]
|
||||||
for neuron in last_layer.neurons {
|
for neuron in last_layer.neurons {
|
||||||
outputs << neuron.value
|
outputs << neuron.value
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputs
|
return outputs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +151,7 @@ fn (s Save) clone() Save {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Genome {
|
struct Genome {
|
||||||
score int
|
score int
|
||||||
network Save
|
network Save
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,65 +161,48 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Generation) add_genome(genome Genome) {
|
fn (mut g Generation) add_genome(genome Genome) {
|
||||||
|
|
||||||
mut i := 0
|
mut i := 0
|
||||||
|
|
||||||
for gg in g.genomes {
|
for gg in g.genomes {
|
||||||
if genome.score > gg.score {
|
if genome.score > gg.score {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
g.genomes.insert(i, genome)
|
g.genomes.insert(i, genome)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g1 Genome) breed(g2 Genome, nb_child int) []Save {
|
fn (g1 Genome) breed(g2 Genome, nb_child int) []Save {
|
||||||
mut datas := []Save{}
|
mut datas := []Save{}
|
||||||
|
|
||||||
for _ in 0 .. nb_child {
|
for _ in 0 .. nb_child {
|
||||||
|
|
||||||
mut data := g1.network.clone()
|
mut data := g1.network.clone()
|
||||||
|
|
||||||
for i, weight in g2.network.weights {
|
for i, weight in g2.network.weights {
|
||||||
if rand.f64() <= 0.5 {
|
if rand.f64() <= 0.5 {
|
||||||
data.weights[i] = weight
|
data.weights[i] = weight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, _ in data.weights {
|
for i, _ in data.weights {
|
||||||
if rand.f64() <= 0.1 {
|
if rand.f64() <= 0.1 {
|
||||||
data.weights[i] += (rand.f64() * 2 - 1) * 0.5
|
data.weights[i] += (rand.f64() * 2 - 1) * 0.5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
datas << data
|
datas << data
|
||||||
}
|
}
|
||||||
|
|
||||||
return datas
|
return datas
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g Generation) next(population int) []Save {
|
fn (g Generation) next(population int) []Save {
|
||||||
|
|
||||||
mut nexts := []Save{}
|
mut nexts := []Save{}
|
||||||
|
|
||||||
if population == 0 {
|
if population == 0 {
|
||||||
return nexts
|
return nexts
|
||||||
}
|
}
|
||||||
|
|
||||||
keep := round(population, 0.2)
|
keep := round(population, 0.2)
|
||||||
|
|
||||||
for i in 0 .. keep {
|
for i in 0 .. keep {
|
||||||
if nexts.len < population {
|
if nexts.len < population {
|
||||||
nexts << g.genomes[i].network.clone()
|
nexts << g.genomes[i].network.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
random := round(population, 0.2)
|
random := round(population, 0.2)
|
||||||
|
for _ in 0 .. random {
|
||||||
for _ in 0 .. random {
|
|
||||||
|
|
||||||
if nexts.len < population {
|
if nexts.len < population {
|
||||||
mut n := g.genomes[0].network.clone()
|
mut n := g.genomes[0].network.clone()
|
||||||
for k, _ in n.weights {
|
for k, _ in n.weights {
|
||||||
|
@ -241,7 +211,6 @@ fn (g Generation) next(population int) []Save {
|
||||||
nexts << n
|
nexts << n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mut max := 0
|
mut max := 0
|
||||||
out: for {
|
out: for {
|
||||||
for i in 0 .. max {
|
for i in 0 .. max {
|
||||||
|
@ -258,14 +227,13 @@ fn (g Generation) next(population int) []Save {
|
||||||
max = 0
|
max = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nexts
|
return nexts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Generations {
|
pub struct Generations {
|
||||||
pub:
|
pub:
|
||||||
population int
|
population int
|
||||||
network []int
|
network []int
|
||||||
mut:
|
mut:
|
||||||
generations []Generation
|
generations []Generation
|
||||||
}
|
}
|
||||||
|
@ -277,7 +245,6 @@ fn (mut gs Generations) first() []Save {
|
||||||
nn.populate(gs.network)
|
nn.populate(gs.network)
|
||||||
out << nn.get_save()
|
out << nn.get_save()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs.generations << Generation{}
|
gs.generations << Generation{}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
@ -299,24 +266,16 @@ fn (mut gs Generations) restart() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut gs Generations) generate() []Network {
|
pub fn (mut gs Generations) generate() []Network {
|
||||||
|
saves := if gs.generations.len == 0 { gs.first() } else { gs.next() }
|
||||||
saves := if gs.generations.len == 0 {
|
|
||||||
gs.first()
|
|
||||||
} else {
|
|
||||||
gs.next()
|
|
||||||
}
|
|
||||||
|
|
||||||
mut nns := []Network{}
|
mut nns := []Network{}
|
||||||
for save in saves {
|
for save in saves {
|
||||||
mut nn := Network{}
|
mut nn := Network{}
|
||||||
nn.set_save(save)
|
nn.set_save(save)
|
||||||
nns << nn
|
nns << nn
|
||||||
}
|
}
|
||||||
|
|
||||||
if gs.generations.len >= 2 {
|
if gs.generations.len >= 2 {
|
||||||
gs.generations.delete(0)
|
gs.generations.delete(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nns
|
return nns
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,4 +285,3 @@ pub fn (mut gs Generations) network_score(network Network, score int) {
|
||||||
network: network.get_save()
|
network: network.get_save()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,31 @@ pub fn (mut ctx Context) create_image(file string) Image {
|
||||||
return img
|
return img
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO copypasta
|
||||||
|
pub fn (mut ctx Context) create_image_with_size(file string, width int, height int) Image {
|
||||||
|
if !C.sg_isvalid() {
|
||||||
|
// Sokol is not initialized yet, add stbi object to a queue/cache
|
||||||
|
// ctx.image_queue << file
|
||||||
|
stb_img := stbi.load(file) or { return Image{} }
|
||||||
|
img := Image{
|
||||||
|
width: width
|
||||||
|
height: height
|
||||||
|
nr_channels: stb_img.nr_channels
|
||||||
|
ok: false
|
||||||
|
data: stb_img.data
|
||||||
|
ext: stb_img.ext
|
||||||
|
path: file
|
||||||
|
id: ctx.image_cache.len
|
||||||
|
}
|
||||||
|
ctx.image_cache << img
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
mut img := create_image(file)
|
||||||
|
img.id = ctx.image_cache.len
|
||||||
|
ctx.image_cache << img
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
|
||||||
// TODO remove this
|
// TODO remove this
|
||||||
fn create_image(file string) Image {
|
fn create_image(file string) Image {
|
||||||
if !os.exists(file) {
|
if !os.exists(file) {
|
||||||
|
@ -127,7 +152,11 @@ pub fn (ctx &Context) draw_image(x f32, y f32, width f32, height f32, img_ &Imag
|
||||||
x0 := f32(x) * ctx.scale
|
x0 := f32(x) * ctx.scale
|
||||||
y0 := f32(y) * ctx.scale
|
y0 := f32(y) * ctx.scale
|
||||||
x1 := f32(x + width) * ctx.scale
|
x1 := f32(x + width) * ctx.scale
|
||||||
y1 := f32(y + height) * ctx.scale
|
mut y1 := f32(y + height) * ctx.scale
|
||||||
|
if height == 0 {
|
||||||
|
scale := f32(img.width) / f32(width)
|
||||||
|
y1 = f32(y + int(f32(img.height) / scale)) * ctx.scale
|
||||||
|
}
|
||||||
//
|
//
|
||||||
sgl.load_pipeline(ctx.timage_pip)
|
sgl.load_pipeline(ctx.timage_pip)
|
||||||
sgl.enable_texture()
|
sgl.enable_texture()
|
||||||
|
|
|
@ -80,8 +80,8 @@ fn (mut p Parser) for_stmt() ast.Stmt {
|
||||||
return for_c_stmt
|
return for_c_stmt
|
||||||
} else if p.peek_tok.kind in [.key_in, .comma] ||
|
} else if p.peek_tok.kind in [.key_in, .comma] ||
|
||||||
(p.tok.kind == .key_mut && p.peek_tok2.kind in [.key_in, .comma]) {
|
(p.tok.kind == .key_mut && p.peek_tok2.kind in [.key_in, .comma]) {
|
||||||
// `for i in vals`, `for i in start .. end`
|
// `for i in vals`, `for i in start .. end`, `for mut user in users`, `for i, mut user in users`
|
||||||
val_is_mut := p.tok.kind == .key_mut
|
mut val_is_mut := p.tok.kind == .key_mut
|
||||||
if val_is_mut {
|
if val_is_mut {
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,11 @@ fn (mut p Parser) for_stmt() ast.Stmt {
|
||||||
mut val_var_name := p.check_name()
|
mut val_var_name := p.check_name()
|
||||||
if p.tok.kind == .comma {
|
if p.tok.kind == .comma {
|
||||||
p.next()
|
p.next()
|
||||||
|
if p.tok.kind == .key_mut {
|
||||||
|
// `for i, mut user in users {`
|
||||||
|
p.next()
|
||||||
|
val_is_mut = true
|
||||||
|
}
|
||||||
key_var_name = val_var_name
|
key_var_name = val_var_name
|
||||||
val_var_pos = p.tok.position()
|
val_var_pos = p.tok.position()
|
||||||
val_var_name = p.check_name()
|
val_var_name = p.check_name()
|
||||||
|
|
Loading…
Reference in New Issue