Hive/messy player.py
2024-01-10 14:48:55 +01:00

375 lines
No EOL
13 KiB
Python

import base as Base
import copy, random, time, math
from PIL import Image, ImageDraw
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"
self.r = [[0,-1],[1,-1],[1,0],[0,1],[-1,1],[-1,0]]
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 bfs(self,g,e):
b = {}
q = []
r = 0
b[str(e)] = True
b[str(g[str(e)][0])] = True
q.append(str(g[str(e)][0]))
while(len(q) > 0):
p = q[0]
del q[0]
r+=1
for i in g[p]:
if(b.get(str(i)) == None):
b[str(i)] = True
q.append(str(i))
return len(g)-1 == r
def grasshopper(self,cell):
result = []
for i in self.r:
q = [cell[0]+i[0],cell[1]+i[1]]
if(self.inBoard(q[0],q[1])):
if(not self.isEmpty(q[0],q[1],self.board)):
while(True):
q = [q[0]+i[0],q[1]+i[1]]
if(self.inBoard(q[0],q[1])):
if(self.isEmpty(q[0],q[1],self.board)):
result.append(q)
break
else:
break
return result
def bug(self,cell):
result = []
b = {}
b[str(cell)] = True
for i in self.r:
q = [cell[0]+i[0],cell[1]+i[1]]
if(self.inBoard(q[0],q[1])):
if(len(self.board[cell[0]][cell[1]]) > 1):
result.append(q)
b[str(q)] = True
continue
if(not self.isEmpty(q[0],q[1],self.board)):
result.append(q)
else:
if(b.get(str(q)) == None):
g = False
# e = False
for j in self.r:
w = [q[0]+j[0],q[1]+j[1]]
if(self.inBoard(w[0],w[1])):
if(not self.isEmpty(w[0],w[1],self.board) and b.get(str(w)) == None):
g = True
# t = [w[0]-cell[0],w[1]-cell[1]]
# if(t in self.r and self.isEmpty(w[0],w[1],self.board)):
# e = True
if(g):
b[str(q)] = True
result.append(q)
return result
def ant(self,cell):
result = []
b = {}
b[str(cell)] = True
a = [cell]
while(len(a) > 0):
p = a[0]
del a[0]
for i in self.r:
q = [p[0]+i[0],p[1]+i[1]]
if(self.inBoard(q[0],q[1])):
if(self.isEmpty(q[0],q[1],self.board) and b.get(str(q)) == None):
g = False
e = False
for j in self.r:
w = [q[0]+j[0],q[1]+j[1]]
if(self.inBoard(w[0],w[1])):
if(not self.isEmpty(w[0],w[1],self.board) and b.get(str(w)) == None):
g = True
t = [w[0]-p[0],w[1]-p[1]]
if(t in self.r and self.isEmpty(w[0],w[1],self.board)):
e = True
if(e and g):
a.append(q)
b[str(q)] = True
result.append(q)
return result
def bee(self,p):
result = []
b = {}
b[str(p)] = True
for i in self.r:
q = [p[0]+i[0],p[1]+i[1]]
if(self.inBoard(q[0],q[1])):
if(self.isEmpty(q[0],q[1],self.board) and b.get(str(q)) == None):
g = False
e = False
for j in self.r:
w = [q[0]+j[0],q[1]+j[1]]
if(self.inBoard(w[0],w[1])):
if(not self.isEmpty(w[0],w[1],self.board) and b.get(str(w)) == None):
g = True
t = [w[0]-p[0],w[1]-p[1]]
if(t in self.r and self.isEmpty(w[0],w[1],self.board)):
e = True
if(e and g):
b[str(q)] = True
result.append(q)
return result
def spider(self,cell):
result = []
b = {}
b[str(cell)] = True
a = [cell]
n = 0
path = []
while(len(a) > 0 and n < 5):
n += 1
if(len(a) == 0):
break
p = a[0]
del a[0]
for i in self.r:
q = [p[0]+i[0],p[1]+i[1]]
if(self.inBoard(q[0],q[1])):
if(self.isEmpty(q[0],q[1],self.board) and b.get(str(q)) == None):
g = False
e = False
for j in self.r:
w = [q[0]+j[0],q[1]+j[1]]
if(self.inBoard(w[0],w[1])):
t = [w[0]-p[0],w[1]-p[1]]
if(t in self.r and not self.isEmpty(w[0],w[1],self.board) and b.get(str(w)) == None):
g = True
if(t in self.r and self.isEmpty(w[0],w[1],self.board) and b.get(str(w)) == None):
e = True
if(e and g):
# print(self.isEmpty(q[0],q[1],self.board))
a.append(q)
path.append(q)
# print(n,q)
# b[str(q)] = True
# if(n == 4 or n == 5):
# result.append(q)
for aa in a:
b[str(aa)] = True
# print(self.myMove)
if(len(path) == 6):
result = path[4:]
print(path)
# print(result)
return result
def move(self):
""" return [animal, oldP, oldQ, newP, newQ], or [animal, None, None, newP, newQ] or [] """
emptyCells = self.getAllEmptyCells()
# tah 0
if(self.myMove == 0):
q = random.choice(list(self.myPieces.keys())) # !
if(len(emptyCells) == 169):
return [q, 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 [q, None,None,m[n][0],m[n][1]]
# tah 1-3
allFigures = self.getAllNonemptyCells()
myFigures = []
enemyFigures = []
graph = {}
for cell in allFigures:
if(graph.get(str(cell)) == None):
graph[str(cell)] = []
for i in self.r:
q = [cell[0]+i[0],cell[1]+i[1]]
if(graph.get(str(q)) != None):
graph[str(cell)] = graph[str(cell)] + [q]
graph[str(q)] = graph[str(q)] + [cell]
a = self.board[cell[0]][cell[1]][-1]
if(self.myColorIsUpper == a.isupper()):
myFigures.append(cell)
else:
enemyFigures.append(cell)
movableFigures = {}
possibleEmptyCells = []
for cell in myFigures:
if(self.myMove > 3):
if(self.bfs(graph,cell) or len(self.board[cell[0]][cell[1]]) > 1):
animal = self.board[cell[0]][cell[1]][-1]
if(animal.lower() == 'g'):
arr = self.grasshopper(cell)
if(len(arr) > 0):
movableFigures[str(cell)] = arr
elif(animal.lower() == 'b'):
arr = self.bug(cell)
if(len(arr) > 0):
movableFigures[str(cell)] = arr
elif(animal.lower() == 'a'):
arr = self.ant(cell)
if(len(arr) > 0):
movableFigures[str(cell)] = arr
elif(animal.lower() == 'q'):
arr = self.bee(cell)
if(len(arr) > 0):
movableFigures[str(cell)] = arr
elif(animal.lower() == 's'):
arr = self.spider(cell)
if(len(arr) > 0):
movableFigures[str(cell)] = arr
for i in self.r:
q = [cell[0]+i[0],cell[1]+i[1]]
if(self.inBoard(q[0],q[1])):
if(self.isEmpty(q[0],q[1],self.board)):
end = False
for e in enemyFigures:
if(end):
break
a = [e[0]-q[0],e[1]-q[1]]
if(a in self.r):
end = True
if(not end):
possibleEmptyCells.append((q))
if(len(possibleEmptyCells) == 0 and len(movableFigures) == 0):
return []
if(len(possibleEmptyCells) == 1):
randomP, randomQ = possibleEmptyCells[0]
else:
if(len(possibleEmptyCells) > 0 ):
randomEmptyCell = possibleEmptyCells[ random.randint(0, len(possibleEmptyCells)-1) ]
randomP, randomQ = randomEmptyCell
if(len(possibleEmptyCells) > 0 ):
if(self.myMove == 3):
q = 'q'
if(self.myColorIsUpper):
q = 'Q'
if(self.myPieces[q] == 1):
return [q,None,None,randomP,randomQ]
if len(emptyCells) == 0:
return []
result = None
while(result == None):
# Place
if(len(possibleEmptyCells) > 0 ):
for animal in self.myPieces:
p = random.choice(list(self.myPieces.keys()))
if self.myPieces[p] > 0:
result = [ p, None, None, randomP, randomQ ]
break
# Move
if(len(movableFigures) > 0 and self.myMove > 3):
randomFigure,figureMoves = random.choice(list(movableFigures.items()))
randomFigure = randomFigure.replace('[','').replace(']','').replace(' ','').split(',')
randomFigure = list(map(int,randomFigure))
if(len(figureMoves) == 1):
randomMove = figureMoves[0]
else:
randomMove = figureMoves[ random.randint(0, len(figureMoves)-1) ]
randomFigureP, randomFigureQ = randomFigure
animal = self.board[ randomFigureP ][ randomFigureQ ][-1]
result = [animal, randomFigureP, randomFigureQ, randomMove[0], randomMove[1] ]
break
return result
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:
activePlayer.myPieces[animal]-=1
passivePlayer.rivalPieces = activePlayer.myPieces.copy()
else:
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 }
bigFigures = { figure.upper(): smallFigures[figure] for figure in smallFigures }
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)
filename = "move-{:03d}-player1.png".format(moveIdx)
P1.saveImage(filename)
move = P2.move()
print("P2 returned", move)
updatePlayers(move, P2, P1)
filename = "move-{:03d}-player2.png".format(moveIdx)
P1.saveImage(filename)
moveIdx += 1
P1.myMove = moveIdx
P2.myMove = moveIdx
if moveIdx > 4:
print("End of the test game")
break