integrated explosion animation, reformatted roulette-GA file
This commit is contained in:
parent
2944099e93
commit
dc539223db
175
algorithms/learn/genetic_algorithm/ga_roulette.py
Normal file
175
algorithms/learn/genetic_algorithm/ga_roulette.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
import numpy as np
|
||||||
|
import random
|
||||||
|
import operator
|
||||||
|
import pandas as pd
|
||||||
|
from algorithms.learn.genetic_algorithm import helpers
|
||||||
|
|
||||||
|
import os
|
||||||
|
from minefield import Minefield
|
||||||
|
gl_minefield = None
|
||||||
|
scores_table = None
|
||||||
|
|
||||||
|
|
||||||
|
class Fitness:
|
||||||
|
def __init__(self, route):
|
||||||
|
self.route = route
|
||||||
|
self.score = 0
|
||||||
|
self.fitness = 0.0
|
||||||
|
|
||||||
|
def route_distance(self):
|
||||||
|
if self.score == 0:
|
||||||
|
self.score = helpers.get_score(gl_minefield, self.route, scores_table)
|
||||||
|
|
||||||
|
return self.score
|
||||||
|
|
||||||
|
def route_fitness(self):
|
||||||
|
if self.fitness == 0:
|
||||||
|
self.fitness = 1000 / float(self.route_distance())
|
||||||
|
|
||||||
|
return self.fitness
|
||||||
|
|
||||||
|
|
||||||
|
def create_route(mine_list):
|
||||||
|
route = random.sample(mine_list, len(mine_list))
|
||||||
|
return route
|
||||||
|
|
||||||
|
|
||||||
|
def initial_population(pop_size, mine_list):
|
||||||
|
population = []
|
||||||
|
|
||||||
|
for i in range(0, pop_size):
|
||||||
|
population.append(create_route(mine_list))
|
||||||
|
return population
|
||||||
|
|
||||||
|
|
||||||
|
def rank_routes(population):
|
||||||
|
fitness_results = {}
|
||||||
|
|
||||||
|
for i in range(0, len(population)):
|
||||||
|
fitness_results[i] = Fitness(population[i]).route_fitness()
|
||||||
|
|
||||||
|
return sorted(fitness_results.items(), key=operator.itemgetter(1), reverse=True)
|
||||||
|
|
||||||
|
|
||||||
|
def selection(pop_ranked, elite_size):
|
||||||
|
selection_results = []
|
||||||
|
df = pd.DataFrame(np.array(pop_ranked), columns=["Index", "Fitness"])
|
||||||
|
df['cum_sum'] = df.Fitness.cumsum()
|
||||||
|
df['cum_perc'] = 100 * df.cum_sum / df.Fitness.sum()
|
||||||
|
|
||||||
|
for i in range(0, elite_size):
|
||||||
|
selection_results.append(pop_ranked[i][0])
|
||||||
|
for i in range(0, len(pop_ranked) - elite_size):
|
||||||
|
pick = 100 * random.random()
|
||||||
|
for j in range(0, len(pop_ranked)):
|
||||||
|
if pick <= df.iat[j, 3]:
|
||||||
|
selection_results.append(pop_ranked[j][0])
|
||||||
|
break
|
||||||
|
return selection_results
|
||||||
|
|
||||||
|
|
||||||
|
def mating_pool(population, selection_results):
|
||||||
|
matingpool = []
|
||||||
|
for i in range(0, len(selection_results)):
|
||||||
|
index = selection_results[i]
|
||||||
|
matingpool.append(population[index])
|
||||||
|
return matingpool
|
||||||
|
|
||||||
|
|
||||||
|
def breed(parent1, parent2):
|
||||||
|
child_p1 = []
|
||||||
|
|
||||||
|
gene_a = int(random.random() * len(parent1))
|
||||||
|
gene_b = int(random.random() * len(parent1))
|
||||||
|
|
||||||
|
start_gene = min(gene_a, gene_b)
|
||||||
|
end_gene = max(gene_a, gene_b)
|
||||||
|
|
||||||
|
for i in range(start_gene, end_gene):
|
||||||
|
child_p1.append(parent1[i])
|
||||||
|
|
||||||
|
child_p2 = [item for item in parent2 if item not in child_p1]
|
||||||
|
|
||||||
|
child = child_p1 + child_p2
|
||||||
|
return child
|
||||||
|
|
||||||
|
|
||||||
|
def breed_population(matingpool, elite_size):
|
||||||
|
children = []
|
||||||
|
length = len(matingpool) - elite_size
|
||||||
|
pool = random.sample(matingpool, len(matingpool))
|
||||||
|
|
||||||
|
for i in range(0, elite_size):
|
||||||
|
children.append(matingpool[i])
|
||||||
|
|
||||||
|
for i in range(0, length):
|
||||||
|
child = breed(pool[i], pool[len(matingpool) - i - 1])
|
||||||
|
children.append(child)
|
||||||
|
return children
|
||||||
|
|
||||||
|
|
||||||
|
def mutate(individual, mutation_rate):
|
||||||
|
for swapped in range(len(individual)):
|
||||||
|
if random.random() < mutation_rate:
|
||||||
|
swap_with = int(random.random() * len(individual))
|
||||||
|
|
||||||
|
city1 = individual[swapped]
|
||||||
|
city2 = individual[swap_with]
|
||||||
|
|
||||||
|
individual[swapped] = city2
|
||||||
|
individual[swap_with] = city1
|
||||||
|
return individual
|
||||||
|
|
||||||
|
|
||||||
|
def mutate_population(population, mutation_rate):
|
||||||
|
mutated_pop = []
|
||||||
|
|
||||||
|
for ind in range(0, len(population)):
|
||||||
|
mutated_ind = mutate(population[ind], mutation_rate)
|
||||||
|
mutated_pop.append(mutated_ind)
|
||||||
|
return mutated_pop
|
||||||
|
|
||||||
|
|
||||||
|
def next_generation(scores, current_gen, elite_size, mutation_rate):
|
||||||
|
selection_results = selection(scores, elite_size)
|
||||||
|
matingpool = mating_pool(current_gen, selection_results)
|
||||||
|
children = breed_population(matingpool, elite_size)
|
||||||
|
next_gen = mutate_population(children, mutation_rate)
|
||||||
|
return next_gen
|
||||||
|
|
||||||
|
|
||||||
|
def genetic_algorithm(minefield, population, pop_size, elite_size, mutation_rate, generations):
|
||||||
|
global gl_minefield, scores_table
|
||||||
|
gl_minefield = minefield
|
||||||
|
|
||||||
|
scores_table = helpers.create_scores_table(gl_minefield)
|
||||||
|
|
||||||
|
pop = initial_population(pop_size, population)
|
||||||
|
scores = rank_routes(pop)
|
||||||
|
|
||||||
|
print("Initial score: " + str(1000 / scores[0][1]))
|
||||||
|
|
||||||
|
for i in range(0, generations):
|
||||||
|
pop = next_generation(scores, pop, elite_size, mutation_rate)
|
||||||
|
scores = rank_routes(pop)
|
||||||
|
|
||||||
|
print(f"Generation {i} best score: {str(1000 / scores[0][1])}")
|
||||||
|
best_route_index = scores[0][0]
|
||||||
|
best_route = pop[best_route_index]
|
||||||
|
print(best_route)
|
||||||
|
|
||||||
|
print("Final score: " + str(1000 / scores[0][1]))
|
||||||
|
best_route_index = scores[0][0]
|
||||||
|
best_route = pop[best_route_index]
|
||||||
|
return best_route
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
gl_minefield = Minefield(os.path.join("..", "..", "..", "resources", "minefields", "fourthmap.json"))
|
||||||
|
|
||||||
|
genetic_algorithm(minefield=gl_minefield,
|
||||||
|
population=helpers.get_mines_coords(gl_minefield),
|
||||||
|
pop_size=100,
|
||||||
|
elite_size=20,
|
||||||
|
mutation_rate=0.01,
|
||||||
|
generations=100)
|
@ -7,20 +7,22 @@ from numpy.random import rand
|
|||||||
|
|
||||||
from algorithms.learn.genetic_algorithm import helpers
|
from algorithms.learn.genetic_algorithm import helpers
|
||||||
|
|
||||||
|
|
||||||
# this is helper function for sum_distance function, it counts the taxi cab distance between 2 vectors [x,y]
|
# this is helper function for sum_distance function, it counts the taxi cab distance between 2 vectors [x,y]
|
||||||
def distance(x,y):
|
def distance(x, y):
|
||||||
temp1 = abs(x[0]-y[0])
|
temp1 = abs(x[0] - y[0])
|
||||||
temp2 = abs(x[1]-y[1])
|
temp2 = abs(x[1] - y[1])
|
||||||
vector_distance = temp1+temp2
|
vector_distance = temp1 + temp2
|
||||||
return vector_distance
|
return vector_distance
|
||||||
|
|
||||||
|
|
||||||
# this is fitting function which tells how well specimen fits the environment
|
# this is fitting function which tells how well specimen fits the environment
|
||||||
# this function counts the sum of distances between vectors for a specimen
|
# this function counts the sum of distances between vectors for a specimen
|
||||||
# this was just for testing, it should be probably changed to A*
|
# this was just for testing, it should be probably changed to A*
|
||||||
def sum_distance(speciment):
|
def sum_distance(speciment):
|
||||||
sum = 0
|
sum = 0
|
||||||
for i in range(0,len(speciment)-2):
|
for i in range(0, len(speciment) - 2):
|
||||||
pom = distance(speciment[i],speciment[i+1])
|
pom = distance(speciment[i], speciment[i + 1])
|
||||||
sum = sum + pom
|
sum = sum + pom
|
||||||
return sum
|
return sum
|
||||||
|
|
||||||
@ -30,7 +32,7 @@ def sum_distance(speciment):
|
|||||||
def selection(pop, scores, k=10):
|
def selection(pop, scores, k=10):
|
||||||
# first random selection
|
# first random selection
|
||||||
selection_ix = randint(len(pop))
|
selection_ix = randint(len(pop))
|
||||||
for ix in randint(0, len(pop), k- 1):
|
for ix in randint(0, len(pop), k - 1):
|
||||||
# check if better (e.g. perform a tournament)
|
# check if better (e.g. perform a tournament)
|
||||||
if scores[ix] < scores[selection_ix]:
|
if scores[ix] < scores[selection_ix]:
|
||||||
selection_ix = ix
|
selection_ix = ix
|
||||||
@ -40,8 +42,8 @@ def selection(pop, scores, k=10):
|
|||||||
# crossover two parents to create two children
|
# crossover two parents to create two children
|
||||||
# this function creates speciments for new generation
|
# this function creates speciments for new generation
|
||||||
def crossover(p1, p2, r_cross):
|
def crossover(p1, p2, r_cross):
|
||||||
p1=list(p1)
|
p1 = list(p1)
|
||||||
p2=list(p2)
|
p2 = list(p2)
|
||||||
# children are copies of parents by default
|
# children are copies of parents by default
|
||||||
c1, c2 = p1.copy(), p2.copy()
|
c1, c2 = p1.copy(), p2.copy()
|
||||||
# check for recombination
|
# check for recombination
|
||||||
@ -71,17 +73,16 @@ def mutation(speciment, r_mut):
|
|||||||
if rand() < r_mut:
|
if rand() < r_mut:
|
||||||
# flip the bit
|
# flip the bit
|
||||||
temp = speciment[i]
|
temp = speciment[i]
|
||||||
pom = random.randint(0,len(speciment)-1)
|
pom = random.randint(0, len(speciment) - 1)
|
||||||
speciment[i] = speciment[pom]
|
speciment[i] = speciment[pom]
|
||||||
speciment[pom] = temp
|
speciment[pom] = temp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# genetic algorithm
|
# genetic algorithm
|
||||||
def genetic_algorithm(minefield, objective, n_iter, n_pop, r_cross, r_mut):
|
def genetic_algorithm(minefield, objective, n_iter, n_pop, r_cross, r_mut):
|
||||||
# this is hardcoded list of coordinates of all mines (for tests only) which represents one speciment in population
|
# this is hardcoded list of coordinates of all mines (for tests only) which represents one speciment in population
|
||||||
# it is then permutated to get set number of species and create population
|
# it is then permutated to get set number of species and create population
|
||||||
speciment=helpers.get_mines_coords(minefield)
|
speciment = helpers.get_mines_coords(minefield)
|
||||||
pop = [random.sample(speciment, len(speciment)) for _ in range(n_pop)]
|
pop = [random.sample(speciment, len(speciment)) for _ in range(n_pop)]
|
||||||
# permutation function returns tuples so I change them to lists
|
# permutation function returns tuples so I change them to lists
|
||||||
|
|
||||||
@ -116,7 +117,6 @@ def genetic_algorithm(minefield, objective, n_iter, n_pop, r_cross, r_mut):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
# define the total iterations
|
# define the total iterations
|
||||||
n_iter = 100
|
n_iter = 100
|
||||||
# bits
|
# bits
|
||||||
@ -131,11 +131,10 @@ if __name__ == "__main__":
|
|||||||
# create new minefield instance
|
# create new minefield instance
|
||||||
import os
|
import os
|
||||||
from minefield import Minefield
|
from minefield import Minefield
|
||||||
|
|
||||||
minefield = Minefield(os.path.join("..", "..", "..", "resources", "minefields", "fourthmap.json"))
|
minefield = Minefield(os.path.join("..", "..", "..", "resources", "minefields", "fourthmap.json"))
|
||||||
|
|
||||||
# perform the genetic algorithm search
|
# perform the genetic algorithm search
|
||||||
best, score = genetic_algorithm(minefield, helpers.get_score, n_iter, n_pop, r_cross, r_mut)
|
best, score = genetic_algorithm(minefield, helpers.get_score, n_iter, n_pop, r_cross, r_mut)
|
||||||
print('Done!')
|
print('Done!')
|
||||||
print('f(%s) = %f' % (best, score))
|
print('f(%s) = %f' % (best, score))
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ def get_score(minefield, speciment, table=None):
|
|||||||
|
|
||||||
mine.active = False
|
mine.active = False
|
||||||
|
|
||||||
minefield.next_turn(n_turns=cost)
|
minefield.next_turn(n_turns=cost, mode="ga")
|
||||||
score += cost
|
score += cost
|
||||||
|
|
||||||
score += 200 * minefield.explosions
|
score += 200 * minefield.explosions
|
||||||
|
@ -1,174 +0,0 @@
|
|||||||
import time
|
|
||||||
import numpy as np, random, operator, pandas as pd
|
|
||||||
from algorithms.learn.genetic_algorithm import helpers
|
|
||||||
|
|
||||||
import os
|
|
||||||
from minefield import Minefield
|
|
||||||
gl_minefield = None
|
|
||||||
scores_table = None
|
|
||||||
|
|
||||||
|
|
||||||
class Fitness:
|
|
||||||
def __init__(self, route):
|
|
||||||
self.route = route
|
|
||||||
self.distance = 0
|
|
||||||
self.fitness = 0.0
|
|
||||||
|
|
||||||
def routeDistance(self):
|
|
||||||
if self.distance == 0:
|
|
||||||
self.distance = helpers.get_score(gl_minefield, self.route, scores_table)
|
|
||||||
|
|
||||||
return self.distance
|
|
||||||
|
|
||||||
def routeFitness(self):
|
|
||||||
if self.fitness == 0:
|
|
||||||
self.fitness = 1000 / float(self.routeDistance())
|
|
||||||
|
|
||||||
return self.fitness
|
|
||||||
|
|
||||||
|
|
||||||
def createRoute(cityList):
|
|
||||||
route = random.sample(cityList, len(cityList))
|
|
||||||
return route
|
|
||||||
|
|
||||||
|
|
||||||
def initialPopulation(popSize, cityList):
|
|
||||||
population = []
|
|
||||||
|
|
||||||
for i in range(0, popSize):
|
|
||||||
population.append(createRoute(cityList))
|
|
||||||
return population
|
|
||||||
|
|
||||||
|
|
||||||
def rankRoutes(population):
|
|
||||||
fitnessResults = {}
|
|
||||||
|
|
||||||
for i in range(0, len(population)):
|
|
||||||
fitnessResults[i] = Fitness(population[i]).routeFitness()
|
|
||||||
|
|
||||||
return sorted(fitnessResults.items(), key=operator.itemgetter(1), reverse=True)
|
|
||||||
|
|
||||||
|
|
||||||
def selection(popRanked, eliteSize):
|
|
||||||
selectionResults = []
|
|
||||||
df = pd.DataFrame(np.array(popRanked), columns=["Index", "Fitness"])
|
|
||||||
df['cum_sum'] = df.Fitness.cumsum()
|
|
||||||
df['cum_perc'] = 100 * df.cum_sum / df.Fitness.sum()
|
|
||||||
|
|
||||||
for i in range(0, eliteSize):
|
|
||||||
selectionResults.append(popRanked[i][0])
|
|
||||||
for i in range(0, len(popRanked) - eliteSize):
|
|
||||||
pick = 100 * random.random()
|
|
||||||
for i in range(0, len(popRanked)):
|
|
||||||
if pick <= df.iat[i, 3]:
|
|
||||||
selectionResults.append(popRanked[i][0])
|
|
||||||
break
|
|
||||||
return selectionResults
|
|
||||||
|
|
||||||
def matingPool(population, selectionResults):
|
|
||||||
matingpool = []
|
|
||||||
for i in range(0, len(selectionResults)):
|
|
||||||
index = selectionResults[i]
|
|
||||||
matingpool.append(population[index])
|
|
||||||
return matingpool
|
|
||||||
|
|
||||||
|
|
||||||
def breed(parent1, parent2):
|
|
||||||
child = []
|
|
||||||
childP1 = []
|
|
||||||
childP2 = []
|
|
||||||
|
|
||||||
geneA = int(random.random() * len(parent1))
|
|
||||||
geneB = int(random.random() * len(parent1))
|
|
||||||
|
|
||||||
startGene = min(geneA, geneB)
|
|
||||||
endGene = max(geneA, geneB)
|
|
||||||
|
|
||||||
for i in range(startGene, endGene):
|
|
||||||
childP1.append(parent1[i])
|
|
||||||
|
|
||||||
childP2 = [item for item in parent2 if item not in childP1]
|
|
||||||
|
|
||||||
child = childP1 + childP2
|
|
||||||
return child
|
|
||||||
|
|
||||||
|
|
||||||
def breedPopulation(matingpool, eliteSize):
|
|
||||||
children = []
|
|
||||||
length = len(matingpool) - eliteSize
|
|
||||||
pool = random.sample(matingpool, len(matingpool))
|
|
||||||
|
|
||||||
for i in range(0, eliteSize):
|
|
||||||
children.append(matingpool[i])
|
|
||||||
|
|
||||||
for i in range(0, length):
|
|
||||||
child = breed(pool[i], pool[len(matingpool) - i - 1])
|
|
||||||
children.append(child)
|
|
||||||
return children
|
|
||||||
|
|
||||||
|
|
||||||
def mutate(individual, mutationRate):
|
|
||||||
for swapped in range(len(individual)):
|
|
||||||
if (random.random() < mutationRate):
|
|
||||||
swapWith = int(random.random() * len(individual))
|
|
||||||
|
|
||||||
city1 = individual[swapped]
|
|
||||||
city2 = individual[swapWith]
|
|
||||||
|
|
||||||
individual[swapped] = city2
|
|
||||||
individual[swapWith] = city1
|
|
||||||
return individual
|
|
||||||
|
|
||||||
|
|
||||||
def mutatePopulation(population, mutationRate):
|
|
||||||
mutatedPop = []
|
|
||||||
|
|
||||||
for ind in range(0, len(population)):
|
|
||||||
mutatedInd = mutate(population[ind], mutationRate)
|
|
||||||
mutatedPop.append(mutatedInd)
|
|
||||||
return mutatedPop
|
|
||||||
|
|
||||||
|
|
||||||
def nextGeneration(scores, currentGen, eliteSize, mutationRate):
|
|
||||||
selectionResults = selection(scores, eliteSize)
|
|
||||||
matingpool = matingPool(currentGen, selectionResults)
|
|
||||||
children = breedPopulation(matingpool, eliteSize)
|
|
||||||
nextGeneration = mutatePopulation(children, mutationRate)
|
|
||||||
return nextGeneration
|
|
||||||
|
|
||||||
|
|
||||||
def genetic_algorithm(minefield, population, popSize, eliteSize, mutationRate, generations):
|
|
||||||
global gl_minefield, scores_table
|
|
||||||
gl_minefield = minefield
|
|
||||||
|
|
||||||
scores_table = helpers.create_scores_table(gl_minefield)
|
|
||||||
|
|
||||||
pop = initialPopulation(popSize, population)
|
|
||||||
scores = rankRoutes(pop)
|
|
||||||
|
|
||||||
print("Initial score: " + str(1000 / scores[0][1]))
|
|
||||||
|
|
||||||
for i in range(0, generations):
|
|
||||||
pop = nextGeneration(scores, pop, eliteSize, mutationRate)
|
|
||||||
scores = rankRoutes(pop)
|
|
||||||
|
|
||||||
print(f"Generation {i} best score: {str(1000 / scores[0][1])}")
|
|
||||||
bestRouteIndex = scores[0][0]
|
|
||||||
bestRoute = pop[bestRouteIndex]
|
|
||||||
print(bestRoute)
|
|
||||||
|
|
||||||
print("Final score: " + str(1000 / scores[0][1]))
|
|
||||||
bestRouteIndex = scores[0][0]
|
|
||||||
bestRoute = pop[bestRouteIndex]
|
|
||||||
return bestRoute
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
gl_minefield = Minefield(os.path.join("..", "..", "..", "resources", "minefields", "fourthmap.json"))
|
|
||||||
|
|
||||||
genetic_algorithm(minefield=gl_minefield,
|
|
||||||
population=helpers.get_mines_coords(gl_minefield),
|
|
||||||
popSize=100,
|
|
||||||
eliteSize=20,
|
|
||||||
mutationRate=0.01,
|
|
||||||
generations=100)
|
|
@ -74,6 +74,9 @@ def blit_graphics(minefield):
|
|||||||
seconds = tile.mine.timer % 60
|
seconds = tile.mine.timer % 60
|
||||||
display_time_mine(tile.position, minutes, "0" + str(seconds))
|
display_time_mine(tile.position, minutes, "0" + str(seconds))
|
||||||
|
|
||||||
|
if tile.mine.blacked:
|
||||||
|
const.SCREEN.blit(const.MINE_INACTIVE, tile_screen_coords)
|
||||||
|
|
||||||
# changed sapper's movement from jumping to continuous movement (moved everything to Agent's class)
|
# changed sapper's movement from jumping to continuous movement (moved everything to Agent's class)
|
||||||
# # sapper
|
# # sapper
|
||||||
# display_sapper(
|
# display_sapper(
|
||||||
|
@ -3,12 +3,15 @@ import pygame
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from project_constants import V_TILE_SIZE, DIR_ASSETS, SCREEN
|
from project_constants import V_TILE_SIZE, DIR_ASSETS, SCREEN
|
||||||
|
from objects.mine_models.mine import Mine
|
||||||
import assets.display_assets
|
import assets.display_assets
|
||||||
|
|
||||||
|
|
||||||
class Explosion(pygame.sprite.Sprite):
|
class Explosion(pygame.sprite.Sprite):
|
||||||
|
|
||||||
def __init__(self, coords: (int, int)):
|
def __init__(self, coords: (int, int) = None, mine: Mine = None):
|
||||||
|
if coords is None:
|
||||||
|
coords = mine.position
|
||||||
|
|
||||||
pygame.sprite.Sprite.__init__(self)
|
pygame.sprite.Sprite.__init__(self)
|
||||||
|
|
||||||
@ -28,6 +31,7 @@ class Explosion(pygame.sprite.Sprite):
|
|||||||
assets.display_assets.calculate_screen_position(coords),
|
assets.display_assets.calculate_screen_position(coords),
|
||||||
(V_TILE_SIZE, V_TILE_SIZE)
|
(V_TILE_SIZE, V_TILE_SIZE)
|
||||||
)
|
)
|
||||||
|
self.mine = mine
|
||||||
|
|
||||||
def update(self, *args, **kwargs):
|
def update(self, *args, **kwargs):
|
||||||
|
|
||||||
@ -39,6 +43,10 @@ class Explosion(pygame.sprite.Sprite):
|
|||||||
if self.frame == len(self.explosion_animation):
|
if self.frame == len(self.explosion_animation):
|
||||||
self.kill()
|
self.kill()
|
||||||
|
|
||||||
|
elif self.frame == len(self.explosion_animation) - 1:
|
||||||
|
if self.mine is not None:
|
||||||
|
self.mine.blacked = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.image = self.explosion_animation[self.frame]
|
self.image = self.explosion_animation[self.frame]
|
||||||
|
|
||||||
|
14
game.py
14
game.py
@ -5,7 +5,7 @@ import project_constants as const
|
|||||||
from assets.display_assets import blit_graphics
|
from assets.display_assets import blit_graphics
|
||||||
from algorithms.search import a_star
|
from algorithms.search import a_star
|
||||||
|
|
||||||
from algorithms.learn.genetic_algorithm import new_ga, helpers
|
from algorithms.learn.genetic_algorithm import ga_roulette, helpers
|
||||||
|
|
||||||
from minefield import Minefield
|
from minefield import Minefield
|
||||||
|
|
||||||
@ -150,12 +150,12 @@ class Game:
|
|||||||
genetics_minefield = Minefield(const.MAP_RANDOM_10x10)
|
genetics_minefield = Minefield(const.MAP_RANDOM_10x10)
|
||||||
|
|
||||||
sequence = \
|
sequence = \
|
||||||
new_ga.genetic_algorithm(minefield=genetics_minefield,
|
ga_roulette.genetic_algorithm(minefield=genetics_minefield,
|
||||||
population=helpers.get_mines_coords(self.minefield),
|
population=helpers.get_mines_coords(self.minefield),
|
||||||
popSize=100,
|
pop_size=100,
|
||||||
eliteSize=20,
|
elite_size=20,
|
||||||
mutationRate=0.01,
|
mutation_rate=0.01,
|
||||||
generations=generations)
|
generations=generations)
|
||||||
|
|
||||||
self.genetic_sequence = sequence
|
self.genetic_sequence = sequence
|
||||||
self.genetics_done = True
|
self.genetics_done = True
|
||||||
|
8
main.py
8
main.py
@ -57,12 +57,6 @@ def main():
|
|||||||
# checking if game should stop running
|
# checking if game should stop running
|
||||||
running = not is_quit_button_pressed(events)
|
running = not is_quit_button_pressed(events)
|
||||||
|
|
||||||
# TODO : added for testing, remove after moving the explosion line
|
|
||||||
keys = pygame.key.get_pressed()
|
|
||||||
if keys[pygame.K_SPACE]:
|
|
||||||
# TODO : move this line to where explosion is called
|
|
||||||
const.EXPLOSIONS.add(Explosion((2, 3)))
|
|
||||||
|
|
||||||
# drawing minefield and agent instances
|
# drawing minefield and agent instances
|
||||||
game.draw_minefield()
|
game.draw_minefield()
|
||||||
|
|
||||||
@ -187,7 +181,7 @@ def main():
|
|||||||
if not game.agent.defuse_a_mine(game.get_mine(game.goal)):
|
if not game.agent.defuse_a_mine(game.get_mine(game.goal)):
|
||||||
print("BOOOOOOM\n\n")
|
print("BOOOOOOM\n\n")
|
||||||
game.explosion(game.get_mine(game.goal))
|
game.explosion(game.get_mine(game.goal))
|
||||||
# is_game_over = True
|
const.EXPLOSIONS.add(Explosion(mine=game.get_mine(game.goal)))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("guess you will live a little longer...\n\n")
|
print("guess you will live a little longer...\n\n")
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import project_constants as const
|
import project_constants as const
|
||||||
|
from assets.explosion import Explosion
|
||||||
from objects import tile as tl, agent as ag
|
from objects import tile as tl, agent as ag
|
||||||
from objects.mine_models.time_mine import TimeMine
|
from objects.mine_models.time_mine import TimeMine
|
||||||
import json_generator as jg
|
import json_generator as jg
|
||||||
@ -39,7 +40,7 @@ class Minefield:
|
|||||||
|
|
||||||
self.time_mines = self._get_time_mines()
|
self.time_mines = self._get_time_mines()
|
||||||
|
|
||||||
def next_turn(self, n_turns=1):
|
def next_turn(self, n_turns=1, mode="main"):
|
||||||
self.turn += n_turns
|
self.turn += n_turns
|
||||||
self.points += n_turns
|
self.points += n_turns
|
||||||
|
|
||||||
@ -47,11 +48,13 @@ class Minefield:
|
|||||||
mine.timer = max(0, mine.starting_time - int(self.turn))
|
mine.timer = max(0, mine.starting_time - int(self.turn))
|
||||||
|
|
||||||
if mine.timer == 0 and mine.active:
|
if mine.timer == 0 and mine.active:
|
||||||
# TODO: BOOM
|
|
||||||
self.explosions += 1
|
self.explosions += 1
|
||||||
self.points += const.EXPLOSION_PENALTY
|
self.points += const.EXPLOSION_PENALTY
|
||||||
mine.active = False
|
mine.active = False
|
||||||
|
|
||||||
|
if mode == "main":
|
||||||
|
const.EXPLOSIONS.add(Explosion(mine=mine))
|
||||||
|
|
||||||
def get_active_mines(self):
|
def get_active_mines(self):
|
||||||
mines = list()
|
mines = list()
|
||||||
|
|
||||||
|
@ -17,11 +17,13 @@ class Mine(ABC):
|
|||||||
self.position = position
|
self.position = position
|
||||||
self.wire = None
|
self.wire = None
|
||||||
self.active = active
|
self.active = active
|
||||||
|
self.blacked = False
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def disarm(self, wire):
|
def disarm(self, wire):
|
||||||
if wire == self.wire:
|
if wire == self.wire:
|
||||||
self.active = False
|
self.active = False
|
||||||
|
self.blacked = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -161,6 +161,12 @@ HIGHLIGHT = pygame.transform.scale(
|
|||||||
)
|
)
|
||||||
HIGHLIGHT.set_alpha(100)
|
HIGHLIGHT.set_alpha(100)
|
||||||
|
|
||||||
|
MINE_INACTIVE = pygame.transform.scale(
|
||||||
|
pygame.image.load(os.path.join(DIR_ASSETS, "old_tiles/tile_black.png")),
|
||||||
|
(V_TILE_SIZE, V_TILE_SIZE)
|
||||||
|
)
|
||||||
|
MINE_INACTIVE.set_alpha(160)
|
||||||
|
|
||||||
|
|
||||||
# ============== #
|
# ============== #
|
||||||
# ==== MAPS ==== #
|
# ==== MAPS ==== #
|
||||||
|
BIN
resources/assets/old_tiles/tile_black.png
Normal file
BIN
resources/assets/old_tiles/tile_black.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 123 B |
Loading…
Reference in New Issue
Block a user