diff --git a/.idea/Projekt_AI-Automatyczny_saper.iml b/.idea/Projekt_AI-Automatyczny_saper.iml
index 4c879079..74d515a0 100644
--- a/.idea/Projekt_AI-Automatyczny_saper.iml
+++ b/.idea/Projekt_AI-Automatyczny_saper.iml
@@ -4,7 +4,7 @@
-
+
\ No newline at end of file
diff --git a/Engine/Agent.py b/Engine/Agent.py
index 063a7f2c..73e7cda9 100644
--- a/Engine/Agent.py
+++ b/Engine/Agent.py
@@ -6,6 +6,7 @@ class Agent(object):
def __init__(self, point):
self.point = point
self.image = pygame.image.load('Engine/agent.png')
+ self.orientation = 0
def getPoint(self):
return self.point
@@ -13,6 +14,23 @@ class Agent(object):
def defuse(self, bomb):
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):
# if destination == UP:
# if self.x - 1 <= 0:
diff --git a/Engine/BfsPathFinder.py b/Engine/BfsPathFinder.py
new file mode 100644
index 00000000..2b603506
--- /dev/null
+++ b/Engine/BfsPathFinder.py
@@ -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
diff --git a/Engine/Board.py b/Engine/Board.py
index d837a6b0..b07afa93 100644
--- a/Engine/Board.py
+++ b/Engine/Board.py
@@ -8,6 +8,7 @@ class Board:
def __init__(self, win):
self.board = []
self.bombMap = {}
+ self.stoneMap = {}
self.win = 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)
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):
if point in self.bombMap:
return self.bombMap[point]
diff --git a/Engine/Game.py b/Engine/Game.py
index c91e31c8..bc893f45 100644
--- a/Engine/Game.py
+++ b/Engine/Game.py
@@ -8,6 +8,8 @@ from Engine.Agent import Agent
from Engine.BombFactory import BombFactory
from Engine.Point import Point
from Engine.Stone import Stone
+from Engine.PathFinder import PathFinder
+from Engine.BfsPathFinder import BfsPathFinder
class Game:
@@ -22,40 +24,63 @@ class Game:
self.agent = Agent(Point(0, 0))
self.turn = GREEN
self.goingDown = True
+ self.path = []
def update(self):
- self.agent.defuse(self.board.getBomb(self.agent.getPoint()))
+ self.defuseBomb()
self.board.drawSquares(self.win)
self.board.drawBombs()
+ self.board.drawStones()
self.board.drawAgent(self.win, self.agent)
pygame.display.update()
- def move(self):
- point = self.agent.getPoint()
- if self.goingDown:
- if point.getY() + 1 < ROWS:
- point.y += 1
- elif point.getX() + 1 < COLS:
- point.x += 1
- self.goingDown = not self.goingDown
- else:
- if point.getY() - 1 >= 0:
- point.y -= 1
- elif point.getX() + 1 < COLS:
- point.x += 1
- self.goingDown = not self.goingDown
- self.agent.point = point
+ # def move(self):
+ # point = self.agent.getPoint()
+ # tmpPoint = Point(point.getX(), point.getY())
+ # if self.goingDown:
+ # if point.getY() + 1 < ROWS:
+ # tmpPoint.y += 1
+ # elif point.getX() + 1 < COLS:
+ # tmpPoint.x += 1
+ # self.goingDown = not self.goingDown
+ # else:
+ # if point.getY() - 1 >= 0:
+ # tmpPoint.y -= 1
+ # elif point.getX() + 1 < COLS:
+ # tmpPoint.x += 1
+ # 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):
i = 0
- while i < 11:
- point = Point(random.randint(0, 7), random.randint(0, 7))
+ while i < 10:
+ 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:
object = self.pickObject(random.randint(0, 4))
self.board.bombMap[point] = object
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):
if rand == 0:
@@ -68,5 +93,28 @@ class Game:
return BombFactory.create(CLAYMORE)
elif rand == 4:
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)
diff --git a/Engine/PathFinder.py b/Engine/PathFinder.py
new file mode 100644
index 00000000..06d65bc8
--- /dev/null
+++ b/Engine/PathFinder.py
@@ -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
+
+
+
+
+
diff --git a/Engine/Point.py b/Engine/Point.py
index 3d872721..0f15323e 100644
--- a/Engine/Point.py
+++ b/Engine/Point.py
@@ -9,6 +9,9 @@ class Point:
def getX(self):
return self.x
+ def distance(self,endpoint):
+ return abs(self.getX() + endpoint.getX()) + abs(self.getY() + endpoint.getY())
+
def __hash__(self):
"""Overrides the default implementation"""
return hash(tuple(sorted(self.__dict__.items())))
diff --git a/Engine/__pycache__/Agent.cpython-39.pyc b/Engine/__pycache__/Agent.cpython-39.pyc
index c3773505..a81294fb 100644
Binary files a/Engine/__pycache__/Agent.cpython-39.pyc and b/Engine/__pycache__/Agent.cpython-39.pyc differ
diff --git a/Engine/__pycache__/BfsPathFinder.cpython-39.pyc b/Engine/__pycache__/BfsPathFinder.cpython-39.pyc
new file mode 100644
index 00000000..5c5a53e3
Binary files /dev/null and b/Engine/__pycache__/BfsPathFinder.cpython-39.pyc differ
diff --git a/Engine/__pycache__/Board.cpython-39.pyc b/Engine/__pycache__/Board.cpython-39.pyc
index 15460151..bde93dbf 100644
Binary files a/Engine/__pycache__/Board.cpython-39.pyc and b/Engine/__pycache__/Board.cpython-39.pyc differ
diff --git a/Engine/__pycache__/Game.cpython-39.pyc b/Engine/__pycache__/Game.cpython-39.pyc
index 50d4b9a5..0ffd955a 100644
Binary files a/Engine/__pycache__/Game.cpython-39.pyc and b/Engine/__pycache__/Game.cpython-39.pyc differ
diff --git a/Engine/__pycache__/PathFinder.cpython-39.pyc b/Engine/__pycache__/PathFinder.cpython-39.pyc
new file mode 100644
index 00000000..565e51ee
Binary files /dev/null and b/Engine/__pycache__/PathFinder.cpython-39.pyc differ
diff --git a/Engine/__pycache__/Point.cpython-39.pyc b/Engine/__pycache__/Point.cpython-39.pyc
index 91544579..f1fc8ec4 100644
Binary files a/Engine/__pycache__/Point.cpython-39.pyc and b/Engine/__pycache__/Point.cpython-39.pyc differ
diff --git a/main.py b/main.py
index 2566a440..ea83ec1f 100644
--- a/main.py
+++ b/main.py
@@ -20,7 +20,12 @@ def main():
run = False
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()