1 #-*- coding: utf-8 -*-
2 from Tkinter import *
3 from PIL importImage,ImageTk4
5 importImage,math,random,time,sched6 importthreading as thd7 classcard2:8 #定义全局变量
9 #总牌数
10 num_list = ['3', '4', '5', '6', '7', '8', '9','T', 'J','Q','K', 'A','2']11 #全局变量纪录玩家当前要打出的牌数字
12 #当前牌面字符串
13 str_num = '';14 #当前牌面字符串在num_list中的位置
15 index_num = -1;16 #中间桌面上牌的大小
17 mid_num = -2;18 #判断是否会生成重复的牌
19 check_list =[];20 #记录当前回合数
21 round_num = 1;22 #当前玩家手中牌位置
23 cur_position =0;24 #定义玩家当前手中牌的集合
25 player_card_list =[];26 player1_card_list =[];27 player2_card_list =[];28 player3_card_list =[];29 player4_card_list =[];30
31 #变量判断玩家身份,默认为玩家
32 cur_identify = 1;33
34 def __init__(self):35 self.tk =Tk()36 #tk.geometry('1200x1600')
37 self.tk.title('A Easy Card Game')38
39 self.img = Image.open('images/poker_pot.png')40 self.w_box = 120
41 self.h_box = 120
42 self.w, self.h =self.img.size43 #w,h = img2.size
44 #缩放图像让它保持比例,同时限制在一个矩形框范围内
45 self.img_resized =self.resize(self.w, self.h, self.w_box, self.h_box, self.img)46 self.photo =ImageTk.PhotoImage(self.img_resized)47 #frm_TL = Frame(bg = 'WHITE',width = 300, height = 200)
48 self.frm_T = Frame(bg='white', width=300, height=200)49 self.frm_L = Frame(bg='white', width=300, height=400)50 self.frm_M = Frame(bg='white', width=200, height=400)51 self.frm_R = Frame(bg='white', width=300, height=400)52 self.frm_B = Frame(bg='white', width=400, height=200)53 #frm_TL.grid(row=0,column=0)
54 self.frm_T.grid(row=0, column=1)55 self.frm_L.grid(row=1, column=0)56 self.frm_M.grid(row=1, column=1)57 self.frm_R.grid(row=1, column=2)58 self.frm_B.grid(row=2, column=1)59 #Top
60 Label(self.frm_T, text="Player3", font=('Arial', 16)).grid(column=1, sticky=N)61 Button(self.frm_T, text="重新发牌", command=self.replay, width=8, height=1,62 font=('Arial', 16)).grid(row=0, column=3)63 self.frm_T_label_L = Label(self.frm_T, image=self.photo)64 self.frm_T_label_L.image =self.photo65 self.frm_T_label_L.grid(row=1, column=0, sticky=E)66 #frm_T_label_L.grid(row=1,column=1,columnspan=2,rowspan=2,sticky=W+E+N+S,padx=5,pady=5)
67 self.frm_T_label_M = Label(self.frm_T, image=self.photo)68 self.frm_T_label_M.image =self.photo69 self.frm_T_label_M.grid(row=1, column=1,padx=10, sticky=E)70 self.frm_T_label_R = Label(self.frm_T, image=self.photo)71 self.frm_T_label_R.image =self.photo72 self.frm_T_label_R.grid(row=1, column=2, sticky=E)73
74 #Left
75 Label(self.frm_L, text="Player4", font=('Arial', 16)).grid(row=1, column=0, sticky=N)76 self.frm_L_label_T = Label(self.frm_L, image=self.photo)77 self.frm_L_label_T.image =self.photo78 self.frm_L_label_T.grid(row=0, column=1, sticky=E)79 self.frm_L_label_T = Label(self.frm_L, image=self.photo)80 self.frm_L_label_T.image =self.photo81 self.frm_L_label_T.grid(row=1, column=1, sticky=E)82 self.frm_L_label_T = Label(self.frm_L, image=self.photo)83 self.frm_L_label_T.image =self.photo84 self.frm_L_label_T.grid(row=2, column=1, sticky=E)85
86 #Middle
87 self.frm_M_label_T = Label(self.frm_M, image=self.photo)88 self.frm_M_label_T.image =self.photo89 self.frm_M_label_T.grid(row=1, column=0, sticky=E)90 self.frm_M_text = Text(self.frm_M, width=30, height=6, bg='Green', font=('Verdana', 15))91
92 #self.frm_M_text.insert('1.0', 'this is '+str(self.round_num)+' round\n')
93 #self.frm_M_text.insert(END, 'last round')
94 self.frm_M_text.grid(row=2, column=0, columnspan=2)95
96 #Right frm_R
97 self.frm_R_label_T = Label(self.frm_R, image=self.photo)98 self.frm_R_label_T.image =self.photo99 self.frm_R_label_T.grid(row=0, column=0, sticky=E)100 self.frm_R_label_T = Label(self.frm_R, image=self.photo)101 self.frm_R_label_T.image =self.photo102 self.frm_R_label_T.grid(row=1, column=0, sticky=E)103 self.frm_R_label_T = Label(self.frm_R, image=self.photo)104 self.frm_R_label_T.image =self.photo105 self.frm_R_label_T.grid(row=2, column=0, sticky=E)106 Label(self.frm_R, text="Player2", font=('Arial', 16)).grid(row=1, column=1, sticky=N)107
108 #初始化玩家手中牌
109 self.load_sys()110
111 self.main_start()112
113 self.frm_B_label_T_4 = Label(self.frm_B, image=self.photo)114 self.frm_B_label_T_4.image =self.photo115 self.frm_B_label_T_4.grid(row=0, column=3, sticky=E)116 Label(self.frm_B, text="Player1", font=('Arial', 16)).grid(row=1, column=1, sticky=N)117 Button(self.frm_B, text="出牌", command=self.discard, width=6, height=1,118 font=('Arial', 16)).grid(row=1, column=3)119 Button(self.frm_B, text="PASS", command=self.player_pass, width=6, height=1,120 font=('Arial', 16)).grid(row=1, column=4)121
122 defresize(self,w, h, w_box, h_box, pil_image):123 '''''124 resize a pil_image object so it will fit into125 a box of size w_box times h_box, but retain aspect ratio126 对一个pil_image对象进行缩放,让它在一个矩形框内,还能保持比例127 '''
128
129 f1 = 1.0 * w_box / w #1.0 forces float division in Python2
130 f2 = 1.0 * h_box /h131 factor =min([f1, f2])132 #print(f1, f2, factor) # test
133 #use best down-sizing filter
134 width = int(w *factor)135 height = int(h *factor)136 returnpil_image.resize((width, height), Image.ANTIALIAS)137 defreplay(self):138 self.load_sys()139
140 #初始化玩家手中牌
141 defload_sys(self):142 #初始化当前玩家手中牌集合,先重置
143 self.player1_card_list =[]144 self.player2_card_list =[]145 self.check_list =[]146 self.cur_identify = 1
147 for i in range(3):148 num = random.randint(0,12)149 #判断是否生成重复的牌,去重
150 while self.check_list.__contains__(num):151 num = random.randint(0, 12)152 cur_str =self.num_list[num]153 photo_current = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box, Image.open('images/card_C' + str(cur_str) + '.png')))154 frm_B_label_T_1 = Label(self.frm_B, image=photo_current)155 frm_B_label_T_1.image =photo_current156 frm_B_label_T_1.grid(row=0, column=i,sticky=E)157 frm_B_label_T_1.bind('', self.handlerAdaptor(self.choose, cur_str,i))158 self.check_list.append(num)159 self.player1_card_list.append(cur_str)160 #生成玩家2手中的牌
161 num2 = random.randint(0, 12)162 #判断是否生成重复的牌,去重
163 while self.check_list.__contains__(num2):164 num2 = random.randint(0, 12)165 cur_str2 =self.num_list[num2]166 self.check_list.append(num2)167 self.player2_card_list.append(cur_str2)168
169 print(self.player1_card_list)170 print(self.player2_card_list)171 #记录当前轮数并递增
172 self.frm_M_text.insert('1.0', 'this is' + str(self.round_num) + 'round\n')173 self.round_num+=1
174
175 #清空桌面上的牌
176 frm_M_label_T = Label(self.frm_M, image=self.photo)177 frm_M_label_T.image =self.photo178 frm_M_label_T.grid(row=1, column=0, sticky=E)179 #重置玩家手中当前牌
180 frm_B_label_T_4 = Label(self.frm_B, image=self.photo)181 frm_B_label_T_4.image =self.photo182 frm_B_label_T_4.grid(row=0, column=3, sticky=E)183 #重置桌面上牌的大小
184 self.mid_num = -2
185 #Bottom
186 defchoose(self,event,a,position):187 self.frm_M_text.insert('1.0','Now Your Card Is C'+str(a)+'\n')188 photo_cur = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box, Image.open('images/card_C' + str(a) + '.png')))189 frm_B_label_T_4 = Label(self.frm_B, image=photo_cur)190 frm_B_label_T_4.image =photo_cur191 frm_B_label_T_4.grid(row=0, column=3, sticky=E)192 self.str_num =a193 self.cur_position =position194 def handlerAdaptor(self,fun, *kwds):195 '''''事件处理函数的适配器,相当于中介,此处接收2个参数,那个event是从那里来的呢,我也纳闷,这也许就是python的伟大之处吧'''
196 return lambda event,fun=fun,kwds=kwds: fun(event, *kwds)197 defdiscard(self):198 if self.cur_identify == 1:199 if self.str_num != '':200 self.index_num =self.num_list.index(self.str_num)201 if self.index_num == -1:202 self.frm_M_text.insert('1.0','请选择一张牌\n')203 #return '请选择一张牌'
204 #判断要打出的牌与桌面上的牌大小
205 elif self.index_num <=self.mid_num:206 self.frm_M_text.insert('1.0', '请选择一张大牌\n')207 #return '请选择一张大牌'
208 else:209 photo_mid = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box, Image.open('images/card_C' + str(self.str_num) + '.png')))210 frm_M_label_T = Label(self.frm_M, image=photo_mid)211 frm_M_label_T.image =photo_mid212 frm_M_label_T.grid(row=1, column=0, sticky=E)213 #清空玩家手中当前牌
214 frm_B_label_T_4 = Label(self.frm_B, image=self.photo)215 frm_B_label_T_4.image =self.photo216 frm_B_label_T_4.grid(row=0, column=3, sticky=E)217 #frm_B_label_T_4.grid_forget()
218 #给当前桌面牌赋值
219 self.mid_num =self.index_num220 #重置玩家手中牌
221 frm_B_label_T_X = Label(self.frm_B, image=self.photo)222 frm_B_label_T_X.image =self.photo223 frm_B_label_T_X.grid(row=0, column=self.cur_position, sticky=E)224 self.frm_M_text.insert('1.0', 'Player1 Play The Card!'+ str(self.str_num) +'\n')225 self.player1_card_list.remove(self.str_num)226 if self.player1_card_list.__len__() ==0:227 self.frm_M_text.insert('1.0', 'Congratulations! Player1 Win The Game!\n')228 return
229 #当玩家打出牌后,切换到电脑2,调用电脑出牌方法
230 self.cur_identify +=1
231 self.discard_pc(self.cur_identify)232 else:233 self.frm_M_text.insert('1.0', '请等待其它玩家出牌\n')234
235 #没有可出的牌,切换到下一个对手
236 defplayer_pass(self):237 #重置中间牌的大小
238 self.mid_num = -2
239 #切换玩家
240 self.cur_identify += 1
241 self.discard_pc(self.cur_identify)242
243 #def player_pc(self,iden):
244 #if iden == 2:
245 #self.player_card_list = self.player2_card_list
246 #247 #if iden ==3:
248 #self.cur_identify = 1
249
250 defdiscard_pc(self,iden):251 card_list_pc =[]252 if iden == 2:253 for i in range(self.player2_card_list.__len__()):254 #将当前牌转化成索引号进行比较大小
255 self.index_pc_num =self.num_list.index(self.player2_card_list[i])256
257 if self.index_pc_num >self.mid_num:258 card_list_pc.append(self.player2_card_list[i])259 card_list_pc.sort()260 if len(card_list_pc) >0:261 self.index_pc_num_temp =self.num_list.index(card_list_pc[0])262 self.mid_num =self.index_pc_num_temp263 photo_mid =ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box,264 Image.open('images/card_C' + str(card_list_pc[0]) + '.png')))265 frm_M_label_T = Label(self.frm_M, image=photo_mid)266 frm_M_label_T.image =photo_mid267 frm_M_label_T.grid(row=1, column=0, sticky=E)268 self.frm_M_text.insert('1.0', 'Player2 Play The Card!' + str(card_list_pc[0]) + '\n')269 self.player2_card_list.remove(card_list_pc[0])270
271 if self.player2_card_list.__len__() ==0:272 self.frm_M_text.insert('1.0', 'Congratulations! Player2 Win The Game!\n')273 return
274 #当玩家打出牌后,切换到电脑2,调用电脑出牌方法
275 self.cur_identify += 1
276 if self.cur_identify == 3:277 self.cur_identify = 1
278 elif len(card_list_pc) ==0:279 self.frm_M_text.insert('1.0', '没有大过玩家的牌,请玩家出牌\n')280 #重置中间牌的大小
281 self.mid_num = -2
282 self.cur_identify = 1
283
284 ## 实例化一个sched对象
285 #schedule = sched.scheduler(time.time, time.sleep)
286 defshow_time(self):287 cur_time = time.strftime('%Y-%m-%d %X',time.localtime())288 top_time_label = Label(self.frm_T, text=cur_time, font=('Arial', 16))289 top_time_label.grid(column=2, sticky=N)290 whileTrue:291 cur_time = time.strftime('%Y-%m-%d %X', time.localtime())292 top_time_label.configure(text=cur_time)293 time.sleep(1)294 defmain_start(self):295 thd.Timer(0, self.show_time).start()296 defmain():297 d =card2()298 mainloop()299
300 if __name__ == '__main__':301 main()