diff --git a/.idea/Projekt_AI-Automatyczny_saper.iml b/.idea/Projekt_AI-Automatyczny_saper.iml index 4c879079..ba6cfa6f 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/.idea/misc.xml b/.idea/misc.xml index 9dfb2a91..2d83d70f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file 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..9915984e 100644 --- a/Engine/Game.py +++ b/Engine/Game.py @@ -8,6 +8,7 @@ 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 class Game: @@ -27,35 +28,55 @@ class Game: self.agent.defuse(self.board.getBomb(self.agent.getPoint())) 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 + # 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 + 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 < 5: + 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 = 15 + 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 +89,11 @@ class Game: return BombFactory.create(CLAYMORE) elif rand == 4: return BombFactory.create(LAND_MINE) - # elif(rand == 5): - # return Stone() + + def finalState(self): + j = 0 + for key in self.board.bombMap: + bomb = self.board.bombMap[key] + if not bomb.isDefused: + j += 1 + return j == 0 diff --git a/Engine/PathFinder.py b/Engine/PathFinder.py new file mode 100644 index 00000000..fc67ef5c --- /dev/null +++ b/Engine/PathFinder.py @@ -0,0 +1,78 @@ +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 not (point1.getX() < 0 or point1.getX() > COLS or point1.getY() < 0 or point1.getY() > ROWS or point1.__eq__(current)) and point1 not in self.board.stoneMap: + neighbourlist.append(point1) + if not (point2.getX() < 0 or point2.getX() > COLS or point2.getY() < 0 or point2.getY() > ROWS or point2.__eq__(current)) and point2 not in self.board.stoneMap: + neighbourlist.append(point2) + if not (point3.getX() < 0 or point3.getX() > COLS or point3.getY() < 0 or point3.getY() > ROWS or point3.__eq__(current)) and point3 not in self.board.stoneMap: + neighbourlist.append(point3) + if not (point4.getX() < 0 or point4.getX() > COLS or point4.getY() < 0 or point4.getY() > ROWS or point4.__eq__(current)) and point4 not in self.board.stoneMap: + neighbourlist.append(point4) + + return neighbourlist + + + 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 2e269567..91bc5844 100644 Binary files a/Engine/__pycache__/Agent.cpython-39.pyc and b/Engine/__pycache__/Agent.cpython-39.pyc differ diff --git a/Engine/__pycache__/Board.cpython-39.pyc b/Engine/__pycache__/Board.cpython-39.pyc index 28b46e8c..314dc224 100644 Binary files a/Engine/__pycache__/Board.cpython-39.pyc and b/Engine/__pycache__/Board.cpython-39.pyc differ diff --git a/Engine/__pycache__/Bomb.cpython-39.pyc b/Engine/__pycache__/Bomb.cpython-39.pyc index 0d130736..330ee454 100644 Binary files a/Engine/__pycache__/Bomb.cpython-39.pyc and b/Engine/__pycache__/Bomb.cpython-39.pyc differ diff --git a/Engine/__pycache__/BombFactory.cpython-39.pyc b/Engine/__pycache__/BombFactory.cpython-39.pyc index 0a585e56..61bcfcf1 100644 Binary files a/Engine/__pycache__/BombFactory.cpython-39.pyc and b/Engine/__pycache__/BombFactory.cpython-39.pyc differ diff --git a/Engine/__pycache__/Game.cpython-39.pyc b/Engine/__pycache__/Game.cpython-39.pyc index 148b0357..a62b4452 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..acdbb3ce 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 4fbbc370..dc8787e4 100644 Binary files a/Engine/__pycache__/Point.cpython-39.pyc and b/Engine/__pycache__/Point.cpython-39.pyc differ diff --git a/Engine/__pycache__/Stone.cpython-39.pyc b/Engine/__pycache__/Stone.cpython-39.pyc index 1a7586bb..1665d1d9 100644 Binary files a/Engine/__pycache__/Stone.cpython-39.pyc and b/Engine/__pycache__/Stone.cpython-39.pyc differ diff --git a/__pycache__/Constants.cpython-39.pyc b/__pycache__/Constants.cpython-39.pyc index 467665c4..4e4f281d 100644 Binary files a/__pycache__/Constants.cpython-39.pyc and b/__pycache__/Constants.cpython-39.pyc differ diff --git a/main.py b/main.py index 2566a440..551c5ccf 100644 --- a/main.py +++ b/main.py @@ -20,6 +20,8 @@ def main(): run = False pygame.time.delay(200) + if(game.finalState()): + run = False game.move() game.update()