Compare commits

..

2 commits

Author SHA1 Message Date
Heli-o
6d0b218dc3 formated a document 2023-12-29 16:35:56 +01:00
Pytaaaa
81a597fc19 smrdis pavouk 2023-12-29 16:34:08 +01:00
15 changed files with 83 additions and 1716 deletions

3
.gitignore vendored
View file

@ -1,3 +0,0 @@
images/*
*.png
moves/*

Binary file not shown.

Binary file not shown.

Binary file not shown.

77
ant.py
View file

@ -1,77 +0,0 @@
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()

View file

@ -1,31 +1,34 @@
from player import Player
import ast
from enum import Enum
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 Piece:
def get_valid_jumps():
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 Bee(Piece):
pass
def update(pkg):
return update_player(*pkg)
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

View file

@ -1,86 +0,0 @@
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View file

@ -1,375 +0,0 @@
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

View file

@ -1,56 +0,0 @@
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>

View file

@ -1,55 +0,0 @@
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>

View file

@ -1,407 +0,0 @@
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

View file

@ -1,273 +0,0 @@
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

355
player.py
View file

@ -1,10 +1,7 @@
import base as Base
import copy
import random
import time
import math
import copy, random, time, math
from PIL import Image, ImageDraw
from collections import deque
# Player template for HIVE --- ALP semestral work
# Vojta Vonasek, 2023
@ -12,205 +9,12 @@ from collections import deque
# 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
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()
self.algorithmName = "myGreatMethod"
@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 = []
@ -220,6 +24,7 @@ class Player(Base.Board):
result.append( [p,q] )
return result
def getAllNonemptyCells(self):
result = []
for p in self.board:
@ -228,120 +33,35 @@ class Player(Base.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 [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 []
self.translate_board()
randomCell = emptyCells[ random.randint(0, len(emptyCells)-1) ]
randomP, randomQ = randomCell
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 []
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 ]
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]]
#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 ]
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
@ -365,18 +85,12 @@ 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)
@ -386,16 +100,18 @@ if __name__ == "__main__":
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)
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 = "moves/move-{:03d}-player2.png".format(moveIdx)
filename = "move-{:03d}-player2.png".format(moveIdx)
P1.saveImage(filename)
moveIdx += 1
@ -405,3 +121,8 @@ if __name__ == "__main__":
if moveIdx > 50:
print("End of the test game")
break

View file

@ -1,25 +0,0 @@
-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