OSDN Git Service

もう一回訂正
[python-games/python-games.git] / reversi / reversi.py
1 '''
2 Created on 2015/08/25
3
4 @author: fuke
5 '''
6 import pygame,os,sys
7 from pygame.locals import *
8 import threading
9 import time
10
11
12 pygame.font.init()
13 screen = pygame.display.set_mode((400,400))
14
15 none, black, white, effect = 0,1,2,3
16
17 def Path():
18     for name in sys.argv:
19         if os.path.exists(name) == True:
20             return os.path.dirname(name)
21     else:
22         return ''
23        
24 img = pygame.image.load(os.path.join(Path(),'png','tips.png')).convert()
25 bkwhite = pygame.image.load(os.path.join(Path(),'png','min_black.png')).convert()
26 bkblack = pygame.image.load(os.path.join(Path(),'png','min_white.png')).convert()
27
28 index_x = 6
29 index_y = 5
30 size = 50
31    
32 class Player():
33     auto = False
34     stone = none
35
36 class Effect():
37     def __init__(self,x=0,y=0):
38         self.X = 0
39         self.Y = 0
40         self.Left = x
41         self.Top = y
42
43 class Grid():       
44     def __init__(self):        
45         self.grid = [[none for y in range(8)] for x in range(8)]
46         self.stone = none    
47     def Assign(self,item):
48         for x in range(8):
49             for y in range(8):
50                 self.grid[x][y] = item.grid[x][y]
51     
52 class StoneGrid():
53     def __init__(self):    
54         self.item = Grid()
55         self.buffer = [Grid() for x in range(61)]
56         self.turn_number = 0
57         self.turn_index = 0
58         self.active = True
59         self.list = []        
60         self.effect_stone = none
61         self.gameover = False
62         self.text = pygame.font.SysFont(None, 25, True).render('reversi',False,(0,0,255)).convert()        
63     
64     def Clear(self):
65         for x in range(8):
66             for y in range(8):
67                 self.item.grid[x][y] = none
68         self.item.grid[3][3] = black
69         self.item.grid[4][4] = black
70         self.item.grid[4][3] = white 
71         self.item.grid[3][4] = white 
72         self.turn_index = 0
73         self.turn_number = 0
74         self.buffer[0].Assign(self.item)
75         
76     def CalScore(self,stone,x,y):
77         loop = 0
78         def Normal():
79             for x in range(8):
80                 for y in range(8):
81                     if self.CanSetStone(stone, x, y, False) == True:
82                         self.score += 1
83                         
84         def Hard():
85             if loop > 2:
86                 return
87             loop =+ 1
88             self.buffer[self.turn_index+loop].Assign(self.item)
89             for x in range(8):
90                 for y in range(8):
91                     if self.CanSetStone(stone, x, y, True) == True:
92                         if stone == black:
93                             stone = white
94                         elif stone == white:
95                             stone = black
96                         Hard()
97                         Normal()                    
98                     self.item.Assign(self.buffer[self.turn_index+loop])
99                     
100         if self.CanSetStone(stone, x, y, True) == True:
101             result = True
102             self.score = 0
103             if stone == black:
104                 stone = white
105             elif stone == white:
106                 stone = black
107             Normal()
108         else:
109             result = False            
110         self.item.Assign(self.buffer[self.turn_index])        
111         return result
112                 
113     def CanSetStone(self,stone,x,y,reverse,visible=False):
114         p = [True,False]
115         j = 0        
116         def Method(m,n):   
117             nonlocal p
118             nonlocal j
119             if p[0] == False:
120                 return
121             i = 1
122             while True:
123                 d = x+m*i
124                 e = y+n*i
125                 if not ((0 <= d)and(d < 8)and(0 <= e)and(e < 8)):
126                     break
127                 s = self.item.grid[d][e]
128                 if s == effect:
129                     s = self.effect_stone
130                 if s == none:
131                     break
132                 elif s == stone:                                
133                     if i > 1:                    
134                         self.effect_stone = stone
135                         if (p[1] == False)and(reverse == True):
136                             self.item.grid[x][y] = stone
137                             p[1] = True
138                         if reverse == True:                            
139                             j = 1
140                             ch = True
141                             while j <= i-1:
142                                 if visible == True:
143                                     if ch:
144                                         Paint()
145                                         ch = False
146                                     q = Effect(x+m*j,y+n*j)          
147                                     self.item.grid[q.Left][q.Top] = effect      
148                                     th = threading.Timer(0.2*j,self.th_run,args=(q,))
149                                     self.list.append(th)
150                                     th.start()                                                                                                                                 
151                                 else:
152                                     self.item.grid[x+m*j][y+n*j] = stone
153                                 j += 1
154                             break
155                         else:
156                             p[0],p[1] = False,True
157                             break
158                     else:
159                         break
160                 else:
161                     i += 1
162                    
163         if self.item.grid[x][y] == none:            
164             Method(-1,-1)
165             Method(-1, 0)
166             Method(-1, 1)
167             Method(0, -1)
168             Method(0, 1)
169             Method(1, -1)
170             Method(1, 0)
171             Method(1, 1)
172         for th in self.list:
173             th.join()
174         ch = False
175         if reverse and visible and(j > 1):
176             ch = True
177         if ch:
178             self.proc()     
179         return p[1]
180                             
181     def NextStone(self,stone,pos):
182         result = False
183         n = 0
184         self.score = 0        
185         for i in range(8):
186             for j in range(8):
187                 if (self.CalScore(stone, i, j) == True)and((result == False)or(n > self.score)):
188                     if result == False:
189                         result = True
190                     n = self.score
191                     pos[0],pos[1] = i,j
192         return result
193     
194     def Start(self):       
195         global index 
196         index = player1
197         self.Clear()
198         self.active = True
199         self.gameover = False
200         
201     def ReStart(self):
202         self.active = True
203         self.gameover = False
204         self.turn_index = self.turn_number
205         
206     def Pause(self):
207         self.active = False
208         
209     def th_run(self,st):
210         while True:
211             if st.X < index_x:
212                 st.X += 1
213             elif st.Y < index_y:
214                 st.X = 0
215                 st.Y += 1
216             else:   
217                 self.item.grid[st.Left][st.Top] = self.effect_stone
218                 break
219             self.Paint(st)
220             time.sleep(0.01)
221                 
222     def proc(self):    
223         if self.turn_index < 60:                               
224             self.turn_index += 1
225             self.turn_number += 1  
226             self.buffer[self.turn_index].Assign(self.item)        
227             self.buffer[self.turn_index].stone = self.effect_stone      
228             ChangePlayer()                                                 
229             if self.gameover == False:             
230                 self.active = True
231         else:
232             self.gameover = True
233     
234     def Paint(self,p):
235         if self.effect_stone == black:
236             s = bkblack            
237         else:
238             s = bkwhite
239         i = 0
240         screen.blit(s,(p.Left*50,p.Top*50),(p.X*50,p.Y*50,50,50))
241         i += 1       
242         pygame.display.update()
243            
244 def Paint():
245     for x in range(8):
246         for y in range(8):
247             s = stone_grid.item.grid[x][y]
248             r = pygame.Rect(x*size,y*size,(x+1)*size,(y+1)*size)
249             if s == white:
250                 screen.blit(img,r,pygame.Rect(2*size,0,3*size,size))
251             elif s == black:
252                 screen.blit(img,r,pygame.Rect(size,0,2*size,size))
253             elif s == effect:
254                 continue
255             else:
256                 screen.blit(img,r,pygame.Rect(0,0,size,size))
257     if stone_grid.gameover == True:
258         screen.blit(stone_grid.text,pygame.Rect(0,0,800,50))
259     pygame.display.update()
260        
261 def ChangePlayer():  
262     def Main():
263         global index        
264         if index == player1:
265             index = player2
266             return 'white'
267         else:
268             index = player1
269             return 'black'  
270     
271     def Execute():
272         for x in range(8):
273             for y in range(8):
274                 if stone_grid.CanSetStone(index.stone, x, y, False) == True:
275                     return True
276         return False
277         
278     s = Main()+str(stone_grid.turn_index+1)
279     if Execute() == False:
280         s = Main()+str(stone_grid.turn_index+1)
281         if Execute() == False:
282             s = 'game over'
283             i = 0
284             j = 0
285             for x in range(8):
286                 for y in range(8):
287                     if stone_grid.item.grid[x][y] == black:
288                         i += 1
289                     elif stone_grid.item.grid[x][y] == white:
290                         j += 1
291             pygame.display.set_caption(s+str(stone_grid.turn_index+1))
292             if i > j:
293                 s = 'Player1 Win!'
294             elif i < j:
295                 s = 'Player2 Win!'
296             else:
297                 s = 'Draw'            
298             stone_grid.text = pygame.font.SysFont(pygame.font.get_fonts()[0],25,True).render(s+'(Player1){0}(Player2){1}'.format(i,j),False,(0,0,255)).convert()
299             stone_grid.gameover = True
300             Paint()
301         else:
302             pygame.display.set_caption(s)
303     else:
304         pygame.display.set_caption(s)
305         
306 def CompStone():
307     pos = [0,0]
308     stone_grid.active = False
309     if stone_grid.NextStone(index.stone, pos) == True:
310         stone_grid.CanSetStone(index.stone, pos[0], pos[1], True, True)        
311     else:
312         ChangePlayer()
313                  
314 player1 = Player()
315 player2 = Player()
316 index = player1
317 player1.stone = black
318 player1.auto = True
319 player2.auto = True
320 player2.stone = white
321 stone_grid = StoneGrid()
322 stone_grid.Start()
323 pygame.event.get()
324 temp = pygame.time.get_ticks()
325 Paint()
326 while True:    
327     if pygame.time.get_ticks()-temp > 300:
328         if (stone_grid.active == True)and(index.auto == True):        
329             CompStone()                                 
330         temp = pygame.time.get_ticks()
331     pygame.time.wait(150)
332     for x in pygame.event.get():
333         if x.type == QUIT:
334             for th in stone_grid.list:                
335                 th.join()
336             sys.exit()    
337     t = pygame.mouse.get_pressed()[0]
338     if (stone_grid.gameover == True)and(t == True):
339         stone_grid.Start()
340     if (index.auto == False)and(stone_grid.active == True)and(t == True):            
341         stone_grid.active = False
342         s = pygame.mouse.get_pos()
343         stone_grid.CanSetStone(index.stone,s[0]//50,s[1]//50,True,True)        
344         stone_grid.active = True    
345