This commit is contained in:
barmal4 2021-04-26 19:13:07 +02:00
commit 641b7091f7
14 changed files with 229 additions and 22 deletions

View File

@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" /> <excludeFolder url="file://$MODULE_DIR$/venv" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.9 (Projekt_AI-Automatyczny_saper)" jdkType="Python SDK" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View File

@ -6,6 +6,7 @@ class Agent(object):
def __init__(self, point): def __init__(self, point):
self.point = point self.point = point
self.image = pygame.image.load('Engine/agent.png') self.image = pygame.image.load('Engine/agent.png')
self.orientation = 0
def getPoint(self): def getPoint(self):
return self.point return self.point
@ -13,6 +14,23 @@ class Agent(object):
def defuse(self, bomb): def defuse(self, bomb):
bomb.isDefused = True bomb.isDefused = True
def rotateImage(self, orientation):
angle = self.getAngle(orientation)
self.image = pygame.transform.rotate(self.image, 360 - self.orientation)
self.image = pygame.transform.rotate(self.image, angle)
self.orientation = angle
def getAngle(self,orientation):
if self.point.getX() < orientation.getX():
return 0
elif self.point.getY() > orientation.getY():
return 90
elif self.point.getX() > orientation.getX():
return 180
elif self.point.getY() < orientation.getY():
return 270
return 0
# def ifNotOnEdge(self, destination): # def ifNotOnEdge(self, destination):
# if destination == UP: # if destination == UP:
# if self.x - 1 <= 0: # if self.x - 1 <= 0:

43
Engine/BfsPathFinder.py Normal file
View File

@ -0,0 +1,43 @@
from queue import Queue
from Engine.PathFinder import PathFinder
class BfsPathFinder(PathFinder):
def __init__(self, board):
super().__init__(board)
self.board = board
self.goal = None
def findBomb(self,start):
frontier = Queue()
frontier.put(start)
cameFrom = dict()
cameFrom[start] = None
while not frontier.empty():
current = frontier.get()
if self.checkGoal(current):
return self.constructPath(cameFrom,start)
for next in self.getNeighbour(current):
if next not in cameFrom:
frontier.put(next)
cameFrom[next] = current
return []
def constructPath(self,cameFrom,start):
current = cameFrom[self.goal]
path = []
path.append(self.goal)
while current != start:
path.append(current)
current = cameFrom[current]
path.append(start)
path.reverse()
return path
def checkGoal(self, current):
if current in self.board.bombMap:
self.goal = current
return True
return False

View File

@ -8,6 +8,7 @@ class Board:
def __init__(self, win): def __init__(self, win):
self.board = [] self.board = []
self.bombMap = {} self.bombMap = {}
self.stoneMap = {}
self.win = win self.win = win
def drawSquares(self, win): def drawSquares(self, win):
@ -33,6 +34,14 @@ class Board:
rect.center = (key.getX() * SQUARE_SIZE + SQUARE_SIZE / 2, key.getY() * SQUARE_SIZE + SQUARE_SIZE / 2) rect.center = (key.getX() * SQUARE_SIZE + SQUARE_SIZE / 2, key.getY() * SQUARE_SIZE + SQUARE_SIZE / 2)
self.win.blit(image, rect) self.win.blit(image, rect)
def drawStones(self):
for key in self.stoneMap:
image = pygame.image.load('Engine/stone.png')
image = pygame.transform.scale(image, (SQUARE_SIZE - 5, SQUARE_SIZE - 5))
rect = image.get_rect()
rect.center = (key.getX() * SQUARE_SIZE + SQUARE_SIZE / 2, key.getY() * SQUARE_SIZE + SQUARE_SIZE / 2)
self.win.blit(image, rect)
def getBomb(self, point): def getBomb(self, point):
if point in self.bombMap: if point in self.bombMap:
return self.bombMap[point] return self.bombMap[point]

View File

