【问题标题】:Java Monopoly-ish GameJava 大富翁游戏
【发布时间】:2012-02-22 20:14:20
【问题描述】:

我正在开发一款基于大富翁的游戏,其中包含属性、金钱、卡牌等。我最近在处理游戏的机会卡方面遇到了一个问题...

我有一组字符串,例如,“退税;收取 25 美元”或“您因股票而亏损;-100 美元”。每张卡都有不同的作用,并非所有卡都只处理金钱。我的问题:我怎样才能将这些卡片存储到每个卡片都包含一个带有其描述的字符串以及所涉及的任何操作。例如,card1 有一个 String 和一个 int 值 (-25),但另一方面,另一张卡 card2 有一个 String、一个 int 值 (+10) 和一个属性。对不起,如果这个问题真的很模糊,但我不知道如何描述它。

澄清一下:

一张卡片可以只包含描述和货币价值。而另一张卡片可能包含描述、货币价值和移动某些空间。

感谢大家这么快就提出了很棒的想法!

【问题讨论】:

  • 为 Card 创建一个类,使用 Command Pattern 设计模式,这样每张卡片可以在需要时具有不同类型的操作。因此它将包含一个字符串字段、文本、一个 int 字段、值和另一个用于表示您的操作的接口的字段。
  • @HovercraftFullOfEels 您应该将其添加为答案。
  • 一张卡片可以有哪些可能的操作?
  • 顺便说一句,RotateText 将来可能会派上用场。

标签: java arrays swing


【解决方案1】:

