-
Notifications
You must be signed in to change notification settings - Fork 73
Description
Discussed in #358
Originally posted by jdonwells February 23, 2022
I am moving Tic-Tac-Toe from Unit 4 to Unit 3 because it doesn't require loops. I am mixing up several projects as discussed here #349
One of the problems I have in my class is with scaling up. Writing 10 lines of code to demonstrate an individual concept doesn't prepare them to write a 100 line program. What I have started is going through a complete program showing them how I structure it and test it. We don't seem to do that in any of our lectures.
One of my ideas about educating programmers is they must read code. Large amounts of code. Taking them line by line through a 100 line program is my way of doing that.
So here is my lecture for Tic-Tac-Toe as a Unit 3 project. I am showing them how to build up layers of functions with a highlight on abstraction and simplicity. https://docs.google.com/presentation/d/1H1ZRKuW9GWSQjYWRKqNEDrIuTMtJ84FrZ9vB9W6skYc/edit?usp=sharing What I am showing here is a 2x2 version of the code.
They will then need to expand that to a 3x3 version. Because of the layers, much of the code doesn't need to change. That is also something useful for them to discover.
There is one example of recursion in the code. I have changed lesson 3.03 to include recursion as proposed here #355
The 3x3 version I am expecting them to be able to create with the above help is below.
EMPTY = " "
X = " X "
O = " O "
def initialize():
global board, winner
board = [
None, # board[0] is not used.
EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY,
]
winner = None
def show_chart():
print(
" 1 | 2 | 3 ",
"-----------",
" 4 | 5 | 6 ",
"-----------",
" 7 | 8 | 9 ",
sep="\n",
)
def show_board():
print(board[1], board[2], board[3], sep="|")
print("-----------")
print(board[4], board[5], board[6], sep="|")
print("-----------")
print(board[7], board[8], board[9], sep="|")
def announce_winner():
if winner == None:
print("It is a tie!")
elif winner == X:
print("Player X is the winner!")
else:
print("Player O is the winner!")
def make_a_move(player):
move = int(input('Player' + player + 'your move? '))
if 1 <= move and move <= 9 and board[move] == EMPTY:
board[move] = player
else:
print("Not a legal move.")
show_chart()
print()
show_board()
make_a_move(player)
def take_a_turn(player):
global winner
if winner != None: # Stop when someone wins.
return
make_a_move(player)
show_board()
if check_for_winner():
winner = player
def check_for_winner():
return check_across() or check_down() or check_diagonal()
def check_across():
return check(1, 2, 3) or check(4, 5, 6) or check(7, 8, 9)
def check_down():
return check(1, 4, 7) or check(2, 5, 8) or check(3, 6, 9)
def check_diagonal():
return check(1, 5, 9) or check(3, 5, 7)
def check(first_space, second_space, third_space):
return (
board[first_space] != EMPTY
and board[first_space] == board[second_space]
and board[second_space] == board[third_space]
)
def play_a_game():
""" Play a game of Tic-Tac-Toe. For 2 players. Uses the console. """
initialize()
print("Use this chart to select your next move:")
show_chart()
take_a_turn(X) # 9 turns max in a game
take_a_turn(O)
take_a_turn(X)
take_a_turn(O)
take_a_turn(X)
take_a_turn(O)
take_a_turn(X)
take_a_turn(O)
take_a_turn(X)
announce_winner()
play_a_game()
The above code only uses what they currently know. I did not teach them the while loop in Unit 2 because I switched to a project that didn't need a loop. #339