source/client/RunManagement.py
def processRuns(card_group, wild_numbers):
    """ handle sorting of run, including placement of wilds.  Handles minor rule checking.

    processRuns does not check length requirement or that all cards are in same suit.
    it DOES:
          require that if Aces are not wild, then they are hi or low, but not both.
          require that there must be two naturals between wild cards in runs.
    To preserve info on whether Ace is assigned hi or low, if Ace is assigned low, then tempnumber is set to -1.
    IF ACE CAN BE HIGH OR LOW (very unusual) THAN AUTOMATICALLY MAKING IT LOW.
    """
    # sort card_group by tempnumber and initialize variables.
    card_group.sort(key=lambda wc: wc.tempnumber)
    groups_wilds = []
    temp_run_group = []
    aces_list =[]
    # Separate wilds & Aces that have NOT been assigned from other cards (do wilds before Aces in case Aces are wild).
    for card in card_group:
        if card.tempnumber in wild_numbers:
            groups_wilds.append(card)
        elif card.tempnumber == 1 and card.number == 1:
            aces_list.append(card)
        else:
            temp_run_group.append(card)
    # first pass on run -- check sequence and place or remove wilds.
    card_group, groups_wilds, gap_flag = buildBaseRun(temp_run_group, groups_wilds, wild_numbers)
    # Check if new Aces will free up additional wild cards.
    if len(aces_list) > 0:
        card_group, groups_wilds = acesFreeWilds(card_group, groups_wilds, wild_numbers)
    # second pass on run -- if there were any gaps, see if wilds can fill them in.
    if gap_flag:
        if len(groups_wilds) > 0:
            card_group, groups_wilds = fillGaps(card_group, groups_wilds)
        else:
            text = 'There is a gap between numbers in run beginning with ' + str(card_group[0])
            raise Exception(text)
    # Now assign Aces that were not previously assigned (Aces cannot be moved once assigned).
    if len(aces_list) > 2:
        raise Exception('Cannot play more than 2 Aces in a single run.')
    # Aces can go high or low.  If single Ace can be played in either location (rare) then play it Low.
    elif len(aces_list) > 0:
        lowAceOK = lowAceChk(card_group, groups_wilds, wild_numbers)
        hiAceOK =  hiAceChk(card_group, groups_wilds, wild_numbers)
        if len(aces_list) == 1:
            if hiAceOK and not lowAceOK:
                card_group, groups_wilds, aces_list = appendAce(card_group, groups_wilds, aces_list)
            elif lowAceOK:
                card_group, groups_wilds, aces_list = insertAce(card_group, groups_wilds, aces_list)
            else:
                text = 'Cannot play ' + str(aces_list[0])
                raise Exception(text)
        if len(aces_list) == 2:
            if hiAceOK and lowAceOK:
                card_group, groups_wilds, aces_list = appendAce(card_group, groups_wilds, aces_list)
                card_group, groups_wilds, aces_list = insertAce(card_group, groups_wilds, aces_list)
            else:
                text = 'Cannot play ' + str(aces_list[0])
                raise Exception(text)
   # Check if wild cards can be played  - only possible remaining slots for wilds are at the ends of the current run.
    num_remaining_wilds = len(groups_wilds)
    possible_wild_assignments = []
    if not num_remaining_wilds == 0:
        # are there options on where to assign wilds?
        if num_remaining_wilds > 2:
            raise Exception('You cannot play all the wild cards.')
        if lowWildChk(card_group, wild_numbers):
            runslot = card_group[0].tempnumber - 1
            possible_wild_assignments.append(runslot)
        if hiWildChk(card_group, wild_numbers):
            runslot = card_group[-1].tempnumber + 1
            possible_wild_assignments.append(runslot)
        # If wilds can be automatically assigned, do it.
        if num_remaining_wilds > len(possible_wild_assignments):
            raise Exception('you cannot play all the wild cards.')
        if num_remaining_wilds == len(possible_wild_assignments):
            for this_wild in groups_wilds:
                this_wild.tempnumber = possible_wild_assignments.pop(0)
                card_group.append(this_wild)
            card_group.sort(key=lambda wc: wc.tempnumber)
            groups_wilds=[]
        # if num_remaining_wilds == 1 and len(possible_wild_assignments) == 2:
        # Will need to ask player whether to play high or low, controller handles that.
    # Final rules check in processRuns: double check that wilds are not placed too close together.
    # (Note that in creating possible_wild_assignments checked that assignments won't violate this rule, but didn't
    # check this everywhere).
    last_card_wild = False
    second2last_card_wild = False
    for card in card_group:
        if (isWild(card, wild_numbers) and last_card_wild) or (isWild(card, wild_numbers) and second2last_card_wild):
            raise Exception('Must have two natural cards between wild cards in runs')
        second2last_card_wild = last_card_wild
        last_card_wild = isWild(card, wild_numbers)
    return card_group, possible_wild_assignments, groups_wilds
 handle sorting of run, including placement of wilds.  Handles minor rule checking.

    processRuns does not check length requirement or that all cards are in same suit.
    it DOES:
          require that if Aces are not wild, then they are hi or low, but not both.
          require that there must be two naturals between wild cards in runs.
    To preserve info on whether Ace is assigned hi or low, if Ace is assigned low, then tempnumber is set to -1.
    IF ACE CAN BE HIGH OR LOW (very unusual) THAN AUTOMATICALLY MAKING IT LOW.
    
