Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- The algorithm is based of patterns repetitions (and doesn't take into consideration the properties of the patterns themselves, only their
- variety in the same map). For example (CAPS means 1/2 note, undercase means 1/4 note):
- dddddddd will have a very low value since it can be break down into many repeating patterns:
- dddd dddd
- ddd d ddd d
- ddd dd ddd
- d d d d d d d d
- etc...
- dkdkdkdk will have a higher value since there are less ways it can be break down forming repeating patterns
- and something like dkKkdDKkKDdkKkdDKkKD will have a considerably higher value.
- 1) The algorithm first reads the taiko map, and generates a list of the sequence of hits needed in the map.
- Each hit in the map has 2 values:
- - The amount of time since the previous hit, in centiseconds, rounded to the nearest centisecond.
- (rounding is needed because of small millisecond differences in the timings in the .osu file,
- which would make seem notes that are practically the same as different kinds of notes).
- For the first hit of the map, set it to -1 as default.
- - Whether the note is red or blue (0 for red, 1 for blue).
- The list would be something like this: HITS= {{-1, 0}, {18, 0}, {88, 0}, {18, 0}, {159, 1}, {18, 0}, {88, 0}...}
- 2) Run an algorithm that finds pattern repetitions, gives a weight for each hit according to the patterns found, and gives a total result.
- Written in Wolfram Language, which shouldn't be hard to understand. (*___*) denotes comments.
- RhythmDifficulty[HITS_,MaxSearch_:-1]:= (*Function definition, with second argument defaulting to -1*)
- Module[{TheMatrix,NoteStrains,Len=Length[HITS],Step,Bonus,i,j,k}, (*Initialize Local Variables*)
- If[MaxSearch==-1,(*Then*) Step=Len,(*Else*) Step=Min[Len,MaxSearch]];
- TheMatrix=ConstantArray[0,{Len+1,Len+1}];(*Make a Matrix with all values equal zero, with information of the patterns found*)
- NoteStrains=ConstantArray[0,Len];(*Make a List, that contains information of the weight of each note in the map*)
- For[i=Len,i>= 1,i--, (*Iterate for each note in the map, starting from the last note, i=1 for the first note, i=Len for the last*)
- For[j=Min[Len,i+Step],j>i,j--, (*Iterate for notes after the current note, up to Step notes, starting from farthest note*)
- If[HITS[[i]]==HITS[[j]], (*If a note is repeated*)
- TheMatrix[[i,j]]=Min[TheMatrix[[i+1,j+1]]+1,j-i]; (*TheMatrix[[i,j]] is the length of the repeating pattern found*)
- Bonus=0.75^(j-i-1); (*Weight according to how far are the elements on the pattern repetition found*)
- For[k=j,k<j+TheMatrix[[i,j]],k++,(*Iterate for each note that belongs to the pattern found, in the repeated instance*)
- NoteStrains[[k]]+=Bonus*(TheMatrix[[i,j]]-(k-j));
- ]
- ]
- ]
- ];
- NoteStrains=0.95^NoteStrains; (*{1,2,3} -> {0.95^1, 0.95^2, 0.95^3}*)
- Total[NoteStrains] (*Sum the values of the list and return the result*)]
- The second argument (MaxSearch) determines how far from each note the repetitions will be search, -1 means that every pattern repetition will be search (which would take a lot of time for longer maps), while using a value of 25 will search for repetitions up to 25 notes after each note.
- Here are some results of the algorithm in different sequences and maps (if not specified, the algorithm was used with MaxSearch 25):
- http://a.pomf.se/xwdmtj.xls
- The worst case scenario (in calculation time) is a map where all the notes are the same (which allows generating many patterns), and, for a constant amount of notes, the least amount of repeating patterns found, the least amount of time the algorithm takes.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement