def goLeft(): if player1.pos.col == 0 or self.isVwall(player1.pos.row, player1.pos.col - 1): return if (player2.pos.row == player1.pos.row and player2.pos.col == player1.pos.col - 1) or ( player3.pos.row == player1.pos.row and player3.pos.col == player1.pos.col - 1) or ( player4.pos.row == player1.pos.row and player4.pos.col == player1.pos.col - 1): if player1.pos.col == 1 or self.isVwall( player1.pos.row, player1.pos.col - 2) or (player2.pos.row == player1.pos.row and player2.pos.col == player1.pos.col - 2) or ( player3.pos.row == player1.pos.row and player3.pos.col == player1.pos.col - 2 ) or (player4.pos.row == player1.pos.row and player4.pos.col == player1.pos.col - 2): if not (player1.pos.row == 0 or self.isHwall( player1.pos.row - 1, player1.pos.col - 1)): pm.append( Position(player1.pos.row - 1, player1.pos.col - 1)) if not (player1.pos.row == 8 or self.isHwall( player1.pos.row, player1.pos.col - 1)): pm.append( Position(player1.pos.row + 1, player1.pos.col - 1)) else: pm.append(Position(player1.pos.row, player1.pos.col - 2)) else: pm.append(Position(player1.pos.row, player1.pos.col - 1))
def goDown(): if player1.pos.row == 8 or self.isHwall(player1.pos.row, player1.pos.col): return if (player2.pos.row == player1.pos.row + 1 and player2.pos.col == player1.pos.col) or ( player3.pos.row == player1.pos.row + 1 and player3.pos.col == player1.pos.col) or ( player4.pos.row == player1.pos.row + 1 and player4.pos.col == player1.pos.col): if player1.pos.row == 7 or self.isHwall( player1.pos.row + 1, player1.pos.col) or ( player3.pos.row == player1.pos.row + 2 and player3.pos.col == player1.pos.col) or ( player4.pos.row == player1.pos.row + 2 and player4.pos.col == player1.pos.col) or ( player2.pos.row == player1.pos.row + 2 and player2.pos.col == player1.pos.col): if not (player1.pos.col == 0 or self.isVwall( player1.pos.row + 1, player1.pos.col - 1)): pm.append( Position(player1.pos.row + 1, player1.pos.col - 1)) if not (player1.pos.col == 8 or self.isVwall( player1.pos.row + 1, player1.pos.col)): pm.append( Position(player1.pos.row + 1, player1.pos.col + 1)) else: pm.append(Position(player1.pos.row + 2, player1.pos.col)) else: pm.append(Position(player1.pos.row + 1, player1.pos.col))
def goRight(): if player1.pos.col == 8 or self.isVwall(player1.pos.row, player1.pos.col): return if player2.pos.row == player1.pos.row and player2.pos.col == player1.pos.col + 1: if player1.pos.col == 7 or self.isVwall(player1.pos.row, player1.pos.col + 1): if not(player1.pos.row == 0 or self.isHwall(player1.pos.row - 1, player1.pos.col + 1)): pm.append(Position(player1.pos.row - 1, player1.pos.col + 1)) if not(player1.pos.row == 8 or self.isHwall(player1.pos.row, player1.pos.col + 1)): pm.append(Position(player1.pos.row + 1, player1.pos.col + 1)) else: pm.append(Position(player1.pos.row, player1.pos.col + 2)) else: pm.append(Position(player1.pos.row, player1.pos.col + 1))
def goUp(): if player1.pos.row == 0 or self.isHwall(player1.pos.row - 1, player1.pos.col): return if player2.pos.row == player1.pos.row - 1 and player2.pos.col == player1.pos.col: if player1.pos.row == 1 or self.isHwall(player1.pos.row - 2, player1.pos.col): if not(player1.pos.col == 0 or self.isVwall(player1.pos.row - 1, player1.pos.col - 1)): pm.append(Position(player1.pos.row - 1, player1.pos.col - 1)) if not(player1.pos.col == 8 or self.isVwall(player1.pos.row - 1, player1.pos.col)): pm.append(Position(player1.pos.row - 1, player1.pos.col + 1)) else: pm.append(Position(player1.pos.row - 2, player1.pos.col)) else: pm.append(Position(player1.pos.row - 1, player1.pos.col))
def shortestPath(self, player1: Player, player2: Player, player3: Player, player4: Player): mark = [[False for i in range(9)] for j in range(9)]; p1 = Player(Position(player1.pos.row, player1.pos.col), None, None, player1.walls); q = deque(); q.append((p1, 0)); mark[p1.pos.row][p1.pos.col] = True; while q: p, d = q.popleft(); if self.isGoal(p, self.source): return d; for pm in self.logic.possibleMoves(p, player2, player3, player4): if not mark[pm.row][pm.col]: mark[pm.row][pm.col] = True; p5 = Player(Position(pm.row, pm.col), None, None, player1.walls); q.append((p5, d + 1)); return -1;
def shortestPath(self, player1: Player, player2: Player, goal): mark = [[False for i in range(9)] for j in range(9)] p1 = Player(Position(player1.pos.row, player1.pos.col)) q = deque() q.append((p1, 0)) mark[p1.pos.row][p1.pos.col] = True while q: p, d = q.popleft() if p.pos.row == goal: return d for pm in self.logic.possibleMoves(p, player2): if not mark[pm.row][pm.col]: mark[pm.row][pm.col] = True p3 = Player(Position(p.pos.row, p.pos.col)) p3.pos.row = pm.row p3.pos.col = pm.col q.append((p3, d + 1)) return -1
def isSurrounded(self, player1, player2, player3, player4, rdes, cdes): blocks = [] visited = [[False for x in range(9)] for y in range(9)] p = Player(Position(player1.pos.row, player1.pos.col)) blocks.append(p.pos) while blocks: p.pos = blocks.pop() temp = self.possibleMoves(p, player2, player3, player4) for t in temp: if not visited[t.row][t.col]: if t.row in rdes or t.col in cdes: return False visited[t.row][t.col] = True blocks.append(t) return True
def minimaxTree(self, player1: Player, player2: Player, player3: Player, player4: Player, d, l, r): sources = []; if self.source == 'r0': sources = ['r0', 'c8', 'r8', 'c0'] if self.source == 'c8': sources = ['c8', 'r8', 'c0', 'r0'] if self.source == 'r8': sources = ['r8', 'c0', 'r0', 'c8'] if self.source == 'c0': sources = ['c0', 'r0', 'c8', 'r8'] if d == 3: return self.heuristic(player1, player2, player3, player4, sources); if self.isGoal(player1, sources[0]): return 80; elif self.isGoal(player2, sources[1]) or self.isGoal(player3, sources[2]) or self.isGoal(player4, sources[3]): return 0; ps = []; if self.source == 'c0': ps = [player2, player3, player4, player1]; elif self.source == 'r8': ps = [player3, player4, player1, player2]; elif self.source == 'c8': ps = [player4, player1, player2, player3]; else: ps = [player1, player2, player3, player4]; if d % 4 == 0: #max alphaBeta = 0; for pm in self.logic.possibleMoves(player1, player2, player3, player4): p = Player(Position(pm.row, pm.col), None, None, player1.walls); a = self.minimaxTree(p, player2, player3, player4, d+1, l, r); alphaBeta = max(alphaBeta, a); if a >= r: return alphaBeta; l = max(l, a); if player1.walls > 0: for row in range(player2.pos.row - 2, player2.pos.row + 2): for col in range(player2.pos.col - 2, player2.pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = max(alphaBeta, a); if a >= r: self.logic.hwalls[row][col] = False; return alphaBeta; l = max(l, a); self.logic.hwalls[row][col] = False; if self.logic.addVwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = max(alphaBeta, a); if a >= r: self.logic.vwalls[row][col] = False; return alphaBeta; l = max(l, a); self.logic.vwalls[row][col] = False; for row in range(player3.pos.row - 2, player3.pos.row + 2): for col in range(player3.pos.col - 2, player3.pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = max(alphaBeta, a); if a >= r: self.logic.hwalls[row][col] = False; return alphaBeta; l = max(l, a); self.logic.hwalls[row][col] = False; if self.logic.addVwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = max(alphaBeta, a); if a >= r: self.logic.vwalls[row][col] = False; return alphaBeta; l = max(l, a); self.logic.vwalls[row][col] = False; for row in range(player4.pos.row - 2, player4.pos.row + 2): for col in range(player4.pos.col - 2, player4.pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = max(alphaBeta, a); if a >= r: self.logic.hwalls[row][col] = False; return alphaBeta; l = max(l, a); self.logic.hwalls[row][col] = False; if self.logic.addVwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = max(alphaBeta, a); if a >= r: self.logic.vwalls[row][col] = False; return alphaBeta; l = max(l, a); self.logic.vwalls[row][col] = False; return alphaBeta; elif d % 4 == 1: #min alphaBeta = 80; for pm in self.logic.possibleMoves(player2, player1, player3, player4): p = Player(Position(pm.row, pm.col), None, None, player2.walls); a = self.minimaxTree(player1, p, player3, player4, d+1, l, r); alphaBeta = min(alphaBeta, a); if a <= l: return alphaBeta; r = max(r, a); if player2.walls > 0: for row in range(player1.pos.row - 2, player1.pos.row + 2): for col in range(player1.pos.col - 2, player1.pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = min(alphaBeta, a); if a <= l: self.logic.hwalls[row][col] = False; return alphaBeta; r = min(r, a); self.logic.hwalls[row][col] = False; if self.logic.addVwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = min(alphaBeta, a); if a <= l: self.logic.vwalls[row][col] = False; return alphaBeta; r = min(r, a); self.logic.vwalls[row][col] = False; return alphaBeta; elif d % 4 == 2: #min alphaBeta = 80; for pm in self.logic.possibleMoves(player3, player1, player2, player4): p = Player(Position(pm.row, pm.col), None, None, player3.walls); a = self.minimaxTree(player1, player2, p, player4, d+1, l, r); alphaBeta = min(alphaBeta, a); if a <= l: return alphaBeta; r = max(r, a); if player3.walls > 0: for row in range(player1.pos.row - 2, player1.pos.row + 2): for col in range(player1.pos.col - 2, player1.pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = min(alphaBeta, a); if a <= l: self.logic.hwalls[row][col] = False; return alphaBeta; r = min(r, a); self.logic.hwalls[row][col] = False; if self.logic.addVwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = min(alphaBeta, a); if a <= l: self.logic.vwalls[row][col] = False; return alphaBeta; r = min(r, a); self.logic.vwalls[row][col] = False; return alphaBeta; elif d % 4 == 3: #min alphaBeta = 80; for pm in self.logic.possibleMoves(player4, player1, player3, player2): p = Player(Position(pm.row, pm.col), None, None, player4.walls); a = self.minimaxTree(player1, player2, player3, p, d+1, l, r); alphaBeta = min(alphaBeta, a); if a <= l: return alphaBeta; r = max(r, a); if player4.walls > 0: for row in range(player1.pos.row - 2, player1.pos.row + 2): for col in range(player1.pos.col - 2, player1.pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = min(alphaBeta, a); if a <= l: self.logic.hwalls[row][col] = False; return alphaBeta; r = min(r, a); self.logic.hwalls[row][col] = False; if self.logic.addVwall(col, row, ps): a = self.minimaxTree(player1, player2, player3, player4, d + 1, l, r); a = min(alphaBeta, a); if a <= l: self.logic.vwalls[row][col] = False; return alphaBeta; r = min(r, a); self.logic.vwalls[row][col] = False; return alphaBeta;
def chooseAnAction(self, players): p1 = Player(Position(players[0].pos.row, players[0].pos.col), None, None, players[0].walls) p2 = Player(Position(players[1].pos.row, players[1].pos.col), None, None, players[1].walls) p3 = Player(Position(players[2].pos.row, players[2].pos.col), None, None, players[2].walls) p4 = Player(Position(players[3].pos.row, players[3].pos.col), None, None, players[3].walls) ps = [] if self.source == 'c0': ps = players[1:4] + players[0:1] elif self.source == 'r8': ps = players[2:4] + players[0:2] elif self.source == 'c8': ps = players[3:4] + players[0:3] else: ps = players alphaBeta = -1 r = 0 c = 0 action = "" sp = -1; sr = 0; sc = 0; pmList = self.logic.possibleMoves(p1, p2, p3, p4); for pm in pmList: p = Player(Position(pm.row, pm.col), None, None, p1.walls); l = self.shortestPath(p, p2, p3, p4); if sp == -1 or l < sp: sp = l; sr = pm.row; sc = pm.col; for pm in pmList: p = Player(Position(pm.row, pm.col), None, None, p1.walls) a = self.minimaxTree(p, p2, p3, p4, 1, 0, 80) if pm.row == sr and pm.col == sc: a += 0.3; if a > alphaBeta: alphaBeta = a r = pm.row c = pm.col action = "move" if players[0].walls > 0: for row in range(players[2].pos.row - 2, players[2].pos.row + 2): for col in range(players[2].pos.col - 2, players[2].pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(p1, p2, p3, p4, 1, 0, 80) if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5 and action != 'move'): alphaBeta = a r = row c = col action = 'add Hwall' self.logic.hwalls[row][col] = False if self.logic.addVwall(col, row, ps): a = self.minimaxTree(p1, p2, p3, p4, 1, 0, 80) if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5 and action != "move"): alphaBeta = a r = row c = col action = "add Vwall" self.logic.vwalls[row][col] = False for row in range(players[3].pos.row - 2, players[3].pos.row + 2): for col in range(players[3].pos.col - 2, players[3].pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(p1, p2, p3, p4, 1, 0, 80) if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5 and action != 'move'): alphaBeta = a r = row c = col action = 'add Hwall' self.logic.hwalls[row][col] = False if self.logic.addVwall(col, row, ps): a = self.minimaxTree(p1, p2, p3, p4, 1, 0, 80) if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5 and action != "move"): alphaBeta = a r = row c = col action = "add Vwall"; self.logic.vwalls[row][col] = False; for row in range(players[1].pos.row - 2, players[1].pos.row + 2): for col in range(players[1].pos.col - 2, players[1].pos.col + 2): if self.logic.addHwall(col, row, ps): a = self.minimaxTree(p1, p2, p3, p4, 1, 0, 80); if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5 and action != 'move'): alphaBeta = a; r = row; c = col; action = 'add Hwall'; self.logic.hwalls[row][col] = False; if self.logic.addVwall(col, row, ps): a = self.minimaxTree(p1, p2, p3, p4, 1, 0, 80); if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5 and action != "move"): alphaBeta = a; r = row; c = col; action = "add Vwall"; self.logic.vwalls[row][col] = False; return action, r, c;
def minimaxTree(self, player1: Player, player2: Player, d, l, r, maxDepth): # TODO find the best depth for algorithm if d == maxDepth: return self.heuristic(player1, player2) if player1.pos.row == self.goal: return 80 g = 0 if self.goal == 8 else 8 if player2.pos.row == g: return 0 if d % 2 == 1: # min alphaBeta = 80 for pm in self.logic.possibleMoves(player2, player1): p = Player(Position(pm.row, pm.col), None, None, player2.walls) a = self.minimaxTree(player1, p, d + 1, l, r, maxDepth) alphaBeta = min(alphaBeta, a) if a <= l: return alphaBeta r = min(r, a) if player2.walls > 0: for row in range(player1.pos.row - 1, player1.pos.row + 2): for col in range(player1.pos.col - 2, player1.pos.col + 2): if self.logic.addHwall(col, row, player1, player2, self.goal): a = self.minimaxTree(player1, player2, d + 1, l, r, maxDepth) alphaBeta = min(alphaBeta, a) if a <= l: self.logic.hwalls[row][col] = False return alphaBeta r = min(r, a) self.logic.hwalls[row][col] = False if (row != 0 and row != 8) or (self.logic.isVwall(2 if row == 0 else 6, col)) \ or (self.logic.isHwall(row, col)) or (self.logic.isHwall(row, col + 1)): if self.logic.addVwall(col, row, player1, player2, self.goal): a = self.minimaxTree(player1, player2, d + 1, l, r, maxDepth) alphaBeta = min(alphaBeta, a) if a <= l: self.logic.vwalls[row][col] = False return alphaBeta r = min(r, a) self.logic.vwalls[row][col] = False return alphaBeta else: # max alphaBeta = 0 for pm in self.logic.possibleMoves(player1, player2): p = Player(Position(pm.row, pm.col), None, None, player1.walls) a = self.minimaxTree(p, player2, d + 1, l, r, maxDepth) alphaBeta = max(alphaBeta, a) if a >= r: return alphaBeta l = max(l, a) if player1.walls > 0: for row in range(player2.pos.row - 1, player2.pos.row + 2): for col in range(player2.pos.col - 2, player2.pos.col + 2): if self.logic.addHwall(col, row, player1, player2, self.goal): a = self.minimaxTree(player1, player2, d + 1, l, r, maxDepth) alphaBeta = max(alphaBeta, a) if a >= r: self.logic.hwalls[row][col] = False return alphaBeta l = max(l, a) self.logic.hwalls[row][col] = False if (row != 0 and row != 8) or (self.logic.isVwall(2 if row == 0 else 6, col)) \ or (self.logic.isHwall(row, col)) or (self.logic.isHwall(row, col + 1)): if self.logic.addVwall(col, row, player1, player2, self.goal): a = self.minimaxTree(player1, player2, d + 1, l, r, maxDepth) alphaBeta = max(alphaBeta, a) if a >= r: self.logic.vwalls[row][col] = False return alphaBeta l = max(l, a) self.logic.vwalls[row][col] = False return alphaBeta
def chooseAnAction(self, player1: Player, player2: Player): start = time.process_time() if player1.walls + player2.walls == self.targetForChangeDepth: self.depth += 1 self.targetForChangeDepth -= 5 p1 = Player(Position(player1.pos.row, player1.pos.col), None, None, player1.walls) p2 = Player(Position(player2.pos.row, player2.pos.col), None, None, player2.walls) alphaBeta = -1 r = 0 c = 0 action = "" sp = -1 sr = 0 sc = 0 for pm in self.logic.possibleMoves(player1, player2): p = Player(Position(pm.row, pm.col), None, None, p1.walls) l = self.shortestPath(p, p2, self.goal) if sp == -1 or l < sp: sp = l sr = pm.row sc = pm.col check = False if len(self.logic.possibleMoves(player1, player2)) > 1 and self.prevRow != -1: check = True for pm in self.logic.possibleMoves(player1, player2): if check and pm.row == self.prevRow and pm.col == self.prevCol: continue p = Player(Position(pm.row, pm.col), None, None, p1.walls) a = self.minimaxTree(p, p2, 1, 0, 80, self.depth) # if pm.row == sr and pm.col == sc: # a += 0.3 # print(a, "move", pm.row, pm.col) if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5): alphaBeta = a r = pm.row c = pm.col action = "move" if player1.walls > 0: for row in range(player2.pos.row - 2, player2.pos.row + 2): for col in range(player2.pos.col - 2, player2.pos.col + 2): if self.logic.addHwall(col, row, p1, p2, self.goal): a = self.minimaxTree(p1, p2, 1, 0, 80, self.depth) # print(a, "add Hwall", row, col) if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5 and action != "move"): alphaBeta = a r = row c = col action = "add Hwall" self.logic.hwalls[row][col] = False if (row != 0 and row != 8) or (self.logic.isVwall(2 if row == 0 else 6, col)) \ or (self.logic.isHwall(row, col)) or (self.logic.isHwall(row, col + 1)): if self.logic.addVwall(col, row, p1, p2, self.goal): a = self.minimaxTree(p1, p2, 1, 0, 80, self.depth) # print(a, "add Vwall", row, col) if a > alphaBeta or (a == alphaBeta and random.randint(0, 10) < 5 and action != "move"): alphaBeta = a r = row c = col action = "add Vwall" self.logic.vwalls[row][col] = False if action == "move": self.prevRow = player1.pos.row self.prevCol = player1.pos.col else: self.prevRow = -1 self.prevCol = -1 t = time.process_time() - start return action, r, c, t