print(`First written: Aug. 7, 1998`): print(` Version of Aug. 7, 1998`): print(`This is CHUTES, A Maple package that plays CHUTES and LADDERS`): print(`Written by: Doron Zeilberger (zeilberg@math.temple.edu)`): print(`Consultant: Hadas Zeilberger (hadasy@aol.com) (b. 1990)`): print(`The most current version of CHUTES is always available by anon. ftp`): print(` to ftp.math.temple.edu directory pub/zeilberg/programs`): print(`or on WWW: http://www.math.temple.edu/~zeilberg/`): print(`For general help, and a list of the available functions,`): print(` type "ezra();". For specific help type "ezra(procedure_name)" `): lprint(``): ezra:=proc() if args=NULL then print(CHUTES): print(`Written by `): print(`Doron Zeilberger: zeilberg@math.temple.edu`): print(`Consultant: Hadas Zeilberger (b. 1990): hadasy@aol.com`): lprint(``): print(`A Maple package that plays CHUTES and LADDERS(TM) and `): print(`computes probablities of winning and expected duration of game`): lprint(``): print(`For help with a specific procedure, type "ezra(procedure_name);"`): print(`Contains procedures: `): print(` Chutes , EMBCAL, ExpNumMoves, PMBCAL, Prob, ProbWinning `): elif nops([args])=1 and op(1,[args])=Prob then print(`Prob(i,j): The probablity of winning in the Milton-Bradley`): print(`Chutes and Ladders(tm) game if it is your turn`): print(`to spin and you are at the i^th place and your`): print(`opponent is at the j^th place`): elif nops([args])=1 and op(1,[args])=ExpNumMoves then print(`ExpNumMoves(N,CHUTES,LADDERS): Gives the list of the`): print(`expected number of moves in a generalized`): print(`Chutes and Ladders game with N squares and`): print(`a list of Chutes and Ladders`): elif nops([args])=1 and op(1,[args])=ProbWinning then print(`ProbWinning(N,CHUTES,LADDERS): Given a game of Chutes and`): print(`ladders with N squares and lists of Chutes, CHUTES,`): print(`and ladders, LADDERS, finds a table of the`): print(`probablities p(i,j) (1<=i,j<=N) of the player whose`): print(`turn is now to spin winning, where her position is`): print(`i and the opponent's (the person who just spun) is j`): elif nops([args])=1 and op(1,[args])=PMBCAL then print(`PMBCAL(): The table of probabilities of winning p[i,j]`): print(`if it is your turn to spin, and you are at the i^th `): print(`position and your opponent is at the j^th position`): elif nops([args])=1 and op(1,[args])=Chutes then print(`Chutes(Name1,Name2, Name3, ...): Playes Chutes and Ladders(tm),`): print(`The Milton-Bradley Game, with any number of players`): print(`For example: Chutes(Hadas,Doron,Tamar)`): elif nops([args])=1 and op(1,[args])=EMBCAL then print(`EMBCAL(): Gives the table of the expected number of moves`): fi: end: spin:=proc() local chu,ra,i; chu:=[1,3,2,5,4,6]: ra:=rand(1..6); i:=ra(): op(i,chu): end: Turn:=proc(kvc,kvl,ac,al,init,NAME) local gu,newp,newpo: gu:=spin(); print(NAME, `You are now in square`,init): print(`You spinned:`, gu): newp:=init+gu: if member(newp,kvl) then newpo:=newp: newp:=al[newp]: print(NAME,`Lucky You!: you got a ladder from`,newpo,`to square`, newp): print(`You came from `, init, ` your position now is`,newp): elif member(newp,kvc) then newp:=ac[newp]: print(NAME,`Too bad, you got a chute to square`, newp): else print(`You came from `, init, ` your position now is`,newp): fi: newp: end: Chutes:=proc() local Listnames,i,CHUTES,LADDERS,N,kvc,kvl,ac,al,NAME,numb,makom,gu,i1,j1 : Listnames:=[args]: N:=100: CHUTES:={[16,6],[47,26],[49,11],[56,53],[62,19],[64,60],[87,24],[93,73], [95,75],[98,78]}; LADDERS:=[[1,38], [4,14],[9,31],[21,42],[28,84],[36,44],[51,67], [71,91],[80,100]]; kvc:={}: for i from 1 to nops(CHUTES) do kvc:=kvc union {op(i,CHUTES)[1]}: ac[op(i,CHUTES)[1]]:=op(i,CHUTES)[2]: od: kvl:={}: for i from 1 to nops(LADDERS) do kvl:=kvl union {op(i,LADDERS)[1]}: al[op(i,LADDERS)[1]]:=op(i,LADDERS)[2]: od: numb:=nops(Listnames): for i from 1 to numb do makom[i]:=0: od: for i from 0 do i1:=(i mod numb)+1: NAME:=op(i1,Listnames): print(NAME,`it is your turn`): gu:=Turn(kvc,kvl,ac,al,makom[i1],NAME): makom[i1]:=gu: if gu>=N then print(`THE WINNER IS`): print(NAME,NAME,NAME,NAME,NAME): lprint(``): print(Congratulations, NAME, `You won!`): print(`The position(s) of the loser(s) is(are) `): for j1 from 1 to numb do if j1<>i1 then lprint(Listnames[j1],`:`,makom[j1]): fi: od: print(`The number of spins (of all players) were,i`): RETURN(i): fi: od: end: EMBCAL:=proc() local N,CHUTES,LADDERS: N:=100: CHUTES:={[16,6],[47,26],[49,11],[56,53],[62,19],[64,60],[87,24],[93,73], [95,75],[98,78]}; LADDERS:=[[1,38], [4,14],[9,31],[21,42],[28,84],[36,44],[51,67], [71,91],[80,100]]; ExpNumMoves(N,CHUTES,LADDERS): end: #ExpNumMoves(N,CHUTES,LADDERS): Gives the list of the #expected number of moves in a generalized #Chutes and Ladders game with N squares and #a list of Chutes and Ladders ExpNumMoves:=proc(N,CHUTES,LADDERS) local kvc,kvl,ac,al,i,eq,var,foll,j,a,eq1,gu1,gu,tab: option remember: kvc:={}: for i from 1 to nops(CHUTES) do kvc:=kvc union {op(i,CHUTES)[1]}: ac[op(i,CHUTES)[1]]:=op(i,CHUTES)[2]: od: kvl:={}: for i from 1 to nops(LADDERS) do kvl:=kvl union {op(i,LADDERS)[1]}: al[op(i,LADDERS)[1]]:=op(i,LADDERS)[2]: od: for i from 0 to N-1 do if not member(i,kvc union kvl) then gu:=[i+1,i+2,i+3,i+4,i+5,i+6]: gu1:=[]: for j from 1 to nops(gu) do if op(j,gu)>=N then gu1:=[op(gu1),N]: elif member(op(j,gu),kvl) then gu1:=[op(gu1),al[op(j,gu)]]: elif member(op(j,gu),kvc) then gu1:=[op(gu1),ac[op(j,gu)]]: else gu1:=[op(gu1),op(j,gu)]: fi: od: foll[i]:=gu1: fi: od: eq:={a[N]}: var:={a[N]}: for i from 0 to N-1 do if not member(i,kvc union kvl) then var:=var union {a[i]}: gu:=foll[i]: eq1:=a[i]-1: for j from 1 to nops(gu) do eq1:=eq1 -a[gu[j]]/6: od: eq:=eq union {eq1}: fi: od: var:=solve(eq,var): tab:=[]: for i from 0 to N do tab:=[op(tab),subs(var,a[i])]: od: tab: end: ################ #ProbWinning(N,CHUTES,LADDERS): Given a game of Chutes and #ladders with N squares and lists of Chutes, CHUTES, #and ladders, LADDERS, finds a table of the #probablities p(i,j) (1<=i,j<=N) of the player whose #turn is now to spin winning, where her position is #i and the opponent's (the person who just spun) is j ProbWinning:=proc(N,CHUTES,LADDERS) local kvc,kvl,ac,al,i,eq,var,foll,j,j1,p,eq1,gu1,gu,tab,tab1: option remember: kvc:={}: for i from 1 to nops(CHUTES) do kvc:=kvc union {op(i,CHUTES)[1]}: ac[op(i,CHUTES)[1]]:=op(i,CHUTES)[2]: od: kvl:={}: for i from 1 to nops(LADDERS) do kvl:=kvl union {op(i,LADDERS)[1]}: al[op(i,LADDERS)[1]]:=op(i,LADDERS)[2]: od: for i from 0 to N-1 do if not member(i,kvc union kvl) then gu:=[i+1,i+2,i+3,i+4,i+5,i+6]: gu1:=[]: for j from 1 to nops(gu) do if op(j,gu)>=N then gu1:=[op(gu1),N]: elif member(op(j,gu),kvl) then gu1:=[op(gu1),al[op(j,gu)]]: elif member(op(j,gu),kvc) then gu1:=[op(gu1),ac[op(j,gu)]]: else gu1:=[op(gu1),op(j,gu)]: fi: od: foll[i]:=gu1: fi: od: eq:={}: var:={}: for i from 0 to N-1 do eq:=eq union {p[i,N]}: var:=var union {p[i,N]}: od: for i from 0 to N-1 do for j from 0 to N-1 do if not member(i,kvc union kvl) and not member(j,kvc union kvl) then var:=var union {p[i,j]}: gu:=foll[i]: eq1:=p[i,j]-1: for j1 from 1 to nops(gu) do eq1:=eq1 +p[j,gu[j1]]/6: od: eq:=eq union {eq1}: fi: od: od: var:=solve(eq,var): tab:=[]: for i from 0 to N-1 do tab1:=[]: for j from 0 to N-1 do tab1:=[op(tab1),subs(var,p[i,j])]: od: tab:=[op(tab),tab1]: od: tab: end: #PMBCAL(): The table of probabilities of winning p[i,j] #if it is your turn to spin, and you are at the i^th #position and your opponent is at the j^th position PMBCAL:=proc() local N,CHUTES,LADDERS: option remember: N:=100: CHUTES:={[16,6],[47,26],[49,11],[56,53],[62,19],[64,60],[87,24],[93,73], [95,75],[98,78]}; LADDERS:=[[1,38], [4,14],[9,31],[21,42],[28,84],[36,44],[51,67], [71,91],[80,100]]; ProbWinning(N,CHUTES,LADDERS): end: #Prob(i,j): The probablity of winning in the Milton-Bradley #Chutes and Ladders(tm) game if it is your turn #to spin and you are at the i^th place and your #opponent is at the j^th place Prob:=proc(i,j) PMBCAL()[i,j]: end: