OSDN Git Service

白抜け関連
[python-games/python-games.git] / rensa3.py
1 '''
2 Created on 2013/03/16
3
4 @author: fu
5 '''
6 import pygame
7 from pygame.locals import *
8 import sys
9 import random
10 from threading import Thread 
11 import operator
12
13 Wid = (10)
14 Hei = (25)
15 Size = (16)
16 Pos = (5,3)
17 Sleep = (10)
18
19 pygame.init()
20 screen = pygame.display.set_mode((2*Wid*Size,Hei*Size))
21
22 white = (255,255,255)
23 gray = (100,100,100)
24 red = (255,0,0)
25 green = (0,255,0)
26 blue = (0,0,255)
27 yellow = (255,255,0)
28 purple = (255,0,255)
29
30 class Ball():
31     def __init__(self):    
32         self.rect = pygame.Rect(0,0,Size,Size)                
33         self.color = white
34         self.index = 0    
35
36 class Item():
37     def __init__(self):
38         self.colors = [white for x in range(4)]
39         self.clear()        
40     def clear(self):
41         self.horizontal = True
42         self.left,self.top = Pos
43         self.visible = True
44         for x in range(4):
45             i = random.randint(0,4)
46             if i == 0:
47                 self.colors[x] = red
48             elif i == 1:
49                 self.colors[x] = green
50             elif i == 2:
51                 self.colors[x] = blue
52             elif i == 3:
53                 self.colors[x] = yellow
54             elif i == 4:
55                 self.colors[x] = purple    
56     def assign(self,source):
57         self.horizontal = source.horizontal
58         self.left = source.left        
59         for x in range(4):
60             self.colors[x] = source.colors[x]               
61         
62 class Game():
63     def __init__(self):        
64         self.interval = 300
65         self.start()        
66        
67     def start(self):     
68         self.time = pygame.time.get_ticks()
69         self.score = 0
70         self.terminate = False
71
72 class System():
73     group = 0    
74     count = 0    
75     rensa = 0    
76         
77 class Ground():
78     def __init__(self):
79         self.rect = pygame.Rect(0,0,Wid*Size,Hei*Size)
80         self.strings = [[Ball() for y in range(Hei)] for x in range(Wid)]
81         for x in range(Wid):
82             for y in range(Hei):
83                 self.strings[x][y].rect.move_ip(x*Size,y*Size)                        
84         
85     def checkindex(self,index):
86         i = 0
87         for x in range(Wid):
88             for y in range(Hei):
89                 if self.strings[x][y].index == index:
90                     i += 1
91         return i   
92     
93     def assign(self,source):
94         for x in range(Wid):
95             for y in range(Hei):
96                 self.strings[x][y].color = source.strings[x][y].color
97            
98     def check(self,x,y):
99         if x < 0 or x > Wid-1 or y < 0 or y > Hei-1:
100             pass
101         else:
102             if y-1 >= 0:
103                 yield self.strings[x][y-1].index 
104             if x-1 >= 0:
105                 yield self.strings[x-1][y].index
106             if x+1 <= Wid-1:
107                 yield self.strings[x+1][y].index
108             if y+1 < Hei-1:
109                 yield self.strings[x][y+1].index
110                                             
111 class Ojama():    
112     class Jama():        
113         pass
114     
115     def __init__(self,ground):
116         self.color = gray
117         self.count = 0
118         self.ground = ground
119         self.strings = []
120         
121     def shoot(self):
122         if self.count > 0:
123             k = []
124             k.extend(self.make())
125             k.sort()
126             for x in k:
127                 s = self.Jama()
128                 s.left = x
129                 s.top = 0                
130                 self.strings.append(s)
131         if len(self.strings) > 0:            
132             self.down()
133         if self.count == 0 and len(self.strings) == 0:
134             return True
135         else:
136             return False
137                 
138     def make(self):
139         if self.count < Wid:
140             s = [x for x in range(Wid)]
141             for x in range(self.count):                
142                 y = random.randint(0,len(s)-1)
143                 s.remove(s[y])
144                 yield y
145             self.count = 0
146         else:
147             self.count -= Wid
148             for x in range(Wid):
149                 yield x
150                                                                                                            
151     def down(self):
152         for x in self.strings:            
153             if x.top < Hei-1 and self.ground.strings[x.left][x.top+1].color == white:
154                 x.top += 1
155             else:
156                 s = self.ground.strings[x.left][x.top]
157                 s.color = self.color
158                 s.index = -1
159                 self.strings.remove(x)
160                 
161     def delete(self,index):                
162         for x in range(Wid):
163             for y in range(Hei):
164                 if self.ground.strings[x][y].color == self.color:
165                     k = []        
166                     k.extend(self.ground.check(x, y))
167                     for i in k:
168                         if i == index:
169                             s = self.ground.strings[x][y]
170                             s.index = 0
171                             s.color = white     
172                             break           
173                    
174 class Player():        
175     def __init__(self):
176         self.ground = Ground()
177         self.item = Item()        
178         self.system = System()
179         self.ojama = Ojama(self.ground)
180             
181     def draw(self):
182         screen.fill(white,pygame.Rect(self.ground.rect))                        
183         for x in range(Wid):
184             for y in range(Hei):
185                 s = self.ground.strings[x][y]
186                 if s.color != white:                    
187                     pygame.draw.ellipse(screen,s.color,s.rect)                
188         if self.item.visible == True:
189             for x in range(4):            
190                 if self.item.horizontal == True:
191                     pygame.draw.ellipse(screen,self.item.colors[x],self.ground.strings[self.item.left+x-1][self.item.top].rect)
192                 else:
193                     pygame.draw.ellipse(screen,self.item.colors[x],self.ground.strings[self.item.left][self.item.top-x+1].rect)
194         for x in self.ojama.strings:
195             pygame.draw.ellipse(screen,self.ojama.color,self.ground.strings[x.left][x.top].rect)
196         pygame.display.update(self.ground.rect)
197         pygame.display.update(pygame.draw.line(screen,(0,0,0),(Wid*Size,0),(Wid*Size,Hei*Size)))
198
199     def put(self,buf=False):
200         self.item.visible = False    
201         for x in range(4):
202             if self.item.horizontal == True:
203                 self.ground.strings[self.item.left+x-1][self.item.top].color = self.item.colors[x]
204             else:
205                 self.ground.strings[self.item.left][self.item.top-x+1].color = self.item.colors[x]        
206         self.system.count = 0  
207         self.system.rensa = 0              
208         while True:          
209             self.system.group = 0  
210             while self.drop():
211                 if buf == False:
212                     self.draw()                
213                     pygame.time.delay(Sleep)       
214             k = []
215             k.extend(self.remove())
216             for x in k:                                    
217                 self.ojama.delete(x)
218                 self.delete(x)
219             if buf == False:
220                 self.draw()
221             if self.drop() == False:
222                 break    
223         if buf == False:                
224             self.score()            
225         
226     def ojamashoot(self):      
227         while self.ojama.shoot() == False:
228             self.draw()
229             pygame.time.delay(Sleep)
230         
231     def before(self):
232         if self.system.rensa > 0:
233             self.system.rensa -= 1
234         if self.ojama.count > 0:
235             if self.ojama.count > self.system.rensa:
236                 self.ojama.count -= self.system.rensa
237             else:
238                 self.ojama.count = 0
239                 self.system.rensa -= self.ojama.count
240                 
241     def score(self):
242         self.before()
243         com.ojama.count += self.system.rensa
244     
245     def remove(self):    
246         self.system.index = 1                
247         for x in range(Wid):
248             for y in range(Hei):
249                 self.ground.strings[x][y].index = 0
250         for x in range(Wid):
251             for y in range(Hei):   
252                 s = self.ground.strings[x][y].color                
253                 if s != white and s != self.ojama.color:  
254                     self.system.color = self.ground.strings[x][y].color       
255                     if self.mapindex(x,y) == True:
256                         self.system.index += 1     
257         for w in range(1,self.system.index):
258             m = self.ground.checkindex(w)
259             if m == 3:
260                 self.system.group += 1
261             if m >= 4:                            
262                 self.system.count += m
263                 self.system.rensa += 1
264                 yield w   
265                 
266     def delete(self,index):             
267         for x in range(Wid):
268             for y in range(Hei):
269                 m = self.ground.strings[x][y]
270                 if m.index == index:                                
271                     m.index = 0                       
272                     m.color = white                                                                                                    
273
274     def start(self):    
275         self.item.clear()        
276         self.system.count = 0
277         self.system.group = 0  
278         self.ojama.strings = []  
279         for x in range(Wid):
280             for y in range(Hei):
281                 s = self.ground.strings[x][y]
282                 s.index = 0
283                 s.color = white
284         self.draw()        
285
286     def mapindex(self,x,y):
287         if x < 0 or x > Wid-1 or y < 0 or y > Hei-1:
288             return False
289         s = self.ground.strings[x][y]
290         if s.index == 0 and s.color == self.system.color:                            
291             self.ground.strings[x][y].index = self.system.index        
292             self.mapindex(x-1,y-1)
293             self.mapindex(x-1,y)
294             self.mapindex(x-1,y+1)
295             self.mapindex(x,y-1)
296             self.mapindex(x,y+1)
297             self.mapindex(x+1,y-1)
298             self.mapindex(x+1,y)
299             self.mapindex(x+1,y+1)
300             return True
301         else:
302             return False
303         
304     def drop(self):
305         s = False
306         for x in range(Wid):
307             for y in range(Hei-1,0,-1):
308                 if self.ground.strings[x][y].color == white:
309                     for w in range(y-1,0,-1):
310                         if self.ground.strings[x][w].color != white:
311                             s = True
312                             break
313                     if s == True:                            
314                         for w in range(y,1,-1):
315                             m = self.ground.strings[x][w]                            
316                             n = self.ground.strings[x][w-1]
317                             m.color = n.color   
318                             m.index = n.index                 
319                         else:
320                             m = self.ground.strings[x][0]
321                             m.color = white
322                             m.index = 0
323         return s    
324     
325     def move(self,key):
326         if key == K_LEFT:
327             self.item.left -= 1
328         elif key == K_RIGHT:
329             self.item.left += 1
330         elif key == K_DOWN:
331             self.item.top += 1
332         s = self.checkitem()
333         if s == False:
334             if key == K_LEFT:
335                 self.item.left += 1
336             elif key == K_RIGHT:
337                 self.item.left -= 1
338             elif key == K_DOWN:
339                 self.item.top -= 1            
340         return s
341     
342     def turn(self,boolean=True):
343         self.item.horizontal = not self.item.horizontal
344         if (boolean == True and self.item.horizontal == True)or(boolean == False and self.item.horizontal == False):
345             x,y = self.item.colors[0],self.item.colors[1] 
346             self.item.colors[0],self.item.colors[1]= self.item.colors[3],self.item.colors[2]
347             self.item.colors[3],self.item.colors[2] = x,y                          
348     
349     def checkitem(self):
350         if self.item.horizontal == True:
351             if self.item.left-1 < 0 or self.item.left+2 > Wid-1 or self.item.top < 0 or self.item.top > Hei-1:
352                 return False
353         else:
354             if self.item.left < 0 or self.item.left > Wid-1 or self.item.top-2 < 0 or self.item.top+1 > Hei-1:
355                 return False
356         for x in range(4):
357             if self.item.horizontal == True:
358                 if self.ground.strings[self.item.left+x-1][self.item.top].color != white:
359                     return False                
360             else:
361                 if self.ground.strings[self.item.left][self.item.top-x+1].color != white:
362                     return False
363         return True                        
364     
365     def shoot(self,buf=False):
366         while self.move(K_DOWN) == True:
367             if buf == False:
368                 self.draw()
369                 pygame.time.delay(Sleep)
370         else:
371             self.item.top -= 1
372             self.put(buf)
373
374 class ComPlayer(Player):
375     def __init__(self):
376         Player.__init__(self)
377         self.buffer = Ground()
378         self.__vir = Item()  
379         self.ground.rect = pygame.Rect(Wid*Size,0,2*Wid*Size,Hei*Size)      
380         for x in range(Wid):
381             for y in range(Hei):
382                 self.ground.strings[x][y].rect.move_ip(Wid*Size,0)
383                        
384     def com(self):        
385         self.buffer.assign(self.ground)                
386         if self.checkitem() == False:                    
387             return
388         self.__vir.assign(self.item)  
389         self.__score = 0      
390         for x in range(4):                        
391             self.__sub()
392             if game.terminate == True:
393                 return
394             self.turn()     
395         self.ground.assign(self.buffer)
396         self.ojamashoot()                
397         self.item.left,self.item.top = Pos
398         self.item.visible = True
399         self.draw()            
400         if self.item.horizontal != self.__vir.horizontal:
401             self.turn()
402             self.draw()
403         for x in range(4):
404             if self.item.colors[x] != self.__vir.colors[x]:
405                 self.turn()
406                 self.draw()
407                 self.turn()
408                 self.draw()
409                 break
410         while self.item.left < self.__vir.left:
411             self.item.left += 1
412             self.draw()
413         while self.item.left > self.__vir.left:
414             self.item.left -= 1
415             self.draw()
416         self.shoot()                  
417     
418     def __sub(self):
419         if self.__score >= 100:
420             return
421         high = (15)                
422         for x in range(Wid):   
423             if game.terminate == True:
424                 return
425             self.ground.assign(self.buffer)   
426             self.item.left,self.item.top = x,3
427             if self.checkitem() == False:
428                 continue                
429             self.shoot(True)                                
430             if self.system.count > high:
431                 self.__vir.assign(self.item)                
432                 self.__score = 100
433                 return 
434             m = self.system.group*10+self.system.count 
435             if self.__score < m:     
436                 self.__score = m  
437                 self.__vir.assign(self.item)  
438                                                                                            
439     def score(self):
440         self.before()
441         man.ojama.count += self.system.rensa
442        
443 class Back(Thread):
444     def __init__(self):
445         Thread.__init__(self)
446         self.setDaemon(True)        
447         
448     def run(self):        
449         while game.terminate == False:        
450             if com.item.visible == True:
451                 com.shoot()
452             else:                
453                 com.com()
454                 com.item.clear()                                          
455                 if com.checkitem() == False:                                
456                     gameover(com)                                    
457              
458 def main():
459     game.start()
460     man.start()
461     com.start()
462     back = Back()
463     back.start()   
464     pygame.display.set_caption("") 
465     while game.terminate == False:
466         while timer() == True:   
467             man.draw()
468             keydown()
469     pygame.time.delay(Sleep*500)
470     back.join()
471                     
472 def keydown():
473     for event in pygame.event.get():
474         if event.type == QUIT:
475             sys.exit()
476         elif event.type == KEYDOWN:
477             if event.key == K_ESCAPE:            
478                 sys.exit()
479             if man.item.visible == False:
480                 return
481             if event.key == K_UP:                
482                 man.turn()
483                 if man.checkitem() == False:
484                     man.turn(False)
485             elif event.key == K_DOWN:
486                 man.shoot()
487             else:
488                 man.move(event.key)
489                    
490 def timer():
491     temp = pygame.time.get_ticks()
492     if game.time+game.interval > temp:        
493         return True   
494     game.time = temp     
495     if man.item.visible == True:
496         if man.move(K_DOWN) == False:
497             man.put()
498         return False
499     else:
500         man.ojamashoot()
501         man.item.clear()        
502         if man.checkitem() == True:
503             return True
504         else:
505             gameover(man)
506             return False  
507     
508 def gameover(sender):    
509     if sender == man:
510         s = 'Player2'
511     elif sender == com:
512         s = 'Player1'
513     pygame.display.set_caption(s+' WIN!!')
514     game.terminate = True      
515     sender.draw()
516
517 man = Player()
518 com = ComPlayer()
519 game = Game()
520 while True:
521     main()