Compare commits
16 commits
Author | SHA1 | Date | |
---|---|---|---|
|
5afa9e7fcf | ||
|
0c59a36efb | ||
|
6fb8dbeaf6 | ||
|
f8d57055a9 | ||
|
fc5b73c771 | ||
|
56b3f0a6f1 | ||
0433665878 | |||
|
089b588450 | ||
|
1b9820b6c9 | ||
|
7069c9df47 | ||
|
a6993ca49b | ||
|
dde404034a | ||
|
6a96aa8e36 | ||
|
fabdce01d5 | ||
|
7ec9c0a084 | ||
|
3412605b1e |
16 changed files with 1901 additions and 85 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
images/*
|
||||
*.png
|
||||
moves/*
|
BIN
__pycache__/assets.cpython-311.pyc
Normal file
BIN
__pycache__/assets.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/base.cpython-311.pyc
Normal file
BIN
__pycache__/base.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/player.cpython-311.pyc
Normal file
BIN
__pycache__/player.cpython-311.pyc
Normal file
Binary file not shown.
77
ant.py
Normal file
77
ant.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
import sys
|
||||
neighbors = lambda p, q: [(p + dp, q + dq) for dp, dq in [(0, -1), (1, -1), (1, 0), (0, 1), (-1, 1), (-1, 0)]]
|
||||
def crawler(table, visitation_rights, pos):
|
||||
visitation_rights.add(pos)
|
||||
resulted_offence = list() # just a result but cause I renamed visited to visitation_rights, I also renamed this.
|
||||
for i in table[pos][0]:
|
||||
|
||||
touching_hive, empty_space = False, False
|
||||
|
||||
if not i in table:
|
||||
continue
|
||||
if i not in visitation_rights and not table[i][1]:
|
||||
|
||||
for j in table[i][0]:
|
||||
if empty_space and touching_hive:
|
||||
break
|
||||
if j in table[pos][0]:
|
||||
if not j in table:
|
||||
continue
|
||||
|
||||
if not table[j][1] or j in visitation_rights:
|
||||
empty_space = True
|
||||
else:
|
||||
touching_hive = True
|
||||
|
||||
|
||||
if empty_space and touching_hive:
|
||||
resulted_offence += [i] + crawler(table, visitation_rights, i)
|
||||
return resulted_offence
|
||||
def flood(table, visited, pos):
|
||||
n = 0
|
||||
for i in table[pos][0]:
|
||||
if i not in table:
|
||||
continue
|
||||
if i not in visited and table[i][1] != 0:
|
||||
visited.add(i)
|
||||
n += 1 + flood(table, visited, i)
|
||||
return n
|
||||
|
||||
def seperation_check(table, figs, pos):
|
||||
for i in table[pos][0]:
|
||||
if i not in table:
|
||||
continue
|
||||
if not table[i][1]:
|
||||
continue
|
||||
visitation_rights = set() #orginally visited, but for some reason I decided to name it like this.
|
||||
visitation_rights.add(pos)
|
||||
visitation_rights.add(i)
|
||||
return figs-2 == flood(table, visitation_rights, i)
|
||||
return False
|
||||
|
||||
def main():
|
||||
with open(sys.argv[1],"r") as f:
|
||||
lines = f.readlines()
|
||||
lines = [list(map(int, l.split(" "))) for l in lines]
|
||||
|
||||
starting_ant = None
|
||||
lookup_table = dict()
|
||||
total_stones_on_board = 0
|
||||
for l in lines:
|
||||
lookup_table[(l[0],l[1])] = [neighbors(l[0],l[1]),l[2]]
|
||||
if l[2] != 0:
|
||||
total_stones_on_board +=1
|
||||
if l[2] == 2:
|
||||
starting_ant = (l[0],l[1])
|
||||
|
||||
if not seperation_check(lookup_table, total_stones_on_board, starting_ant):
|
||||
print([])
|
||||
return
|
||||
|
||||
res = crawler(lookup_table, set(), starting_ant)
|
||||
res.sort()
|
||||
print(list(map(list,res)))
|
||||
|
||||
|
||||
if __name__=="__main__":
|
||||
main()
|
53
assets.py
53
assets.py
|
@ -1,34 +1,31 @@
|
|||
from enum import Enum
|
||||
from player import Player
|
||||
import ast
|
||||
|
||||
|
||||
class Piece:
|
||||
def get_valid_jumps():
|
||||
pass
|
||||
def update_player(b, m, t, mp, rp):
|
||||
p = Player("p", t, 13, mp, rp)
|
||||
p.myMove = m
|
||||
p.board = b
|
||||
p.update()
|
||||
return p
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
pass
|
||||
def insert():
|
||||
board = input("insert board: ").strip()
|
||||
move = input("insert move: ").strip()
|
||||
mp = input("insert my team: ").strip()
|
||||
rp = input("insert rival team: ").strip()
|
||||
team = input("insert team: ").strip()
|
||||
|
||||
board = ast.literal_eval(board.split(" = ")[1])
|
||||
move = ast.literal_eval(move.split(" = ")[1])
|
||||
team = ast.literal_eval(team.split(" = ")[1])
|
||||
mp = ast.literal_eval(mp.split(" = ")[1])
|
||||
rp = ast.literal_eval(rp.split(" = ")[1])
|
||||
|
||||
p = update_player(board, move, team, mp, rp)
|
||||
return p, [board, move, team, mp, rp]
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class PieceTranslator(Enum):
|
||||
q = Bee
|
||||
b = Beetle
|
||||
s = Spider
|
||||
g = Grasshopper
|
||||
a = Ant
|
||||
def update(pkg):
|
||||
return update_player(*pkg)
|
||||
|
|
86
babylon.py
Normal file
86
babylon.py
Normal file
|
@ -0,0 +1,86 @@
|
|||
import sys
|
||||
from collections import deque
|
||||
|
||||
class towersolve:
|
||||
def __init__(self, matrix):
|
||||
self.matrix = matrix
|
||||
self.visited = set()
|
||||
self.queue = deque([(matrix, [])])
|
||||
|
||||
def solve(self):
|
||||
while self.queue:
|
||||
c_matrix, steps = self.queue.popleft()
|
||||
state = self.m2t(c_matrix)
|
||||
|
||||
if state in self.visited:
|
||||
continue
|
||||
self.visited.add(state)
|
||||
|
||||
if self.is_goal_state(c_matrix):
|
||||
return steps
|
||||
|
||||
zero_pos = self.find0(c_matrix)
|
||||
self.explore(c_matrix, steps, zero_pos)
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def m2t(matrix):
|
||||
return tuple(tuple(row) for row in matrix)
|
||||
|
||||
@staticmethod
|
||||
def is_goal_state(matrix):
|
||||
for col in range(len(matrix[0])):
|
||||
non_zero_numbers = [row[col] for row in matrix if row[col] != 0]
|
||||
if non_zero_numbers and non_zero_numbers.count(non_zero_numbers[0]) != len(non_zero_numbers):
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def rotate(matrix, row_index, vec):
|
||||
row = matrix[row_index]
|
||||
if vec == -1:
|
||||
row = row[1:] + row[:1]
|
||||
elif vec == 1:
|
||||
row = row[-1:] + row[:-1]
|
||||
matrix[row_index] = row
|
||||
return matrix
|
||||
|
||||
@staticmethod
|
||||
def move0(matrix, zero_pos, vec):
|
||||
row, col = zero_pos
|
||||
if vec == 1 and row > 0: # Swapped the directions
|
||||
matrix[row][col], matrix[row - 1][col] = matrix[row - 1][col], 0
|
||||
elif vec == -1 and row < len(matrix) - 1: # Swapped the directions
|
||||
matrix[row][col], matrix[row + 1][col] = matrix[row + 1][col], 0
|
||||
return matrix
|
||||
|
||||
@staticmethod
|
||||
def find0(matrix):
|
||||
for i, row in enumerate(matrix):
|
||||
for j, value in enumerate(row):
|
||||
if value == 0:
|
||||
return i, j
|
||||
return None
|
||||
|
||||
def explore(self, c_mat, steps, zero_pos):
|
||||
for row_index in range(len(c_mat)):
|
||||
for vec in [-1, 1]:
|
||||
new_matrix = self.rotate([row[:] for row in c_mat], row_index, vec)
|
||||
new_steps = steps + [f"r {row_index} {vec}"]
|
||||
self.queue.append((new_matrix, new_steps))
|
||||
|
||||
for vec in [-1, 1]:
|
||||
new_matrix = self.move0([row[:] for row in c_mat], zero_pos, vec)
|
||||
new_steps = steps + [f"m {vec}"]
|
||||
self.queue.append((new_matrix, new_steps))
|
||||
|
||||
def read_mat(file_path):
|
||||
with open(file_path, "r") as file:
|
||||
return [[int(num) for num in line.split()] for line in file]
|
||||
|
||||
if __name__ == "__main__":
|
||||
_input = read_mat(sys.argv[1])
|
||||
solver = towersolve(_input)
|
||||
sol = solver.solve()
|
||||
print(",".join(sol))
|
BIN
begin.png
Normal file
BIN
begin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
375
messy player.py
Normal file
375
messy player.py
Normal file
|
@ -0,0 +1,375 @@
|
|||
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
|
56
modified_assets.py
Normal file
56
modified_assets.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class Piece:
|
||||
def get_valid_jumps() -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class PieceTranslator(Enum):
|
||||
q = Bee
|
||||
b = Beetle
|
||||
s = Spider
|
||||
g = Grasshopper
|
||||
a = Ant
|
||||
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
def __init__(self, board, p, q, team):
|
||||
self.board = board
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team # 'team' should be 'upper' or 'lower' based on the piece case.
|
||||
|
||||
def get_valid_jumps(self):
|
||||
# The bee can move to an adjacent empty space.
|
||||
valid_moves = []
|
||||
for neighbor in get_neighbors(self.p, self.q):
|
||||
# Check if the neighbor is within the bounds of the board and is empty
|
||||
if neighbor in self.board and self.board[neighbor] == '':
|
||||
valid_moves.append(neighbor)
|
||||
return valid_moves
|
||||
|
||||
|
||||
get_neighbors = <function get_neighbors at 0x7eb8eda90940>
|
||||
|
55
modified_assets_v2.py
Normal file
55
modified_assets_v2.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class Piece:
|
||||
def get_valid_jumps() -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class PieceTranslator(Enum):
|
||||
q = Bee
|
||||
b = Beetle
|
||||
s = Spider
|
||||
g = Grasshopper
|
||||
a = Ant
|
||||
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team # 'team' is a boolean where True represents one team and False represents the other.
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
# The bee can move to an adjacent empty space.
|
||||
valid_moves = []
|
||||
for neighbor in get_neighbors(self.p, self.q):
|
||||
# Check if the neighbor is within the bounds of the board and is empty
|
||||
if neighbor in board and board[neighbor] == '':
|
||||
valid_moves.append(neighbor)
|
||||
return valid_moves
|
||||
|
||||
|
||||
def get_neighbors(p, q):
|
||||
get_neighbors.<locals>.<listcomp>
|
407
player - Copy.txt
Normal file
407
player - Copy.txt
Normal file
|
@ -0,0 +1,407 @@
|
|||
import base as Base
|
||||
import copy
|
||||
import random
|
||||
import time
|
||||
import math
|
||||
from PIL import Image, ImageDraw
|
||||
from collections import deque
|
||||
|
||||
# Player template for HIVE --- ALP semestral work
|
||||
# Vojta Vonasek, 2023
|
||||
|
||||
|
||||
# PUT ALL YOUR IMPLEMENTATION INTO THIS FILE
|
||||
|
||||
def inBoard(p, q, size):
|
||||
""" return True if (p,q) is valid coordinate """
|
||||
return (q >= 0) and (q < size) and (p >= -(q//2)) and (p < (size - q//2))
|
||||
|
||||
|
||||
def get_neighbors(p, q):
|
||||
directions = [(0, -1), (1, -1), (1, 0), (0, 1), (-1, 1), (-1, 0)]
|
||||
return [(p + dp, q + dq) for dp, dq in directions]
|
||||
|
||||
|
||||
def has_neighbors(p, q, board, pp, pq):
|
||||
# Check if the position (p, q) has at least one neighbor
|
||||
board = copy.deepcopy(board)
|
||||
board[pp][pq] = ""
|
||||
for dp, dq in get_neighbors(0, 0):
|
||||
neighbor_p, neighbor_q = p + dp, q + dq
|
||||
if inBoard(neighbor_p, neighbor_q, 13) and board[neighbor_p][neighbor_q] != "":
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def connection_crawler(spots, s, visited):
|
||||
n = 0
|
||||
for i in spots[s][0]:
|
||||
if i not in visited and spots[i][1]:
|
||||
visited.add(i)
|
||||
n += 1
|
||||
n += connection_crawler(spots, i, visited)
|
||||
return n
|
||||
|
||||
class Piece:
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_piece_info(self, myisupper):
|
||||
class_to_letter = {
|
||||
"Bee": "Q",
|
||||
"Beetle": "B",
|
||||
"Spider": "S",
|
||||
"Grasshopper": "G",
|
||||
"Ant": "A",
|
||||
}
|
||||
letter = class_to_letter[self.__class__.__name__]
|
||||
if not myisupper:
|
||||
letter = letter.lower()
|
||||
return [letter, self.p, self.q]
|
||||
|
||||
def get_valid_jumps() -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
|
||||
def get_valid_jumps(self, spots, s) -> list:
|
||||
result = []
|
||||
for i in spots[s][0]:
|
||||
if spots[i][1] is None:
|
||||
hive = False
|
||||
empty = False
|
||||
for j in spots[i][0]:
|
||||
if hive and empty:
|
||||
break
|
||||
if j in spots[s][0]:
|
||||
if spots[j][1] is None:
|
||||
empty = True
|
||||
else:
|
||||
hive = True
|
||||
if (hive and empty):
|
||||
result.append(i)
|
||||
return result
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
def __init__(self, p, q, team, stack=""):
|
||||
super().__init__(p, q, team)
|
||||
self.stack = stack
|
||||
|
||||
def get_valid_jumps(self, spots, s):
|
||||
if len(spots[s][1].stack) > 0:
|
||||
return spots[s][0]
|
||||
result = []
|
||||
for i in spots[s][0]:
|
||||
cs = copy.deepcopy(spots)
|
||||
cs[s][1] = None
|
||||
for j in spots[i][0]:
|
||||
if j in spots.keys() and cs[j][1]:
|
||||
result.append(i)
|
||||
break
|
||||
return result
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
def get_valid_jumps(self, spots: dict, s: tuple):
|
||||
return self.crawl(spots, s, 0, set())
|
||||
|
||||
def crawl(self, spots, s, n, visited):
|
||||
n += 1
|
||||
visited.add(s)
|
||||
if n == 4:
|
||||
return [s]
|
||||
result = []
|
||||
for i in spots[s][0]:
|
||||
hive = False
|
||||
empty = False
|
||||
if i not in visited and spots[i][1] is None:
|
||||
for j in spots[i][0]:
|
||||
if empty and hive:
|
||||
break
|
||||
if j in spots[s][0]:
|
||||
if spots[j][1] is None or j in visited:
|
||||
empty = True
|
||||
else:
|
||||
hive = True
|
||||
if (empty and hive):
|
||||
result += self.crawl(spots, i, n, visited.copy())
|
||||
return result
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
|
||||
def get_valid_jumps(self, spots, s):
|
||||
result = []
|
||||
for i in get_neighbors(0, 0):
|
||||
q = (s[0]+i[0], s[1]+i[1])
|
||||
if q in spots.keys() and spots[q][1]:
|
||||
while True:
|
||||
q = (q[0]+i[0], q[1]+i[1])
|
||||
if q in spots.keys() and spots[q][1] is None:
|
||||
nei = [1 for n in spots[q][0] if n!=s and spots[n][1]]
|
||||
if sum(nei)>0:
|
||||
result.append(q)
|
||||
break
|
||||
if q not in spots.keys():
|
||||
break
|
||||
return result
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
def get_valid_jumps(self, spots: dict, s: tuple):
|
||||
return self.crawl(spots, s, set())
|
||||
|
||||
def crawl(self, spots: dict, s: tuple, visited: set):
|
||||
visited.add(s)
|
||||
result = []
|
||||
for i in spots[s][0]:
|
||||
hive = False
|
||||
empty = False
|
||||
if i not in visited and spots[i][1] is None:
|
||||
for j in spots[i][0]:
|
||||
if empty and hive:
|
||||
break
|
||||
if j in spots[s][0]:
|
||||
if spots[j][1] is None or j in visited:
|
||||
empty = True
|
||||
else:
|
||||
hive = True
|
||||
if empty and hive:
|
||||
result += [i]
|
||||
result += self.crawl(spots, i, visited)
|
||||
return result
|
||||
|
||||
|
||||
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 = "just roll the dice, eh?"
|
||||
self.spots = dict()
|
||||
self.figures_player = list()
|
||||
self.bee = None
|
||||
self.total_piece_count = 18
|
||||
self.all_placed = list()
|
||||
|
||||
@property
|
||||
def all_remaining(self):
|
||||
return self.total_piece_count - sum(list(self.myPieces.values())+list(self.rivalPieces.values()))
|
||||
|
||||
@property
|
||||
def remaining_pieces(self):
|
||||
return sum(self.myPieces.values())
|
||||
|
||||
def connections_checker(self, spots, s):
|
||||
if isinstance(spots[s][1], Beetle):
|
||||
if len(spots[s][1].stack) > 0:
|
||||
return True
|
||||
for i in spots[s][0]:
|
||||
if spots[i][1] is None:
|
||||
continue
|
||||
visited = set()
|
||||
visited.add(s)
|
||||
visited.add(i)
|
||||
return len(self.all_placed)-2 == connection_crawler(spots, i, visited)
|
||||
return False
|
||||
|
||||
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 translate_board(self):
|
||||
# mapper dict
|
||||
piece_class_mapping = {
|
||||
"Q": Bee,
|
||||
"B": Beetle,
|
||||
"S": Spider,
|
||||
"G": Grasshopper,
|
||||
"A": Ant,
|
||||
}
|
||||
|
||||
spots = dict()
|
||||
self.all_placed = list()
|
||||
figures_player = list()
|
||||
|
||||
for p, r in self.board.items():
|
||||
for q, a in r.items():
|
||||
surr = [s for s in get_neighbors(
|
||||
p, q) if self.inBoard(s[0], s[1])]
|
||||
|
||||
if a:
|
||||
if len(a) > 1 and a[-1].lower == "b":
|
||||
spots[(p,q)] = [surr, piece_class_mapping["B"](p, q, self.myColorIsUpper == a[-1].isupper(), a[:-1])]
|
||||
else:
|
||||
spots[(p, q)] = [surr, piece_class_mapping[a[-1].upper()](
|
||||
p, q, self.myColorIsUpper == a[-1].isupper())]
|
||||
else:
|
||||
spots[(p,q)] = [surr, None]
|
||||
|
||||
if a and self.myColorIsUpper == a[-1].isupper():
|
||||
figures_player.append((p, q))
|
||||
if "Q" in list(map(lambda x: x.upper(),a)):
|
||||
self.bee = Bee(p, q, True)
|
||||
if a != "":
|
||||
self.all_placed.append(piece_class_mapping[a[-1].upper()](
|
||||
p, q, self.myColorIsUpper == a[-1].isupper()))
|
||||
|
||||
self.spots = spots
|
||||
self.figures_player = figures_player
|
||||
|
||||
def get_movable_and_empties(self):
|
||||
moveable = {}
|
||||
empty_spots = []
|
||||
for fig in self.figures_player:
|
||||
# Empty spots
|
||||
if self.remaining_pieces != 0:
|
||||
for i in get_neighbors(fig[0], fig[1]):
|
||||
if i in self.spots.keys():
|
||||
if self.spots[i][1] is None:
|
||||
enemy = False
|
||||
for j in get_neighbors(i[0], i[1]):
|
||||
if j in self.spots.keys():
|
||||
if self.spots[j][1] and self.spots[j][1].team == False:
|
||||
enemy = True
|
||||
break
|
||||
if not enemy:
|
||||
empty_spots.append(i)
|
||||
# actual move calc
|
||||
if self.myMove > 3:
|
||||
var = self.connections_checker(self.spots, fig)
|
||||
if var:
|
||||
animal = self.spots[fig][1]
|
||||
arr = animal.get_valid_jumps(self.spots, fig)
|
||||
if (len(arr) > 0):
|
||||
moveable[fig] = arr
|
||||
return moveable, empty_spots
|
||||
|
||||
def placer(self, empty):
|
||||
animal = random.choice([a for a, v in self.myPieces.items() if v != 0])
|
||||
spot = random.choice(empty)
|
||||
return [animal, None, None, spot[0], spot[1]]
|
||||
|
||||
def mover(self, moveable):
|
||||
animal = random.choice([a for a in moveable.keys()])
|
||||
jump = random.choice(moveable[animal])
|
||||
return self.spots[animal][1].get_piece_info(self.myColorIsUpper) + [jump[0], jump[1]]
|
||||
|
||||
def move(self):
|
||||
if self.myMove > 80:
|
||||
return []
|
||||
|
||||
self.translate_board()
|
||||
|
||||
free = [6]
|
||||
if self.bee:
|
||||
free = [1 for n in get_neighbors(
|
||||
self.bee.p, self.bee.q) if n in self.spots.keys() and self.spots[n][1] == None]
|
||||
if sum(free) <= 0:
|
||||
return []
|
||||
|
||||
if self.myMove == 0:
|
||||
animal = random.choice(list(self.myPieces.keys()))
|
||||
if self.all_remaining == 0:
|
||||
return [animal, None, None, 3, 6]
|
||||
else:
|
||||
choice = random.choice(get_neighbors(3, 6))
|
||||
return [animal, None, None, choice[0], choice[1]]
|
||||
|
||||
moveable, empty = self.get_movable_and_empties()
|
||||
if len(moveable) == 0 and len(empty) == 0: # movement impossible
|
||||
return []
|
||||
|
||||
if self.bee == None and (self.myMove == 3 or random.choice([True, False])) and self.myMove<=3:
|
||||
spot = random.choice(empty)
|
||||
return ["Q" if self.myColorIsUpper else 'q', None, None, spot[0], spot[1]]
|
||||
|
||||
if self.myMove <= 3:
|
||||
return self.placer(empty)
|
||||
|
||||
if self.bee:
|
||||
if (random.choice([True, False]) or len(moveable) == 0) and self.remaining_pieces:
|
||||
return self.placer(empty)
|
||||
else:
|
||||
return self.mover(moveable)
|
||||
return moveable
|
||||
|
||||
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 = "moves/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 = "moves/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
|
273
player algo.py
Normal file
273
player algo.py
Normal file
|
@ -0,0 +1,273 @@
|
|||
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
|
393
player.py
393
player.py
|
@ -1,7 +1,10 @@
|
|||
import base as Base
|
||||
import copy, random, time, math
|
||||
import copy
|
||||
import random
|
||||
import time
|
||||
import math
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
from collections import deque
|
||||
|
||||
# Player template for HIVE --- ALP semestral work
|
||||
# Vojta Vonasek, 2023
|
||||
|
@ -9,75 +12,352 @@ from PIL import Image, ImageDraw
|
|||
|
||||
# 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 inBoard(p, q, size):
|
||||
""" return True if (p,q) is valid coordinate """
|
||||
return (q >= 0) and (q < size) and (p >= -(q//2)) and (p < (size - q//2))
|
||||
|
||||
|
||||
def get_neighbors(p, q):
|
||||
directions = [(0, -1), (1, -1), (1, 0), (0, 1), (-1, 1), (-1, 0)]
|
||||
return [(p + dp, q + dq) for dp, dq in directions]
|
||||
|
||||
|
||||
def has_neighbors(p, q, board, pp, pq):
|
||||
# Check if the position (p, q) has at least one neighbor
|
||||
board = copy.deepcopy(board)
|
||||
board[pp][pq] = ""
|
||||
for dp, dq in get_neighbors(0, 0):
|
||||
neighbor_p, neighbor_q = p + dp, q + dq
|
||||
if inBoard(neighbor_p, neighbor_q, 13) and board[neighbor_p][neighbor_q] != "":
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def connection_crawler(spots, s, visited):
|
||||
n = 0
|
||||
for i in spots[s][0]:
|
||||
if i not in visited and spots[i][1]:
|
||||
visited.add(i)
|
||||
n += 1
|
||||
n += connection_crawler(spots, i, visited)
|
||||
return n
|
||||
|
||||
class Piece:
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_piece_info(self, myisupper):
|
||||
class_to_letter = {
|
||||
"Bee": "Q",
|
||||
"Beetle": "B",
|
||||
"Spider": "S",
|
||||
"Grasshopper": "G",
|
||||
"Ant": "A",
|
||||
}
|
||||
letter = class_to_letter[self.__class__.__name__]
|
||||
if not myisupper:
|
||||
letter = letter.lower()
|
||||
return [letter, self.p, self.q]
|
||||
|
||||
def get_valid_jumps() -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
|
||||
def get_valid_jumps(self, spots, s) -> list:
|
||||
result = []
|
||||
for i in spots[s][0]:
|
||||
if spots[i][1] is None:
|
||||
hive = False
|
||||
empty = False
|
||||
for j in spots[i][0]:
|
||||
if hive and empty:
|
||||
break
|
||||
if j in spots[s][0]:
|
||||
if spots[j][1] is None:
|
||||
empty = True
|
||||
else:
|
||||
hive = True
|
||||
if (hive and empty):
|
||||
result.append(i)
|
||||
return result
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
def __init__(self, p, q, team, stack=""):
|
||||
super().__init__(p, q, team)
|
||||
self.stack = stack
|
||||
|
||||
def get_valid_jumps(self, spots, s):
|
||||
if len(spots[s][1].stack) > 0:
|
||||
return spots[s][0]
|
||||
result = []
|
||||
for i in spots[s][0]:
|
||||
cs = copy.deepcopy(spots)
|
||||
cs[s][1] = None
|
||||
for j in spots[i][0]:
|
||||
if j in spots.keys() and cs[j][1]:
|
||||
result.append(i)
|
||||
break
|
||||
return result
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
def get_valid_jumps(self, spots: dict, s: tuple):
|
||||
return self.crawl(spots, s, 0, set())
|
||||
|
||||
def crawl(self, spots, s, n, visited):
|
||||
n += 1
|
||||
visited.add(s)
|
||||
if n == 4:
|
||||
return [s]
|
||||
result = []
|
||||
for i in spots[s][0]:
|
||||
hive = False
|
||||
empty = False
|
||||
if i not in visited and spots[i][1] is None:
|
||||
for j in spots[i][0]:
|
||||
if empty and hive:
|
||||
break
|
||||
if j in spots[s][0]:
|
||||
if spots[j][1] is None or j in visited:
|
||||
empty = True
|
||||
else:
|
||||
hive = True
|
||||
if (empty and hive):
|
||||
result += self.crawl(spots, i, n, visited.copy())
|
||||
return result
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
|
||||
def get_valid_jumps(self, spots, s):
|
||||
result = []
|
||||
for i in get_neighbors(0, 0):
|
||||
q = (s[0]+i[0], s[1]+i[1])
|
||||
if q in spots.keys() and spots[q][1]:
|
||||
while True:
|
||||
q = (q[0]+i[0], q[1]+i[1])
|
||||
if q in spots.keys() and spots[q][1] is None:
|
||||
nei = [1 for n in spots[q][0] if n!=s and spots[n][1]]
|
||||
if sum(nei)>0:
|
||||
result.append(q)
|
||||
break
|
||||
if q not in spots.keys():
|
||||
break
|
||||
return result
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
def get_valid_jumps(self, spots: dict, s: tuple):
|
||||
return self.crawl(spots, s, set())
|
||||
|
||||
def crawl(self, spots: dict, s: tuple, visited: set):
|
||||
visited.add(s)
|
||||
result = []
|
||||
for i in spots[s][0]:
|
||||
hive = False
|
||||
empty = False
|
||||
if i not in visited and spots[i][1] is None:
|
||||
for j in spots[i][0]:
|
||||
if empty and hive:
|
||||
break
|
||||
if j in spots[s][0]:
|
||||
if spots[j][1] is None or j in visited:
|
||||
empty = True
|
||||
else:
|
||||
hive = True
|
||||
if empty and hive:
|
||||
result += [i]
|
||||
result += self.crawl(spots, i, visited)
|
||||
return result
|
||||
|
||||
|
||||
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 = "just roll the dice, eh?"
|
||||
self.spots = dict()
|
||||
self.figures_player = list()
|
||||
self.bee = None
|
||||
self.total_piece_count = 18
|
||||
self.all_placed = list()
|
||||
|
||||
@property
|
||||
def all_remaining(self):
|
||||
return self.total_piece_count - sum(list(self.myPieces.values())+list(self.rivalPieces.values()))
|
||||
|
||||
@property
|
||||
def remaining_pieces(self):
|
||||
return sum(self.myPieces.values())
|
||||
|
||||
def connections_checker(self, spots, s):
|
||||
if isinstance(spots[s][1], Beetle):
|
||||
if len(spots[s][1].stack) > 0:
|
||||
return True
|
||||
for i in spots[s][0]:
|
||||
if spots[i][1] is None:
|
||||
continue
|
||||
visited = set()
|
||||
visited.add(s)
|
||||
visited.add(i)
|
||||
return len(self.all_placed)-2 == connection_crawler(spots, i, visited)
|
||||
return False
|
||||
|
||||
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] )
|
||||
if self.isEmpty(p, q, self.board):
|
||||
result.append([p, q])
|
||||
return result
|
||||
|
||||
|
||||
def getAllNonemptyCells(self):
|
||||
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] )
|
||||
if not self.isEmpty(p, q, self.board):
|
||||
result.append([p, q])
|
||||
return result
|
||||
|
||||
def translate_board(self):
|
||||
# mapper dict
|
||||
piece_class_mapping = {
|
||||
"Q": Bee,
|
||||
"B": Beetle,
|
||||
"S": Spider,
|
||||
"G": Grasshopper,
|
||||
"A": Ant,
|
||||
}
|
||||
|
||||
spots = dict()
|
||||
self.all_placed = list()
|
||||
figures_player = list()
|
||||
|
||||
for p, r in self.board.items():
|
||||
for q, a in r.items():
|
||||
surr = [s for s in get_neighbors(
|
||||
p, q) if self.inBoard(s[0], s[1])]
|
||||
|
||||
if a:
|
||||
if len(a) > 1 and a[-1].lower == "b":
|
||||
spots[(p,q)] = [surr, piece_class_mapping["B"](p, q, self.myColorIsUpper == a[-1].isupper(), a[:-1])]
|
||||
else:
|
||||
spots[(p, q)] = [surr, piece_class_mapping[a[-1].upper()](
|
||||
p, q, self.myColorIsUpper == a[-1].isupper())]
|
||||
else:
|
||||
spots[(p,q)] = [surr, None]
|
||||
|
||||
if a and self.myColorIsUpper == a[-1].isupper():
|
||||
figures_player.append((p, q))
|
||||
if "Q" in list(map(lambda x: x.upper(),a)):
|
||||
self.bee = Bee(p, q, True)
|
||||
if a != "":
|
||||
self.all_placed.append(piece_class_mapping[a[-1].upper()](
|
||||
p, q, self.myColorIsUpper == a[-1].isupper()))
|
||||
|
||||
self.spots = spots
|
||||
self.figures_player = figures_player
|
||||
|
||||
def get_movable_and_empties(self):
|
||||
moveable = {}
|
||||
empty_spots = []
|
||||
for fig in self.figures_player:
|
||||
# Empty spots
|
||||
if self.remaining_pieces != 0:
|
||||
for i in get_neighbors(fig[0], fig[1]):
|
||||
if i in self.spots.keys():
|
||||
if self.spots[i][1] is None:
|
||||
enemy = False
|
||||
for j in get_neighbors(i[0], i[1]):
|
||||
if j in self.spots.keys():
|
||||
if self.spots[j][1] and self.spots[j][1].team == False:
|
||||
enemy = True
|
||||
break
|
||||
if not enemy:
|
||||
empty_spots.append(i)
|
||||
# actual move calc
|
||||
if self.myMove > 3:
|
||||
var = self.connections_checker(self.spots, fig)
|
||||
if var:
|
||||
animal = self.spots[fig][1]
|
||||
arr = animal.get_valid_jumps(self.spots, fig)
|
||||
if (len(arr) > 0):
|
||||
moveable[fig] = arr
|
||||
return moveable, empty_spots
|
||||
|
||||
def placer(self, empty):
|
||||
animal = random.choice([a for a, v in self.myPieces.items() if v != 0])
|
||||
spot = random.choice(empty)
|
||||
return [animal, None, None, spot[0], spot[1]]
|
||||
|
||||
def mover(self, moveable):
|
||||
animal = random.choice([a for a in moveable.keys()])
|
||||
jump = random.choice(moveable[animal])
|
||||
return self.spots[animal][1].get_piece_info(self.myColorIsUpper) + [jump[0], jump[1]]
|
||||
|
||||
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:
|
||||
if self.myMove > 80:
|
||||
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 ]
|
||||
self.translate_board()
|
||||
|
||||
free = [6]
|
||||
if self.bee:
|
||||
free = [1 for n in get_neighbors(
|
||||
self.bee.p, self.bee.q) if n in self.spots.keys() and self.spots[n][1] == None]
|
||||
if sum(free) <= 0:
|
||||
return []
|
||||
|
||||
if self.myMove == 0:
|
||||
animal = random.choice(list(self.myPieces.keys()))
|
||||
if self.all_remaining == 0:
|
||||
return [animal, None, None, 3, 6]
|
||||
else:
|
||||
choice = random.choice(get_neighbors(3, 6))
|
||||
return [animal, None, None, choice[0], choice[1]]
|
||||
|
||||
#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 ]
|
||||
moveable, empty = self.get_movable_and_empties()
|
||||
if len(moveable) == 0 and len(empty) == 0: # movement impossible
|
||||
return []
|
||||
|
||||
if self.bee == None and (self.myMove == 3 or random.choice([True, False])) and self.myMove<=3:
|
||||
spot = random.choice(empty)
|
||||
return ["Q" if self.myColorIsUpper else 'q', None, None, spot[0], spot[1]]
|
||||
|
||||
|
||||
if self.myMove <= 3:
|
||||
return self.placer(empty)
|
||||
|
||||
if self.bee:
|
||||
if (random.choice([True, False]) or len(moveable) == 0) and self.remaining_pieces:
|
||||
return self.placer(empty)
|
||||
else:
|
||||
return self.mover(moveable)
|
||||
return moveable
|
||||
|
||||
def updatePlayers(move, activePlayer, passivePlayer):
|
||||
""" write move made by activePlayer player
|
||||
this method assumes that all moves are correct, no checking is made
|
||||
"""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
|
||||
animal, p, q, newp, newq = move
|
||||
if p == None and q == None:
|
||||
#placing new animal
|
||||
activePlayer.myPieces[animal]-=1
|
||||
# placing new animal
|
||||
activePlayer.myPieces[animal] -= 1
|
||||
passivePlayer.rivalPieces = activePlayer.myPieces.copy()
|
||||
else:
|
||||
#just moving animal
|
||||
#delete its old position
|
||||
# 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]
|
||||
|
||||
|
@ -85,33 +365,37 @@ def updatePlayers(move, activePlayer, passivePlayer):
|
|||
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
|
||||
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)
|
||||
|
||||
updatePlayers(move, P1, P2) # update P1 and P2 according to the move
|
||||
filename = "moves/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)
|
||||
updatePlayers(move, P2, P1) # update P2 and P1 according to the move
|
||||
filename = "moves/move-{:03d}-player2.png".format(moveIdx)
|
||||
P1.saveImage(filename)
|
||||
|
||||
moveIdx += 1
|
||||
|
@ -121,8 +405,3 @@ if __name__ == "__main__":
|
|||
if moveIdx > 50:
|
||||
print("End of the test game")
|
||||
break
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
183
spider.py
Normal file
183
spider.py
Normal file
|
@ -0,0 +1,183 @@
|
|||
import copy
|
||||
import math
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
|
||||
class Board:
|
||||
def __init__(self, size=0):
|
||||
self.size = size
|
||||
self.board = {}
|
||||
|
||||
# create empty board as a dictionary
|
||||
self.b2 = {}
|
||||
for p in range(-self.size, self.size):
|
||||
for q in range(-self.size, self.size):
|
||||
if self.inBoard(p, q):
|
||||
if not p in self.board:
|
||||
self.board[p] = {}
|
||||
self.board[p][q] = 0
|
||||
|
||||
if not q in self.b2:
|
||||
self.b2[q] = {}
|
||||
self.b2[q][p] = 0
|
||||
|
||||
# this is for visualization and to synchronize colors between png/js
|
||||
self._colors = {}
|
||||
self._colors[-1] = "#fdca40" # sunglow
|
||||
self._colors[0] = "#ffffff" # white
|
||||
self._colors[1] = "#947bd3" # medium purple
|
||||
self._colors[2] = "#ff0000" # red
|
||||
self._colors[3] = "#00ff00" # green
|
||||
self._colors[4] = "#0000ff" # blue
|
||||
self._colors[5] = "#566246" # ebony
|
||||
self._colors[6] = "#a7c4c2" # opan
|
||||
self._colors[7] = "#ADACB5" # silver metalic
|
||||
self._colors[8] = "#8C705F" # liver chestnut
|
||||
self._colors[9] = "#FA7921" # pumpkin
|
||||
self._colors[10] = "#566E3D" # dark olive green
|
||||
|
||||
def inBoard(self, p, q):
|
||||
"""return True if (p,q) is valid coordinate"""
|
||||
return (
|
||||
(q >= 0)
|
||||
and (q < self.size)
|
||||
and (p >= -(q // 2))
|
||||
and (p < (self.size - q // 2))
|
||||
)
|
||||
|
||||
def rotateRight(self, p, q):
|
||||
pp = -q
|
||||
qq = p + q
|
||||
return pp, qq
|
||||
|
||||
def rotateLeft(self, p, q):
|
||||
pp = p + q
|
||||
qq = -p
|
||||
return pp, qq
|
||||
|
||||
def saveImage(self, filename):
|
||||
"""draw actual board to png"""
|
||||
|
||||
cellRadius = 60
|
||||
cellWidth = int(cellRadius * (3**0.5))
|
||||
cellHeight = 2 * cellRadius
|
||||
|
||||
width = cellWidth * self.size + cellRadius * 3
|
||||
height = cellHeight * self.size
|
||||
|
||||
img = Image.new("RGB", (width, height), "white")
|
||||
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
lineColor = (50, 50, 50)
|
||||
|
||||
for p in self.board:
|
||||
for q in self.board[p]:
|
||||
cx = cellRadius * (math.sqrt(3) * p + math.sqrt(3) / 2 * q) + cellRadius
|
||||
cy = cellRadius * (0 * p + 3 / 2 * q) + cellRadius
|
||||
|
||||
pts = []
|
||||
for a in [30, 90, 150, 210, 270, 330]:
|
||||
nx = cx + cellRadius * math.cos(a * math.pi / 180)
|
||||
ny = cy + cellRadius * math.sin(a * math.pi / 180)
|
||||
pts.append(nx)
|
||||
pts.append(ny)
|
||||
color = "#ff00ff" # pink is for values out of range -1,..10
|
||||
if self.board[p][q] in self._colors:
|
||||
color = self._colors[self.board[p][q]]
|
||||
|
||||
draw.polygon(pts, fill=color)
|
||||
pts.append(pts[0])
|
||||
pts.append(pts[1])
|
||||
draw.line(pts, fill="black", width=1)
|
||||
draw.text(
|
||||
[cx - 3, cy - 3], "{} {}".format(p, q), fill="black", anchor="m"
|
||||
)
|
||||
img.save(filename)
|
||||
|
||||
def loadBoard(self, filename):
|
||||
board = {}
|
||||
fread = open(filename, "rt")
|
||||
size = -1
|
||||
for line in fread:
|
||||
p, q, value = list(map(int, line.strip().split()))
|
||||
size = max(size, q)
|
||||
if p not in board:
|
||||
board[p] = {}
|
||||
board[p][q] = value
|
||||
fread.close()
|
||||
self.board = board
|
||||
self.size = size + 1
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
# alternativa: nacteni ze souboru
|
||||
b = Board()
|
||||
b.loadBoard(sys.argv[1])
|
||||
|
||||
# prochazeni radku/sloupce:
|
||||
b_copy = {}
|
||||
for p in b.board:
|
||||
b_copy[p] = {}
|
||||
for q in b.board[p]:
|
||||
b_copy[p][q] = b.board[p][q]
|
||||
if b.board[p][q] == 2:
|
||||
spider_p = p
|
||||
spider_q = q
|
||||
|
||||
smer = ((0, -1), (1, -1), (1, 0), (0, 1), (-1, 1), (-1, 0))
|
||||
|
||||
|
||||
def okoli(b, p, q):
|
||||
o = [0] * 6
|
||||
for i in range(6):
|
||||
p2, q2 = smer[i]
|
||||
if b.inBoard(p + p2, q + q2):
|
||||
o[i] = b.board[p + p2][q + q2]
|
||||
else:
|
||||
o[i] = -1
|
||||
return o
|
||||
|
||||
|
||||
def spider_tah1(p, q, o):
|
||||
mozne_tahy = []
|
||||
for i in range(6):
|
||||
if o[i] == 0 and (
|
||||
(o[(i - 1) % 6] == 0 and o[(i + 1) % 6] == 1)
|
||||
or (o[(i - 1) % 6] == 1 and o[(i + 1) % 6] == 0)
|
||||
):
|
||||
mozne_tahy.append([p + smer[i][0], q + smer[i][1]])
|
||||
return mozne_tahy
|
||||
|
||||
|
||||
o_spider = okoli(b, spider_p, spider_q)
|
||||
print(o_spider)
|
||||
|
||||
komponenty = 0
|
||||
for i in range(6):
|
||||
if o_spider[i] == 1 and o_spider[(i + 1) % 6] != 1:
|
||||
komponenty += 1
|
||||
|
||||
if komponenty > 1:
|
||||
flood_fill()
|
||||
|
||||
pos = [[spider_p, spider_q]]
|
||||
dont_go_back = pos[:]
|
||||
b.board[spider_p][spider_q] = 0
|
||||
|
||||
for i in range(3):
|
||||
pos2 = []
|
||||
print(i, pos)
|
||||
for p, q in pos:
|
||||
mozne = spider_tah1(p, q, okoli(b, p, q))
|
||||
for x in mozne:
|
||||
if not x in dont_go_back:
|
||||
print("jdu vpred", x)
|
||||
pos2.append(x)
|
||||
dont_go_back.append(x)
|
||||
else:
|
||||
print("jdu zpet", x)
|
||||
pos = pos2
|
||||
pos2.sort()
|
||||
print(pos2)
|
25
test.txt
Normal file
25
test.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
-2 4 0
|
||||
-1 2 2
|
||||
-1 3 0
|
||||
-1 4 0
|
||||
0 0 0
|
||||
0 1 1
|
||||
0 2 0
|
||||
0 3 0
|
||||
0 4 0
|
||||
1 0 1
|
||||
1 1 1
|
||||
1 2 1
|
||||
1 3 1
|
||||
1 4 0
|
||||
2 0 1
|
||||
2 1 1
|
||||
2 2 0
|
||||
2 3 1
|
||||
2 4 0
|
||||
3 0 1
|
||||
3 1 1
|
||||
3 2 0
|
||||
3 3 0
|
||||
4 0 0
|
||||
4 1 0
|
Loading…
Add table
Reference in a new issue