1. 程式人生 > >python應用開發實戰第一章

python應用開發實戰第一章

第一章:採用面向物件程式設計實現獸人之襲文字遊戲

# python應用開發實戰
#獸人之襲v1.0.面向物件程式設計
'''
需求分析:
1、獲得所有木屋擊敗木屋裡的所有敵人
2、可以在同伴或者無人居住的木屋中治療自身
3、可以選擇放棄戰鬥,在木屋中治療後返回戰鬥
4、引入一個或者多個騎士幫助FOO先生,他們可以輪流佔領木屋
5、可以為每個敵人和騎士配置最大的攻擊點
6、木屋數量實現可配置
7、木屋中可以存放一些黃金或者武器,Foo先生和他的同伴可以撿起這把武器
8、可以讓一個精靈騎士加入隊伍,更大機率獲勝
'''
import random
import textwrap
import sys
if sys.version_info<(3,0):
	print('本程式碼需要在python3.5以上的版本執行')
	print('當前版本號為%d.%d'%(sys.version_info[0],sys.version_info[1]))
	print('正在退出')
	sys.exit(1)
def print_dotted_line(width=72):
	print('-'*width)


def show_theme_message(width=72):
	print_dotted_line()
	print('\033[1;35;34m'+'獸人之襲V0.0.1:'+'\033[0m')
	#---------------------------------------
	#輸出字型顏色格式的更改
	#1:高亮顯示,35:前景色為紫紅色,34:背景色為藍色
	#格式為‘\033[顯示方式;前景色;背景色 +'text' +'\033[0m'
	msg=(
		'人類和他們的敵人——獸人之間的戰爭即將開始,'
		'foo爵士,守衛在南部平原的勇敢騎士之一,開'
		'始了一段漫長的旅途。在一個未知的茂密的森'
		'林,他發現了一個小的孤立居住點,因為'
		'疲勞的原因,再加上希望能補充到糧食儲備,他'
		'決定繞道而行。當他走進村莊時,他看見5個木屋'
		',周圍沒有任何敵人。猶豫之後,他決定走進其中'
		'一間木屋......'
	)
	print(textwrap.fill(msg, width=width//2))#調整輸出格式,以填充的形式輸出


def weighted_random_selection(obj1,obj2):
	weighted_list=3*[id(obj1)]+7*[id(obj2)]
	selction=random.choice(weighted_list)
	if selction==id(obj1):
		return obj1
	else:
		return obj2


def print_bold(msg,end='\n'):
	print('\033[1m'+msg+'\033[0m',end=end)


class gameunit():
	def __init__(self,name=''):
		self.max_hp=0
		self.name=name
		self.health_meter=0
		self.enemy=None
		self.unit_type=None   #表示NPC人物的陣營
	def info(self):
		'''Information on the unit (overridden in subclasses'''
		pass
	def attack(self,enemy):
		injured_unit=weighted_random_selection(self,enemy)
		injury=random.randint(10,15)
		injured_unit.health_meter = max(injured_unit.health_meter - injury, 0)
		print("攻擊! ", end='')
		self.show_health(end='  ')
		enemy.show_health(end='  ')
	def heal(self, heal_by=2, full_healing=True):
		"""Heal the unit replenishing all the hit points"""
		if self.health_meter == self.max_hp:
			return
		if full_healing:
			self.health_meter = self.max_hp
		else:
			self.health_meter += heal_by
			print_bold("已被治療!", end=' ')
			self.show_health(bold=True)
	def reset_health_meter(self):
		"""Reset the `health_meter` (assign default hit points)"""
		self.health_meter = self.max_hp
	def show_health(self, bold=False, end='\n'):
		"""Show the remaining hit points of the player and the enemy"""
		# TODO: what if there is no enemy?
		msg = "生命值: %s: %d" % (self.name, self.health_meter)
		if bold:
			print_bold(msg, end=end)
		else:
			print(msg, end=end)


class knight(gameunit):
	def __init__(self,name='Foo先生'):
		super().__init__(name=name)#呼叫超類的初始化函式
		self.max_hp=40
		self.health_meter=self.max_hp
		self.unit_type='朋友'
	def info(self):
		print ('我是一名騎士')
	def acquire_hut(self,hut):
		print_bold('進入%d號木屋'%hut.number,end='')
		is_enemy=(isinstance(hut.occupant,gameunit)and hut.occupant.unit_type=='敵人')
		continue_attack='y'
		if is_enemy:
			print_bold('發現敵人!')
			self.show_health(bold=True,end='  ')
			hut.occupant.show_health(bold=True,end='')
			while continue_attack:
				continue_attack=input('是否繼續攻擊?(y/n): ')
				if continue_attack=='n':
					self.runaway()
					break
				self.attack(hut.occupant)
				if hut.occupant.health_meter<=0:
					print(' ')
					hut.acquire(self)
					break
				if self.health_meter<=0:
					print(' ')
					break
		else:
			if hut.get_occupant_type()=='無人居住':
				print_bold('木屋無人居住')
			else:
				print_bold('找到一個朋友')
			hut.acquire(self)
			self.heal()
	def runaway(self):
		print_bold('溜了溜了...')
		self.enemy=None


class hut():
	def __init__(self,number,occupant):
		self.occupant=occupant
		self.number=number
		self.is_acquired=False    #木屋是否被調查
	def acquire(self,new_occupant):
		self.occupant=new_occupant
		self.is_acquired=True
		print_bold('幹得好!,%d號木屋已經被調查'%self.number)
	def get_occupant_type(self):
		if self.is_acquired:
			occupant_type='已被調查'
		elif self.occupant is None:
			occupant_type='無人居住'
		else:
			occupant_type=self.occupant.unit_type
		return occupant_type


class orcrider(gameunit):
	def __init__(self,name=''):
		super().__init__(name=name)
		self.max_hp=30
		self.health_meter=self.max_hp
		self.unit_type='敵人'
		self.hut_number=0
	def info(self):
		print('啊啊啊啊!獸人永不為奴!別惹我')


class attackoftheorcs:
	def __init__(self):
		self.huts = []
		self.player=None
	def get_occupants(self):
		return [x.get_occupant_type() for x in self.huts]
	def show_game_mission(self):
		print_bold('任務1:')
		print('1、打敗所有敵人')
		print('2、調查所有木屋,獲取所有木屋的控制權')
		print_dotted_line()
	def process_user_choice(self):
		verifying_choice=True
		idx=0
		print("木屋調查情況: %s" % self.get_occupants())
		while verifying_choice:
			user_choice=input('選擇一個木屋進入(1-5):')
			idx=int(user_choice)
			if self.huts[idx-1].is_acquired:
				print('你已經調察過這個木屋,請再嘗試一次'
					  '提示:不能再已調查的木屋得到治療')
			else:
				verifying_choice=False
		return idx
	def occupy_huts(self):
		for i in range(5):
			choice_list=['敵人','朋友',None]
			computer_choice=random.choice(choice_list)
			if computer_choice=='敵人':
				name='敵人-'+str(i+1)
				self.huts.append(hut(i+1,orcrider(name)))
			elif computer_choice=='朋友':
				name='騎士-'+str(i+1)
				self.huts.append(hut(i+1,knight(name)))
			else:
				self.huts.append(hut(i+1,computer_choice))

	def play(self):
		self.player=knight()
		self.occupy_huts()
		acquires_hut_counter=0
		self.show_game_mission()
		self.player.show_health(bold=True)
		while acquires_hut_counter<5:
			idx=self.process_user_choice()
			self.player.acquire_hut(self.huts[idx-1])
			if self.player.health_meter<=0:
				print_bold('你輸了!祝下次好運!')
				break
			if self.huts[idx-1].is_acquired:
				acquires_hut_counter+=1
		if acquires_hut_counter==5:
			print_bold('祝賀你!,你已經調查完所有的木屋')


if __name__=='__main__':
	game=attackoftheorcs()
	game.play()