You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否优化简化这段石头剪刀布Python代码?现有条件判断待改进

Absolutely! That long chain of or conditions in your rock-paper-scissors code is definitely ripe for simplification. Let's walk through a few cleaner, more maintainable approaches to fix that clunky conditional logic.


优化方案1:使用胜负映射字典

This is probably the most intuitive approach—we can store the winning relationships in a dictionary, where each key is a player's choice, and the value is the choice it beats. This eliminates the need for all those or clauses entirely.

import random as ra

out = ['rock', 'paper', 'scissor']
# 定义每个选项能击败的对手
winning_mappings = {
    'rock': 'scissor',
    'paper': 'rock',
    'scissor': 'paper'
}

def match():
    p1, p2 = ra.choice(out), ra.choice(out)
    print(f'P1: {p1} x P2: {p2}')
    if p1 == p2:
        print('Draw\n')
    elif winning_mappings[p1] == p2:
        print('P1 win\n')
    else:
        print('P2 win\n')

for i in range(10):
    match()

优势

  • 可读性强: 任何人看代码都能通过字典一眼看懂胜负规则
  • 易维护: 如果以后要修改规则(比如新增选项),只需要更新字典,不用重写冗长的条件判断
  • 简洁: 把复杂的多条件判断简化成一次字典查找

优化方案2:利用索引的循环数学关系

石头剪刀布的胜负是循环克制的,我们可以用选项列表的索引结合简单数学来判断:

  • rock(索引0)击败scissor(索引2)
  • paper(索引1)击败rock(索引0)
  • scissor(索引2)击败paper(索引1)

你会发现规律:当(p1索引 - p2索引) % 3 == 1时,玩家1获胜,这是因为获胜组合的索引差在模3运算后刚好为1。

import random as ra

out = ['rock', 'paper', 'scissor']

def match():
    # 先随机选索引,再映射到对应选项
    p1_idx = ra.randint(0, 2)
    p2_idx = ra.randint(0, 2)
    p1, p2 = out[p1_idx], out[p2_idx]
    
    print(f'P1: {p1} x P2: {p2}')
    if p1_idx == p2_idx:
        print('Draw\n')
    elif (p1_idx - p2_idx) % 3 == 1:
        print('P1 win\n')
    else:
        print('P2 win\n')

for i in range(10):
    match()

优势

  • 无需硬编码配对: 不用列出所有获胜组合,用数学逻辑自动处理
  • 扩展性好: 如果以后扩展游戏(比如加入蜥蜴和史波克),只需要调整模数值和选项列表,不用修改判断逻辑

优化方案3:使用枚举增强类型可读性

如果想让代码更健壮(避免字符串拼写错误),可以用Python的Enum类型,它提供了命名常量,让代码意图更明确。

import random as ra
from enum import Enum

# 定义枚举类,限定合法选项
class RPSChoice(Enum):
    ROCK = 0
    PAPER = 1
    SCISSOR = 2

# 映射枚举值为人类可读的字符串
choice_to_str = {
    RPSChoice.ROCK: 'rock',
    RPSChoice.PAPER: 'paper',
    RPSChoice.SCISSOR: 'scissor'
}

def match():
    p1 = ra.choice(list(RPSChoice))
    p2 = ra.choice(list(RPSChoice))
    
    print(f'P1: {choice_to_str[p1]} x P2: {choice_to_str[p2]}')
    if p1 == p2:
        print('Draw\n')
    elif (p1.value - p2.value) % 3 == 1:
        print('P1 win\n')
    else:
        print('P2 win\n')

for i in range(10):
    match()

优势

  • 类型安全: 不会出现'roc'这种拼写错误的无效选项,枚举限定了只能选合法值
  • 代码清晰: 枚举让代码意图更明确,尤其适合多人协作的大型项目

这三种方案都比原来的条件链更优秀,你可以根据场景选择:字典法适合小型脚本,索引法适合喜欢数学逻辑的场景,枚举法适合需要结构化、高可维护性的项目。

内容的提问来源于stack exchange,提问作者Salman Abdullah Idrees

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:01:53