Projekt_Sztuczna_Inteligencja/algorithms/learn/genetic_algorithm/helpers.py

147 lines
4.7 KiB
Python

from minefield import Minefield
import project_constants as const
from project_constants import Direction
from algorithms.search.a_star import State, graphsearch
from objects.mine_models.chained_mine import ChainedMine
from objects.mine_models.time_mine import TimeMine
def possible_states(row, column):
possible_states = []
if Minefield.is_valid_move(row + 1, column):
possible_states.append(State(row + 1, column, Direction.UP))
if Minefield.is_valid_move(row - 1, column):
possible_states.append(State(row + 1, column, Direction.DOWN))
if Minefield.is_valid_move(row, column + 1):
possible_states.append(State(row, column + 1, Direction.LEFT))
if Minefield.is_valid_move(row, column - 1):
possible_states.append(State(row, column - 1, Direction.RIGHT))
return possible_states
def create_scores_table(minefield):
mines = get_mines_coords(minefield)
dict_table = {
mine1: {
mine2: {
direction: 0
for direction in Direction}
for mine2 in mines}
for mine1 in mines}
dict_table[(0, 0)] = {mine: {Direction.RIGHT: 0} for mine in mines}
for mine in mines:
_, end_state, cost = \
graphsearch(State(0, 0, Direction.RIGHT),
minefield,
target_type="mine",
tox=mine[0],
toy=mine[1],
with_data=True)
dict_table[(0, 0)][mine][Direction.RIGHT] = (end_state, cost)
for mine1 in mines:
for mine2 in mines:
for initial_state in possible_states(mine1[0], mine1[1]):
_, end_state, cost = \
graphsearch(initial_state,
minefield,
target_type="mine",
tox=mine2[0],
toy=mine2[1],
with_data=True)
dict_table[mine1][mine2][initial_state.direction] = (end_state, cost)
return dict_table
def get_score(minefield, speciment, table=None):
score = 0
initial_state = State(0, 0, Direction.RIGHT)
if table is not None:
for el_index in range(len(speciment) - 1):
if table[(initial_state.row, initial_state.column)] \
[(speciment[el_index][0], speciment[el_index][1])] \
[initial_state.direction]:
end_state, cost = table[(initial_state.row, initial_state.column)] \
[(speciment[el_index][0], speciment[el_index][1])] \
[initial_state.direction]
initial_state = State(speciment[el_index][0], speciment[el_index][1], end_state.direction)
else:
action_sequence, _, cost = \
graphsearch(initial_state,
minefield,
target_type="mine",
tox=speciment[el_index][0],
toy=speciment[el_index][1],
with_data=True)
mine = minefield.matrix[speciment[el_index][0]][speciment[el_index][1]].mine
if isinstance(mine, ChainedMine) and mine.predecessor is not None and mine.predecessor.active:
cost += 200
mine.active = False
for _ in range(cost):
minefield.next_turn()
score += cost
score += 200 * minefield.explosions
return score
# IF THERE IS NO TABLE
else:
for el_index in range(len(speciment) - 1):
action_sequence, initial_state, cost = \
graphsearch(initial_state,
minefield,
target_type="mine",
tox=speciment[el_index][0],
toy=speciment[el_index][1],
with_data=True)
mine = minefield.matrix[speciment[el_index][0]][speciment[el_index][1]].mine
if isinstance(mine, ChainedMine) and mine.predecessor is not None and mine.predecessor.active:
cost += 200
mine.active = False
for _ in range(cost):
minefield.next_turn()
score += cost
score += 200 * minefield.explosions
return score
def get_mines_coords(minefield: Minefield):
mines = list()
for row in range(const.V_GRID_VER_TILES):
for column in range(const.V_GRID_VER_TILES):
mine = minefield.matrix[row][column].mine
if mine is not None:
mines.append((row, column))
return mines