""" The naive line counter aims to calculate the best move by comparing the lines and checking how many are filled. """ from __future__ import annotations import random from .agent import Agent, Payload class NaiveLineCounter(Agent): """ Tic-tac-toe has 8 possible lines where you can get 3 in a row. For all 8 lines, count how many would benefit from the addition of a single sign. In priority, count how many lines are added. """ def __init__(self) -> None: super().__init__( name="Naive line counter", author="Bram", version="1.0.0", profile={}, ) self.add_tic_tac_toe(on_move=self.play_tic_tac_toe, profile={}) def play_tic_tac_toe(self, payload : Payload) -> Payload: """ For each line: [X][X][_] -> 3 in a row [O][O][_] -> ruin an opponent's 3 in a row [X][_][ ] -> 2 in a row [O][_][ ] -> ruin an opponent's 2 in a row [_][ ][ ] -> 1 in a row Count how many they occur, then sort based on priority. """ lines = [ [ 1, 2, 3, ], [ 4, 5, 6, ], [ 7, 8, 9, ], [ 1, 4, 7, ], [ 2, 5, 8, ], [ 3, 6, 9, ], [ 1, 5, 9, ], [ 3, 5, 7, ], ] my_piece = payload["your_token"] moves, value = [], ( 0, 0, 0, 0, 0 ) for i in range(1, 10): i_val = field_score(payload=payload, field=i, my_piece=my_piece) if i_val > value: moves, value = [i], i_val elif i_val == value: moves.append(i) return dict(move=random.choice(moves)) def field_score(payload : Payload, field : int, my_piece : str) -> tuple[int, int, int, int, int]: """ Determine the score of a specific field in the grid. """ a, b, c, d, e = 0, 0, 0, 0, 0 lines = [ [ 1, 2, 3, ], [ 4, 5, 6, ], [ 7, 8, 9, ], [ 1, 4, 7, ], [ 2, 5, 8, ], [ 3, 6, 9, ], [ 1, 5, 9, ], [ 3, 5, 7, ], ] if payload[str(field)] != "": return ( a, b, c, d, e ) for line in lines: if field not in line: continue values = [ payload[str(f)] for f in line if field != f ] x = values.count("X") o = values.count("O") s = ( x, o ) if my_piece == "X" else ( o, x ) match s: case ( 2, 0 ): a += 1 case ( 0, 2 ): b += 1 case ( 1, 0 ): c += 1 case ( 0, 1 ): d += 1 case ( 0, 0 ): e += 1 case ( 1, 1 ): pass case _: raise ValueError( f"Unknown number of items: {s}" ) return ( a, b, c, d, e )