frettableDifficulty function
Implementation
int frettableDifficulty(List<int> frets) {
List<List<Map<String, int>>> usedFingers = [];
int difficulty = 0;
for (int string = 0; string < frets.length; string++) {
int fret = frets[string];
List<Map<String, int>> newGroup = [];
Map<String, int> note = {'fret': fret, 'string': string};
if (fret > 0) {
bool needNewGroup = true;
// first try to add note to one of current finger groups
for (var fingerGroup in usedFingers) {
int groupFret = fingerGroup[0]['fret']!;
int groupString = fingerGroup[0]['string']!;
// barre if fret number matches where finger is fretted on a previous note
// but dont barre when:
// * on top 5 strings and next note in sequence is a lower fret
// * on 5th note and third group, and last note would create fourth group
if (fret == groupFret &&
!(string < 5 && fret >= frets[string + 1]) &&
!(string == 4 && frets[5] != fret && usedFingers.length == 3)) {
// if the in between notes are on higher frets
List<int> diff = frets.sublist(groupString + 1, string);
if (diff.where((i) => (i >= fret)).length == diff.length) {
// then barre this note with the rest of this finger group
fingerGroup.add(note);
needNewGroup = false;
}
}
}
// otherwise create new group
if (needNewGroup) {
newGroup.add(note);
usedFingers.add(newGroup);
if (newGroup.length == 1) {
difficulty++;
} else {
difficulty += 2;
}
}
}
}
return difficulty;
}