用公式逻辑地确定游戏结果 [英] Logically determine game outcome with formula

查看:53
本文介绍了用公式逻辑地确定游戏结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力成为一个更好的编码器,其中包括摆脱我的硬编码"习惯,以保持程序的动态性和易于维护性.

I am trying to become a better coder, which includes getting rid of my 'hard-coding' habits to keep my programs dynamic and easy to maintain.

现在,我正在练习编写一个简单的石头,剪刀,剪刀"游戏:

Right now I am writing a simple Rock, Paper, Scissors game as practice:

import time

validoptions = ["rock", "paper", "scissors"]

u1input = input("User 1, do you want to choose rock, paper or scissors?").lower()
if not u1input in(validoptions):
    u1input = input("What the hell User 1, choose a valid option: rock, paper or scissors?").lower()
u2input = input("User 2, do you want to choose rock, paper or scissors?").lower()
if not u2input in(validoptions):
    u2input = input("What the hell User 2, choose a valid option: rock, paper or scissors?").lower()

u1 = validoptions.index(u1input)
u2 = validoptions.index(u2input)

if u1 - u2 == 0:
    result = "It's a draw! Both parties have proven to be of equal strength."


print("Stakes are high... The battle is on... Calculating losses...")
for i in range(1,4):
    time.sleep(1)
    print("...")

time.sleep(1)
print(result)

对于像Rock,Paper和Scissors这样的游戏,结果并不多(6次赢/输,1次平局或3 ^ 2个人结果).我可以轻松地将所有可能的结果编码到已经编码的抽奖结果旁边.但是,如果游戏扩展了3个选项,该怎么办?说:Rock, Paper, Scissors, Pans, Swords, and Rifles:那将是6 ^ 2 = 36个结果!

For such a game like Rock, Paper, Scissors, there aren't many outcomes (6 wins/losses, and 1 draw outcome, or 3^2 individual outcomes). I could easily code all possible outcomes next to the draw outcome I have already coded. However, what if the game expands with 3 more options? Say: Rock, Paper, Scissors, Pans, Swords, and Rifles: that would be 6^2 = 36 outcomes!

随着此列表的扩展,潜在结果的数量变得越来越难以硬编码.我想使用一种公式或另一种智能"的动态方法来确定游戏的结果,方法与if u1 - u2 == 0:行类似.

As this list expands, the amount of potential outcomes becomes harder to hard-code. I want to use a formula or another 'smart', dynamic method of determining the game's outcome, in a similar fashion to the if u1 - u2 == 0: line.

这有可能吗?

推荐答案

我最初对 R ock– P aper– S的看法剪刀( RPS )规则:

What I initially thought about the Rock–Paper–Scissors (RPS) rules:

  • 这是元素之间的循环关系,其中每个元素在其之前击败一个(剪刀击败(剪切)纸张)
    • 1 st 元素(之前没有任何内容)击败了最后一个元素(并且循环完成了)
    • It's a cyclic relation between the elements where each element beats the one in before it (Scissors beats (cuts) Paper)
      • The 1st element (that doesn't have anything before) beats the last one (and the cycle is complete)

      显然(由于 [Wikipedia]:Rock –paper–剪刀),用于平衡游戏(元素数量奇数):

      Apparently (thanks to [Wikipedia]: Rock–paper–scissors), for a balanced game (odd number of elements):

      • 每个元素都击败了其他元素的一半(结果是输给了另一半)

      • Each element beats half of the other ones (and as a consequence, loses to the other half)

      • (1 st )之前的一个
      • 前3个 rd
      • 第5个
      • ...
      • 到达列表的开头时,跳到结尾(环绕)
      • The (1st) one before it
      • The 3rd one before it
      • The 5th one before it
      • ...
      • When reaching beginning of the list, jump to its end (wrap-around)

      这是3个元素( RPS )游戏的概括(也适用于 RPSLS )

      This is a generalization of the 3 element (RPS) game (and also applies to RPSLS)

      这是上面的规则在输入代码时的样子(我还对它进行了重新设计,以纠正您的代码段中的某些错误).所有的魔术"发生在结果中.

      Here's what the above rule looks like when put into code (I've also redesigned it to correct some errors in your snippet). All the "magic" happens in outcome.

      code00.py :

      #!/usr/bin/env python3
      
      import sys
      
      
      _elements_list = [
          ["Rock", "Paper", "Scissors"],
          ["Rock", "Paper", "Scissors", "Spock", "Lizard"],  # !!! The order is DIFFERENT (RPSSL) than the name of the game: RPSLS !!!
      ]
      
      elements_dict = {len(item): item for item in _elements_list}
      del _elements_list
      
      
      def get_users_choices(valid_options):
          ret = [-1] * 2
          for i in (0, 1):
              user_choice = None
              while user_choice not in valid_options:
                  user_choice = input("Enter user {0:d} option (out of {1:}): ".format(i + 1, valid_options))
              ret[i] = valid_options.index(user_choice)
          return ret
      
      
      def outcome(idx0, idx1, count):  # Returns -1 when 1st player wins, 0 on draw and 1 when 2nd player wins
          if idx0 == idx1:
              return 0
          index_steps = [-i * 2 - 1 for i in range(count // 2)]  # Index steps (n // 2 items) from current index: {-1, -3, -5, ...} (negative values mean: before)
          idx0_beat_idxes = [(idx0 + i + count) % count for i in index_steps]  # Wrap around when reaching the beginning of the list
          if idx1 in idx0_beat_idxes:
              return -1
          return 1
      
      
      def main():
          element_count = 3  # Change it to 5 for RPSLS
          if element_count <= 2:
              raise ValueError("Can't play game")
          elements = elements_dict.get(element_count)
          if not elements:
              raise ValueError("Invalid option count")
          choices = get_users_choices(elements)
          res = outcome(*choices, element_count)
          if res == 0:
              print("'{0:s}' and '{1:s}' are DRAW.".format(elements[choices[0]], elements[choices[1]]))
          elif res < 0:
              print("'{0:s}' WINS over '{1:s}'.".format(elements[choices[0]], elements[choices[1]]))
          else:
              print("'{0:s}' LOSES to '{1:s}'.".format(elements[choices[0]], elements[choices[1]]))
      
      
      if __name__ == "__main__":
          print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
          main()
          print("\nDone.")
      

      输出:

      [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q057491776]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py
      Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32
      
      Enter user 1 option (out of ['Rock', 'Paper', 'Scissors']): Rock
      Enter user 2 option (out of ['Rock', 'Paper', 'Scissors']): Scissors
      'Rock' WINS over 'Scissors'.
      
      Done.
      

      这篇关于用公式逻辑地确定游戏结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