On Fri, Jun 26, 2026 at 09:01:20PM -0400, funkymail via cypherpunks wrote:
On Fri, Jun 26, 2026 at 08:43:14PM -0400, funkymail via cypherpunks wrote:
On Fri, Jun 26, 2026 at 08:35:55PM -0400, funkymail via cypherpunks wrote:
On Fri, Jun 26, 2026 at 08:31:23PM -0400, funkymail via cypherpunks wrote:
On Fri, Jun 26, 2026 at 08:28:11PM -0400, funkymail via cypherpunks wrote:
On Fri, Jun 26, 2026 at 08:25:05PM -0400, funkymail via cypherpunks wrote:
On Fri, Jun 26, 2026 at 08:21:01PM -0400, funkymail via cypherpunks wrote: > On Fri, Jun 26, 2026 at 08:13:40PM -0400, funkymail via cypherpunks wrote: > > > > https://ar.anyone.tech/QkHIWrCSy3iXoP_fS-2snSKIdPYBqGHNmPDya89lWHE#QE8jBZoNz... > > > > https://ar.anyone.tech/ExicPTy-13WSydg1y-DHVOPtR8L6IMDMiMc7ZAGt2_Q > > > > > > > > class Go:
https://ar.anyone.tech/TR4YX5YIB93wYCr6QEa8x8QTmR8OlexgIBDax4pSF88#1kZvnXfgd... 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#solCOXHas... https://ar.anyone.tech/mVPpGtZd5jBVzUc44l6MtY48kfQJdMq6o6OCubaR2eU I am not affiliated with https://ar.anyone.tech .