【问题标题】:How to check and calculate full house of dice如何检查和计算骰子满屋
【发布时间】:2019-12-09 09:12:31
【问题描述】:

我正在使用 Flutter + Dart 制作一个带有 5 个骰子的类似 Yahtzee 的游戏。我将骰子值保存在List<int> 中。检查是否有满堂彩的最佳方法是什么?总和或相关骰子是多少?

如果我只想确定我是否有满屋,this solution 会很好。但是我必须在之后计算总和,所以我需要知道我有多少个数字。

制作 30 个ifs 来覆盖每个案例一个解决方案,但可能不是最好的解决方案。有人有更好的主意吗?

【问题讨论】:

  • "我必须事后计算总和" - 你的意思是你需要知道五个骰子的总和,例如1, 1, 1, 2, 2->7?我发现在 Yahtzee 游戏中,满屋总是让你得分 25
  • @creativecreatorormaybenot 在我的实现中,我希望它是所有数字的“真实”总和

标签: flutter dart


【解决方案1】:

这是一个使用 List/Iterable 方法的简单 Dart 实现:

bool fullHouse(List<int> dice) {
  final counts = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0};

  dice.forEach((n) => counts[n]++);

  return counts.containsValue(3) && counts.containsValue(2);
}

int diceSum(List<int> dice) => dice.reduce((v, e) => v + e);

如您所见,我将总和和全屋检查分开,但如有必要,我也可以进行调整。

扩展

如果您使用的是 Dart 2.6 或更高版本,您还可以为此创建一个不错的 extension

void main() {
  print([1, 1, 2, 1, 2].fullHouseScore);
}

extension YahtzeeDice on List<int> {
  int get fullHouseScore {
    if (isFullHouse) return diceSum;
    return 0;
  }

  bool get isFullHouse {
    final counts = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0};

    forEach((n) => counts[n]++);

    return counts.containsValue(3) && counts.containsValue(2);
  }

  int get diceSum => reduce((v, e) => v + e);
}

测试

这是测试函数的简单用法:

int checkFullHouse(List<int> dice) {
  if (fullHouse(dice)) {
    final sum = diceSum(dice);
    print('Dice are a full house. Sum is $sum.');
    return sum;
  } else {
    print('Dice are not a full house.');
    return 0;
  }
}

void main() {
  const fullHouses = [
    [1, 1, 1, 2, 2],
    [1, 2, 1, 2, 1],
    [2, 1, 2, 1, 1],
    [6, 5, 6, 5, 5],
    [4, 4, 3, 3, 3],
    [3, 5, 3, 5, 3],
  ],
      other = [
    [1, 2, 3, 4, 5],
    [1, 1, 1, 1, 2],
    [5, 5, 5, 5, 5],
    [6, 5, 5, 4, 6],
    [4, 3, 2, 5, 6],
    [2, 4, 6, 3, 2],
  ];

  print('Testing dice that are full houses.');
  fullHouses.forEach(checkFullHouse);

  print('Testing dice that are not full houses.');
  other.forEach(checkFullHouse);
}

【讨论】:

    【解决方案2】:

    为什么不直接使用链接解决方案?

    bool isFullHouse(List<int> diceResults) {
      String counterString = diceResults.map((i) => i.toString()).join();
      return RegExp('20*3|30*2').hasMatch(counterString);
    }
    
    int getDiceSum(List<int> diceResults) {
      int sum = 0;
      for (int i = 0; i < 6; i++) {
        sum += [0, 0, 2, 0, 3, 0][i] * (i + 1);
      }
      return sum;
    }
    
    // elsewhere
    dice = [0, 0, 2, 0, 3, 0]; // example result
    if (isFullHouse(dice)) {
      int score = getDiceSum(dice);
      // Do something with sum
    }
    

    【讨论】:

    • 既然可以坚持列表,为什么还要使用RegExp?另外,很高兴在这里见到你:)
    • @creativecreatorormaybenot 你在性能上失去了什么,你在简洁和简洁中获得了。对于 Yahtzee 中所有可能的事情,链接问题中都有预先建立的正则表达式模式,您可以获得分数(除了简单的东西,如 6 和机会)。列表和地图同样适用于满堂红,但对于直道等其他东西会涉及更多。这只是“如果它没有坏,就不要修复它”的情况。 (另外,对于这么小的字符串和每秒只被调用几次的方法,性能差异可以忽略不计。)
    猜你喜欢
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2014-12-29
    • 2020-06-06
    • 1970-01-01
    相关资源
    最近更新 更多