private static List <OsuMovement> createMovements(List <OsuHitObject> hitObjects, double clockRate, List <Vector <double> > strainHistory) { OsuMovement.Initialize(); var movements = new List <OsuMovement>(); if (hitObjects.Count == 0) { return(movements); } // the first object movements.AddRange(OsuMovement.ExtractMovement(hitObjects[0])); // the rest for (int i = 1; i < hitObjects.Count; i++) { var obj0 = i > 1 ? hitObjects[i - 2] : null; var obj1 = hitObjects[i - 1]; var obj2 = hitObjects[i]; var obj3 = i < hitObjects.Count - 1 ? hitObjects[i + 1] : null; var tapStrain = strainHistory[i]; movements.AddRange(OsuMovement.ExtractMovement(obj0, obj1, obj2, obj3, tapStrain, clockRate)); } return(movements); }
public static double CalculateCheeseHitProb(OsuMovement movement, double tp, double cheeseLevel) { double perMovementCheeseLevel = cheeseLevel; if (movement.EndsOnSlider) { perMovementCheeseLevel = 0.5 * cheeseLevel + 0.5; } double cheeseMt = movement.MovementTime * (1 + perMovementCheeseLevel * movement.CheesableRatio); return(FittsLaw.CalculateHitProb(movement.Distance, cheeseMt, tp)); }
/// <summary> /// Estimates the probability of hitting the given <paramref name="movement"/>, with added penalty for cheesable /// movements given by <paramref name="cheeseLevel"/>. /// </summary> /// <param name="movement">The movement being performed by the player.</param> /// <param name="throughput"> /// The assumed throughput of the player in terms of Fitts's law /// (functioning as a skill measure). /// </param> /// <param name="cheeseLevel">The penalty to apply to cheesable movements.</param> public static double GetHitProbabilityAdjustedForCheese(OsuMovement movement, double throughput, double cheeseLevel) { double perMovementCheeseLevel = cheeseLevel; if (movement.EndsOnSlider) { perMovementCheeseLevel = 0.5 * cheeseLevel + 0.5; } // if the movement can be cheesed, movement time is increased, resulting in a difficulty decrease double adjustedMovementTime = movement.MovementTime * (1 + perMovementCheeseLevel * movement.CheeseWindow); return(FittsLaw.ProbabilityToHit(movement.Distance, adjustedMovementTime, throughput)); }
/// <summary> /// Converts hit objects into movements. /// </summary> /// <param name="hitObjects">List of all map hit objects</param> /// <param name="strainHistory">List of all hit objects' tap strain</param> /// <param name="noteDensities">List of all hit objects' visual note densities</param> /// <param name="clockRate">Clock rate</param> /// <param name="hidden">Are we calculating hidden mod?</param> /// <returns>List of all movements</returns> private static List <OsuMovement> createMovements(List <OsuHitObject> hitObjects, double clockRate, List <Vector <double> > strainHistory, bool hidden = false, List <double> noteDensities = null) { var movements = new List <OsuMovement>(); if (hitObjects.Count == 0) { return(movements); } // the first object movements.AddRange(OsuMovement.ExtractMovement(hitObjects[0])); // the rest for (int i = 1; i < hitObjects.Count; i++) { var objNeg4 = i > 3 ? hitObjects[i - 4] : null; var objNeg2 = i > 1 ? hitObjects[i - 2] : null; var objPrev = hitObjects[i - 1]; var objCurr = hitObjects[i]; var objNext = i < hitObjects.Count - 1 ? hitObjects[i + 1] : null; var tapStrain = strainHistory[i]; if (hidden) { movements.AddRange(OsuMovement.ExtractMovement(objNeg2, objPrev, objCurr, objNext, tapStrain, clockRate, hidden: true, noteDensity: noteDensities[i], objNeg4: objNeg4)); } else { movements.AddRange(OsuMovement.ExtractMovement(objNeg2, objPrev, objCurr, objNext, tapStrain, clockRate, objNeg4: objNeg4)); } } return(movements); }
private static double calculateCheeseHitProb(OsuMovement movement, double tp, double cheeseLevel) { double cheeseMT = movement.MT * (1 + cheeseLevel * movement.CheesableRatio); return(FittsLaw.CalculateHitProb(movement.D, cheeseMT, tp)); }