# Jic-Jac-Joe

As the name suggests, this is a computer version of the well-known game Tic-Tac-Toe. This version supports a computer player, but it is not the smartest algorithm and can lose. In this setup, the computer plays ‘O’ and starts, the player plays ‘X’.
Win detection is fully implemented.

#### Controls

• The 3×3-field is projected on the numpad
• So 7 sets your piece in the upper left corner
• And 3 puts it in the lower right corner
• Escape resets the game

``````# Python 2.7.7 Code
# Pygame 1.9.1 (for Python 2.7.7)
# Jonathan Frech  9th of July, 2015
#         edited 10th of July, 2015``````

``````# importing needed modules
import pygame, sys, time, math, os, random

""" CLASSES """
# dummy class for global variables
class dummy():
pass

""" FUNCTIONS """
# gets the mouse position
def getMousePos():
p = pygame.mouse.get_pos()
return [p[0], p[1]]

# validates color integer
# extra feature: _min and _max implementation
def colorValid(_color, _min = 0, _max = 255):
newColor = math.fabs(_color)
n = _max - _min
if newColor > n:
if int(newColor / n) % 2 == 0:
newColor = newColor % n
else:
newColor = n - (newColor % n)

return int(newColor) + _min

# gets the position on a circle
# circle center                           : '_pos'
# angle from center to point on the circle: '_angle'
return [
]

# returns an integer version of given positon
def intpos(_pos):
return [int(_pos[0]), int(_pos[1])]

# basic vector functions
def vecConvert(p1, p2):
return [p2[0] - p1[0], p2[1] - p1[1]]
def vecLen(vec):
return math.sqrt( (vec[0]**2) + (vec[1]**2) )
def vecMultiply(vec, n):
return [vec[0] * n, vec[1] * n]
def vecGetPoint(vec, point):
return [point[0] + vec[0], point[1] + vec[1]]
return [vec1[0] + vec2[0], vec1[1] + vec2[1]]

# calculates distance between given positions
def posDistance(p1, p2):
return math.sqrt( (p2[0] - p1[0])**2 + (p2[1] - p1[1])**2 )

# quits the program
def quit():
sys.exit()

# sets a piece
def set(_n):
if not main.GAMEOVER and main.FIELD[_n] == -1:
main.FIELD[_n] = main.CURRENT
if main.CURRENT == 0:
main.CURRENT = 1
else:
main.CURRENT = 0

# computer move
def com():
wins = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
]

s = -1

if s == -1:
# win
for _ in wins:
if main.FIELD[_[1]] == main.CURRENT and main.FIELD[_[0]] == main.FIELD[_[1]] and main.FIELD[_[2]] == -1:
s = _[2];break
elif main.FIELD[_[2]] == main.CURRENT and main.FIELD[_[1]] == main.FIELD[_[2]] and main.FIELD[_[0]] == -1:
s = _[0];break
elif main.FIELD[_[0]] == main.CURRENT and main.FIELD[_[2]] == main.FIELD[_[0]] and main.FIELD[_[1]] == -1:
s = _[1];break

if s == -1:
# stop other player
for _ in wins:
if main.FIELD[_[1]] != -1 and main.FIELD[_[1]] != main.CURRENT and main.FIELD[_[0]] == main.FIELD[_[1]] and main.FIELD[_[2]] == -1:
s = _[2];break
elif main.FIELD[_[2]] != -1 and main.FIELD[_[2]] != main.CURRENT and main.FIELD[_[1]] == main.FIELD[_[2]] and main.FIELD[_[0]] == -1:
s = _[0];break
elif main.FIELD[_[0]] != -1 and main.FIELD[_[0]] != main.CURRENT and main.FIELD[_[2]] == main.FIELD[_[0]] and main.FIELD[_[1]] == -1:
s = _[1];break

if s == -1:
# try to put in corners or center
available = []
for _ in [0, 2, 4, 6, 8]:
if main.FIELD[_] == -1:
available.append(_)
if len(available) > 0:
s = available[random.randint(0, len(available) - 1)]

if s == -1:
# do something...
available = []
for _ in range(0, len(main.FIELD) - 1):
if main.FIELD[_] == -1:
available.append(_)
if len(available) > 0:
s = available[random.randint(0, len(available) - 1)]

if s != -1:
set(s)

# checks for win
def check():
wins = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
]

full = True

for _ in wins:
if main.FIELD[_[0]] == -1 or main.FIELD[_[1]] == -1 or main.FIELD[_[2]] == -1:
full = False
elif main.FIELD[_[0]] == main.FIELD[_[1]] and main.FIELD[_[1]] == main.FIELD[_[2]]:
main.GAMEOVER = True
main.WINNER = main.FIELD[_[0]]
main.WIN = _
break

if full:
main.GAMEOVER = True

