mirror of
https://github.com/kristoferssolo/2048.git
synced 2025-10-21 15:20:35 +00:00
feat(game, AI): add option with AI play
This commit is contained in:
parent
5cd4a6d0ae
commit
b10c90cbdf
@ -1,4 +1,5 @@
|
|||||||
|
from .config import get_config
|
||||||
from .io import read_genome
|
from .io import read_genome
|
||||||
from .training import train
|
from .training import train
|
||||||
|
|
||||||
__all__ = ["train", "read_genome"]
|
__all__ = ["train", "read_genome", "get_config"]
|
||||||
|
|||||||
@ -39,15 +39,18 @@ def eval_genomes(genomes, config: neat.Config):
|
|||||||
|
|
||||||
time_passed = time.perf_counter() - start_time
|
time_passed = time.perf_counter() - start_time
|
||||||
score = app.game.board.score
|
score = app.game.board.score
|
||||||
if (
|
if max_val >= 32:
|
||||||
app.game.board.is_game_over()
|
|
||||||
or (app.game.board._is_full() and time_passed >= 0.1)
|
|
||||||
or max_val >= 2048
|
|
||||||
):
|
|
||||||
calculate_fitness(genome, max_val)
|
calculate_fitness(genome, max_val)
|
||||||
logger.info(f"{max_val=}\t{score=:_}\t{genome_id=}")
|
logger.info(f"{max_val=}\t{score=:_}\t{genome_id=}")
|
||||||
app.game.restart()
|
app.game.restart()
|
||||||
break
|
break
|
||||||
|
elif app.game.board.is_game_over() or (
|
||||||
|
app.game.board._is_full() and time_passed >= 0.1
|
||||||
|
):
|
||||||
|
calculate_fitness(genome, -max_val)
|
||||||
|
logger.info(f"{max_val=}\t{score=:_}\t{genome_id=}")
|
||||||
|
app.game.restart()
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
def calculate_fitness(genome: neat.DefaultGenome, score: int):
|
def calculate_fitness(genome: neat.DefaultGenome, score: int):
|
||||||
|
|||||||
@ -5,11 +5,11 @@ import neat
|
|||||||
from path import BASE_PATH
|
from path import BASE_PATH
|
||||||
|
|
||||||
|
|
||||||
def read_genome(filename: Path) -> neat.DefaultGenome:
|
def read_genome() -> neat.DefaultGenome:
|
||||||
with open(filename, "rb") as f:
|
with open(BASE_PATH / "best_genome", "rb") as f:
|
||||||
return pickle.load(f)
|
return pickle.load(f)
|
||||||
|
|
||||||
|
|
||||||
def save_genome(genome, filename: Path) -> None:
|
def save_genome(genome) -> None:
|
||||||
with open(filename, "wb") as f:
|
with open(BASE_PATH / "best_genome", "wb") as f:
|
||||||
pickle.dump(genome, f)
|
pickle.dump(genome, f)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import neat
|
||||||
import pygame
|
import pygame
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import neat
|
import neat
|
||||||
import pygame
|
import pygame
|
||||||
|
from ai import get_config, read_genome
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from py2048 import Config
|
from py2048 import Config
|
||||||
@ -68,7 +70,8 @@ class Menu:
|
|||||||
if self._game_active:
|
if self._game_active:
|
||||||
self.game.draw(self._surface)
|
self.game.draw(self._surface)
|
||||||
elif self._ai_active:
|
elif self._ai_active:
|
||||||
pass
|
self._ai_move()
|
||||||
|
self.game.draw(self._surface)
|
||||||
elif self._setting_active:
|
elif self._setting_active:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -99,6 +102,28 @@ class Menu:
|
|||||||
def ai(self) -> None:
|
def ai(self) -> None:
|
||||||
logger.debug("AI")
|
logger.debug("AI")
|
||||||
|
|
||||||
|
self._ai_active = True
|
||||||
|
self.game = Game()
|
||||||
|
self.network = neat.nn.FeedForwardNetwork.create(read_genome(), get_config())
|
||||||
|
|
||||||
|
def _ai_move(self) -> None:
|
||||||
|
decisions = {
|
||||||
|
0: self.game.move_up,
|
||||||
|
1: self.game.move_down,
|
||||||
|
2: self.game.move_left,
|
||||||
|
3: self.game.move_right,
|
||||||
|
}
|
||||||
|
|
||||||
|
output = self.network.activate(
|
||||||
|
(
|
||||||
|
*self.game.board.matrix(),
|
||||||
|
self.game.board.score,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
decision = output.index(max(output))
|
||||||
|
|
||||||
|
decisions[decision]()
|
||||||
|
|
||||||
def settings(self) -> None:
|
def settings(self) -> None:
|
||||||
logger.debug("Settings")
|
logger.debug("Settings")
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user