# Tic tac toe

This a problem set for you to work through [1]

This is a problem set. Some of these are easy, others are far more difficult. The purpose of these problems sets are:

1. to build your skill applying computational thinking to a problem
2. to assess your knowledge and skills of different programming practices

## What is this problem set trying to do

This problem set is testing your computational thinking, your skill and understanding of lists, and your skill and understanding of loops

## The Problem

Your program must do three things:

1. it must allow a human to play against a computer a game of tic tac toe
1. your program must have win and lose conditions
2. it must draw a tic tac to board, updated with x's and O's as the computer and human play.
3. It must follow the rules of tic tac toe

## Hacker edition

In the hacker version:

• Your program should be good at playing tic tac toe

## Python Version

```import random

# initialization stuff here:

board = [1,2,3,4,5,6,7,8,9]
computerSpaces = []
humanSpaces =[1]
game = 0

def drawPieces(position):
if position in humanSpaces:
return "X"
elif position in computerSpaces:
return "O"
else:
return position

# this function draws the board
def drawBoard():
print("")
print("")
print(" ",drawPieces(1),"  |   (2)    | (3) ")
print("     |          |     ")
print("----------------------")
print(" (4) |   (5)    | (6) ")
print("     |          |     ")
print("----------------------")
print(" (7) |   (8)    | (9) ")
print("     |          |     ")

return

# this function manages player moves
def playerMove(move):
return

# this function manages computer moves
def computerMove(computerMove):
return

while True:
print(drawBoard())
move=input("Please choose a move (99 to quit): ")
if move == "99":
break
elif str(move) in computerSpaces or str(move) in humanSpaces:
print("this is a invalid move")
else:
humanSpaces.append(move)
print(humanSpaces)
# playerMove(move)
```

## How you will be assessed

Scope

• To what extent does your code implement the features required by our specification?
• To what extent is there evidence of effort?

Correctness

• To what extent did your code meet specifications?
• To what extent did your code meet unit tests?
• To what extent is your code free of bugs?

Design

• To what extent is your code written well (i.e. clearly, efficiently, elegantly, and/or logically)?
• To what extent is your code eliminating repetition?
• To what extent is your code using functions appropriately?

Style

• To what extent is your code commented?
• To what extent are your variables well named?
• To what extent do you adhere to style guide?

## A possible solution

Click the expand link to see one possible solution in Python, but NOT before you have tried and failed!

