diff --git a/generator/__main__.py b/generator/__main__.py new file mode 100644 index 0000000..e110fa6 --- /dev/null +++ b/generator/__main__.py @@ -0,0 +1,39 @@ +from jinja2 import Environment, select_autoescape, FileSystemLoader + +from generator.model import Board, NOT_DETERMINED +from generator.tictactoe import calculate_best_move + +env = Environment( + loader=FileSystemLoader(["./generator"]), + autoescape=select_autoescape() +) +template = env.get_template("template.html") + + +def render_board(initial_prefix, prefix, board): + with open("output/" + prefix + ".html", "w") as file: + file.write(template.render(board=board, prefix=prefix, reset=initial_prefix + ".html")) + pass + + +def generate_options(initial_prefix, prefix, board): + render_board(initial_prefix, prefix, board) + + if board.winner() == NOT_DETERMINED: + for move in board.moves(): + future = board.apply(move) + response, _ = calculate_best_move(future) + + print(prefix, move, response) + + generate_options( + initial_prefix, + prefix + str(move), + future.apply(response) if response else future + ) + + +if __name__ == "__main__": + board = Board() + + generate_options("g", "g", board) diff --git a/generator/model.py b/generator/model.py new file mode 100644 index 0000000..2e53931 --- /dev/null +++ b/generator/model.py @@ -0,0 +1,104 @@ +import copy + +FREE = 0 +DRAW = 0 +NOT_DETERMINED = -1 + +WIN = 1 +LOSS = -1 + +PLAYER1 = 1 +PLAYER2 = 2 + + +class Move: + def __init__(self, x, y): + self.x = x + self.y = y + + def __str__(self): + return str(self.x) + str(self.y) + + def __repr__(self): + return str(self) + + +class Board: + field = [ + [FREE, FREE, FREE], + [FREE, FREE, FREE], + [FREE, FREE, FREE] + ] + current = PLAYER1 + + def moves(self): + moves = [] + for y in range(3): + for x in range(3): + if self.field[y][x] == FREE: + moves.append(Move(x, y)) + + return moves + + def apply(self, move): + board = Board() + board.field = copy.deepcopy(self.field) + board.field[move.y][move.x] = self.current + board.current = PLAYER2 if self.current == PLAYER1 else PLAYER1 + return board + + def winner(self): + for y in range(3): + player = self.field[y][0] + won = True + if player != FREE: + for x in range(3): + if self.field[y][x] != player: + won = False + break + if won: + return player + + for x in range(3): + player = self.field[0][x] + won = True + if player != FREE: + for y in range(3): + if self.field[y][x] != player: + won = False + break + if won: + return player + + player = self.field[0][0] + won = True + if player != FREE: + for i in range(3): + if self.field[i][i] != player: + won = False + break + if won: + return player + + player = self.field[2][0] + won = True + if player != FREE: + for i in range(3): + if self.field[2 - i][i] != player: + won = False + break + if won: + return player + + for y in range(3): + for x in range(3): + if self.field[y][x] == FREE: + return NOT_DETERMINED + + return DRAW + + def visualize(self): + for y in range(3): + for x in range(3): + print(self.field[y][x], end=' ') + print("") diff --git a/generator/template.html b/generator/template.html new file mode 100644 index 0000000..b54de3a --- /dev/null +++ b/generator/template.html @@ -0,0 +1,52 @@ + +{{- "" -}} +
{{- "" -}} ++ {%- set cell = board.field[y][x] -%} + {%- if cell != 0 -%} + {{- 'X' if cell == 1 else 'O' -}} + {%- elif winner != -1 -%} + + {%- else -%} + ? + {%- endif -%} + | + {%- endfor -%} +