""" TICK; RENDER """
# tick function
def tick():
# handle events
for event in pygame.event.get():
# quit
if event.type == pygame.QUIT:
quit()

# keyup
if event.type == pygame.KEYUP:
# handle 'main.KEYSDOWN'
if event.key in main.KEYSDOWN:
main.KEYSDOWN.remove(event.key)

if event.key == pygame.K_ESCAPE:
reset()

if not main.CURRENT in main.COM:
if event.key == pygame.K_KP1:
set(6)
elif event.key == pygame.K_KP2:
set(7)
elif event.key == pygame.K_KP3:
set(8)
elif event.key == pygame.K_KP4:
set(3)
elif event.key == pygame.K_KP5:
set(4)
elif event.key == pygame.K_KP6:
set(5)
elif event.key == pygame.K_KP7:
set(0)
elif event.key == pygame.K_KP8:
set(1)
elif event.key == pygame.K_KP9:
set(2)

# keydown
if event.type == pygame.KEYDOWN:
# handle 'main.KEYSDOWN'
if event.key not in main.KEYSDOWN:
main.KEYSDOWN.append(event.key)

check()
if main.CURRENT in main.COM:
main.COMDELAY -= 1
if main.COMDELAY <= 0:
main.COMDELAY = main.MAXCOMDELAY
com()
check()

# render function
def render():
# fill
main.SURF.fill(main.COLOR)

for _ in range(0, 9):
x, y = (main.FWIDTH+main.GAP) * (_ % 3) + main.GAP, (main.FHEIGHT+main.GAP) * (_ / 3) + main.GAP

if main.FIELD[_] == -1:
pygame.draw.rect(main.SURF, (50, 50, 50), [x, y, main.FWIDTH, main.FHEIGHT])
else:
pygame.draw.rect(main.SURF, (20, 20, 20), [x, y, main.FWIDTH, main.FHEIGHT])

if main.WIN:
if _ in main.WIN:
pygame.draw.rect(main.SURF, (70, 20, 20), [x, y, main.FWIDTH, main.FHEIGHT])

if main.FIELD[_] == 0:
pygame.draw.rect(main.SURF, (0, 0, 255), [x, y, main.FWIDTH, main.FHEIGHT], 1)
elif main.FIELD[_] == 1:
pygame.draw.line(main.SURF, (0, 0, 255), [x, y], [x + main.FWIDTH - 1, y + main.FHEIGHT - 1])
pygame.draw.line(main.SURF, (0, 0, 255), [x, y + main.FHEIGHT - 1], [x + main.FWIDTH - 1, y])

# blit and flip
main.SCREEN.blit(pygame.transform.scale(main.SURF, main.SSIZE), [0, 0])
pygame.display.flip()

""" INIT; RESET """
# resets the game
def reset():
main.FIELD = [
-1, -1, -1,
-1, -1, -1,
-1, -1, -1
]
main.CURRENT = 0

main.GAMEOVER = False
main.WINNER = -1
main.WIN = None

# initialize program
def init():
main.GAP = 1

main.FWIDTH, main.FHEIGHT = 10, 10
main.FSIZE = [main.FWIDTH, main.FHEIGHT]

main.WIDTH, main.HEIGHT = (main.FWIDTH+main.GAP)*3+main.GAP, (main.FHEIGHT+main.GAP)*3+main.GAP
main.SIZE = [main.WIDTH, main.HEIGHT]
main.SURF = pygame.Surface(main.SIZE)

main.SCALE = 10
main.SWIDTH, main.SHEIGHT = main.WIDTH * main.SCALE, main.HEIGHT * main.SCALE
main.SSIZE = [main.SWIDTH, main.SHEIGHT]
main.SCREEN = pygame.display.set_mode(main.SSIZE)

main.CAPTION = "Jic-Jac-Joe"
main.COLOR = (0, 0, 0)
main.TICKS = 0
main.KEYSDOWN = []

reset()

main.COM = [0]
main.MAXCOMDELAY = 10
main.COMDELAY = main.MAXCOMDELAY

# functions
pygame.display.set_caption(main.CAPTION)

""" RUN """
# run function (uses tick() and render())
def run():
ticksPerSecond = 60
lastTime = time.time() * 1000000000
nsPerTick =  1000000000.0 / float(ticksPerSecond)

ticks = 0
frames = 0

lastTimer = time.time() * 1000
delta = 0.0

while True:
now = time.time() * 1000000000
delta += float(now - lastTime) / float(nsPerTick)
lastTime = now
shouldRender = False

while delta >= 1:
ticks += 1
main.TICKS += 1
tick()
delta -= 1
shouldRender = True

if shouldRender:
frames += 1
render()

if time.time() * 1000 - lastTimer >= 1000:
lastTimer += 1000

# debug
# print("Frames: " + str(frames) + ", ticks: " + str(ticks))

frames = 0
ticks = 0

# main variable
main = dummy()
init()

# start program
run()``````