[pythonvis] Re: Farkel scoring function version 1

  • From: "Richard Dinger" <rrdinger@xxxxxxxxxx>
  • To: <pythonvis@xxxxxxxxxxxxx>
  • Date: Sun, 26 Apr 2020 20:13:15 -0700

Hi Jeff,

Looks like you have been busy.

The rules for these games seem complicated since I don’t have any actual 
experience playing, but I will try and catch up with you in a few days.

Richard
From: Jeffrey Thompson (Redacted sender "jthomp" for DMARC) 
Sent: Sunday, April 26, 2020 11:14 AM
To: pythonvis@xxxxxxxxxxxxx 
Subject: [pythonvis] Farkel scoring function version 1

Hi,

 

              Below is a function which I wrote as part of a larger program I 
am writing to do Farkel (or Zilchh, if modified, since the games are rather 
similar) using python.

It is the part of the game which does scoring on a given roll of the dice.

 

To understand this function, you should refer to scoring and scoring variations 
in the wikipedia article on farkel.  

 

              There are different variations on how to score; see the 
description of farkel in wikipedia.

The function accepts a tuple of booleans which indicate which scoring options 
are selected by the user in this game.

 

              I am including this code to illustrate how the programmer can use 
the collections.counter() class to provide a count of the number of each number 
of each die possibly thrown.

The game scores when there are 3 (and in some variations, or more) of a kind. 
This is easy to do with a counter.

Note that because counter is a derived class of the dict class,it needs to have 
non-integers as keys for the key-value pairs.

So I use the digits 1-6 turned into strings as the keys in the input to the 
scoring, i.e. the roll consists of a number (<= 6) of dice thrown as single 
digit characters in a list.

The counter class automatically counts the number of each die present in the 
roll of the dice.

note 2: The rules allow the user to take additional rolls of (some of) the 
remaining dice which the user doesn't put aside for scoring.

I believe that the dice put aside must have a positive score associated with 
them.

If the user scores nothing extra on a given roll, they "farkel" and lose any 
accumulated score they may have had on that turn.

The choice to continue rolling or not is what gives the user some strategic 
choice about how to play the game,

and the fun is in when someone takes a chance and "farkels" out. Or not.

 

code:

def update_user_score(current_throw, maximum_dice, scoring_variations_boolean):

              """ calculates the score for this throw. """

 

              # maximum_dice is 6 for this application.

 

              # Note This could be improved by having Scoring values stored in 
an list of scoring values which can be input into the function.

              # This will allow the programmer/user to alter the scoring levels 
as they wish without altering the code, which is desirable.

              # This list or tuple could be assigned to a list of variables, as 
is done here with the scoring variations

 

              do_straight, do_full_house, do_piggy_backing, do_add_duplicates, 
do_nothing_bonus = *scoring_variations_boolean

              score = 0

 

              if do_straight and len(current_throw) == maximum_dice and 
len(current_throw) == len(set(current_throw)):

                             # straight; 

                             #there are no duplicates in the throw of all dice, 
and this means that there must be 6 separate die values, or a straight.

                             score += 1000

                             return score

              # not straight

              # count number of doubles or greater duplicates

              countof_each = counter(current_throw)

              # 3 doubles scores 500

              if 3 == sum([(0,1)[c>1] for c in cost_of_each.balues()]):

                             score += 500

                             return score

              # end if

              if count_of_each[0] >= 3:

                             score += 1000

                             count_of_each =count_of_each[1:]

              # else:

                             second_count = 
list(count_of_each.items())[1:].reverse()

                             second_count = [(a_key, a_value) for a_key, 
a_value in count_of_each.items() if a_value >= 3]

                             if second_count != []:

                                           the_key, the_value  = second_count[0]

                                           value_mult = (1, 
the_value-2)[do_add_duplicates]

                                           score += 100*int(the_key)*value_mult

                                           count_of_each = {a_key: a_value for 
a_key, a_value in count_of_each.items() if a_key != the_key}

                             else:

                                           do_full_house = False

              # end outer if

 

              if  do_full_house and 2 <= (count_of_each.most_common(), 0)[1]:

                                           # full house

                                           score += 250

              # end if

 

              if count_of_each['1'] >0 or count_of_each['5'] > 0:

                             score += count_of_each['1'] *100 + 
count_of_each['5']*50

              # end if

              if do_nothing_bonus and current_dice == maximum_dice and score == 
0:

                             score += 500

              # end if

              return score

# end function update_user_score()

 

# end code

 

              Jeff Thompsons

Other related posts: