@@ -133,73 +133,69 @@ protected async Task<double[]> GetLadderScore(double[] scores)
133
133
// 解析 JSON 字符串
134
134
var result = JsonConvert . DeserializeObject < List < ContestResult > > ( jsonString ) ;
135
135
double [ ] org = ( from r in result select ( double ) ( r . score ) ) . ToArray ( ) ;
136
- double [ ] final = Cal ( org , scores ) ;
136
+ double [ ] final = LadderCalculate ( org , scores ) ;
137
137
return final ;
138
138
}
139
139
catch ( Exception e )
140
140
{
141
141
GameServerLogging . logger . ConsoleLog ( "No response from ladder URL!" ) ;
142
142
GameServerLogging . logger . ConsoleLog ( e . ToString ( ) ) ;
143
- return new double [ 0 ] ;
143
+ return [ ] ;
144
144
}
145
145
}
146
146
else
147
147
{
148
148
GameServerLogging . logger . ConsoleLog ( "Null URL!" ) ;
149
- return new double [ 0 ] ;
149
+ return [ ] ;
150
150
}
151
151
}
152
152
153
- protected double [ ] Cal ( double [ ] orgScore , double [ ] competitionScore )
153
+ protected static double [ ] LadderCalculate ( double [ ] oriScores , double [ ] competitionScores )
154
154
{
155
- // 调整顺序,让第一个元素成为获胜者,便于计算
156
- bool reverse = false ; // 记录是否需要调整
157
- if ( competitionScore [ 0 ] < competitionScore [ 1 ] )
155
+ // 调整顺序,让第一项成为获胜者,便于计算
156
+ bool scoresReverse = false ; // 顺序是否需要交换
157
+ if ( competitionScores [ 0 ] < competitionScores [ 1 ] ) // 第一项为落败者
158
+ scoresReverse = true ;
159
+ else if ( competitionScores [ 0 ] == competitionScores [ 1 ] ) // 平局
158
160
{
159
- reverse = true ;
160
- }
161
- else if ( competitionScore [ 0 ] == competitionScore [ 1 ] )
162
- {
163
- if ( orgScore [ 0 ] == orgScore [ 1 ] )
164
- {
161
+ if ( oriScores [ 0 ] == oriScores [ 1 ] )
165
162
// 完全平局,不改变天梯分数
166
- return orgScore ;
167
- }
168
- if ( orgScore [ 0 ] > orgScore [ 1 ] )
169
- {
170
- // 本次游戏平局,但一方天梯分数高,另一方天梯分数低,需要将两者向中间略微靠拢,因此天梯分数低的定为获胜者
171
- reverse = true ;
172
- }
163
+ return oriScores ;
164
+ if ( oriScores [ 0 ] > oriScores [ 1 ] )
165
+ // 本次游戏平局,但一方天梯分数高,另一方天梯分数低,
166
+ // 需要将两者向中间略微靠拢,因此天梯分数低的定为获胜者
167
+ scoresReverse = true ;
173
168
}
174
- if ( reverse )
169
+ if ( scoresReverse ) // 如果需要换,交换两者的顺序
175
170
{
176
- // 如果需要换,换两者的顺序
177
- double t = competitionScore [ 1 ] ;
178
- competitionScore [ 1 ] = competitionScore [ 0 ] ;
179
- competitionScore [ 0 ] = t ;
180
- t = orgScore [ 1 ] ;
181
- orgScore [ 1 ] = orgScore [ 0 ] ;
182
- orgScore [ 0 ] = t ;
171
+ ( competitionScores [ 0 ] , competitionScores [ 1 ] ) = ( competitionScores [ 1 ] , competitionScores [ 0 ] ) ;
172
+ ( oriScores [ 0 ] , oriScores [ 1 ] ) = ( oriScores [ 1 ] , oriScores [ 0 ] ) ;
183
173
}
174
+
175
+ const double normalDeltaThereshold = 1000.0 ; // 分数差标准化参数,同时也是大分数差阈值
176
+ const double correctParam = normalDeltaThereshold * 1.2 ; // 修正参数
177
+ const double winnerWeight = 9e-6 ; // 获胜者天梯得分权值
178
+ const double loserWeight = 5e-6 ; // 落败者天梯得分权值
179
+ const double scoreDeltaThereshold = 2100.0 ; // 极大分数差阈值
180
+
184
181
double [ ] resScore = [ 0 , 0 ] ;
185
- double deltaWeight = 1000.0 ; // 差距悬殊判断参数
186
- double delta = ( orgScore [ 0 ] - orgScore [ 1 ] ) / deltaWeight ;
187
- // 盈利者天梯得分权值、落败者天梯得分权值
188
- double firstnerGet = 9e-6 ;
189
- double secondrGet = 5e-6 ;
190
- double deltaScore = 2100.0 ; // 两队竞争分差超过多少时就认为非常大
191
- double correctRate = ( orgScore [ 0 ] - orgScore [ 1 ] ) / ( deltaWeight * 1.2 ) ; // 订正的幅度,该值越小,则在势均力敌时天梯分数改变越大
192
- double correct = 0.5 * ( Math . Tanh ( ( competitionScore [ 0 ] - competitionScore [ 1 ] - deltaScore ) / deltaScore - correctRate ) + 1.0 ) ; // 一场比赛中,在双方势均力敌时,减小天梯分数的改变量
193
- resScore [ 0 ] = orgScore [ 0 ] + Math . Round ( competitionScore [ 0 ] * competitionScore [ 0 ] * firstnerGet * ( 1 - Math . Tanh ( delta ) ) * correct ) ; // 胜者所加天梯分
194
- resScore [ 1 ] = orgScore [ 1 ] - Math . Round (
195
- ( competitionScore [ 0 ] - competitionScore [ 1 ] ) * ( competitionScore [ 0 ] - competitionScore [ 1 ] ) * secondrGet * ( 1 - Math . Tanh ( delta ) ) * correct ) ; // 败者所扣天梯分
196
- // 如果换过,再换回来
197
- if ( reverse )
198
- {
199
- double t = resScore [ 1 ] ;
200
- resScore [ 1 ] = resScore [ 0 ] ;
201
- resScore [ 0 ] = t ;
202
- }
182
+ double oriDelta = oriScores [ 0 ] - oriScores [ 1 ] ; // 原分数差
183
+ double competitionDelta = competitionScores [ 0 ] - competitionScores [ 1 ] ; // 本次比赛分数差
184
+ double normalOriDelta = oriDelta / normalDeltaThereshold ; // 标准化原分数差
185
+ double correctRate = oriDelta / correctParam ; // 修正率,修正方向为缩小分数差
186
+ double correct = 0.5 * ( Math . Tanh ( ( competitionDelta - scoreDeltaThereshold ) / scoreDeltaThereshold
187
+ - correctRate )
188
+ + 1.0 ) ; // 分数修正
189
+ resScore [ 0 ] = oriScores [ 0 ] + Math . Round ( Math . Pow ( competitionScores [ 0 ] , 2 )
190
+ * winnerWeight
191
+ * ( 1 - Math . Tanh ( normalOriDelta ) )
192
+ * correct ) ; // 胜者所加天梯分
193
+ resScore [ 1 ] = oriScores [ 1 ] - Math . Round ( Math . Pow ( competitionDelta , 2 )
194
+ * loserWeight
195
+ * ( 1 - Math . Tanh ( normalOriDelta ) )
196
+ * correct ) ; // 败者所扣天梯分
197
+ if ( scoresReverse ) // 顺序换回
198
+ ( resScore [ 0 ] , resScore [ 1 ] ) = ( resScore [ 1 ] , resScore [ 0 ] ) ;
203
199
return resScore ;
204
200
}
205
201
0 commit comments