還記得那些年,我們玩過的Windows小遊戲嗎?說起Windows自備的遊戲,相信許多80、90後的朋友都不陌生。在很早的那個遊戲貧瘠的年代, 《紙牌》、《掃雷》等遊戲幫助我們在微電腦課上帶來了許多歡
樂的時光。但在這些遊戲中,有一款遊戲似乎玩得懂的人,甚至知道玩法的人並不多。這款遊戲
就是《紅心大戰》。
最近小編心血來潮仔細鑽研了一下之後,發現這款遊戲玩起來確實比其他的幾款遊戲更有感
一些。因為這款遊戲的玩法簡單概括就是兩個字: 「坑人」 ,而且是明著坑的那種。
1.打開遊戲:雙擊hongxindazhan.py 主程式運行即可!
2.開始遊戲:鍵入玩家姓名,建立新ID,點選確認進入遊戲。
3.遊戲流程:
1)換牌:選出三張手牌,點選上方按鈕完成交換;2)出牌:輪到玩家出牌時,選擇手牌點擊便可打出。 (具體出牌規則詳見附錄)註:當此時機不能打出此牌時,下方提示欄會顯示無法打出原因。
4.統分階段:一輪遊戲過後,會彈出得分錶,顯示玩家和三名電腦每輪積分和總積分,並顯示
玩家當前名次。 (具體勝負判定規則詳見附錄)
5.選單列:
1)遊戲欄: 新遊戲(F2):點選開啟新遊戲。 得分(F4):點選顯示得分錶。 背景音樂:點選切換音樂開關。 選項(F5):點選修改電腦出牌速度。 退出:點擊退出遊戲。 2)幫助欄: 規則介紹(F1):點選顯示簡要規則和獲勝條件。 名言:點擊彈出一則名言。
6.背景音樂:更換:可用自己的wav格式音樂重新命名為'm1.wav'替換程式目錄下的同名檔案。
1.玩遊戲前,需要決定莊家。在電腦中,莊家坐南。 2.拿到一手牌(共13張)後,莊家先必須選出三張牌傳給其他對手。第一局把牌傳給左手邊的玩家;第二局把牌傳給右手邊的玩家;第三局把牌傳給坐在對面的玩家;第四局不傳牌,依此類推。接到莊家的傳牌後,也需要任意傳回給莊家三張牌。在電腦中,如要選牌,點選對應牌張即可。如要取消選定的牌,請再次按一下。 3.抓有梅花2的玩家必須先出梅花2,謂首攻。 4.然後順時針方向出牌。每位玩家依序必須跟同花色牌。如果已經沒有與發牌花色相同的牌,則可以出任何一張牌。唯一例外是不能在第一圈牌中出紅桃或黑桃Q(通常稱為“豬”)。注意:出的同一花色牌中最大的牌會贏取這一圈,贏牌的玩家在下一圈中先出牌。只有前面出過紅桃以後,才可以拿紅桃領出(除非手中只剩下紅桃一種花色的牌張)。 5,、每一輪遊戲結束時,每張紅心計1分,「黑桃皇后(豬)」計13分。遊戲將持續到有人得100分或更多分或莊家退出遊戲時結束。如果在一輪牌中贏得了所有的紅心和「黑桃皇后」(稱之為「全收」),則「全收」者得零分,其餘玩家每人得26分。該遊戲的得分越低越好。
▲環境安裝本文所用的運作環境:Python3.7、Pycharm社群版2020、tkinter模組、部分
自備模組直接導入不需要安裝。 (如果需要安裝軟體、啟動碼或遇到問題的話可以私訊我
哈! ) 模組安裝:pip install -i
https://pypi.douban.com/simple/ +模組名
最原始的綠色背景。 (僅展示背景,其餘圖片比較多不展示)參考為最上方第二張圖片
僅展示主程式原始碼。每行程式碼都有註解所以直接展示!全部的源碼見文末!
從 Tkinter import * from tkFont import * import winsound from tkMessageBox import * from inner import * from dialog import * #遊戲主介面建立classGameFrame:def__init__(self,game,bgimg):#game,Game類別物件; .master = game.root #建立畫布,繪製背景self.c = Canvas(self.master,width = 1024,height = 640) self.c.create_image(514,322,image=bgimg) self.c.pack() #創建狀態條self.status = Label(self.master,text=" 歡迎參加紅心大戰!", bd=1,relief=SUNKEN,anchor=W) self.status.pack(fill = X) #開啟開始對話框startdialog = StartDialog(self.master,"紅心大戰") ifstartdialog.isCancel:game.cancel() else:self.gamemodetext = ['向左傳','向右傳','交叉換牌'] self.name = [startdialog.name,'西','北','東'] self.handXY = [[346.5,490,1,0],[20,135,0,1], [586.5,20,-1,0 ],[913,375,0,-1]] self.nameXY = [[-20,130,SE],[0,-20,SW],[91+20,0,NW],[91,130+20,NE]] self.middleXY = [[466.5,330],[411,255],[466.5,180],[522,255]] self.img = 53* [''] fori inrange(52): self.img[iage] = PhotoImage( file = 'card\%s.pgm'% (i)) self.img[52] = PhotoImage(file = 'back.pgm') self.scorelist = [] self.cards = [] self.gamemode = 0self .speed = 100self.wait = self.speed self.isChanging = False self.iswait = False #繪製名字fori inrange(4): self.c.create_text(self.handXY[i][0]+self.name[i ][0], self.handXY[i][1]+self.nameXY[i][1], fill = 'white',text = self.name[i], anchor = self.nameXY[i][2 ], font = Font(size=15,weight="bold")) #建立手牌self.l = 52* [''] fori inrange(52): self.l[i] = Label(self.master, image=self.img[52],bd = -1) fori inrange(13): self.l[i]['text'] = str(i) self.l[i].bind("<Button-1 >",self.cardEvent) #建立中央牌self.ml = 4* [''] fori inrange(4): self.ml[i] = Label(self.master,image=self.img[52],bd = -1) self.b = Button(self.master,width=15,command=self.buttonEvent) #一輪遊戲開始self.oneGameStart() defoneGameStart(self): #建立Onegame對象,用來取得出牌資訊self.onegame = OneGame() #取得玩家手牌,顯示hand = self.onegame.getPlayerHand(0) fori inrange(13): self.l[i]['image'] = self.img[hand[i] .id] fori inrange(4): forj inrange(13): self.moveCard(i,j,0) #遊戲模式為0,1,2時進入換牌階段ifself.gamemode != 3: self.changeHands( ) else:self.onegame.changeCards([],3) self.isChanging = False self.leftCards = 13#進入出牌階段,玩家前的電腦出牌self.playpreCards() defHands(self): #換牌階段對應初始化self.select = []#所選的牌self.isChanging = True self.isOK = False s = [1,3,2] self.status['text'] = ' 請選三張牌傳給' +self.name[s[self.gamemode]]+'。 '#提示按鈕顯示self.b['text'] = self.gamemodetext[self.gamemode] self.b.place(x = 460,y = 400) self.b['state'] = DISABLED defcardEvent(self, event): #牌的事件#取得牌的位置i = int(event.widget['text']) ifnotself.isChanging:#出牌階段的牌事件#等待中不出牌ifself.iswait:return#出不了的牌不出ifnotself.onegame.available(i): self.status['text'] = self.onegame.errorString returnself.onegame.playCard(i) #所出牌顯示到中央event.widget.place_forget() selfplace_forget() self .ml[self.turn]['image'] = event.widget['image'] self.ml[self.turn].place(x = self.middleXY[0][0],y = self.middleXY[ 0][1]) self.turn += 1self.leftCards -= 1#玩家後的電腦出牌self.iswait = True self.playlaterCards() self.status['text'] = ' 正在等候…'self .wait += 500+ 5* self.speed #等待一段時間後,中央牌清空,玩家前的電腦出牌self.master.after(self.wait,self.playpreCards) self.wait = self.speed else: #換牌階段的牌事件,彈起的落下,落下的彈起ifnotself.isOK:ifi inself.select:self.select.remove(i) self.moveCard(0,i,0) self.b['state '] = DISABLED else:iflen(self.select) < 3: self.select.append(i) self.moveCard(0,i,1) iflen(self.select) == 3: self.b['state' ] = NORMAL defbuttonEvent(self): #提示按鈕事件ifnotself.isOK:#換牌前取得電腦換的牌進行交換self.select = self.onegame.changeCards(self.select,self.gamemode) hand = self.onegame .getPlayerHand(0) fori inrange(13): self.l[i]['image'] = self.img[hand[i].id] self.moveCard(0,i,0) fori inself.select:self .moveCard(0,i,1) self.status['text'] = ' 請按"確定"接受傳來的牌。 'self.b['text'] = '確定'self.isOK = True else:#換牌後進行確認,進入出牌階段,玩家前的電腦出牌fori inself.select:self.moveCard(0,i ,0) self.b.place_forget() self.isChanging = False self.leftCards = 13self.playpreCards() defplaypreCards(self): ifself.leftCards == 0: #牌出完結了進行統分,顯示得分對話框(4): hand = self.onegame.p[i].scoreHand forj inrange(len(hand)): self.l[i*13+j]['image'] = self.img[hand[j]. id] self.moveCard(i,j,0) score = self.onegame.getScore() self.scorelist.append(score) iflen(self.scorelist) != 1: fori inrange(4): self.scorelist[- 1][i] += self.scorelist[-2][i] self.status['text'] = ' 分數'scoredialog = self.showScoreDialog() #分數確認後初始化,開始新一輪遊戲ifscoredialog.isover :self.scorelist = [] self.gamemode = 0else:self.gamemode = (self.gamemode + 1) % 4fori inrange(52): self.l[i].place_forget() self.l[i]['image '] = self.img[52] fori inrange(4): self.ml[i].place_forget() self.oneGameStart() else:#取得玩家之前的電腦出牌,進行顯示fori inrange(4): self .ml[i].place_forget() self.turn = 0preCards = self.onegame.preCard iflen(preCards) == 0: self.end() else:fori inrange(len(preCards)): p,j = preCards[ i][0],preCards[i][1] self.cards.append([self.turn,p,j]) self.master.after(self.wait,self.showMiddleCard) ifp == 3: self. master.after(self.wait,self.end) self.wait = self.speed else:self.wait += self.speed self.turn += 1defplaylaterCards(self): #取得玩家之後的電腦出牌,進行顯示laterCards = self.onegame.laterCard fori inrange(len(laterCards)): p,j = laterCards[i][0],laterCards[i][1] self.cards.append([self.turn,p,j] ) self.master.after(self.wait,self.showMiddleCard) self.wait += self.speed self.turn += 1defmoveCard(self,i,j,state):#i,玩家;j,第幾張牌;state,彈起還是放下#牌的移動self.l[i*13+j].place_forget() x0= self.handXY[i][0] + self.handXY[i][2]*j*20y0 = self.handXY[i][1] + self.handXY[i][3]*j*20self.l[i*13+j].place(x = x0,y = y0- state * 20) defnewGame( self): #新遊戲self.scorelist = [] self.gamemode = 0fori inrange(52): self.l[i].place_forget() self.l[i]['image'] = self.img[52] fori inrange(4): self.ml[i].place_forget() self.oneGameStart() defshowScoreDialog(self): #顯示分數對話方塊scoredialog = ScoreDialog(self.master,self.scorelist,self.name) returnscoreDialog(self.master,self.scorelist,self.name) returnscoreDialog; self): #中央牌顯示i = self.cards[0][0] p = self.cards[0][1] j = self.cards[0][2] del self.cards[0] self.l [p*13+j].place_forget() hand = self.onegame.getPlayerHand(p) self.ml[i]['image'] = self.img[hand[j].id] self.ml[i] .place(x = self.middleXY[p][0], y = self.middleXY[p][1]) defend(self): #電腦出完牌至玩家出牌的切換self.iswait = False self. status['text'] = ' 請出一張牌。 '#遊戲視窗創建,並建立遊戲選單項目classGame:def__init__(self): #建立根窗口,設定self.root = Tk() self.root.title("紅心大戰") self.root.geometry('+ 150+10') self.root.resizable(False, False) #播放背景音樂self.s = winsound.PlaySound('m1.wav', winsound.SND_ASYNC+winsound.SND_LOOP) #建立選單m = Menu(self. root) self.root['menu'] = m gamemenu = Menu(m) helpmenu = Menu(m) m.add_cascade(label = '遊戲',menu = gamemenu) m.add_cascade(label = '幫助',menu = helpmenu) gamemenu.add_command(label="新遊戲F2",command = self.gameEvent1) gamemenu.add_separator() gamemenu.add_command(label="得分... F4",command = self.gameEventemenu.add_command(label="得分... F4",command = self.gameEventemenu.add_command(label="得分... F4",command = self.gameEventeme ="選項... F5",command = self.gameEvent4) self.v = IntVar() self.v.set(1) gamemenu.add_checkbutton(label="背景音樂",variable = self.v, command = self .gameEvent3) gamemenu.add_separator() gamemenu.add_command(label="退出",command = self.cancel) helpmenu.add_command(label="規則介紹... F1",command = self.helpEvent1) helpmenu.add_command(el ="名言...",command = self.helpEvent2) self.root.bind('<F2>',self.gameEvent1) self.root.bind('<F4>',self.gameEvent2) self.root. bind('<F5>',self.gameEvent4) self.root.bind('<F1>',self.helpEvent1) self.root.protocol("WM_DELETE_WINDOW",self.cancel) #匯入背景圖片bgimg = PhotoImage( file = 'bg.gif') #建立主介面self.frame = GameFrame(self,bgimg) #主循環self.root.mainloop() defgameEvent1(self,event=None): #遊戲選單項目」新遊戲「flag = askokcancel('新遊戲','你確定要放棄當前遊戲開始新遊戲麼? ') ifflag:self.frame.newGame() defgameEvent2(self,event=None): #遊戲選單項目」分數「self.frame.showScoreDialog() defgameEvent3(self): #遊戲選單項目」背景音樂「ifself.v .get() == 0: winsound.PlaySound(self.s,winsound.SND_PURGE) else:self.s = winsound.PlaySound('m1.wav', winsound.SND_ASYNC+winsound.SND_selOP) defgameLOOPd None): #遊戲選單項目」選項「optionDialog = OptionDialog(self.root,self.frame.speed / 100- 1) ifnotoptionDialog.isCancel:self.frame.speed = 100+ optionDialog.v.get() *100def self,event=None): #幫助選單項目」規則介紹「HelpDialog(self.root) defhelpEvent2(self): #幫助選單項目」名言「SayDialog(self.root) defcancel(self): #關閉音樂,退出遊戲winsound.PlaySound(self.s,winsound.SND_PURGE) self.root.destroy() defmain(): Game() if__name__== '__main__': main()
科技日新月異,台式「大磚頭」轉眼變成便攜平板,當年偷偷「摸魚」玩這些內建遊戲的人
或成為職場新人,或為人父母,都開始了各自的新階段,這些遊戲也完成自己的使命!
少年時期的遊戲你最喜歡哪一款?話說之前寫過多期遊戲了,需要源碼的記得找我拿!