# Re-evaluate a random generator to simulate a raquetball play?

Posted 4 months ago
884 Views
|
19 Replies
|
3 Total Likes
|
 Sorry - trying to learn the language...your playing racquetball , you only score when you serve. 60% chance of winning when you serve, 50% chance of winning when you don't serve p5 := If[Random[] >= .5, 1, 0] p6 := If[Random[] >= .6, 1, 0] p := If[x < x + Evaluate[p6], x += 1, np]; np := If[Evaluate[p5] == 1, p, np]; score = Table[p, 10] Do[Print[x]; p, 5] the best I can do so far and it's not working, I want to see how far it will take to get to 21, I am not sure how Mathematica works as a programming language. Thanks for any help.
19 Replies
Sort By:
Posted 4 months ago
 What is ratchball? It would help to know what the rules are. Do players alternate or does the winner serve again? Are there more than two players? Why is play asymmetric (p(winning if not serving)=0.5 vs p(winning if serving) =0.6). Who serves first?
Posted 4 months ago
 Sorry -- raquetball -- yes there are two players, but I didn't want to complicated the problem so only looking just one side. You start serving but only win a point when you serve. you have a 60% chance of winning your serve and earning one point. If you lose your serve you only have a 50% chance of winning the serve back again. Wanted to create the simulation to see how long it would take to get to 21 points to win. Also trying to figure out how to do this mathematically equally without success. If you win the serve and then win the next play, only then do you earn a point and get to serve again, earning points until you lose your serve.
Posted 4 months ago
 how would I count the number of times the ball was served??? x = 0; p5 := If[Random[] <= .5, 1, 0] p6 := If[Random[] <= .6, 1, 0] Table[p5, 10] Table[p6, 10] p := If[0 < p6, x += 1, np] np := If[p5 == 1, p, np] score = Table[{p, x}, 10] The score is going up one point at a time, as it should, but I don't know how many times the ball has been played between point (p) and no point (np), how would I count this????
Posted 4 months ago
 I'm getting closer--- x = 0; s = 0; p5 := If[Random[] <= .5, 1, 0] p6 := If[Random[] <= .6, 1, 0] p := If[0 < p6, {x += 1, s += 1}, {np, s += 1}] np := If[p5 == 1, {p, s += 1}, {np, s += 1}] score = Table[{p, s}, 10] the output is {{{{{{{{{1, 1}, 2}, 3}, 4}, 5}, 6}, 7}, 7}, {{2, 8}, 8}, {{3, 9}, 9}, {{{{4, 10}, 11}, 12}, 12}, {{5, 13}, 13}, {{{{{{6, 14}, 15}, 16}, 17}, 18}, 18}, {{{{7, 19}, 20}, 21}, 21}, {{{{{8, 22}, 23}, 24}, 25}, 25}, {{9, 26}, 26}, {{10, 27}, 27}} to win 10 points the ball has been played 27 times -- I am not sure why the last number (s) prints twice????
Posted 4 months ago
 I am having a difficult reading the lists in the output, would there be an easier way?? x = 0; s = 0; p5 := If[Random[] <= .5, 1, 0] p6 := If[Random[] <= .6, 1, 0] p := If[0 < p6, {x += 1, s += 1}, {np, s += 1}] np := If[p5 == 1, {p, s += 1}, {np, s += 1}] score = Table[{s, Style[p, Bold, Red]}, 10] output {{0,{{{{{{{{1,1},2},3},4},5},6},7},8}},{8,{2,9}},{9,{{{3,10},11},12}},{12,{{{4,13},14},15}},{15,{{{{{{{{{5,16},17},18},19},20},21},22},23},24}},{24,{{{{6,25},26},27},28}},{28,{{{7,29},30},31}},{31,{8,32}},{32,{{{9,33},34},35}},{35,{10,36}}} sorry I can't get the red to appear in the post
Posted 4 months ago
 I ran 100,000 games to 21. The maximum number of serves required was 104, the minimum number of serves was 24, and average number of serves was about 52.
