Selaa lähdekoodia

Update weights calculation
Fix major issue in wall collision detection

Alexey Edelev 5 vuotta sitten
vanhempi
commit
e7d8cec18c
2 muutettua tiedostoa jossa 85 lisäystä ja 60 poistoa
  1. 1 1
      neuralnetwork/main.go
  2. 84 59
      neuralnetwork/snakesimulator/snakesimulator.go

+ 1 - 1
neuralnetwork/main.go

@@ -17,7 +17,7 @@ func main() {
 		net.SetStateWatcher(rc)
 	}
 	p.NaturalSelection(200)
-	s.Run()
+	// s.Run()
 
 	// sizes := []int{13, 8, 12, 3}
 	// nn, _ := neuralnetwork.NewNeuralNetwork(sizes, neuralnetwork.NewRPropInitializer(neuralnetwork.RPropConfig{

+ 84 - 59
neuralnetwork/snakesimulator/snakesimulator.go

@@ -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()