chat gpt is probably god? hopefully works, untested
This commit is contained in:
parent
28fcbd4a0d
commit
3412605b1e
5 changed files with 688 additions and 70 deletions
129
assets.py
129
assets.py
|
@ -1,34 +1,137 @@
|
|||
from enum import Enum
|
||||
from collections import deque
|
||||
|
||||
|
||||
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]
|
||||
|
||||
|
||||
class Piece:
|
||||
def get_valid_jumps():
|
||||
pass
|
||||
def get_valid_jumps() -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
pass
|
||||
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) -> list:
|
||||
# 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
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
pass
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
# The beetle can move to an adjacent space whether it is empty or not.
|
||||
valid_moves = get_neighbors(self.p, self.q)
|
||||
return valid_moves
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
pass
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
# Use BFS to find all tiles exactly three moves away
|
||||
start = (self.p, self.q)
|
||||
visited = set() # Keep track of visited tiles
|
||||
queue = deque([(start, 0)]) # Queue of (position, distance)
|
||||
valid_moves = []
|
||||
|
||||
while queue:
|
||||
current_position, current_distance = queue.popleft()
|
||||
if current_distance == 3:
|
||||
# We have found a tile exactly three moves away
|
||||
valid_moves.append(current_position)
|
||||
continue # We don't want to move further from this tile
|
||||
|
||||
if current_position in visited:
|
||||
continue # Already visited this tile
|
||||
|
||||
visited.add(current_position)
|
||||
|
||||
# Get all neighboring positions
|
||||
for neighbor in get_neighbors(*current_position):
|
||||
if (
|
||||
neighbor in board
|
||||
and board[neighbor] == ""
|
||||
and neighbor not in visited
|
||||
):
|
||||
queue.append((neighbor, current_distance + 1))
|
||||
|
||||
return valid_moves
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
pass
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
# Generator function to yield valid moves
|
||||
def generate_moves():
|
||||
# Check each direction for possible jumps
|
||||
for dp, dq in get_neighbors(0, 0): # Use (0, 0) to get direction vectors
|
||||
pos = (self.p + dp, self.q + dq)
|
||||
# Continue in the direction until we find a piece to jump over
|
||||
while pos in board and board[pos] != "":
|
||||
pos = (pos[0] + dp, pos[1] + dq)
|
||||
# If we jumped over at least one piece and landed on an empty space, yield the move
|
||||
if (
|
||||
pos in board
|
||||
and board[pos] == ""
|
||||
and (pos[0] != self.p or pos[1] != self.q)
|
||||
):
|
||||
yield pos
|
||||
|
||||
return list(generate_moves())
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
pass
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
visited = set() # Keep track of visited nodes to prevent cycles
|
||||
|
||||
class PieceTranslator(Enum):
|
||||
q = Bee
|
||||
b = Beetle
|
||||
s = Spider
|
||||
g = Grasshopper
|
||||
a = Ant
|
||||
# Recursive function to explore all valid moves
|
||||
def explore(p, q):
|
||||
for dp, dq in get_neighbors(0, 0): # Get direction vectors
|
||||
new_p, new_q = p + dp, q + dq
|
||||
next_pos = (new_p, new_q)
|
||||
# Continue in this direction while there are pieces to slide around
|
||||
while (
|
||||
next_pos in board
|
||||
and board[next_pos] != ""
|
||||
and next_pos not in visited
|
||||
):
|
||||
visited.add(next_pos)
|
||||
next_pos = (next_pos[0] + dp, next_pos[1] + dq)
|
||||
# If we found an empty space, add it as a valid move and explore from there
|
||||
if next_pos in board and board[next_pos] == "":
|
||||
visited.add(next_pos)
|
||||
yield next_pos
|
||||
# Explore further moves from this new position
|
||||
yield from explore(next_pos[0], next_pos[1])
|
||||
|
||||
# Start exploring from the Ant's current position
|
||||
return list(explore(self.p, self.q))
|
||||
|
|
56
modified_assets.py
Normal file
56
modified_assets.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class Piece:
|
||||
def get_valid_jumps() -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class PieceTranslator(Enum):
|
||||
q = Bee
|
||||
b = Beetle
|
||||
s = Spider
|
||||
g = Grasshopper
|
||||
a = Ant
|
||||
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
def __init__(self, board, p, q, team):
|
||||
self.board = board
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team # 'team' should be 'upper' or 'lower' based on the piece case.
|
||||
|
||||
def get_valid_jumps(self):
|
||||
# The bee can move to an adjacent empty space.
|
||||
valid_moves = []
|
||||
for neighbor in get_neighbors(self.p, self.q):
|
||||
# Check if the neighbor is within the bounds of the board and is empty
|
||||
if neighbor in self.board and self.board[neighbor] == '':
|
||||
valid_moves.append(neighbor)
|
||||
return valid_moves
|
||||
|
||||
|
||||
get_neighbors = <function get_neighbors at 0x7eb8eda90940>
|
||||
|
55
modified_assets_v2.py
Normal file
55
modified_assets_v2.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class Piece:
|
||||
def get_valid_jumps() -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
pass
|
||||
|
||||
|
||||
class PieceTranslator(Enum):
|
||||
q = Bee
|
||||
b = Beetle
|
||||
s = Spider
|
||||
g = Grasshopper
|
||||
a = Ant
|
||||
|
||||
|
||||
|
||||
class Bee(Piece):
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team # 'team' is a boolean where True represents one team and False represents the other.
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
# The bee can move to an adjacent empty space.
|
||||
valid_moves = []
|
||||
for neighbor in get_neighbors(self.p, self.q):
|
||||
# Check if the neighbor is within the bounds of the board and is empty
|
||||
if neighbor in board and board[neighbor] == '':
|
||||
valid_moves.append(neighbor)
|
||||
return valid_moves
|
||||
|
||||
|
||||
def get_neighbors(p, q):
|
||||
get_neighbors.<locals>.<listcomp>
|
335
player.py
335
player.py
|
@ -1,6 +1,7 @@
|
|||
import base as Base
|
||||
import copy, random, time, math
|
||||
from PIL import Image, ImageDraw
|
||||
from collections import deque
|
||||
|
||||
|
||||
# Player template for HIVE --- ALP semestral work
|
||||
|
@ -9,75 +10,296 @@ 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 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]
|
||||
|
||||
|
||||
class Piece:
|
||||
def get_piece_info(self):
|
||||
# Convert the class name to the corresponding letter
|
||||
class_to_letter = {
|
||||
'Bee': 'Q',
|
||||
'Beetle': 'B',
|
||||
'Spider': 'S',
|
||||
'Grasshopper': 'G',
|
||||
'Ant': 'A'
|
||||
}
|
||||
letter = class_to_letter[self.__class__.__name__]
|
||||
if not self.team: # If the piece is not on the player's team, make it lowercase
|
||||
letter = letter.lower()
|
||||
return [letter, self.p, self.q]
|
||||
|
||||
def get_valid_jumps() -> list:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
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) -> list:
|
||||
# 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
|
||||
|
||||
|
||||
class Beetle(Piece):
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
# The beetle can move to an adjacent space whether it is empty or not.
|
||||
valid_moves = get_neighbors(self.p, self.q)
|
||||
return valid_moves
|
||||
|
||||
|
||||
class Spider(Piece):
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
# Use BFS to find all tiles exactly three moves away
|
||||
start = (self.p, self.q)
|
||||
visited = set() # Keep track of visited tiles
|
||||
queue = deque([(start, 0)]) # Queue of (position, distance)
|
||||
valid_moves = []
|
||||
|
||||
while queue:
|
||||
current_position, current_distance = queue.popleft()
|
||||
if current_distance == 3:
|
||||
# We have found a tile exactly three moves away
|
||||
valid_moves.append(current_position)
|
||||
continue # We don't want to move further from this tile
|
||||
|
||||
if current_position in visited:
|
||||
continue # Already visited this tile
|
||||
|
||||
visited.add(current_position)
|
||||
|
||||
# Get all neighboring positions
|
||||
for neighbor in get_neighbors(*current_position):
|
||||
if (
|
||||
neighbor in board
|
||||
and board[neighbor] == ""
|
||||
and neighbor not in visited
|
||||
):
|
||||
queue.append((neighbor, current_distance + 1))
|
||||
|
||||
return valid_moves
|
||||
|
||||
|
||||
class Grasshopper(Piece):
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
# Generator function to yield valid moves
|
||||
def generate_moves():
|
||||
# Check each direction for possible jumps
|
||||
for dp, dq in get_neighbors(0, 0): # Use (0, 0) to get direction vectors
|
||||
pos = (self.p + dp, self.q + dq)
|
||||
# Continue in the direction until we find a piece to jump over
|
||||
while pos in board and board[pos] != "":
|
||||
pos = (pos[0] + dp, pos[1] + dq)
|
||||
# If we jumped over at least one piece and landed on an empty space, yield the move
|
||||
if (
|
||||
pos in board
|
||||
and board[pos] == ""
|
||||
and (pos[0] != self.p or pos[1] != self.q)
|
||||
):
|
||||
yield pos
|
||||
|
||||
return list(generate_moves())
|
||||
|
||||
|
||||
class Ant(Piece):
|
||||
def __init__(self, p, q, team):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.team = team
|
||||
|
||||
def get_valid_jumps(self, board):
|
||||
visited = set() # Keep track of visited nodes to prevent cycles
|
||||
|
||||
# Recursive function to explore all valid moves
|
||||
def explore(p, q):
|
||||
for dp, dq in get_neighbors(0, 0): # Get direction vectors
|
||||
new_p, new_q = p + dp, q + dq
|
||||
next_pos = (new_p, new_q)
|
||||
# Continue in this direction while there are pieces to slide around
|
||||
while (
|
||||
next_pos in board
|
||||
and board[next_pos] != ""
|
||||
and next_pos not in visited
|
||||
):
|
||||
visited.add(next_pos)
|
||||
next_pos = (next_pos[0] + dp, next_pos[1] + dq)
|
||||
# If we found an empty space, add it as a valid move and explore from there
|
||||
if next_pos in board and board[next_pos] == "":
|
||||
visited.add(next_pos)
|
||||
yield next_pos
|
||||
# Explore further moves from this new position
|
||||
yield from explore(next_pos[0], next_pos[1])
|
||||
|
||||
# Start exploring from the Ant's current position
|
||||
return list(explore(self.p, self.q))
|
||||
|
||||
|
||||
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?"
|
||||
|
||||
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, board):
|
||||
# Create a dictionary to map letters to piece classes
|
||||
piece_class_mapping = {
|
||||
'Q': Bee,
|
||||
'B': Beetle,
|
||||
'S': Spider,
|
||||
'G': Grasshopper,
|
||||
'A': Ant
|
||||
}
|
||||
|
||||
translated_board = {p: {} for p in board}
|
||||
total_pieces_count = 0 # To count the total number of pieces on the board
|
||||
my_pieces_count = 0 # To count the number of your pieces on the board
|
||||
|
||||
for p, row in board.items():
|
||||
for q, piece_letter in row.items():
|
||||
if piece_letter.isalpha(): # Check if it's a letter representing a piece
|
||||
is_upper = piece_letter.isupper()
|
||||
piece_class = piece_class_mapping.get(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] = piece_letter
|
||||
else:
|
||||
translated_board[p][q] = piece_letter
|
||||
|
||||
return translated_board, total_pieces_count, my_pieces_count
|
||||
|
||||
@property
|
||||
def queen_placed(self):
|
||||
# Check if the queen is placed
|
||||
return any(isinstance(p, Bee) for p in self.myPieces)
|
||||
|
||||
def get_piece_class(self, letter):
|
||||
# Maps letter to piece class
|
||||
return {
|
||||
'Q': Bee,
|
||||
'B': Beetle,
|
||||
'S': Spider,
|
||||
'G': Grasshopper,
|
||||
'A': Ant
|
||||
}.get(letter)
|
||||
|
||||
def get_unplaced_pieces(self):
|
||||
# Return a list of unplaced pieces
|
||||
unplaced_pieces = []
|
||||
for piece_letter, count in self.myPieces.items():
|
||||
for _ in range(count):
|
||||
piece_class = self.get_piece_class(piece_letter)
|
||||
unplaced_pieces.append(piece_class(None, None, True))
|
||||
return unplaced_pieces
|
||||
|
||||
def move(self):
|
||||
""" return [animal, oldP, oldQ, newP, newQ], or [animal, None, None, newP, newQ] or [] """
|
||||
translated_board, total_pieces_count, _ = self.translate_board(self.board)
|
||||
|
||||
#the following code just randomly places (ignoring all the rules) some random figure at the board
|
||||
emptyCells = self.getAllEmptyCells()
|
||||
|
||||
if len(emptyCells) == 0:
|
||||
return []
|
||||
|
||||
randomCell = emptyCells[ random.randint(0, len(emptyCells)-1) ]
|
||||
randomP, randomQ = randomCell
|
||||
# Randomly choose a piece to place or move
|
||||
def choose_random_piece(pieces):
|
||||
return random.choice(pieces) if pieces else None
|
||||
|
||||
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 we're the first player and no pieces are on the board, place a random piece at the center
|
||||
if total_pieces_count == 0:
|
||||
piece_to_place = choose_random_piece(self.get_unplaced_pieces())
|
||||
return piece_to_place.get_piece_info()[:1] + [None, None, 3, 6] if piece_to_place else []
|
||||
|
||||
# If we're the second player, place next to the first player's piece
|
||||
elif total_pieces_count == 1:
|
||||
for _, row in translated_board.items():
|
||||
for _, piece in row.items():
|
||||
if piece: # Found the first player's piece
|
||||
adjacent_positions = get_neighbors(piece.p, piece.q)
|
||||
random_position = choose_random_piece(adjacent_positions)
|
||||
piece_to_place = choose_random_piece(self.get_unplaced_pieces())
|
||||
return piece_to_place.get_piece_info()[:1] + [None, None, *random_position] if piece_to_place else []
|
||||
|
||||
# After the queen is placed or after the 4th turn, randomly choose between moving and placing a piece
|
||||
elif self.queen_placed or total_pieces_count >= 8:
|
||||
move_or_place = random.choice(["move", "place"])
|
||||
if move_or_place == "move":
|
||||
movable_pieces = [p for p in translated_board.values() if p.get_valid_jumps(translated_board)]
|
||||
chosen_piece = choose_random_piece(movable_pieces)
|
||||
if chosen_piece:
|
||||
new_p, new_q = random.choice(chosen_piece.get_valid_jumps(translated_board))
|
||||
return chosen_piece.get_piece_info() + [new_p, new_q]
|
||||
else:
|
||||
piece_to_place = choose_random_piece(self.get_unplaced_pieces())
|
||||
if piece_to_place:
|
||||
valid_placements = self.get_valid_placements(translated_board, piece_to_place)
|
||||
new_p, new_q = random.choice(valid_placements) if valid_placements else (None, None)
|
||||
return piece_to_place.get_piece_info()[:1] + [None, None, new_p, new_q]
|
||||
|
||||
# If it's not possible to move or place a piece, pass the turn
|
||||
return []
|
||||
|
||||
|
||||
|
||||
#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 ]
|
||||
|
||||
|
||||
|
||||
|
||||
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,32 +307,36 @@ 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 = "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
|
||||
updatePlayers(move, P2, P1) # update P2 and P1 according to the move
|
||||
filename = "move-{:03d}-player2.png".format(moveIdx)
|
||||
P1.saveImage(filename)
|
||||
|
||||
|
@ -121,8 +347,3 @@ if __name__ == "__main__":
|
|||
if moveIdx > 50:
|
||||
print("End of the test game")
|
||||
break
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
183
spider.py
Normal file
183
spider.py
Normal file
|
@ -0,0 +1,183 @@
|
|||
import copy
|
||||
import math
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
|
||||
class Board:
|
||||
def __init__(self, size=0):
|
||||
self.size = size
|
||||
self.board = {}
|
||||
|
||||
# create empty board as a dictionary
|
||||
self.b2 = {}
|
||||
for p in range(-self.size, self.size):
|
||||
for q in range(-self.size, self.size):
|
||||
if self.inBoard(p, q):
|
||||
if not p in self.board:
|
||||
self.board[p] = {}
|
||||
self.board[p][q] = 0
|
||||
|
||||
if not q in self.b2:
|
||||
self.b2[q] = {}
|
||||
self.b2[q][p] = 0
|
||||
|
||||
# this is for visualization and to synchronize colors between png/js
|
||||
self._colors = {}
|
||||
self._colors[-1] = "#fdca40" # sunglow
|
||||
self._colors[0] = "#ffffff" # white
|
||||
self._colors[1] = "#947bd3" # medium purple
|
||||
self._colors[2] = "#ff0000" # red
|
||||
self._colors[3] = "#00ff00" # green
|
||||
self._colors[4] = "#0000ff" # blue
|
||||
self._colors[5] = "#566246" # ebony
|
||||
self._colors[6] = "#a7c4c2" # opan
|
||||
self._colors[7] = "#ADACB5" # silver metalic
|
||||
self._colors[8] = "#8C705F" # liver chestnut
|
||||
self._colors[9] = "#FA7921" # pumpkin
|
||||
self._colors[10] = "#566E3D" # dark olive green
|
||||
|
||||
def inBoard(self, p, q):
|
||||
"""return True if (p,q) is valid coordinate"""
|
||||
return (
|
||||
(q >= 0)
|
||||
and (q < self.size)
|
||||
and (p >= -(q // 2))
|
||||
and (p < (self.size - q // 2))
|
||||
)
|
||||
|
||||
def rotateRight(self, p, q):
|
||||
pp = -q
|
||||
qq = p + q
|
||||
return pp, qq
|
||||
|
||||
def rotateLeft(self, p, q):
|
||||
pp = p + q
|
||||
qq = -p
|
||||
return pp, qq
|
||||
|
||||
def saveImage(self, filename):
|
||||
"""draw actual board to png"""
|
||||
|
||||
cellRadius = 60
|
||||
cellWidth = int(cellRadius * (3**0.5))
|
||||
cellHeight = 2 * cellRadius
|
||||
|
||||
width = cellWidth * self.size + cellRadius * 3
|
||||
height = cellHeight * self.size
|
||||
|
||||
img = Image.new("RGB", (width, height), "white")
|
||||
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
lineColor = (50, 50, 50)
|
||||
|
||||
for p in self.board:
|
||||
for q in self.board[p]:
|
||||
cx = cellRadius * (math.sqrt(3) * p + math.sqrt(3) / 2 * q) + cellRadius
|
||||
cy = cellRadius * (0 * p + 3 / 2 * q) + cellRadius
|
||||
|
||||
pts = []
|
||||
for a in [30, 90, 150, 210, 270, 330]:
|
||||
nx = cx + cellRadius * math.cos(a * math.pi / 180)
|
||||
ny = cy + cellRadius * math.sin(a * math.pi / 180)
|
||||
pts.append(nx)
|
||||
pts.append(ny)
|
||||
color = "#ff00ff" # pink is for values out of range -1,..10
|
||||
if self.board[p][q] in self._colors:
|
||||
color = self._colors[self.board[p][q]]
|
||||
|
||||
draw.polygon(pts, fill=color)
|
||||
pts.append(pts[0])
|
||||
pts.append(pts[1])
|
||||
draw.line(pts, fill="black", width=1)
|
||||
draw.text(
|
||||
[cx - 3, cy - 3], "{} {}".format(p, q), fill="black", anchor="m"
|
||||
)
|
||||
img.save(filename)
|
||||
|
||||
def loadBoard(self, filename):
|
||||
board = {}
|
||||
fread = open(filename, "rt")
|
||||
size = -1
|
||||
for line in fread:
|
||||
p, q, value = list(map(int, line.strip().split()))
|
||||
size = max(size, q)
|
||||
if p not in board:
|
||||
board[p] = {}
|
||||
board[p][q] = value
|
||||
fread.close()
|
||||
self.board = board
|
||||
self.size = size + 1
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
# alternativa: nacteni ze souboru
|
||||
b = Board()
|
||||
b.loadBoard(sys.argv[1])
|
||||
|
||||
# prochazeni radku/sloupce:
|
||||
b_copy = {}
|
||||
for p in b.board:
|
||||
b_copy[p] = {}
|
||||
for q in b.board[p]:
|
||||
b_copy[p][q] = b.board[p][q]
|
||||
if b.board[p][q] == 2:
|
||||
spider_p = p
|
||||
spider_q = q
|
||||
|
||||
smer = ((0, -1), (1, -1), (1, 0), (0, 1), (-1, 1), (-1, 0))
|
||||
|
||||
|
||||
def okoli(b, p, q):
|
||||
o = [0] * 6
|
||||
for i in range(6):
|
||||
p2, q2 = smer[i]
|
||||
if b.inBoard(p + p2, q + q2):
|
||||
o[i] = b.board[p + p2][q + q2]
|
||||
else:
|
||||
o[i] = -1
|
||||
return o
|
||||
|
||||
|
||||
def spider_tah1(p, q, o):
|
||||
mozne_tahy = []
|
||||
for i in range(6):
|
||||
if o[i] == 0 and (
|
||||
(o[(i - 1) % 6] == 0 and o[(i + 1) % 6] == 1)
|
||||
or (o[(i - 1) % 6] == 1 and o[(i + 1) % 6] == 0)
|
||||
):
|
||||
mozne_tahy.append([p + smer[i][0], q + smer[i][1]])
|
||||
return mozne_tahy
|
||||
|
||||
|
||||
o_spider = okoli(b, spider_p, spider_q)
|
||||
print(o_spider)
|
||||
|
||||
komponenty = 0
|
||||
for i in range(6):
|
||||
if o_spider[i] == 1 and o_spider[(i + 1) % 6] != 1:
|
||||
komponenty += 1
|
||||
|
||||
if komponenty > 1:
|
||||
flood_fill()
|
||||
|
||||
pos = [[spider_p, spider_q]]
|
||||
dont_go_back = pos[:]
|
||||
b.board[spider_p][spider_q] = 0
|
||||
|
||||
for i in range(3):
|
||||
pos2 = []
|
||||
print(i, pos)
|
||||
for p, q in pos:
|
||||
mozne = spider_tah1(p, q, okoli(b, p, q))
|
||||
for x in mozne:
|
||||
if not x in dont_go_back:
|
||||
print("jdu vpred", x)
|
||||
pos2.append(x)
|
||||
dont_go_back.append(x)
|
||||
else:
|
||||
print("jdu zpet", x)
|
||||
pos = pos2
|
||||
pos2.sort()
|
||||
print(pos2)
|
Loading…
Add table
Reference in a new issue