import base as Base import copy, random, time, math from PIL import Image, ImageDraw # Player template for HIVE --- ALP semestral work # Vojta Vonasek, 2023 # PUT ALL YOUR IMPLEMENTATION INTO THIS FILE class Spider: def __init__(self, p,q, parent=None): self.p = p self.q = q self.path=[] self.parent = None #not important 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 getAllEmptyCells(self): result = [] for p in self.board: for q in self.board[p]: if self.isEmpty(p,q, self.board): result.append( [p,q] ) return result def getAllNonemptyCells(self): result = [] for p in self.board: for q in self.board[p]: if not self.isEmpty(p,q, self.board): result.append( [p,q] ) return result def move(self): """ return [animal, oldP, oldQ, newP, newQ], or [animal, None, None, newP, newQ] or [] """ #the following code just randomly places (ignoring all the rules) some random figure at the board emptyCells = self.getAllEmptyCells() if len(emptyCells) == 0: return [] randomCell = emptyCells[ random.randint(0, len(emptyCells)-1) ] randomP, randomQ = randomCell for animal in self.myPieces: if self.myPieces[animal] > 0: #is this animal still available? if so, let's place it return [ animal, None, None, randomP, randomQ ] #all animals are places, let's move some randomly (again, while ignoring all rules) allFigures = self.getAllNonemptyCells() randomCell = allFigures[ random.randint(0, len(allFigures)-1) ] randomFigureP, randomFigureQ = randomCell #determine which animal is at randomFigureP, randomFigureQ animal = self.board[ randomFigureP ][ randomFigureQ ][-1] # [-1] means the last letter return [animal, randomFigureP, randomFigureQ, randomP, randomQ ] def canSlide(self, p,q, lp, lq, board): SN = {} SN[ (1,0) ] = [ [1,-1], [0,1] ] SN[ (1,-1) ] = [ [0,-1], [1,0] ] SN[ (0,-1) ] = [ [1,-1], [-1,0] ] SN[ (-1,0) ] = [ [0,-1], [-1,1] ] SN[ (-1,1) ] = [ [-1,0], [0,1] ] SN[ (0,1) ] = [ [-1,1], [1,0 ] ] newp, newq = p+lp, q+lq if self.inBoard(newp, newq) and \ self.isEmpty(newp, newq, board): for cell in SN[ (lp, lq ) ]: cellp, cellq = cell cellp += p cellq += q if self.inBoard(cellp, cellq) and \ self.isEmpty(cellp, cellq, board): return True return False def spiderMoves(self, p,q): #return list of all paths result = [] start = Spider(p,q) start.path = [ [p,q] ] queue = [ start ] N = [ [1,-1],[0,-1],[-1,0],[-1,1], [0,1] ,[1,0]] while len(queue) > 0: act = queue.pop() #if goal if len(act.path) == 4: result.append(act.path) continue #expanze for cell in N: cellp, cellq = cell if self.canSlide(act.p, act.q, cellp, cellq, self.board): newp, newq = act.p + cellp, act.q + cellq newState = Spider( newp, newq ) newState.path = copy.deepcopy(act.path) + [ [newp, newq] ] queue.insert(0, newState ) result2 = [] for path in result: isWrong = False for i in range(len(path) - 1): p1,q1 = path[i] p2,q2 = path[i+1] if self.shareNeighbors(p1,q1,p2,q2): pass else: isWrong = True break if isWrong == False: result2.append( path) return result2 def listNonemptyNeighbors(self, p,q): N = [ [1,-1],[0,-1],[-1,0],[-1,1], [0,1] ,[1,0]] nec = {} for cell in N: cellp, cellq = cell cellp += p cellq += q if self.inBoard(cellp, cellq) and not self.isEmpty(cellp, cellq, self.board): nec[ (cellp, cellq) ] = True return nec def shareNeighbors(self, p1,q1, p2,q2): NEC1 = self.listNonemptyNeighbors(p1,q1) NEC2 = self.listNonemptyNeighbors(p2,q2) for cell in NEC1: if cell in NEC2: return True return False def testSpider(self): self.board[6][6] = "S" self.board[6][7] = "a" self.board[5][7] = "a" moves = self.spiderMoves(6,6) moveidx = 0 for path in moves: #path = [ [p,q], ... [p,q] ] HL = {} for cell in path: HL[ (cell[0], cell[1]) ] = "#00FF00" self.saveImage("spider"+str(moveidx) + ".png", HL=HL) moveidx += 1 def test(self): N = [ [1,-1],[0,-1],[-1,0],[-1,1], [0,1] ,[1,0]] self.board[6][6] = "S" self.board[7][5] = "a" self.board[6][7] = "a" p,q = 6,6 #### TEST POZICE frame = 0 for cell in N: lp, lq = cell if self.canSlide(p,q, lp, lq, self.board): newp, newq = p + lp, q+ lq #self.board[newp][newq] = "Q" HL = {} HL[ (newp, newq) ] = "#00FF00" self.saveImage("move"+str(frame) + ".png", HL=HL) frame += 1 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) P1.testSpider() print("end") moveIdx = 0 while True: break 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