> > > > > > > > > > > https://ar.anyone.tech/QkHIWrCSy3iXoP_fS-2snSKIdPYBqGHNmPDya89lWHE#QE8jBZoNzMY9kVYQG13A6oMuI7XhK_sR11WTxCAJ1FqzSRctyUo5iAX14G3o541X#1941075 > > > > > > > > > > > https://ar.anyone.tech/ExicPTy-13WSydg1y-DHVOPtR8L6IMDMiMc7ZAGt2_Q > > > > > > > > > > > > > > > > > > > > > > > > > > > > > class Go: > > > https://ar.anyone.tech/TR4YX5YIB93wYCr6QEa8x8QTmR8OlexgIBDax4pSF88#1kZvnXfgdcSig3uBZIy_KBN6K3YSV5y_qKu5FPWNEnxR-xyl6gSnlaFdxwM_4r4t#1947193 > > https://ar.anyone.tech/Bb-FKg6i6ow-CoAiXBpYFEApMYKKrXjBiPONm5sHJaQ > > Here is the current state of the simple gogame code: > > import numpy as np > > class Go: > EMPTY = ' ' > BLACK = 'X' > WHITE = 'O' > EDGE = '#' > MARK = '\0' > NEIGHBORS = np.array([[-1,0],[0,-1],[1,0],[0,1]]) > def __init__(self, size=10): > self.clear(size) > @property > def board(self): > return self.edged_board[1:-1,1:-1] > @property > def size(self): > return self.board.shape[0] > def __repr__(self): > return '\n'.join([' '.join(row) for row in self.edged_board.T[::-1]]) > def clear(self, size = None): > if size is not None: > self.edged_board = np.full((size+2, size+2), Go.EDGE) > col_axis_len = min(size, 27) > row_axis_len = min(size, 9) > self.edged_board[1:col_axis_len+1,0] = [chr(X) for X in > np.arange(col_axis_len)+ord('A')] > self.edged_board[0,1:row_axis_len+1] = [str(Y) for Y in > np.arange(row_axis_len)+1] > self.board[:] = Go.EMPTY > self.turn = Go.BLACK > self.passes = 0 > self.captures = {Go.BLACK:0, Go.WHITE:0} > def pass_(self, player): > if player != self.turn: > raise ValueError(f"It is {self.turn}'s turn, not {player}'s") > self.turn = Go.BLACK if player == Go.WHITE else Go.WHITE > self.passes += 1 > def naive_score_needslock(self): > unscored_territory = self.board == Go.EMPTY > #while len > @staticmethod > def str2coord(coord : str): > col = ord(coord[0].upper()) > row = coord[1:] > if col < ord('A') or col > ord('Z'): > raise ValueError(f'Column "{col}" not A-Z') > return np.array([col - ord('A'), int(row) - 1]) > @staticmethod > def coord2str(col, row = None): > if row is None: > col, row = col > return chr(ord('A') + col) + str(1 + row) > def move(self, col, row, player): > if player != self.turn: > raise ValueError(f"It is {self.turn}'s turn, not {player}'s") > try: > if row < 0 or col < 0: > raise IndexError() > if self.board[col, row] != Go.EMPTY: > raise ValueError(f"{self.board[col, row]} has already moved > there.") > except IndexError: > raise ValueError(f"{col}, {row} is off the board.") > captures = [] > self.board[col, row] = player > self.turn = Go.BLACK if player == Go.WHITE else Go.WHITE > try: > for neighbor in Go.NEIGHBORS + 1: > colrow = neighbor + [col, row] > if self.edged_board[*colrow] == self.turn: > members, liberties = self.liberties_needslock(*(colrow - > 1)) > if len(liberties) == 0: > captures.extend(members) > self.board[*members.T] = Go.EMPTY > > members, liberties = self.liberties_needslock(col, row) > if len(liberties) == 0: > raise ValueError(f"No liberties for {player}: > {[self.coord2str(*coord) for coord in members]}.") > except: > self.board[col, row] = Go.EMPTY > self.board[*np.array(captures).T] = self.turn > self.turn = player > raise > self.captures[player] += len(captures) > self.passes = 0 > def play(self): > while self.passes < 2: > self.play1() > def play1(self): > print(self) > move = input(f'{self.turn}: ') > if move: > try: > self.move(*self.str2coord(move), self.turn) > except Exception as e: > print(type(e),e) > else: > self.pass_(self.turn) > def liberties_needslock(self, col, row): > colrow = np.array([col, row]) > player = self.board[*colrow] > members = [colrow] > liberties = [] > next_index = 0 > try: > while next_index < len(members): > colrow = members[next_index] > next_index += 1 > self.board[*colrow] = Go.MARK > neighbor_colrows = Go.NEIGHBORS + colrow[None] > neighbors = self.edged_board[*(neighbor_colrows.T + 1)] > if player != Go.EMPTY: > liberties.extend(neighbor_colrows[neighbors == Go.EMPTY]) > else: > liberties.extend(neighbor_colrows[neighbors == Go.BLACK > or neighbors == Go.WHITE]) > new_members = neighbor_colrows[neighbors == player] > members.extend(new_members) > self.board[*new_members.T] = Go.MARK > finally: > self.board[*np.array(members).T] = player > assert (self.edged_board != Go.MARK).all() > return np.array(members), np.array(liberties) > def atari_needslock(self, col, row): > members, liberties = self.liberties_needslock(col, row) > return len(liberties) == 1 > > if __name__ == '__main__': > def main(): > go = Go(5) > go.move(0,0,go.turn) > go.pass_(go.turn) > assert(go.board[0,0] == go.turn) > go.pass_(go.turn) > go.move(1,0,go.turn) > go.move(1,1,go.turn) > go.move(0,1,go.turn) > assert(go.board[0,0] == Go.EMPTY) > go.pass_(go.turn) > go.move(0,0,go.turn) > go.pass_(go.turn) > assert(go.board[0,0] == go.turn) > go.clear() > go.move(0,0,go.turn) > go.move(1,1,go.turn) > go.move(0,1,go.turn) > go.pass_(go.turn) > assert(go.board[0,1] == go.turn) > go.clear() > import traceback > while True: > try: > go.move(np.random.randint(go.size), > np.random.randint(go.size), > go.turn) > except Exception as e: > if "has already moved" in str(e): > continue > traceback.print_exc() > #print(type(e), e, repr(e.__traceback__)) > go.play1() > continue > print(go) > go.play() > > main() > > > https://ar.anyone.tech/avN9UKjg-MuEP6JkPV3-jZ_giKvpalfrMPGg5ejzOmc#solCOXHasYsThT2R-MCJK-qXhMs1n8GfMjKKRUn1f0AlD6Tq1o6PRNJC72TOJ5FC#1947222 > https://ar.anyone.tech/mVPpGtZd5jBVzUc44l6MtY48kfQJdMq6o6OCubaR2eU
7 dimensional checkers. older star trek had "tri-dimensional chess". i played once this game. there are floating board partitions and rules for moving the pieces between the board partitions -- more like 2.5d uncertain ahmmmmm https://ar.anyone.tech/trIB7Z9WE4t7Nf8mXgK6RG2PQoZbzaf6dj3qHmYKKNI#NUmAYW_ulyg0QQu8tMCIYKKTAj5GrngiKK-2VkP5DjZ4k_ZW5Ck3fIRTkY18WTsh#1947263 https://ar.anyone.tech/GqtLDIu6YDgzmW84K4NsdPlgAUx7z4vRL2WQDpXq794 I am not affiliated with https://ar.anyone.tech .
