supernovattt 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- supernovattt-1.0.0/LICENSE +17 -0
- supernovattt-1.0.0/PKG-INFO +42 -0
- supernovattt-1.0.0/README.md +28 -0
- supernovattt-1.0.0/pyproject.toml +20 -0
- supernovattt-1.0.0/setup.cfg +4 -0
- supernovattt-1.0.0/supernovattt/__init__.py +6 -0
- supernovattt-1.0.0/supernovattt/brain.py +162 -0
- supernovattt-1.0.0/supernovattt.egg-info/PKG-INFO +42 -0
- supernovattt-1.0.0/supernovattt.egg-info/SOURCES.txt +9 -0
- supernovattt-1.0.0/supernovattt.egg-info/dependency_links.txt +1 -0
- supernovattt-1.0.0/supernovattt.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Supernova
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: supernovattt
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A simple Python Tic Tac Toe game with a Supernova AI bot
|
|
5
|
+
Author: Supernova
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Topic :: Games/Entertainment :: Board Games
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# Supernova TTT
|
|
16
|
+
|
|
17
|
+
A simple Tic Tac Toe game against the Supernova AI bot.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install supernovattt
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Play
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from supernovattt import play
|
|
29
|
+
|
|
30
|
+
play("easy")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Available levels: `easy`, `medium`, `hard`, `impossible`.
|
|
34
|
+
|
|
35
|
+
Default difficulty:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
play()
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The bot uses Minimax with alpha-beta pruning for optimal play
|
|
42
|
+
on the impossible difficulty.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Supernova TTT
|
|
2
|
+
|
|
3
|
+
A simple Tic Tac Toe game against the Supernova AI bot.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install supernovattt
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Play
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from supernovattt import play
|
|
15
|
+
|
|
16
|
+
play("easy")
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Available levels: `easy`, `medium`, `hard`, `impossible`.
|
|
20
|
+
|
|
21
|
+
Default difficulty:
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
play()
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The bot uses Minimax with alpha-beta pruning for optimal play
|
|
28
|
+
on the impossible difficulty.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "supernovattt"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "A simple Python Tic Tac Toe game with a Supernova AI bot"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{name = "Supernova"}]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
16
|
+
"Topic :: Games/Entertainment :: Board Games",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[tool.setuptools.packages.find]
|
|
20
|
+
include = ["supernovattt*"]
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from math import inf
|
|
3
|
+
|
|
4
|
+
EMPTY = " "
|
|
5
|
+
HUMAN = "X"
|
|
6
|
+
BOT = "O"
|
|
7
|
+
|
|
8
|
+
WIN_LINES = (
|
|
9
|
+
(0, 1, 2), (3, 4, 5), (6, 7, 8),
|
|
10
|
+
(0, 3, 6), (1, 4, 7), (2, 5, 8),
|
|
11
|
+
(0, 4, 8), (2, 4, 6),
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
DIFFICULTIES = ("easy", "medium", "hard", "impossible")
|
|
15
|
+
MOVE_ORDER = (4, 0, 2, 6, 8, 1, 3, 5, 7)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def check_winner(board):
|
|
19
|
+
for a, b, c in WIN_LINES:
|
|
20
|
+
if board[a] != EMPTY and board[a] == board[b] == board[c]:
|
|
21
|
+
return board[a]
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def legal_moves(board):
|
|
26
|
+
return [i for i, cell in enumerate(board) if cell == EMPTY]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def terminal_score(board, depth):
|
|
30
|
+
result = check_winner(board)
|
|
31
|
+
if result == BOT:
|
|
32
|
+
return 10 - depth
|
|
33
|
+
if result == HUMAN:
|
|
34
|
+
return depth - 10
|
|
35
|
+
if not legal_moves(board):
|
|
36
|
+
return 0
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def minimax(board, bot_turn, depth=0, alpha=-inf, beta=inf):
|
|
41
|
+
score = terminal_score(board, depth)
|
|
42
|
+
if score is not None:
|
|
43
|
+
return score
|
|
44
|
+
|
|
45
|
+
if bot_turn:
|
|
46
|
+
best = -inf
|
|
47
|
+
for move in MOVE_ORDER:
|
|
48
|
+
if board[move] != EMPTY:
|
|
49
|
+
continue
|
|
50
|
+
board[move] = BOT
|
|
51
|
+
score = minimax(board, False, depth + 1, alpha, beta)
|
|
52
|
+
board[move] = EMPTY
|
|
53
|
+
best = max(best, score)
|
|
54
|
+
alpha = max(alpha, best)
|
|
55
|
+
if alpha >= beta:
|
|
56
|
+
break
|
|
57
|
+
return best
|
|
58
|
+
|
|
59
|
+
best = inf
|
|
60
|
+
for move in MOVE_ORDER:
|
|
61
|
+
if board[move] != EMPTY:
|
|
62
|
+
continue
|
|
63
|
+
board[move] = HUMAN
|
|
64
|
+
score = minimax(board, True, depth + 1, alpha, beta)
|
|
65
|
+
board[move] = EMPTY
|
|
66
|
+
best = min(best, score)
|
|
67
|
+
beta = min(beta, best)
|
|
68
|
+
if alpha >= beta:
|
|
69
|
+
break
|
|
70
|
+
return best
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def best_moves(board):
|
|
74
|
+
scored = []
|
|
75
|
+
for move in legal_moves(board):
|
|
76
|
+
board[move] = BOT
|
|
77
|
+
score = minimax(board, False, 1, -inf, inf)
|
|
78
|
+
board[move] = EMPTY
|
|
79
|
+
scored.append((move, score))
|
|
80
|
+
|
|
81
|
+
if not scored:
|
|
82
|
+
return []
|
|
83
|
+
|
|
84
|
+
top = max(score for _, score in scored)
|
|
85
|
+
return [move for move, score in scored if score == top]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def choose_move(board, difficulty="impossible"):
|
|
89
|
+
difficulty = difficulty.lower()
|
|
90
|
+
if difficulty not in DIFFICULTIES:
|
|
91
|
+
raise ValueError(f"Choose one of: {', '.join(DIFFICULTIES)}")
|
|
92
|
+
if len(board) != 9:
|
|
93
|
+
raise ValueError("Board must contain exactly 9 cells.")
|
|
94
|
+
if any(c not in (EMPTY, HUMAN, BOT) for c in board):
|
|
95
|
+
raise ValueError("Cells must be X, O, or a space.")
|
|
96
|
+
if check_winner(board):
|
|
97
|
+
raise ValueError("The game has already ended.")
|
|
98
|
+
|
|
99
|
+
moves = legal_moves(board)
|
|
100
|
+
if not moves:
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
if difficulty == "easy":
|
|
104
|
+
return random.choice(best_moves(board)) if random.random() < 0.2 else random.choice(moves)
|
|
105
|
+
if difficulty == "medium":
|
|
106
|
+
return random.choice(best_moves(board)) if random.random() < 0.5 else random.choice(moves)
|
|
107
|
+
if difficulty == "hard":
|
|
108
|
+
return random.choice(best_moves(board)) if random.random() < 0.9 else random.choice(moves)
|
|
109
|
+
|
|
110
|
+
return random.choice(best_moves(board))
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def play(difficulty="impossible"):
|
|
114
|
+
difficulty = difficulty.lower()
|
|
115
|
+
if difficulty not in DIFFICULTIES:
|
|
116
|
+
raise ValueError(f"Choose one of: {', '.join(DIFFICULTIES)}")
|
|
117
|
+
|
|
118
|
+
board = [EMPTY] * 9
|
|
119
|
+
print(f"=== SUPERNOVA TTT | {difficulty.upper()} ===")
|
|
120
|
+
print("You are X. Supernova is O. Enter 1-9, or q to quit.")
|
|
121
|
+
|
|
122
|
+
while True:
|
|
123
|
+
print()
|
|
124
|
+
for row in range(3):
|
|
125
|
+
print(" " + " | ".join(
|
|
126
|
+
board[row * 3 + col] if board[row * 3 + col] != EMPTY
|
|
127
|
+
else str(row * 3 + col + 1)
|
|
128
|
+
for col in range(3)
|
|
129
|
+
))
|
|
130
|
+
if row < 2:
|
|
131
|
+
print("---+---+---")
|
|
132
|
+
|
|
133
|
+
result = check_winner(board)
|
|
134
|
+
if result:
|
|
135
|
+
print("Supernova wins!" if result == BOT else "You win!")
|
|
136
|
+
return result
|
|
137
|
+
if not legal_moves(board):
|
|
138
|
+
print("Draw!")
|
|
139
|
+
return "draw"
|
|
140
|
+
|
|
141
|
+
choice = input("\nYour move: ").strip().lower()
|
|
142
|
+
if choice == "q":
|
|
143
|
+
print("Game ended.")
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
move = int(choice) - 1
|
|
148
|
+
except ValueError:
|
|
149
|
+
print("Enter a number from 1 to 9.")
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
if move not in range(9) or board[move] != EMPTY:
|
|
153
|
+
print("Invalid or occupied square.")
|
|
154
|
+
continue
|
|
155
|
+
|
|
156
|
+
board[move] = HUMAN
|
|
157
|
+
if check_winner(board) or not legal_moves(board):
|
|
158
|
+
continue
|
|
159
|
+
|
|
160
|
+
bot_move = choose_move(board, difficulty)
|
|
161
|
+
board[bot_move] = BOT
|
|
162
|
+
print(f"Supernova chose square {bot_move + 1}.")
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: supernovattt
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A simple Python Tic Tac Toe game with a Supernova AI bot
|
|
5
|
+
Author: Supernova
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Topic :: Games/Entertainment :: Board Games
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# Supernova TTT
|
|
16
|
+
|
|
17
|
+
A simple Tic Tac Toe game against the Supernova AI bot.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install supernovattt
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Play
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from supernovattt import play
|
|
29
|
+
|
|
30
|
+
play("easy")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Available levels: `easy`, `medium`, `hard`, `impossible`.
|
|
34
|
+
|
|
35
|
+
Default difficulty:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
play()
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The bot uses Minimax with alpha-beta pruning for optimal play
|
|
42
|
+
on the impossible difficulty.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
supernovattt
|