> I get the impression it is a set number of turns. In that case,
> you'll need
> to be a bit canny, doing something like biasing the roll according to the
> distance to the goal.

I enjoyed this problem way too much, so I've written an implementation (in
Lingo, I'm afraid - it's my first language. But it should be easy enough to
follow)

on getRolls tSquares, tTurns, tList
  if voidP(tList) then tList = []
  if tTurns = 1 then
    tList.add(tSquares)
    return tList
  end if
  tMean = 1.*tSquares / tTurns
  -- Find the minimum value needed: min q>=1 such that (S-q)/(n-1)<=6
  tMin = tSquares - 6*(tTurns - 1)
  if tMin<1 then tMin = 1
  if tMin>6 then return #no
  -- Find the maximum value needed: max r<=6 such that (S-r)/(n-1)>=1
  tMax = tSquares - (tTurns - 1)
  if tMax>6 then tMax = 6
  if tMax<1 then return #no
  if tMax = tMin then
    -- Only one possible answer here
    tRoll = tMin
  else
    tOptions = tMax - tMin
    -- Set probability  distribution
    tWeight = 1 - 1.0/tTurns
    tProbabilities = []
    tProbMean = tMean - tMin
    -- ensure p lies between 0 and 1
    tSkew = min(tProbMean, tOptions - tProbMean)
    if tWeight> 2*tSkew / tOptions then
      tWeight = 2*tSkew / tOptions
    end if
    tBinomialProb = (tProbMean - tWeight*tOptions/2) / ((1 -
tWeight)*tOptions)
    repeat with i = 0 to tOptions
      tProbabilities.add(tWeight/(tOptions+1) + (1 -
tWeight)*choose(tOptions,i)*power(tBinomialProb,i)*power(1-tBinomialProb,
tOptions-i))
    end repeat
    -- choose a random number according to this distribution
    r = random(1000)
    repeat with i = 1 to tProbabilities.count
      tProb = tProbabilities[i]*1000
      if r<tProb then
        tRoll = i-1+tMin
        exit repeat
      end if
      r = r-tProb
    end repeat
  end if
  tList.add(tRoll)
  return getRolls(tSquares - tRoll, tTurns-1, tList)
end

on choose n, k
  if k>n/2 then return choose(n,(n-k))
  tRes = 1
  repeat with i=0 to k-1
    tRes = tRes * (n-i)
  end repeat
  repeat with i=1 to k
    tRes = tRes / i
  end repeat
  return tRes
end

on getLotsOfRolls s, n, m
  repeat with i=1 to m
    put getRolls(s,n)
  end repeat
end

I asked for getLotsOfRolls(50,15,20) and got this:

-- [6, 4, 3, 6, 6, 4, 1, 5, 1, 1, 5, 1, 1, 1, 5]
-- [5, 6, 1, 5, 5, 2, 2, 1, 1, 2, 2, 6, 4, 4, 4]
-- [3, 6, 5, 2, 4, 2, 1, 1, 6, 5, 6, 1, 1, 3, 4]
-- [5, 4, 1, 3, 5, 6, 1, 1, 3, 2, 3, 1, 4, 6, 5]
-- [1, 3, 2, 1, 1, 1, 5, 3, 2, 6, 6, 6, 2, 5, 6]
-- [1, 5, 2, 2, 2, 4, 1, 6, 4, 1, 6, 6, 1, 4, 5]
-- [4, 1, 6, 6, 2, 1, 1, 3, 2, 4, 3, 6, 3, 5, 3]
-- [3, 6, 1, 3, 4, 2, 1, 1, 6, 2, 3, 1, 6, 6, 5]
-- [5, 3, 1, 4, 6, 1, 2, 3, 2, 3, 3, 6, 1, 4, 6]
-- [1, 5, 4, 1, 4, 3, 1, 5, 5, 5, 3, 4, 5, 1, 3]
-- [2, 2, 5, 4, 3, 2, 3, 4, 1, 5, 6, 3, 1, 3, 6]
-- [1, 1, 2, 5, 6, 2, 5, 1, 5, 2, 6, 3, 5, 4, 2]
-- [1, 4, 5, 3, 3, 6, 4, 1, 4, 3, 1, 5, 6, 1, 3]
-- [3, 5, 1, 3, 4, 3, 3, 3, 1, 6, 6, 4, 3, 3, 2]
-- [3, 4, 4, 1, 6, 5, 6, 1, 1, 1, 4, 6, 1, 1, 6]
-- [1, 6, 5, 3, 2, 1, 5, 2, 5, 6, 1, 6, 1, 3, 3]
-- [1, 5, 3, 2, 5, 2, 2, 2, 3, 5, 5, 4, 3, 6, 2]
-- [1, 2, 5, 1, 2, 6, 5, 5, 2, 2, 3, 6, 4, 2, 4]
-- [2, 5, 1, 6, 4, 3, 1, 3, 3, 5, 2, 3, 1, 6, 5]
-- [3, 1, 2, 3, 3, 4, 2, 5, 6, 5, 1, 3, 3, 4, 5]


Looks pretty decent to me.

Danny

_______________________________________________
[email protected]
To change your subscription options or search the archive:
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Brought to you by Fig Leaf Software
Premier Authorized Adobe Consulting and Training
http://www.figleaf.com
http://training.figleaf.com

Reply via email to