Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Hako2807 committed Nov 5, 2024
2 parents f675961 + cc4731c commit a74995c
Showing 19 changed files with 3,237 additions and 96 deletions.
466 changes: 466 additions & 0 deletions app.py

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Example function for sending data to the Flask backend
async function runTrain() {
const response = await fetch('http://localhost:5000/train', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ n_generations: 100, neat_name: 'experiment1' })
});
const result = await response.json();
console.log(result.output); // Process the output as needed
}
12 changes: 5 additions & 7 deletions gui_with_pygame.py
Original file line number Diff line number Diff line change
@@ -45,8 +45,8 @@ def get_genomes(self):
class Settings():
def __init__(self):
self.fps = 60
self.default_x_size = 2560
self.default_y_size = 1600
self.default_x_size = 1080
self.default_y_size = 720
self.fullscreen = False
self.fs_start_time = 0
self.fs_is_pressed = False
@@ -125,7 +125,7 @@ def __init__(self, x, y, width, height, items, font, text_color, bg_color, selec
self.scroll_offset = 0 # This tracks where we are in the list
self.padding = padding # Distance between items
# Create a base list of items without positioning them

self.list_items = [
SelectableListItem(
x, y, width, (height - (visible_count - 1) * padding) // visible_count, # Adjust height to account for padding
@@ -400,7 +400,7 @@ def __init__(self):
Button(460, 170, 200, 50, "Start Training", st.normal_font, st.text_color, st.button_color, st.hover_color, st.pressed_color, self.start_training_process),
Button(460, 300, 200, 50, "Back to Menu", st.normal_font, st.text_color, st.button_color, st.hover_color, st.pressed_color, self.main_menu_scene)]
try:
self.fitness_graph = ImageSprite("data/latest/fitness/fitness_plot.png", (700, 100))
self.fitness_graph = ImageSprite("data/latest/latest/fitness/fitness_plot.png", (700, 100))
except:
print("ERROR: Could not find image path")
self.fitness_graph = ImageSprite("data/genome_frames/genome_0.png", (700, 100))
@@ -445,12 +445,11 @@ def __init__(self):
# Use the loaded genome objects (printing as an example)
for genome in loaded_genomes:
self.genomes.append(genome)
print(genome)

## Genome viewer
self.genome_viewer = GenomeViewer(self.genomes, st.normal_font, st.text_color, st.input_field_bg, st.input_field_active_bg)

self.watch_genes_visualize = ImageSprite("data/genome_frames/genome_0.png", (600, 100), (600, 400))
self.watch_genes_visualize = ImageSprite("data/latest/genome_frames/genome_0.png", (600, 100), (600, 400))

## Run button
self.run_button = Button(600, 20, 200, 50, "Run Selected Genomes", st.normal_font, st.text_color, st.button_color, st.hover_color, st.pressed_color, self.run_selected_genomes)
@@ -658,7 +657,6 @@ def tick(self):
self.update_screen()
self.clock.tick(st.fps)


st = Settings()

def main():
76 changes: 61 additions & 15 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from src.environments.debug_env import env_debug_init, run_game_debug
from src.environments.playback_env import env_playback_init, run_game_playback
from src.utils.config import Config
from src.genetics.NEAT import NEAT
from src.utils.utils import read_fitness_file, save_fitness, save_best_genome, load_best_genome, save_neat, load_neat, save_fitness_graph_file
from src.utils.utils import read_fitness_file, save_fitness, save_best_genome, load_best_genome, save_neat, load_neat, save_fitness_graph_file, get_latest_generation
import warnings
import cProfile
import pstats
@@ -10,31 +11,58 @@
warnings.filterwarnings("ignore", category=UserWarning, message=".*Gym version v0.24.1.*")

def play_genome(args):
neat_name = "latest"
if args.neat_name != '':
neat_name = args.neat_name
neat_name = args.neat_name if args.neat_name != '' else 'latest'

if args.to_gen is not None:
to_gen = args.to_gen
if args.from_gen is not None:
from_gen = args.from_gen
else:
from_gen = 0
test_genome(from_gen, to_gen, neat_name)
from_gen = args.from_gen if args.from_gen is not None else 0
test_genome(from_gen, args.to_gen, neat_name)
return

generation_num = args.generation if args.generation is not None else -1
genome = load_best_genome(generation_num, neat_name)
if args.from_gen is not None:
latest_gen = get_latest_generation(neat_name)
test_genome(args.from_gen, latest_gen, neat_name)
return

genome = load_best_genome(args.generation if args.generation is not None else -1, neat_name)
env, state = env_debug_init()
run_game_debug(env, state, genome, 0, visualize=True)
run_game_debug(env, state, genome, neat_name, visualize=True)

def test_genome(from_gen: int, to_gen: int, neat_name: str):
for i in range(from_gen, to_gen + 1):
print(f"Testing genome {i}...")
genome = load_best_genome(i, neat_name)
env, state = env_debug_init()
fitness = run_game_debug(env, state, genome, i)
fitness = run_game_debug(env, state, genome, neat_name)
print(fitness)


def playback_genomes(args):
neat_name = args.neat_name if args.neat_name != '' else 'latest'

if args.to_gen is not None:
from_gen = args.from_gen if args.from_gen is not None else 0
playback_genome(from_gen, args.to_gen, neat_name, args.environment)
return

if args.from_gen is not None:
latest_gen = get_latest_generation(neat_name)
playback_genome(args.from_gen, latest_gen, neat_name, args.environment)
return

genome = load_best_genome(args.generation if args.generation is not None else -1, neat_name)
env, state = env_playback_init(args.environment)
run_game_playback(env, state, genome, neat_name, visualize=False)

def playback_genome(from_gen: int, to_gen: int, neat_name: str, environment: int):
for i in range(from_gen, to_gen + 1):
print(f"Playback genome {i}...")
genome = load_best_genome(i, neat_name)
env, state = env_playback_init(environment)
fitness = run_game_playback(env, state, genome, neat_name)
print(fitness)



def collect_fitnesses(genomes, generation, min_fitnesses, avg_fitnesses, best_fitnesses, neat_name):
fitnesses = [genome.fitness_value for genome in genomes]

@@ -94,6 +122,7 @@ def main(args):
if not genome.elite:
neat.add_mutation(genome)
save_fitness_graph_file(neat_name)
save_neat(neat, neat_name)
except KeyboardInterrupt:
print("\nProcess interrupted! Saving fitness data...")
finally:
@@ -104,8 +133,17 @@ def main(args):

if neat.config.SHOULD_PROFILE:
profiler.disable()
stats = pstats.Stats(profiler).sort_stats('cumtime') # Create a stats object to print out profiling results

# Create a stats object to format the profiling results
stats = pstats.Stats(profiler).sort_stats('cumtime')

# Print stats to terminal (optional, you may remove if too verbose)
stats.print_stats()

# Write human-readable stats to a text file
with open("profile_output.txt", "w") as f:
stats = pstats.Stats(profiler, stream=f)
stats.sort_stats('cumtime').print_stats()

return neat.genomes

@@ -127,6 +165,12 @@ def command_line_interface():
play_parser.add_argument('-g', '--generation', type=int, help="The generation of the genome to play")
play_parser.add_argument('-f', '--from_gen', type=int, help="The starting genome to test")
play_parser.add_argument('-t', '--to_gen', type=int, help="The ending genome to test (exclusive)")

playback_parser = subparsers.add_parser('playback', help="Play back the best genome from the lastest generation on an environment of your choice")
playback_parser.add_argument('-g', '--generation', type=int, help="The generation of the genome to play")
playback_parser.add_argument('-f', '--from_gen', type=int, help="The starting genome to test")
playback_parser.add_argument('-t', '--to_gen', type=int, help="The ending genome to test (exclusive)")
playback_parser.add_argument('-e', '--environment', type=int, help="The environment to play back the actions (0,1,2,3)")

args = parser.parse_args()

@@ -136,6 +180,8 @@ def command_line_interface():
save_fitness_graph_file(args.neat_name, show=True)
elif args.command == "play":
play_genome(args)
elif args.command == "playback":
playback_genomes(args)
else:
parser.print_help()

Binary file added main.py.lprof
Binary file not shown.
Loading

0 comments on commit a74995c

Please sign in to comment.