-
Notifications
You must be signed in to change notification settings - Fork 1
/
myanimation.py
258 lines (220 loc) · 8.65 KB
/
myanimation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
import pygame,random,sys
from pygame.locals import *
#dimensions of board and window
w_width=640
w_height=480
boxsize=40
boxspeed=8
boxgap=10
b_width=10
b_height=7
b_size=b_width*b_height
assert(b_width*b_height)%2==0,'Error! For having pair matches:The board size must be even!'
XMARGIN = int((w_width - (b_width * (boxsize + boxgap))) / 2)
YMARGIN = int((w_height - (b_height * (boxsize + boxgap))) / 2)
#colors used in the game
BLACK=(0,0,0)
GRAY=(100,100,100)
NAVYBLUE=(60,60,100)
WHITE=(255,255,255)
RED=(255,0,0)
GREEN=(0,255,0)
BLUE=(0,0,255)
YELLOW=(255,255,0)
ORANGE=(255,128,0)
PURPLE=(255,0,255)
CYAN=(0,255,255)
#designing of board color
bgcolor=NAVYBLUE
lightbgcolor=GRAY
highlightcolor=BLUE
boxcolor=BLACK
#shapes used in the game
DONUT = 'donut'
SQUARE = 'square'
DIAMOND = 'diamond'
LINES = 'lines'
OVAL = 'oval'
#To check whether board is available for all combinations of shapes/colors
colors=(RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, CYAN)
shapes=(DONUT, SQUARE, DIAMOND, LINES, OVAL)
assert(len(colors)*len(shapes*2))>=(b_width*b_height),'Board is too big considering all the combination of shapes/colors.'
def main():
global clock,screen
pygame.init()
clock=pygame.time.Clock()
screen=pygame.display.set_mode((w_width,w_height))
pygame.display.set_caption("Memory game")
mouse_x=0
mouse_y=0
mainBoard=getRandomizedBoard()
revealedBoxes=generateRevealedBoxesData(False)
firstclick=None
screen.fill(bgcolor)
startgame(mainBoard)
while True:
click=False
screen.fill(bgcolor)
drawBoard(mainBoard,revealedBoxes)
for event in pygame.event.get(): # event handling loop
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == MOUSEMOTION:
mousex, mousey = event.pos
elif event.type == MOUSEBUTTONUP:
mousex, mousey = event.pos
mouseClicked = True
box_x,box_y=getBox(mouse_x,mouse_y)
if box_x!=None and box_y!=None:
if not revealedBoxes[box_x][box_y]:#if not clicked, but mouse is over the box
HighlightBox(box_x,box_y)
if not revealedBoxes[box_x][box_y] and click:#if the box is clicked
revealBoxesAnimation(mainBoard,[(box_x,box_y)])
revealedBoxes[box_x][box_y]=True
if firstClick==None:#if first box pair is clicked
firstClick=[box_x][box_y]
else:
iconshape1,iconcolor1=getdata(mainBoard,firstClick[0],firstClick[1])#if second box is clicked
iconshape2,iconcolor2=getdata(mainBoard,box_x,box_y)
if iconshape1!=iconshape2 or iconcolor1!=iconcolor2:#if the pairs don't match
pygame.time.wait(1000)
coverBoxes(mainBoard,[(firstClick[0],firstClick[1]),(box_x,box_y)])#cover the boxes back
revealedBoxes[firstClick[0]][firsClick[1]]=False
revealedBoxes[box_x][box_y]=False
elif Won(revealedBoxes):#if all pairs are found
gameWon(mainBoard)
pygame.time.wait(3000)
#reset the board
mainBoard=getRandomizedBoard()
revealedBoxes=generateRevealedBoxesData(False)
#show the board fully revealed for some seconds
drawBoard(mainBoard,revealBoxes)
pygame.display.update()#update the screen object with the data
pygame.time.wait(2000)
#restart Game
startGame(mainBoard)
firstClick=None
pygame.display.update()
clock.tick(30)
#definition of revealing the box
def generateRevealedBoxesData(val):
revealedBoxes=[]
for i in range(b_width):
revealedBoxes.append([val]*b_width)
return revealedBoxes
#definition of function to get all combinations of shape and color
def getRandomizedBoard():
icons=[]
for color in colors:
for shape in shapes:
icons.append((shape,color))
random.shuffle(icons)#To randomize the order of icons list
numIcons=int(b_width*b_height/2)#total number of icons needed
icons=icons[:numIcons]*2#replicate
random.shuffle(icons)#shuffle again
board=[]
for x in range(b_width):
column=[]
for y in range(b_height):
column.append(icons[0])
del icons[0]
board.append(column)
return board
def splitIntoGroupsOf(groupSize, theList):
# splits a list into a list of lists, where the inner lists have at
# most groupSize number of items.
result = []
for i in range(0, len(theList), groupSize):
result.append(theList[i:i + groupSize])
return result
def leftTopCoordsOfBox(boxx, boxy):
# Convert board coordinates to pixel coordinates
left = boxx * (boxsize + boxgap) + XMARGIN
top = boxy * (boxsize + boxgap) + YMARGIN
return (left, top)
def getBox(x, y):
for boxx in range(b_width):
for boxy in range(b_height):
left, top = leftTopCoordsOfBox(boxx, boxy)
boxRect = pygame.Rect(left, top, boxsize, boxsize)
if boxRect.collidepoint(x, y):
return (boxx, boxy)
return (None, None)
def drawIcon(shape, color, boxx, boxy):
quarter = int(boxsize * 0.25)
half =int(boxsize * 0.5)
left, top = leftTopCoordsOfBox(boxx, boxy)
# Draw the shapes
if shape == DONUT:
pygame.draw.circle(screen, color, (left + half, top + half), half - 5)
pygame.draw.circle(screen, bgcolor, (left + half, top + half), quarter - 5)
elif shape == SQUARE:
pygame.draw.rect(screen, color, (left + quarter, top + quarter, boxsize - half, boxsize - half))
elif shape == DIAMOND:
pygame.draw.polygon(screen, color, ((left + half, top), (left + boxsize - 1, top + half), (left + half, top + boxsize - 1), (left, top + half)))
elif shape == LINES:
for i in range(0, boxsize, 4):
pygame.draw.line(screen, color, (left, top + i), (left + i, top))
pygame.draw.line(screen, color, (left + i, top + boxsize - 1), (left + boxsize - 1, top + i))
elif shape == OVAL:
pygame.draw.ellipse(screen, color, (left, top + quarter, boxsize, half))
def getData(board, boxx, boxy):
return board[boxx][boxy][0], board[boxx][boxy][1]
def drawBoxCovers(board, boxes, coverage):
for box in boxes:
left, top = leftTopCoordsOfBox(box[0], box[1])
pygame.draw.rect(screen, bgcolor, (left, top, boxsize, boxsize))
shape, color = getShapeAndColor(board, box[0], box[1])
drawIcon(shape, color, box[0], box[1])
if coverage > 0:
pygame.draw.rect(screen, boxcolor, (left, top, coverage, boxsize))
pygame.display.update()
clock.tick(30)
def revealBoxes(board, boxesToReveal):
for coverage in range(boxsize, (-boxspeed) - 1, -boxspeed):
drawBoxCovers(board, boxesToReveal, coverage)
def coverBoxes(board, boxesToCover):
for coverage in range(0,boxsize + boxspeed, boxspeed):
drawBoxCovers(board, boxesToCover, coverage)
def drawBoard(board, revealed):
for boxx in range(b_width):
for boxy in range(b_height):
left, top = leftTopCoordsOfBox(boxx, boxy)
if not revealed[boxx][boxy]:
pygame.draw.rect(screen, boxcolor,(left,top,boxsize,boxsize))
else:
shape, color = getData(board, boxx, boxy)
drawIcon(shape, color, boxx, boxy)
def drawHighlightBox(boxx, boxy):
left, top = leftTopCoordsOfBox(boxx, boxy)
pygame.draw.rect(screen,hightlightcolor, (left - 5, top - 5, boxsize + 10, boxsize + 10), 4)
def startgame(board):
coveredBoxes = generateRevealedBoxesData(False)
boxes = []
for x in range(b_width):
for y in range(b_height):
boxes.append( (x, y) )
random.shuffle(boxes)
boxGroups = splitIntoGroupsOf(8, boxes)
drawBoard(board, coveredBoxes)
for boxGroup in boxGroups:
revealBoxes(board, boxGroup)
coverBoxes(board, boxGroup)
def gameWon(board):
coveredBoxes = generateRevealedBoxesData(True)
color1 = lightbgcolor
color2 = bgcolor
for i in range(13):
color1, color2 = color2, color1
screen.fill(color1)
drawBoard(board, coveredBoxes)
pygame.display.update()
pygame.time.wait(300)
def Won(revealedBoxes):
for i in revealedBoxes:
if False in i:
return False
return True
if __name__ == '__main__':
main()