-
Notifications
You must be signed in to change notification settings - Fork 0
Sourcery refactored master branch #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -180,25 +180,23 @@ class _PieceRotationPoint: | |
|
|
||
| def __init__(self, name: str, rot: _PieceRotation, pt: Tile): | ||
| self.id = len(_PIECE_ROTATION_POINTS) | ||
| self.as_set = 1 << self.id | ||
| self.as_set = 1 << self.id | ||
| global _PRP_SET_ALL | ||
| _PRP_SET_ALL |= self.as_set | ||
| self.piece = rot.piece | ||
| self.rotation = rot | ||
| self.piece_id = self.piece.id | ||
| self.name = name | ||
| self.contact = pt | ||
| self.piece = rot.piece | ||
| self.rotation = rot | ||
| self.piece_id = self.piece.id | ||
| self.name = name | ||
| self.contact = pt | ||
| _PIECE_ROTATION_POINTS.append(self) | ||
|
|
||
| dy, dx = pt | ||
|
|
||
| self.tiles: list[Tile] = [] | ||
| self.adjacent: set[Tile] = set() | ||
| self.corners: set[Tile] = set() | ||
|
|
||
| for y, x in rot.tiles: | ||
| self.tiles.append((y - dy, x - dx)) | ||
|
|
||
| self.tiles.extend((y - dy, x - dx) for y, x in rot.tiles) | ||
| for y, x in self.tiles: | ||
| for cy, cx in [(-1, 0), (1, 0), (0, -1), (0, 1)]: | ||
| rel = (y + cy, x + cx) | ||
|
|
@@ -210,7 +208,7 @@ def __init__(self, name: str, rot: _PieceRotation, pt: Tile): | |
| rel = (y + cy, x + cx) | ||
| if rel not in self.tiles and rel not in self.adjacent: | ||
| self.corners.add(rel) | ||
|
|
||
| self.adjacent = sorted(list(self.adjacent)) | ||
| self.corners = sorted(list(self.corners)) | ||
|
|
||
|
|
@@ -222,7 +220,7 @@ def __init__(self, name: str, rot: _PieceRotation, pt: Tile): | |
| _PIECE_ROTATION_POINTS: list[_PieceRotationPoint] = [] | ||
| _PRP_SET_ALL: _PrpSet = 0 | ||
|
|
||
| def _create_piece(name: str, shape: list[list[int]]) -> Piece: | ||
| def _create_piece(name: str, shape: list[list[int]]) -> Piece: | ||
|
Comment on lines
-225
to
+223
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
|
||
| """ | ||
| Adds a piece to the game data, including all rotation and | ||
| horizontal flips of that piece. | ||
|
|
@@ -240,11 +238,11 @@ def _create_piece(name: str, shape: list[list[int]]) -> Piece: | |
| The new id assigned to this piece | ||
| """ | ||
|
|
||
| global PIECE_COUNT | ||
| id = PIECE_COUNT | ||
| PIECE_COUNT += 1 | ||
| pc = _Piece(name, id) | ||
| _PIECES.append(pc) | ||
| global PIECE_COUNT | ||
| id = PIECE_COUNT | ||
| PIECE_COUNT += 1 | ||
| pc = _Piece(name, id) | ||
| _PIECES.append(pc) | ||
| f_names = [] | ||
|
|
||
| def add(suffix: str, arr: np.ndarray): | ||
|
|
@@ -253,8 +251,8 @@ def add(suffix: str, arr: np.ndarray): | |
| for uniqueness across rotations and horizontal flips. | ||
| """ | ||
|
|
||
| rot = None | ||
| unique = True | ||
| rot = None | ||
| unique = True | ||
| cur_rot = len(pc.rotations) | ||
| true_rot = cur_rot # assume rotation is unique | ||
|
|
||
|
|
@@ -268,34 +266,34 @@ def add(suffix: str, arr: np.ndarray): | |
| if rot is None: | ||
| rot = _PieceRotation(name + suffix, pc, len(pc.rotations), arr) | ||
|
|
||
| f_names.append(suffix + "f") | ||
| pc.rotations.append(rot) | ||
| pc.unique.append(unique) | ||
| pc.true_rot.append(true_rot) | ||
| pc.true_rot_for.append([]) | ||
| f_names.append(f"{suffix}f") | ||
| pc.rotations.append(rot) | ||
| pc.unique.append(unique) | ||
| pc.true_rot.append(true_rot) | ||
| pc.true_rot_for.append([]) | ||
| pc.true_rot_for[true_rot].append(cur_rot) | ||
|
|
||
| # original shape, north | ||
| cur = np.array(shape, dtype=np.uint8)[::-1] | ||
| cur = np.array(shape, dtype=np.uint8)[::-1] | ||
| add("n", cur) | ||
|
|
||
| # east | ||
| cur = np.rot90(cur, 1) | ||
| cur = np.rot90(cur, 1) | ||
| add("e", cur) | ||
|
|
||
| # south | ||
| cur = np.rot90(cur, 1) | ||
| cur = np.rot90(cur, 1) | ||
| add("s", cur) | ||
|
|
||
| # west | ||
| cur = np.rot90(cur, 1) | ||
| cur = np.rot90(cur, 1) | ||
| add("w", cur) | ||
|
|
||
| # flipped | ||
| n_unflipped = len(pc.rotations) | ||
| n_unflipped = len(pc.rotations) | ||
| for i in range(n_unflipped): | ||
| add(f_names[i], np.fliplr(pc.rotations[i].shape)) | ||
|
|
||
| return id | ||
|
|
||
| # setup the 21 piece shapes | ||
|
|
@@ -418,9 +416,7 @@ def add(suffix: str, arr: np.ndarray): | |
| for _tile in _pt.adjacent: | ||
| _PRP_WITH_ADJ_REL_COORD[_tile] |= _pt.as_set | ||
|
|
||
| _PRP_REL_COORDS: set[Tile] = set() | ||
| for _pt in _PRP_WITH_REL_COORD: | ||
| _PRP_REL_COORDS.add(_pt) | ||
| _PRP_REL_COORDS: set[Tile] = set(_PRP_WITH_REL_COORD) | ||
|
Comment on lines
-421
to
+419
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lines
|
||
| for _pt in _PRP_WITH_ADJ_REL_COORD: | ||
| _PRP_REL_COORDS.add(_pt) | ||
| _PRP_REL_COORDS = list(_PRP_REL_COORDS) | ||
|
|
@@ -664,10 +660,7 @@ def is_equal(self, value: 'Move') -> bool: | |
| self.to_tile == value.to_tile | ||
|
|
||
| def __eq__(self, value: object) -> bool: | ||
| if isinstance(value, Move): | ||
| return self.is_equal(value) | ||
| else: | ||
| return False | ||
| return self.is_equal(value) if isinstance(value, Move) else False | ||
|
Comment on lines
-667
to
+663
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
|
||
|
|
||
| def to_unique(self) -> 'Move': | ||
| """ | ||
|
|
@@ -714,9 +707,9 @@ def __init__(self, n_players: int): | |
| if n_players < 1 or n_players > 4: | ||
| raise Exception("Number of players must be between 1 and 4") | ||
|
|
||
| self._state: list[_BoardState] = [] | ||
| self._tiles = np.zeros((20, 20), dtype=np.uint8) | ||
| self._n_players = n_players | ||
| self._state: list[_BoardState] = [] | ||
| self._tiles = np.zeros((20, 20), dtype=np.uint8) | ||
| self._n_players = n_players | ||
|
Comment on lines
-717
to
+712
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
|
||
| self._players: list[_Player] = [] | ||
|
|
||
| chars = [ | ||
|
|
@@ -725,12 +718,10 @@ def __init__(self, n_players: int): | |
| 'R', | ||
| 'G' | ||
| ] | ||
| for i in range(n_players): | ||
| self._players.append(_Player(chars[i], i, self)) | ||
|
|
||
| self._players.extend(_Player(chars[i], i, self) for i in range(n_players)) | ||
| self.current_player: Color = BLUE | ||
| self.finished = False | ||
| self.ply = 0 | ||
| self.finished = False | ||
| self.ply = 0 | ||
| self.moves: list[Move] = [] | ||
|
|
||
| def copy_current_state(self) -> 'Board': | ||
|
|
@@ -817,15 +808,15 @@ def is_legal(self, move: Move, for_player: Color=None) -> bool: | |
| # target tile must be empty | ||
| if move.to_tile is None or self.color_at(move.to_tile) != NO_COLOR: | ||
| return False | ||
|
|
||
| # piece must be real | ||
| if move.piece is None or move.piece >= len(_PIECES) or move.piece < 0: | ||
| return False | ||
| return False | ||
| pc = _PIECES[move.piece] | ||
|
|
||
| # rotation must be real | ||
| if move.rotation is None or move.rotation >= len(ROTATIONS) or move.rotation < 0: | ||
| return False | ||
| return False | ||
|
Comment on lines
-820
to
+819
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
This removes the following comments ( why? ): |
||
| pc_rot = pc.rotations[move.rotation] | ||
|
|
||
| # piece rotation must have the contact | ||
|
|
@@ -835,21 +826,16 @@ def is_legal(self, move: Move, for_player: Color=None) -> bool: | |
|
|
||
| # available permutations at the requested tile | ||
| prps = player.corners.get(move.to_tile, None) | ||
| if prps is None: | ||
| return False | ||
|
|
||
| # permutation must fit at the corner square | ||
| return (prps & prp.as_set) != 0 | ||
| return False if prps is None else (prps & prp.as_set) != 0 | ||
|
|
||
| def n_legal_moves(self, unique: bool=True, for_player: Color=None): | ||
| player = self._players[self.current_player if for_player is None else for_player] | ||
| total = 0 | ||
|
|
||
| if unique: | ||
| for prps in player.corners.values(): | ||
| total += prps.bit_count() | ||
| else: | ||
| for prps in player.corners.values(): | ||
| for prps in player.corners.values(): | ||
| if unique: | ||
| total += prps.bit_count() | ||
| else: | ||
|
Comment on lines
-848
to
+838
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
|
||
| while prps != 0: | ||
| # get least significant bit | ||
| prp_id = (prps & -prps).bit_length() - 1 | ||
|
|
@@ -864,45 +850,34 @@ def n_legal_moves(self, unique: bool=True, for_player: Color=None): | |
| return total | ||
|
|
||
| def generate_legal_moves(self, unique: bool=True, for_player: Color=None): | ||
| moves: list[Move] = [] | ||
| moves: list[Move] = [] | ||
| player = self._players[self.current_player if for_player is None else for_player] | ||
|
|
||
| # duplicate for loop so that we don't check the if statement for every permutation | ||
| if unique: | ||
| for to_sq, prps in player.corners.items(): | ||
| while prps != 0: | ||
| # get least significant bit | ||
| prp_id = (prps & -prps).bit_length() - 1 | ||
| # remove it so the next LSB is another PRP | ||
| prps ^= 1 << prp_id | ||
|
|
||
| prp = _PIECE_ROTATION_POINTS[prp_id] | ||
|
|
||
| for to_sq, prps in player.corners.items(): | ||
| # duplicate for loop so that we don't check the if statement for every permutation | ||
| while prps != 0: | ||
| # get least significant bit | ||
| prp_id = (prps & -prps).bit_length() - 1 | ||
| # remove it so the next LSB is another PRP | ||
| prps ^= 1 << prp_id | ||
|
|
||
| prp = _PIECE_ROTATION_POINTS[prp_id] | ||
|
|
||
| # duplicate for loop so that we don't check the if statement for every permutation | ||
| if unique: | ||
| moves.append(Move( | ||
| prp.piece.id, | ||
| prp.rotation.rotation, | ||
| prp.contact, | ||
| to_sq | ||
| )) | ||
| else: | ||
| for to_sq, prps in player.corners.items(): | ||
| while prps != 0: | ||
| # get least significant bit | ||
| prp_id = (prps & -prps).bit_length() - 1 | ||
| # remove it so the next LSB is another PRP | ||
| prps ^= 1 << prp_id | ||
|
|
||
| prp = _PIECE_ROTATION_POINTS[prp_id] | ||
|
|
||
| else: | ||
| # include permutations with non-unique rotations/flips | ||
| for rot in prp.piece.true_rot_for[prp.rotation.rotation]: | ||
| moves.append(Move( | ||
| prp.piece.id, | ||
| rot, | ||
| prp.contact, | ||
| to_sq | ||
| )) | ||
|
|
||
| moves.extend( | ||
| Move(prp.piece.id, rot, prp.contact, to_sq) | ||
| for rot in prp.piece.true_rot_for[prp.rotation.rotation] | ||
| ) | ||
|
Comment on lines
-867
to
+880
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
This removes the following comments ( why? ): |
||
| return moves | ||
|
|
||
| def push_null(self) -> None: | ||
|
|
@@ -998,7 +973,7 @@ def _push_prp(self, move: Move, prp: _PieceRotationPoint, tile: Tile) -> None: | |
|
|
||
| def __str__(self): | ||
| out = "" | ||
|
|
||
|
Comment on lines
-1001
to
+976
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
|
||
| board = self._tiles[::-1] | ||
|
|
||
| chars = None | ||
|
|
@@ -1027,14 +1002,12 @@ def __str__(self): | |
| for player in self._players: | ||
| out += f"{player.name}: {int(player.score)} " | ||
|
|
||
| pcs = [_PIECES[pc] for pc in self._remaining_piece_set(player.id)] | ||
|
|
||
| if len(pcs) > 0: | ||
| if pcs := [_PIECES[pc] for pc in self._remaining_piece_set(player.id)]: | ||
| pcs = sorted(pcs, key=lambda x: x.id) | ||
|
|
||
| out += "( " | ||
| for pc in pcs: | ||
| out += pc.name + " " | ||
| out += f"{pc.name} " | ||
| out += ")\n" | ||
| else: | ||
| out += "( )\n" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,8 +56,7 @@ def compute_elo_adjustment_2(elo1: float, elo2: float, outcome: float, K: int = | |
|
|
||
| p1_win_probability = elo_win_probability(elo1, elo2) | ||
| new_elo1 = elo1 + K * (outcome - p1_win_probability) | ||
| delta_elo = new_elo1 - elo1 | ||
| return delta_elo | ||
| return new_elo1 - elo1 | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
|
||
|
|
||
| def compute_elo_adjustment_n(elos: list[float], scores: list[int], K: int = 32): | ||
| """ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,15 +110,15 @@ def __init__(self, name: str="LargestPiece"): | |
| super().__init__(name) | ||
|
|
||
| def on_search(self, board: tilewe.Board, _seconds: float) -> tilewe.Move: | ||
| moves = board.generate_legal_moves(unique=True) | ||
| moves = board.generate_legal_moves(unique=True) | ||
| random.shuffle(moves) | ||
|
|
||
| best = max(moves, key=lambda m: | ||
| tilewe.n_piece_tiles(m.piece) * 100 + | ||
| tilewe.n_piece_corners(m.piece) * 10 + | ||
| tilewe.n_piece_contacts(m.piece)) | ||
|
|
||
| return best | ||
| return max( | ||
| moves, | ||
| key=lambda m: tilewe.n_piece_tiles(m.piece) * 100 | ||
| + tilewe.n_piece_corners(m.piece) * 10 | ||
| + tilewe.n_piece_contacts(m.piece), | ||
| ) | ||
|
Comment on lines
-113
to
+121
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
|
||
|
|
||
| class MaximizeMoveDifferenceEngine(Engine): | ||
| """ | ||
|
|
@@ -213,24 +213,24 @@ class TileWeightEngine(Engine): | |
| 'turtle': TURTLE_WEIGHTS | ||
| } | ||
|
|
||
| def __init__(self, name: str="TileWeight", weight_map: str='wall_crawl', custom_weights: list[int | float]=None): | ||
| def __init__(self, name: str="TileWeight", weight_map: str='wall_crawl', custom_weights: list[int | float]=None): | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function
|
||
| """ | ||
| Current `weight_map` built-in options are 'wall_crawl' and 'turtle' | ||
| Can optionally provide a custom set of weights instead | ||
| """ | ||
|
|
||
| super().__init__(name) | ||
|
|
||
| if custom_weights is not None: | ||
| if len(custom_weights) != 20 * 20: | ||
| raise Exception("TileWeightEngine custom_weights must be a list of exactly 400 values") | ||
| self.weights = custom_weights | ||
|
|
||
| else: | ||
| if custom_weights is None: | ||
| if weight_map not in self.weight_maps: | ||
| raise Exception("TileWeightEngine given invalid weight_map choice") | ||
| self.weights = self.weight_maps[weight_map] | ||
|
|
||
| elif len(custom_weights) != 20 * 20: | ||
| raise Exception("TileWeightEngine custom_weights must be a list of exactly 400 values") | ||
| else: | ||
| self.weights = custom_weights | ||
|
|
||
| def on_search(self, board: tilewe.Board, _seconds: float) -> tilewe.Move: | ||
|
|
||
| cur_player = board.current_player | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function
_PieceRotationPoint.__init__refactored with the following changes:for-append-to-extend)