Skip to content

Instantly share code, notes, and snippets.

@ArjixWasTaken
Created November 25, 2021 22:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArjixWasTaken/8b1043aa27bf27eab7c42bbceee71800 to your computer and use it in GitHub Desktop.
Save ArjixWasTaken/8b1043aa27bf27eab7c42bbceee71800 to your computer and use it in GitHub Desktop.
Tic Tac Toe! in python
from typing import List
from itertools import cycle
from os import system as run_cmd
def get_player_id():
id = 1
while 1:
yield id
id += 1
get_player_id = get_player_id()
class Player:
def __init__(self, char: str) -> None:
self.id = next(get_player_id)
self.char = char
if len(char) != 1:
raise Exception(
"A player can only have a single symbol as his char.")
if char.isdigit():
raise Exception("A player can't have a digit as his char.")
def ask_input(self, available_moves: List[int]) -> int:
answer = input(
"Player {} - {} - Enter your move: ".format(self.id, self.char))
while 1:
if not answer.isdigit():
print("Invalid choice, you must enter a number.")
answer = input("Player {} - {} - Enter your move ({}): ".format(
self.id,
self.char,
", ".join([str(x) for x in available_moves])
)
)
elif int(answer) not in available_moves:
print("Invalid choice: That move is not available.")
answer = input("Player {} - {} - Enter your move ({}): ".format(
self.id,
self.char,
", ".join([str(x) for x in available_moves])
)
)
else:
break
return int(answer)
class Grid:
def __init__(self) -> None:
self.table = [
[" 1 ", " 2 ", " 3 "],
[" 4 ", " 5 ", " 6 "],
[" 7 ", " 8 ", " 9 "]
]
@property
def is_full(self) -> bool:
return all([
not x.strip().isdigit()
for row in self.table
for x in row
])
def set_cell(self, index: int, char: str):
if index < 4:
self.table[0][index-1] = f" {char} "
elif index < 7:
self.table[1][index-4] = f" {char} "
else:
self.table[2][index-7] = f" {char} "
def get_available_moves(self) -> List[int]:
moves: List[int] = []
for row in self.table:
for col in row:
if col.strip().isdigit():
moves.append(int(col))
return moves
def __repr__(self):
out = "_"*13 + "\n"
out += "|" + "|".join(self.table[0]) + "|" + "\n" + "-"*13 + "\n"
out += "|" + "|".join(self.table[1]) + "|" + "\n" + "-"*13 + "\n"
out += "|" + "|".join(self.table[2]) + "|" + "\n"
out += "‾"*13
return out
class Game:
def __init__(self) -> None:
self.grid = Grid()
self.finished = False
self.player = cycle([Player("x"), Player("o")])
def check_if_win(self, char):
winning_str = str([f" {char} "]*3)
if str(self.grid.table[0]) == winning_str:
return True
elif str(self.grid.table[1]) == winning_str:
return True
elif str(self.grid.table[2]) == winning_str:
return True
rev = list(reversed(list(zip(*self.grid.table))))
if any([str(list(x)) == winning_str for x in rev]):
return True
if str([
self.grid.table[0][0],
self.grid.table[1][1],
self.grid.table[2][2]
]) == winning_str:
return True
elif str([
self.grid.table[0][2],
self.grid.table[1][1],
self.grid.table[2][0]
]) == winning_str:
return True
return False
def run(self):
while not self.finished:
run_cmd("cls || clear")
print(self.grid)
player = next(self.player)
move = player.ask_input(self.grid.get_available_moves())
self.grid.set_cell(move, player.char)
if self.check_if_win(player.char):
print("Congrats! Player {} won!".format(player.id))
break
elif self.grid.is_full:
print("It's a tie!")
break
game = Game()
game.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment