Estoy haciendo un juego tipo Yahtzee con 5 dados usando Flutter + Dart. Mantengo los valores de los dados en un List<int>. ¿Cuál sería la mejor manera de verificar si hay una casa llena y cuál es la suma o los dados relevantes?

Si solo quiero determinar si tengo una casa completa, esta solución sería buena. Pero tengo que calcular la suma después, así que necesito saber cuántos números tengo.

Hacer 30 if s para cubrir cada caso es una solución, pero probablemente no sea la mejor. ¿Alguien tiene alguna idea mejor?

1
vtomic85 8 dic. 2019 a las 18:52

2 respuestas

La mejor respuesta

Aquí habría una implementación simple de Dart usando los métodos List / Iterable:

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);

Como puede ver, separé la suma y el cheque de casa completo, pero también puedo ajustar esto si es necesario.

Extensión

Si está utilizando un Dart 2.6 o posterior, también podría crear un buen extension para esto:

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);
}

Pruebas

Este sería un uso simple de las funciones para probar:

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);
}
0
creativecreatorormaybenot 8 dic. 2019 a las 16:28

¿Por qué no solo usar la solución vinculada?

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
}
0
Abion47 9 dic. 2019 a las 01:12