diff --git a/89_Tic-Tac-Toe/python/TicTacToe_exe/Images.py b/89_Tic-Tac-Toe/python/TicTacToe_exe/Images.py new file mode 100644 index 00000000..ed41288d --- /dev/null +++ b/89_Tic-Tac-Toe/python/TicTacToe_exe/Images.py @@ -0,0 +1,23 @@ +import os +import game_config as gc + +from pygame import image, transform + +def GetName(val): + return str(val) + ".png" + +class Image: + def __init__(self, val): + self.name = GetName(val) #names of image with .png + self.image_path = os.path.join(gc.ASSET_DIR, self.name) #path of image from the assets file + self.image = image.load(self.image_path) #loaded the image + self.image = transform.scale(self.image, (gc.IMAGE_SIZE - 2 * gc.MARGIN, gc.IMAGE_SIZE - 2 * gc.MARGIN)) #fixed image as per req. + # self.box = self.image.copy() # box + #self.box.fill((200, 200, 200)) + + + +if __name__ == '__main__': + for i in gc.ASSET_FILES: + temp = Image(i) + print(temp.name,temp.image_path,temp.image,temp) diff --git a/89_Tic-Tac-Toe/python/TicTacToe_exe/README.md b/89_Tic-Tac-Toe/python/TicTacToe_exe/README.md new file mode 100644 index 00000000..2620f8c9 --- /dev/null +++ b/89_Tic-Tac-Toe/python/TicTacToe_exe/README.md @@ -0,0 +1,3 @@ +Making of .exe file command +pip install pyinstaller // if you don't have it, also make sure the path you are using is correct +pyinstaller --onefile (I wanted it all to be in 1 file) -w (since i used pygames) app.py (name of my main python file) \ No newline at end of file diff --git a/89_Tic-Tac-Toe/python/TicTacToe_exe/TicTacToe.py b/89_Tic-Tac-Toe/python/TicTacToe_exe/TicTacToe.py new file mode 100644 index 00000000..82bda683 --- /dev/null +++ b/89_Tic-Tac-Toe/python/TicTacToe_exe/TicTacToe.py @@ -0,0 +1,145 @@ +from ctypes.wintypes import PINT +from pickle import TRUE +from numpy import flip, source +import pygame +import game_config as gc +from process import TicTacToe as T +from pygame import display, event, image +from time import sleep +import Images + +def initial() -> pygame.Surface: + pygame.init() + display.set_caption('Tic-Tac-Toe') + screen = display.set_mode((gc.SCREEN_SIZE, gc.SCREEN_SIZE)) + print( type(screen) ) + return screen + +def find_xy(x, y): + row = y // gc.IMAGE_SIZE + col = x // gc.IMAGE_SIZE + return row, col + +def update_board_display(screen : pygame.Surface, Game : T ):#Update only + screen.blit(image.load('assets/blank.png'), (0, 0)) + #sleep(1) + screen.fill((0, 0, 0)) + for i in range(gc.NUM_TILES_SIDE): + for j in range(gc.NUM_TILES_SIDE): + tile = Images.Image(Game.board[i][j]) + screen.blit(tile.image, (j * gc.IMAGE_SIZE + gc.MARGIN, i * gc.IMAGE_SIZE + gc.MARGIN)) + display.flip() + #sleep(1) + +def GameOver(Game : T,screen : pygame.Surface) -> bool: + val = Game.CheckWin() + if val == 1: + display.flip() + update_board_display(screen,Game=Game) + sleep(1.5) + screen.blit(image.load('assets/win.png'), (0, 0)) + display.flip() + sleep(2.3) + return True + if val == 0: + display.flip() + update_board_display(screen,Game=Game) + sleep(1.5) + screen.blit(image.load('assets/lose.png'), (0, 0)) + display.flip() + sleep(2.3) + return TRUE + return False + + +def run(Game : T,screen : pygame.Surface, running : bool): + update_board_display(screen,Game) + display.flip() + while running: + current_events = event.get() + for e in current_events: + if e.type == pygame.QUIT:# clicked X + running = False + + if e.type == pygame.KEYDOWN: #keyboard + if e.key == pygame.K_ESCAPE:# Esc to end it + running = False + + if e.type == pygame.MOUSEBUTTONDOWN: #clickd + mouse_x, mouse_y = pygame.mouse.get_pos()# got position + row, col = find_xy(mouse_x, mouse_y)#location of click + if row >= gc.NUM_TILES_SIDE or col >= gc.NUM_TILES_SIDE:# if it's on screen + continue + if Game.MoveRecord(row,col) == True:#if the move is possible + if GameOver(Game,screen):#if game ends with it + running = False + break + #game is still on + a,b = Game.NextMove()# computer makes the move + print(a,b, " here ") + if a == -1 and b == -1: #special condition for tie + running = False #end the game + screen.blit(image.load('assets/tie.png'), (0, 0)) + display.flip() + sleep(2.3) + break; + else:#not a tie + if GameOver(Game,screen):#if game ends with it + running = False + break + + update_board_display(screen=screen,Game=Game) + display.flip() + sleep(2.1) + + #screen.blit(tile.image, (j * gc.IMAGE_SIZE + gc.MARGIN, i * gc.IMAGE_SIZE + gc.MARGIN)) + +def X_or_O(screen : pygame.Surface) -> str: + X = Images.Image("x") + O = Images.Image("o") + #pygame.transform.scale() + # Surface, (width, height) -> Surface + X.image = pygame.transform.scale(X.image,(gc.SCREEN_SIZE//2,gc.SCREEN_SIZE)) + O.image = pygame.transform.scale(O.image,(gc.SCREEN_SIZE//2,gc.SCREEN_SIZE)) + screen.blit(X.image, (gc.MARGIN, gc.MARGIN)) + screen.blit(O.image, (gc.MARGIN +gc.SCREEN_SIZE//2 , gc.MARGIN)) + #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)) ] ) + display.flip() + pick = "-1" + while True: + current_events = event.get() + for e in current_events: + if e.type == pygame.QUIT:# clicked X + return pick + + if e.type == pygame.KEYDOWN: #keyboard + if e.key == pygame.K_ESCAPE:# Esc to end it + return pick + if e.type == pygame.MOUSEBUTTONDOWN: + x,y = pygame.mouse.get_pos() + if (x < gc.SCREEN_SIZE and x >= 0) or (y < gc.SCREEN_SIZE and y > 0):# if it's on screen + if x > gc.SCREEN_SIZE//2: + pick = "O" + else: pick = "X" + screen.fill((0,0,0)) + display.flip() + sleep(1.1) + return pick + return pick + + +def play(): + screen = initial() + running = True + pick = X_or_O(screen=screen) + if pick == "-1": + return + Game = T(pick,gc.NUM_TILES_SIDE) + run(Game,screen,running) + +if __name__ == "__main__": + + print("Hello World!") + play() + print('Goodbye!') + diff --git a/89_Tic-Tac-Toe/python/TicTacToe_exe/game_config.py b/89_Tic-Tac-Toe/python/TicTacToe_exe/game_config.py new file mode 100644 index 00000000..803e0b3a --- /dev/null +++ b/89_Tic-Tac-Toe/python/TicTacToe_exe/game_config.py @@ -0,0 +1,11 @@ +import os + +IMAGE_SIZE = 103 +SCREEN_SIZE = 321 +NUM_TILES_SIDE = 3 +NUM_TILES_TOTAL = 9 +MARGIN = 2 + +ASSET_DIR = 'assets' +ASSET_FILES = [x for x in os.listdir(ASSET_DIR)] +#assert len(ASSET_FILES) == 8 \ No newline at end of file diff --git a/89_Tic-Tac-Toe/python/TicTacToe_exe/process.py b/89_Tic-Tac-Toe/python/TicTacToe_exe/process.py new file mode 100644 index 00000000..12836af9 --- /dev/null +++ b/89_Tic-Tac-Toe/python/TicTacToe_exe/process.py @@ -0,0 +1,166 @@ + +class TicTacToe: + def __init__(self,pick,sz=3): + self.pick = pick + self.dim_sz = sz + self.board = self.ClearBoard() + + def ClearBoard(self): + board = [['blur' for i in range(self.dim_sz)] for j in range(self.dim_sz)] + # made a 3x3 by-default board + return board + + def MoveRecord(self,r,c): + if r > self.dim_sz or c > self.dim_sz: + return "Out of Bounds" + if self.board[r][c] != 'blur': + return "Spot Pre-Occupied" + self.board[r][c] = self.pick + return True + + def CheckWin(self):# 1 you won, 0 computer won, -1 tie + + #Flag syntax -> first player no. , User is Player#1 ; Check set 1 -> row and '\' diagonal & Check set 2 -> col and '/' diagonal + + + for i in range(0,self.dim_sz):#Rows + flag11 = True + flag21 = True + + flag12 = True + flag22 = True + for j in range(0,self.dim_sz): + + ch2 = self.board[i][j] + ch1 = self.board[j][i] + #Row + if ch1 == self.pick:# if it's mine, computer didn't make it + flag21 = False + elif ch1 == 'blur':#if it's blank no one made it + flag11 = False + flag21 = False + else: flag11 = False# else i didn't make it + + if ch2 == self.pick:#Same but for Col + flag22 = False + elif ch2 == 'blur': + flag12 = False + flag22 = False + else: flag12 = False + + if flag11 is True or flag12 is True:# I won + return 1 + if flag21 is True or flag22 is True:#Computer Won + return 0 + + #Diagonals# + flag11 = True + flag21 = True + + flag12 = True + flag22 = True + for i in range(0,self.dim_sz): + + ch2 = self.board[i][i] + ch1 = self.board[i][self.dim_sz-1-i] + + if ch1 == self.pick: + flag21 = False + elif ch1 == 'blur': + flag11 = False + flag21 = False + else:flag11 = False + + if ch2 == self.pick: + flag22 = False + elif ch2 == 'blur': + flag12 = False + flag22 = False + else:flag12 = False + + if flag11 or flag12: + return 1 + if flag21 or flag22: + return 0 + + return -1 + + + def NextMove(self): + AvailableMoves = []# will carry all available moves + PlayerWinSpot = []#if player (user Wins) + CompPick = 'O' + if self.pick == 'O': + CompPick = 'X' + for i in range(0,self.dim_sz): + for j in range(0,self.dim_sz): + + if self.board[i][j] == 'blur':#BLANK + t = (i,j) + AvailableMoves.append(t)#add it to available moves + self.board[i][j] = CompPick#Check if I (Computer can win) + if self.CheckWin() ==0:#Best Case I(Computer) win! + return i,j; + self.board[i][j] = self.pick + if self.CheckWin() == 1: #Second Best Case, he (player) didn't won + PlayerWinSpot.append(t) + self.board[i][j] = 'blur' + + if len(PlayerWinSpot) != 0: + self.board[PlayerWinSpot[0][0]] [PlayerWinSpot[0][1]] = CompPick + return PlayerWinSpot[0][0],PlayerWinSpot[0][1] + print(AvailableMoves) + if len(AvailableMoves) == 1: + self.board[ AvailableMoves[0][0] ][ AvailableMoves[0][1] ] = CompPick + return [ AvailableMoves[0][0] ],[ AvailableMoves[0][1] ] + if len(AvailableMoves) == 0: + return -1,-1 + + c1 , c2 = self.dim_sz//2,self.dim_sz//2 + print(c1,c2,self.dim_sz) + if (c1,c2) in AvailableMoves:#CENTER + self.board[c1][c2] = CompPick + return c1,c2 + for i in range(c1-1,-1,-1):#IN TO OUT + gap = c1 - i + #checking - 4 possibilities at max + #EDGES + if (c1-gap,c2-gap) in AvailableMoves: + self.board[c1-gap][c2-gap] = CompPick + return c1-gap,c2-gap + if (c1-gap,c2+gap) in AvailableMoves: + self.board[c1-gap][c2+gap] = CompPick + return c1-gap,c2+gap + if (c1+gap,c2-gap) in AvailableMoves: + self.board[c1+gap][c2-gap] = CompPick + return c1+gap,c2-gap + if (c1+gap,c2+gap) in AvailableMoves: + self.board[c1+gap][c2+gap] = CompPick + return c1+gap,c2+gap + + #Four Lines + + for i in range(0,gap): + if (c1-gap,c2-gap+i) in AvailableMoves:#TOP LEFT TO TOP RIGHT + self.board[c1-gap][c2-gap+i] = CompPick + return c1-gap,c2-gap+i + if (c1+gap,c2-gap+i) in AvailableMoves:#BOTTOM LEFT TO BOTTOM RIGHT + self.board[c1+gap][c2-gap+i] = CompPick + return c1+gap,c2-gap+i + if (c1-gap,c2-gap) in AvailableMoves:#LEFT TOP TO LEFT BOTTOM + self.board[c1-gap+i][c2-gap] = CompPick + return c1-gap+i,c2-gap + if (c1-gap+i,c2+gap) in AvailableMoves:#RIGHT TOP TO RIGHT BOTTOM + self.board[c1-gap+i][c2+gap] = CompPick + return c1-gap+i,c2+gap + +if __name__ == "__main__": + Game = TicTacToe("X") + for i in range(0,10): + print(Game.board) + move = list(map(int,input().split()) ) + print(Game.MoveRecord(move[0],move[1])) + print(Game.CheckWin()) + t = Game.NextMove() + print("(",t[0],", ",t[1],")") + print(Game.CheckWin())