@@ -782,9 +782,7 @@ class BasePlayer:
782782 def __init__ (self ) -> None :
783783 """Initialize BasePlayer."""
784784 self .fitness = 0.0
785- self .vision : list [float ] = [] # The input array for the neural network
786785 self .unadjusted_fitness = 0
787- self .lifespan = 0 # How long the player lived for fitness
788786 self .best_score = 0.0 # Stores the score achieved used for replay
789787 self .dead = False
790788 self .score = 0.0
@@ -802,22 +800,20 @@ def start(self) -> Genome:
802800 """Return new brain."""
803801 return Genome (self .genome_inputs , self .genome_outputs )
804802
805- def update (self , decision : tuple [float , ...]) -> None :
803+ def look (self ) -> Iterable [float ]:
804+ """Return inputs for the nural network."""
805+ return (random .random () * 2 - 1 for _ in range (self .genome_inputs ))
806+
807+ def think (self , inputs : Iterable [float ]) -> Iterable [float ]:
808+ """Return decision from nural network."""
809+ return self .brain .feed_forward (inputs )
810+
811+ def update (self , decision : Iterable [float ]) -> None :
806812 """Move the player according to the outputs from the neural network."""
807813 # print(decision)
808814 # do = decision.index(max(self.decision))
809815 return
810816
811- def look (self ) -> None :
812- """Get inputs for brain."""
813- self .vision = [
814- random .random () * 2 - 1 for _ in range (self .genome_inputs )
815- ]
816-
817- def think (self ) -> tuple [float , ...]:
818- """Return decision from nural network."""
819- return self .brain .feed_forward (self .vision )
820-
821817 def clone (self ) -> BasePlayer :
822818 """Return a clone of self."""
823819 clone = self .__class__ ()
@@ -828,11 +824,9 @@ def clone(self) -> BasePlayer:
828824 clone .best_score = float (self .score )
829825 return clone
830826
831- clone_for_replay = clone
832-
833- def calculate_fitness (self ) -> None :
827+ def calculate_fitness (self ) -> float :
834828 """Calculate the fitness of the AI."""
835- self . fitness = random .randint (0 , 10 )
829+ return random .randint (0 , 10 )
836830
837831 def crossover (self , parent : BasePlayer ) -> BasePlayer :
838832 """Return a BasePlayer object by crossing over our brain and parent2's brain."""
@@ -904,7 +898,7 @@ def __init__(self, player: BasePlayer | None = None) -> None:
904898 # Since it is the only one in the species it is by default the best
905899 self .best_fitness = player .fitness
906900 self .rep = player .brain .clone ()
907- self .champ = player .clone_for_replay ()
901+ self .champ = player .clone ()
908902
909903 def __repr__ (self ) -> str :
910904 """Return what this object should be represented by in the python interpreter."""
@@ -975,7 +969,7 @@ def sort_species(self) -> None:
975969 if self .players [0 ].fitness > self .best_fitness :
976970 self .staleness = 0
977971 self .best_fitness = self .players [0 ].fitness
978- # self.rep = self.players[0].clone_for_replay ()
972+ # self.rep = self.players[0].clone ()
979973 self .rep = self .players [0 ].brain .clone ()
980974 else : # If no new best player,
981975 self .staleness += 1
@@ -1121,27 +1115,30 @@ def update_alive(self) -> None:
11211115 """Update all of the players that are alive."""
11221116 for player in list (self .players ):
11231117 if not player .dead :
1124- player .look () # Get inputs for brain
1125- decision = player .think () # outputs from neural network
1126- player .update (
1127- decision ,
1128- ) # Move the player according to the outputs from the neural network
1118+ # Get inputs for nural network
1119+ inputs = player .look ()
1120+ # Get nural network's decision (output) from inputs
1121+ decision = player .think (inputs )
1122+ # Move the player according to the outputs from the
1123+ # neural network
1124+ player .update (decision )
1125+ # Update max score
11291126 if player .score > self .global_best_score :
11301127 self .global_best_score = player .score
11311128
11321129 def done (self ) -> bool :
11331130 """Return True if all the players are dead. :(."""
11341131 return all (player .dead for player in self .players )
11351132
1136- def setbest_player (self ) -> None :
1133+ def set_best_player (self ) -> None :
11371134 """Set the best player globally and for current generation."""
11381135 if not (self .species and self .species [0 ].players ):
11391136 return
11401137 temp_best = self .species [0 ].players [0 ]
11411138 temp_best .gen = self .gen
11421139
11431140 if temp_best .score >= self .best_score :
1144- best_clone = temp_best .clone_for_replay ()
1141+ best_clone = temp_best .clone ()
11451142 self .gen_players .append (best_clone )
11461143 # print stuff was here, removed
11471144 self .best_score = temp_best .score
@@ -1169,10 +1166,10 @@ def separate(self) -> None:
11691166 if not species_found :
11701167 self .species .append (Species (player ))
11711168
1172- def calculate_fitness (self ) -> None :
1169+ def calculate_fitnesses (self ) -> None :
11731170 """Calculate the fitness of each player."""
11741171 for player in self .players :
1175- player .calculate_fitness ()
1172+ player .fitness = player . calculate_fitness ()
11761173
11771174 def sort_species (self ) -> None :
11781175 """Sort the species to be ranked in fitness order, best first."""
@@ -1235,7 +1232,7 @@ def natural_selection(self) -> None:
12351232 # Separate players into species
12361233 self .separate ()
12371234 # Calculate the fitness of each player
1238- self .calculate_fitness ()
1235+ self .calculate_fitnesses ()
12391236 # Sort the species to be ranked in fitness order, best first
12401237 self .sort_species ()
12411238 if self .mass_extinction_event :
@@ -1244,7 +1241,7 @@ def natural_selection(self) -> None:
12441241 # Kill off the bottom half of each species
12451242 self .cull_species ()
12461243 # Save the best player of this generation
1247- self .setbest_player ()
1244+ self .set_best_player ()
12481245 # Remove species which haven't improved in 15 generations
12491246 self .kill_stale_species ()
12501247 # Kill species which are super bad
@@ -1296,11 +1293,14 @@ def update_alive_in_batches(self, worlds: list[World]) -> None:
12961293 for player in list (self .players ):
12971294 if self .player_in_batch (player , worlds ) and not player .dead :
12981295 alive += 1
1299- player .look () # Get inputs for brain
1300- decision = player .think () # outputs from neural network
1301- player .update (
1302- decision ,
1303- ) # Move the player according to the outputs from the neural network
1296+ # Get inputs for nural network
1297+ inputs = player .look ()
1298+ # Get nural network's decision (output) from inputs
1299+ decision = player .think (inputs )
1300+ # Move the player according to the outputs from the
1301+ # neural network
1302+ player .update (decision )
1303+ # Update max score
13041304 if player .score > self .global_best_score :
13051305 self .global_best_score = player .score
13061306
0 commit comments