日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python17_项目实操关卡-人机PK

發(fā)布時間:2024/1/8 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python17_项目实操关卡-人机PK 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

項目實操關卡-人機PK

通過實戰(zhàn)去成長,這體現(xiàn)在:能在學習初期就知道什么是關鍵知識,了解專業(yè)程序員一般是怎么思考和解決問題的,在一遍遍分析問題、拆解問題及解決問題的過程中真正地理解知識,并用這些知識來解決自己的問題。

一個項目一般是怎么完成的。更具體的說,程序員是如何思考和解決問題的呢?

我認為其中一個很重要的能力是【問題拆解】。問題拆解,指的是在做一件事或面對一個問題的時候,將其拆解成多個步驟或多個層次,逐步執(zhí)行和解決問題,直至達到最終效果。

不過可能是出于長期編寫代碼的習慣,程序員會將問題拆得更細致一些,即拆到無法再拆為止

將完成一個項目的流程總結為以下三步
1.明確項目目標
2.分析過程,拆解項目
3.逐步執(zhí)行,代碼實現(xiàn)

明確項目目標

在互聯(lián)網公司,一般情況下是由產品經理提出明確的項目需求,由程序員來實現(xiàn),他們之間是“相愛相殺”的關系。:)

今天且讓我扮演一下產品經理的角色。我們此次要實現(xiàn)的需求是:人機PK小游戲。具體效果請參照下面的示意動圖。

簡單來說,這個游戲中,會隨機生成玩家和敵人的屬性,同時互相攻擊,直至一方血量小于零。

另外,這樣的戰(zhàn)斗會持續(xù)三局,采取三局兩勝制,最后輸出戰(zhàn)斗結果,公布獲勝方。

分析過程,拆解項目

“功能疊加、難度遞增”這個角度考慮,將我們要實現(xiàn)的小游戲拆分成了三個版本

各版本程序功能描述

  • 版本1.0:規(guī)定雙方角色屬性,戰(zhàn)斗時人為計算扣血量,并打印出戰(zhàn)斗過程;
  • 版本2.0︰隨機生成雙方角色屬性,自動計算扣血量,并優(yōu)化顯示戰(zhàn)斗過程的代碼;
  • 版本3.0:雙方進行3局PK,每局判定勝負。三局兩勝,判斷最終結果.
    ?

當項目被清晰地拆解后,剩下的就是去逐步執(zhí)行,也就是重復“執(zhí)行→遇到問題→解決問題→繼續(xù)執(zhí)行”這個循環(huán)的過程。

逐步執(zhí)行,代碼實現(xiàn)

  • 版本1.0:自定屬性,人工PK版本
  • 版本2.0:隨機屬性,自動PK
  • 版本3.0:打印戰(zhàn)果,三局兩勝

版本1.0:自定屬性,人工PK

我們要做的主要有三步:1.規(guī)定并顯示出玩家和敵人的屬性 2.雙方同時互相攻擊,血量根據對方的攻擊力扣除 3.若有一方血量小于等于0,游戲結束。

好,我們從第1步開始:設定【玩家】和【敵人】的屬性,即【血量】和【攻擊】。

print('【玩家】血量:100 攻擊:50') # 自定義玩家角色的血量和攻擊 print('【敵人】血量:100 攻擊:30') # 自定義敵人角色的血量和攻擊

第2步:手動計算攻擊一次,雙方各自所剩的血量。

print('你發(fā)起了攻擊,【敵人】剩余血量50') # 人工計算敵人血量:100-50=50 print('敵人向你發(fā)起了攻擊,【玩家】剩余血量70') # 人工計算玩家血量:100-30=70

第3步:繼續(xù)做人工計算:算一算,玩家攻擊2次敵人,敵人的血量就等于0了,這時候可以結束戰(zhàn)斗,打印游戲結果。

print('你發(fā)起了攻擊,【敵人】剩余血量0') # 雙方同時攻擊,若血量出現(xiàn)小于等于0,游戲結束 print('敵人向你發(fā)起了攻擊,【玩家】剩余血量40')print('敵人死翹翹了,你贏了!') # 打印結果

很簡單吧!現(xiàn)在我們要做的,就是把這三段代碼拼起來,然后我會加一些修飾視覺的換行符和分割線,讓運行結果看得更清楚一點。

