本節作業: 熟練使用類和模塊,寫一個交互性強、有衝突的程式。 一、作業目的 1、規範程式寫法,要按照模塊來規範書寫; 2、類的使用,文件之間的調用練習; 3、思路的開闊,自己編寫衝突,實現調用; 4、對基礎知識的熟練掌握。 本文寫了一個決鬥系統,兩個男的為了一個女的進行決鬥,獲勝者贏得美女放心,失敗 ...
本節作業:
熟練使用類和模塊,寫一個交互性強、有衝突的程式。
一、作業目的
1、規範程式寫法,要按照模塊來規範書寫;
2、類的使用,文件之間的調用練習;
3、思路的開闊,自己編寫衝突,實現調用;
4、對基礎知識的熟練掌握。
本文寫了一個決鬥系統,兩個男的為了一個女的進行決鬥,獲勝者贏得美女放心,失敗者自擼。
系統功能模塊:
第六天的作業:文字游戲程式是在python3.5.2環境下開發,在python2.7環境下大同小異,主要功能模塊如下圖:
系統目錄結構:
程式採用分層的方式編寫,包括系統配置conf、資料庫訪問層database、業務邏輯層modules,業務處理主程式game_menu.py,主要分類如下圖:
應用知識點
a) 類的使用
b) 文件的讀寫操作
c) 系統模塊、自定義模塊的操作
d) 日誌模塊的使用
程式流程圖如下:
程式代碼如下:
1 主程式game_index.py:
from modules import common from conf import menu,setting from datetime import datetime,date from modules import role import pickle,os,re,sys from database import dbapi _filename = os.path.join(setting.file_path,'game.log') filename = os.path.join(setting.file_path,"vs.log") def duel(skill_num, week_today, date_today, name1, score1, name2, score2,skill_list1,skill_list2): """ 決鬥,兩個人進行決鬥,並計算得分 :param skill_num: 決鬥次數 :param week_today: 星期 :param date_today: 日期 :param name1: 決鬥者1姓名 :param score1: 決鬥者2姓名 :param name2: 決鬥者3姓名 :param score2: 決鬥者4姓名 :return: 返回決鬥得分 """ while True: skill1 = input("決鬥者1請根據實際情況輸入技能編號:") if int(skill1) in list(range(11, len(setting.Skills) + 11)): skill1 = setting.Skills[int(skill1) - 11] if not skill1 in skill_list1: #判斷技能編號是否重覆,同一個技能不能釋放兩次 tem_score1 = setting.Skill_Score[skill1][0] skill_list1.append(skill1) score1 += tem_score1 break else: print("對不起,技能編號不能重覆輸入!") continue else: print("對不起,您輸入的技能編號有誤,請核對後重新輸入!") continue while True: skill2 = input("決鬥者2請根據實際情況輸入技能編號:") if int(skill2) in list(range(11, len(setting.Skills) + 11)): skill2 = setting.Skills[int(skill2) - 11] if not skill2 in skill_list2: #判斷技能編號是否重覆,同一個技能不能釋放兩次 tem_score2 = setting.Skill_Score[skill2][0] skill_list2.append(skill2) score2 += tem_score2 break else: print("對不起,技能編號不能重覆輸入!") continue else: print("對不起,您輸入的技能編號有誤,請核對後重新輸入!") continue with open(_filename, "a+") as f: mess = "第{0}回合 決鬥者1:{1} 得分:{2} vs 決鬥者2:{3} 得分:{4} 日期:{5}\n" f.write(mess.format(skill_num,name1,tem_score1,name2,tem_score2,date_today)) print(menu.duel_message.format(skill_num, week_today, date_today, name1, skill1, tem_score1, name2, skill2, tem_score2)) return (score1, score2) def match_n_score(mes,skill_num,name1,score1,name2,score2): '''第n次比賽得分''' print(mes.format(skill_num,name1,score1,name2,score2)) def finally_score(mes,skill_num,name1,score1,name2,score2): ''' 展示經過幾輪比賽之後最終的得分 :param mes: 展示最終得分框架 :param skill_num: 最終比賽次數 :param name1: 決鬥者1名字 :param score1: 決鬥者1最終得分 :param name2: 決鬥者2名字 :param score2: 決鬥者2最終得分 :return: 無返回值 ''' skill_num = 3 print(mes.format(skill_num,name1,score1,name2,score2)) if __name__ == "__main__": flag = True date_today = date.today().strftime("%Y-%m-%d") week_today = common.week_day(date.today()) while flag: common.home_show(menu.homepage) num = input("請輸入您要查詢的功能編號:") if num == '1': common.stroy_show(menu.story_introduce) common.skill_show(menu.skill_show) elif num == '2': common.pk_show(menu.pk_message,week_today,date_today) '''下麵該實例化類了,生成兩個決鬥實例,決鬥者1和決鬥者2''' print("--------------------------下麵將完善決鬥者1的信息--------------------------------------") name1 = input("請輸入決鬥者1的名字:") age1 = input("請輸入決鬥者1的年齡:") sex1 = "男" '''生成決鬥者1的實例''' m1 = role.Man(name1,age1,sex1) print("\033[31;1m決鬥者1信息完善完畢!\033[0m") print("--------------------------下麵將完善決鬥者2的信息--------------------------------------") name2 = input("請輸入決鬥者2的名字:") age2 = input("請輸入決鬥者2的年齡:") sex2 = "男" '''生成決鬥者2的實例''' m2 = role.Man(name2,age2,sex2) print("\033[31;1m決鬥者2信息完善完畢!\033[0m") '''完善美女的信息''' print("--------------------------下麵將完善美女的信息--------------------------------------") name = input("請輸入美女的名字:") age = input("請輸入美女的年齡:") sex = "女" '''生成美女實例''' w1 = role.Woman(name,age,sex) common.dule_show(menu.start_duel,m1.name,m2.name,w1.name) common.skill_show(menu.skill_show) skill_num = 0 skill_list1 = [] skill_list2 = [] while skill_num < 3: score = duel(skill_num+1,week_today,date_today,m1.name,m1.score,m2.name,m2.score,skill_list1,skill_list2) skill_num += 1 m1.score = score[0] m2.score = score[1] match_n_score(menu.duel_score,skill_num,m1.name,m1.score,m2.name,m2.score) finally_score(menu.finall_score,skill_num,m1.name,m1.score,m2.name,m2.score) '''進行比分判斷如果兩者得分一樣,還要進入加時賽''' if m1.score > m2.score: print(menu.victor_show.format(m1.name,m1.score,m2.name,m2.score,m1.name)) with open(filename,'a+') as fa: mess1 = "經過{0}回合比賽 決鬥者1:{1} 最終得分:{2} vs 決鬥者2:{3} 最終得分:{4} {5}勝利 日期:{6}\n" fa.write(mess1.format(3,m1.name,m1.score,m2.name,m2.score,m1.name,date_today)) role.Woman.bridal_chamber(w1.name,m1.name) elif m1.score < m2.score: print(menu.victor_show.format(m2.name,m2.score,m1.name,m1.score,m2.name)) role.Woman.bridal_chamber(w1.name, m2.name) with open(filename,'a+') as fa: mess1 = "經過{0}回合比賽 決鬥者1:{1} 最終得分:{2} vs 決鬥者2:{3} 最終得分:{4} {5}勝利 日期:{6}\n" fa.write(mess1.format(3,m2.name,m2.score,m1.name,m1.score,m2.name,date_today)) elif m1.score == m2.score: print("兩位決鬥者打成平手,將進入加時賽!!!") while True: skill_num += 1 score = duel(skill_num, week_today, date_today, m1.name, m1.score, m2.name, m2.score, skill_list1, skill_list2) m1.score = score[0] m2.score = score[1] match_n_score(menu.duel_score,skill_num,m1.name,m1.score,m2.name,m2.score) if m1.score > m2.score: print(menu.victor_show.format(m1.name,m1.score,m2.name,m2.score,m1.name)) role.Woman.bridal_chamber(w1.name,m1.name) with open(filename, 'a+') as fa: mess1 = "經過{0}回合比賽 決鬥者1:{1} 最終得分:{2} vs 決鬥者2:{3} 最終得分:{4} {5}勝利 日期:{6}\n" fa.write(mess1.format(skill_num, m1.name, m1.score, m2.name, m2.score, m1.name, date_today)) break elif m1.score < m2.score: print(menu.victor_show.format(m2.name,m2.score,m1.name,m1.score,m2.name)) role.Woman.bridal_chamber(w1.name, m2.name) with open(filename, 'a+') as fa: mess1 = "經過{0}回合比賽 決鬥者1:{1} 最終得分:{2} vs 決鬥者2:{3} 最終得分:{4} {5}勝利 日期:{6}\n" fa.write(mess1.format(skill_num, m2.name, m2.score, m1.name, m1.score, m2.name, date_today)) break elif num == '3': '''數據報表查詢模塊''' dbapi.game_query() elif num == 'q' or num == 'quit': sys.exit("退出,歡迎下次光臨!!!")
2 配置文件包conf
2.1 參數配置文件setting.py
import os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) Skills = ["rich",'poor','handsome','high','short','car','house','struggle','ugly','soso'] Skill_Score = {"rich":[66,'有錢'],"poor":[15,"貧窮"],"handsome":[49,"帥氣"],'high':[36,"高"], "short":[18,"矮"],"car":[40,"有車"],'house':[59,"有房"],'struggle':[42,"上進"], 'ugly':[14,"醜陋"],"soso":[29,"一般"]} file_path = os.path.join(BASE_DIR,"log")
2.2 界面顯示模板文件menu.py
homepage = ''' ----------------------------------------------------------------------------------------------- 歡迎來到PK贏美女平臺 星期:{0} 日期:{1} ----------------------------------------------------------------------------------------------- 【1】平臺介紹 【2】PK場 【3】戰績查詢 【q]退出 ----------------------------------------------------------------------------------------------- ''' story_introduce = '''\033[32;1m ----------------------------------------------------------------------------------------------- \033[34;1m相傳民國時候,如果兩個男的同時愛上一個女的,那麼他們就會通過決戰來獲得美人的芳心。 勝利之人抱得美人歸。\033[0m 比賽規則如下: 1、兩人進行三次比賽,三次比賽總分最高者勝出; 2、如果三次比賽之後,兩人成績一樣,則進入加時賽; 3、加時賽進行次數由此局比薩決定,如果此次某人得分高,則比賽結束,否則一直進行,直到分出勝負; ----------------------------------------------------------------------------------------------- \033[0m''' skill_show = ''' ----------------------------------------------------------------------------------------------- 【技能編號】 【技能名稱】 【技能屬性】 【技能得分】 ----------------------------------------------------------------------------------------------- ''' pk_message = '''\033[38;1m ----------------------------------------------------------------------------------------------- 歡迎來到PK場 星期:{0} 日期:{1} 兩位決鬥者將在這裡進行決鬥,勝利的人將抱得沒人歸來,下麵讓我們拭目以待,看誰將贏得比賽,獲得 美人的芳心。 ----------------------------------------------------------------------------------------------- \033[0m''' start_duel = ''' ----------------------------------------------------------------------------------------------- \033[34;1m下麵有請決鬥者1:{0} 和 決鬥者2:{1} 閃亮登場 並有請美女:{2}在旁邊觀戰,比賽正式開始\033[0m ----------------------------------------------------------------------------------------------- ''' duel_message = ''' ----------------------------------------------------------------------------------------------- 第{0}回合 星期:{1} 日期:{2} ----------------------------------------------------------------------------------------------- 決鬥者1--姓名:{3} 決鬥者2--姓名:{6} VS 技能:{4} 得分:{5} 技能:{7} 得分:{8} ----------------------------------------------------------------------------------------------- ''' duel_score = ''' ----------------------------------------------------------------------------------------------- 第{0}回合 決鬥者1:{1} 累計得分:{2} 決鬥者2:{3} 累計得分:{4} ----------------------------------------------------------------------------------------------- ''' finall_score = """ ----------------------------------------------------------------------------------------------- \033[31;1m 最終得分展示 經過{0}回合比賽 決鬥者1:{1} 最終得分:{2} 決鬥者2:{3} 最終得分:{4} \033[0m ----------------------------------------------------------------------------------------------- """ victor_show = ''' ----------------------------------------------------------------------------------------------- \033[31;1m 決鬥者:{0} 最終得分:{1} 超過 決鬥者:{2} 最終得分:{3} 恭喜決鬥者:{4}最終獲得勝利,將抱得美人歸!!!!Congratulation for you!\033[0m -----------------------------------------------------------------------------------------------
3 資料庫包database:
3.1 數據訪問層模塊dbapi.py
''' Created on 2017年8月6日 @author:耿長學 資料庫訪問層: 提供從數據文件、報表文件中讀取數據的介面 將數據寫入到數據文件的介面 ''' import datetime,re,os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from conf import setting def date_error(dated): ''' 查看日期是否合法 :param dated: 查看的日期 :return: ''' (year,month,day) = dated.split("-") try: normal_date = datetime.date(int(year),int(month),int(day)) return normal_date except ValueError: print("您輸入的日期格式不對,請重新輸入!") def game_query(): File_path = os.path.join(setting.file_path,'game.log') name = input("請輸入您要查詢的決戰者姓名:") while True: start_date = input("請輸入您要查詢的起始日期(yyyy-mm-dd):") start_date = date_error(start_date) if start_date: break else: continue while True: end_date = input("請輸入您要查詢的起始日期(yyyy-mm-dd):") end_date = date_error(end_date) if end_date: break else: continue file_lists = [] if name: with open(File_path,'r+') as f: for line in f: mess = re.search(name,line) if mess: re_date = re.search("\d{4}-\d{2}-\d{2}",line) if re_date: re_date = re_date.group() re_date = date_error(re_date) if re_date >= start_date and re_date <= end_date: file_lists.append(line) else: print("這段時間沒有%s的決鬥記錄!" %(mess.group())) else: print("沒有匹配到日期!") else: pass else: with open(File_path,'r+') as f: for line in f: re_date = re.search("\d{4}-\d{2}-\d{2}",line) if re_date: re_date = re_date.group() re_date = date_error(re_date) if re_date >= start_date and re_date <= end_date: file_lists.append(line) else: sys.exit("開始時間大於結束時間!!!") else: sys.exit("這段時間沒有決鬥信息!!!") '''列印記錄''' if len(file_lists) == 0: pass else: for file_list in file_lists: print(file_list.strip())
4 業務處理包modules:
4.1 公共函數模塊common.py
import os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from conf import menu,setting from datetime import datetime,date def home_show(mes): """ 主頁展示模塊,展示平臺都有哪些功能 :param mes: 展示模板 :return: 無返回值 """ print(mes) def stroy_show(mes): ''' 主題介紹,游戲的主題展示,起源 :param mes: 展示的信息 :return: ''' print(mes) def make_equal_length(length,mes,add=" "): ''' 統一長度,讓看起來整潔好看一點 :param length: 統一幾個字元長度 :param mes: 統一字元的內容 :param add: 填充的字元 :return: ''' if length >= len(mes): mes = mes + (length - len(mes)) * add else: pass return mes def skill_show(mes): ''' 技能展示模塊,展示具有的功能 :param mes:展示的技能 :return: 無返回值 ''' print(mes) for skill_num,skill in enumerate(setting.Skills,11): skill_score = setting.Skill_Score[skill][0] skill_introduce = make_equal_length(2,setting.Skill_Score[skill][1]) skill = make_equal_length(10,skill) print("\033[35;1m%10s%32s%10s%26s\033[0m" %(skill_num,skill,skill_introduce,skill_score)) print("-----------------------------------------------------------------------------------------------") def week_day(mes): ''' 日期轉換函數,將日期轉換為中國人習慣額日期格式 :param date: 要轉換的日期 :return: 返回中文日期 ''' week_lists = ["一","二","三","四","五","六","日"] week_today = week_lists[date.weekday(mes)] return week_today def pk_show(mes,date1,week1): ''' 進入PK場展示 :param mes: 展示的信息 :return: 無返回值 ''' print(mes.format(week1,date1)) def dule_show(mes,name1,name2,name3): ''' 邀請兩位決鬥者登場信息展示 :param mes: 登場展示信息 :return: 無返回值 ''' print(mes.format(name1,name2,name3))
4.2角色類模塊role.py
import os,sys from modules import common BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from conf import setting,menu class Person(object): ''''生成一個男女共有屬性的類''' def __init__(self,name,age,sex): '''實例化類的屬性''' self.name = name self.age = age self.sex = sex class Man(Person): '''生成一個男人類,繼承Person類''' def __init__(self,name,age,sex,score=0): super(Man,self).__init__(name,age,sex) #重寫父類方法,由於上面把父類衝掉了 self.score = score class Woman(Person): '''定義一個女人類,繼承父類Person''' def __init__(self,name,age,sex,belong_to=""): '''重寫父類方法''' super(Woman,self).__init__(name,age,sex) self.belog_to = belong_to @staticmethod def bridal_chamber(name1,name2): '''獲勝者將與美女洞房''' print("\033[34;1m恭喜你贏得這次決賽,奴家%s從此以後屬於你了,今晚我將與%s洞房花燭夜!!\033[0m" %(name1,name2))
5 日誌報表目錄log:
5.1 對戰日誌game.log
第1回合 決鬥者1:alex 得分:66 vs 決鬥者2:wupeiqi 得分:15 日期:2017-08-06 第2回合 決鬥者1:alex 得分:40 vs 決鬥者2:wupeiqi 得分:59 日期:2017-08-06 第3回合 決鬥者1:alex 得分:42 vs 決鬥者2:wupeiqi 得分:18 日期:2017-08-06 第1回合 決鬥者1:張前海 得分:66 vs 決鬥者2:張欣欣 得分:66 日期:2017-08-06 第2回合 決鬥者1:張前海 得分:40 vs 決鬥者2:張欣欣 得分:18 日期:2017-08-06 第3回合 決鬥者1:張前海 得分:42 vs 決鬥者2:張欣欣 得分:40 日期:2017-08-06 第1回合 決鬥者1:孟令號 得分:66 vs 決鬥者2:高自動 得分:40 日期:2017-08-06 第2回合 決鬥者1:孟令號 得分:18 vs 決鬥者2:高自動 得分:36 日期:2017-08-06 第3回合 決鬥者1:孟令號 得分:49 vs 決鬥者2:高自動 得分:18 日期:2017-08-06 第1回合 決鬥者1:林磊 得分:66 vs 決鬥者2:蔣小波 得分:18 日期:2017-08-06 第2回合 決鬥者1:林磊 得分:36 vs 決鬥者2:蔣小波 得分:49 日期:2017-08-06 第3回合 決鬥者1:林磊 得分:42 vs 決鬥者2:蔣小波 得分:59 日期:2017-08-06 第1回合 決鬥者1:於洋 得分:66 vs 決鬥者2:萬寶 得分:40 日期:2017-08-06 第2回合 決鬥者1:於洋 得分:18 vs 決鬥者2:萬寶 得分:36 日期:2017-08-06 第3回合 決鬥者1:於洋 得分:49 vs 決鬥者2:萬寶 得分:15 日期:2017-08-06 第1回合 決鬥者1:張前海 得分:66 vs 決鬥者2:周萬寶 得分:66 日期:2017-08-06 第2回合 決鬥者1:張前海 得分:18 vs 決鬥者2:周萬寶 得分:18 日期:2017-08-06 第3回合 決鬥者1:張前海 得分:36 vs 決鬥者2:周萬寶 得分:49 日期:2017-08-06 第1回合 決鬥者1:喬兵 得分:66 vs 決鬥者2:周瑜 得分:66 日期:2017-08-06 第2回合 決鬥者1:喬兵 得分:15 vs 決鬥者2:周瑜 得分:15 日期:2017-08-06 第3回合 決鬥者1:喬兵 得分:49 vs 決鬥者2:周瑜 得分:49 日期:2017-08-06 第4回合 決鬥者1:喬兵 得分:40 vs 決鬥者2:周瑜 得分:18 日期:2017-08-06 第1回合 決鬥者1:張鵬 得分:66 vs 決鬥者2:高進 得分:66 日期:2017-08-06 第2回合 決鬥者1:張鵬 得分:15 vs 決鬥者2:高進 得分:15 日期:2017-08-06 第3回合 決鬥者1:張鵬 得分:49 vs 決鬥者2:高進 得分:49 日期:2017-08-06 第4回合 決鬥者1:張鵬 得分:42 vs 決鬥者2:高進 得分:40 日期:2017-08-06
5.2 對戰報表vs.log
經過3回合比賽 決鬥者1:alex 最終得分:148 vs 決鬥者2:wupeiqi 最終得分:92 alex勝利 日期:2017-08-06 經過3回合比賽 決鬥者1:張前海 最終得分:148 vs 決鬥者2:張欣欣 最終得分:124 張前海勝利 日期:2017-08-06 經過3回合比賽 決鬥者1:孟令號 最終得分:133 vs 決鬥者2:高自動 最終得分:94 孟令號勝利 日期:2017-08-06 經過3回合比賽 決鬥者1:林磊 最終得分:144 vs 決鬥者2:蔣小波 最終得分:126 林磊勝利 日期:2017-08-06 經過3回合比賽 決鬥者1:於洋 最終得分:133 vs 決鬥者2:萬寶 最終得分:91 於洋勝利 日期:2017-08-06 經過3回合比賽 決鬥者1:周萬寶 最終得分:133 vs 決鬥者2:張前海 最終得分:120 周萬寶勝利 日期:2017-08-06 經過4回合比賽