|
@@ -55,6 +55,8 @@ func (s *SnakeSimulator) Verify(population *genetic.Population) (fitnesses []*ge
|
|
|
s.stats.Generation++
|
|
|
s.statsUpdateQueue <- true
|
|
|
s.field.GenerateNextFood()
|
|
|
+ s.fieldUpdateQueue <- true
|
|
|
+
|
|
|
fitnesses = make([]*genetic.IndividalFitness, len(population.Networks))
|
|
|
for index, inidividual := range population.Networks {
|
|
|
s.stats.Individual = uint32(index)
|
|
@@ -62,9 +64,9 @@ func (s *SnakeSimulator) Verify(population *genetic.Population) (fitnesses []*ge
|
|
|
|
|
|
s.runSnake(inidividual, false)
|
|
|
fitnesses[index] = &genetic.IndividalFitness{
|
|
|
- // Fitness: float64(len(s.snake.Points)-2) * float64(s.stats.Move),
|
|
|
- Fitness: float64(s.stats.Move),
|
|
|
- Index: index,
|
|
|
+ Fitness: float64(len(s.snake.Points)-2) * float64(s.stats.Move),
|
|
|
+ // Fitness: float64(s.stats.Move),
|
|
|
+ Index: index,
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -177,10 +179,8 @@ func (s *SnakeSimulator) runSnake(inidividual *neuralnetwork.NeuralNetwork, rand
|
|
|
if newHead.X == s.field.Food.X && newHead.Y == s.field.Food.Y {
|
|
|
s.snake.Feed(newHead)
|
|
|
s.field.GenerateNextFood()
|
|
|
- if s.speed > 0 {
|
|
|
- s.fieldUpdateQueue <- true
|
|
|
- }
|
|
|
- } else if newHead.X >= s.field.Width || newHead.Y >= s.field.Height {
|
|
|
+ s.fieldUpdateQueue <- true
|
|
|
+ } else if newHead.X >= s.field.Width || newHead.Y >= s.field.Height || newHead.X < 0 || newHead.Y < 0 {
|
|
|
// fmt.Printf("Game over\n")
|
|
|
// time.Sleep(1000 * time.Millisecond)
|
|
|
break
|
|
@@ -220,10 +220,14 @@ func (s *SnakeSimulator) GetHeadState() []float64 {
|
|
|
tFood = headY - foodY
|
|
|
if tFood < 0 {
|
|
|
tFood = height
|
|
|
+ } else {
|
|
|
+ tFood = 0
|
|
|
}
|
|
|
bFood = foodY - headY
|
|
|
if bFood < 0 {
|
|
|
bFood = height
|
|
|
+ } else {
|
|
|
+ bFood = 0
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -231,10 +235,14 @@ func (s *SnakeSimulator) GetHeadState() []float64 {
|
|
|
rFood = foodX - headX
|
|
|
if rFood < 0 {
|
|
|
rFood = width
|
|
|
+ } else {
|
|
|
+ rFood = 0
|
|
|
}
|
|
|
lFood = headX - foodX
|
|
|
if lFood < 0 {
|
|
|
lFood = width
|
|
|
+ } else {
|
|
|
+ lFood = 0
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -245,15 +253,15 @@ func (s *SnakeSimulator) GetHeadState() []float64 {
|
|
|
if math.Abs(foodY-headY) == math.Abs(foodX-headX) {
|
|
|
if foodX > headX {
|
|
|
if foodY > headY {
|
|
|
- trFood = math.Abs(foodX-headX) * math.Sqrt2
|
|
|
+ trFood = 0 //math.Abs(foodX-headX) * math.Sqrt2
|
|
|
} else {
|
|
|
- brFood = math.Abs(foodX-headX) * math.Sqrt2
|
|
|
+ brFood = 0 //math.Abs(foodX-headX) * math.Sqrt2
|
|
|
}
|
|
|
} else {
|
|
|
if foodY > headY {
|
|
|
- tlFood = math.Abs(foodX-headX) * math.Sqrt2
|
|
|
+ tlFood = 0 //math.Abs(foodX-headX) * math.Sqrt2
|
|
|
} else {
|
|
|
- blFood = math.Abs(foodX-headX) * math.Sqrt2
|
|
|
+ blFood = 0 //math.Abs(foodX-headX) * math.Sqrt2
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -310,39 +318,56 @@ func (s *SnakeSimulator) GetHeadState() []float64 {
|
|
|
brWall = float64(rWall) * math.Sqrt2
|
|
|
}
|
|
|
|
|
|
- tTail := (headY - tailY)
|
|
|
- if tTail < 0 {
|
|
|
- tTail = height
|
|
|
- }
|
|
|
- bTail := (tailY - headY)
|
|
|
- if bTail < 0 {
|
|
|
- bTail = height
|
|
|
- }
|
|
|
- lTail := (headX - tailX)
|
|
|
- if lTail < 0 {
|
|
|
- tTail = width
|
|
|
+ tTail := float64(0)
|
|
|
+ bTail := float64(0)
|
|
|
+ if headX == tailX {
|
|
|
+ tTail = (headY - tailY)
|
|
|
+ if tTail < 0 {
|
|
|
+ tTail = height
|
|
|
+ } else {
|
|
|
+ tTail = 0
|
|
|
+ }
|
|
|
+ bTail = (tailY - headY)
|
|
|
+ if bTail < 0 {
|
|
|
+ bTail = height
|
|
|
+ } else {
|
|
|
+ bTail = 0
|
|
|
+ }
|
|
|
}
|
|
|
- rTail := (tailX - headX)
|
|
|
- if lTail < 0 {
|
|
|
- tTail = width
|
|
|
+
|
|
|
+ lTail := float64(0)
|
|
|
+ rTail := float64(0)
|
|
|
+ if headY == tailY {
|
|
|
+ lTail = (headX - tailX)
|
|
|
+ if lTail < 0 {
|
|
|
+ tTail = width
|
|
|
+ } else {
|
|
|
+ tTail = 0
|
|
|
+ }
|
|
|
+ rTail = (tailX - headX)
|
|
|
+ if lTail < 0 {
|
|
|
+ tTail = width
|
|
|
+ } else {
|
|
|
+ tTail = 0
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- tlTail := float64(diag)
|
|
|
- trTail := float64(diag)
|
|
|
- blTail := float64(diag)
|
|
|
- brTail := float64(diag)
|
|
|
+ tlTail := float64(0)
|
|
|
+ trTail := float64(0)
|
|
|
+ blTail := float64(0)
|
|
|
+ brTail := float64(0)
|
|
|
if math.Abs(headY-tailY) == math.Abs(headX-tailX) {
|
|
|
if tailY > headY {
|
|
|
if tailX > headX {
|
|
|
- trTail = math.Abs(tailX-headX) * math.Sqrt2
|
|
|
+ trTail = diag //math.Abs(tailX-headX) * math.Sqrt2
|
|
|
} else {
|
|
|
- tlTail = math.Abs(tailX-headX) * math.Sqrt2
|
|
|
+ tlTail = diag //math.Abs(tailX-headX) * math.Sqrt2
|
|
|
}
|
|
|
} else {
|
|
|
if tailX > headX {
|
|
|
- brTail = math.Abs(tailX-headX) * math.Sqrt2
|
|
|
+ brTail = diag //math.Abs(tailX-headX) * math.Sqrt2
|
|
|
} else {
|
|
|
- blTail = math.Abs(tailX-headX) * math.Sqrt2
|
|
|
+ blTail = diag //math.Abs(tailX-headX) * math.Sqrt2
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -391,32 +416,32 @@ func (s *SnakeSimulator) StartServer() {
|
|
|
}()
|
|
|
}
|
|
|
|
|
|
-func (s *SnakeSimulator) Run() {
|
|
|
- s.field.GenerateNextFood()
|
|
|
- for true {
|
|
|
- direction := rand.Int31()%4 + 1
|
|
|
- newHead := s.snake.NewHead(Direction(direction))
|
|
|
- if newHead.X == s.field.Food.X && newHead.Y == s.field.Food.Y {
|
|
|
- s.snake.Feed(newHead)
|
|
|
- s.field.GenerateNextFood()
|
|
|
- s.fieldUpdateQueue <- true
|
|
|
- } else if newHead.X > s.field.Width || newHead.Y > s.field.Height {
|
|
|
- fmt.Printf("Game over\n")
|
|
|
- break
|
|
|
- } else if selfCollisionIndex := s.snake.SelfCollision(newHead); selfCollisionIndex > 0 {
|
|
|
- if selfCollisionIndex == 1 {
|
|
|
- fmt.Printf("Step backward, skip\n")
|
|
|
- continue
|
|
|
- }
|
|
|
- fmt.Printf("Game over self collision\n")
|
|
|
- break
|
|
|
- } else {
|
|
|
- s.snake.Move(newHead)
|
|
|
- }
|
|
|
- s.snakeUpdateQueue <- true
|
|
|
- time.Sleep(50 * time.Millisecond)
|
|
|
- }
|
|
|
-}
|
|
|
+// func (s *SnakeSimulator) Run() {
|
|
|
+// s.field.GenerateNextFood()
|
|
|
+// for true {
|
|
|
+// direction := rand.Int31()%4 + 1
|
|
|
+// newHead := s.snake.NewHead(Direction(direction))
|
|
|
+// if newHead.X == s.field.Food.X && newHead.Y == s.field.Food.Y {
|
|
|
+// s.snake.Feed(newHead)
|
|
|
+// s.field.GenerateNextFood()
|
|
|
+
|
|
|
+// } else if newHead.X > s.field.Width || newHead.Y > s.field.Height {
|
|
|
+// fmt.Printf("Game over\n")
|
|
|
+// break
|
|
|
+// } else if selfCollisionIndex := s.snake.SelfCollision(newHead); selfCollisionIndex > 0 {
|
|
|
+// if selfCollisionIndex == 1 {
|
|
|
+// fmt.Printf("Step backward, skip\n")
|
|
|
+// continue
|
|
|
+// }
|
|
|
+// fmt.Printf("Game over self collision\n")
|
|
|
+// break
|
|
|
+// } else {
|
|
|
+// s.snake.Move(newHead)
|
|
|
+// }
|
|
|
+// s.snakeUpdateQueue <- true
|
|
|
+// time.Sleep(50 * time.Millisecond)
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
func (s *SnakeSimulator) Field(_ *None, srv SnakeSimulator_FieldServer) error {
|
|
|
ctx := srv.Context()
|