I've become addicted to the Forge of Empires web browser game. Presently, the game has a special event going on, which is in commemoration of the 2016 EUFA Soccer Championship. The event has a set of probability-based challenges and I would like to use Mathematica to figure out the best use of my resources.

Goal (heh) of the event

Take a penalty shot, score, and gain points (aka cups). Cups can be traded in for prizes. You receive one credit per hour to take one shot at the goal. You can make four different types of shots, each with a different chance of earning cups. The riskier the shot, the greater then number of cups awarded if successful.

Rules of the event

I probably do not have these starting values correct, but it may not be relevant as you'll see below

Initially, each of the four shots has a base score of points that can be rewarded:

  • A shot with 100% chance of scoring rewards 10 cups
  • A shot with 20% chance of scoring rewards 40 cups
  • A shot with 10% chance of scoring rewards 60 cups
  • A shot with 5% chance of scoring rewards 100 cups

If a shot is missed, then the reward increases:

  • 20% shot increases by 5 cups per miss
  • 10% shot increases by 10 cups per miss
  • 15% shot increases by 15 cups per miss

My objective is to figure out which shot is best to take

My approach to the problem thus far has been to create a set of random integers with a range appropriate so that the presence of a "1" indicates success, find the positions of the 1's, and calculate the differences between those positions to figure out how much the pot has increased each time. The code looks something like this:

cups[prob_, inc_, base_] := Module[{shots, wins},
  shots = RandomInteger[{1, prob}, 1000];
  wins = Position[shots, 1] // Flatten;
  Sum[inc i, {i, #}] + base & /@ 
    Prepend[Differences[wins], First@wins] // Total

One example output using MapThread[ cups[#1, #2, #3] &, {{5, 10, 20}, {5, 10, 15}, {40, 60, 100}}] gives me points of 30k, 107k, and 317k for each, suggesting to me that I should always stick with the lowest probability shot because over time, it will provide me with the greatest payout. Is my thinking on this correct?

The real challenge

The hard part, which I have no idea how to model, is that all players in my neighborhood influence the rewards. For example, if there is one player in my neighborhood (typically, there are 80), and she misses a 1-in-20 shot, then my potential reward for a 1-in-20 shot is increased by 15 cups. Likewise, if she wins the attempt, the reward is reset to its base. How might I incorporate this complexity into my model?

May the best country win, and may your relatives (who scored tickets to the game while you are at home working) not be terribly affected by the endless strikes, currently underway in France.

  • 1
    $\begingroup$ May be this question has to be asked with a bounty... $\endgroup$ – Anton Antonov Jun 9 '16 at 14:12
  • $\begingroup$ Do you always know the current reward at the time of the shot? $\endgroup$ – george2079 Jun 9 '16 at 14:38
  • $\begingroup$ @george2079 yes, and any changes by the neighborhood players are reflected in realtime (well, realtime for a flash player game) $\endgroup$ – bobthechemist Jun 9 '16 at 14:43
  • $\begingroup$ Not sure I see the question here - unless you either know the precise strategies of the other players in the pool, or they all play randomly, all the simulation in the world is for naught. Seems that taking the shot with the highest expected value at the time of the shot is the optimal solution, or am I missing something? $\endgroup$ – ciao Jun 9 '16 at 22:42
  • $\begingroup$ I'm quite interested in this problem(even more if a bounty is offered :) ), and I would like to make something clear: can you shot a few shots at one time or you can only shot once an hour? Is one of your goal to be able to choose whether to shot at some time and how much shot you shall take or simply wait till next time you play? $\endgroup$ – Wjx Jun 10 '16 at 1:26

Running the code below, which shows the results for runs of 1000 shots, the rewards as set mean you should always take the 100% shot. With different rewards you could add a condition to take a different shot depending on the level of the increased reward.

shot[chance_, reward_, hike_] := Module[{result},
  result = If[chance < RandomInteger[{1, 100}], "miss", "hit"];
   "hit", score += reward; misshike = 0,
   "miss", misshike += hike]]

calc[chance_, reward_, hike_] := Module[{},
  table = Table[
    score = 0;
    misshike = 0;
    Do[shot[chance, reward, hike], {1000}]; score, {100}];
  N@Through[{Mean, StandardDeviation}@table]]

  calc[100, 10, Null],
  calc[20, 40, 5],
  calc[10, 60, 10],
  calc[5, 100, 15]}, TableHeadings -> {
   {"100%", "20%", "10%", "5%"}, {"Average", "Std.dev."}}]
  • $\begingroup$ Hmm, slow and steady wins the race. The results of your code suggest that none of the < 100% options have a chance for a bigger payout than the trivial option. I wonder if the game designers would be so sneaky... $\endgroup$ – bobthechemist Jun 9 '16 at 19:04
  • $\begingroup$ @bobthechemist Well the OP does say "I probably do not have these starting values correct." If they were different one could try a switch of shot depending on the reward increase. $\endgroup$ – Chris Degnen Jun 9 '16 at 19:42
  • $\begingroup$ Chris, you know bob here is the OP, right? :) $\endgroup$ – J. M. is in limbo Jun 9 '16 at 22:39
  • $\begingroup$ Oops. Missed that :-) $\endgroup$ – Chris Degnen Jun 10 '16 at 5:45
  • $\begingroup$ Cleaning up my old questions, and reflecting on what I could have done with all of those hours spent on useless web-games. $\endgroup$ – bobthechemist Dec 17 '18 at 13:22

I cant see doing more than this:

shot[rewards_] := 
    Transpose[{#, rewards #/100} &@{100, 20, 10, 5}], #[[2]] &][[1, 1]]

shot[{10, 40, 60, 100}]


then just key in the current values before your shot:

 shot[{10, 50, 160, 200}]


That said, I suppose the real game is about watching the rewards change and taking the right shot at the right time.

Another thought is just make a chart like this:

Grid[{{"20%", "10%", "5%"}, {
   TableForm@Table[{x,  x/5}  , {x, 40, 100, 5 }],
   TableForm@Table[{x,  x/10}  , {x, 60, 180, 10 }],
   TableForm@Table[{x,  x/20}  , {x, 100, 340, 20 }]}}, 
 Dividers -> All]

enter image description here

so you can readily see the probabilistic value of each choice as the rewards change.

  • $\begingroup$ Interesting approach. I may not be using the correct terminology here, but your answer would give the best instantaneous option, but does not take in to account that the 3 non-100% options grow with time and a few failures may ultimately lead to a better reward. Perhaps I'm overthinking things. $\endgroup$ – bobthechemist Jun 9 '16 at 19:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.