prototype v2
This commit is contained in:
parent
14640a2b12
commit
7b358760e9
@ -3,5 +3,5 @@
|
|||||||
<component name="Black">
|
<component name="Black">
|
||||||
<option name="sdkName" value="Python 3.9 (traktor)" />
|
<option name="sdkName" value="Python 3.9 (traktor)" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (traktor)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (Traktor)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
@ -2,9 +2,10 @@
|
|||||||
<module type="PYTHON_MODULE" version="4">
|
<module type="PYTHON_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="jdk" jdkName="Python 3.9 (Traktor)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
@ -4,8 +4,7 @@ import pygame
|
|||||||
|
|
||||||
# Wymiary planszy
|
# Wymiary planszy
|
||||||
rows, cols = 10, 10 # Ustalona liczba wierszy i kolumn
|
rows, cols = 10, 10 # Ustalona liczba wierszy i kolumn
|
||||||
size = 50 # Rozmiar pojedynczego pola na planszy
|
size = 64 # Rozmiar pojedynczego pola na planszy
|
||||||
|
|
||||||
|
|
||||||
# Klasa reprezentująca planszę
|
# Klasa reprezentująca planszę
|
||||||
class Board:
|
class Board:
|
||||||
@ -19,46 +18,59 @@ class Board:
|
|||||||
|
|
||||||
# Metoda do ładowania obrazów
|
# Metoda do ładowania obrazów
|
||||||
def load_images(self):
|
def load_images(self):
|
||||||
self.grass = pygame.Surface((size, size)) # Tworzenie powierzchni dla trawy
|
try:
|
||||||
self.grass.fill((0, 255, 0)) # Wypełnienie powierzchni zielonym kolorem (trawa)
|
self.grass = pygame.image.load("board/grass.png") # Załaduj obraz trawy
|
||||||
|
self.dirt = pygame.image.load("board/dirt.png") # Załaduj obraz ziemi
|
||||||
|
self.rock = pygame.image.load("board/rock.png") # Załaduj obraz kamienia
|
||||||
|
except pygame.error as e:
|
||||||
|
print(f"Failed to load image: {e}")
|
||||||
|
self.grass = pygame.Surface((size, size))
|
||||||
|
self.grass.fill((0, 255, 0)) # Zastępczy kolor zielony (trawa)
|
||||||
|
self.dirt = pygame.Surface((size, size))
|
||||||
|
self.dirt.fill((139, 69, 19)) # Zastępczy kolor brązowy (ziemia)
|
||||||
|
self.rock = pygame.Surface((size, size))
|
||||||
|
self.rock.fill((128, 128, 128)) # Zastępczy kolor szary (kamień)
|
||||||
|
|
||||||
# Tworzenie powierzchni dla różnych warzyw
|
# Tworzenie powierzchni dla różnych warzyw
|
||||||
self.warzywa_images = {
|
self.warzywa_images = {
|
||||||
"pomidor": [pygame.Surface((size, size)) for _ in range(9)],
|
"marchewka": [pygame.image.load(f"warzywa/Carrot/{i}.jpg") for i in range(1, 10)],
|
||||||
"ogorek": [pygame.Surface((size, size)) for _ in range(9)],
|
"ziemniak": [pygame.image.load(f"warzywa/Potato/{i}.jpg") for i in range(1, 10)],
|
||||||
"kalafior": [pygame.Surface((size, size)) for _ in range(9)]
|
"pomidor": [pygame.image.load(f"warzywa/tomato/{i}.jpg") for i in range(1, 10)],
|
||||||
|
"fasola": [pygame.image.load(f"warzywa/Bean/{i}.jpg") for i in range(1, 10)],
|
||||||
|
"dynia": [pygame.image.load(f"warzywa/Pumpkin/{i}.jpg") for i in range(1, 10)],
|
||||||
|
"rzodkiewka": [pygame.image.load(f"warzywa/Radish/{i}.jpg") for i in range(1, 10)],
|
||||||
|
"ogorek": [pygame.image.load(f"warzywa/Cucumber/{i}.jpg") for i in range(1, 10)],
|
||||||
|
"kalafior": [pygame.image.load(f"warzywa/Cauliflower/{i}.jpg") for i in range(1, 10)],
|
||||||
|
"kapusta": [pygame.image.load(f"warzywa/Cabbage/{i}.jpg") for i in range(1, 10)],
|
||||||
|
"brokul": [pygame.image.load(f"warzywa/Broccoli/{i}.jpg") for i in range(1, 10)]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Kolory przypisane do każdego warzywa
|
|
||||||
colors = {
|
|
||||||
"pomidor": (255, 0, 0), # Czerwony
|
|
||||||
"ogorek": (255, 165, 0), # Pomarańczowy
|
|
||||||
"kalafior": (255, 255, 255) # Biały
|
|
||||||
}
|
|
||||||
|
|
||||||
# Wypełnianie powierzchni odpowiednim kolorem dla każdego warzywa
|
|
||||||
for veg, color in colors.items():
|
|
||||||
for surface in self.warzywa_images[veg]:
|
|
||||||
surface.fill(color)
|
|
||||||
|
|
||||||
# Typy warzyw przypisane do liczb
|
# Typy warzyw przypisane do liczb
|
||||||
self.vegetable_types = {
|
self.vegetable_types = {
|
||||||
"pomidor": 1,
|
"marchewka": 2,
|
||||||
"ogorek": 2,
|
"ziemniak": 3,
|
||||||
"kalafior": 3
|
"pomidor": 4,
|
||||||
|
"fasola": 5,
|
||||||
|
"dynia": 6,
|
||||||
|
"rzodkiewka": 7,
|
||||||
|
"ogorek": 8,
|
||||||
|
"kalafior": 9,
|
||||||
|
"kapusta": 10,
|
||||||
|
"brokul": 11
|
||||||
}
|
}
|
||||||
|
|
||||||
# Metoda do generowania początkowej planszy
|
# Metoda do generowania początkowej planszy
|
||||||
def generate_board(self):
|
def generate_board(self):
|
||||||
self.board = [[random.choice([0, 1, 2, 3]) for _ in range(cols)] for _ in range(rows)]
|
# Zwiększenie prawdopodobieństwa generowania trawy i kamieni
|
||||||
|
self.board = [[random.choice([0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) for _ in range(cols)] for _ in range(rows)]
|
||||||
self.vegetables = [[None for _ in range(cols)] for _ in range(rows)]
|
self.vegetables = [[None for _ in range(cols)] for _ in range(rows)]
|
||||||
self.vegetable_names = [[None for _ in range(cols)] for _ in range(rows)]
|
self.vegetable_names = [[None for _ in range(cols)] for _ in range(rows)]
|
||||||
|
|
||||||
# Losowe przypisanie warzyw do planszy
|
# Losowe przypisanie warzyw do planszy
|
||||||
for row in range(rows):
|
for row in range(rows):
|
||||||
for col in range(cols):
|
for col in range(cols):
|
||||||
if self.board[row][col] in (1, 2, 3):
|
if self.board[row][col] in self.vegetable_types.values():
|
||||||
vegetable_type = list(self.warzywa_images.keys())[self.board[row][col] - 1]
|
vegetable_type = list(self.warzywa_images.keys())[self.board[row][col] - 2]
|
||||||
vegetable_image = random.choice(self.warzywa_images[vegetable_type])
|
vegetable_image = random.choice(self.warzywa_images[vegetable_type])
|
||||||
self.vegetables[row][col] = vegetable_image
|
self.vegetables[row][col] = vegetable_image
|
||||||
self.vegetable_names[row][col] = vegetable_type
|
self.vegetable_names[row][col] = vegetable_type
|
||||||
@ -98,9 +110,9 @@ class Board:
|
|||||||
for row in range(rows):
|
for row in range(rows):
|
||||||
for col in range(cols):
|
for col in range(cols):
|
||||||
if random.random() < mutation_rate:
|
if random.random() < mutation_rate:
|
||||||
self.board[row][col] = random.choice([0, 1, 2, 3])
|
self.board[row][col] = random.choice([0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
|
||||||
if self.board[row][col] in (1, 2, 3):
|
if self.board[row][col] in self.vegetable_types.values():
|
||||||
vegetable_type = list(self.warzywa_images.keys())[self.board[row][col] - 1]
|
vegetable_type = list(self.warzywa_images.keys())[self.board[row][col] - 2]
|
||||||
vegetable_image = random.choice(self.warzywa_images[vegetable_type])
|
vegetable_image = random.choice(self.warzywa_images[vegetable_type])
|
||||||
self.vegetables[row][col] = vegetable_image
|
self.vegetables[row][col] = vegetable_image
|
||||||
self.vegetable_names[row][col] = vegetable_type
|
self.vegetable_names[row][col] = vegetable_type
|
||||||
@ -112,10 +124,8 @@ class Board:
|
|||||||
for j in range(cols):
|
for j in range(cols):
|
||||||
if i * cols + j > crossover_point:
|
if i * cols + j > crossover_point:
|
||||||
self.board[i][j], other_board.board[i][j] = other_board.board[i][j], self.board[i][j]
|
self.board[i][j], other_board.board[i][j] = other_board.board[i][j], self.board[i][j]
|
||||||
self.vegetables[i][j], other_board.vegetables[i][j] = other_board.vegetables[i][j], \
|
self.vegetables[i][j], other_board.vegetables[i][j] = other_board.vegetables[i][j], self.vegetables[i][j]
|
||||||
self.vegetables[i][j]
|
self.vegetable_names[i][j], other_board.vegetable_names[i][j] = other_board.vegetable_names[i][j], self.vegetable_names[i][j]
|
||||||
self.vegetable_names[i][j], other_board.vegetable_names[i][j] = other_board.vegetable_names[i][j], \
|
|
||||||
self.vegetable_names[i][j]
|
|
||||||
|
|
||||||
# Metoda kopiująca planszę
|
# Metoda kopiująca planszę
|
||||||
def copy(self):
|
def copy(self):
|
||||||
@ -128,7 +138,7 @@ class Board:
|
|||||||
|
|
||||||
# Sprawdza, czy dane pole zawiera warzywo
|
# Sprawdza, czy dane pole zawiera warzywo
|
||||||
def is_vegetable(self, row, col):
|
def is_vegetable(self, row, col):
|
||||||
return self.board[row][col] in (1, 2, 3)
|
return self.board[row][col] in self.vegetable_types.values()
|
||||||
|
|
||||||
# Rysowanie planszy na oknie pygame
|
# Rysowanie planszy na oknie pygame
|
||||||
def draw_cubes(self, win):
|
def draw_cubes(self, win):
|
||||||
@ -137,64 +147,68 @@ class Board:
|
|||||||
cube_rect = pygame.Rect(col * size, row * size, size, size)
|
cube_rect = pygame.Rect(col * size, row * size, size, size)
|
||||||
cube = self.board[row][col]
|
cube = self.board[row][col]
|
||||||
if cube == 0:
|
if cube == 0:
|
||||||
win.blit(self.grass, cube_rect)
|
win.blit(self.grass, cube_rect) # Użyj obrazu trawy
|
||||||
|
elif cube == 1:
|
||||||
|
rock_scale = pygame.transform.scale(self.rock, (size, size))
|
||||||
|
win.blit(self.dirt, cube_rect)
|
||||||
|
win.blit(rock_scale, cube_rect)
|
||||||
else:
|
else:
|
||||||
if self.vegetables[row][col]:
|
if self.vegetables[row][col]:
|
||||||
vegetable_image = pygame.transform.scale(self.vegetables[row][col], (size, size))
|
vegetable_image = pygame.transform.scale(self.vegetables[row][col], (size, size))
|
||||||
win.blit(vegetable_image, cube_rect)
|
win.blit(vegetable_image, cube_rect)
|
||||||
|
|
||||||
|
|
||||||
# Funkcja oceniająca planszę (wywołuje metodę evaluate)
|
# Funkcja oceniająca planszę (wywołuje metodę evaluate)
|
||||||
def evaluate(board):
|
def evaluate(board):
|
||||||
return board.evaluate()
|
return board.evaluate()
|
||||||
|
|
||||||
|
|
||||||
# Generowanie początkowej populacji plansz
|
# Generowanie początkowej populacji plansz
|
||||||
def generate_population(size):
|
def generate_population(size):
|
||||||
return [Board() for _ in range(size)]
|
return [Board() for _ in range(size)]
|
||||||
|
|
||||||
|
|
||||||
# Selekcja metodą ruletki
|
# Selekcja metodą ruletki
|
||||||
def roulette_wheel_selection(population, fitnesses):
|
def roulette_wheel_selection(population, fitnesses):
|
||||||
total_fitness = sum(fitnesses)
|
total_fitness = sum(fitnesses)
|
||||||
selection_probs = [f / total_fitness for f in fitnesses]
|
selection_probs = [f / total_fitness for f in fitnesses]
|
||||||
return population[random.choices(range(len(population)), weights=selection_probs, k=1)[0]]
|
return population[random.choices(range(len(population)), weights=selection_probs, k=1)[0]]
|
||||||
|
|
||||||
|
|
||||||
# Krzyżowanie jednopunktowe
|
# Krzyżowanie jednopunktowe
|
||||||
def crossover(parent1, parent2):
|
def crossover(parent1, parent2):
|
||||||
child1, child2 = parent1.copy(), parent2.copy()
|
child1, child2 = parent1.copy(), parent2.copy()
|
||||||
child1.crossover(child2)
|
child1.crossover(child2)
|
||||||
return child1, child2
|
return child1, child2
|
||||||
|
|
||||||
|
|
||||||
# Mutacja planszy
|
# Mutacja planszy
|
||||||
def mutate(board, mutation_rate):
|
def mutate(board, mutation_rate):
|
||||||
board.mutate(mutation_rate)
|
board.mutate(mutation_rate)
|
||||||
|
|
||||||
|
|
||||||
# Algorytm genetyczny
|
# Algorytm genetyczny
|
||||||
def genetic_algorithm(pop_size, generations, mutation_rate):
|
def genetic_algorithm(pop_size, generations, mutation_rate):
|
||||||
population = generate_population(pop_size) # Generowanie początkowej populacji
|
population = generate_population(pop_size)
|
||||||
for _ in range(generations):
|
for generation in range(generations):
|
||||||
fitnesses = [evaluate(board) for board in population] # Ocenianie każdej planszy
|
fitnesses = [evaluate(board) for board in population]
|
||||||
new_population = []
|
new_population = [max(population, key=evaluate).copy()] # Elityzm - zachowanie najlepszego osobnika
|
||||||
while len(new_population) < pop_size:
|
while len(new_population) < pop_size:
|
||||||
parent1 = roulette_wheel_selection(population, fitnesses) # Wybór rodzica 1 metodą ruletki
|
parent1 = roulette_wheel_selection(population, fitnesses)
|
||||||
parent2 = roulette_wheel_selection(population, fitnesses) # Wybór rodzica 2 metodą ruletki
|
parent2 = roulette_wheel_selection(population, fitnesses)
|
||||||
offspring1, offspring2 = crossover(parent1, parent2) # Krzyżowanie rodziców
|
offspring1, offspring2 = crossover(parent1, parent2)
|
||||||
mutate(offspring1, mutation_rate) # Mutacja potomka 1
|
mutate(offspring1, mutation_rate)
|
||||||
mutate(offspring2, mutation_rate) # Mutacja potomka 2
|
mutate(offspring2, mutation_rate)
|
||||||
new_population.extend([offspring1, offspring2]) # Dodanie potomków do nowej populacji
|
new_population.extend([offspring1, offspring2])
|
||||||
population = new_population # Zamiana starej populacji na nową
|
population = new_population[:pop_size]
|
||||||
best_board = max(population, key=evaluate) # Wybór najlepszej planszy z populacji
|
print(f"Generation {generation}: Best Fitness = {max(fitnesses)}")
|
||||||
|
best_board = max(population, key=evaluate)
|
||||||
return best_board
|
return best_board
|
||||||
|
|
||||||
|
# Funkcja do zapisywania planszy jako obraz PNG
|
||||||
|
def save_board_as_image(board, filename):
|
||||||
|
surface = pygame.Surface((cols * size, rows * size))
|
||||||
|
board.draw_cubes(surface)
|
||||||
|
pygame.image.save(surface, filename)
|
||||||
|
|
||||||
# Parametry algorytmu
|
# Parametry algorytmu
|
||||||
pop_size = 50 # Rozmiar populacji
|
pop_size = 50 # Rozmiar populacji
|
||||||
generations = 200 # Liczba generacji
|
generations = 300 # Liczba generacji
|
||||||
mutation_rate = 0.05 # Wskaźnik mutacji
|
mutation_rate = 0.03 # Wskaźnik mutacji
|
||||||
|
|
||||||
# Inicjalizacja Pygame
|
# Inicjalizacja Pygame
|
||||||
pygame.init()
|
pygame.init()
|
||||||
@ -210,12 +224,21 @@ pygame.display.update()
|
|||||||
|
|
||||||
# Zapisywanie planszy do pliku
|
# Zapisywanie planszy do pliku
|
||||||
np.save('generated_board.npy', best_board.board)
|
np.save('generated_board.npy', best_board.board)
|
||||||
|
save_board_as_image(best_board, 'generated_board.png') # Zapisz planszę jako obraz PNG
|
||||||
|
|
||||||
# Utrzymanie okna otwartego do zamknięcia przez użytkownika
|
# Utrzymanie okna otwartego do zamknięcia przez użytkownika
|
||||||
run = True
|
run = True
|
||||||
|
needs_redraw = True # Flaga informująca, czy trzeba przerysować planszę
|
||||||
while run:
|
while run:
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
run = False
|
run = False
|
||||||
|
elif event.type == pygame.MOUSEBUTTONDOWN or event.type == pygame.KEYDOWN:
|
||||||
|
needs_redraw = True # Przerysowanie planszy w przypadku kliknięcia myszą lub naciśnięcia klawisza
|
||||||
|
|
||||||
|
if needs_redraw:
|
||||||
|
best_board.draw_cubes(win)
|
||||||
|
pygame.display.flip()
|
||||||
|
needs_redraw = False # Wyłącz przerysowywanie do momentu kolejnego zdarzenia
|
||||||
|
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
|
Binary file not shown.
BIN
generated_board.png
Normal file
BIN
generated_board.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 767 KiB |
Loading…
Reference in New Issue
Block a user