handle sorting of run, including placement of wilds.  Handles minor rule checking.
processRuns does not check length requirement or that all cards are in same suit.
it DOES:
require that if Aces are not wild, then they are hi or low, but not both.
require that there must be two naturals between wild cards in runs.
To preserve info on whether Ace is assigned hi or low, if Ace is assigned low, then tempnumber is set to -1.
handle sorting of run including placement of wilds . Handles minor rule checking . processRuns does not check length requirement or that all cards are in same suit . it DOES : require that if Aces are not wild then they are hi or low but not both . require that there must be two naturals between wild cards in runs . To preserve info on whether Ace is assigned hi or low if Ace is assigned low then tempnumber is set to - 1 .
def processRuns(card_group, wild_numbers):
    card_group.sort(key=lambda wc: wc.tempnumber)
    groups_wilds = []
    temp_run_group = []
    aces_list =[]
    for card in card_group:
        if card.tempnumber in wild_numbers:
            groups_wilds.append(card)
        elif card.tempnumber == 1 and card.number == 1:
            aces_list.append(card)
        else:
            temp_run_group.append(card)
    card_group, groups_wilds, gap_flag = buildBaseRun(temp_run_group, groups_wilds, wild_numbers)
    if len(aces_list) > 0:
        card_group, groups_wilds = acesFreeWilds(card_group, groups_wilds, wild_numbers)
    if gap_flag:
        if len(groups_wilds) > 0:
            card_group, groups_wilds = fillGaps(card_group, groups_wilds)
        else:
            text = 'There is a gap between numbers in run beginning with ' + str(card_group[0])
            raise Exception(text)
    if len(aces_list) > 2:
        raise Exception('Cannot play more than 2 Aces in a single run.')
    elif len(aces_list) > 0:
        lowAceOK = lowAceChk(card_group, groups_wilds, wild_numbers)
        hiAceOK =  hiAceChk(card_group, groups_wilds, wild_numbers)
        if len(aces_list) == 1:
            if hiAceOK and not lowAceOK:
                card_group, groups_wilds, aces_list = appendAce(card_group, groups_wilds, aces_list)
            elif lowAceOK:
                card_group, groups_wilds, aces_list = insertAce(card_group, groups_wilds, aces_list)
            else:
                text = 'Cannot play ' + str(aces_list[0])
                raise Exception(text)
        if len(aces_list) == 2:
            if hiAceOK and lowAceOK:
                card_group, groups_wilds, aces_list = appendAce(card_group, groups_wilds, aces_list)
                card_group, groups_wilds, aces_list = insertAce(card_group, groups_wilds, aces_list)
            else:
                text = 'Cannot play ' + str(aces_list[0])
                raise Exception(text)
    num_remaining_wilds = len(groups_wilds)
    possible_wild_assignments = []
    if not num_remaining_wilds == 0:
        if num_remaining_wilds > 2:
            raise Exception('You cannot play all the wild cards.')
        if lowWildChk(card_group, wild_numbers):
            runslot = card_group[0].tempnumber - 1
            possible_wild_assignments.append(runslot)
        if hiWildChk(card_group, wild_numbers):
            runslot = card_group[-1].tempnumber + 1
            possible_wild_assignments.append(runslot)
        if num_remaining_wilds > len(possible_wild_assignments):
            raise Exception('you cannot play all the wild cards.')
        if num_remaining_wilds == len(possible_wild_assignments):
            for this_wild in groups_wilds:
                this_wild.tempnumber = possible_wild_assignments.pop(0)
                card_group.append(this_wild)
            card_group.sort(key=lambda wc: wc.tempnumber)
            groups_wilds=[]
    last_card_wild = False
    second2last_card_wild = False
    for card in card_group:
        if (isWild(card, wild_numbers) and last_card_wild) or (isWild(card, wild_numbers) and second2last_card_wild):
            raise Exception('Must have two natural cards between wild cards in runs')
        second2last_card_wild = last_card_wild
        last_card_wild = isWild(card, wild_numbers)
    return card_group, possible_wild_assignments, groups_wilds
