Projekt_Sztuczna_Inteligencja/main.py

197 lines
6.6 KiB
Python

# libraries
import pygame
import time
from pyglet.gl import * # for blocky textures
import random
# other files of this project
import project_constants as const
import minefield as mf
from mine_models.time_mine import TimeMine
import searching_algorithms.a_star as a_star
from display_assets import blit_graphics
from project_constants import HIGHLIGHT, INPUT_ROW, INPUT_COLUMN, RANDOM_BUTTON, OK_BUTTON
from ui.ui_components_list import UiComponentsList
from ui.text_box import TextBox
from ui.button import Button
def main():
pygame.init()
pygame.display.set_caption(const.V_NAME_OF_WINDOW)
# for blocky textures
glEnable(GL_TEXTURE_2D)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
# FPS clock
clock = pygame.time.Clock()
# create an instance of Minefield, pass necessary data
minefield = mf.Minefield(const.MAP_RANDOM_10x10)
# getting agent's instance
agent = minefield.agent
# setting flags for program
running = True
in_menu = True
is_game_over = False
# creating list storing all ui components
ui_components_list = UiComponentsList([INPUT_ROW, INPUT_COLUMN, RANDOM_BUTTON, OK_BUTTON])
# initializing goal position
row, column = 0, 0
# drawing map so black screen doesn't appear
blit_graphics(minefield)
while running:
# ============== #
# ==== MENU ==== #
# ============== #
while running and in_menu:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
running = False
# graphics (from display_assets)
blit_graphics(minefield)
agent.update_and_draw(const.SCREEN, 0)
# drawing gui
ui_components_list.run_all(const.SCREEN, pygame.mouse.get_pos(), events)
# highlighting chosen tile destination (if exists)
if not (INPUT_ROW.empty() or INPUT_COLUMN.empty()):
row = min(9, int(INPUT_ROW.get_input()))
column = min(9, int(INPUT_COLUMN.get_input()))
const.SCREEN.blit(HIGHLIGHT, const.get_tile_coordinates((row, column)))
# updating graphics
pygame.display.flip()
ui_components_list.switch_selected_objects_with_arrow_keys(events, pygame.mouse.get_pos())
OK_BUTTON.set_flags(is_active=(not (INPUT_ROW.empty() or INPUT_COLUMN.empty())))
if OK_BUTTON.is_clicked(pygame.mouse.get_pos(), events) or OK_BUTTON.enter_pressed(events):
in_menu = False
if RANDOM_BUTTON.is_clicked(pygame.mouse.get_pos(), events) or RANDOM_BUTTON.enter_pressed(events):
INPUT_ROW.set_texts(user_input=str(random.randint(0, 9)))
INPUT_COLUMN.set_texts(user_input=str(random.randint(0, 9)))
clock.tick(const.V_FPS)
# ========================== #
# ==== BEFORE GAME LOOP ==== #
# ========================== #
if running:
for component in ui_components_list.selectable_ui_components:
component.set_flags(is_active=False)
action_sequence = a_star.graphsearch(
initial_state=a_star.State(
row=minefield.agent.position[0],
column=minefield.agent.position[1],
direction=minefield.agent.direction),
minefield=minefield, tox=row, toy=column)
action = None
in_game_timer = 0
# =================== #
# ==== GAME LOOP ==== #
# =================== #
while running and not in_menu and not is_game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# FPS control
clock.tick(const.V_FPS)
delta_time = clock.get_time() / 1000
action_delta_time = delta_time / const.ACTION_INTERVAL
# graphics (from display_assets)
blit_graphics(minefield)
const.SCREEN.blit(HIGHLIGHT, const.get_tile_coordinates((row, column)))
agent.update_and_draw(const.SCREEN, action_delta_time)
# drawing ui components so they don't "disappear"
ui_components_list.draw_all(const.SCREEN, pygame.mouse.get_pos())
# updating graphics
pygame.display.flip()
# make the next move from sequence of actions
if in_game_timer >= const.ACTION_INTERVAL and any(action_sequence):
in_game_timer -= const.ACTION_INTERVAL
minefield.next_turn()
agent.take_action(action)
action = action_sequence.pop(0)
agent.animate(action)
elif in_game_timer >= const.ACTION_INTERVAL:
agent.take_action(action)
agent.update_and_draw(const.SCREEN, delta_time)
agent.reset_actions()
in_menu = True
if not any([x.is_selected for x in ui_components_list.ui_components]):
INPUT_ROW.set_is_selected(True)
for component in ui_components_list.selectable_ui_components:
component.set_flags(is_active=True)
in_game_timer += delta_time
for x in minefield.matrix:
for y in x:
if y.mine is not None:
if isinstance(y.mine, TimeMine):
if y.mine.timer == 0:
is_game_over = True
while running and is_game_over:
clock.tick(const.V_FPS)
const.SCREEN.fill((255, 255, 255))
tb = TextBox(position=(150, 200), dimensions=(500, 100), text="Game Over")
cont = Button(position=(350, 350), dimensions=(100, 50), text="Try again")
close = Button(position=(350, 450), dimensions=(100, 50), text="Close")
ev = pygame.event.get()
if close.is_clicked(pygame.mouse.get_pos(), ev):
running = False
if cont.is_clicked(pygame.mouse.get_pos(), ev):
minefield = mf.Minefield(const.MAP_RANDOM_10x10)
agent = minefield.agent
in_menu = True
is_game_over = False
for component in ui_components_list.selectable_ui_components:
component.set_flags(is_active=True)
cont.draw(const.SCREEN, pygame.mouse.get_pos())
close.draw(const.SCREEN, pygame.mouse.get_pos())
tb.draw(const.SCREEN)
pygame.display.flip()
# is_game_over = False
if __name__ == "__main__":
main()