print('【玩家】\n血量:100\n攻擊:50') # 自定義玩家角色的血量和攻擊,用換行符'\n'來優(yōu)化視覺 print('------------------------') # 輔助功能,起到視覺分割的作用,讓代碼的運行結果更清晰print('【敵人】\n血量:100\n攻擊:30') print('------------------------')print('你發(fā)起了攻擊,【敵人】剩余血量50') # 人工計算敵人血量:100-50=50 print('敵人向你發(fā)起了攻擊,【玩家】剩余血量70') # 人工計算玩家血量:100-30=70 print('------------------------')print('你發(fā)起了攻擊,【敵人】剩余血量0') # 雙方同時攻擊,若血量出現(xiàn)小于等于0,游戲結束 print('敵人向你發(fā)起了攻擊,【玩家】剩余血量40') print('-----------------------')print('敵人死翹翹了,你贏了!') # 打印結果

結果

【玩家】 血量:100 攻擊:50 ------------------------ 【敵人】 血量:100 攻擊:30 ------------------------ 你發(fā)起了攻擊,【敵人】剩余血量50 敵人向你發(fā)起了攻擊,【玩家】剩余血量70 ------------------------ 你發(fā)起了攻擊,【敵人】剩余血量0 敵人向你發(fā)起了攻擊,【玩家】剩余血量40 ----------------------- 敵人死翹翹了,你贏了!

唔...雖然看起來還有點兒意思,但所有信息一下子都蹦跶出來,一點都沒有體現(xiàn)游戲的進程感。

所以,為了讓打印出的東西能有時間間隔地依次出現(xiàn),我們需要設置一個類似“計時器”的東西。在Python里,我們需要用到兩行代碼來實現(xiàn):(敲黑板,很簡單的新知識)

import time #調用time模塊 time.sleep(secs) #使用time模塊下面的sleep()函數,括號里填的是間隔的秒數(seconds,簡稱secs) #time.sleep(1.5)就表示停留1.5秒再運行后續(xù)代碼

這里有個新名詞——模塊,它是Python里一個重要的概念

你可以把模塊想象成是一個裝著許多神奇函數的百寶箱,不過想要使用這個百寶箱里的函數,得先用 import 模塊名 這樣一句代碼來打開它。

然后這里我們想使用time模塊里的sleep()函數,也就是讓代碼運行結果不要一次性全部出現(xiàn),而是分批分批的出現(xiàn)。就要寫成time.sleep(secs)的形式。

如果我想設置成打印的信息間隔1.5秒出現(xiàn),代碼就可以這么寫:

import time #通常import語句會寫到代碼的開頭print('【玩家】\n血量:100\n攻擊:50') print('------------------------') time.sleep(1.5) #暫停1.5秒,再繼續(xù)運行后面的代碼print('【敵人】\n血量:100\n攻擊:30') print('------------------------') time.sleep(1.5) #同上print('你發(fā)起了攻擊,【敵人】剩余血量50') print('敵人向你發(fā)起了攻擊,【玩家】剩余血量70') print('------------------------') time.sleep(1.5)print('你發(fā)起了攻擊,【敵人】剩余血量0') print('敵人向你發(fā)起了攻擊,【玩家】剩余血量40') print('-----------------------') time.sleep(1.5)print('敵人死翹翹了,你贏了!')

這個版本的代碼還有兩個明顯的缺陷:一是玩家和敵人的屬性(血量&攻擊)是我自己說了算,那勝負早已沒有懸念;二是戰(zhàn)斗過程中血量的變化要自己手動算,那要計算機有何用?

你放心,這些都是我們會在版本2.0解決的問題。

版本2.0:隨機屬性,自動PK

如前所述,這個階段,我們主要新增【隨機屬性】和【自動戰(zhàn)斗】兩個功能,畫成流程圖是這樣子的:

版本2.0流程圖

  • 隨機生成玩家和敵人的屬性
  • 顯示玩家和敵人的屬性
  • PK過程展示自動攻擊扣血

Python 隨機生成數字

import random #調用random模塊 a = random.randint(1,100) # 隨機生成1-100范圍內(含1和100)的一個整數,并賦值給變量a print(a)

方法步驟

1.定義兩個變量,來存儲玩家血量和玩家攻擊力的數值

2.血量是100-150的隨機數,攻擊力是30-50的隨機數