def processRuns ( card_group , wild_numbers ) : card_group . sort ( key = lambda wc : wc . tempnumber ) groups_wilds = [ ] temp_run_group = [ ] aces_list = [ ] for card in card_group : if card . tempnumber in wild_numbers : groups_wilds . append ( card ) elif card . tempnumber == 1 and card . number == 1 : aces_list . append ( card ) else : temp_run_group . append ( card ) card_group , groups_wilds , gap_flag = buildBaseRun ( temp_run_group , groups_wilds , wild_numbers ) if len ( aces_list ) > 0 : card_group , groups_wilds = acesFreeWilds ( card_group , groups_wilds , wild_numbers ) if gap_flag : if len ( groups_wilds ) > 0 : card_group , groups_wilds = fillGaps ( card_group , groups_wilds ) else : text = 'There is a gap between numbers in run beginning with ' + str ( card_group [ 0 ] ) raise Exception ( text ) if len ( aces_list ) > 2 : raise Exception ( 'Cannot play more than 2 Aces in a single run.' ) elif len ( aces_list ) > 0 : lowAceOK = lowAceChk ( card_group , groups_wilds , wild_numbers ) hiAceOK = hiAceChk ( card_group , groups_wilds , wild_numbers ) if len ( aces_list ) == 1 : if hiAceOK and not lowAceOK : card_group , groups_wilds , aces_list = appendAce ( card_group , groups_wilds , aces_list ) elif lowAceOK : card_group , groups_wilds , aces_list = insertAce ( card_group , groups_wilds , aces_list ) else : text = 'Cannot play ' + str ( aces_list [ 0 ] ) raise Exception ( text ) if len ( aces_list ) == 2 : if hiAceOK and lowAceOK : card_group , groups_wilds , aces_list = appendAce ( card_group , groups_wilds , aces_list ) card_group , groups_wilds , aces_list = insertAce ( card_group , groups_wilds , aces_list ) else : text = 'Cannot play ' + str ( aces_list [ 0 ] ) raise Exception ( text ) num_remaining_wilds = len ( groups_wilds ) possible_wild_assignments = [ ] if not num_remaining_wilds == 0 : if num_remaining_wilds > 2 : raise Exception ( 'You cannot play all the wild cards.' ) if lowWildChk ( card_group , wild_numbers ) : runslot = card_group [ 0 ] . tempnumber - 1 possible_wild_assignments . append ( runslot ) if hiWildChk ( card_group , wild_numbers ) : runslot = card_group [ - 1 ] . tempnumber + 1 possible_wild_assignments . append ( runslot ) if num_remaining_wilds > len ( possible_wild_assignments ) : raise Exception ( 'you cannot play all the wild cards.' ) if num_remaining_wilds == len ( possible_wild_assignments ) : for this_wild in groups_wilds : this_wild . tempnumber = possible_wild_assignments . pop ( 0 ) card_group . append ( this_wild ) card_group . sort ( key = lambda wc : wc . tempnumber ) groups_wilds = [ ] last_card_wild = False second2last_card_wild = False for card in card_group : if ( isWild ( card , wild_numbers ) and last_card_wild ) or ( isWild ( card , wild_numbers ) and second2last_card_wild ) : raise Exception ( 'Must have two natural cards between wild cards in runs' ) second2last_card_wild = last_card_wild last_card_wild = isWild ( card , wild_numbers ) return card_group , possible_wild_assignments , groups_wilds
handle sorting of run, including placement of wilds.
handle sorting of run including placement of wilds .
""" handle sorting of run, including placement of wilds.  Handles minor rule checking.

    processRuns does not check length requirement or that all cards are in same suit.
    it DOES:
          require that if Aces are not wild, then they are hi or low, but not both.
          require that there must be two naturals between wild cards in runs.
    To preserve info on whether Ace is assigned hi or low, if Ace is assigned low, then tempnumber is set to -1.
    IF ACE CAN BE HIGH OR LOW (very unusual) THAN AUTOMATICALLY MAKING IT LOW.
    """ # sort card_group by tempnumber and initialize variables. # Separate wilds & Aces that have NOT been assigned from other cards (do wilds before Aces in case Aces are wild). # first pass on run -- check sequence and place or remove wilds. # Check if new Aces will free up additional wild cards. # second pass on run -- if there were any gaps, see if wilds can fill them in. # Now assign Aces that were not previously assigned (Aces cannot be moved once assigned). # Aces can go high or low.  If single Ace can be played in either location (rare) then play it Low. # Check if wild cards can be played  - only possible remaining slots for wilds are at the ends of the current run. # are there options on where to assign wilds? # If wilds can be automatically assigned, do it. # if num_remaining_wilds == 1 and len(possible_wild_assignments) == 2: # Will need to ask player whether to play high or low, controller handles that. # Final rules check in processRuns: double check that wilds are not placed too close together. # (Note that in creating possible_wild_assignments checked that assignments won't violate this rule, but didn't # check this everywhere).
card_group
wild_numbers