Skip to content

Commit 3efe6e3

Browse files
Classic TicTacToe just in Executable format
First, pick either 'X' or 'O' from the screen then, play the normal one Player TicTacToe. Playing on Terminal is kinda boring so, I made it into an executable file.
1 parent df868be commit 3efe6e3

File tree

13 files changed

+348
-0
lines changed

13 files changed

+348
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import os
2+
import game_config as gc
3+
4+
from pygame import image, transform
5+
6+
def GetName(val):
7+
return str(val) + ".png"
8+
9+
class Image:
10+
def __init__(self, val):
11+
self.name = GetName(val) #names of image with .png
12+
self.image_path = os.path.join(gc.ASSET_DIR, self.name) #path of image from the assets file
13+
self.image = image.load(self.image_path) #loaded the image
14+
self.image = transform.scale(self.image, (gc.IMAGE_SIZE - 2 * gc.MARGIN, gc.IMAGE_SIZE - 2 * gc.MARGIN)) #fixed image as per req.
15+
# self.box = self.image.copy() # box
16+
#self.box.fill((200, 200, 200))
17+
18+
19+
20+
if __name__ == '__main__':
21+
for i in gc.ASSET_FILES:
22+
temp = Image(i)
23+
print(temp.name,temp.image_path,temp.image,temp)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Making of .exe file command
2+
pip install pyinstaller // if you don't have it, also make sure the path you are using is correct
3+
pyinstaller --onefile (I wanted it all to be in 1 file) -w (since i used pygames) app.py (name of my main python file)
Binary file not shown.
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
from ctypes.wintypes import PINT
2+
from pickle import TRUE
3+
from numpy import flip, source
4+
import pygame
5+
import game_config as gc
6+
from process import TicTacToe as T
7+
from pygame import display, event, image
8+
from time import sleep
9+
import Images
10+
11+
def initial() -> pygame.Surface:
12+
pygame.init()
13+
display.set_caption('Tic-Tac-Toe')
14+
screen = display.set_mode((gc.SCREEN_SIZE, gc.SCREEN_SIZE))
15+
print( type(screen) )
16+
return screen
17+
18+
def find_xy(x, y):
19+
row = y // gc.IMAGE_SIZE
20+
col = x // gc.IMAGE_SIZE
21+
return row, col
22+
23+
def update_board_display(screen : pygame.Surface, Game : T ):#Update only
24+
screen.blit(image.load('assets/blank.png'), (0, 0))
25+
#sleep(1)
26+
screen.fill((0, 0, 0))
27+
for i in range(gc.NUM_TILES_SIDE):
28+
for j in range(gc.NUM_TILES_SIDE):
29+
tile = Images.Image(Game.board[i][j])
30+
screen.blit(tile.image, (j * gc.IMAGE_SIZE + gc.MARGIN, i * gc.IMAGE_SIZE + gc.MARGIN))
31+
display.flip()
32+
#sleep(1)
33+
34+
def GameOver(Game : T,screen : pygame.Surface) -> bool:
35+
val = Game.CheckWin()
36+
if val == 1:
37+
display.flip()
38+
update_board_display(screen,Game=Game)
39+
sleep(1.5)
40+
screen.blit(image.load('assets/win.png'), (0, 0))
41+
display.flip()
42+
sleep(2.3)
43+
return True
44+
if val == 0:
45+
display.flip()
46+
update_board_display(screen,Game=Game)
47+
sleep(1.5)
48+
screen.blit(image.load('assets/lose.png'), (0, 0))
49+
display.flip()
50+
sleep(2.3)
51+
return TRUE
52+
return False
53+
54+
55+
def run(Game : T,screen : pygame.Surface, running : bool):
56+
update_board_display(screen,Game)
57+
display.flip()
58+
while running:
59+
current_events = event.get()
60+
for e in current_events:
61+
if e.type == pygame.QUIT:# clicked X
62+
running = False
63+
64+
if e.type == pygame.KEYDOWN: #keyboard
65+
if e.key == pygame.K_ESCAPE:# Esc to end it
66+
running = False
67+
68+
if e.type == pygame.MOUSEBUTTONDOWN: #clickd
69+
mouse_x, mouse_y = pygame.mouse.get_pos()# got position
70+
row, col = find_xy(mouse_x, mouse_y)#location of click
71+
if row >= gc.NUM_TILES_SIDE or col >= gc.NUM_TILES_SIDE:# if it's on screen
72+
continue
73+
if Game.MoveRecord(row,col) == True:#if the move is possible
74+
if GameOver(Game,screen):#if game ends with it
75+
running = False
76+
break
77+
#game is still on
78+
a,b = Game.NextMove()# computer makes the move
79+
print(a,b, " here ")
80+
if a == -1 and b == -1: #special condition for tie
81+
running = False #end the game
82+
screen.blit(image.load('assets/tie.png'), (0, 0))
83+
display.flip()
84+
sleep(2.3)
85+
break;
86+
else:#not a tie
87+
if GameOver(Game,screen):#if game ends with it
88+
running = False
89+
break
90+
91+
update_board_display(screen=screen,Game=Game)
92+
display.flip()
93+
sleep(2.1)
94+
95+
#screen.blit(tile.image, (j * gc.IMAGE_SIZE + gc.MARGIN, i * gc.IMAGE_SIZE + gc.MARGIN))
96+
97+
def X_or_O(screen : pygame.Surface) -> str:
98+
X = Images.Image("x")
99+
O = Images.Image("o")
100+
#pygame.transform.scale()
101+
# Surface, (width, height) -> Surface
102+
X.image = pygame.transform.scale(X.image,(gc.SCREEN_SIZE//2,gc.SCREEN_SIZE))
103+
O.image = pygame.transform.scale(O.image,(gc.SCREEN_SIZE//2,gc.SCREEN_SIZE))
104+
screen.blit(X.image, (gc.MARGIN, gc.MARGIN))
105+
screen.blit(O.image, (gc.MARGIN +gc.SCREEN_SIZE//2 , gc.MARGIN))
106+
#screen.blits( blit_sequence=[ (X.image , (0,0) , pygame.Rect(0,0,gc.SCREEN_SIZE//2,gc.SCREEN_SIZE//2)), (O.image , (gc.SCREEN_SIZE//2,gc.SCREEN_SIZE//2) , pygame.Rect(gc.SCREEN_SIZE//2,gc.SCREEN_SIZE//2,gc.SCREEN_SIZE,gc.SCREEN_SIZE)) ] )
107+
display.flip()
108+
pick = "-1"
109+
while True:
110+
current_events = event.get()
111+
for e in current_events:
112+
if e.type == pygame.QUIT:# clicked X
113+
return pick
114+
115+
if e.type == pygame.KEYDOWN: #keyboard
116+
if e.key == pygame.K_ESCAPE:# Esc to end it
117+
return pick
118+
if e.type == pygame.MOUSEBUTTONDOWN:
119+
x,y = pygame.mouse.get_pos()
120+
if (x < gc.SCREEN_SIZE and x >= 0) or (y < gc.SCREEN_SIZE and y > 0):# if it's on screen
121+
if x > gc.SCREEN_SIZE//2:
122+
pick = "O"
123+
else: pick = "X"
124+
screen.fill((0,0,0))
125+
display.flip()
126+
sleep(1.1)
127+
return pick
128+
return pick
129+
130+
131+
def play():
132+
screen = initial()
133+
running = True
134+
pick = X_or_O(screen=screen)
135+
if pick == "-1":
136+
return
137+
Game = T(pick,gc.NUM_TILES_SIDE)
138+
run(Game,screen,running)
139+
140+
if __name__ == "__main__":
141+
142+
print("Hello World!")
143+
play()
144+
print('Goodbye!')
145+
Loading
Loading
Loading
2.31 KB
Loading
Loading
Loading
1.38 KB
Loading
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import os
2+
3+
IMAGE_SIZE = 103
4+
SCREEN_SIZE = 321
5+
NUM_TILES_SIDE = 3
6+
NUM_TILES_TOTAL = 9
7+
MARGIN = 2
8+
9+
ASSET_DIR = 'assets'
10+
ASSET_FILES = [x for x in os.listdir(ASSET_DIR)]
11+
#assert len(ASSET_FILES) == 8
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
2+
class TicTacToe:
3+
def __init__(self,pick,sz=3):
4+
self.pick = pick
5+
self.dim_sz = sz
6+
self.board = self.ClearBoard()
7+
8+
def ClearBoard(self):
9+
board = [['blur' for i in range(self.dim_sz)] for j in range(self.dim_sz)]
10+
# made a 3x3 by-default board
11+
return board
12+
13+
def MoveRecord(self,r,c):
14+
if r > self.dim_sz or c > self.dim_sz:
15+
return "Out of Bounds"
16+
if self.board[r][c] != 'blur':
17+
return "Spot Pre-Occupied"
18+
self.board[r][c] = self.pick
19+
return True
20+
21+
def CheckWin(self):# 1 you won, 0 computer won, -1 tie
22+
23+
#Flag syntax -> first player no. , User is Player#1 ; Check set 1 -> row and '\' diagonal & Check set 2 -> col and '/' diagonal
24+
25+
26+
for i in range(0,self.dim_sz):#Rows
27+
flag11 = True
28+
flag21 = True
29+
30+
flag12 = True
31+
flag22 = True
32+
for j in range(0,self.dim_sz):
33+
34+
ch2 = self.board[i][j]
35+
ch1 = self.board[j][i]
36+
#Row
37+
if ch1 == self.pick:# if it's mine, computer didn't make it
38+
flag21 = False
39+
elif ch1 == 'blur':#if it's blank no one made it
40+
flag11 = False
41+
flag21 = False
42+
else: flag11 = False# else i didn't make it
43+
44+
if ch2 == self.pick:#Same but for Col
45+
flag22 = False
46+
elif ch2 == 'blur':
47+
flag12 = False
48+
flag22 = False
49+
else: flag12 = False
50+
51+
if flag11 is True or flag12 is True:# I won
52+
return 1
53+
if flag21 is True or flag22 is True:#Computer Won
54+
return 0
55+
56+
#Diagonals#
57+
flag11 = True
58+
flag21 = True
59+
60+
flag12 = True
61+
flag22 = True
62+
for i in range(0,self.dim_sz):
63+
64+
ch2 = self.board[i][i]
65+
ch1 = self.board[i][self.dim_sz-1-i]
66+
67+
if ch1 == self.pick:
68+
flag21 = False
69+
elif ch1 == 'blur':
70+
flag11 = False
71+
flag21 = False
72+
else:flag11 = False
73+
74+
if ch2 == self.pick:
75+
flag22 = False
76+
elif ch2 == 'blur':
77+
flag12 = False
78+
flag22 = False
79+
else:flag12 = False
80+
81+
if flag11 or flag12:
82+
return 1
83+
if flag21 or flag22:
84+
return 0
85+
86+
return -1
87+
88+
89+
def NextMove(self):
90+
AvailableMoves = []# will carry all available moves
91+
PlayerWinSpot = []#if player (user Wins)
92+
CompPick = 'O'
93+
if self.pick == 'O':
94+
CompPick = 'X'
95+
for i in range(0,self.dim_sz):
96+
for j in range(0,self.dim_sz):
97+
98+
if self.board[i][j] == 'blur':#BLANK
99+
t = (i,j)
100+
AvailableMoves.append(t)#add it to available moves
101+
self.board[i][j] = CompPick#Check if I (Computer can win)
102+
if self.CheckWin() ==0:#Best Case I(Computer) win!
103+
return i,j;
104+
self.board[i][j] = self.pick
105+
if self.CheckWin() == 1: #Second Best Case, he (player) didn't won
106+
PlayerWinSpot.append(t)
107+
self.board[i][j] = 'blur'
108+
109+
if len(PlayerWinSpot) != 0:
110+
self.board[PlayerWinSpot[0][0]] [PlayerWinSpot[0][1]] = CompPick
111+
return PlayerWinSpot[0][0],PlayerWinSpot[0][1]
112+
print(AvailableMoves)
113+
if len(AvailableMoves) == 1:
114+
self.board[ AvailableMoves[0][0] ][ AvailableMoves[0][1] ] = CompPick
115+
return [ AvailableMoves[0][0] ],[ AvailableMoves[0][1] ]
116+
if len(AvailableMoves) == 0:
117+
return -1,-1
118+
119+
c1 , c2 = self.dim_sz//2,self.dim_sz//2
120+
print(c1,c2,self.dim_sz)
121+
if (c1,c2) in AvailableMoves:#CENTER
122+
self.board[c1][c2] = CompPick
123+
return c1,c2
124+
for i in range(c1-1,-1,-1):#IN TO OUT
125+
gap = c1 - i
126+
#checking - 4 possibilities at max
127+
#EDGES
128+
if (c1-gap,c2-gap) in AvailableMoves:
129+
self.board[c1-gap][c2-gap] = CompPick
130+
return c1-gap,c2-gap
131+
if (c1-gap,c2+gap) in AvailableMoves:
132+
self.board[c1-gap][c2+gap] = CompPick
133+
return c1-gap,c2+gap
134+
if (c1+gap,c2-gap) in AvailableMoves:
135+
self.board[c1+gap][c2-gap] = CompPick
136+
return c1+gap,c2-gap
137+
if (c1+gap,c2+gap) in AvailableMoves:
138+
self.board[c1+gap][c2+gap] = CompPick
139+
return c1+gap,c2+gap
140+
141+
#Four Lines
142+
143+
for i in range(0,gap):
144+
if (c1-gap,c2-gap+i) in AvailableMoves:#TOP LEFT TO TOP RIGHT
145+
self.board[c1-gap][c2-gap+i] = CompPick
146+
return c1-gap,c2-gap+i
147+
if (c1+gap,c2-gap+i) in AvailableMoves:#BOTTOM LEFT TO BOTTOM RIGHT
148+
self.board[c1+gap][c2-gap+i] = CompPick
149+
return c1+gap,c2-gap+i
150+
if (c1-gap,c2-gap) in AvailableMoves:#LEFT TOP TO LEFT BOTTOM
151+
self.board[c1-gap+i][c2-gap] = CompPick
152+
return c1-gap+i,c2-gap
153+
if (c1-gap+i,c2+gap) in AvailableMoves:#RIGHT TOP TO RIGHT BOTTOM
154+
self.board[c1-gap+i][c2+gap] = CompPick
155+
return c1-gap+i,c2+gap
156+
157+
if __name__ == "__main__":
158+
Game = TicTacToe("X")
159+
for i in range(0,10):
160+
print(Game.board)
161+
move = list(map(int,input().split()) )
162+
print(Game.MoveRecord(move[0],move[1]))
163+
print(Game.CheckWin())
164+
t = Game.NextMove()
165+
print("(",t[0],", ",t[1],")")
166+
print(Game.CheckWin())

0 commit comments

Comments
 (0)