@ -8,6 +8,8 @@ from Engine.Agent import Agent
from Engine.BombFactory import BombFactory from Engine.BombFactory import BombFactory
from Engine.Point import Point from Engine.Point import Point
from Engine.Stone import Stone from Engine.Stone import Stone
from Engine.PathFinder import PathFinder
from Engine.BfsPathFinder import BfsPathFinder
class Game: class Game:
@ -22,40 +24,63 @@ class Game:
self.agent = Agent(Point(0, 0)) self.agent = Agent(Point(0, 0))
self.turn = GREEN self.turn = GREEN
self.goingDown = True self.goingDown = True
self.path = []
def update(self): def update(self):
self.agent.defuse(self.board.getBomb(self.agent.getPoint())) self.defuseBomb()
self.board.drawSquares(self.win) self.board.drawSquares(self.win)
self.board.drawBombs() self.board.drawBombs()
self.board.drawStones()
self.board.drawAgent(self.win, self.agent) self.board.drawAgent(self.win, self.agent)
pygame.display.update() pygame.display.update()
def move(self): # def move(self):
point = self.agent.getPoint() # point = self.agent.getPoint()
if self.goingDown: # tmpPoint = Point(point.getX(), point.getY())
if point.getY() + 1 < ROWS: # if self.goingDown:
point.y += 1 # if point.getY() + 1 < ROWS:
elif point.getX() + 1 < COLS: # tmpPoint.y += 1
point.x += 1 # elif point.getX() + 1 < COLS:
self.goingDown = not self.goingDown # tmpPoint.x += 1
else: # self.goingDown = not self.goingDown
if point.getY() - 1 >= 0: # else:
point.y -= 1 # if point.getY() - 1 >= 0:
elif point.getX() + 1 < COLS: # tmpPoint.y -= 1
point.x += 1 # elif point.getX() + 1 < COLS:
self.goingDown = not self.goingDown # tmpPoint.x += 1
self.agent.point = point # self.goingDown = not self.goingDown
# self.agent.rotateImage(tmpPoint)
# self.agent.point = tmpPoint
# #self.moveSequence()
#
# def moveSequence(self):
# pathfinder = PathFinder(self.board)
# for point in pathfinder.findPath(Point(0,0), Point(5,5)):
# self.agent.point = point
# self.update()
def randomizeObject(self): def randomizeObject(self):
i = 0 i = 0
while i < 11: while i < 10:
point = Point(random.randint(0, 7), random.randint(0, 7)) point = Point(random.randint(0, 9), random.randint(0, 9))
if(point.getX() == 0 and point.getY() == 0): if(point.getX() == 0 and point.getY() == 0):
continue; continue;
if point not in self.board.bombMap: if point not in self.board.bombMap:
object = self.pickObject(random.randint(0, 4)) object = self.pickObject(random.randint(0, 4))
self.board.bombMap[point] = object self.board.bombMap[point] = object
i += 1 i += 1
r = 5
j = 0
while j < r:
point = Point(random.randint(0, 9), random.randint(0, 9))
if (point.getX() == 0 and point.getY() == 0):
continue;
if point not in self.board.bombMap and point not in self.board.stoneMap:
object = Stone()
self.board.stoneMap[point] = object
j += 1
def pickObject(self, rand): def pickObject(self, rand):
if rand == 0: if rand == 0:
@ -68,5 +93,28 @@ class Game:
return BombFactory.create(CLAYMORE) return BombFactory.create(CLAYMORE)
elif rand == 4: elif rand == 4:
return BombFactory.create(LAND_MINE) return BombFactory.create(LAND_MINE)
# elif(rand == 5):
# return Stone() def findBomb(self):
return BfsPathFinder(self.board).findBomb(self.agent.getPoint())
def finalState(self):
if len(self.board.bombMap) == 0:
return True
return False
def moveToNext(self):
point = self.path.pop(0)
self.agent.rotateImage(point)
self.agent.point = point
def savePath(self,path):
self.path = path
def getPath(self):
return self.path
def defuseBomb(self):
point = self.agent.getPoint()
self.agent.defuse(self.board.getBomb(point))
if point in self.board.bombMap:
self.board.bombMap.pop(point)

81
Engine/PathFinder.py Normal file
View File

@ -0,0 +1,81 @@
from Constants import ROWS, COLS
from Engine.Point import Point
class PathFinder:
def __init__(self, board):
self.board = board
self.openList = []
self.cameFrom = {}
self.gScore = {}
self.fScore = {}
self.current = Point(0,0)
def findPath(self,startPoint, endPoint):
self.openList.append(startPoint)
self.gScore[startPoint] = 0
self.fScore[startPoint] = startPoint.distance(endPoint)
while self.openList:
self.current = self.minKey(self.fScore, self.openList)
if self.current.__eq__(endPoint):
return self.reconstructPath()
self.openList.remove(self.current)
for point in self.getNeighbour(self.current):
tentativeGScore = self.gScore.get(self.current) + self.current.distance(point)
if tentativeGScore < self.gScore.get(point, 10000):
self.cameFrom[point] = self.current
self.gScore[point] = tentativeGScore
self.fScore[point] = point.distance(startPoint)
if(point not in self.openList):
self.openList.append(point)
return []
def reconstructPath(self):
totalPath = []
totalPath.append(self.current)
while self.current in self.cameFrom:
self.current = self.cameFrom[self.current]
totalPath.insert(0,self.current)
return totalPath
def getNeighbour(self, current):
neighbourlist = []
point1 = Point(current.getX() + 1, current.getY())
point2 = Point(current.getX(), current.getY() + 1)
point3 = Point(current.getX(), current.getY() - 1)
point4 = Point(current.getX() - 1, current.getY())
if self.checkField(current,point1):
neighbourlist.append(point1)
if self.checkField(current, point2):
neighbourlist.append(point2)
if self.checkField(current,point3):
neighbourlist.append(point3)
if self.checkField(current,point4):
neighbourlist.append(point4)
return neighbourlist
def checkField(self,current, point):
if not (point.getX() < 0 or point.getX() > COLS - 1 or point.getY() < 0 or point.getY() > ROWS - 1 or point.__eq__(current)) and point not in self.board.stoneMap:
return True
return False
def minKey(self, fscore, openlist):
minkey = Point(0,0)
minValue = float('inf')
for point in openlist:
value = fscore.get(point, 10000)
if value < minValue:
minValue = value
minkey = point
return minkey

View File

@ -9,6 +9,9 @@ class Point:
def getX(self): def getX(self):
return self.x return self.x
def distance(self,endpoint):
return abs(self.getX() + endpoint.getX()) + abs(self.getY() + endpoint.getY())
def __hash__(self): def __hash__(self):
"""Overrides the default implementation""" """Overrides the default implementation"""
return hash(tuple(sorted(self.__dict__.items()))) return hash(tuple(sorted(self.__dict__.items())))

Binary file not shown.

Binary file not shown.

View File

@ -20,7 +20,12 @@ def main():
run = False run = False
pygame.time.delay(200) pygame.time.delay(200)
game.move() if game.finalState():
break
if len(game.getPath()) == 0:
path = game.findBomb()
game.savePath(path)
game.moveToNext()
game.update() game.update()