134 lines
4.1 KiB
Python
134 lines
4.1 KiB
Python
import time
|
|
|
|
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)):
|
|
|
|
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)
|
|
|
|
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:
|
|
score += 200
|
|
|
|
mine.active = False
|
|
|
|
minefield.next_turn(n_turns=cost, mode="ga")
|
|
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 |