```import PySimpleGUI as sg
import random

from PySimpleGUI.PySimpleGUI import WINDOW_CLOSED
sg.theme('Python')

turn = 1
turn2 = 0
board = [0,1,2,3,4,5,6,7,8]
win_p = [
[0,1,2],
[3,4,5],
[6,7,8],
[0,3,6],
[1,4,7],
[2,5,8],
[0,4,8],
[2,4,6]
]

def draw_board():
print(board[0],board[1],board[2])
print(board[3],board[4],board[5])
print(board[6],board[7],board[8])

computer_first_move = random.choice(board)
board[computer_first_move-1] = "X"

layout = [
[sg.Text('The turn is:',font=("Helevtica", 25), key='D'), sg.Text(turn, key = 'D1',font=("Helevtica", 25))],
[sg.Button(board[0],font=("Helevtica", 50),key = '0'),sg.Button(board[1],font=("Helevtica", 50),key = '1'),sg.Button(board[2],font=("Helevtica", 50),key = '2')],
[sg.Button(board[3],font=("Helevtica", 50),key = '3'),sg.Button(board[4],font=("Helevtica", 50),key = '4'),sg.Button(board[5],font=("Helevtica", 50),key = '5')],
[sg.Button(board[6],font=("Helevtica", 50),key = '6'),sg.Button(board[7],font=("Helevtica", 50),key = '7'),sg.Button(board[8],font=("Helevtica", 50),key = '8')],
]

window = sg.Window('TicTacToe', layout)

while True:
if event == WINDOW_CLOSED:
break

print(event)

for i in range(0,9):
if str(event) == str(board[i]):
window[str(i)].update('O')
board[i] = "O"
draw_board()

computer_turn = True
count2 = 0
win = 0
loss = 0

#================================================================

if(event):
for x in win_p:
count = 0
count1 = 0
poss = []

for i in x:
if(board[i]) == "O":
count = count +1

if count == 3:
win += 1
break

if win == 1:
draw_board()
sg.popup('YOU WON!')

# #================================================================

for x in win_p:
count = 0
count1 = 0
poss = []

for i in x:
if(board[i]) == "O":
count = count +1

if count == 0:
for i in x:
if(board[i]) == "X":
count1 = count1 + 1

if (count1 == 2) and (computer_turn == True):
for i in x:
if(board[i]) != "X":
window[str(i)].update('X')
board[i] = "X"
loss = loss + 1
break
computer_turn == False

if loss == 1:
draw_board()
sg.popup("YOU LOST")
break

#=============================================================================

for x in win_p:
count = 0
count1 = 0
poss = []

for i in x:
if(board[i]) == "O":
count = count +1

if count == 2 and computer_turn == True:
for i in x:
if(board[i]) != "O" and (board[i]) != "X":

board[i] = "X"
window[str(i)].update('X')

computer_turn = False

# #=============================================================================

for x in win_p:
count = 0
count1 = 0
poss = []

for i in x:
if(board[i]) == "O":
count = count +1

if count == 0:
for i in x:
if(board[i]) == "X":
count1 =+ 1
if (count1 == 1) and (computer_turn == True):
print(x)
for i in x:
print(i,board[i])
if(board[i]) != "X":
poss.append(i)
print(poss)
q = random.choice(poss)
board[q] = "X"
window[str(q)].update('X')

computer_turn = False

for i in range(0,9):
if board[i] != i:
count2 = count2 + 1
print("count2:",count2)

if count2 == 8:
for i in range(0,9):
if board[i] == i:
board[i] = "X"
window[str(i)].update('X')

draw_board()
sg.popup("Tie")
break
if count2 == 9:
draw_board()
sg.popup("Tie")
break

print("="*25)
draw_board()
turn = turn+1
window['D1'].update(turn)
print("loop")

# ====================== another example below ==================================

import os, random, time

#setting
table = ["\033[1;30m1\033[0m","\033[1;30m2\033[0m","\033[1;30m3\033[0m","\033[1;30m4\033[0m","\033[1;30m5\033[0m","\033[1;30m6\033[0m","\033[1;30m7\033[0m","\033[1;30m8\033[0m","\033[1;30m9\033[0m"]
# table1 = ["\033[1;30m1\033[0m","\033[1;30m2\033[0m","\033[1;30m3\033[0m","\033[1;30m4\033[0m","\033[1;30m5\033[0m","\033[1;30m6\033[0m","\033[1;30m7\033[0m","\033[1;30m8\033[0m","\033[1;30m9\033[0m"]
ending = False
def drawing():
os.system('clear')
print(f"{table[0]}   {table[1]}   {table[2]}")
print(f"\n{table[3]}   {table[4]}   {table[5]}")
print(f"\n{table[6]}   {table[7]}   {table[8]}")

#event loop
while True:
drawing()
a=0
b=0

#win or lose or draw
# if any(table1) in table:
#     print("You draw!")
#     ending = True
if table[0] == table[4] == table[8]:
if table[0] == 'O':
print("You Win!")
ending = True
else:
print("You Lose!")
ending = True
elif table[2] == table[4] == table[6]:
if table[2] == 'O':
print("You Win!")
ending = True
else:
print("You Lose!")
ending = True
for i in range(3):
if table[a] == table[a+1] == table[a+2]:
if table[a] == 'O':
print("You Win!")
ending = True
else:
print("You Lose!")
ending = True
elif table[b] == table[b+3] == table[b+6]:
if table[b] == 'O':
print("You Win!")
ending = True
else:
print("You Lose!")
ending = True
a += 3
b += 1

if ending == True:
break

#user's turn
user_move = int(input("\nplace number: "))
if table[user_move-1] != 'O' and table[user_move-1] != 'X':
table[user_move-1] = 'O'
else:
input("that's not proper place...")
continue
drawing()

#computer's turn
while True:
a=0
b=0
## simple UI logic
# if table[4] == 'X' or 'O':
#     if table[4] == table[0] or table[4] == table[8]:
#         if table[0] == 'O' or 'X':
#             table[8] = 'X'
#             break
#         elif table[8] == 'O' or 'X':
#             table[0] = 'X'
#             break
#     elif table[4] == table[2] or table[4] == table[6]:
#         if table[2] == 'O' or 'X':
#             table[6] == 'X'
#             break
#         elif table[6] == 'O' or 'X':
#             table[2] == 'X'
#             break
#     else:
#         pass

# for i in range(3):
#     if table[a] == table[a+1] or table[a+1] == table[a+2] and table[a+1] == 'X' or 'O':
#         if table[a] == 'O' or 'X':
#             table[a] = 'X'
#             logic_loop = False
#         if table[a+2] == 'O' or 'X':
#             table[a+2] = 'X'
#             break
#     elif table[b] == table[b+3] or table[b+3] == table[b+6] and table[b+3] == 'X' or 'O':
#         if table[b] == 'O' or 'X':
#             table[b] = 'X'
#             break
#         if table[b+6] == 'O' or 'X':
#             table[b+6] = 'X'
#             break
#     else:
#         pass
#     a += 3
#     b += 1

com_move = random.randrange(1,10)
if table[com_move-1] != 'O' and table[com_move-1] != 'X':
table[com_move-1] = 'X'
break
else:
continue

time.sleep(0.7)

# ============================ second example below ====================
import random

# initialization stuff here:

board = [1,2,3,4,5,6,7,8,9]
computerSpaces = []
humanSpaces =[]
game = 0

# this function draws pieces on the board.
def drawPieces(position):
if position in humanSpaces:
return "X"
elif position in computerSpaces:
return "O"
else:
return position

# this function manages player moves
def playerMove(move):
humanSpaces.append(move)
humanSpaces.sort()
board.remove(int(move))
return

# this function manages computer moves
def computerMove():
# we choose a possible move from any moves left in the list board
move=random.choice(board)
# we append the move we just made into a list
computerSpaces.append(str(move))
# we sort the list because our win conditions are in a certain order. 1,2,3 is a win, but 3,2,1 isn't.
# sorting is a bit of a hack (there might be a better way to test for membership in a list iregardless of order)
computerSpaces.sort()
# finally, we remove the place from our list keeping track of the places.
board.remove(move)
return

# this function draws the board
def drawBoard():
print("")
print("")
print(" ",drawPieces('1'),"  |   ",drawPieces('2'),"    | ",drawPieces('3'), "  ")
print("      |          |     ")
print("----------------------")
print(" ",drawPieces('4'),"  |   ",drawPieces('5'),"    | ",drawPieces('6'), "  ")
print("      |          |     ")
print("----------------------")
print(" ",drawPieces('7'),"  |   ",drawPieces('8'),"    | ",drawPieces('9'), "  ")
print("      |          |     ")
return

# this functions looks for win win conditions
def winConditions():
winConditions = [['1','2','3'],['4','5','6'],['7','8','9'],['1','5','9'],['3','5','7'],['1','4','7'],['2','5','8'],['3','6','9']]
if any(humanSpaces) in winConditions:
print("human won")
raise SystemExit
elif any(computerSpaces) in winConditions:
print("commputer won")
raise SystemExit
return

# main game loop
while True:
print(board)
print(drawBoard())
move=input("Please choose a move (99 to quit): ")
if move == "99":
break
elif str(move) in computerSpaces or str(move) in humanSpaces:
print("this is a invalid move")
else:
playerMove(move)
computerMove()
winConditions()
print(humanSpaces)
print(computerSpaces)
# playerMove(move)

#
# ==========================.  example three below ==================
#

import itertools
import random
import os

def check_win(board):
for j in [0,3,6]:
if board[j] == board[j+1] and board[j] == board[j+2] and board[j] != "-":
return board[j]
for j in [0,1,2]:
if board[j] == board[j+3] and board[j] == board[j+6] and board[j] != "-":
return board[j]
if board[0] == board[4] and board[0] == board[8] and board[0] != "-":
return board[0]
if board[2] == board[4] and board[2] == board[6] and board[2] != "-":
return board[2]
return "draw"

def calculate(stones):
table = ["-", "-", "-", "-", "-", "-", "-", "-", "-"]
pl_1 = [stones[0],stones[2],stones[4],stones[6],stones[8]]
for j in range(9):
k = stones[j]
if k in pl_1:
table[k-1] = "1"
else:
table[k-1] = "2"
result = check_win(table)
if result == "1":
return "player 1"
elif result == "2":
return "player 2"
else:
pass
return "draw"

def find_ans(log,turn):
INF = 10**10
rates = []
left = [1,2,3,4,5,6,7,8,9]
for i in log:
left.remove(i)

left_clone = []
for i in left:
left_clone.append(i)

for k in left_clone:
t_logs = []
left.remove(k)
for i in itertools.permutations(left,len(left)):
b = list(i)
t_logs.append(log +[k]+ b)

left = [1,2,3,4,5,6,7,8,9]
for i in log:
left.remove(i)

count = 0
wincount = 0
losecount = 0
for i in t_logs:
count += 1
result = calculate(i)
if turn == 0:
if result == "player 1":
losecount += 1
if result == "player 2":
wincount += 1
elif turn == 1:
if result == "player 2":
losecount += 1
if result == "player 1":
wincount += 1

winrate = wincount/count
loserate = losecount/count
rates.append([k,winrate, loserate])

g_lose = INF
for i in rates:
if i[2] < g_lose:
decision = i[0]
g_win = i[1]
g_lose = i[2]
elif i[2] == g_lose and i[1] > g_win:
decision = i[0]
g_win = i[1]
g_lose = i[2]
elif i[2] == g_lose and i[1] == g_win:
if random.choice([True, False]):
decision = i[0]
g_win = i[1]
g_lose = i[2]

if i[1] >= 0.95:
decision = i[0]
g_win = i[1]
g_lose = i[2]
break

return decision

# tic-tac-toe
table = ["-","-","-","-","-","-","-","-","-"]
log = []
first = random.choice(['your',"opponent's"])
if first == 'your':
now = True
else:
now = False

def turn(choice,sign):
table[choice-1] = sign
log.append(choice)
update_color('grid1',table[0])
update_color('grid2',table[1])
update_color('grid3',table[2])
update_color('grid4',table[3])
update_color('grid5',table[4])
update_color('grid6',table[5])
update_color('grid7',table[6])
update_color('grid8',table[7])
update_color('grid9',table[8])
end = check_win(table)
if end == "draw":
pass
elif end == "x":
sg.popup("Blue win!")
return 'break'
elif end == "o":
sg.popup("Red win!")
return 'break'
if '-' not in table:
return 'break'

import PySimpleGUI as sg
colors = [None, 'red','blue']

def update_color(grid,mark):
if mark == '-':
window[grid].update(background_color='white')
elif mark == 'o':
window[grid].update(background_color='red')
elif mark == 'x':
window[grid].update(background_color='blue')

sg.theme('DarkAmber')
layout = [
[sg.Text(f"{first} turn", key='Turn')],
[sg.Text(key='grid1',size=(5,3),background_color='white',text_color='black'),sg.Text(key='grid2',size=(5,3),background_color='white',text_color='black'),sg.Text(key='grid3',size=(5,3),background_color='white',text_color='black')],
[sg.Text(key='grid4',size=(5,3),background_color='white',text_color='black'),sg.Text(key='grid5',size=(5,3),background_color='white',text_color='black'),sg.Text(key='grid6',size=(5,3),background_color='white',text_color='black')],
[sg.Text(key='grid7',size=(5,3),background_color='white',text_color='black'),sg.Text(key='grid8',size=(5,3),background_color='white',text_color='black'),sg.Text(key='grid9',size=(5,3),background_color='white',text_color='black')],
[sg.Button('1',size=(1.5,1.5)),sg.Button('2',size=(1.5,1.5)),sg.Button('3',size=(1.5,1.5))],
[sg.Button('4',size=(1.5,1.5)),sg.Button('5',size=(1.5,1.5)),sg.Button('6',size=(1.5,1.5))],
[sg.Button('7',size=(1.5,1.5)),sg.Button('8',size=(1.5,1.5)),sg.Button('9',size=(1.5,1.5))],
[sg.Button('pass turn',)]
]

window = sg.Window('IMPOSIBLE TIC_TAC_TOE',layout)

while True:
p1_choice = '\$\$'
if event == sg.WINDOW_CLOSED:
break
if True:
if event == '1':
if table[0] == '-':
p1_choice = 1
if event == '2':
if table[1] == '-':
p1_choice = 2
if event == '3':
if table[2] == '-':
p1_choice = 3
if event == '4':
if table[3] == '-':
p1_choice = 4
if event == '5':
if table[4] == '-':
p1_choice = 5
if event == '6':
if table[5] == '-':
p1_choice = 6
if event == '7':
if table[6] == '-':
p1_choice = 7
if event == '8':
if table[7] == '-':
p1_choice = 8
if event == '9':
if table[8] == '-':
p1_choice = 9
if not now:
p1_choice = -1
if p1_choice == '\$\$':
continue

if first == 'your':
if now:
if turn(p1_choice,'x') == 'break':
break
else:
p2_choice = find_ans(log,0)
if turn(p2_choice,'o') == 'break':
break

if first == "opponent's":
if now:
if turn(p1_choice,'o') == 'break':
break
else:
p2_choice = find_ans(log,1)
if turn(p2_choice,'x') == 'break':
break

if now:
window['Turn'].update("opponent's turn")
else: