Compare commits

...
Sign in to create a new pull request.

16 commits

Author SHA1 Message Date
Heli-o
5afa9e7fcf addded homework 9 and 10 2024-01-12 22:06:42 +01:00
Heli-o
0c59a36efb almost fully working 2024-01-11 22:20:03 +01:00
Heli-o
6fb8dbeaf6 not working yet 2024-01-11 18:29:56 +01:00
Heli-o
f8d57055a9 Pre filip change 2024-01-10 14:48:55 +01:00
Heli-o
fc5b73c771 still not working 2024-01-06 19:56:48 +01:00
Heli-o
56b3f0a6f1 im so fucking lost 2024-01-05 21:45:03 +01:00
0433665878
removed not from validation 2024-01-05 18:57:42 +01:00
Heli-o
089b588450 still nonfunctional 2024-01-05 18:21:32 +01:00
Heli-o
1b9820b6c9 refuses to work, movement broken 2024-01-05 13:15:16 +01:00
Heli-o
7069c9df47 still errors 2024-01-03 20:05:34 +01:00
Heli-o
a6993ca49b safety commit 2024-01-03 18:10:42 +01:00
Heli-o
dde404034a fixed some issues, offline test not working 2024-01-03 00:13:13 +01:00
Heli-o
6a96aa8e36 Merge branch 'main' of https://github.com/Heli-o/Hive 2024-01-01 19:05:49 +01:00
Heli-o
fabdce01d5 Still untested 2024-01-01 19:05:36 +01:00
Heli-o
7ec9c0a084 formated 2024-01-01 19:03:55 +01:00
Heli-o
3412605b1e chat gpt is probably god? hopefully works, untested 2024-01-01 19:03:26 +01:00
16 changed files with 1901 additions and 85 deletions

3
.gitignore vendored Normal file
View file

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

77
ant.py Normal file
View 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()

View file

@ -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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

375
messy player.py Normal file
View 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
View 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
View 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
View 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
View 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
View file

@ -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
View 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
View 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