-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from stanriders/main
Release 1.0.0
- Loading branch information
Showing
37 changed files
with
1,241 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
# EditorConfig is awesome: http://editorconfig.org | ||
root = true | ||
|
||
[*.cs] | ||
end_of_line = crlf | ||
insert_final_newline = true | ||
indent_style = space | ||
indent_size = 4 | ||
trim_trailing_whitespace = true | ||
|
||
#Roslyn naming styles | ||
|
||
#PascalCase for public and protected members | ||
dotnet_naming_style.pascalcase.capitalization = pascal_case | ||
dotnet_naming_symbols.public_members.applicable_accessibilities = public,internal,protected,protected_internal,private_protected | ||
dotnet_naming_symbols.public_members.applicable_kinds = property,method,field,event | ||
dotnet_naming_rule.public_members_pascalcase.severity = error | ||
dotnet_naming_rule.public_members_pascalcase.symbols = public_members | ||
dotnet_naming_rule.public_members_pascalcase.style = pascalcase | ||
|
||
#camelCase for private members | ||
dotnet_naming_style.camelcase.capitalization = camel_case | ||
|
||
dotnet_naming_symbols.private_members.applicable_accessibilities = private | ||
dotnet_naming_symbols.private_members.applicable_kinds = property,method,field,event | ||
dotnet_naming_rule.private_members_camelcase.severity = warning | ||
dotnet_naming_rule.private_members_camelcase.symbols = private_members | ||
dotnet_naming_rule.private_members_camelcase.style = camelcase | ||
|
||
dotnet_naming_symbols.local_function.applicable_kinds = local_function | ||
dotnet_naming_rule.local_function_camelcase.severity = warning | ||
dotnet_naming_rule.local_function_camelcase.symbols = local_function | ||
dotnet_naming_rule.local_function_camelcase.style = camelcase | ||
|
||
#all_lower for private and local constants/static readonlys | ||
dotnet_naming_style.all_lower.capitalization = all_lower | ||
dotnet_naming_style.all_lower.word_separator = _ | ||
|
||
dotnet_naming_symbols.private_constants.applicable_accessibilities = private | ||
dotnet_naming_symbols.private_constants.required_modifiers = const | ||
dotnet_naming_symbols.private_constants.applicable_kinds = field | ||
dotnet_naming_rule.private_const_all_lower.severity = warning | ||
dotnet_naming_rule.private_const_all_lower.symbols = private_constants | ||
dotnet_naming_rule.private_const_all_lower.style = all_lower | ||
|
||
dotnet_naming_symbols.private_static_readonly.applicable_accessibilities = private | ||
dotnet_naming_symbols.private_static_readonly.required_modifiers = static,readonly | ||
dotnet_naming_symbols.private_static_readonly.applicable_kinds = field | ||
dotnet_naming_rule.private_static_readonly_all_lower.severity = warning | ||
dotnet_naming_rule.private_static_readonly_all_lower.symbols = private_static_readonly | ||
dotnet_naming_rule.private_static_readonly_all_lower.style = all_lower | ||
|
||
dotnet_naming_symbols.local_constants.applicable_kinds = local | ||
dotnet_naming_symbols.local_constants.required_modifiers = const | ||
dotnet_naming_rule.local_const_all_lower.severity = warning | ||
dotnet_naming_rule.local_const_all_lower.symbols = local_constants | ||
dotnet_naming_rule.local_const_all_lower.style = all_lower | ||
|
||
#ALL_UPPER for non private constants/static readonlys | ||
dotnet_naming_style.all_upper.capitalization = all_upper | ||
dotnet_naming_style.all_upper.word_separator = _ | ||
|
||
dotnet_naming_symbols.public_constants.applicable_accessibilities = public,internal,protected,protected_internal,private_protected | ||
dotnet_naming_symbols.public_constants.required_modifiers = const | ||
dotnet_naming_symbols.public_constants.applicable_kinds = field | ||
dotnet_naming_rule.public_const_all_upper.severity = warning | ||
dotnet_naming_rule.public_const_all_upper.symbols = public_constants | ||
dotnet_naming_rule.public_const_all_upper.style = all_upper | ||
|
||
dotnet_naming_symbols.public_static_readonly.applicable_accessibilities = public,internal,protected,protected_internal,private_protected | ||
dotnet_naming_symbols.public_static_readonly.required_modifiers = static,readonly | ||
dotnet_naming_symbols.public_static_readonly.applicable_kinds = field | ||
dotnet_naming_rule.public_static_readonly_all_upper.severity = warning | ||
dotnet_naming_rule.public_static_readonly_all_upper.symbols = public_static_readonly | ||
dotnet_naming_rule.public_static_readonly_all_upper.style = all_upper | ||
|
||
#Roslyn formating options | ||
|
||
#Formatting - indentation options | ||
csharp_indent_case_contents = true | ||
csharp_indent_case_contents_when_block = false | ||
csharp_indent_labels = one_less_than_current | ||
csharp_indent_switch_labels = true | ||
|
||
#Formatting - new line options | ||
csharp_new_line_before_catch = true | ||
csharp_new_line_before_else = true | ||
csharp_new_line_before_finally = true | ||
csharp_new_line_before_open_brace = all | ||
#csharp_new_line_before_members_in_anonymous_types = true | ||
#csharp_new_line_before_members_in_object_initializers = true # Currently no effect in VS/dotnet format (16.4), and makes Rider confusing | ||
csharp_new_line_between_query_expression_clauses = true | ||
|
||
#Formatting - organize using options | ||
dotnet_sort_system_directives_first = true | ||
|
||
#Formatting - spacing options | ||
csharp_space_after_cast = false | ||
csharp_space_after_colon_in_inheritance_clause = true | ||
csharp_space_after_keywords_in_control_flow_statements = true | ||
csharp_space_before_colon_in_inheritance_clause = true | ||
csharp_space_between_method_call_empty_parameter_list_parentheses = false | ||
csharp_space_between_method_call_name_and_opening_parenthesis = false | ||
csharp_space_between_method_call_parameter_list_parentheses = false | ||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false | ||
csharp_space_between_method_declaration_parameter_list_parentheses = false | ||
|
||
#Formatting - wrapping options | ||
csharp_preserve_single_line_blocks = true | ||
csharp_preserve_single_line_statements = true | ||
|
||
#Roslyn language styles | ||
|
||
#Style - this. qualification | ||
dotnet_style_qualification_for_field = false:warning | ||
dotnet_style_qualification_for_property = false:warning | ||
dotnet_style_qualification_for_method = false:warning | ||
dotnet_style_qualification_for_event = false:warning | ||
|
||
#Style - type names | ||
dotnet_style_predefined_type_for_locals_parameters_members = true:warning | ||
dotnet_style_predefined_type_for_member_access = true:warning | ||
csharp_style_var_when_type_is_apparent = true:none | ||
csharp_style_var_for_built_in_types = true:none | ||
csharp_style_var_elsewhere = true:silent | ||
|
||
#Style - modifiers | ||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning | ||
csharp_preferred_modifier_order = public,private,protected,internal,new,abstract,virtual,sealed,override,static,readonly,extern,unsafe,volatile,async:warning | ||
|
||
#Style - parentheses | ||
# Skipped because roslyn cannot separate +-*/ with << >> | ||
|
||
#Style - expression bodies | ||
csharp_style_expression_bodied_accessors = true:warning | ||
csharp_style_expression_bodied_constructors = false:none | ||
csharp_style_expression_bodied_indexers = true:warning | ||
csharp_style_expression_bodied_methods = false:silent | ||
csharp_style_expression_bodied_operators = true:warning | ||
csharp_style_expression_bodied_properties = true:warning | ||
csharp_style_expression_bodied_local_functions = true:silent | ||
|
||
#Style - expression preferences | ||
dotnet_style_object_initializer = true:warning | ||
dotnet_style_collection_initializer = true:warning | ||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning | ||
dotnet_style_prefer_auto_properties = true:warning | ||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent | ||
dotnet_style_prefer_conditional_expression_over_return = true:silent | ||
dotnet_style_prefer_compound_assignment = true:warning | ||
|
||
#Style - null/type checks | ||
dotnet_style_coalesce_expression = true:warning | ||
dotnet_style_null_propagation = true:warning | ||
csharp_style_pattern_matching_over_is_with_cast_check = true:warning | ||
csharp_style_pattern_matching_over_as_with_null_check = true:warning | ||
csharp_style_throw_expression = true:silent | ||
csharp_style_conditional_delegate_call = true:warning | ||
|
||
#Style - unused | ||
dotnet_style_readonly_field = true:silent | ||
dotnet_code_quality_unused_parameters = non_public:silent | ||
csharp_style_unused_value_expression_statement_preference = discard_variable:silent | ||
csharp_style_unused_value_assignment_preference = discard_variable:warning | ||
|
||
#Style - variable declaration | ||
csharp_style_inlined_variable_declaration = true:warning | ||
csharp_style_deconstructed_variable_declaration = true:warning | ||
|
||
#Style - other C# 7.x features | ||
dotnet_style_prefer_inferred_tuple_names = true:warning | ||
csharp_prefer_simple_default_expression = true:warning | ||
csharp_style_pattern_local_over_anonymous_function = true:warning | ||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent | ||
|
||
#Style - C# 8 features | ||
csharp_prefer_static_local_function = true:warning | ||
csharp_prefer_simple_using_statement = true:silent | ||
csharp_style_prefer_index_operator = true:warning | ||
csharp_style_prefer_range_operator = true:warning | ||
csharp_style_prefer_switch_expression = false:none | ||
|
||
#Supressing roslyn built-in analyzers | ||
# Suppress: EC112 | ||
|
||
#Private method is unused | ||
dotnet_diagnostic.IDE0051.severity = silent | ||
#Private member is unused | ||
dotnet_diagnostic.IDE0052.severity = silent | ||
|
||
#Rules for disposable | ||
dotnet_diagnostic.IDE0067.severity = none | ||
dotnet_diagnostic.IDE0068.severity = none | ||
dotnet_diagnostic.IDE0069.severity = none |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using Pettanko.Difficulty; | ||
using Pettanko.Performance; | ||
using Xunit; | ||
|
||
namespace Pettanko.Tests | ||
{ | ||
public class CalculatorTests | ||
{ | ||
[Fact] | ||
public void TestOsuCalculator() | ||
{ | ||
var result = Pettanko.Calculate( | ||
new OsuDifficultyAttributes | ||
{ | ||
AimDifficulty = 2.9864489908605893, | ||
SpeedDifficulty = 3.1111283473891254, | ||
FlashlightDifficulty = 3.54341969421949, | ||
SliderFactor = 0.99796469139376365, | ||
ApproachRate = 9.50, | ||
OverallDifficulty = 9.00, | ||
MaxCombo = 3220, | ||
HitCircleCount = 1534, | ||
SliderCount = 587, | ||
SpinnerCount = 5 | ||
}, | ||
new Score | ||
{ | ||
RulesetId = 0, | ||
Accuracy = 1.0, | ||
MaxCombo = 3220, | ||
Statistics = new Statistics | ||
{ | ||
Count300 = 2126 | ||
} | ||
}); | ||
|
||
var osuPerfAttributes = result as OsuPerformanceAttributes; | ||
|
||
Assert.NotNull(osuPerfAttributes); | ||
Assert.Equal(455.90599187959032, osuPerfAttributes.Total); | ||
Assert.Equal(141.45654132294621, osuPerfAttributes.Aim); | ||
Assert.Equal(167.49667236961548, osuPerfAttributes.Speed); | ||
Assert.Equal(140.70696717850745, osuPerfAttributes.Accuracy); | ||
Assert.Equal(0.0000, osuPerfAttributes.Flashlight); | ||
Assert.Equal(0.0000, osuPerfAttributes.EffectiveMissCount); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> | ||
<PackageReference Include="xunit" Version="2.4.0" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | ||
<PackageReference Include="coverlet.collector" Version="1.2.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Pettanko\Pettanko.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.0.31912.275 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pettanko", "Pettanko\Pettanko.csproj", "{A5154878-72F7-4E36-9FB7-25B5C9E2B884}" | ||
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pettanko.Tests", "Pettanko.Tests\Pettanko.Tests.csproj", "{1D2CD22C-6716-4707-8A6E-007F7D1A9FB4}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{A5154878-72F7-4E36-9FB7-25B5C9E2B884}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{A5154878-72F7-4E36-9FB7-25B5C9E2B884}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{A5154878-72F7-4E36-9FB7-25B5C9E2B884}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{A5154878-72F7-4E36-9FB7-25B5C9E2B884}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{1D2CD22C-6716-4707-8A6E-007F7D1A9FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{1D2CD22C-6716-4707-8A6E-007F7D1A9FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{1D2CD22C-6716-4707-8A6E-007F7D1A9FB4}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{1D2CD22C-6716-4707-8A6E-007F7D1A9FB4}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {73ADA6B4-4B6C-439B-89F6-49B0BC85CE5B} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. | ||
|
||
using System; | ||
using System.Linq; | ||
using Pettanko.Difficulty; | ||
using Pettanko.Mods; | ||
using Pettanko.Performance; | ||
|
||
namespace Pettanko.Calculators | ||
{ | ||
public class CatchPerformanceCalculator : IPerformanceCalculator | ||
{ | ||
private int fruitsHit; | ||
private int ticksHit; | ||
private int tinyTicksHit; | ||
private int tinyTicksMissed; | ||
private int misses; | ||
|
||
public PerformanceAttributes Calculate(DifficultyAttributes difficultyAttributes, Score scoreData) | ||
{ | ||
var catchAttributes = (CatchDifficultyAttributes)difficultyAttributes; | ||
|
||
fruitsHit = scoreData.Statistics.Count300; | ||
ticksHit = scoreData.Statistics.Count100; | ||
tinyTicksHit = scoreData.Statistics.Count50; | ||
tinyTicksMissed = scoreData.Statistics.CountKatu; | ||
misses = scoreData.Statistics.CountMiss; | ||
|
||
// We are heavily relying on aim in catch the beat | ||
double value = Math.Pow(5.0 * Math.Max(1.0, catchAttributes.StarRating / 0.0049) - 4.0, 2.0) / 100000.0; | ||
|
||
// Longer maps are worth more. "Longer" means how many hits there are which can contribute to combo | ||
int numTotalHits = totalComboHits(); | ||
|
||
double lengthBonus = | ||
0.95 + 0.3 * Math.Min(1.0, numTotalHits / 2500.0) + | ||
(numTotalHits > 2500 ? Math.Log10(numTotalHits / 2500.0) * 0.475 : 0.0); | ||
value *= lengthBonus; | ||
|
||
value *= Math.Pow(0.97, misses); | ||
|
||
// Combo scaling | ||
if (catchAttributes.MaxCombo > 0) | ||
value *= Math.Min(Math.Pow(scoreData.MaxCombo, 0.8) / Math.Pow(catchAttributes.MaxCombo, 0.8), 1.0); | ||
|
||
double approachRate = catchAttributes.ApproachRate; | ||
double approachRateFactor = 1.0; | ||
if (approachRate > 9.0) | ||
approachRateFactor += 0.1 * (approachRate - 9.0); // 10% for each AR above 9 | ||
if (approachRate > 10.0) | ||
approachRateFactor += 0.1 * (approachRate - 10.0); // Additional 10% at AR 11, 30% total | ||
else if (approachRate < 8.0) | ||
approachRateFactor += 0.025 * (8.0 - approachRate); // 2.5% for each AR below 8 | ||
|
||
value *= approachRateFactor; | ||
|
||
if (scoreData.Mods.Any(m => m is ModHidden)) | ||
{ | ||
// Hiddens gives almost nothing on max approach rate, and more the lower it is | ||
if (approachRate <= 10.0) | ||
value *= 1.05 + 0.075 * (10.0 - approachRate); // 7.5% for each AR below 10 | ||
else if (approachRate > 10.0) | ||
value *= 1.01 + 0.04 * (11.0 - Math.Min(11.0, approachRate)); // 5% at AR 10, 1% at AR 11 | ||
} | ||
|
||
if (scoreData.Mods.Any(m => m is ModFlashlight)) | ||
value *= 1.35 * lengthBonus; | ||
|
||
value *= Math.Pow(accuracy(), 5.5); | ||
|
||
if (scoreData.Mods.Any(m => m is ModNoFail)) | ||
value *= 0.90; | ||
|
||
return new CatchPerformanceAttributes | ||
{ | ||
Total = value | ||
}; | ||
} | ||
private double accuracy() => totalHits() == 0 ? 0 : Extensions.Clamp((double)totalSuccessfulHits() / totalHits(), 0, 1); | ||
private int totalHits() => tinyTicksHit + ticksHit + fruitsHit + misses + tinyTicksMissed; | ||
private int totalSuccessfulHits() => tinyTicksHit + ticksHit + fruitsHit; | ||
private int totalComboHits() => misses + ticksHit + fruitsHit; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Pettanko.Difficulty; | ||
using Pettanko.Performance; | ||
|
||
namespace Pettanko.Calculators | ||
{ | ||
public interface IPerformanceCalculator | ||
{ | ||
PerformanceAttributes Calculate(DifficultyAttributes difficultyAttributes, Score scoreData); | ||
} | ||
} |
Oops, something went wrong.