So I would like to post the following code to help possible newbies like me (I'm no newcomer, I'm just noob).
I edited with notepad++ using "language ->N - Normal text" and then the chapter J of the AUR to help me with the translation of special chars that are not available in plain text.
The following code contains subprograms that can be easily disabled, for debugging purposes, avoiding to execute EVAL after them or after recalling them.
In the same way, if instead of EVAL, DBUG is used, then the user can DBUG exactly the wanted block and nothing else, simply evaluating the main program (The execution will stop once DBUG is reached, then one can proceed with the RUN & DEBUG menu). Speeding up the identification of problems. Once I discover this the debugging of quirks in the program was way faster than my previous experiences. It is something should be more advertised for newcomers, I wish I would known before.
Then I suppose the directory structure in one source file would be even better but it is something I'm going to use after this post for the first time.
Code:
%%HP: T(0)A(D)F(.);
@ You may edit the T(0)A(D)F(.) parts.
@ The earlier parts of the line are used by Debug4x.
@ in npp, just select encoding "normal" to get rid of the highlight.
@ Objective:
@ - We want to compare the expected performances of teams of a certain
@ average strength in some types of tournaments to determine
@ what is the one that determines the best team.
@ Assuming that the best team is the one is given higher strength
@ a priori. Of course the simulation of the tournaments
@ should be done some times to determine the percentage of winning.
@ 1. round robin. Every team meet everyone else, at least twice.
@ (it could be extended with four times, six and so on)
@ Often used in long tournaments.
@ This is assumed as the best format and will be used as reference.
@ 2. swiss tournament
@ Random pairings, and then teams with high score meet other teams
@ with high score, if possible avoiding pairings already done.
@ The minimum is that teams meet once.
@ Often used in chess, short but maybe effective.
@ 3. knowckout tournaments. Random pairing at the start and then
@ the ones that wins proceed.
@ Often used in "show tournaments", short but maybe not so effective.
@ 4. only one match against all the others (like half of a round robin)
@ Often used in show tournaments. Short but maybe not so effective.
@ Remarks: the comments try to give an idea, the values in the comments may
@ be different from the actual code though.
\<<
'n*25+1200' 'n' 1 16 1 SEQ
@listTeams
@ list of teams with a priori strength score
0 @numTeams
0 @tmpV to use for short time, value can be changed in other functions!
0 @tmpV2
0 @maxSumProbV
0 @numProbV
0 @mVarProb
0 @curProbV
1 @colSumProb
2 @colProb
3 @colVar
0 @getVarFunc
0 @matchResFunc
10 @uFteamAwon
30 @uFmatchingProbFound
0 @rrFunc
0 @teamAstrV
0 @teamBstrV
0 @teamAtmpV
0 @teamBtmpV
0 @rrResArr
0 @rrResList (not sure what I'll use)
0 @IncListElFunc
1 @pointsForWin
\->
listTeams
numTeams
tmpV
tmpV2
maxSumProbV
numProbV
mVarProb
curProbV
colSumProb
colProb
colVar
getVarFunc
matchResFunc
uFteamAwon
uFmatchingProbFound
rrFunc
teamAstrV
teamBstrV
teamAtmpV
teamBtmpV
rrResArr
rrResList
IncListElFunc
pointsForWin
\<<
listTeams SIZE 'numTeams' STO
\<<
@ creating the matrix containing the probability of the points oscillation
@ between -400 points and +400 points
@ every drop or increment of the base strength is made in 25 points.
@ those points have a probability. So I assign "probability tokens" at every
@ change. For example.
@ -400 has 25 prob tokens. -375 has 50, -350 has 75 and so on, until the
@ base value then goes back. +25 has 400 tokens, +50 has 375 and so on.
@ so I want to model those tokens.
'n' 'n' 25 400 25 SEQ
425 +
@ expanding the previous list with 425
'n' 'n' 400 25 -25 SEQ
@ Or REVLIST could have been used.
+ 'tmpV' STO
@ storing the list
@ the complete list now goes from 25 to 425 and back to 25.
@ Now we want to create the sum of all this tokens,
@ one value for each token, We can use STREAM but we need to recall
@ objects from the tack. I do not like stack operations because
@ they are unreadable but when they are a little it is ok.
@ otherwise one should comment the actions.
1 'tmpV2' STO
@ counter, it needs to start from 1.
tmpV
\<<
@ having 25 50 75 100
@ STREAM 25 2 Pick 25 + 25 STREAM 25 Pick 2 25 + 25 STREAM 25 Pick 2 25 + 25
@ 50 50 75 75 75 75 75 75 75
@ 25 75 75 150 150 150 150
@ 75 100 100 250
@ 150
2 PICK
+
1 'tmpV2' STO+
@we need to count the objects that we leave on the stack. Plus 1 added at the start.
\>>
STREAM
@now we have the list with all the sums
@before making a vector out of it we save the last value that is the maximum value.
DUP 'maxSumProbV' STO
@we continue
tmpV2
@ the number of objects.
\->ARRY
@ transformed in a vector
tmpV
@ the first list
OBJ\->
@ exploded
@before saving it as vector I save the number of elements or
@probility tokens (equals to variances)
DUP 'numProbV' STO
\->ARRY
@ transformed in a vector
'n' 'n' -400 -25 25 SEQ
0 +
'n' 'n' 25 400 +25 SEQ
+ OBJ\->
@ added and then exploded
\->ARRY
@ transformed in a vector
3 COL\-> 'mVarProb' STO
@final matrix with columns: sum of probability tokens, probability tokens for variance, variance in points.
\>>
EVAL
@compute the above program immediately
\<<
@program to extract the variance out of the built matrix
@output, the variance of the strength points out of the matrix
maxSumProbV RAND * 1 + IP 'curProbV' STO
@ we get a random vnumber that has to be compared with the probability sums
1 'tmpV' STO
@with tmpV we will use it as a counter
uFmatchingProbFound CF
WHILE
uFmatchingProbFound FC?
tmpV numProbV \<=
AND
REPEAT
IF
curProbV 'mVarProb(tmpV, colSumProb)' EVAL \<=
@accessing the matrix in algebraic mode, slower but more readable.
@ than the messy RPN (RPN is not always less readable, but in some cases)
@maintenance and debug use resources as well that often are more valuable.
THEN
@ found a probability sum bigger than the actual random value.
uFmatchingProbFound SF
ELSE
1 'tmpV' STO+
END
END
'mVarProb(tmpV, colVar)' EVAL
\>>
'getVarFunc' STO
@get variance function.
\<<
@program to compute the result of a match based on the variance and probability of it.
@ should be used by all the tournaments.
@In input are expected the strength of the two teams
@ and a user flag for the result
@as for of variables already existing.
@teamA
@teamB
@userFlagNumber
@in output a flag is set
@if teamA won, otherwise teamB
uFteamAwon CF
@ teamA streangth modified
teamAstrV
getVarFunc EVAL
+ 'teamAtmpV' STO
@ teamB streangth modified
teamBstrV
getVarFunc EVAL
+ 'teamBtmpV' STO
@there is no draw possible, at least for now.
IF
teamAtmpV teamBtmpV >
THEN
@teamA won.
uFteamAwon SF
ELSE
@ teamA with lower or equal strength
IF
teamAtmpV teamBtmpV <
THEN
@teamA lost
uFteamAwon CF
ELSE
@ same strength
@ coin toss
IF
RAND 10 * IP
5 <
THEN
@teamA won
uFteamAwon SF
ELSE
@teamA lost
uFteamAwon CF
END
END
END
\>>
'matchResFunc' STO
\<<
@ program to increase the value of element in a list
@ input on the stack see variables
@ see the following, that if I keep adding variables on the main
@ program it gets too unreadable.
\->
lList
@list
lPosV
@position of the element
lincV
@increase
\<<
lList lPosV
@placing list and position on the stack
@for storing, later.
lList lPosV GET
lincV +
@getting the value and increasing it
PUT
@putting the increasing value back
\>>
\>>
'IncListElFunc' STO
\<<
@program to compute a round robin tournament
@ given a list of teams with their strength and other
@already named and set variables.
@output, the list of teams with final points.
'0' 'n' 1 numTeams 1
SEQ 'rrResList' STO
@saving the result list that at the start is just zeroes
1
numTeams 1 -
FOR teamPosA
listTeams teamPosA GET 'teamAstrV' STO
@get first team
teamPosA 1 +
numTeams
FOR teamPosB
listTeams teamPosB GET 'teamBstrV' STO
@get second team team
@compute the result of a match. twice
@as round robin requirement.
1 2
FOR counter
matchResFunc EVAL
IF
uFteamAwon FS?
THEN
@update results
rrResList teamPosA pointsForWin
IncListElFunc EVAL
'rrResList' STO
ELSE
@update results
rrResList teamPosB pointsForWin
IncListElFunc EVAL
'rrResList' STO
END
NEXT
NEXT
NEXT
rrResList
\>>
'rrFunc' STO
rrFunc EVAL
\>>
\>>
@ log {
@ 12:05 29.03.2017{
@ Generating list of 16 teams between 1200 and 1600 strength points
@ 'n*25+1200' 'n' 1 16 1 SEQ
@ }
@ }