# Arup Guha
# 10/20/2020
# Solution to COP2930 Program 7: Yahtzee, Simplified

import random

# Runs a game for the #of turns the players want.
def main():
    turns = int(input("How many turns do both of you want for the game?\n"))
    yatzhee(turns)

# Runs yatzhee for nTurns number of turns.
def yatzhee(nTurns):

    # Initial scores for both players.
    p1Score = 0
    p2Score = 0

    # Go through each turn, alternating between players.
    for i in range(nTurns):
        p1Score += turn(1)
        p2Score += turn(2)

    # Display the final result.
    if p1Score > p2Score:
        print("Player 1 wins ", p1Score, " to ", p2Score, ".", sep="")
    elif p2Score > p1Score:
        print("Player 2 wins ", p2Score, " to ", p1Score, ".", sep="")
    else:
        print("It's a tie, both players scored", p1Score,"points.")

# Returns the value of a single standard die roll.
def rollOneDie():
    return random.randint(1,6)

# Executes the turn for player number player.
def turn(player):

    # Print a greeting and generate 3 dice rolls.
    print("Player",player,"it is your turn.")
    d1 = rollOneDie()
    d2 = rollOneDie()
    d3 = rollOneDie()

    # Print the values of the dice.
    print("You have rolled ",d1,", ",d2," and ",d3, sep="")
    response = input("Hit enter to continue.")

    # Calculate each type of score.
    threeKindScore = threeOfAKind(d1,d2,d3)
    twoKindScore = twoOfAKind(d1,d2,d3)
    straightScore = straight(d1,d2,d3)

    # This takes first precedent.
    if threeKindScore != 0:
        print("Great you got a three of a kind worth",threeKindScore,"points.\n")
        return threeKindScore

    # Followed by 2 of a kind.
    if twoKindScore != 0:
        print("You got a two of a kind worth", twoKindScore,"points.\n")
        return twoKindScore

    # Then straights.
    if straightScore != 0:
        print("You got a straight worth", straightScore, "points.\n")
        return straightScore

    # If we get here, there are no points.
    print("Sorry, unfortunately, this turn isn't worth any points.\n")
    return 0
        
# Pre-condition: a, b, and c represent dice rolls, all ints in between 1 and 6.
# Post-condition: Returns the three of a kind score for these dice.
#                 Specifically, if all 3 are equal, the sum of the dice plus
#                 30 is returned, otherwise 0 is returned.
def threeOfAKind(a,b,c):

    # This is a valid check for all 3 being equal.
    if a == b and b == c:
        return 30 + 3*a

    # If we get here, we get no points for three of a kind.
    return 0

# Pre-condition: a, b, and c represent dice rolls, all ints in between 1 and 6.
# Post-condition: Returns the two of a kind score for these dice.
#                 Specifically, if 2 dice are equal and the third is not, then
#                 the sum of the two equal dice are returned. Otherwise, 0 is
#                 returned.
def twoOfAKind(a,b,c):

    # Three pairs of dice could be the two equal dice, check all three.
    if a == b and a != c:
        return 2*a
    elif a == c and a != b:
        return 2*a
    elif b == c and b != a:
        return 2*b

    # If we get here, no points.
    return 0

# Pre-condition: a, b, and c are ints
# Post-condition: The smallest of a, b and c is returned.
def mymin(a,b,c):
    if a < b and a < c:
        return a
    elif b < c:
        return b
    return c

# Pre-condition: a, b, and c are ints
# Post-condition: The largest of a, b and c is returned.
def mymax(a,b,c):
    if a > b and a > c:
        return a
    elif b > c:
        return b
    return c

# Pre-condition: a, b, and c represent dice rolls, all ints in between 1 and 6.
# Post-condition: Returns the straight score for these dice.
#                 Specifically, if the three dice rolls form a sequence of 3
#                 consecutive integers, then 15 plus the sum of the rolls is
#                 returned. Otherwise, 0 is returned.
def straight(a,b,c):

    # All straights of length 3 have a difference of 2 between their min and max.
    if mymax(a,b,c)-mymin(a,b,c) != 2:
        return 0

    # If there are any repeats, it can't be a straight.
    if threeOfAKind(a,b,c) or twoOfAKind(a,b,c):
        return 0

    # If a,b,c pass the tests above, they must make a straight!
    return 15+a+b+c

# Do it!
main()
