Compare commits
No commits in common. "fc8375e25162013ec28f38656759c49b1ee6ce18" and "6cd1ec9c9763ae170b321240f9dbc778320474e1" have entirely different histories.
fc8375e251
...
6cd1ec9c97
|
|
@ -10,9 +10,11 @@
|
|||
from .agent import Agent
|
||||
from .chaos import AgentOfChaos
|
||||
from .mute import MuteAgent
|
||||
from .remote import RemoteAgent
|
||||
|
||||
__all__ = [
|
||||
"Agent",
|
||||
"AgentOfChaos",
|
||||
"MuteAgent",
|
||||
"RemoteAgent",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
"""
|
||||
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 )
|
||||
|
|
@ -19,10 +19,7 @@ RUN pip install --no-cache-dir --no-index --find-links=/wheels \
|
|||
-r requirements-pyserver.txt && rm -rf /wheels
|
||||
|
||||
# Install PyServer code
|
||||
COPY agents/ agents/
|
||||
COPY pyserver/ pyserver/
|
||||
COPY server.py .
|
||||
|
||||
ENV CONTAINERIZED=1
|
||||
|
||||
CMD ["python", "server.py"]
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from flask import Flask, jsonify, request
|
||||
from agents import Agent
|
||||
from typing import Any
|
||||
|
|
@ -26,7 +24,6 @@ class PyServer:
|
|||
:param import_name: Flask application import name
|
||||
:type import_name: str
|
||||
"""
|
||||
self.containerized : bool = bool(int(os.environ.get("CONTAINERIZED", "0")))
|
||||
self.agent = agent
|
||||
self.app = Flask(import_name)
|
||||
|
||||
|
|
@ -52,7 +49,6 @@ class PyServer:
|
|||
|
||||
d = { **self.agent.profile, **d }
|
||||
|
||||
d["me.noordstar.peanuts.containerized"] = self.containerized
|
||||
d["games"] = {}
|
||||
for game, (profile, _) in self.agent.registered_games.items():
|
||||
d["games"][game] = profile
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ from __future__ import annotations
|
|||
|
||||
import agents
|
||||
|
||||
from agents.naive_line_counter import NaiveLineCounter
|
||||
from pyserver import PyServer
|
||||
|
||||
def main() -> int:
|
||||
|
|
@ -16,7 +15,7 @@ def main() -> int:
|
|||
:return: Exit code
|
||||
:rtype: int
|
||||
"""
|
||||
player = PyServer(NaiveLineCounter())
|
||||
player = PyServer(agents.RemoteAgent(url="https://bmt001.noordstar.me/"))
|
||||
|
||||
# Start listening for games
|
||||
player.start(
|
||||
|
|
|
|||
Loading…
Reference in New Issue