3.將兩個變量打印出來

import random player_life = random.randint(100,150) #表示玩家血量 player_attack = random.randint(30,50) #表示玩家攻擊 print(player_life) print(player_attack)

標準的變量名最好是用英文來表達含義,如果是多個單詞組成,需要用英文下劃線_來隔開。

對于取英文變量名,很多英語水平在高考即巔峰的同學會感到頭疼,這里我推薦大家一個網站:CODELF(https://unbug.github.io/codelf),輸入中文就可以看到別人是怎么命名的。

好,我們已經知道如何生成隨機屬性,下面我們就要將屬性展示打印出來,請閱讀下列代碼,弄懂每一行的含義:

import time import random #也可合并寫成一行:import time,random# 生成隨機屬性 player_life = random.randint(100,150) # “player_life” 代表玩家血量 player_attack = random.randint(30,50) # “player_attack” 代表玩家攻擊 enemy_life = random.randint(100,150) # “enemy_life” 代表敵人血量 enemy_attack = random.randint(30,50) # “enemy_attack” 代表敵人攻擊# 展示雙方角色的屬性 print('【玩家】\n'+'血量:'+str(player_life)+'\n攻擊:'+str(player_attack)) #player_life和player_attack的數據類型都是整數,所以拼接時需要先用str()轉換 print('------------------------') time.sleep(1) #暫停一秒再執(zhí)行后續(xù)代碼 print('【敵人】\n'+'血量:'+str(enemy_life)+'\n攻擊:'+str(enemy_attack)) print('------------------------')

那截至目前,我們已經完成了隨機生成屬性和展示屬性,接下來我們就來實現(xiàn)"自動戰(zhàn)斗"。

因為現(xiàn)在雙方的血量和攻擊是隨機生成,不是固定的。所以我們不知道具體要戰(zhàn)斗多少回合才能分出勝負,也就是循環(huán)次數不明確,那自然要用while循環(huán)。

while (player_life >= 0) and (enemy_life >= 0): #and兩邊的條件分別用括號括起,是一種習慣,方便閱讀

現(xiàn)在我們確定了執(zhí)行while循環(huán)的條件,接下來就是要填充循環(huán)內部的內容。

根據剛才的分析,我們希望循環(huán)的內容是雙方互相攻擊,掉血的過程。

print('你發(fā)起了攻擊,【敵人】剩余血量xxx') print('敵人向你發(fā)起了攻擊,【玩家】剩余血量xxx') print('------------------------')

其中【敵人】剩余血量=敵人當前血量-玩家攻擊,【玩家】剩余血量=玩家當前血量-敵人攻擊。

事實上我們之前已經定義好了這四個變量,每一次互相傷害后,player_life(玩家血量)和enemy_life(敵人血量)都會被重新賦值,所以轉換為代碼邏輯就是:

player_life = player_life - enemy_attack enemy_life = enemy_life - player_attack #賦值語句的執(zhí)行順序是先計算等號右邊,再賦值給左邊的變量

好,自動攻擊的基礎邏輯也已經理清楚了。我們先合并一下這之前寫過的代碼。

import time,random# 生成隨機屬性 player_life = random.randint(100,150) player_attack = random.randint(30,50) enemy_life = random.randint(100,150) enemy_attack = random.randint(30,50) # 展示雙方角色的屬性 print('【玩家】\n'+'血量:'+str(player_life)+'\n攻擊:'+str(player_attack)) #player_life和player_attack都是整數類型,所以拼接時需要先用str()轉換 print('------------------------') time.sleep(1) print('【敵人】\n'+'血量:'+str(enemy_life)+'\n攻擊:'+str(enemy_attack)) print('------------------------') time.sleep(1)while (player_life >0) and (enemy_life > 0):player_life = player_life - enemy_attack enemy_life = enemy_life - player_attack

補充完成while循環(huán)語句,讓雙方自動戰(zhàn)斗、扣血的過程循環(huán)起來

import time,randomplayer_life = random.randint(100,150) player_attack = random.randint(30,50) enemy_life = random.randint(100,150) enemy_attack = random.randint(30,50) print('【玩家】\n'+'血量:'+str(player_life)+'\n攻擊:'+str(player_attack)) print('------------------------') time.sleep(1) print('【敵人】\n'+'血量:'+str(enemy_life)+'\n攻擊:'+str(enemy_attack)) print('------------------------') time.sleep(1)while (player_life >0) and (enemy_life > 0):player_life = player_life - enemy_attack enemy_life = enemy_life - player_attack print('你發(fā)起了攻擊,【玩家】剩余血量'+str(player_life))#player_life是整數,所以拼接時要先用str()轉換print('敵人向你發(fā)起了攻擊,【敵人】剩余血量'+str(enemy_life))print('------------------------')time.sleep(1.5)# 為了體現(xiàn)出戰(zhàn)斗回合,這里停頓1.5秒

打印出每局結果,三局兩勝,并打印最終戰(zhàn)果的功能。這就是我們在版本3.0要增加的功能

版本3.0:打印戰(zhàn)果,三局兩勝

對比版本2.0,在版本3.0中,我們想要增加的功能是:

1.打印戰(zhàn)果:每局戰(zhàn)斗后,根據勝負平的結果打印出不同的提示;

2.三局兩勝:雙方戰(zhàn)斗三局,勝率高的為最終贏家。

  • 游戲開始
  • ?
  • #循環(huán)三局
  • 隨機生成屬性
  • 顯示屬性
  • PK過程展示
  • 輸出單局結果
  • ?
  • 輸出三局兩勝結果
  • 游戲結束
    ?

反復解釋新增功能,是因為這樣不斷地明確項目的階段性目標,可以讓自己持續(xù)專注地推進項目。

import time,random# 生成雙方角色,并生成隨機屬性。 player_life = random.randint(100,150) player_attack = random.randint(30,50) enemy_life = random.randint(100,150) enemy_attack = random.randint(30,50)# 展示雙方角色的屬性 print('【玩家】\n'+'血量:'+str(player_life)+'\n攻擊:'+str(player_attack)) print('------------------------') time.sleep(1) print('【敵人】\n'+'血量:'+str(enemy_life)+'\n攻擊:'+str(enemy_attack)) print('------------------------') time.sleep(1)# 雙方PK while player_life > 0 and enemy_life > 0:player_life = player_life - enemy_attackenemy_life = enemy_life - player_attackprint('你發(fā)起了攻擊,【玩家】剩余血量'+str(player_life))print('敵人向你發(fā)起了攻擊,【敵人】剩余血量'+str(enemy_life))print('-----------------------')time.sleep(1.5)# 打印戰(zhàn)果 if player_life > 0 and enemy_life <= 0:print('敵人死翹翹了,你贏了') elif player_life <= 0 and enemy_life > 0:print('悲催,敵人把你干掉了!') else:print('哎呀,你和敵人同歸于盡了!')

可以將其拆分成兩個部分:先來個三局,再判斷最終勝負。

首先我們來看,三局戰(zhàn)斗也是一個可以循環(huán)的結構,且循環(huán)次數是固定的,所以要用到for循環(huán)。

在這里我們可以使用for i in range( )的結構,我們先來回顧一下之前學過的range()函數:

range(a,b,c)
a:計數從a開始。不填時,默認從0開始例如, range(1,5),表示從1開始生成
b:計數到b 結束,但不包括b例如, range(11),表示從0開始到11結束,不包括11
c:計數的間隔,不填時默認為1例如, range(0,30,5),表示計數的間隔5
?

嘗試把代碼打出來吧,讓戰(zhàn)斗循環(huán)三局。(先不用統(tǒng)計最后的結果)

給兩個提示:1.想清楚哪些代碼要嵌套到for循環(huán)里,即一局戰(zhàn)斗里包括什么信息。確定了for寫在哪里之后,一句戰(zhàn)斗包含的所有信息都要縮進;

2.細節(jié)也需要留意,如局與局之間要怎么區(qū)分開來(時間間隔&打印局數信息)

之后計算勝場數

player_victory = 0 enemy_victory = 0if player_life > 0 and enemy_life <= 0:player_victory += 1print('敵人死翹翹了,你贏了!') elif player_life <= 0 and enemy_life > 0:enemy_victory += 1print('悲催,敵人把你干掉了!') else:print('哎呀,你和敵人同歸于盡了!')

最終代碼

import time,randomplayer_victory = 0 enemy_victory = 0for i in range(1,4):time.sleep(2) # 讓局與局之間有較明顯的有時間間隔print(' \n——————現(xiàn)在是第'+str(i)+'局——————') # 作為局的標記player_life = random.randint(100,150)player_attack = random.randint(30,50)enemy_life = random.randint(100,150)enemy_attack = random.randint(30,50)# 展示雙方角色的屬性print('【玩家】\n'+'血量:'+str(player_life)+'\n攻擊:'+str(player_attack))print('------------------------')time.sleep(1)print('【敵人】\n'+'血量:'+str(enemy_life)+'\n攻擊:'+str(enemy_attack))print('------------------------')time.sleep(1)# 雙方PKwhile player_life > 0 and enemy_life > 0:player_life = player_life - enemy_attackenemy_life = enemy_life - player_attackprint('你發(fā)起了攻擊,【玩家】剩余血量'+str(player_life))print('敵人向你發(fā)起了攻擊,【敵人】剩余血量'+str(enemy_life))print('-----------------------')time.sleep(1.5)#打印最終戰(zhàn)果if player_life > 0 and enemy_life <= 0:player_victory += 1print('敵人死翹翹了,你贏了!')elif player_life <= 0 and enemy_life > 0:enemy_victory += 1print('悲催,敵人把你干掉了!')else:print('哎呀,你和敵人同歸于盡了!')if player_victory > enemy_victory :time.sleep(1)print('【最終結果:你贏了!】') elif enemy_victory > player_victory:print('【最終結果:你輸了!】') else: print('【最終結果:平局!】')

格式化字符串

print('【玩家】\n'+'血量:'+str(player_life)+'\n攻擊:'+str(player_attack)) print('【敵人】\n'+'血量:'+str(enemy_life)+'\n攻擊:'+str(enemy_attack))

我們在用+拼接字符串和變量的時候,常常需要考慮變量是什么類型的數據,如果不是字符串類型,還先需要str()函數轉換。

并且一句話常常要拼接成好幾個部分,然后我們要考慮每一對引號' '的起始位置,好麻煩,相信你多少會有點體會。

所以,為了更方便地實現(xiàn)不同數據類型的拼接,用【格式符%】是更常用更便利的一種方式

我們可以把%想象成:圖書館里用來占位的一本書。先占一個位置,之后再填上實際的變量。舉個例子:下面這兩種寫法是相同的,請你著重研究下第二行的語法。

print('血量:'+str(player_life)+' 攻擊:'+str(player_attack)) print('血量:%s 攻擊:%s' % (player_life,player_attack))

我們看到格式符%后面有一個字母s,這是一個類型碼,用來控制數據顯示的類型。%s就表示先占一個字符串類型的位置。

常見的類型碼

%d?? 整數

%f?? 浮點數

%s? 字符串

修改過后的代碼

import time import randomplayer_victory = 0 enemy_victory = 0for i in range(1,4):time.sleep(1.5)print(' \n——————現(xiàn)在是第 %s 局——————' % i)#對比之前:(' \n——————現(xiàn)在是第'+str(i)+'局——————')player_life = random.randint(100,150)player_attack = random.randint(30,50)enemy_life = random.randint(100,150)enemy_attack = random.randint(30,50)print('【玩家】\n血量:%s\n攻擊:%s' % (player_life,player_attack))print('------------------------')time.sleep(1)print('【敵人】\n血量:%s\n攻擊:%s' % (enemy_life,enemy_attack))print('-----------------------')time.sleep(1)while player_life > 0 and enemy_life > 0:player_life = player_life - enemy_attack enemy_life = enemy_life - player_attackprint('你發(fā)起了攻擊,【玩家】剩余血量%s' % player_life)print('敵人向你發(fā)起了攻擊,【敵人】的血量剩余%s' % enemy_life)print('-----------------------')time.sleep(1.2)if player_life > 0 and enemy_life <= 0:player_victory += 1print('敵人死翹翹了,你贏了!')elif player_life <= 0 and enemy_life > 0:enemy_victory += 1print('悲催,敵人把你干掉了!')else:print('哎呀,你和敵人同歸于盡了!')if player_victory > enemy_victory :time.sleep(1)print('\n【最終結果:你贏了!】') elif enemy_victory > player_victory:print('\n【最終結果:你輸了!】') else: print('\n【最終結果:平局!】')

總結

以上是生活随笔為你收集整理的Python17_项目实操关卡-人机PK的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。