steveyehtw's picture
Add independent Lessons 23–25 auction project and parent demo
cb6638a
Raw History Blame Contribute Delete
3.5 kB
"""荒謬商品拍賣會:使用虛擬幣,所有資料只留在本次執行。"""
PRODUCT = "永遠慢一天的作業提醒手錶"
BUDGET = 100
START = 10
STEP = 5
PLAYERS = ["甲", "乙", "丙"]
BOTS = [("模擬買家甲", 30), ("模擬買家乙", 45), ("模擬買家丙", 60)]
def ask_bid(name, minimum, sealed=False):
if minimum > BUDGET:
return 0
while True:
prompt = "秘密出價" if sealed else "出價"
raw = input(f"{name},{prompt} {minimum}~{BUDGET} 幣,0 放棄:").strip()
try:
bid = int(raw)
except ValueError:
print("請輸入整數。")
continue
if bid == 0 or minimum <= bid <= BUDGET:
return bid
print(f"出價需在 {minimum}~{BUDGET} 幣之間。")
def open_round(players, solo=False):
"""每次新出價都公開;全員一整輪沒有加價即開標。"""
winner, price = "", 0
while True:
changed = False
for name in players:
if name == winner:
continue
minimum = price + STEP if winner else START
bid = ask_bid(name, minimum)
if bid:
winner, price, changed = name, bid, True
print(f"目前最高:{winner}|{price} 幣")
if solo:
for bot, cap in BOTS:
minimum = price + STEP if winner else START
if bot != winner and minimum <= min(cap, BUDGET):
winner, price, changed = bot, minimum, True
print(f"{bot} 公開出價:{price} 幣")
if not changed or price >= BUDGET:
return winner, price
def sealed_round(players, solo=False):
"""每人一次;同價依收件順序。現場以紙條先寫好再輸入。"""
offers = []
print("先各自寫好出價,再由主持人輸入;開標前不要讓其他人看 Console。")
for name in players:
bid = ask_bid(name, START, sealed=True)
if bid:
offers.append((name, bid))
if solo:
offers.extend((name, cap) for name, cap in BOTS if START <= cap <= BUDGET)
return max(offers, key=lambda offer: offer[1], default=("", 0))
def announce(result):
winner, price = result
if not winner:
print("流標:沒有符合條件的出價。")
return
print(f"{winner} 得標|成交 {price} 幣|剩餘 {BUDGET - price} 幣")
def compare(sealed, opened):
print("\n成交價比較(共同尺度:每格 5 幣,數字是實際價格)")
for label, (winner, price) in [("秘密出價", sealed), ("公開出價", opened)]:
print(f"{label}|{'█' * (price // 5)} {price} 幣" if winner else f"{label}|流標")
print("想一想:看到別人出價時,你有改變原本的決定嗎?")
def main():
if not 1 <= START <= BUDGET or STEP < 1:
print("請設定 1 ≤ 起標價 ≤ 預算,最低加價至少 1 幣。")
return
print(f"\n荒謬商品拍賣會|{PRODUCT}")
print(f"每人 {BUDGET} 枚虛擬幣|起標 {START}|公開加價至少 {STEP} 幣")
print("所有人都可以放棄。相同價格的秘密出價,以先收到的為準。")
sealed = sealed_round(PLAYERS)
announce(sealed)
print("\n公開出價開始:每位買家的預算重新計算。")
opened = open_round(PLAYERS)
announce(opened)
compare(sealed, opened)
if __name__ == "__main__":
main()