Files
tic-tac-toe/README.md
2025-10-05 21:23:50 +00:00

300 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# tic-tac-toe
This silly little repo showcases the stupid amount of effort I put into a python course.
You can see in the full spec it just wanted me to write out four silly little functions, but that's not what I did.
Because I was trying to be thorough and not hardcode anything.
I ended up hardcoding the display and logic for who wins, along with poor detection for ties.
Way way way more effort than it was worth and I don't even think it'll get accepted lol.
~~Plot twist: You didn't have to do it at all!!!~~
## Running the program
uhh...okay I guess?
Just download `main.py` and run `py main.py` on Windows or `./main.py` on Linux
## The specific instructions
<details>
<summary>It did NOT tell me to make classes or anything, it just wanted simple programming</summary>
### Scenario
Your task is to write **a simple program which pretends to play *tic-tac-toe* with the user**. To make it all easier for you, we've decided to simplify the game. Here are our assumptions:
- the computer (i.e., your program) should play the game using `'X's`;
- the user (e.g., you) should play the game using `'O'`s;
- the first move belongs to the computer it always puts its first `'X'` in the middle of the board;
- all the squares are numbered row by row starting with `1` (see the example session below for reference)
- the user inputs their move by entering the number of the square they choose the number must be valid, i.e., it must be an integer, it must be greater than `0` and less than `10`, and it cannot point to a field which is already occupied;
- the program checks if the game is over there are four possible verdicts: the game should continue, the game ends with a tie, you win, or the computer wins;
- the computer responds with its move and the check is repeated;
- don't implement any form of artificial intelligence a random field choice made by the computer is good enough for the game.
The example session with the program may look as follows:
```
+-------+-------+-------+
| | | |
| 1 | 2 | 3 |
| | | |
+-------+-------+-------+
| | | |
| 4 | X | 6 |
| | | |
+-------+-------+-------+
| | | |
| 7 | 8 | 9 |
| | | |
+-------+-------+-------+
Enter your move: 1
+-------+-------+-------+
| | | |
| O | 2 | 3 |
| | | |
+-------+-------+-------+
| | | |
| 4 | X | 6 |
| | | |
+-------+-------+-------+
| | | |
| 7 | 8 | 9 |
| | | |
+-------+-------+-------+
+-------+-------+-------+
| | | |
| O | X | 3 |
| | | |
+-------+-------+-------+
| | | |
| 4 | X | 6 |
| | | |
+-------+-------+-------+
| | | |
| 7 | 8 | 9 |
| | | |
+-------+-------+-------+
Enter your move: 8
+-------+-------+-------+
| | | |
| O | X | 3 |
| | | |
+-------+-------+-------+
| | | |
| 4 | X | 6 |
| | | |
+-------+-------+-------+
| | | |
| 7 | O | 9 |
| | | |
+-------+-------+-------+
+-------+-------+-------+
| | | |
| O | X | 3 |
| | | |
+-------+-------+-------+
| | | |
| 4 | X | X |
| | | |
+-------+-------+-------+
| | | |
| 7 | O | 9 |
| | | |
+-------+-------+-------+
Enter your move: 4
+-------+-------+-------+
| | | |
| O | X | 3 |
| | | |
+-------+-------+-------+
| | | |
| O | X | X |
| | | |
+-------+-------+-------+
| | | |
| 7 | O | 9 |
| | | |
+-------+-------+-------+
+-------+-------+-------+
| | | |
| O | X | X |
| | | |
+-------+-------+-------+
| | | |
| O | X | X |
| | | |
+-------+-------+-------+
| | | |
| 7 | O | 9 |
| | | |
+-------+-------+-------+
Enter your move: 7
+-------+-------+-------+
| | | |
| O | X | X |
| | | |
+-------+-------+-------+
| | | |
| O | X | X |
| | | |
+-------+-------+-------+
| | | |
| O | O | 9 |
| | | |
+-------+-------+-------+
You won!
```
### Requirements
Implement the following features:
- the board should be stored as a three-element list, while each element is another three-element list (the inner lists represent rows) so that all of the squares may be accessed using the following syntax:
```
board[row][column]
```
each of the inner list's elements can contain 'O', 'X', or a digit representing the square's number (such a square is considered free)
the board's appearance should be exactly the same as the one presented in the example.
implement the functions defined for you in the editor.
Drawing a random integer number can be done by utilizing a Python function called `randrange()`. The example program below shows how to use it (the program prints ten random numbers from 0 to 8).
[!NOTE] the `from-import` instruction provides access to the `randrange` function defined within an external Python module callled `random`.
```python
from random import randrange
for i in range(10):
print(randrange(8))
```
```python
def display_board(board):
# The function accepts one parameter containing the board's current status
# and prints it out to the console.
def enter_move(board):
# The function accepts the board's current status, asks the user about their move,
# checks the input, and updates the board according to the user's decision.
def make_list_of_free_fields(board):
# The function browses the board and builds a list of all the free squares;
# the list consists of tuples, while each tuple is a pair of row and column numbers.
def victory_for(board, sign):
# The function analyzes the board's status in order to check if
# the player using 'O's or 'X's has won the game
def draw_move(board):
# The function draws the computer's move and updates the board.
```
<details>
<summary>Their solution</summary>
```python
from random import randrange
def display_board(board):
print("+-------" * 3,"+", sep="")
for row in range(3):
print("| " * 3,"|", sep="")
for col in range(3):
print("| " + str(board[row][col]) + " ", end="")
print("|")
print("| " * 3,"|",sep="")
print("+-------" * 3,"+",sep="")
def enter_move(board):
ok = False # fake assumption - we need it to enter the loop
while not ok:
move = input("Enter your move: ")
ok = len(move) == 1 and move >= '1' and move <= '9' # is user's input valid?
if not ok:
print("Bad move - repeat your input!") # no, it isn't - do the input again
continue
move = int(move) - 1 # cell's number from 0 to 8
row = move // 3 # cell's row
col = move % 3 # cell's column
sign = board[row][col] # check the selected square
ok = sign not in ['O','X']
if not ok: # it's occupied - to the input again
print("Field already occupied - repeat your input!")
continue
board[row][col] = 'O' # set '0' at the selected square
def make_list_of_free_fields(board):
free = []
for row in range(3): # iterate through rows
for col in range(3): # iterate through columns
if board[row][col] not in ['O','X']: # is the cell free?
free.append((row,col)) # yes, it is - append new tuple to the list
return free
def victory_for(board,sgn):
if sgn == "X": # are we looking for X?
who = 'me' # yes - it's computer's side
elif sgn == "O": # ... or for O?
who = 'you' # yes - it's our side
else:
who = None # we should not fall here!
cross1 = cross2 = True # for diagonals
for rc in range(3):
if board[rc][0] == sgn and board[rc][1] == sgn and board[rc][2] == sgn: # check row rc
return who
if board[0][rc] == sgn and board[1][rc] == sgn and board[2][rc] == sgn: # check column rc
return who
if board[rc][rc] != sgn: # check 1st diagonal
cross1 = False
if board[2 - rc][2 - rc] != sgn: # check 2nd diagonal
cross2 = False
if cross1 or cross2:
return who
return None
def draw_move(board):
free = make_list_of_free_fields(board) # make a list of free fields
cnt = len(free)
if cnt > 0:
this = randrange(cnt)
row, col = free[this]
board[row][col] = 'X'
board = [ [3 * j + i + 1 for i in range(3)] for j in range(3) ]
board[1][1] = 'X' # set first 'X' in the middle
free = make_list_of_free_fields(board)
human_turn = True # which turn is it now?
while len(free):
display_board(board)
if human_turn:
enter_move(board)
victor = victory_for(board,'O')
else:
draw_move(board)
victor = victory_for(board,'X')
if victor != None:
break
human_turn = not human_turn
free = make_list_of_free_fields(board)
display_board(board)
if victor == 'you':
print("You won!")
elif victor == 'me':
print("I won")
else:
print("Tie!")
```
</details>
</details>