Posted 4 months ago
 Thanks Ed, if you used my code, I would love to know how you ran it 100,000 times. I have tried and "score" just repeats itself and doesn't re-evaluate. I also don't understand why Table stops when p = 21 and not when s reaches 21 or x, other than Mathematica knew that is what I wanted -- pretty good if Mathematica was intuitive like that... With all the crazy lists I am getting, how would extract the last s value? I have tried "Flatten" but it will not get rid of all the lists from the p value x = 0; s = 0; p5 := If[Random[] <= .5, 1, 0] p6 := If[Random[] <= .6, 1, 0] p := If[p6 == 1, {x += 1, s += 1}, {np, s += 1}] np := If[p5 == 1, {p, s += 1}, {np, s += 1}] score = Table[{s, Style[x, Bold, Red], Style[p, Green]}, 21] 
Posted 4 months ago
 Hereâ€™s how I did it. First, model a single game with a function. The players are numbered either 0 or 1, and a single game is represented as a pair {WINNER, LOSER}. So, if player 0 wins, the results is {0,1}, and {1,0} otherwise. SingleStep[server_]:= Module[ {pwin}, pwin=If[server==0,0.6,0.5]; If[Random[]
Posted 4 months ago
 Correction to my original post. Ran 100,000 games counting all serves. The maximum number of total serves in a game was 64. The minimum was 21, and the average was about 35. These runs didn't stop the game if the other player scored 21 points first. Player with 0.6 probability served first.
Posted 4 months ago
 okay not pretty, but this is what I got so far t = Table[{ x = 0; s = 0; p5 := If[Random[] <= .5, 1, 0]; p6 := If[Random[] <= .6, 1, 0]; p := If[p6 == 1, {x += 1, s += 1}, {np, s += 1}]; np := If[p5 == 1, {p, s += 1}, {np, s += 1}]; score = Table[{Style[p, Green], s, Style[x, Bold, Red]}, 21]; s}, 100000]; Histogram[Flatten[t], 150] Max[t] Min[t] Mean[t] // N Max = 152, Min = 21, Mean = 63
Posted 4 months ago
 Why not generate your list first: WLWWWLWLLL etc. Maybe 3.5 million if you expect 100,000 games. Look at EACH run WWW LLLLLL etc...and subtract 1 from the length (in this case, person 1 gets two points, then person 2 gets 5 points). Thats how many points that person gets. Reset the game at the point someone gets to 21. Once you have that, adjust code so winner has to win by 2. Think about end of game adjustments so there isnt a score like 17-25 for a large streak.
Posted 4 months ago
 thanks Matthew, ran your program 100,000 times and your max,min,mean are about half of mine. I am only guessing, but I don't see how your "server" could = 1 and thus only have a potential to win at 50%, though your graph is much more normalized and smoother than what my program produces.
Posted 4 months ago
 Welcome to Wolfram Community! Please make sure you know the rules: https://wolfr.am/READ-1STPlease do NOT post code as images. Other members cannot copy it then.The rules explain how to format your code properly. If you do not format code, it may become corrupted and useless to other members. Please EDIT your post and make sure code blocks start on a new paragraph and look framed and colored like this. int = Integrate[1/(x^3 - 1), x]; Map[Framed, int, Infinity] 
Posted 4 months ago
 @ Raymond Low A game ends when one of the players, A or B, earns 21 points. I ran 100,000 games stopping each at 21 points. I show that player A with 0.6 probability of earning a point on a serve, wins about 82.5% of the games played. The total number of serves by both players has a mean value of about 58 serves when A wins. Player A serves about 34 times (mean value) to win 21 points and thus a game. When B player wins, the total number of serves during these games has a mean value of about 66 serves. B playerâ€™s mean number of serves for winning a game was about 35.I failed to understand how Matthews code switched between players when a serve didnâ€™t make a point. I just couldnâ€™t visualize it. I suspect his code was counting the individual serves by the winner of each game.
Posted 4 months ago
 You're right - I posted code that counts wrong. Modified code where players are either player 1 or 2: SingleStep[cfg_] := If[Random[] < 0.6, cfg, Reverse[cfg]] This is passed a pair: {server,other}. The server has a 60% chance of winning the round. If the server loses the round, the configuration is reversed so the next round the other player is the server.The main loop then becomes: CountGames[x_] := Module[{wins, curserve, newserve, games}, wins = {0, 0}; curserve = {1, 2}; games = 0; While[wins[[1]] < x && wins[[2]] < x, newserve = SingleStep[curserve]; If[newserve[[1]] == curserve[[1]], wins[[newserve[[1]]]] = wins[[newserve[[1]]]] + 1]; curserve = newserve; games = games + 1]; games] Start off with 0 wins for each player, 0 games played, and with player 1 being the first server. Loop while neither player has exceeded the target win count (x). Each step, given the current serving configuration, return the next serving configuration. If the configuration didn't change, then record a win for the server. Otherwise, just increment the game count and set the current configuration to the new one.I'm not sure about the way the original problem was defined (0.6 and 0.5 probabilities), but this should be a less buggy attempt compared to my original code. Thanks Ed for pointing out the mistake - that's what I get for trying to code something up quickly and not thinking it through...
Posted 4 months ago
 Thank you Matthew --I was wondering how to time your program. I tried wrapping your code in "Timing" but it won't run. How would I time how long it takes your program to run?? Also would it be possible to extract "wins" out of the code?
Posted 4 months ago
 Regarding timing, you should be able to use the timing function: for example, one run: In[6]:= {time, count} = CountGames[21] // Timing Out[6]= {0.000357, 51} The time variable will hold the timing, and the count variable is the number of games played until one player reached 21. If you modify the CountGames function, you can have it return both the total game count as well as the per-player win count: CountGames[x_] := Module[{wins, curserve, newserve, games}, wins = {0, 0}; curserve = {1, 2}; games = 0; While[wins[[1]] < x && wins[[2]] < x, newserve = SingleStep[curserve]; If[newserve[[1]] == curserve[[1]], wins[[newserve[[1]]]] = wins[[newserve[[1]]]] + 1]; curserve = newserve; games = games + 1]; {wins, games}] In this case the final expression in the body of the function is {wins, games}. For example: In[10]:= {time, {wins, count}} = CountGames[21] // Timing Out[10]= {0.000242, {{21, 5}, 44}} Here we see that in 0.000242 seconds it found that player 1 won 21 points, player 2 won 5 points, and 44 total games were played where 18 of the games were rounds where the server did not win, so the serve changed players but the winner didn't pick up a point since they didn't serve in that round. If I run 100,000 games, I can get the timing and win count as: In[12]:= {time, history} = Table[CountGames[21], {i, 1, 100000}] // Timing; In[13]:= time Out[13]= 21.4189 In[18]:= numgames = #[[2]] & /@ history; That last line just maps the function #[[2]]& over the elements of the history to get the second element of the pair returned by CountGames[] to get the total games played until someone reached 21. Similarly, if I map the function #[[1]]& over history, I would get a table of pairs {WinsA, WinsB} for each game to 21 if you wanted to look at those values as well.
 @ Raymond Low Following not elegant but here is code I used. game = 0; hitsAwin = {}; hitsBwin = {}; lAsrv = {}; lBsrv = {}; space = " "; (Label[start]; pntA = 0; pntB = 0; srv = 0; srvA = 0; srvB = 0; game = game + 1; Label[A]; srv = srv + 1; srvA = srvA + 1;(*Print[{srv," ",srvA}];*) If[RandomInteger[{1, 10}] <= 6, pntA = pntA + 1, Goto[B]]; If[pntA >= 21, Goto[End], Goto[A]]; Label[B]; srv = srv + 1; srvB = srvB + 1; If[RandomInteger[{1, 10}] <= 5, pntB++, Goto[A]]; If[pntB >= 21, Goto[End], Goto[B]]; Label[End]; If[pntA == 21, AppendTo[hitsAwin, srv], AppendTo[hitsBwin, srv]]; If[pntA == 21, AppendTo[lAsrv, srvA], AppendTo[lBsrv, srvB]]; (*Print[{srv,space,srvA,space,srvB}]*) If[game < 100000, Goto[start]]); Print[{Length[hitsAwin], space, Max[hitsAwin], space, Min[hitsAwin], space, N[Mean[hitsAwin]], " ", N[Mean[lAsrv]]}] Print[{Length[hitsBwin], space, Max[hitsBwin], space, Min[hitsBwin], space, N[Mean[hitsBwin]], space, N[Mean[lBsrv]]}] Histogram[{hitsAwin, hitsBwin}] Histogram[{lAsrv, lBsrv}] `