128 lines
4.0 KiB
Python
128 lines
4.0 KiB
Python
import pygame
|
|
from pygame.math import Vector2
|
|
import math as m
|
|
|
|
|
|
class Tractor(object):
|
|
|
|
def __init__(self, game):
|
|
self.game = game
|
|
|
|
size = self.game.screen.get_size()
|
|
|
|
self.pos = Vector2(22, 22)
|
|
self.oy = True
|
|
self.oz = False
|
|
|
|
# A*
|
|
self.g_score = []
|
|
self.f_score = [
|
|
self.came_from = []
|
|
self.neighbours()
|
|
self.score()
|
|
|
|
#ruszanie się
|
|
self.road = self.algo(0, 24)
|
|
|
|
|
|
def tick(self):
|
|
|
|
# input
|
|
|
|
if pygame.key.get_pressed()[pygame.K_SPACE]:
|
|
# obecne pole
|
|
pole = self.pos.y // 144 * 5 + self.pos.x // 144
|
|
|
|
if len(self.road) == 0:
|
|
sys.exit(0)
|
|
if self.road[0] == self.pole + 1:
|
|
self.pos.x = self.pos.x + 144
|
|
elif self.road[0] == self.pole - 1:
|
|
self.pos.x = self.pos.x - 144
|
|
elif self.road[0] == self.pole + 5:
|
|
self.pos.y = self.pos.y + 144
|
|
elif self.road[0] == self.pole - 5:
|
|
self.pos.y = self.pos.y - 144
|
|
self.road.pop(0)
|
|
|
|
|
|
def draw(self):
|
|
# drawing
|
|
rect = pygame.Rect(self.pos.x, self.pos.y, 100, 100)
|
|
pygame.draw.rect(self.game.screen, (255, 255, 0), rect)
|
|
|
|
# Sąsiedztwo poszczególnych pól
|
|
def neighbours(self):
|
|
self.neighbours = list(range(25))
|
|
self.neighbours[0] = [1, 5]
|
|
self.neighbours[4] = [3, 9]
|
|
self.neighbours[20] = [15, 21]
|
|
self.neighbours[24] = [19, 23]
|
|
for x in range(1, 4):
|
|
self.neighbours[x] = [x - 1, x + 5, x + 1]
|
|
for x in range(5, 16, 5):
|
|
self.neighbours[x] = [x - 5, x + 1, x + 5]
|
|
for x in range(9, 20, 5):
|
|
self.neighbours[x] = [x - 5, x - 1, x + 5]
|
|
for x in range(21, 24):
|
|
self.neighbours[x] = [x - 1, x - 5, x + 1]
|
|
for x in [6, 7, 8, 11, 12, 13, 16, 17, 18]:
|
|
self.neighbours[x] = [x - 5, x - 1, x + 1, x + 5]
|
|
|
|
# Tworzenie list dla g, h, f oraz came_from
|
|
def score(self):
|
|
for x in range(25):
|
|
self.g_score.append(0)
|
|
self.f_score.append(0)
|
|
self.came_from.append(0)
|
|
|
|
# Obliczanie h (założenie - odległość pomiędzy sąsiednimi polami wynosi 2, tak jak koszt wjazdu na puste pole)
|
|
# s to pole na którym jesteśmy
|
|
# f to pole końcowe
|
|
def h_score(self, s, f):
|
|
a_h = m.fabs(s - f) // 5
|
|
b_h = m.fabs(f % 5 - s % 5)
|
|
return 2 * m.sqrt(a_h ** 2 + b_h ** 2)
|
|
|
|
# A*
|
|
def algo(self, start, koniec):
|
|
# definiowanie setów
|
|
closed_set = []
|
|
open_set = [start]
|
|
|
|
while open_set:
|
|
# Szukanie pola w open_set z najniższym f
|
|
temp1 = max(self.f_score) + 1
|
|
x = 0
|
|
for i in range(len(open_set)):
|
|
if self.f_score[open_set[i]] <= temp1:
|
|
x = open_set[i]
|
|
temp1 = self.f_score[open_set[i]]
|
|
|
|
if x == koniec:
|
|
return self.reconstruct_path(self.came_from, koniec)
|
|
|
|
open_set.remove(x)
|
|
closed_set.append(x)
|
|
for y in self.neighbours[x]:
|
|
if y in closed_set:
|
|
continue
|
|
tentative_g_score = self.g_score[x] + self.game.fields[y][3]
|
|
if y not in open_set:
|
|
open_set.append(y)
|
|
tentative_is_better = True
|
|
elif tentative_g_score < self.g_score[y]:
|
|
tentative_is_better = True
|
|
if tentative_is_better == True:
|
|
self.came_from[y] = x
|
|
self.g_score[y] = tentative_g_score
|
|
self.f_score[y] = self.g_score[y] + self.h_score(y, koniec)
|
|
print("failure")
|
|
|
|
def reconstruct_path(self, came_from, current):
|
|
total_path = [current]
|
|
while came_from[current] != 0:
|
|
current = came_from[current]
|
|
total_path.insert(0, current)
|
|
return total_path
|