hand_type Function

function hand_type(me, with_jokers)

returns the type of hand

Arguments

Type IntentOptional Attributes Name
class(hand), intent(in) :: me
logical, intent(in) :: with_jokers

if considering jokers

Return Value integer


Calls

proc~~hand_type~~CallsGraph proc~hand_type problem_7::hand_type interface~unique~2 aoc_utilities::unique proc~hand_type->interface~unique~2 proc~unique32 aoc_utilities::unique32 interface~unique~2->proc~unique32 proc~unique64 aoc_utilities::unique64 interface~unique~2->proc~unique64 interface~sort aoc_utilities::sort proc~unique32->interface~sort proc~unique64->interface~sort proc~sort_ascending aoc_utilities::sort_ascending interface~sort->proc~sort_ascending proc~sort_ascending_64 aoc_utilities::sort_ascending_64 interface~sort->proc~sort_ascending_64 interface~swap~2 aoc_utilities::swap proc~sort_ascending->interface~swap~2 proc~swap64 aoc_utilities::swap64 proc~sort_ascending_64->proc~swap64 interface~swap~2->proc~swap64 proc~swap32 aoc_utilities::swap32 interface~swap~2->proc~swap32 proc~swap_str aoc_utilities::swap_str interface~swap~2->proc~swap_str

Called by

proc~~hand_type~~CalledByGraph proc~hand_type problem_7::hand_type proc~beats problem_7::beats proc~beats->proc~hand_type program~problem_7 problem_7 program~problem_7->proc~beats

Source Code

    integer function hand_type(me, with_jokers)
        !! returns the type of hand
        class(hand),intent(in) :: me
        logical,intent(in) :: with_jokers !! if considering jokers
        integer,dimension(5) :: i
        integer,dimension(:),allocatable :: u
        integer :: n_jokers, n_unique
        character(len=1),dimension(5) :: h

        h = me%cards
        i = ichar(h)  ! convert to code
        u = unique(i) ! unique elements
        n_unique = size(u)

        if (with_jokers .and. any(h=='J')) then

            ! have to pick best hand for all jokers
            ! just do it by inspection
            n_jokers = count(h=='J')
            select case (n_jokers)
            case(5)
                hand_type = FIVE_OF_A_KIND !jjjjj
            case(4)
                hand_type = FIVE_OF_A_KIND !jjjja
            case(3)
                ! can always turn to 4 or 5 of a kind
                if (n_unique==2) then !jjjaa
                    hand_type = FIVE_OF_A_KIND
                else ! jjjab
                    hand_type = FOUR_OF_A_KIND
                end if
            case(2)
                if (n_unique==2) then !jjaaa
                    hand_type = FIVE_OF_A_KIND
                else if (n_unique==3) then !jjaab
                    hand_type = FOUR_OF_A_KIND
                else !jjabc
                    hand_type = THREE_OF_A_KIND
                end if
            case(1)
                if (n_unique==2) then !jaaaa
                    hand_type = FIVE_OF_A_KIND
                else if (n_unique==3) then
                    if ( any([count(i==u(1))==3, &
                              count(i==u(2))==3 , &
                              count(i==u(3))==3]) ) then !jaaab
                        hand_type = FOUR_OF_A_KIND
                    elseif ( (count(i==u(1))==2 .and. count(i==u(2))==2) .or. &
                             (count(i==u(1))==2 .and. count(i==u(3))==2) .or. &
                             (count(i==u(2))==2 .and. count(i==u(2))==2) ) then !jaabb
                        hand_type = FULL_HOUSE
                    end if
                else if (n_unique==4) then !jaabc
                    hand_type = THREE_OF_A_KIND
                else if (n_unique==5) then !jabcd
                    hand_type = ONE_PAIR
                end if
            end select

        else

            !Every hand is exactly one type. From strongest to weakest, they are:
            select case (n_unique)
            case(1) ! aaaaa
                hand_type = FIVE_OF_A_KIND
            case(2) ! aaaab, aaabb
                if ((count(i==u(1))==4 .and. count(i==u(2))==1) .or. &
                    (count(i==u(1))==1 .and. count(i==u(2))==4) ) then
                    hand_type = FOUR_OF_A_KIND
                else if ((count(i==u(1))==3 .and. count(i==u(2))==2) .or. &
                        (count(i==u(1))==2 .and. count(i==u(2))==3) ) then
                    hand_type = FULL_HOUSE
                end if
            case(3) ! aaabc, aabcc
                if ( any([count(i==u(1))==3, count(i==u(2))==3 , count(i==u(3))==3]) ) then
                    hand_type = THREE_OF_A_KIND
                else if ( any([ count(i==u(1))==2 .and. count(i==u(2))==2,  &
                                count(i==u(1))==2 .and. count(i==u(3))==2, &
                                count(i==u(2))==2 .and. count(i==u(3))==2]) ) then
                    hand_type = TWO_PAIR
                end if
            case(4) !aabcd
                hand_type = ONE_PAIR
            case(5) !abcde
                hand_type = HIGH_CARD ! High card, where all cards' labels are distinct: 23456
            end select

        end if
    end function hand_type