Skip to content

Commit 5a7365e

Browse files
committed
feat: lambda handler
1 parent 051a665 commit 5a7365e

File tree

9 files changed

+341
-316
lines changed

9 files changed

+341
-316
lines changed

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
tmp/
2+
13
# Byte-compiled / optimized / DLL files
24
__pycache__/
35
*.py[cod]

Diff for: poetry.lock

+288-294
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: pyproject.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ version = "0.1.0"
44
description = "TicTacToe, solved with Reinforcement Learning"
55
authors = ["Luis Da Silva <[email protected]>"]
66
license = "MIT"
7+
packages = [
8+
{ include = "tictactoe" },
9+
]
710

811
[tool.poetry.dependencies]
912
python = "^3.8"
1013
click = "^8.0.3"
11-
numpy = "^1.22.1"
1214
Flask = "^2.0.2"
1315
gunicorn = "^20.1.0"
1416

Diff for: tictactoe/agent/searcher.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from typing import Dict, Optional, Union
22

3-
import numpy as np
4-
53
from tictactoe.agent.base import TrainableAgent
64
from tictactoe.agent.enums import AgentTypes
75
from tictactoe.database import Database
@@ -28,6 +26,7 @@ def __init__(
2826

2927
self.set_player_number(player_number)
3028

29+
@property
3130
def agent_type(self) -> AgentTypes:
3231
return AgentTypes.searcher
3332

@@ -66,9 +65,9 @@ def _evaluate_moves(self, board: Board, current_depth: int) -> Dict[int, int]:
6665
).values()
6766
]
6867
values[move] = (
69-
np.max(future_values)
68+
max(future_values)
7069
if new_board.next_player == self.player_number.value
71-
else np.min(future_values)
70+
else min(future_values)
7271
)
7372
elif new_board.outcome == GameOutcome.DRAW:
7473
values[move] = self.DRAW_REWARD

Diff for: tictactoe/app.py

+5-16
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@
22

33
from flask import Flask, request
44

5-
from tictactoe.agent import ExhaustiveSearchAgent
65
from tictactoe.database import DictDatabase
7-
from tictactoe.environment import (
8-
DICT_DATABASE_FILE,
9-
Board,
10-
GameOutcome,
11-
InvalidBoardError,
12-
)
6+
from tictactoe.environment import DICT_DATABASE_FILE, Board, InvalidBoardError
7+
from tictactoe.game import get_move_response
138

149
app = Flask(__name__)
1510
database = DictDatabase(DICT_DATABASE_FILE)
@@ -32,18 +27,12 @@ def get_action() -> str:
3227
{"action": 2, "result": "NA"}
3328
"""
3429
args = request.args.to_dict()
30+
board_str = args.get("board", "0")
3531

3632
try:
37-
board = Board(args.get("board", "0"))
33+
board = Board(board_str)
3834
except InvalidBoardError as e:
3935
return json.dumps({"error": str(e)})
4036

41-
if board.outcome == GameOutcome.NA:
42-
agent = ExhaustiveSearchAgent(db=database, player_number=board.next_player)
43-
action = agent.get_action(board)
44-
board.make_move(action)
45-
response = {"action": action, "result": board.outcome.name}
46-
else:
47-
response = {"result": board.outcome.name}
48-
37+
response = get_move_response(board, database)
4938
return json.dumps(response)

Diff for: tictactoe/environment/board.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def search_for_winner_in_columns(self) -> GameOutcome:
132132
return GameOutcome.NA
133133

134134
def search_for_winner_in_rows(self) -> GameOutcome:
135-
for row in range(0, N_ROWS ** 2, N_ROWS):
135+
for row in range(0, N_ROWS**2, N_ROWS):
136136
if (
137137
self.state[row] != "0"
138138
and self.state[row] == self.state[row + 1] == self.state[row + 2]

Diff for: tictactoe/game/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
from tictactoe.game.move import get_move_response
12
from tictactoe.game.play import Game

Diff for: tictactoe/game/move.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from typing import Any, Dict
2+
3+
from tictactoe.agent import ExhaustiveSearchAgent
4+
from tictactoe.database import Database
5+
from tictactoe.environment import Board, GameOutcome
6+
7+
8+
def get_move_response(board: Board, database: Database) -> Dict[str, Any]:
9+
if board.outcome == GameOutcome.NA:
10+
agent = ExhaustiveSearchAgent(db=database, player_number=board.next_player)
11+
action = agent.get_action(board)
12+
board.make_move(action)
13+
response = {"action": action, "result": board.outcome.name}
14+
else:
15+
response = {"result": board.outcome.name}
16+
return response

Diff for: tictactoe/lambda.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import json
2+
from typing import Any, Dict
3+
4+
from tictactoe.database import DictDatabase
5+
from tictactoe.environment import DICT_DATABASE_FILE, Board, InvalidBoardError
6+
from tictactoe.game import get_move_response
7+
from pathlib import Path
8+
9+
10+
def move_handler(event: Dict[str, Any], context: Dict[str, Any]) -> str:
11+
board_str = event.get("board", "0")
12+
13+
try:
14+
board = Board(board_str)
15+
except InvalidBoardError as e:
16+
return json.dumps({"error": str(e)})
17+
18+
database = DictDatabase(data_path=DICT_DATABASE_FILE)
19+
database.connect()
20+
21+
response = get_move_response(board, database)
22+
return json.dumps(response)

0 commit comments

Comments
 (0)