Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 55c38ff

Browse files
committed
added solution for 22
1 parent 7b896db commit 55c38ff

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

22_itictactoe/tictactoe.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Author : Martin Schuh <[email protected]>
4+
Date : 2022-11-26
5+
Purpose: Tic-Tac-Toe (interactive)
6+
"""
7+
8+
from typing import List, NamedTuple, Optional
9+
import re
10+
11+
12+
class State(NamedTuple):
13+
"""Container for storing game state"""
14+
board: List[str] = list('.' * 9)
15+
player: str = 'X'
16+
quit: bool = False
17+
draw: bool = False
18+
error: Optional[str] = None
19+
winner: Optional[str] = None
20+
21+
22+
# --------------------------------------------------
23+
def main() -> None:
24+
"""Make a jazz noise here"""
25+
26+
state = State()
27+
28+
while not any([state.quit, state.draw, state.winner]):
29+
board = state.board
30+
print(format_board(board))
31+
32+
move = input(f'Player "{state.player}", what is your move? '
33+
'[q to quit]: ')
34+
if not re.match(r'[1-9q]', move):
35+
print(f'Invalid cell "{move}", please use 1-9')
36+
continue
37+
38+
if move == 'q':
39+
state = state._replace(quit=True, error=False)
40+
continue
41+
42+
if board[int(move) - 1] in 'XO':
43+
print(f'Cell "{move}" already taken')
44+
state = state._replace(error=True)
45+
continue
46+
47+
board[int(move) - 1] = state.player
48+
49+
# get next player
50+
player = 'O' if state.player == 'X' else 'X'
51+
winner = find_winner(board)
52+
draw = not winner and all(map(lambda i: i in 'XO', board))
53+
state = state._replace(board=board, player=player,
54+
winner=winner, draw=draw)
55+
56+
if not state.quit:
57+
print(format_board(state.board))
58+
if state.winner:
59+
print(f'"{state.winner}" has won!')
60+
if state.draw:
61+
print("It's a draw!")
62+
63+
64+
# --------------------------------------------------
65+
def find_winner(board: List[str]):
66+
"""Returns the winning player of a board, None if there is no one"""
67+
winning = [[0, 1, 2], [3, 4, 5], [6, 7, 8],
68+
[0, 3, 6], [1, 4, 7], [2, 5, 8],
69+
[0, 4, 8], [2, 4, 6]]
70+
71+
for player in 'XO':
72+
for i, j, k in winning:
73+
if ''.join([board[i], board[j], board[k]]) == player * 3:
74+
return player
75+
76+
return None
77+
78+
79+
def format_board(board: List[str]) -> str:
80+
"""Returns string representation of the board"""
81+
82+
cells = [str(i) if c == '.' else board[i-1]
83+
for i, c in enumerate(board, start=1)]
84+
85+
horizontal_rule = '-' * 13
86+
87+
return (f'{horizontal_rule}\n'
88+
f'| {cells[0]} | {cells[1]} | {cells[2]} |\n'
89+
f'{horizontal_rule}\n'
90+
f'| {cells[3]} | {cells[4]} | {cells[5]} |\n'
91+
f'{horizontal_rule}\n'
92+
f'| {cells[6]} | {cells[7]} | {cells[8]} |\n'
93+
f'{horizontal_rule}'
94+
)
95+
96+
97+
# --------------------------------------------------
98+
if __name__ == '__main__':
99+
main()

0 commit comments

Comments
 (0)