Sztuczna_inteligencja/board.py

215 lines
9.4 KiB
Python
Raw Normal View History

import random
import pygame
import sys
import pathfinder
import time
from decisiontree import DecisionTree
from imagerecognizer import ImageRecognizer
from objects import Grass
from objects import Mine
from objects import Rock
from objects import Puddle
MARGIN = 20 # marginesy - odległość kraty od końca okna
SQUARE_HEIGHT = 35
SQUARE_WIDTH = 35
CENTER_DIST = 38 # odległość pomiędzy środkami kwadratów
BOARDCOLS = 15 # liczba kolumn planszy
BOARDROWS = BOARDCOLS # liczba wierszy planszy
WINDOW_HEIGHT = BOARDCOLS * CENTER_DIST + (2 * MARGIN)
WINDOW_WIDTH = BOARDROWS * CENTER_DIST + (2 * MARGIN)
class Field: # obiekt clasy field jest pojedynczym polem planszy
def __init__(self, coordinates, color, fieldty):
Board.fields.append(self)
self.rect = pygame.Rect(coordinates[0], coordinates[1], SQUARE_WIDTH, SQUARE_HEIGHT)
self.color = color
self.type = fieldty
self.object = self.assign_object()
self.deley_value = self.object.deley
self.redisp = True
def assign_object(self):
if self.type == 'T':
object = Grass(self.rect.center[0],self.rect.center[1], SQUARE_WIDTH, SQUARE_HEIGHT)
return object
if self.type == 'P':
object = Puddle(self.rect.center[0],self.rect.center[1],SQUARE_WIDTH, SQUARE_HEIGHT)
return object
if self.type == 'R':
object = Rock(self.rect.center[0],self.rect.center[1],SQUARE_WIDTH, SQUARE_HEIGHT)
return object
if self.type == 'B':
object = Mine(self.rect.center[0],self.rect.center[1],SQUARE_WIDTH, SQUARE_HEIGHT)
return object
class Board:
fields = [] # tablica obiektów klasy filed, czyli po prostu tablica pól planszy gotowych do wizualizacji
bombs = 0
def __init__(self):
self.margin = MARGIN
self.square_high = SQUARE_HEIGHT
self.square_width = SQUARE_WIDTH
self.center_dist = CENTER_DIST
self.window_height = WINDOW_HEIGHT
self.window_widhth = WINDOW_WIDTH
self.boardcols = BOARDCOLS # liczba kolumn planszy
self.boardrows = BOARDROWS # liczba wierszy planszy
self.board = [[0 for i in range(self.boardcols)] for j in range(self.boardrows)]
self.firstwinner = True
pygame.display.set_caption("Saper")
self.game_display = pygame.display.set_mode((self.window_height, self.window_widhth)) # wielkość okna adaptująca się do wielkości planszy
self.load_board()
self.first_ground = self.board[0].index('T')
self.show_board()
self.init_board()
self.bombfield = pathfinder.find_bomb(self.fields, self.first_ground)
print(self.bombfield)
self.pathf = pathfinder.Pathfind(self.fields, self.bombfield, self.first_ground)
self.ir = ImageRecognizer()
self.dt = DecisionTree()
def load_board(self): # funkcja tworząca tablicę opisującą planszę
for i in range(self.boardrows):
for j in range(self.boardcols):
chance = random.randint(1,100) # prawdopodobieństwo że dane pole będzie terenem (T), przeszkodą (O) lub bombą (B)
if chance >= 1 and chance < 80:
self.board[i][j] = 'T'
if chance >= 80 and chance < 95:
chance = random.randint(1,2)
if chance == 1:
self.board[i][j] = 'R'
if chance == 2:
self.board[i][j] = 'P'
if chance >= 95 and chance <= 100:
self.board[i][j] = 'B'
self.bombs += 1
def show_board(self): # funkcja pomocnicza wypisująca tablicę opisującą planszę
for i in range(self.boardrows):
for j in range(self.boardcols):
print(self.board[i][j], end=' ')
print("")
print("")
print("bomby:",self.bombs)
def init_board(self): # funkcja inicjująca planszę
x = self.margin
y = self.margin
for i in range(self.boardrows):
for j in range(self.boardcols):
if self.board[i][j] == 'T':
Field((x, y), (0, 128,0), 'T') # tworzony jest obiekt clasy field zawierający współżędne oraz kolor danego pola planszy
if self.board[i][j] == 'R':
Field((x, y), (255, 255, 0), 'R')
if self.board[i][j] == 'P':
Field((x, y), (255, 255, 0), 'P')
if self.board[i][j] == 'B':
Field((x, y), (165, 42, 42), 'B')
x += self.center_dist
y += self.center_dist
x = self.margin
def objects_display(self,i):
objecttype = self.fields[i].object
self.game_display.blit(objecttype.image_scaled, objecttype.rect)
def board_events(self, agent):
for event in pygame.event.get():
self.agent_field_update(agent)
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: # klawisz esc zamyka program
sys.exit(0)
#if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT and agent.pos_field+1 < len(self.fields):
# if self.fields[agent.pos_field+1].object.walkable == 0:
# self.fields[agent.pos_field].redisp = True
# agent.move(self.window_height, self.margin, self.center_dist, "RIGHT", 1)
#if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT and agent.pos_field-1 >= 0:
# if self.fields[agent.pos_field - 1].object.walkable == 0:
# self.fields[agent.pos_field].redisp = True
# agent.move(self.window_height, self.margin, self.center_dist, "LEFT", -1)
#if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN and agent.pos_field+BOARDROWS < len(self.fields):
# if self.fields[agent.pos_field + BOARDROWS].object.walkable == 0:
# self.fields[agent.pos_field].redisp = True
# agent.move(self.window_height, self.margin, self.center_dist, "DOWN", BOARDROWS)
#if event.type == pygame.KEYDOWN and event.key == pygame.K_UP and agent.pos_field-BOARDROWS >= 0:
# if self.fields[agent.pos_field - BOARDROWS].object.walkable == 0:
# self.fields[agent.pos_field].redisp = True
# agent.move(self.window_height,self.margin,self.center_dist,"UP", -BOARDROWS)
def agent_field_update(self,agent):
agent.cooldown = 100
if self.fields[agent.pos_field].type == 'B' and self.fields[agent.pos_field].object.defused == False:
if self.ir.recognize(self.fields[agent.pos_field].object.itr) == "stones":
print("to kamień!")
self.fields[agent.pos_field].object.its_rock(SQUARE_WIDTH, SQUARE_HEIGHT)
self.fields[agent.pos_field].redisp = True
self.bombs -= 1
else:
print("to bomba!")
wtd = self.dt.make_decision(((self.bombs*100)//(BOARDCOLS**2))+1, self.fields[agent.pos_field].object.time, self.fields[agent.pos_field].object.reach)
if wtd == "Defuse":
self.fields[agent.pos_field].object.defuse(SQUARE_WIDTH, SQUARE_HEIGHT)
self.fields[agent.pos_field].redisp = True
if wtd == "Move away":
self.fields[agent.pos_field].object.move_away(SQUARE_WIDTH, SQUARE_HEIGHT)
self.fields[agent.pos_field].redisp = True
self.bombs -= 1
if self.bombs > 0:
self.bombfield = pathfinder.find_bomb(self.fields, agent.pos_field)
#print(self.bombfield)
self.pathf = pathfinder.Pathfind(self.fields, self.bombfield, agent.pos_field)
def automove_agent(self,agent):
self.agent_field_update(agent)
if len(self.pathf.way) > 0:
wayfield = self.pathf.way[0]
self.pathf.way.remove(wayfield)
if agent.pos_field - BOARDCOLS == wayfield:
self.fields[agent.pos_field].redisp = True
agent.move(self.window_height, self.margin, self.center_dist, "UP", -BOARDCOLS)
if agent.pos_field + BOARDCOLS == wayfield:
self.fields[agent.pos_field].redisp = True
agent.move(self.window_height, self.margin, self.center_dist, "DOWN", BOARDCOLS)
if agent.pos_field - 1 == wayfield:
self.fields[agent.pos_field].redisp = True
agent.move(self.window_height, self.margin, self.center_dist, "LEFT", -1)
if agent.pos_field + 1 == wayfield:
self.fields[agent.pos_field].redisp = True
agent.move(self.window_height, self.margin, self.center_dist, "RIGHT", 1)
def full_board_display(self,first): # funkcja pomocnicza wywołująca program, w celu wizualizacji planszy możną ją wywołać
if self.bombs <= 0 and self.firstwinner == True:
print("wszystkie miny rozbrojone!")
self.firstwinner = False
if first == True:
self.game_display.fill((0, 0, 0))
i=0
for square in self.fields:
if square.redisp == True:
pygame.draw.rect(self.game_display, square.color, square.rect)
self.objects_display(i)
square.redisp = False
i=i+1