[pythonvis] Farkel scoring function version 1

  • From: "Jeffrey Thompson" <dmarc-noreply@xxxxxxxxxxxxx> (Redacted sender "jthomp" for DMARC)
  • To: <pythonvis@xxxxxxxxxxxxx>
  • Date: Sun, 26 Apr 2020 14:14:47 -0400

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: