【问题标题】:Ruby - Player vs Player for Rock, Paper & Scissor Game橄榄球 - 球员与球员的石头、纸和剪刀游戏
【发布时间】:2019-10-29 00:52:00
【问题描述】:

如果我重复其他人之前提出的问题,请道歉。我已经在 stackoverflow 上完成了其他 RSP 游戏问题。大多数是关于播放器与计算机的。可能我需要阅读更多理论以更好地理解并修改代码以适合我的目的,即玩家一与玩家二。

我正在尝试玩家一与玩家二 - Ruby 中的剪刀石头布和纸游戏。我对以下代码有以下疑问。 - 如何隐藏每个玩家条目? - 代码中有很多重复,因此违反了 DRY 原则。我应该如何重构这个? - 类方法是玩这个游戏的最好方法吗(最有效)? - 目前,此游戏仅适用于石头剪刀布。如果我想稍后添加蜥蜴 spock,我应该如何证明这一点?或以最有效的方式添加它? 提前致谢!

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

while true

    print <<TEXT 
1 - rock
2 - scissors
3 - paper
9 - end game
TEXT

    puts "Player 1, choose rock(1), scissors(2), paper(3). To end the game, enter 9."
    player1_val = gets.to_i

    puts "Player 2, choose rock(1), scissors(2), paper(3). To end the game, enter 9."
    player2_val = gets.to_i

    if player1_val == 9 # I am repeating the same condition for player2. How should I combine? 
        puts "End"
        exit
    end

    if player2_val == 9 
        puts "End"
        exit
    end

    player1 = options[player1_val-1]
    player2 = options[player2_val-1]

    if player1 == player2
        puts "Tie, next throw please"
        redo 
    end 

    if player1 == 1 and player2 == 2
        puts "Rock blunts scissors, you win"

    elsif player1 == 2 and player2 == 1
        puts "Rock blunts scissors, you loose"

    elsif player1 == 2 and player2 == 3
        puts "Scissors cut paper, you win"

    elsif player1 == 3 and player2 == 2
        puts "Scissors cut paper, you loose"

    elsif player1 == 3 and player2 == 1
        puts "Paper covers rock, you win"

    elsif player1 == 1 and player2 == 3
        puts "Paper covers rock, you loose"
    end  
end

【问题讨论】:

  • 假设玩家 1 抛出 p1 并且玩家 2 抛出 p2。我们希望确定是否有玩家获胜或p1 == p2。让winners = { "paper"=&gt;"rock", "rock"=&gt;"scissors", "scissors"=&gt;"paper" }。如果winners[p1] == p2,则玩家 1 获胜,如果winners[p2] == p1,则玩家 2 获胜,否则 p1 == p2 并再次投掷。您可能希望在您的代码中使用此结果。
  • 感谢 Cary 提供的代码。我会努力的。 :)

标签: ruby logic rubygame


【解决方案1】:

您提出了一个非常有主见的开放式问题。对于 Stack Overflow,这不是最好的问题。但是,我会试一试。

首先,我会将您的评分代码提取到一个函数中。像这样的:

def battle(p1, p2)
  if p1 == p2
    'Tie!'
  elsif p1 == 'paper' && p2 = 'rock'
    'Paper smothers Rock...Player 1 wins!"
  elsif etc..
end 

这会让你的主循环变得非常小......这几乎总是一件好事。当您开始为代码编写单元测试时,这也将使您的生活变得美好。

至于优化你的游戏结束测试,使用||一次比较几个东西,例如player1_val == 9 || player2_val == 9

我怀疑您的代码不会像当前编写的那样工作。尝试在调试器中逐行运行...或者更简单地说,将puts "var is #{var}" 放在各个位置,转储有趣变量的值。任何一种方法都会很快暴露任何错误并使修复显而易见。

至于使用 Ruby 方式做事,请考虑在选项数组中使用符号而不是字符串。像[:paper, :rock, :scissors] 这样的东西。避免代码中出现幻数。任何时候你的代码中有一个字面数字(也许不是 1 或 0),很有可能你有一个幻数,应该努力使它成为一个常数、符号或方程。

redo 不是一个常用的 Ruby 命令。 (我不得不去查一下它的作用!)你已经有一个循环......你不应该需要重做来完成你的任务。

除了良好的编码实践,我们还可以谈论 UX/UI(用户体验/用户界面)。这对这款游戏来说是一个大问题……玩家不能看到彼此的输入,这一点很重要。对getch 做一些研究。还可以考虑给每个玩家一半的键盘...“ASD”代表一个玩家的三个选择,“JKL”代表另一个玩家。

这些是你可以用来提升你的游戏的一堆想法!祝你好运,在你完成它之后随时跟进。

【讨论】:

  • 感谢您的解释。我根本没有要固执己见的意思。我将检查 getch 并研究我的解决方案。谢谢!
【解决方案2】:

您可以通过以下方式判断获胜者:

choice1, choice2 = (gets.to_i - 1), (gets.to_i - 1)
winner = %w(none player1 player2)[choice2 - choice1 % 3]

让我们测试一下

winner = proc { |choice1, choice2| %w(none player1 player2)[choice2 - choice1 % 3] }

cases = [[0, 0], [0, 1], [0, 2], [1, 2], [2, 0], [2, 1]]
cases.map(&winner) #=> ["none", "player1", "player2", "player1", "player1", "player2"]

同样可以简化输出逻辑。

HOW_TO_WIN = ['Rock blunts scissors',
              'Scissors cut paper',
              'Paper covers rock'].freeze

def player(no: num)
  # ...
  choice = (gets.to_i - 1)
  # ...
end

def play
  choice1, choice2 = [1, 2].map { |num| player(no: num) }
  winner = %w[none player1 player2][choice2 - choice1 % 3]
  how_to = HOW_TO_WIN[choice2 - choice1 % 3]

  if winner == 'none'
    puts 'Tie, next throw please'
  else
    puts "#{how_to}, #{winner} win"
  end
end

play

【讨论】:

  • 谢谢卡文!我仍在学习课程、过程和 lambdas。我可以问你吗?在下面的代码中,为什么选择 choic1 % 3?是正则表达式吗?为什么没有包括在内?我可以知道你为什么选择proc吗? winner = proc { |choice1, choice2| %w(none player1 player2)[choice2 - choice1 % 3] } 。再次感谢。
  • 1) 数学。 (choice2 - choice1) % 3 2) proc 用于使测试代码更易于阅读。 cases.map(&amp;winner)
  • 谢谢卡文。感谢您的解释! 1)%w[none player1 player2][choice2 - choice1 % 3]。我可以知道为什么没有添加吗? 1) [choice2 - choice1 % 3] 为什么是 % 3? % 是模数?抱歉,如果我的问题非常基本。同时我也在学习理论。谢谢!
  • 1) player1 中奖案例[[0,1], [1, 2], [2,0]],player2 中奖案例[[0,2], [1,0], [2,1]]。申请choice2 - choice1[1, 1, -2],[2, -1, -1]。申请%3[1, 1, 1][2,2,2]。所以%w(none player1 player2)[(choice2 - choice1) % 3] 返回了一个赢家。 none 用于领带盒[[0,0],[1,1],[2,2]]
猜你喜欢
  • 2021-09-21
  • 2015-12-19
  • 2013-12-09
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 2017-01-17
  • 2015-05-16
相关资源
最近更新 更多