Skip to content

Commit 5cb6f68

Browse files
authored
Game File
1 parent 384a4b5 commit 5cb6f68

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

Game.py

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
#Hearder Files
2+
import cv2
3+
import numpy as np
4+
from random import randint
5+
#-----------------------------------------------------------------------------------
6+
7+
#Classes
8+
class Block() :
9+
def __init__(self,i,j) :
10+
self.value = None
11+
self.pos = (i,j)
12+
def setValue(self,value) :
13+
self.value = value
14+
15+
#-----------------------------------------------------------------------------------
16+
17+
class GUI() :
18+
def __init__(self,windowName) :
19+
self.windowName = windowName
20+
self.width,self.height = 400,400
21+
self.menuHeight = 100
22+
self.image = np.zeros((self.height+self.menuHeight,self.width,3),np.uint8)
23+
self.turn = 1
24+
self.vsCom = 0
25+
self.reset()
26+
#-----------------------------------------------------------------------------------
27+
#Reset Game
28+
def reset(self) :
29+
self.blocks = []
30+
self.win = False
31+
self.change = True
32+
self.selected = False
33+
for i in range(3) :
34+
row = []
35+
for j in range(3) :
36+
row.append([Block(i,j),(j*(self.width/3)+3,i*(self.height/3)+3),((j+1)*(self.width/3)-3,(i+1)*(self.height/3)-3)])
37+
self.blocks.append(row)
38+
#-----------------------------------------------------------------------------------
39+
#Drawing GUI and Game Screen
40+
def draw(self) :
41+
self.image = np.zeros((self.height+self.menuHeight,self.width,3),np.uint8)
42+
for i in range(3) :
43+
for j in range(3) :
44+
start_point = self.blocks[i][j][1]
45+
end_point = self.blocks[i][j][2]
46+
cv2.rectangle(self.image,start_point,end_point,(255,255,255),-1)
47+
value = " " if self.blocks[i][j][0].value is None else self.blocks[i][j][0].value
48+
cv2.putText(self.image,value,(j*(self.width/3)+25,(i*self.height/3)+100),cv2.FONT_HERSHEY_SIMPLEX,5,(0,0,0),5)
49+
if self.checkWin() :
50+
string = ("Player "+str(self.turn)+" Wins" if self.turn!=self.vsCom else "Computer Wins") if self.turn==1 else ("Player "+str(2)+" Win" if self.turn!=self.vsCom else "Computer Win")
51+
else :
52+
if not self.checkDraw() :
53+
string = ("Player "+str(self.turn)+"'s Turn" if self.turn!=self.vsCom else "Computer's Turn") if self.turn==1 else ("Player "+str(2)+"'s Turn" if self.turn!=self.vsCom else "Computer's Turn")
54+
else :
55+
string = "Match Draw!!"
56+
cv2.putText(self.image,string,(self.width/2-70,self.height+30),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1)
57+
cv2.putText(self.image,"R - Reset",(10,self.height+60),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1)
58+
cv2.putText(self.image,"Esc - Exit",(10,self.height+80),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1)
59+
string = "vs Computer" if self.vsCom==0 else "vs Human"
60+
cv2.putText(self.image,"Space - "+string,(self.width/2+10,self.height+80),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1)
61+
62+
if self.selected and not(self.checkWin() or self.checkDraw()):
63+
self.change = True
64+
self.selected = False
65+
self.turn *= -1
66+
#-----------------------------------------------------------------------------------
67+
#Game Play Functions
68+
def mainLoop(self) : #Game Loop till Esc(Close) button is pressed
69+
cv2.namedWindow(self.windowName)
70+
cv2.setMouseCallback(self.windowName,self.mouseCall)
71+
while True and cv2.getWindowProperty(self.windowName,1) != -1 :
72+
if self.change :
73+
self.change=False
74+
self.draw()
75+
if self.vsCom == self.turn and not(self.checkWin() or self.checkDraw()):
76+
block = self.nextMove()
77+
block.setValue("x" if self.turn==1 else "o")
78+
self.selected = True
79+
self.change = True
80+
cv2.imshow(self.windowName,self.image)
81+
#Keyboard Hits
82+
key = cv2.waitKey(1)
83+
if key == 27 : break
84+
elif key == ord("r") or key == ord("R") :
85+
self.reset()
86+
if key == ord(" ") and not(self.checkWin() or self.checkDraw()):
87+
if self.vsCom :
88+
self.vsCom = 0
89+
else :
90+
self.vsCom = self.turn
91+
self.change = True
92+
cv2.destroyAllWindows()
93+
94+
def checkWin(self) :
95+
self.win = False
96+
if (self.blocks[0][0][0].value is not None and self.blocks[0][0][0].value==self.blocks[0][1][0].value==self.blocks[0][2][0].value)or(self.blocks[1][0][0].value is not None and self.blocks[1][0][0].value==self.blocks[1][1][0].value==self.blocks[1][2][0].value)or(self.blocks[2][0][0].value is not None and self.blocks[2][0][0].value==self.blocks[2][1][0].value==self.blocks[2][2][0].value)or(self.blocks[0][0][0].value is not None and self.blocks[0][0][0].value==self.blocks[1][0][0].value==self.blocks[2][0][0].value)or(self.blocks[0][1][0].value is not None and self.blocks[0][1][0].value==self.blocks[1][1][0].value==self.blocks[2][1][0].value)or(self.blocks[0][2][0].value is not None and self.blocks[0][2][0].value==self.blocks[1][2][0].value==self.blocks[2][2][0].value)or(self.blocks[0][0][0].value is not None and self.blocks[0][0][0].value==self.blocks[1][1][0].value==self.blocks[2][2][0].value)or(self.blocks[2][0][0].value is not None and self.blocks[2][0][0].value==self.blocks[0][2][0].value==self.blocks[1][1][0].value) :
97+
self.win = True
98+
return self.win
99+
100+
def checkDraw(self) :
101+
flag = True
102+
for i in range(3) :
103+
for j in range(3) :
104+
if self.blocks[i][j][0].value == None :
105+
flag=False
106+
return flag
107+
#-----------------------------------------------------------------------------------
108+
#Computers Move Decided Using Minmax Algorithm
109+
def nextMove(self) : #Decide NextMove of Computer by this return the block to selected by the Computer
110+
flag=0
111+
blocks = []
112+
for i in range(3) :
113+
for j in range(3) :
114+
if self.blocks[i][j][0].value == None :
115+
blocks.append(self.blocks[i][j][0])
116+
if not (len(blocks)==sum([len(row) for row in self.blocks]) or len(blocks)==sum([len(row) for row in self.blocks])-1 or len(blocks)==1) :
117+
scoresList={}
118+
for block in blocks :
119+
if block.value == None :
120+
if self.computerWins(block) :
121+
scoresList[block] = 50
122+
elif self.playerWins(block) :
123+
scoresList[block] = -50
124+
elif not self.checkDraw() :
125+
block.value = ("x" if self.turn == 1 else "o")
126+
scoresList[block] = self.min_max(1,self.vsCom)
127+
block.value = None
128+
else :
129+
scoresList[block] = 0
130+
#Choosing Either Best Closest Winning Score or Next Closest Losing Score
131+
bestScore = (min(scoresList.values()) if abs(min(scoresList.values()))>abs(max(scoresList.values())) else max(scoresList.values()))
132+
blocks = []
133+
for block in scoresList :
134+
if scoresList[block] == bestScore :
135+
#print(block.pos,bestScore)
136+
blocks.append(block)
137+
choice = blocks[randint(0,len(blocks)-1)]
138+
print(choice.pos)
139+
return choice
140+
141+
def min_max(self,depth,player) : #MinMax Algorithms Function
142+
scoresList = []
143+
for row in self.blocks :
144+
for block in row :
145+
if block[0].value == None :
146+
if self.computerWins(block[0]) :
147+
return (50-depth)
148+
elif self.playerWins(block[0]) :
149+
return (-50+depth)
150+
else :
151+
block[0].value = ("x" if self.turn == 1 else "o")
152+
scoresList.append(self.min_max(depth+1,player*-1))
153+
block[0].value = None
154+
return (min(scoresList) if abs(min(scoresList))>abs(max(scoresList)) else max(scoresList))
155+
156+
def computerWins(self,block) :
157+
flag = False
158+
block.value = ("x" if self.vsCom == 1 else "o")
159+
if self.checkWin() : flag = True
160+
self.win = False
161+
block.value = None
162+
return flag
163+
164+
def playerWins(self,block) :
165+
flag = False
166+
block.value = ("x" if self.vsCom != 1 else "o")
167+
if self.checkWin() : flag = True
168+
self.win = False
169+
block.value = None
170+
return flag
171+
#-----------------------------------------------------------------------------------
172+
#Mouse Click Functions - (For User Players)
173+
def mouseCall(self,event,posx,posy,flag,param) :
174+
if event == cv2.EVENT_LBUTTONDOWN and not self.win and self.turn!=self.vsCom:
175+
self.setBlockInPos(posx,posy)
176+
177+
def setBlockInPos(self,x,y) :
178+
for i in range(3) :
179+
for j in range(3) :
180+
if self.blocks[i][j][0].value is None and self.blocks[i][j][1][0]<=x<=self.blocks[i][j][2][0] and self.blocks[i][j][1][1]<= y<= self.blocks[i][j][2][1]:
181+
self.blocks[i][j][0].setValue("x" if self.turn == 1 else "o")
182+
self.change = True
183+
self.selected = True
184+
break
185+
#-----------------------------------------------------------------------------------
186+
187+
#Main Program
188+
game = GUI("TicTacToe")
189+
game.mainLoop()

0 commit comments

Comments
 (0)