HandRange.parse constructor

HandRange.parse(
  1. String value
)

Creates a HandRange from a String.

final handRange = HandRange.parse("AhKdAKsT9o55ATs+88+");

This method expects a String that consists of following parts:

  • AhKd - Specific pair of cards. It will literally turn into a CardPair.
  • AKs - All suited combination of CardPairs from two different ranks.
  • T9o - All ofsuit combination of CardPairs from two different ranks.
  • 66 - All pocket pair combination of CardPairs for a specific rank.
  • ATs+ - All suited combination of CardPairs from a specific high rank and the kicker rank that is above than or equal. ATs+ turn into equivalent of ATs, AJs, AQs and AKs.
  • ATo+ - All ofsuit combination of CardPairs from a specific high rank and the kicker rank that is above than or equal. ATo+ turn into equivalent of ATo, AJo, AQo and AKo.
  • JJ+ - All pocket pairs above and equal than a specific rank. JJ+ will turn into equivalent of JJ, QQ, KK and AA.

Available characters for rank are A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3 and 2.

Implementation

factory HandRange.parse(String value) {
  final pocketRankPairs = <RankPair>{};
  final suitedRankPairs = <RankPair>{};
  final ofsuitRankPairs = <RankPair>{};
  final individualCardPairs = <CardPair>{};

  final regex = RegExp(
      r'[AKQJT98765432]{2}[so]?(-[AKQJT98765432]{2}[so]?|\+)?|([AKQJT98765432][shdc]){2}');
  int scanned = 0;

  while (true) {
    final match = regex.firstMatch(value.substring(scanned));

    if (match == null) {
      if (scanned < value.length) {
        if (scanned == 0) {
          throw HandRangeParseFailureException(whole: value);
        }

        throw HandRangeParseFailureException(
          whole: value,
          part: value.substring(scanned),
        );
      }

      break;
    }

    final part = match[0]!;
    scanned += part.length;

    if (RegExp(r'^[AKQJT98765432]{2}-[AKQJT98765432]{2}$').hasMatch(part) &&
        part[0] == part[1] &&
        part[3] == part[4]) {
      final top = Rank.parse(part[0]);
      final bottom = Rank.parse(part[3]);

      for (int i = _ranks.indexOf(top); i <= _ranks.indexOf(bottom); ++i) {
        pocketRankPairs.add(RankPair.pocket(_ranks[i]));
      }

      continue;
    }

    if (RegExp(r'^[AKQJT98765432]{2}[so]-[AKQJT98765432]{2}[so]$')
            .hasMatch(part) &&
        part[0] == part[4] &&
        part[1] != part[5] &&
        part[2] == part[6]) {
      final high = Rank.parse(part[0]);
      final kickerTop = Rank.parse(part[1]);
      final kickerBottom = Rank.parse(part[5]);

      if (high.power > kickerTop.power &&
          kickerTop.power > kickerBottom.power) {
        for (int i = _ranks.indexOf(kickerTop);
            i <= _ranks.indexOf(kickerBottom);
            ++i) {
          if (part[2] == 's') {
            suitedRankPairs.add(RankPair.suited(high, _ranks[i]));
          } else {
            ofsuitRankPairs.add(RankPair.ofsuit(high, _ranks[i]));
          }
        }

        continue;
      }
    }

    if (RegExp(r'^[AKQJT98765432]{2}\+$').hasMatch(part) &&
        part[0] == part[1]) {
      for (int i = 0; i <= _ranks.indexOf(Rank.parse(part[0])); ++i) {
        pocketRankPairs.add(RankPair.pocket(_ranks[i]));
      }

      continue;
    }

    if (RegExp(r'^[AKQJT98765432]{2}[so]\+$').hasMatch(part) &&
        part[0] != part[1]) {
      final high = Rank.parse(part[0]);
      final kicker = Rank.parse(part[1]);

      for (int i = _ranks.indexOf(high) + 1;
          i <= _ranks.indexOf(kicker);
          ++i) {
        if (part[2] == 's') {
          suitedRankPairs.add(RankPair.suited(high, _ranks[i]));
        } else {
          ofsuitRankPairs.add(RankPair.ofsuit(high, _ranks[i]));
        }
      }

      continue;
    }

    if (RegExp(r'^[AKQJT98765432]{2}$').hasMatch(part) &&
        part[0] == part[1]) {
      pocketRankPairs.add(RankPair.pocket(Rank.parse(part[0])));

      continue;
    }

    if (RegExp(r'^[AKQJT98765432]{2}[so]$').hasMatch(part) &&
        part[0] != part[1]) {
      final high = Rank.parse(part[0]);
      final kicker = Rank.parse(part[1]);

      if (part[2] == 's') {
        suitedRankPairs.add(RankPair.suited(high, kicker));
      } else {
        ofsuitRankPairs.add(RankPair.ofsuit(high, kicker));
      }

      continue;
    }

    if (RegExp(r'^([AKQJT98765432][shdc]){2}$').hasMatch(part)) {
      individualCardPairs.add(CardPair.parse(part));

      continue;
    }

    throw HandRangeParseFailureException(whole: value, part: part);
  }

  return HandRange._(
    pocketRankPairs: pocketRankPairs,
    suitedRankPairs: suitedRankPairs,
    ofsuitRankPairs: ofsuitRankPairs,
    individualCardPairs: individualCardPairs,
  );
}