not working yet
This commit is contained in:
parent
f8d57055a9
commit
6fb8dbeaf6
2 changed files with 183 additions and 249 deletions
|
@ -45,7 +45,7 @@ class Player(Base.Board):
|
||||||
for i in graph[str(cell)][0]:
|
for i in graph[str(cell)][0]:
|
||||||
if(graph[str(i)][1] == False):
|
if(graph[str(i)][1] == False):
|
||||||
break
|
break
|
||||||
return self.getCount()-1 == cn(graph,i,{str(cell):True,str(i):True}) + 1
|
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):
|
def spider(self,graph,cell,n,visited):
|
||||||
n += 1
|
n += 1
|
||||||
|
|
430
player.py
430
player.py
|
@ -33,7 +33,25 @@ def has_neighbors(p, q, board, pp, pq):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def cn(spots, s, visited):
|
||||||
|
n = 0
|
||||||
|
for i in spots[s][0]:
|
||||||
|
if i not in visited and spots[i][1] == False:
|
||||||
|
visited.add(i)
|
||||||
|
n += len(spots[i][2])
|
||||||
|
n += cn(spots, i, visited)
|
||||||
|
return n
|
||||||
|
|
||||||
class Piece:
|
class Piece:
|
||||||
|
def __init__(self, p, q, team):
|
||||||
|
self.p = p
|
||||||
|
self.q = q
|
||||||
|
self.team = team
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pos(self):
|
||||||
|
return (self.p, self.q)
|
||||||
|
|
||||||
def get_piece_info(self, myisupper):
|
def get_piece_info(self, myisupper):
|
||||||
class_to_letter = {
|
class_to_letter = {
|
||||||
"Bee": "Q",
|
"Bee": "Q",
|
||||||
|
@ -99,124 +117,110 @@ class Piece:
|
||||||
|
|
||||||
|
|
||||||
class Bee(Piece):
|
class Bee(Piece):
|
||||||
def __init__(self, p, q, team):
|
|
||||||
self.p = p
|
|
||||||
self.q = q
|
|
||||||
self.team = team
|
|
||||||
|
|
||||||
def get_valid_jumps(self, board) -> list:
|
def get_valid_jumps(self, spots, s) -> list:
|
||||||
valid_moves = []
|
result = []
|
||||||
for neighbor in get_neighbors(self.p, self.q):
|
for i in spots[s][0]:
|
||||||
if neighbor in board and board[neighbor] == "":
|
if spots[i][1]:
|
||||||
valid_moves.append(neighbor)
|
hive = False
|
||||||
return valid_moves
|
empty = False
|
||||||
|
for j in spots[i][0]:
|
||||||
|
if hive and empty:
|
||||||
|
break
|
||||||
|
if j in spots[s][0]:
|
||||||
|
if spots[j][1]:
|
||||||
|
empty = True
|
||||||
|
else:
|
||||||
|
hive = True
|
||||||
|
if (hive and empty):
|
||||||
|
result.append(i)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Beetle(Piece):
|
class Beetle(Piece):
|
||||||
def __init__(self, p, q, team):
|
|
||||||
self.p = p
|
|
||||||
self.q = q
|
|
||||||
self.team = team
|
|
||||||
|
|
||||||
def get_valid_jumps(self, board):
|
def get_valid_jumps(self, spots, s):
|
||||||
valid_moves = get_neighbors(self.p, self.q)
|
if len(spots[s][2]) > 1:
|
||||||
checked = [v for v in valid_moves if has_neighbors(
|
return spots[s][0]
|
||||||
v[0], v[1], board, self.p, self.q)]
|
result = []
|
||||||
return checked
|
for i in spots[s][0]:
|
||||||
|
if spots[i][1]:
|
||||||
|
for j in spots[i][0]:
|
||||||
|
if (j[0] != s[0] or j[1] != s[1]) and spots[j][1] == False:
|
||||||
|
result.append(i)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
result.append(i)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Spider(Piece):
|
class Spider(Piece):
|
||||||
def __init__(self, p, q, team):
|
def get_valid_jumps(self, spots: dict, s: tuple):
|
||||||
self.p = p
|
return self.crawl(spots, s, 0, set())
|
||||||
self.q = q
|
|
||||||
self.team = team
|
|
||||||
|
|
||||||
def get_valid_jumps(self, board):
|
def crawl(self, spots, s, n, visited):
|
||||||
start = (self.p, self.q)
|
n += 1
|
||||||
visited = set()
|
visited.add(s)
|
||||||
queue = deque([(start, 0)]) # Queue of (position, distance)
|
if n == 4:
|
||||||
valid_moves = []
|
return [s]
|
||||||
|
result = []
|
||||||
while queue:
|
for i in spots[s][0]:
|
||||||
current_position, current_distance = queue.popleft()
|
hive = False
|
||||||
if current_distance == 3:
|
empty = False
|
||||||
if has_neighbors(*current_position, board, self.p, self.q):
|
if i in visited and spots[i][1]:
|
||||||
valid_moves.append(current_position)
|
for j in spots[i][0]:
|
||||||
continue
|
if empty and hive:
|
||||||
|
break
|
||||||
if current_position in visited:
|
if j in spots[s][0]:
|
||||||
continue
|
if spots[str(j)][1] or j in visited:
|
||||||
|
empty = True
|
||||||
visited.add(current_position)
|
else:
|
||||||
|
hive = True
|
||||||
for p, q in get_neighbors(*current_position):
|
if (empty and hive):
|
||||||
next_pos = (p, q)
|
result += self.spider(spots, i, n, visited.copy())
|
||||||
if (inBoard(p, q, 13) and board[p][q] == "" and next_pos not in visited
|
return result
|
||||||
and has_neighbors(p, q, board, self.p, self.q)):
|
|
||||||
queue.append((next_pos, current_distance + 1))
|
|
||||||
|
|
||||||
return valid_moves
|
|
||||||
|
|
||||||
|
|
||||||
class Grasshopper(Piece):
|
class Grasshopper(Piece):
|
||||||
def __init__(self, p, q, team):
|
|
||||||
self.p = p
|
|
||||||
self.q = q
|
|
||||||
self.team = team
|
|
||||||
|
|
||||||
def get_valid_jumps(self, board):
|
def get_valid_jumps(self, spots, s):
|
||||||
# Generator function to yield valid moves
|
result = []
|
||||||
def generate_moves():
|
for i in get_neighbors(0, 0):
|
||||||
for dp, dq in get_neighbors(0, 0):
|
q = (s[0]+i[0], s[1]+i[1])
|
||||||
pos = (self.p + dp, self.q + dq)
|
if not spots[q][1]:
|
||||||
while pos in board and board[pos] != "":
|
while True:
|
||||||
pos = (pos[0] + dp, pos[1] + dq)
|
q = (q[0]+i[0], q[1]+i[1])
|
||||||
if (
|
if q in spots.keys() and spots[q][1]:
|
||||||
pos in board
|
result.append(q)
|
||||||
and board[pos] == ""
|
break
|
||||||
and (pos[0] != self.p or pos[1] != self.q)
|
else:
|
||||||
):
|
break
|
||||||
yield pos
|
return result
|
||||||
|
|
||||||
valid_moves = list(generate_moves())
|
|
||||||
return valid_moves
|
|
||||||
|
|
||||||
|
|
||||||
class Ant(Piece):
|
class Ant(Piece):
|
||||||
def __init__(self, p, q, team):
|
def get_valid_jumps(self, spots: dict, s: tuple):
|
||||||
self.p = p
|
return self.crawl(spots, s, set())
|
||||||
self.q = q
|
|
||||||
self.team = team
|
|
||||||
|
|
||||||
def get_valid_jumps(self, board):
|
def crawl(self, spots: dict, s: tuple, visited: set):
|
||||||
visited = set()
|
visited.add(s)
|
||||||
|
result = []
|
||||||
def explore(p, q, depth=0):
|
for i in spots[s][0]:
|
||||||
if depth >= 5: # Limit recursion depth
|
hive = False
|
||||||
return []
|
empty = False
|
||||||
|
if i in visited and spots[i][1]:
|
||||||
valid_moves = []
|
for j in spots[i][0]:
|
||||||
for dp, dq in get_neighbors(0, 0):
|
if empty and hive:
|
||||||
new_p, new_q = p + dp, q + dq
|
break
|
||||||
next_pos = (new_p, new_q)
|
if j in spots[s][0]:
|
||||||
|
if spots[str(j)][1] or visited.get(str(j)):
|
||||||
while (inBoard(next_pos[0], next_pos[1], 13) and
|
empty = True
|
||||||
board[next_pos[0]][next_pos[1]] != "" and
|
else:
|
||||||
next_pos not in visited):
|
hive = True
|
||||||
visited.add(next_pos)
|
if empty and hive:
|
||||||
next_pos = (next_pos[0] + dp, next_pos[1] + dq)
|
result += [i]
|
||||||
|
result += self.ant(spots, i, visited)
|
||||||
if (inBoard(next_pos[0], next_pos[1], 13) and
|
return result
|
||||||
board[next_pos[0]][next_pos[1]] == "" and
|
|
||||||
has_neighbors(next_pos[0], next_pos[1], board, self.p, self.q)):
|
|
||||||
visited.add(next_pos)
|
|
||||||
valid_moves.append(next_pos)
|
|
||||||
valid_moves.extend(
|
|
||||||
explore(next_pos[0], next_pos[1], depth + 1))
|
|
||||||
|
|
||||||
return valid_moves
|
|
||||||
|
|
||||||
return explore(self.p, self.q)
|
|
||||||
|
|
||||||
|
|
||||||
class Player(Base.Board):
|
class Player(Base.Board):
|
||||||
|
@ -227,10 +231,25 @@ class Player(Base.Board):
|
||||||
self, myIsUpper, size, myPieces, rivalPieces
|
self, myIsUpper, size, myPieces, rivalPieces
|
||||||
) # do not change this line
|
) # do not change this line
|
||||||
self.playerName = playerName
|
self.playerName = playerName
|
||||||
self.myIsUpper = myIsUpper
|
|
||||||
self.algorithmName = "just roll the dice, eh?"
|
self.algorithmName = "just roll the dice, eh?"
|
||||||
self.tboard = dict()
|
self.spots = dict()
|
||||||
self.can_place = lambda: sum([v for v in self.myPieces.values()])
|
self.figures_player = list()
|
||||||
|
self.bee = None
|
||||||
|
self.total_piece_count = 18
|
||||||
|
|
||||||
|
@property
|
||||||
|
def all_remaining(self):
|
||||||
|
return self.total_piece_count - sum(self.myPieces.values()+self.rivalPieces.values())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def remaining_pieces(self):
|
||||||
|
return sum(self.myPieces.values())
|
||||||
|
|
||||||
|
def connected(self, graph, cell):
|
||||||
|
for i in graph[str(cell)][0]:
|
||||||
|
if (graph[i][1] == False):
|
||||||
|
break
|
||||||
|
return self.remaining_pieces-1 == cn(graph, i, {str(cell): True, i: True}) + len(graph[i][2])
|
||||||
|
|
||||||
def getAllEmptyCells(self):
|
def getAllEmptyCells(self):
|
||||||
result = []
|
result = []
|
||||||
|
@ -258,160 +277,75 @@ class Player(Base.Board):
|
||||||
"A": Ant,
|
"A": Ant,
|
||||||
}
|
}
|
||||||
|
|
||||||
translated_board = {p: {} for p in board}
|
spots = dict()
|
||||||
total_pieces_count = 0
|
|
||||||
my_pieces_count = 0
|
|
||||||
|
|
||||||
for p, row in board.items():
|
figures_player = list()
|
||||||
for q, tile_content in row.items():
|
|
||||||
if tile_content.isalpha():
|
|
||||||
topmost_piece_letter = tile_content[-1]
|
|
||||||
is_upper = topmost_piece_letter.isupper()
|
|
||||||
piece_class = piece_class_mapping.get(
|
|
||||||
topmost_piece_letter.upper())
|
|
||||||
if piece_class:
|
|
||||||
piece_instance = piece_class(
|
|
||||||
p, q, is_upper == self.myIsUpper)
|
|
||||||
translated_board[p][q] = piece_instance
|
|
||||||
total_pieces_count += 1
|
|
||||||
if is_upper == self.myIsUpper:
|
|
||||||
my_pieces_count += 1
|
|
||||||
else:
|
|
||||||
translated_board[p][q] = topmost_piece_letter
|
|
||||||
else:
|
|
||||||
translated_board[p][q] = tile_content
|
|
||||||
|
|
||||||
return translated_board, total_pieces_count, my_pieces_count
|
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])]
|
||||||
|
spots[(p, q)] = [surr, piece_class_mapping[a[-1].upper()](
|
||||||
|
p, q, self.myColorIsUpper == a[-1].isupper()) if a else None]
|
||||||
|
if (a, self.myColorIsUpper == a.isupper()):
|
||||||
|
figures_player.append((p, q))
|
||||||
|
|
||||||
@property
|
self.spots = spots
|
||||||
def queen_placed(self):
|
self.figures_player = figures_player
|
||||||
return any(isinstance(p, Bee) for p in self.myPieces)
|
|
||||||
|
|
||||||
def random_piece(self, pieces):
|
def get_movable_pieces(self):
|
||||||
return random.choice(pieces) if pieces else None
|
# GET Movable,Empty
|
||||||
|
moveable = {}
|
||||||
def get_piece_class(self, letter):
|
empty_spots = []
|
||||||
return {"Q": Bee, "B": Beetle, "S": Spider, "G": Grasshopper, "A": Ant}.get(
|
for cell in self.figures_player:
|
||||||
letter.upper()
|
# Get all empty cells
|
||||||
)
|
if (self.remaining_pieces != 0):
|
||||||
|
for i in get_neighbors(0, 0):
|
||||||
def get_unplaced_pieces(self):
|
q = (cell[0]+i[0], cell[1]+i[1])
|
||||||
unplaced_pieces = []
|
if q in self.spots.keys():
|
||||||
for piece_letter, count in self.myPieces.items():
|
if self.spots[q][1]:
|
||||||
for _ in range(count):
|
enemy = False
|
||||||
piece_class = self.get_piece_class(piece_letter)
|
for j in get_neighbors(0, 0):
|
||||||
unplaced_pieces.append(piece_class(None, None, True))
|
qq = (q[0]+j[0], q[1]+j[1])
|
||||||
return unplaced_pieces
|
qqs = str(qq)
|
||||||
|
if (self.spots.get(qqs) != None):
|
||||||
def get_valid_placements(self, translated_board, piece_to_place):
|
if (self.spots[qqs][1] == False):
|
||||||
valid_placements = []
|
if (self.spots[qqs][2] == False):
|
||||||
|
enemy = True
|
||||||
# If the board is empty, place the piece at the center.
|
break
|
||||||
if not any(row.values() for row in translated_board.values()):
|
if (not enemy):
|
||||||
return [(3, 6)]
|
empty_spots.append(q)
|
||||||
|
# Get all moves
|
||||||
# Iterate over each tile in the board
|
if self.myMove > 3:
|
||||||
for p, row in translated_board.items():
|
if self.connected(self.spots, cell):
|
||||||
for q, tile_content in row.items():
|
animal = self.spots[cell][2]
|
||||||
# Check if the tile is empty
|
arr = animal.get_valid_jumps(self.spots, cell)
|
||||||
if tile_content == "":
|
if (len(arr) > 0):
|
||||||
# Check if any neighbors are your pieces and none are opponent's pieces
|
moveable[cell] = arr
|
||||||
neighbors = get_neighbors(p, q)
|
return moveable, empty_spots
|
||||||
if any(
|
|
||||||
# Check if the neighboring tile is occupied by your team's piece
|
|
||||||
isinstance(translated_board.get(np, {}).get(nq), Piece) and
|
|
||||||
translated_board[np][nq].team == piece_to_place.team
|
|
||||||
for np, nq in neighbors
|
|
||||||
) and not any(
|
|
||||||
# Check if the neighboring tile is occupied by the opponent's piece
|
|
||||||
isinstance(translated_board.get(np, {}).get(nq), Piece) and
|
|
||||||
translated_board[np][nq].team != piece_to_place.team
|
|
||||||
for np, nq in neighbors
|
|
||||||
):
|
|
||||||
valid_placements.append((p, q))
|
|
||||||
|
|
||||||
return valid_placements
|
|
||||||
|
|
||||||
def mover(self):
|
|
||||||
movable_pieces = list()
|
|
||||||
for row in self.tboard.values():
|
|
||||||
for piece in row.values():
|
|
||||||
if piece and piece.team:
|
|
||||||
jumps = piece.validate_jumps(self.tboard)
|
|
||||||
if jumps:
|
|
||||||
movable_pieces.append((piece, jumps))
|
|
||||||
|
|
||||||
# -> can be None, usually the cause for an error
|
|
||||||
chosen_piece = self.random_piece(movable_pieces)
|
|
||||||
if chosen_piece:
|
|
||||||
new_p, new_q = random.choice(chosen_piece[1])
|
|
||||||
return chosen_piece[0].get_piece_info(self.myIsUpper) + [new_p, new_q]
|
|
||||||
return "failed"
|
|
||||||
|
|
||||||
def placer(self):
|
|
||||||
piece_to_place = self.random_piece(self.get_unplaced_pieces())
|
|
||||||
if piece_to_place:
|
|
||||||
valid_placements = self.get_valid_placements(
|
|
||||||
self.tboard, piece_to_place)
|
|
||||||
new_p, new_q = random.choice(valid_placements)
|
|
||||||
return piece_to_place.get_piece_info(self.myIsUpper)[:1] + [
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
new_p,
|
|
||||||
new_q,
|
|
||||||
]
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
trb, total_pieces_count, my_pieces_count = self.translate_board(
|
|
||||||
self.board)
|
|
||||||
self.tboard = trb
|
|
||||||
p = self
|
|
||||||
return total_pieces_count, my_pieces_count
|
|
||||||
|
|
||||||
def move(self):
|
def move(self):
|
||||||
total_pieces_count, my_pieces_count = self.update()
|
if self.myMove > 80:
|
||||||
|
return []
|
||||||
|
|
||||||
bee_unplaced = "q" in [k.lower() for k in self.myPieces.keys()] and {
|
self.translate_board()
|
||||||
k.lower(): v for k, v in self.myPieces.items()}["q"] != 0
|
|
||||||
|
|
||||||
if bee_unplaced and (total_pieces_count > 3 or random.choice([True, False])):
|
free = [1 for n in get_neighbors(
|
||||||
queen_bee = self.get_piece_class('Q')(None, None, True)
|
self.bee.p, self.bee.q) if self.spots[n][1] == None]
|
||||||
valid_placements = self.get_valid_placements(
|
if sum(free) <= 0:
|
||||||
self.tboard, queen_bee)
|
return []
|
||||||
if valid_placements:
|
|
||||||
new_p, new_q = random.choice(valid_placements)
|
|
||||||
return queen_bee.get_piece_info(self.myIsUpper)[:1] + [None, None, new_p, new_q]
|
|
||||||
|
|
||||||
elif total_pieces_count == 0:
|
if (self.myMove == 0):
|
||||||
piece_to_place = self.random_piece(self.get_unplaced_pieces())
|
animal = random.choice(list(self.myPieces.keys()))
|
||||||
return (
|
if (self.getCount() == 0):
|
||||||
piece_to_place.get_piece_info(self.myIsUpper)[
|
return [animal, None, None, 3, 6]
|
||||||
:1] + [None, None, 3, 6]
|
else:
|
||||||
)
|
choice = random.choice(get_neighbors(3, 6))
|
||||||
|
return [animal, None, None, choice[0], choice[1]]
|
||||||
elif total_pieces_count == 1:
|
|
||||||
for _, row in self.tboard.items():
|
|
||||||
for _, piece in row.items():
|
|
||||||
if piece:
|
|
||||||
adjacent_positions = get_neighbors(piece.p, piece.q)
|
|
||||||
random_position = self.random_piece(adjacent_positions)
|
|
||||||
piece_to_place = self.random_piece(
|
|
||||||
self.get_unplaced_pieces())
|
|
||||||
return (
|
|
||||||
piece_to_place.get_piece_info(self.myIsUpper)[:1]
|
|
||||||
+ [None, None, *random_position]
|
|
||||||
)
|
|
||||||
|
|
||||||
elif self.myMove <= 4:
|
|
||||||
return self.placer()
|
|
||||||
|
|
||||||
choice = random.choice(["move", "place"])
|
|
||||||
print(choice)
|
|
||||||
if choice == "place" and bool(self.can_place):
|
|
||||||
return self.placer()
|
|
||||||
else:
|
|
||||||
return self.mover()
|
|
||||||
|
|
||||||
|
moveable, empty = self.get_movable_pieces()
|
||||||
|
if len(moveable) == 0 and len(empty) == 0: # movement impossible
|
||||||
|
return []
|
||||||
|
|
||||||
def updatePlayers(move, activePlayer, passivePlayer):
|
def updatePlayers(move, activePlayer, passivePlayer):
|
||||||
"""write move made by activePlayer player
|
"""write move made by activePlayer player
|
||||||
|
|
Loading…
Add table
Reference in a new issue