使用每个类创建一个Rock-Paper-Scissors游戏

时间:2015-11-25 06:15:26

标签: c# oop

今天艰难的任务。我已经在圈子里工作了大约五个小时。我只是无法绕过这个,看看这个上的雾。以下是我们老师今晚指派的作业:

  

创建一个名为的新Visual Studio控制台应用程序   RockPaperScissors。

     

Rock / Paper / Scissors游戏有以下规则:

     
      
  • Scissor总是赢得Paper
  •   
  • Rock总是胜过Scissors
  •   
  • 纸总是胜过Rock
  •   
     

创建以下三个类   遵循以下规则:

     
      
  • PlayerRock - 始终执行Rock的Act()。

  •   
  • PlayerScissors -   始终执行Scissors的Act()。

  •   
  • PlayerPaper - 始终执行   论文()。

  •   
     

创建一个名为的方法的Game类   战斗()满足这些要求:

     
      
  • Fight()方法接受两个参数:Player1和Player2。

  •   
  • Fight()方法调用两个玩家的Act()方法。

  •   
  • Fight()方法使用上面的Rock / Paper / Scissors规则返回获胜玩家。

  •   
     

经过100轮比赛,哪位球员获胜?

我可以轻松地将游戏逻辑和脚本编写出来,没问题。如何使每个武器的法案方法成为现实?并传递一个player1和player2?我是否需要类来创建新的播放器对象?我有Rock,Paper,Scissors课程,但他们基本上只有一种方法可以让他们回归摇滚,纸张和剪刀。我不是要求任何人为我制作这个游戏,但任何人都可以让我指出正确的方向吗?谢谢大家!

3 个答案:

答案 0 :(得分:5)

听起来你需要一个名为abstract的{​​{1}}基类,其抽象Player方法返回Act()(可能只是GameAction,除非你想在enum类中编码游戏逻辑,这很好。)

您可以从GameAction派生出三个类PlayerRock等,并覆盖每个派生类中的Player方法。

调用Act(),传入派生的玩家类的两个实例。在Game.Fight(Player player1, Player player2)内,您应该在两个玩家上调用Fight(...)方法,并根据结果决定谁赢了(如果有人)。

同一位玩家每次都会获胜,但不需要100轮才能表现出来。也许你应该随机生成一些玩家,或者稍后让一些玩家采用更微妙的策略?

抽象和具体类的示例:

Act()

答案 1 :(得分:1)

这是上面的5分钟版本。 (供参考)。

namespace RockPaperScissors
{
    class Program
    {
        private static void Main(string[] args)
        {

            var player1 = new PlayerPaper()
            {
                Name = "Derek",

            };

            var player2 = new PlayerScissors()
            {
                Name = "Jonny"
            };

            var winner = new Battle(player1, player2).PlayMatchUp();

            if (winner == null)
            {
                Console.WriteLine("The Game was a draw.");
            }
            else
            {
                Console.WriteLine("The Winner of this battle : {0}", winner.Name);
            }

            Console.ReadKey();
        }

    }

    public abstract class Player
    {
        public string Name { get; set; }
        public abstract GameAction Act();
    }

    public class PlayerRock : Player
    {
        public override GameAction Act()
        {
            return GameAction.Rock;
        }
    }

    public class PlayerPaper : Player
    {
        public override GameAction Act()
        {
            return GameAction.Paper;
        }
    }

    public class PlayerScissors : Player
    {
        public override GameAction Act()
        {
            return GameAction.Scissors;
        }
    }

    public enum GameAction
    {
        Rock,
        Paper,
        Scissors
    }

    public class Battle
    {
        private readonly Player _player1;
        private readonly Player _player2;

        public Battle(Player player1, Player player2)
        {
            this._player1 = player1;
            this._player2 = player2;
        }

        public  Player PlayMatchUp()
        {

            var result = WinningHand(_player1.Act(), _player2.Act());

            if (_player1.Act() == result)
            {
                return _player1;
            }

            if (_player2.Act() == result)
            {
                return _player2;
            }

            return null;
        }
        private  GameAction? WinningHand(GameAction p1, GameAction p2)
        {
            if (p1 == GameAction.Paper && p2 == GameAction.Rock)
            {
                return GameAction.Paper;
            }

            if (p1 == GameAction.Paper && p2 == GameAction.Scissors)
            {
                return GameAction.Scissors;
            }

            if (p1 == GameAction.Scissors && p2 == GameAction.Paper)
            {
                return GameAction.Scissors;
            }

            if (p1 == GameAction.Scissors && p2 == GameAction.Rock)
            {
                return GameAction.Rock;
            }

            if (p1 == GameAction.Rock && p2 == GameAction.Paper)
            {
                return GameAction.Paper;
            }

            if (p1 == GameAction.Rock && p2 == GameAction.Scissors)
            {
                return GameAction.Rock;
            }

            return null;
        }


    }
}

答案 2 :(得分:0)

通过增量步骤。首先,您不需要RockPaper等单独的类。enum已经足够了:

  public enum Action {
    Rock,
    Paper,
    Scissors
  }

  public static class ActionExtensions {
    // +1 left wins, 0 - draw, -1 right wins
    public static int Outcome(this Action left, Action right) {
      if (left == right)
        return 0;
      else if ((left == Action.Rock) && (right == Action.Scissors) ||
               (left == Action.Paper) && (right == Action.Rock) ||
               (left == Action.Scissors) && (right == Action.Paper))
        return 1;
      else
        return -1;
    }
  } 

然后实施Player及其后代

  public abstract class Player {
    public abstract Action Act();
  }

  public sealed class PlayerRock: Player {
    public override Action Act() {
      return Action.Rock;
    }

    public override String ToString() {
      return "I'm Rock player; I always say 'Rock'";
    }
  }
  ...

最后Game

  public static class Game {
    public static Player Fight(Player player1, Player player2) {
      if (null == player1)
        throw new ArgumentNullException("player1"); 
      else if (null == player2)
        throw new ArgumentNullException("player2"); 

      int score1 = 0;
      int score2 = 0;

      const int upToScore = 100;
      const int maxParties = 1000;

      for (int match = 0; match < maxParties; ++maxParties) {
        if (score1 >= upToScore)
          return player1;
        else if (score2 >= upToScore)
          return player2;

        int outcome = player1.Act().Outcome(player2.Act());

        if (outcome > 0)
          score1 += 1;
        else if (outcome < 0)
          score2 += 1;
      }

      // maxParties passed, and no-one has won; so no winner
      return null;
    }
  }

不要忘记测试

  var player1 = new PlayerRock();
  var player2 = new PlayerScissors(); 

  Console.Write(Game.Fight(player1, player2).ToString());