import re import base as Base import copy, random, time, math from PIL import Image, ImageDraw # Player template for HIVE --- ALP semestral work # Vojta Vonasek, 2023 r = [[0,-1],[1,-1],[1,0],[0,1],[-1,1],[-1,0]] totalPieces = 18 def cn(graph,cell,visited): n = 0 for i in graph[str(cell)][0]: if(visited.get(str(i)) == None and graph[str(i)][1] == False): visited[str(i)] = True n += len(graph[str(i)][2]) n += cn(graph,i,visited) return n # PUT ALL YOUR IMPLEMENTATION INTO THIS FILE class Player(Base.Board): def __init__(self, playerName, myIsUpper, size, myPieces, rivalPieces): #do not change this line Base.Board.__init__(self, myIsUpper, size, myPieces, rivalPieces) #do not change this line self.playerName = playerName self.algorithmName = "myGreatMethod" def getCount(self): n = 0 for i in self.myPieces.values(): n += i for i in self.rivalPieces.values(): n += i return totalPieces - n def getMyCount(self): n = 0 for i in self.myPieces.values(): n += i return n def connected(self,graph,cell): for i in graph[str(cell)][0]: if(graph[str(i)][1] == False): break return self.getCount()-1 == cn(graph, i, {str(cell): True, str(i): True}) + len(graph[str(i)][2]) def spider(self,graph,cell,n,visited): n += 1 visited[str(cell)] = True if(n == 4): return [cell] result = [] for i in graph[str(cell)][0]: hive = False empty = False if(visited.get(str(i)) == None and graph[str(i)][1]): for j in graph[str(i)][0]: if(empty and hive): break if(j in graph[str(cell)][0]): if(graph[str(j)][1] or visited.get(str(j))): empty = True else: hive = True if(empty and hive): result += self.spider(graph,i,n,visited.copy()) return result def bee(graph,cell): result = [] for i in graph[str(cell)][0]: if(graph[str(i)][1]): hive = False empty = False for j in graph[str(i)][0]: if(hive and empty): break if(j in graph[str(cell)][0]): if(graph[str(j)][1]): empty = True else: hive = True if(hive and empty): result.append(i) return result def grasshopper(graph,cell): result = [] for i in r: q = [cell[0]+i[0],cell[1]+i[1]] if(graph.get(str(q))[1] == False): while(True): q = [q[0]+i[0],q[1]+i[1]] if(graph.get(str(q)) != None): if(graph.get(str(q))[1]): result.append(q) break else: break return result def bug(graph,cell): if(len(graph[str(cell)][2]) > 1): return graph[str(cell)][0] result = [] for i in graph[str(cell)][0]: if(graph[str(i)][1]): for j in graph[str(i)][0]: if(j[0] != cell[0] or j[1] != cell[1]): if(graph[str(j)][1] == False): result.append(i) break else: result.append(i) return result def ant(self,graph,cell,visited): visited[str(cell)] = True result = [] for i in graph[str(cell)][0]: hive = False empty = False if(visited.get(str(i)) == None and graph[str(i)][1]): for j in graph[str(i)][0]: if(empty and hive): break if(j in graph[str(cell)][0]): if(graph[str(j)][1] or visited.get(str(j))): empty = True else: hive = True if(empty and hive): result += [i] result += self.ant(graph,i,visited) return result def move(self): """ return [animal, oldP, oldQ, newP, newQ], or [animal, None, None, newP, newQ] or [] """ graph = {} # [0] neighbours [1] empty [2] myFigure myFigures = [] # GET GRAPH,MYFIGURES for k,v in self.board.items(): for q,a in v.items(): ng = [] for i in r: if(self.inBoard(k+i[0],q+i[1])): ng.append([k+i[0],q+i[1]]) graph[str([k,q])] = [ng,a == "",self.myColorIsUpper == a.isupper()] if(a != ""): if(self.myColorIsUpper == a.isupper()): myFigures.append([k,q]) # GET Movable,Empty movableFigures = {} emptyCells = [] for cell in myFigures: # Get all empty cells if(self.getMyCount() != 0): for i in r: q = [cell[0]+i[0],cell[1]+i[1]] qs = str(q) if(graph.get(qs) != None): if(graph[qs][1] == True): enemy = False for j in r: qq = [q[0]+j[0],q[1]+j[1]] qqs = str(qq) if(graph.get(qqs) != None): if(graph[qqs][1] == False): if(graph[qqs][2] == False): enemy = True break if(not enemy): emptyCells.append(q) # Get all moves if(self.myMove > 3): if(self.connected(graph,cell)): animal = graph[str(cell)][2][-1].lower() arr = [] if(animal == 's'): arr = self.spider(graph,cell,0,{}) elif(animal == 'b'): arr = self.bug(graph,cell) elif(animal == 'g'): arr = self.grasshopper(graph,cell) elif(animal == 'a'): arr = self.ant(graph,cell,{}) else: arr = self.bee(graph,cell) if(len(arr) > 0): movableFigures[str(cell)] = arr # can't place or move if(len(emptyCells) == 0 and len(movableFigures) == 0): return [] # 0 - center or around if(self.myMove == 0): animal = random.choice(list(self.myPieces.keys())) if(self.getCount() == 0): return [animal,None,None,3,6] else: m = [[2,6],[4,6],[3,5],[4,5],[2,7],[3,7]] n = random.randint(0,len(m)-1) # ! return [animal, None,None,m[n][0],m[n][1]] # 1-3 - place figures # 3 - must place queen # 4+ - can move or place # end # - bee is surrounded - all neighbours arr full # - move n > 80 # - both player can't play return [] def updatePlayers(move, activePlayer, passivePlayer): """ write move made by activePlayer player this method assumes that all moves are correct, no checking is made """ if len(move) == 0: return animal, p,q, newp, newq = move if p == None and q == None: #placing new animal activePlayer.myPieces[animal]-=1 passivePlayer.rivalPieces = activePlayer.myPieces.copy() else: #just moving animal #delete its old position activePlayer.board[p][q] = activePlayer.board[p][q][:-1] passivePlayer.board[p][q] = passivePlayer.board[p][q][:-1] activePlayer.board[newp][newq] += animal passivePlayer.board[newp][newq] += animal if __name__ == "__main__": boardSize = 13 smallFigures = { "q":1, "a":2, "b":2, "s":2, "g":2 } #key is animal, value is how many is available for placing bigFigures = { figure.upper(): smallFigures[figure] for figure in smallFigures } #same, but with upper case P1 = Player("player1", False, 13, smallFigures, bigFigures) P2 = Player("player2", True, 13, bigFigures, smallFigures) filename = "begin.png" P1.saveImage(filename) moveIdx = 0 while True: move = P1.move() print("P1 returned", move) updatePlayers(move, P1, P2) #update P1 and P2 according to the move filename = "move-{:03d}-player1.png".format(moveIdx) P1.saveImage(filename) move = P2.move() print("P2 returned", move) updatePlayers(move, P2, P1) #update P2 and P1 according to the move filename = "move-{:03d}-player2.png".format(moveIdx) P1.saveImage(filename) moveIdx += 1 P1.myMove = moveIdx P2.myMove = moveIdx if moveIdx > 50: print("End of the test game") break