I wrote something to enumerate the relevant states and then print out the probabilities it found that way. Somehow a simulation felt like a cop-out to me :)
I believe this game is for more than one player? And it ends when ANY player gets 10 cherries, right? The code and results below assume that.
For the two-player case, I got a mean end turn of around 9.56. Since I was counting turns as every player spinning once, that's two spins per turn, so let's say that in the mean case, it takes between 19 and 20 spins for the game to end when two people are playing. It looks like the median is lower: about 15 spins, so half of the two-player games should end on or before the 15th spin.
The original question makes it sound like the one-player case is what was being considered so here is the info for that one.
For one player: the mean game length is 15.8 spins and the median game length is between 11 and 12 turns (half end on or before 11, half on or after 12 spins).
Here is the code to generate the data used above. Warning: It gets really slow as you add players (exponential runtime in number of players, but only quadratic in terms of the number of turns). You can change the values of turn_cap and num_players at the top of the file to match what you want to find out. It only enumerates up to turn_cap, because you probably don't care beyond that. Games that end later ARE still taken into account, it just doesn't spit out data for them.
from copy import deepcopy
from sys import stdout
num_players = 2
turn_cap = 50 # I assume everybody is sick of it by this point
print_merges = False
print_num_states = False
print_turn_progress = True
ignore_score_of_finished_games = True
r"""helper for flattening a list of lists into a single list"""
return [item for sub_list in list_of_lists for item in sub_list]
r"""return for how many items in iterable the predicate p evaluates to true"""
n = 0
for item in iterable:
n += 1
return len(l0)==len(l1) and \
all(l0[i]==l1[i] for i in range(len(l0)))
r"""split the list "items" into two lists based on a predicate "p"
returns a tuple. (items where the predicate is true, items where the predicate is false) """
good, bad = , 
for i in items:
return good, bad
def __init__(self, num_players=2, probability=1.0):
self.player_scores = [0 for x in range(num_players)]
self.probability = probability
self.turn_number = 0
self.ended_on_turn = None
self.num_players = num_players
if any(( (score>=10) for score in self.player_scores)):
self.ended_on_turn = self.turn_number
def gain_cherries(self, player_index, num_cherries):
self.player_scores[player_index] += num_cherries
def lose_cherries(self, player_index, num_cherries):
self.player_scores[player_index] = max(0, self.player_scores[player_index] - num_cherries)
def lose_all_cherries(self, player_index):
self.player_scores[player_index] = 0
r"""if not ended, it splits the world into 7 new worlds based on each player's spin"""
self.turn_number += 1
worlds = [self]
for i in range(self.num_players):
worlds = flatten([w.run_player_turn(i) for w in worlds])
def run_player_turn(self, player_index):
new_worlds = [deepcopy(self) for i in range(7)]
for w in new_worlds:
w.probability = self.probability / 7.0
def mergable(self, other):
if world_ended(self) and ignore_score_of_finished_games:
return ( (self.ended_on_turn == other.ended_on_turn) and
(self.num_players == other.num_players) )
return ( lists_the_same(self.player_scores, other.player_scores) and
(self.turn_number == other.turn_number) and
(self.ended_on_turn == other.ended_on_turn) and
(self.num_players == other.num_players) )
def merge(self, other):
w = deepcopy(self)
w.probability += other.probability
return ( str(self.player_scores) + ", " +
"p:" + str(self.probability) + ", " +
"ended on:" + str(self.ended_on_turn) + ", " )
r"""look through the list of worlds, find ones that can be merged
and merge them, modifying the list in place"""
i0 = 0
while i0 < len(world_list):
i1 = len(world_list) - 1
while i1 > i0+1:
w0 = world_list[i0]
w1 = world_list[i1]
world_list[i0] = w0.merge(w1)
i0 += 1
p_on = [0.0 for i in range(turn_cap+1)]
p_by = [0.0 for i in range(turn_cap+1)]
for w in worlds:
turn = w.ended_on_turn
p_on[turn] += w.probability
for i in range(turn, turn_cap+1):
p_by[i] += w.probability
for i in range(1,turn_cap+1):
worlds = [World(num_players)]
finished_worlds = 
for i in range(turn_cap):
worlds = flatten([w.run_turn() for w in worlds])
done, worlds = split_list(worlds,world_ended)
print len(worlds),"unfinished world states"
print len(finished_worlds),"finished world states"