merged
This commit is contained in:
commit
641b7091f7
@ -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>
|
@ -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
43
Engine/BfsPathFinder.py
Normal 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
|
@ -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]
|
||||||
|
@ -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
81
Engine/PathFinder.py
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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.
BIN
Engine/__pycache__/BfsPathFinder.cpython-39.pyc
Normal file
BIN
Engine/__pycache__/BfsPathFinder.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Engine/__pycache__/PathFinder.cpython-39.pyc
Normal file
BIN
Engine/__pycache__/PathFinder.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user