创建一个Card 类,带有一个名为text 的字符串,以及一个名为onAction() 的方法。然后,制作许多其他类 - 每张卡片一个 - 扩展 Card 类。给字符串你想要的文本,然后在方法中你可以准确地输入你想要发生的事情。您可以创建一个名为Deck 的类,其中包含所有这些Cards 和一个数组/列表的实例,以及一个draw() 方法或您已经完成的任何事情。在从Deck 绘制Card 时,让它打印Card 的文本并调用它的onAction() 方法。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    这是一个允许每张卡片有多个动作的解决方案。

    ActionType 是一个接口,因为它只有几个正确的值。

    所有字段都是最终的,因为一旦创建了卡片,就不允许更改。

    getActions() 方法返回数组的副本,因为我们不希望游戏能够在创建后修改卡片的操作。

    enum ActionType {
        MONEY, MOVE, ...
    }
    
    class Action {
        private final String description;
        private final ActionType type;
        private final int value;
    
        public Action(String desc, ActionType type, int value) {
            this.description = desc;
            this.type = type;
            this.value = value;
        }
    
        public String getDescription() {
            return description;
        }
    
        public ActionType getType() {
            return type;
        }
    
        public int getValue() {
            return value;
        }
    
    }
    
    class Card {
        private final Action[] actions; // If you want to be able to modify the list of actions after creation, use a non-final List<>, otherwise an array
    
        public Card(Action... actions) {
            this.actions = actions;
        }
    
        public Action[] getActions() {
            Action[] copy = new Action[actions.length];
            System.arraycopy(actions, 0, copy, 0, actions.length);
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果您的动作范围非常有限(例如,涉及金钱、移动格子等的 2 或 3 个动作),那么我可能会使用以下类:

      class Card {
          // It would be a good practice to not make the following fields
          // public and use getters/setters instead but I've made them this
          // way just for illustration purposes
      
          public String text;
          public String action;
          public int value;
      
          Card(String text, String action, int value) {
              this.text = text;
              this.action = action;
              this.value = value;
          }
      }
      

      这样(正如其他一些答案已经指出的那样),您可以使用Cards 的数组而不是Strings 的数组。然后,您可以在一个字段中包含文本,在单独的字段中包含操作,在第三个字段中包含与该操作关联的值。例如,您可能有以下卡片:

      Card lose25 = new Card("You lose $25", "money", -25);
      Card move5squares = new Card("Move 5 squares ahead!", "move", 5);
      

      当您“处理”卡片时,您可以通过以下方式进行:

      ...
      if (card.action.equals("money") {
          // Update user's money with card.value
      } else if (card.action.equals("move") {
          // Update user's position with card.value
      } else if (card.action.equals("...") {
          // and so on...
      }
      ...
      

      编辑:
      如果卡片可以包含多个操作,您可以使用 HashMap 来存储该卡片的操作:

      class Card {
      
          public String text;
          public HashMap<String, Integer> actions;
      
          Card(String text) {
              this.text = text;
              actions = new HashMap<String, Integer>();
          }
      
          addAction(String action, int value) {
              actions.put(action, value);
          }
      }
      

      HashMap 是一个可以存储键值对的集合。所以对于一张有 2 个动作的卡片,你可以使用上面的代码:

      Card aCard = new Card("Lose $25 and move back 3 spaces!");
      aCard.addAction("money", -25);
      aCard.addAction("move", -3);
      

      现在,当您实际处理卡片时,您需要检查HashMap 以了解存储在此卡片中的所有操作。遍历HashMap 的一种方法是执行以下操作:

      Card processCard = ...;
      
      for (Map.Entry<String, Integer> entry : processCard.actions.entrySet()) {
          // This loop will get each 'action' and 'value' that you added to
          // the HashSet for this card and process it.
      
          String action = entry.getKey();
          int value = entry.getValue();
      
          // Add the earlier 'card processing' code here...
      
          if (action.equals("money") {
              // Update user's money with value
          } else if (action.equals("move") {
              // Update user's position with value
          } else if (action.equals("...") {
              // and so on...
          }
      }
      

      【讨论】:

      • 我可以在一张卡片中执行多个操作吗?如“输25美元,后退3格”
      • 那么在您的新示例中,使用 2 个操作声明新卡的方法是什么?
      • 哇,很棒的解决方案。非常感谢你的好主意和演练。我迫不及待地想直接创造大量很酷的卡片创意。
      • 我试图说明基础知识......希望它有所帮助。基本上,使用这种方法,您可以在卡片中存储任意数量的操作......甚至根本不存储任何操作。如果动作的不同类型是有限的,那么循环内的if块不应该太大。
      • @mbreen:我发布了一个解决方案,允许您在新答案中对每张卡片执行多项操作。
      【解决方案4】:

      为 Card 创建一个类,使用 Command Pattern 设计模式,这样每张卡片都可以在需要时具有不同类型的操作。因此它将包含一个字符串字段、文本、一个 int 字段、值和另一个用于表示您的操作的接口的字段。

      关键字段是“action”字段,其中包含对接口类型的引用,例如 CardAction:

      interface CardAction {
         execute();
      }
      

      或者,如果您想使用现成的接口,您可以使用 Runnable 或 Future。通过这种方式,您可以为不同类型的卡片注入具有不同操作的此类对象。这将避免您必须创建多个不同的 Card 类。

      【讨论】:

      • 我投了赞成票,因为这是处理事情的正确方式,但不确定这是否是 OP 能够接受的复​​杂程度。我并不是说听起来不雅,但更适合初学者的东西可能是合适的。例如,如果动作的范围非常有限(2 或 3 个动作),则另一个字符串可以存储该动作,而一个 int 用于存储与该动作关联的值。
      • 对命令模式不太熟悉,但我会研究一下。谢谢!我一直在寻找新技术
      【解决方案5】:

      有一个带有描述和价值的 Card 类。

      Card
      {
      String description;
      int value;
      
          Card(String desc, int value)
          {
          this.description = desc;
          this.value = value;
          }
      
          getters..
          setters...
          }
      

      创建类似的对象

      Card c = new Card("You may loose 25$...", -25);
      

      请注意,这些具有 int 值的卡可以接受介于 -2,147,483,648 到 2,147,483,647 之间的值。如果您想要一些更高的值,您可以将 int 更改为 long 或其他值。

      【讨论】:

      • "请注意,这些具有 int 值的卡可以接受 -128 到 127 之间的值" - 不正确。它们可以存储从 -2,147,483,648 到 2,147,483,647(32 位整数)的值。
      • @Dawood,你说得对,我正在做 2s 恭维课,并且印象相同。更新了我的答案
      • 太棒了。虽然我怀疑 OP 是否会拥有涉及超过 21.5 亿美元交易的垄断卡 :)
      • 是的,不用担心整数范围哈哈。但我喜欢这个简单的解决方案,当我遇到一张卡有(“description”,-25)但另一张卡有(“description”,+100,-1 属性)的问题时,我已经在实施它了。有些卡片包含超过 1 个“动作”
      【解决方案6】:

      创建一个卡片类,它应该包含描述 (String) 和一个值 (int) (+10,-2​​5, 0 等...)。然后你会得到一个卡片数组而不是字符串数组。

      【讨论】:

        猜你喜欢
        • 2012-02-20
        • 1970-01-01
        • 2021-05-29
        • 2015-06-12
        • 2014-01-21
        • 1970-01-01
        • 2012-04-28
        • 2014-08-11
        • 1970-01-01
        相关资源
        最近更新 更多