-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: de_soot <78423238+de-soot@users.noreply.github.com>
- Loading branch information
Showing
1 changed file
with
90 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,108 @@ | ||
def display_board(board_: list[list]) -> None: | ||
for i in range(3): | ||
print(" " + board_[i][0] + " │ " + board_[i][1] + " │ " + board_[i][2]) | ||
print("─────┼─────┼─────") | ||
def main() -> None: | ||
if input("Press enter to play a game of Tic-Tac-Toe (A.K.A Noughts-and-Crosses) \ | ||
or type 'quit' to exit the program : ").lower() == "quit": return | ||
|
||
# initialise board | ||
board_length = int(input("Enter the side length of the board : ")) | ||
|
||
while board_length < 1: | ||
board_length = int(input("Enter the side length of the board (must be larger than 0) : ")) | ||
|
||
board_square = board_length * board_length | ||
board_digit = len(str(board_square)) # maximum number of digits on the board | ||
board = create_board(board_length) | ||
|
||
count = 0 | ||
X_or_O = 'X' | ||
has_winner = False | ||
|
||
# game loop start | ||
while not has_winner and count < board_square: | ||
count += 1 | ||
display_board(board, board_length, board_square, board_digit) | ||
x_turn = (count % 2 == 1) | ||
X_or_O = ('X' * x_turn) + ('O' * (not x_turn)) | ||
|
||
print(X_or_O + "'s Turn\n->\t", end = '') | ||
user_input = int(input("Position : ")) | ||
|
||
count -= plot(board, user_input, X_or_O , board_length, board_square) # uncount invalid moves | ||
has_winner = win(board, X_or_O, board_length) # check for winning moves | ||
# game loop end | ||
|
||
# display results | ||
display_board(board, board_length, board_square, board_digit) | ||
print((X_or_O + " is the winner !\n") * has_winner + ("It's a tie !\n") * (not has_winner)) | ||
main() | ||
|
||
|
||
def create_board(board_length: int) -> list[list]: | ||
return [[str(x + y * board_length) for x in range(1, board_length + 1)] for y in range(board_length)] | ||
|
||
|
||
def display_board(board: list[list], board_length: int, board_square: int, board_digit: int) -> None: | ||
print("\n") | ||
|
||
for y in range(board_length): | ||
for x in range(board_length): | ||
board_plot = board[y][x] | ||
# adjust the spacing / padding around the current number displayed | ||
# according to the number of digits in the current number displayed | ||
print(" │ " + board_plot, end = (' ' * (board_digit - len(board_plot)))) | ||
|
||
# scale the board display according to the maximum number of digits of a number on the board | ||
print(("\n ┼──" + '─' * board_digit) + ("┼──" + '─' * board_digit) * (board_length - 1)) | ||
|
||
print("\n") | ||
|
||
|
||
def plot(board_: list[list], input_position_: int, X_or_O_: str) -> int: | ||
if input_position_ < 1 or input_position_ > 9: | ||
def plot(board: list[list], input_position: int, X_or_O: str, board_length: int, board_square: int) -> int: | ||
if input_position < 1 or input_position > board_square: | ||
print("Out of bounds, try again\n") | ||
return 1 | ||
return 1 # uncount move | ||
|
||
y = (input_position_ - 1) // 3 | ||
x = (input_position_ % 3) - 1 | ||
y = (input_position - 1) // board_length | ||
x = (input_position % board_length) - 1 | ||
|
||
board_plot = board[y][x] | ||
|
||
if (board_[y][x] == 'X') or (board_[y][x] == 'O'): | ||
if (board_plot == 'X') or (board_plot == 'O'): | ||
print("Already taken, try again\n") | ||
return 1 | ||
return 1 # uncount move | ||
|
||
board_[y][x] = X_or_O_ | ||
board[y][x] = X_or_O | ||
|
||
return 0 | ||
return 0 # do not uncount move | ||
|
||
|
||
def win(board_: list[list], X_or_O_: str) -> bool: | ||
# 8 total checks for 3 horizontal, 3 vertical, and 2 diagonal rows | ||
return (board_[0][0] == X_or_O_ and board_[0][1] == X_or_O_ and board_[0][2] == X_or_O_) or\ | ||
(board_[1][0] == X_or_O_ and board_[1][1] == X_or_O_ and board_[1][2] == X_or_O_) or\ | ||
(board_[2][0] == X_or_O_ and board_[2][1] == X_or_O_ and board_[2][2] == X_or_O_) or\ | ||
(board_[0][0] == X_or_O_ and board_[1][0] == X_or_O_ and board_[2][0] == X_or_O_) or\ | ||
(board_[0][1] == X_or_O_ and board_[1][1] == X_or_O_ and board_[2][1] == X_or_O_) or\ | ||
(board_[0][2] == X_or_O_ and board_[1][2] == X_or_O_ and board_[2][2] == X_or_O_) or\ | ||
(board_[0][0] == X_or_O_ and board_[1][1] == X_or_O_ and board_[2][2] == X_or_O_) or\ | ||
(board_[2][0] == X_or_O_ and board_[1][1] == X_or_O_ and board_[0][2] == X_or_O_) | ||
|
||
|
||
def main() -> None: | ||
user_input = input("Press enter to play a game of tic-tac-toe / noughts-and-crosses or type 'quit' to exit the program : ").lower() | ||
|
||
if user_input == "quit": | ||
return | ||
def win(board: list[list], X_or_O: str, board_length: int) -> bool: | ||
# check for horizontal win condition | ||
for y in range(board_length): | ||
for x in range(board_length): | ||
win_condition = (board[y][x] == X_or_O) | ||
if not win_condition: break # do not continue checking if impossible | ||
if win_condition: return True # return True if row is complete | ||
|
||
# initialise variables | ||
board = [ | ||
['1', '2', '3'], | ||
['4', '5', '6'], | ||
['7', '8', '9'] | ||
] | ||
# check for vertical win condition | ||
for x in range(board_length): | ||
for y in range(board_length): | ||
win_condition = (board[y][x] == X_or_O) | ||
if not win_condition: break | ||
if win_condition: return True | ||
|
||
count = 0 | ||
X_or_O = 'X' | ||
|
||
# game start | ||
while not win(board, X_or_O) and (count < 9): | ||
count += 1 | ||
display_board(board) | ||
x_turn = (count % 2 == 1) | ||
X_or_O = ( 'X' * (x_turn) ) + ( 'O' * (not x_turn) ) | ||
print(X_or_O + "'s turn") | ||
# check for diagonal win condition | ||
for x in range(board_length): # top left to bottom right (y = x) | ||
win_condition = (board[x][x] == X_or_O) | ||
if not win_condition: break | ||
if win_condition: return True | ||
|
||
input_position = input("Position : ") | ||
for x in range(board_length): # bottom left to top right (y = -x) | ||
win_condition = (board[x][board_length - x - 1] == X_or_O) | ||
if not win_condition: break | ||
if win_condition: return True | ||
|
||
while type(input_position) != "int": | ||
input_position = input("Position (must be an integer) : ") | ||
# return False if no win conditions are met | ||
return False | ||
|
||
count -= plot(board, input_position, X_or_O) # recount if move is invalid | ||
# game end | ||
|
||
# display results | ||
display_board(board) | ||
has_winner = win(board, X_or_O) | ||
print( (X_or_O + " is the winner !\n") * (has_winner) + ("It's a tie !\n") * (not has_winner) ) | ||
main() | ||
|
||
if __name__ == "__main__": | ||
main() | ||
if __name__ == "__main__": main() |