SztIn_gr.234798/field.py

346 lines
12 KiB
Python
Raw Permalink Normal View History

import random
2023-04-21 15:29:32 +02:00
import time
from heapq import *
from enum import Enum, IntEnum
from collections import deque
2023-03-12 16:50:42 +01:00
import pygame
2023-03-12 16:50:42 +01:00
pygame.init()
2023-03-12 17:46:49 +01:00
BLACK = (0, 0, 0)
WHITE = (200, 200, 200)
2023-03-12 16:50:42 +01:00
BLUE = (46, 34, 240)
2023-03-31 13:01:22 +02:00
WINDOW_DIMENSIONS = 900
BLOCK_SIZE = 60
ROCKS_NUMBER = 15
VEGETABLES_NUMBER = 20
VEGETABLES = ('Potato', 'Broccoli', 'Carrot', 'Onion')
BOARD_SIZE = int(WINDOW_DIMENSIONS / BLOCK_SIZE)
2023-03-31 13:01:22 +02:00
WATER_TANK_CAPACITY = 10
GAS_TANK_CAPACITY = 100
SPAWN_POINT = (0, 0)
2023-03-12 17:46:49 +01:00
2023-03-28 20:05:01 +02:00
def draw_grid():
# Set the size of the grid block
wei = pygame.transform.scale(pygame.image.load("images/wet_earth_tile.jpg"), (BLOCK_SIZE, BLOCK_SIZE))
dei = pygame.transform.scale(pygame.image.load("images/dry_earth_tile.jpg"), (BLOCK_SIZE, BLOCK_SIZE))
for x in range(0, BOARD_SIZE):
for y in range(0, BOARD_SIZE):
sc.blit(wei, (x * BLOCK_SIZE, y * BLOCK_SIZE))
rect = pygame.Rect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
2023-03-12 17:46:49 +01:00
pygame.draw.rect(sc, WHITE, rect, 1)
2023-03-28 20:05:01 +02:00
def get_click_mouse_pos():
x, y = pygame.mouse.get_pos()
grid_x, grid_y = x // BLOCK_SIZE, y // BLOCK_SIZE
pygame.draw.rect(sc, BLUE, (grid_x * BLOCK_SIZE, grid_y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)
click = pygame.mouse.get_pressed()
2023-04-27 13:21:43 +02:00
return (grid_x, grid_y, Direction.RIGHT) if click[0] else False
2023-03-12 17:46:49 +01:00
def draw_interface():
global sc
sc = pygame.display.set_mode((WINDOW_DIMENSIONS, WINDOW_DIMENSIONS))
2023-03-12 17:46:49 +01:00
pygame.display.set_caption("Pole i ciągnik")
pygame.display.set_icon(pygame.image.load("images/icon.png"))
2023-03-12 16:50:42 +01:00
2023-03-12 17:46:49 +01:00
clock = pygame.time.Clock()
sc.fill(BLACK)
FPS = 60
2023-03-12 16:50:42 +01:00
# region Images import
# bg = pygame.image.load("images/field_image.jpg")
tractor_image = pygame.transform.scale(pygame.image.load("images/tractor_image.png"), (BLOCK_SIZE, BLOCK_SIZE))
rock_image = pygame.transform.scale(pygame.image.load("images/rock_image.png"), (BLOCK_SIZE, BLOCK_SIZE))
potato_image = pygame.transform.scale(pygame.image.load("images/potato.png"), (BLOCK_SIZE, BLOCK_SIZE))
carrot_image = pygame.transform.scale(pygame.image.load("images/carrot.png"), (BLOCK_SIZE, BLOCK_SIZE))
broccoli_image = pygame.transform.scale(pygame.image.load("images/broccoli.png"), (BLOCK_SIZE, BLOCK_SIZE))
onion_image = pygame.transform.scale(pygame.image.load("images/onion.png"), (BLOCK_SIZE, BLOCK_SIZE))
2023-03-31 13:01:22 +02:00
gas_station_image = pygame.transform.scale(pygame.image.load("images/gas_station.png"), (BLOCK_SIZE, BLOCK_SIZE))
font = pygame.font.Font('freesansbold.ttf', BLOCK_SIZE // 2)
# endregion
2023-03-17 15:56:15 +01:00
2023-03-31 13:01:22 +02:00
(x, y) = SPAWN_POINT
tractor = Tractor(x, y, Direction.RIGHT)
2023-03-12 16:50:42 +01:00
grid = Grid(BOARD_SIZE, BOARD_SIZE, BLOCK_SIZE)
2023-04-21 15:29:32 +02:00
graph1 = Graph(grid)
graph1.initialize_graph(grid)
startpoint = (0, 0)
endpoint = startpoint
fl_running = True
while fl_running:
draw_grid()
# region events
2023-03-12 17:46:49 +01:00
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
fl_running = False
2023-03-12 17:46:49 +01:00
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
tractor.rot_center(Direction.LEFT)
2023-03-12 17:46:49 +01:00
elif event.key == pygame.K_RIGHT:
tractor.rot_center(Direction.RIGHT)
2023-03-12 17:46:49 +01:00
elif event.key == pygame.K_UP:
tractor.move(grid=grid)
elif event.key == pygame.K_RETURN:
for y, row in enumerate(grid.grid):
for x, col in enumerate(row):
if col in [item.value for item in vegetables] and (x, y) == (tractor.x, tractor.y):
tractor.collected_vegetables[vegetables(col)] += 1
grid.remove_object(x, y)
break
if (tractor.x, tractor.y) == SPAWN_POINT:
tractor.water = WATER_TANK_CAPACITY
tractor.gas = GAS_TANK_CAPACITY
2023-04-21 15:29:32 +02:00
elif event.type == pygame.MOUSEBUTTONDOWN:
2023-04-27 13:21:43 +02:00
startpoint = (tractor.x, tractor.y, tractor.direction)
2023-04-21 15:29:32 +02:00
endpoint = get_click_mouse_pos()
print(endpoint)
a = graph1.dijkstra(startpoint, endpoint)
b = getRoad(startpoint, endpoint, a)
print(b)
startpoint = endpoint
movement(tractor, grid, b)
# endregion
for y, row in enumerate(grid.grid):
for x, col in enumerate(row):
if grid.grid[x][y] == vegetables.POTATO:
sc.blit(potato_image, (x * BLOCK_SIZE + 5, y * BLOCK_SIZE + 5))
elif grid.grid[x][y] == vegetables.CARROT:
sc.blit(carrot_image, (x * BLOCK_SIZE + 5, y * BLOCK_SIZE + 5))
elif grid.grid[x][y] == vegetables.BROCCOLI:
sc.blit(broccoli_image, (x * BLOCK_SIZE + 5, y * BLOCK_SIZE + 5))
elif grid.grid[x][y] == vegetables.ONION:
sc.blit(onion_image, (x * BLOCK_SIZE + 5, y * BLOCK_SIZE + 5))
elif grid.grid[x][y] == types.ROCK:
sc.blit(rock_image, (x * BLOCK_SIZE, y * BLOCK_SIZE))
2023-03-31 13:01:22 +02:00
sc.blit(gas_station_image, (SPAWN_POINT[0] * BLOCK_SIZE, SPAWN_POINT[1] * BLOCK_SIZE))
# region text
vegetables_text = font.render(
'Potato: ' + str(tractor.collected_vegetables[vegetables.POTATO]) + ' Broccoli: ' + str(
tractor.collected_vegetables[vegetables.BROCCOLI]) + ' Carrot: ' + str(
tractor.collected_vegetables[vegetables.CARROT]) + ' Onion: ' + str(
tractor.collected_vegetables[vegetables.ONION]), True, WHITE, BLACK)
vegetables_textrect = vegetables_text.get_rect()
vegetables_textrect.center = (WINDOW_DIMENSIONS // 2, WINDOW_DIMENSIONS - 30)
sc.blit(vegetables_text, vegetables_textrect)
gas_text = font.render('Gas tank: ' + str(tractor.gas), True, WHITE, BLACK)
gas_textrect = gas_text.get_rect()
gas_textrect.center = (WINDOW_DIMENSIONS // 4 * 3, 20)
sc.blit(gas_text, gas_textrect)
2023-03-31 13:01:22 +02:00
# endregion
sc.blit(tractor.image, (tractor.x * BLOCK_SIZE + 5, tractor.y * BLOCK_SIZE + 5))
2023-03-12 17:46:49 +01:00
pygame.display.update()
2023-03-12 16:50:42 +01:00
clock.tick(FPS)
class Direction(IntEnum):
UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3
class vegetables(Enum):
POTATO = 3
BROCCOLI = 4
CARROT = 5
ONION = 6
class types(Enum):
EMPTY = 0
ROCK = 1
POTATO = 3
BROCCOLI = 4
CARROT = 5
ONION = 6
class Grid:
def __init__(self, width, height, block_size):
self.width = width
self.height = height
self.block_size = block_size
self.grid = [[types.EMPTY for col in range(BOARD_SIZE)] for row in range(BOARD_SIZE)]
self.initialize_grid()
def add_object(self, x, y, type_of_object: types):
if self.grid[x][y] == types.EMPTY:
self.grid[x][y] = type_of_object
return True
else:
return False
def remove_object(self, x, y):
if self.grid[x][y] != types.EMPTY:
self.grid[x][y] = types.EMPTY
return True
else:
return False
def initialize_grid(self):
for i in range(VEGETABLES_NUMBER):
x, y = random.randrange(0, BOARD_SIZE), random.randrange(0, BOARD_SIZE)
if self.grid[x][y] == types.EMPTY and (x, y) != (0, 0):
self.add_object(x, y, random.choice(list(vegetables)))
else:
i -= 1
for i in range(ROCKS_NUMBER):
x, y = random.randrange(0, BOARD_SIZE - 1), random.randrange(0, BOARD_SIZE - 1)
if self.grid[x][y] == types.EMPTY and (x, y) != (0, 0):
self.add_object(x, y, types.ROCK)
else:
i -= 1
class Graph:
def __init__(self, grid: Grid):
self.graph = {}
self.initialize_graph(grid)
def initialize_graph(self, grid: Grid):
for y, row in enumerate(grid.grid):
for x, col in enumerate(row):
2023-04-27 13:21:43 +02:00
for direction in Direction:
self.graph[(x, y, direction)] = get_next_nodes(x, y, direction, grid)
2023-04-21 16:02:18 +02:00
def dijkstra(self, start, goal):
2023-04-21 16:02:18 +02:00
# not finished yet https://www.youtube.com/watch?v=abHftC1GU6w
queue = []
heappush(queue, (0, start))
cost_visited = {start: 0}
visited = {start: None}
while queue:
cur_cost, cur_node = heappop(queue)
if cur_node == goal:
2023-04-21 15:29:32 +02:00
queue = []
break
next_nodes = self.graph[cur_node]
for next_node in next_nodes:
neigh_cost, neigh_node = next_node
new_cost = cost_visited[cur_node] + neigh_cost
2023-04-21 15:29:32 +02:00
if neigh_node not in cost_visited or new_cost < cost_visited[neigh_node]:
heappush(queue, (new_cost, neigh_node))
cost_visited[neigh_node] = new_cost
visited[neigh_node] = cur_node
2023-04-21 15:29:32 +02:00
# print(visited)
return visited
2023-04-21 16:02:18 +02:00
class Tractor:
def __init__(self, x, y, direction: Direction):
self.x = x
self.y = y
self.direction = direction
self.gas = GAS_TANK_CAPACITY
self.water = WATER_TANK_CAPACITY
self.collected_vegetables = {vegetables.POTATO: 0, vegetables.BROCCOLI: 0, vegetables.CARROT: 0,
vegetables.ONION: 0}
self.image = pygame.transform.scale(pygame.image.load("images/tractor_image.png"), (BLOCK_SIZE, BLOCK_SIZE))
def rot_center(self, direc: Direction):
self.image = pygame.transform.rotate(self.image, - int(direc) * 90)
self.direction = ((int(self.direction) + int(direc)) % 4)
return
def move(self, grid: Grid):
if self.direction == Direction.UP:
if self.y > 0:
self.y -= 1
elif self.direction == Direction.RIGHT:
if self.x < BOARD_SIZE - 1:
self.x += 1
elif self.direction == Direction.DOWN:
if self.y < BOARD_SIZE - 1:
self.y += 1
elif self.direction == Direction.LEFT:
if self.x > 0:
self.x -= 1
if grid.grid[self.x][self.y] == types.ROCK:
self.gas -= 5
else:
self.gas -= 1
return
2023-04-21 15:29:32 +02:00
2023-04-27 13:21:43 +02:00
def get_next_nodes(x, y, direction: Direction, grid: Grid):
check_next_node = lambda x, y: True if 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE else False
way = [0, -1] if direction == Direction.UP else [1, 0] if direction == Direction.RIGHT else [0, 1] if direction == Direction.DOWN else [-1, 0]
next_nodes = []
for new_direction in Direction:
if new_direction != direction:
next_nodes.append((1, (x, y, new_direction)))
else:
if check_next_node(x + way[0], y + way[1]):
next_nodes.append((grid.grid[x + way[0]][y + way[1]].value, (x + way[0], y + way[1], new_direction)))
return next_nodes
2023-04-21 16:02:18 +02:00
def movement(traktor: Tractor, grid: Grid, road):
2023-04-21 15:29:32 +02:00
n = len(road)
2023-04-21 16:02:18 +02:00
for i in range(n - 1):
if road[i][0] != road[i + 1][0]:
if road[i][0] > road[i + 1][0]:
if traktor.direction != 3:
while traktor.direction != 3:
2023-04-21 15:29:32 +02:00
traktor.rot_center(Direction.LEFT)
traktor.move(grid=grid)
print("move left")
2023-04-21 16:02:18 +02:00
elif road[i][0] < road[i + 1][0]:
if traktor.direction != 1:
while traktor.direction != 1:
2023-04-21 15:29:32 +02:00
traktor.rot_center(Direction.LEFT)
traktor.move(grid=grid)
print("move right")
else:
if road[i][1] > road[i + 1][1]:
2023-04-21 16:02:18 +02:00
if traktor.direction != 0:
while traktor.direction != 0:
2023-04-21 15:29:32 +02:00
traktor.rot_center(Direction.LEFT)
traktor.move(grid=grid)
print("move up")
elif road[i][1] < road[i + 1][1]:
2023-04-21 16:02:18 +02:00
if traktor.direction != 2:
while traktor.direction != 2:
2023-04-21 15:29:32 +02:00
traktor.rot_center(Direction.LEFT)
traktor.move(grid=grid)
print("move down")
2023-04-21 16:02:18 +02:00
2023-04-21 15:29:32 +02:00
def getRoad(start, goal, visited):
arr = []
aFrom = goal
while aFrom != start:
arr.append(aFrom)
aFrom = visited[aFrom]
arr.append(start)
2023-04-21 16:02:18 +02:00
brr = arr[::-1]
2023-04-21 15:29:32 +02:00
return brr
# grid = Grid(BOARD_SIZE, BOARD_SIZE, BLOCK_SIZE)
# graph1 = Graph(grid)
# graph1.initialize_graph(grid)
#
# startpoint = (1, 1)
# endpoint = (2,2)
#
# a = graph1.dijkstra(startpoint, endpoint)
# b = getRoad(startpoint, endpoint, a)
# print(b)