Przeszukiwanie przestrzeni stanów za pomocą BFS
This commit is contained in:
parent
26ce5b770e
commit
6c9bda39e6
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
container/__pycache__/graph.cpython-39.pyc
Normal file
BIN
container/__pycache__/graph.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
container/__pycache__/state.cpython-39.pyc
Normal file
BIN
container/__pycache__/state.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
@ -3,12 +3,90 @@ from container.piece import Piece
|
||||
|
||||
|
||||
class Agent(Piece):
|
||||
def __init__(self,x_y):
|
||||
def __init__(self,x_y, square_size):
|
||||
self.name = "Agent"
|
||||
self.row = x_y[0]
|
||||
self.col = x_y[1]
|
||||
self.col = x_y[0]
|
||||
self.row = x_y[1]
|
||||
self.angle = 0
|
||||
self.moving = 0
|
||||
self.rotating = 0
|
||||
self.move_to = (self.row, self.col)
|
||||
|
||||
self.points = 0
|
||||
self.img = pygame.image.load(r'container\detective.png')
|
||||
self.img = pygame.image.load(r'container\new_detective.png')
|
||||
self.square_size = square_size
|
||||
self.img = pygame.transform.scale(self.img, (int(self.square_size[0]), int(self.square_size[1])))
|
||||
|
||||
|
||||
def draw(self, win):
|
||||
x = (self.col + 0.5 + (self.move_to[0] - self.col)/10*self.moving)*self.square_size[0]
|
||||
y = (self.row + 0.5 + (self.move_to[1] - self.row)/10*self.moving)*self.square_size[1]
|
||||
|
||||
#win.blit(self.img, (x, y))
|
||||
|
||||
self.blitRotate(win, self.img, (x, y), (self.square_size[0]/2, self.square_size[1]/2), self.angle*90 + self.rotating*90/10)
|
||||
|
||||
def rotate(self, angle):
|
||||
if self.moving == self.rotating == 0:
|
||||
self.rotating += angle
|
||||
|
||||
def move(self):
|
||||
if self.moving == self.rotating == 0:
|
||||
move_to = (0,-1)
|
||||
if self.angle == 1: move_to = (-1,0)
|
||||
if self.angle == 2: move_to = (0,1)
|
||||
if self.angle == 3: move_to = (1,0)
|
||||
|
||||
self.move_to = (self.col + move_to[0], self.row + move_to[1])
|
||||
|
||||
self.moving += 1
|
||||
|
||||
def update_animation(self):
|
||||
if self.moving > 0:
|
||||
self.moving += 1
|
||||
if self.moving >= 10:
|
||||
self.moving = 0
|
||||
self.col, self.row = self.move_to
|
||||
|
||||
if self.rotating > 0:
|
||||
self.rotating += 1
|
||||
if self.rotating >= 10:
|
||||
self.rotating = 0
|
||||
self.angle = (self.angle + 1) % 4
|
||||
if self.rotating < 0:
|
||||
self.rotating -= 1
|
||||
if self.rotating <= -10:
|
||||
self.rotating = 0
|
||||
self.angle = (self.angle - 1) % 4
|
||||
|
||||
|
||||
def blitRotate(self, surf, image, pos, originPos, angle):
|
||||
|
||||
# calcaulate the axis aligned bounding box of the rotated image
|
||||
w, h = image.get_size()
|
||||
box = [pygame.math.Vector2(p) for p in [(0, 0), (w, 0), (w, -h), (0, -h)]]
|
||||
box_rotate = [p.rotate(angle) for p in box]
|
||||
min_box = (min(box_rotate, key=lambda p: p[0])[0], min(box_rotate, key=lambda p: p[1])[1])
|
||||
max_box = (max(box_rotate, key=lambda p: p[0])[0], max(box_rotate, key=lambda p: p[1])[1])
|
||||
|
||||
# calculate the translation of the pivot
|
||||
pivot = pygame.math.Vector2(originPos[0], -originPos[1])
|
||||
pivot_rotate = pivot.rotate(angle)
|
||||
pivot_move = pivot_rotate - pivot
|
||||
|
||||
# calculate the upper left origin of the rotated image
|
||||
origin = (pos[0] - originPos[0] + min_box[0] - pivot_move[0], pos[1] - originPos[1] - max_box[1] + pivot_move[1])
|
||||
|
||||
# get a rotated image
|
||||
rotated_image = pygame.transform.rotate(image, angle)
|
||||
|
||||
# rotate and blit the image
|
||||
surf.blit(rotated_image, origin)
|
||||
|
||||
# draw rectangle around the image
|
||||
#pygame.draw.rect(surf, (255, 0, 0), (*origin, *rotated_image.get_size()),2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,25 +1,12 @@
|
||||
import pygame
|
||||
import random
|
||||
#sth goes wrong with imports so its for preventing errors
|
||||
"""
|
||||
try:
|
||||
from .constans import GREEN,GREEN_2,WHITE,ROWS,COLUMNS,SQUARE_SIZE,MARGIN
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
from constans import GREEN,GREEN_2,WHITE,ROWS,COLUMNS,SQUARE_SIZE,MARGIN
|
||||
|
||||
#sth goes wrong with imports so its for preventing errors
|
||||
try:
|
||||
from .piece import *
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
from piece import *
|
||||
from agent import *
|
||||
|
||||
#from .constans import GREEN,GREEN_2,WHITE,ROWS,COLUMNS,SQUARE_SIZE
|
||||
"""
|
||||
from container.constans import *
|
||||
from container.tree import Tree
|
||||
from container.mushroom import Mushroom
|
||||
from container.agent import Agent
|
||||
from container.state import State
|
||||
from container.graph import Graph
|
||||
|
||||
class Board:
|
||||
def __init__(self, x = 0, y = 0, width = WIDTH, height = HEIGHT, row = ROWS, col = COLUMNS):
|
||||
@ -29,12 +16,14 @@ class Board:
|
||||
self.height = height
|
||||
self.row = row
|
||||
self.col = col
|
||||
self.square_size = (self.width // self.col, self.height // self.row)
|
||||
self.board = [[False for j in range(self.col)] for i in range(self.row)]
|
||||
self.square_size = (self.width / self.col, self.height / self.row)
|
||||
self.board = [[False for j in range(self.row)] for i in range(self.col)]
|
||||
self.free_spaces = []
|
||||
self.update_free_spaces()
|
||||
|
||||
self.agent = Agent(self.free_spaces.pop())
|
||||
self.agent = Agent(self.free_spaces.pop(), self.square_size)
|
||||
|
||||
print(f"Board {col}x{row} with agent on ({self.agent.col},{self.agent.row})")
|
||||
|
||||
self.surface = pygame.Surface((self.width, self.height))
|
||||
|
||||
@ -47,45 +36,72 @@ class Board:
|
||||
x_y = self.free_spaces.pop()
|
||||
self.board[x_y[0]][x_y[1]] = Mushroom(x_y, random.randint(0, 2))
|
||||
|
||||
for i in range(POISON_MUSHROOMS_MAX):
|
||||
for i in range(POISON_MUSHROOMS_START):
|
||||
x_y = self.free_spaces.pop()
|
||||
self.board[x_y[0]][x_y[1]] = Mushroom(x_y, random.randint(0, 2), True)
|
||||
|
||||
#generowanie przestrzeni stanów
|
||||
# dla każdego pola (nie będącego drzewem) tworzę 4 stany dla 4 pozycji obrotu
|
||||
# potem dla każdego stanu dodaję listę stanów sąsiadujących i połączenia te nazywam "rotate_left" "rotate_right" "move"
|
||||
self.set_of_states = []
|
||||
id_couunt = 0
|
||||
for x in range(self.col):
|
||||
for y in range(self.row):
|
||||
if self.board[x][y] == False or self.board[x][y].name != "Tree":
|
||||
for angle in range(4):
|
||||
self.set_of_states.append(State(id_couunt, x, y, angle))
|
||||
id_couunt += 1
|
||||
|
||||
self.set_of_states[id_couunt-4].adjacent_states.append((id_couunt-3, "rotate_left"))
|
||||
self.set_of_states[id_couunt-4].adjacent_states.append((id_couunt-1, "rotate_right"))
|
||||
|
||||
self.set_of_states[id_couunt-3].adjacent_states.append((id_couunt-4, "rotate_right"))
|
||||
self.set_of_states[id_couunt-3].adjacent_states.append((id_couunt-2, "rotate_left"))
|
||||
|
||||
self.set_of_states[id_couunt-2].adjacent_states.append((id_couunt-3, "rotate_right"))
|
||||
self.set_of_states[id_couunt-2].adjacent_states.append((id_couunt-1, "rotate_left"))
|
||||
|
||||
self.set_of_states[id_couunt-1].adjacent_states.append((id_couunt-4, "rotate_left"))
|
||||
self.set_of_states[id_couunt-1].adjacent_states.append((id_couunt-2, "rotate_right"))
|
||||
|
||||
for state in self.set_of_states:
|
||||
for s in self.set_of_states:
|
||||
if state.angle == s.angle == 0 and state.x == s.x and state.y - 1 == s.y: state.adjacent_states.append((s.id, "move"))
|
||||
elif state.angle == s.angle == 1 and state.x - 1 == s.x and state.y == s.y: state.adjacent_states.append((s.id, "move"))
|
||||
elif state.angle == s.angle == 2 and state.x == s.x and state.y + 1 == s.y: state.adjacent_states.append((s.id, "move"))
|
||||
elif state.angle == s.angle == 3 and state.x + 1 == s.x and state.y == s.y: state.adjacent_states.append((s.id, "move"))
|
||||
|
||||
|
||||
self.graph = None
|
||||
self.path = []
|
||||
|
||||
def update_free_spaces(self):
|
||||
self.free_spaces = []
|
||||
|
||||
for x in range(self.row):
|
||||
for y in range(self.col):
|
||||
for x in range(self.col):
|
||||
for y in range(self.row):
|
||||
if self.board[x][y] == False: self.free_spaces.append((x,y))
|
||||
|
||||
random.shuffle(self.free_spaces)
|
||||
|
||||
|
||||
def get_piece(self,x,y):
|
||||
#print(self.board[x][y], x, y)
|
||||
return self.board[x][y]
|
||||
|
||||
def draw_squares(self,win):
|
||||
self.surface.fill(GREEN_2)
|
||||
for row in range(self.row):
|
||||
for col in range(self.col):
|
||||
if (row+col) % 2 == 0:
|
||||
pygame.draw.rect(self.surface,GREEN,(col*self.square_size[0], row*self.square_size[1], self.square_size[0], self.square_size[1]))
|
||||
for x in range(self.col):
|
||||
for y in range(self.row):
|
||||
if (x+y) % 2 == 0:
|
||||
pygame.draw.rect(self.surface,GREEN,(x*self.square_size[0], y*self.square_size[1], self.square_size[0], self.square_size[1]))
|
||||
|
||||
win.blit(self.surface, (self.x, self.y))
|
||||
|
||||
def draw_agent(self,win):
|
||||
self.agent.draw(self.surface, self.square_size)
|
||||
self.agent.draw(self.surface)
|
||||
win.blit(self.surface, (self.x, self.y))
|
||||
|
||||
def draw_pieces(self,win):
|
||||
for row in range(self.row):
|
||||
for col in range(self.col):
|
||||
if self.board[row][col] != False:
|
||||
self.board[row][col].draw(self.surface, self.square_size)
|
||||
for x in range(self.col):
|
||||
for y in range(self.row):
|
||||
if self.board[x][y] != False:
|
||||
self.board[x][y].draw(self.surface, self.square_size)
|
||||
win.blit(self.surface, (self.x, self.y))
|
||||
|
||||
def draw_info(self,win):
|
||||
@ -93,15 +109,83 @@ class Board:
|
||||
textsurface = myfont.render(str(self.agent.points), False, (0, 0, 0))
|
||||
win.blit(textsurface,(self.x+self.width-textsurface.get_width()-5,self.y-40))
|
||||
|
||||
def move(self, x, y):
|
||||
if 0 <= self.agent.row + x < self.row and 0 <= self.agent.col + y < self.col:
|
||||
if self.board[self.agent.row + x][self.agent.col + y] == False or self.board[self.agent.row + x][self.agent.col + y].name != "Tree":
|
||||
self.agent.col += y
|
||||
self.agent.row += x
|
||||
if self.board[self.agent.row][self.agent.col] != False:
|
||||
self.agent.points += self.board[self.agent.row][self.agent.col].points
|
||||
self.board[self.agent.row][self.agent.col] = False
|
||||
|
||||
# kolumna agneta
|
||||
textsurface = myfont.render("c: "+str(self.agent.col), False, (0, 0, 0))
|
||||
win.blit(textsurface,(self.x+1,self.y-40))
|
||||
|
||||
# wiersz agneta
|
||||
textsurface = myfont.render("r: "+str(self.agent.row), False, (0, 0, 0))
|
||||
win.blit(textsurface,(self.x+100,self.y-40))
|
||||
|
||||
# kierunek agenta
|
||||
textsurface = myfont.render("a: "+str(self.agent.angle), False, (0, 0, 0))
|
||||
win.blit(textsurface,(self.x+200,self.y-40))
|
||||
|
||||
# id stanu agenta
|
||||
state = 0
|
||||
for s in self.set_of_states:
|
||||
if self.agent.col == s.x and self.agent.row == s.y and self.agent.angle == s.angle: state = s.id
|
||||
|
||||
textsurface = myfont.render("s: "+str(state), False, (0, 0, 0))
|
||||
win.blit(textsurface,(self.x+300,self.y-40))
|
||||
|
||||
|
||||
def update_agent(self):
|
||||
self.agent.update_animation()
|
||||
|
||||
if self.board[self.agent.col][self.agent.row] != False and self.board[self.agent.col][self.agent.row].name == "Mushroom":
|
||||
self.agent.points += self.board[self.agent.col][self.agent.row].points
|
||||
self.board[self.agent.col][self.agent.row] = False
|
||||
self.free_spaces.append((self.agent.col, self.agent.row))
|
||||
|
||||
# wykonaj następny ruch na ścieżce
|
||||
if len(self.path) > 0:
|
||||
if self.agent.moving == self.agent.rotating == 0:
|
||||
move = self.path.pop(0)
|
||||
|
||||
print(f"execute {move}")
|
||||
|
||||
if move[1] == "move": self.agent.move()
|
||||
elif move[1] == "rotate_left": self.agent.rotate(1)
|
||||
elif move[1] == "rotate_right": self.agent.rotate(-1)
|
||||
|
||||
def next_move(self):
|
||||
start_state = 0
|
||||
|
||||
for state in self.set_of_states:
|
||||
if state.x == self.agent.col and state.y == self.agent.row and state.angle == self.agent.angle: start_state = state.id
|
||||
|
||||
self.graph = Graph(start_state)
|
||||
|
||||
state_to_add = [start_state]
|
||||
|
||||
self.path = []
|
||||
|
||||
# BFS
|
||||
while len(state_to_add) > 0:
|
||||
state = state_to_add.pop(0)
|
||||
print(f"checking {state}, x:{self.set_of_states[state].x}, y:{self.set_of_states[state].y}, a:{self.set_of_states[state].angle}")
|
||||
|
||||
self.graph.visit(state)
|
||||
|
||||
# test czy znaleźliśmy grzyba
|
||||
if self.board[self.set_of_states[state].x][self.set_of_states[state].y] != False and self.board[self.set_of_states[state].x][self.set_of_states[state].y].name == "Mushroom" and self.board[self.set_of_states[state].x][self.set_of_states[state].y].poison == False:
|
||||
self.path = self.graph.get_path(state)
|
||||
break
|
||||
|
||||
# dodawanie kolejnych stanów
|
||||
for s in self.set_of_states[state].adjacent_states:
|
||||
print(f"\t checking {s[0]}, x:{self.set_of_states[s[0]].x}, y:{self.set_of_states[s[0]].y}, a:{self.set_of_states[s[0]].angle}, s:{s[1]}")
|
||||
if self.graph.is_visited(s[0]) == False:
|
||||
self.graph.add(s[0], state, s[1])
|
||||
state_to_add.append(s[0])
|
||||
print(f"\t add {s[0]} {s[1]}")
|
||||
|
||||
#print(self.path)
|
||||
print("-------------------------")
|
||||
|
||||
#for v in self.graph.vertices:
|
||||
# print(f" id:{v.id} parent:{v.parent} move:{v.move}, visited:{v.visited}")
|
||||
|
||||
|
||||
|
||||
|
@ -3,8 +3,8 @@ import pygame
|
||||
#board size variables
|
||||
WIDTH = 1000
|
||||
HEIGHT = 700
|
||||
ROWS = 7
|
||||
COLUMNS = 10
|
||||
COLUMNS = 20
|
||||
ROWS = 14
|
||||
|
||||
#number of mushrooms
|
||||
|
||||
@ -12,7 +12,7 @@ MUSHROOMS_START = 5
|
||||
MUSHROOMS_MAX = 10
|
||||
POISON_MUSHROOMS_START = 5
|
||||
POISON_MUSHROOMS_MAX = 10
|
||||
TREES = 5
|
||||
TREES = 50
|
||||
|
||||
|
||||
#colors in game in rgb
|
||||
|
55
container/graph.py
Normal file
55
container/graph.py
Normal file
@ -0,0 +1,55 @@
|
||||
class Vertex():
|
||||
def __init__(self, id, parent, depth, move):
|
||||
self.id = id
|
||||
self.parent = parent
|
||||
self.child = []
|
||||
self.visited = False
|
||||
self.depth = depth
|
||||
self.move = move
|
||||
|
||||
|
||||
class Graph():
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.vertices = [Vertex(root, None, 0, None)]
|
||||
|
||||
def add(self, id, parent, move):
|
||||
for v in self.vertices:
|
||||
if v.id == id and v.parent == parent:
|
||||
return
|
||||
|
||||
for v in self.vertices:
|
||||
if v.id == parent:
|
||||
self.vertices.append(Vertex(id, parent, v.depth+1, move))
|
||||
v.child.append(id)
|
||||
return
|
||||
|
||||
def visit(self, id):
|
||||
for v in self.vertices:
|
||||
if v.id == id: v.visited = True
|
||||
|
||||
def is_visited(self, id):
|
||||
for v in self.vertices:
|
||||
if v.id == id: return v.visited
|
||||
return False
|
||||
|
||||
def get_path(self, id):
|
||||
result = []
|
||||
next = None
|
||||
for v in self.vertices:
|
||||
if v.id == id:
|
||||
result.append([v.id, v.move])
|
||||
next = v.parent
|
||||
|
||||
while next != None:
|
||||
for v in self.vertices:
|
||||
if v.id == next:
|
||||
result.append([v.id, v.move])
|
||||
next = v.parent
|
||||
return result[::-1]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -4,11 +4,15 @@ import pygame
|
||||
class Mushroom(Piece):
|
||||
def __init__(self,x_y, img = 0, poison = False):
|
||||
self.name = "Mushroom"
|
||||
self.row = x_y[0]
|
||||
self.col = x_y[1]
|
||||
self.col = x_y[0]
|
||||
self.row = x_y[1]
|
||||
self.poison = poison
|
||||
|
||||
|
||||
|
||||
self.img = pygame.image.load(r'container\mushrooms\m'+str(img)+'.png')
|
||||
if poison: self.img = pygame.image.load(r'container\mushrooms\pm'+str(img)+'.png')
|
||||
|
||||
self.points = img+1
|
||||
if poison: self.points *= -1
|
||||
|
||||
|
BIN
container/new_detective.png
Normal file
BIN
container/new_detective.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -4,8 +4,8 @@ class Piece:
|
||||
|
||||
def __init__(self,x_y):
|
||||
self.name = ""
|
||||
self.row = x_y[0]
|
||||
self.col = x_y[1]
|
||||
self.col = x_y[0]
|
||||
self.row = x_y[1]
|
||||
self.img = ''
|
||||
self.mushroom = False
|
||||
self.isSbThere = False
|
||||
@ -15,7 +15,7 @@ class Piece:
|
||||
self.isSbThere = not self.isSbThere
|
||||
|
||||
def draw(self, win, square_size):
|
||||
win.blit(pygame.transform.scale(self.img, square_size), (self.col*square_size[0], self.row*square_size[1]))
|
||||
win.blit(pygame.transform.scale(self.img, (int(square_size[0]), int(square_size[1]))), (self.col*square_size[0], self.row*square_size[1]))
|
||||
|
||||
|
||||
|
||||
|
9
container/state.py
Normal file
9
container/state.py
Normal file
@ -0,0 +1,9 @@
|
||||
class State():
|
||||
def __init__(self, id, x, y, angle):
|
||||
self.id = id
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.angle = angle
|
||||
|
||||
self.adjacent_states = []
|
||||
|
@ -4,8 +4,8 @@ import pygame
|
||||
class Tree(Piece):
|
||||
def __init__(self,x_y, img = 0):
|
||||
self.name = "Tree"
|
||||
self.row = x_y[0]
|
||||
self.col = x_y[1]
|
||||
self.col = x_y[0]
|
||||
self.row = x_y[1]
|
||||
self.img = pygame.image.load(r'container\trees\tree'+str(img)+'.png')
|
||||
|
||||
|
||||
|
36
main.py
36
main.py
@ -2,7 +2,7 @@ import pygame
|
||||
from container.constans import WIDTH, HEIGHT, ROWS, COLUMNS, GREEN
|
||||
from container.board import Board
|
||||
|
||||
FPS = 8
|
||||
FPS = 30
|
||||
|
||||
#creating game window
|
||||
WIN = pygame.display.set_mode((WIDTH,HEIGHT))
|
||||
@ -18,51 +18,33 @@ def main():
|
||||
run = True
|
||||
clock = pygame.time.Clock() #for fps
|
||||
board = Board(0,40,WIDTH,HEIGHT-40)
|
||||
#board.manage_rows_and_col(ROWS,COLUMNS)
|
||||
|
||||
#managing agent location
|
||||
#current_column = 0
|
||||
#current_row = 0
|
||||
#current_piece = board.get_piece(current_row,current_column)
|
||||
#current_piece.change_status()
|
||||
|
||||
#calculate desireable location to pixels
|
||||
def claculate_position(x,y):
|
||||
x = SQUARE_SIZE * x
|
||||
y = SQUARE_SIZE * y
|
||||
return [x,y]
|
||||
|
||||
while run:
|
||||
|
||||
clock.tick(FPS)
|
||||
#print(current_column,current_row)
|
||||
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
run = False
|
||||
if event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_SPACE: board.next_move()
|
||||
|
||||
|
||||
#managing arrow click
|
||||
|
||||
key_input = pygame.key.get_pressed()
|
||||
if key_input[pygame.K_LEFT]: board.move(0,-1)
|
||||
if key_input[pygame.K_UP]: board.move(-1,0)
|
||||
if key_input[pygame.K_RIGHT]: board.move(0,1)
|
||||
if key_input[pygame.K_DOWN]: board.move(1,0)
|
||||
"""
|
||||
#managing agent location
|
||||
current_piece.change_status()
|
||||
current_piece = board.get_piece(current_row,current_column)
|
||||
current_piece.change_status()
|
||||
"""
|
||||
|
||||
if key_input[pygame.K_LEFT]: board.agent.rotate(1)
|
||||
if key_input[pygame.K_UP]: board.agent.move()
|
||||
if key_input[pygame.K_RIGHT]: board.agent.rotate(-1)
|
||||
|
||||
#drawing map and detective
|
||||
WIN.fill(GREEN)
|
||||
board.update_agent()
|
||||
board.draw_squares(WIN)
|
||||
board.draw_pieces(WIN)
|
||||
board.draw_agent(WIN)
|
||||
board.draw_info(WIN)
|
||||
#WIN.blit(detective, (claculate_position(current_column,current_row)[0], claculate_position(current_column,current_row)[1]))
|
||||
|
||||
pygame.display.update()
|
||||
|
||||
pygame.quit()
|
||||
|
Loading…
Reference in New Issue
Block a user