From da6bfb561a092dfb9956f0f97512a64c07add2b7 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 10 Jan 2020 21:53:59 +0100 Subject: Object-oriented re-factor --- http/api-inc.php | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ http/api.php | 199 ++--------------------------------------------------- 2 files changed, 209 insertions(+), 194 deletions(-) create mode 100644 http/api-inc.php diff --git a/http/api-inc.php b/http/api-inc.php new file mode 100644 index 0000000..40aa612 --- /dev/null +++ b/http/api-inc.php @@ -0,0 +1,204 @@ + "Bad Request", + 500 => "Internal Server Error"); + if (!isset($codes[$code])) { + return; + } + $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'); + header($protocol . ' ' . $code . ' ' . $codes[$code]); + } +} + +function safe_ceil($value, $precision = 1e-6) { + $ceilValue = ceil($value); + return (abs($value - $ceilValue) < (1-$precision)) ? $ceilValue : round($value); +} + +function recursive_ksort(&$array, $flags = SORT_REGULAR) { + if (!is_array($array)) return false; + ksort($array, $flags); + foreach ($array as &$arr) { + recursive_ksort($arr, $flags); + } + return true; +} + +class ParametersException extends Exception {}; + +class ApiPkl { + + const RANK_KMP = 101; + + protected $parameters; + + function __construct($parameters) { + $this->parameters = $parameters; + $this->check_parameters($parameters); + $this->parameters = $this->parse_parameters($parameters); + } + + function ensure_parameters($params) { + foreach ($params as $param) { + if (!isset($this->parameters[$param])) { + throw new ParametersException('Missing parameter: ' . $param); + } + if (!is_numeric($this->parameters[$param])) { + throw new ParametersException('Parameter: ' . $param . ' is not a numeric value (' . $this->parameters[$param] . ')'); + } + } + } + + function check_values($parameters, $params) { + foreach ($params as $param => $test) { + if (!$test($parameters[$param])) { + throw new ParametersException('Parameter: ' . $param . ' has incorrect value (' . $parameters[$param] . ')'); + } + } + } + + function check_parameters() { + $this->ensure_parameters(array('type', 'contestants', 'title_sum')); + $this->check_values($this->parameters, array( + 'type' => function($r) { return ctype_digit($r) && intval($r) > 0; }, + 'contestants' => function($r) { return ctype_digit($r) && intval($r) > 0; }, + 'title_sum' => function($r) { return floatval($r) >= 0; } + )); + if (isset($this->parameters['players'])) { + $this->check_values($this->parameters, array( + 'players' => function($r) { return ctype_digit($r) && intval($r) > 0; } + )); + } + if (!isset($this->parameters['manual']) || !isset($this->parameters['manual']['min_points']) || !isset($this->parameters['manual']['tournament_weight'])) { + $this->ensure_parameters(array('tournament_rank', 'over39_boards')); + $this->check_values($this->parameters, array( + 'tournament_rank' => function($r) { return ctype_digit($r) && ((intval($r) >= 0 && intval($r) <= 7) || intval($r) == self::RANK_KMP); }, + 'over39_boards' => function($r) { return ctype_digit($r) && intval($r) >= 0 && intval($r) <= 1; } + )); + } else { + $this->check_values($this->parameters['manual'], array( + 'min_points' => function($r) { return ctype_digit($r) && intval($r) >= 0; }, + 'tournament_weight' => function($r) { return ctype_digit($r) && intval($r) > 0; } + )); + } + if (isset($this->parameters['manual']) && isset($this->parameters['manual']['players_coefficient'])) { + $this->check_values($this->parameters['manual'], array( + 'players_coefficient' => function($r) { return floatval($r) >= 0; } + )); + } + } + + function parse_parameters() { + $return = array(); + $return['type'] = intval($this->parameters['type']); + if ($return['type'] == 3 || $return['type'] > 4) { + throw new ParametersException('Parameter: type has incorrect value (' . $return['type'] . ')'); + } + if ($return['type'] != 2 && $this->parameters['tournament_rank'] == self::RANK_KMP) { + throw new ParametersException('Parameter: type has incorrect value (' . $return['type'] . ') for KMP tournament'); + } + $return['contestants'] = intval($this->parameters['contestants']); + $return['players'] = isset($this->parameters['players']) ? intval($this->parameters['players']) : intval($this->parameters['contestants']) * $return['type']; + $return['title_sum'] = floatval($this->parameters['title_sum']); + $weights = array( + array(1, 2, 4, 5, 7, 10, 15, 25, self::RANK_KMP => 0), + array(2, 3, 5, 7, 10, 15, 25, 40, self::RANK_KMP => 0) + ); + $return['tournament_weight'] = (isset($this->parameters['manual']) && isset($this->parameters['manual']['tournament_weight'])) ? intval($this->parameters['manual']['tournament_weight']) : $weights[intval($this->parameters['over39_boards'])][intval($this->parameters['tournament_rank'])]; + $min_points = array( + array(0, 0, 0, 0, 50, 75, 150, 200, self::RANK_KMP => 0), + array(0, 0, 0, 0, 70, 100, 200, 300, self::RANK_KMP => 0) + ); + $return['min_points'] = (isset($this->parameters['manual']) && isset($this->parameters['manual']['min_points'])) ? intval($this->parameters['manual']['min_points']) : $min_points[intval($this->parameters['over39_boards'])][intval($this->parameters['tournament_rank'])]; + $return['players_coefficient'] = (isset($this->parameters['manual']) && isset($this->parameters['manual']['players_coefficient'])) ? floatval($this->parameters['manual']['players_coefficient']) : 0.05; + $return['points_cutoffs'] = (isset($this->parameters['manual']) && isset($this->parameters['manual']['points_cutoffs']) && is_array($this->parameters['manual']['points_cutoffs'])) ? $this->parameters['manual']['points_cutoffs'] : array( + array(0.0, 1.0), + array(0.02, 0.9), + array(0.2, 0.2), + array(0.5, 0.0) + ); + recursive_ksort($return['points_cutoffs']); + if ($return['points_cutoffs'][0][0] != 0.0) { + array_unshift($return['points_cutoffs'], array(0.0, 1.0)); + } + if ($return['points_cutoffs'][count($return['points_cutoffs'])-1][1] != 0.0) { + array_push($return['points_cutoffs'], array(1.0, 0.0)); + } + foreach ($return['points_cutoffs'] as &$cutoff) { + if (($cutoff[0] < 0.0) || ($cutoff[0] > 1.0)) { + throw new ParametersException('Cutoff points need to be between 0.0 and 1.0: ' . $cutoff[0]); + } + $cutoff[0] = floatval($cutoff[0]); + if (($cutoff[1] < 0.0) || ($cutoff[1] > 1.0)) { + throw new ParametersException('Cutoff values need to be between 1.0 and 0.0: ' . $cutoff[1]); + } + $cutoff[1] = floatval($cutoff[1]); + } + unset($cutoff); + for ($prev = 0; $prev < count($return['points_cutoffs']) - 1; $prev++) { + $next = $prev + 1; + if ($return['points_cutoffs'][$prev][0] >= $return['points_cutoffs'][$next][0]) { + throw new ParametersException( + 'Cutoff points need to be ascending: ' . $return['points_cutoffs'][$prev][0] . ', ' . $return['points_cutoffs'][$next][0]); + } + if ($return['points_cutoffs'][$prev][1] < $return['points_cutoffs'][$next][1]) { + throw new ParametersException( + 'Cutoff values need to be non-ascending: ' . $return['points_cutoffs'][$prev][1] . ', ' . $return['points_cutoffs'][$next][1]); + } + } + return $return; + } + + function get_position_percentage_from_position($position, $contestants) { + return ($position - 1) / $contestants; + } + + function get_percentage_from_position($position, $contestants, $cutoffs) { + $position_percentage = $this->get_position_percentage_from_position($position, $contestants); + for ($prev = 0; $prev < count($cutoffs) - 1; $prev++) { + $next = $prev + 1; + if (($cutoffs[$prev][0] <= $position_percentage) && ($cutoffs[$next][0] >= $position_percentage)) { + $result = ($position_percentage - $cutoffs[$prev][0]) * ($cutoffs[$prev][1] - $cutoffs[$next][1]) / ($cutoffs[$prev][0] - $cutoffs[$next][0]) + $cutoffs[$prev][1]; + return $result; + } + } + return 0.0; + } + + function calculate_points() { + $max_points = safe_ceil(max( + $this->parameters['min_points'], + (1 + 0.25 * ($this->parameters['type'] > 2)) * (max(0.15, $this->parameters['title_sum'] / $this->parameters['players']) * $this->parameters['tournament_weight'] + $this->parameters['players_coefficient'] * $this->parameters['contestants'] * $this->parameters['type']) + )); + $min_points = 1; + $result = array("sum" => 0, "points" => array()); + for ($place = 1; $place <= $this->parameters['contestants']; $place++) { + $percentage = $this->get_percentage_from_position($place, $this->parameters['contestants'], $this->parameters['points_cutoffs']); + $points = safe_ceil(floatval($max_points) * $percentage); + $result['points'][$place] = max($min_points, intval($points)); + $result['sum'] += $this->parameters['type'] * $result['points'][$place]; + } + return $result; + } + + function calculate_kmp_points() { + $max_points = safe_ceil($this->parameters['contestants'] * 0.5); + $min_points = 1; + $result = array("sum" => 0, "points" => array(1 => $max_points)); + for ($place = 2; $place <= $this->parameters['contestants']; $place++) { + $result['points'][$place] = max($min_points, $result['points'][$place-1]-1); + $result['sum'] += $this->parameters['type'] * $result['points'][$place]; + } + if ($this->parameters['title_sum'] / $this->parameters['players'] >= 2.5) { + $result['points'][1] += 5; + $result['points'][2] += 3; + $result['points'][3] += 1; + $result['sum'] += $this->parameters['type'] * 8; + } + return $result; + } +} + +?> diff --git a/http/api.php b/http/api.php index 3ab7f3d..b0140b9 100644 --- a/http/api.php +++ b/http/api.php @@ -28,204 +28,15 @@ Parametry: */ -if (!function_exists('http_response_code')) { - function http_response_code($code = NULL) { - $codes = array(400 => "Bad Request", - 500 => "Internal Server Error"); - if (!isset($codes[$code])) { - return; - } - $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'); - header($protocol . ' ' . $code . ' ' . $codes[$code]); - } -} - -class ParametersException extends Exception {}; - -function safe_ceil($value, $precision = 1e-6) { - $ceilValue = ceil($value); - return (abs($value - $ceilValue) < (1-$precision)) ? $ceilValue : round($value); -} - -function recursive_ksort(&$array, $flags = SORT_REGULAR) { - if (!is_array($array)) return false; - ksort($array, $flags); - foreach ($array as &$arr) { - recursive_ksort($arr, $flags); - } - return true; -} - -function ensure_parameters($parameters, $params) { - foreach ($params as $param) { - if (!isset($parameters[$param])) { - throw new ParametersException('Missing parameter: ' . $param); - } - if (!is_numeric($parameters[$param])) { - throw new ParametersException('Parameter: ' . $param . ' is not a numeric value (' . $parameters[$param] . ')'); - } - } -} - -function check_values($parameters, $params) { - foreach ($params as $param => $test) { - if (!$test($parameters[$param])) { - throw new ParametersException('Parameter: ' . $param . ' has incorrect value (' . $parameters[$param] . ')'); - } - } -} - -function check_parameters($parameters) { - ensure_parameters($parameters, array('type', 'contestants', 'title_sum')); - check_values($parameters, array( - 'type' => function($r) { return ctype_digit($r) && intval($r) > 0; }, - 'contestants' => function($r) { return ctype_digit($r) && intval($r) > 0; }, - 'title_sum' => function($r) { return floatval($r) >= 0; } - )); - if (isset($parameters['players'])) { - check_values($parameters, array( - 'players' => function($r) { return ctype_digit($r) && intval($r) > 0; } - )); - } - if (!isset($parameters['manual']) || !isset($parameters['manual']['min_points']) || !isset($parameters['manual']['tournament_weight'])) { - ensure_parameters($parameters, array('tournament_rank', 'over39_boards')); - check_values($parameters, array( - 'tournament_rank' => function($r) { return ctype_digit($r) && ((intval($r) >= 0 && intval($r) <= 7) || intval($r) == RANK_KMP); }, - 'over39_boards' => function($r) { return ctype_digit($r) && intval($r) >= 0 && intval($r) <= 1; } - )); - } else { - check_values($parameters['manual'], array( - 'min_points' => function($r) { return ctype_digit($r) && intval($r) >= 0; }, - 'tournament_weight' => function($r) { return ctype_digit($r) && intval($r) > 0; } - )); - } - if (isset($parameters['manual']) && isset($parameters['manual']['players_coefficient'])) { - check_values($parameters['manual'], array( - 'players_coefficient' => function($r) { return floatval($r) >= 0; } - )); - } -} - -const RANK_KMP = 101; - -function parse_parameters($parameters) { - $return = array(); - $return['type'] = intval($parameters['type']); - if ($return['type'] == 3 || $return['type'] > 4) { - throw new ParametersException('Parameter: type has incorrect value (' . $return['type'] . ')'); - } - if ($return['type'] != 2 && $parameters['tournament_rank'] == RANK_KMP) { - throw new ParametersException('Parameter: type has incorrect value (' . $return['type'] . ') for KMP tournament'); - } - $return['contestants'] = intval($parameters['contestants']); - $return['players'] = isset($parameters['players']) ? intval($parameters['players']) : intval($parameters['contestants']) * $return['type']; - $return['title_sum'] = floatval($parameters['title_sum']); - $weights = array( - array(1, 2, 4, 5, 7, 10, 15, 25, RANK_KMP => 0), - array(2, 3, 5, 7, 10, 15, 25, 40, RANK_KMP => 0) - ); - $return['tournament_weight'] = (isset($parameters['manual']) && isset($parameters['manual']['tournament_weight'])) ? intval($parameters['manual']['tournament_weight']) : $weights[intval($parameters['over39_boards'])][intval($parameters['tournament_rank'])]; - $min_points = array( - array(0, 0, 0, 0, 50, 75, 150, 200, RANK_KMP => 0), - array(0, 0, 0, 0, 70, 100, 200, 300, RANK_KMP => 0) - ); - $return['min_points'] = (isset($parameters['manual']) && isset($parameters['manual']['min_points'])) ? intval($parameters['manual']['min_points']) : $min_points[intval($parameters['over39_boards'])][intval($parameters['tournament_rank'])]; - $return['players_coefficient'] = (isset($parameters['manual']) && isset($parameters['manual']['players_coefficient'])) ? floatval($parameters['manual']['players_coefficient']) : 0.05; - $return['points_cutoffs'] = (isset($parameters['manual']) && isset($parameters['manual']['points_cutoffs']) && is_array($parameters['manual']['points_cutoffs'])) ? $parameters['manual']['points_cutoffs'] : array( - array(0.0, 1.0), - array(0.02, 0.9), - array(0.2, 0.2), - array(0.5, 0.0) - ); - recursive_ksort($return['points_cutoffs']); - if ($return['points_cutoffs'][0][0] != 0.0) { - array_unshift($return['points_cutoffs'], array(0.0, 1.0)); - } - if ($return['points_cutoffs'][count($return['points_cutoffs'])-1][1] != 0.0) { - array_push($return['points_cutoffs'], array(1.0, 0.0)); - } - foreach ($return['points_cutoffs'] as &$cutoff) { - if (($cutoff[0] < 0.0) || ($cutoff[0] > 1.0)) { - throw new ParametersException('Cutoff points need to be between 0.0 and 1.0: ' . $cutoff[0]); - } - $cutoff[0] = floatval($cutoff[0]); - if (($cutoff[1] < 0.0) || ($cutoff[1] > 1.0)) { - throw new ParametersException('Cutoff values need to be between 1.0 and 0.0: ' . $cutoff[1]); - } - $cutoff[1] = floatval($cutoff[1]); - } - unset($cutoff); - for ($prev = 0; $prev < count($return['points_cutoffs']) - 1; $prev++) { - $next = $prev + 1; - if ($return['points_cutoffs'][$prev][0] >= $return['points_cutoffs'][$next][0]) { - throw new ParametersException( - 'Cutoff points need to be ascending: ' . $return['points_cutoffs'][$prev][0] . ', ' . $return['points_cutoffs'][$next][0]); - } - if ($return['points_cutoffs'][$prev][1] < $return['points_cutoffs'][$next][1]) { - throw new ParametersException( - 'Cutoff values need to be non-ascending: ' . $return['points_cutoffs'][$prev][1] . ', ' . $return['points_cutoffs'][$next][1]); - } - } - return $return; -} - -function get_position_percentage_from_position($position, $contestants) { - return ($position - 1) / $contestants; -} - -function get_percentage_from_position($position, $contestants, $cutoffs) { - $position_percentage = get_position_percentage_from_position($position, $contestants); - for ($prev = 0; $prev < count($cutoffs) - 1; $prev++) { - $next = $prev + 1; - if (($cutoffs[$prev][0] <= $position_percentage) && ($cutoffs[$next][0] >= $position_percentage)) { - $result = ($position_percentage - $cutoffs[$prev][0]) * ($cutoffs[$prev][1] - $cutoffs[$next][1]) / ($cutoffs[$prev][0] - $cutoffs[$next][0]) + $cutoffs[$prev][1]; - return $result; - } - } - return 0.0; -} - -function calculate_points($parameters) { - $max_points = safe_ceil(max( - $parameters['min_points'], - (1 + 0.25 * ($parameters['type'] > 2)) * (max(0.15, $parameters['title_sum'] / $parameters['players']) * $parameters['tournament_weight'] + $parameters['players_coefficient'] * $parameters['contestants'] * $parameters['type']) - )); - $min_points = 1; - $result = array("sum" => 0, "points" => array()); - for ($place = 1; $place <= $parameters['contestants']; $place++) { - $percentage = get_percentage_from_position($place, $parameters['contestants'], $parameters['points_cutoffs']); - $points = safe_ceil(floatval($max_points) * $percentage); - $result['points'][$place] = max($min_points, intval($points)); - $result['sum'] += $parameters['type'] * $result['points'][$place]; - } - return $result; -} - -function calculate_kmp_points($parameters) { - $max_points = safe_ceil($parameters['contestants'] * 0.5); - $min_points = 1; - $result = array("sum" => 0, "points" => array(1 => $max_points)); - for ($place = 2; $place <= $parameters['contestants']; $place++) { - $result['points'][$place] = max($min_points, $result['points'][$place-1]-1); - $result['sum'] += $parameters['type'] * $result['points'][$place]; - } - if ($parameters['title_sum'] / $parameters['players'] >= 2.5) { - $result['points'][1] += 5; - $result['points'][2] += 3; - $result['points'][3] += 1; - $result['sum'] += $parameters['type'] * 8; - } - return $result; -} +require_once('api-inc.php'); function run($parameters) { try { - check_parameters($parameters); - $params = parse_parameters($parameters); - if ($parameters['tournament_rank'] == RANK_KMP) { - $result = calculate_kmp_points($params); + $api = new ApiPkl($parameters); + if ($parameters['tournament_rank'] == ApiPkl::RANK_KMP) { + $result = $api->calculate_kmp_points(); } else { - $result = calculate_points($params); + $result = $api->calculate_points(); } return $result; } -- cgit v1.2.3 From 27d32d8b5b5a6bab278bebaafdb2c07d38778701 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 10 Jan 2020 22:10:07 +0100 Subject: Selection of API class depending on privided version --- http/api-inc.php | 2 ++ http/api.php | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/http/api-inc.php b/http/api-inc.php index 40aa612..041c8ff 100644 --- a/http/api-inc.php +++ b/http/api-inc.php @@ -201,4 +201,6 @@ class ApiPkl { } } +class ApiPklV1 extends ApiPkl {} + ?> diff --git a/http/api.php b/http/api.php index b0140b9..ea633e3 100644 --- a/http/api.php +++ b/http/api.php @@ -31,8 +31,15 @@ Parametry: require_once('api-inc.php'); function run($parameters) { + try { - $api = new ApiPkl($parameters); + $versionClasses = array( + '1' => 'ApiPklV1', // RegKlas 2018.11.01 + '_default' => 'ApiPklV1' + ); + $version = isset($parameters['version']) ? $parameters['version'] : '_default'; + $apiClass = isset($versionClasses[$version]) ? $versionClasses[$version] : $versionClasses['_default']; + $api = new $apiClass($parameters); if ($parameters['tournament_rank'] == ApiPkl::RANK_KMP) { $result = $api->calculate_kmp_points(); } else { -- cgit v1.2.3 From fc6a2893e4e9d87d4752adba7675628a6152823a Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 10 Jan 2020 22:35:32 +0100 Subject: 2020.01.01 version (new KMP) --- http/api-inc.php | 14 ++++++++++++++ http/api.php | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/http/api-inc.php b/http/api-inc.php index 041c8ff..64612d9 100644 --- a/http/api-inc.php +++ b/http/api-inc.php @@ -203,4 +203,18 @@ class ApiPkl { class ApiPklV1 extends ApiPkl {} +class ApiPklV2 extends ApiPklV1 { + + function calculate_kmp_points() { + // the line below works only because you can't play > 39 boards in KMP + // please kill me if it ever changes + $this->parameters['tournament_weight'] = 4; + $this->parameters['min_points'] = 0; + $intermediate = $this->calculate_points(); + $this->parameters['min_points'] = $intermediate['points'][1] + 10; + return $this->calculate_points(); + } + +} + ?> diff --git a/http/api.php b/http/api.php index ea633e3..0458831 100644 --- a/http/api.php +++ b/http/api.php @@ -34,7 +34,8 @@ function run($parameters) { try { $versionClasses = array( - '1' => 'ApiPklV1', // RegKlas 2018.11.01 + '1' => 'ApiPklV1', // RegKlas 2018.11.01 + '2' => 'ApiPklV2', // RegKMP 2020.01.01 '_default' => 'ApiPklV1' ); $version = isset($parameters['version']) ? $parameters['version'] : '_default'; -- cgit v1.2.3 From 63fca7536a331b41d593c3ee7e40fa5999be94ed Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 10 Jan 2020 22:42:36 +0100 Subject: Legacy API call for 2018 calculator + new calculator with current API Fixes #3 --- http/api.php | 2 +- http/pkle.php | 2 +- http/pkle2018.php | 1 + http/pkle2020.php | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 301 insertions(+), 2 deletions(-) create mode 100644 http/pkle2020.php diff --git a/http/api.php b/http/api.php index 0458831..acf2752 100644 --- a/http/api.php +++ b/http/api.php @@ -36,7 +36,7 @@ function run($parameters) { $versionClasses = array( '1' => 'ApiPklV1', // RegKlas 2018.11.01 '2' => 'ApiPklV2', // RegKMP 2020.01.01 - '_default' => 'ApiPklV1' + '_default' => 'ApiPklV2' ); $version = isset($parameters['version']) ? $parameters['version'] : '_default'; $apiClass = isset($versionClasses[$version]) ? $versionClasses[$version] : $versionClasses['_default']; diff --git a/http/pkle.php b/http/pkle.php index 8159e28..0bc46be 100644 --- a/http/pkle.php +++ b/http/pkle.php @@ -1,3 +1,3 @@ + + + + + + Kargulator PKLi + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

KALKULATOR PKLI W TURNIEJACH PZBS
+ zgodny z nowym regulaminem (obowiązującym od 01.11.2018)
+ oraz nowym regulaminem KMP (obowiązującym od 01.01.2020)

+ Przejdź do kalkulatora zgodnego ze starym regulaminem KMP! +

+ Możesz eksperymentować ze wszystkimi (prawie) parametrami.
+ Dla przywrócenia stanu regulaminowego otwórz ponownie stronę.
 
turniej do 39 rozdańturniej od 40 rozdań
WAGA
turnieju
MINIMUM
za 1sze miejsce
WAGA
turnieju
MINIMUM
za 1sze miejsce
WSP:
+ OTP∗∗∗∗:
+ OTP∗∗∗:
+ OTP∗∗:
+ OTP:
+ OTP:
+ Regionalny:
+ Okręgowy:
+ Klubowy: + +
+
+
+
+
+
+
+
+ +
+ OTP∗∗∗∗:
+ OTP∗∗∗:
+ OTP∗∗:
+ OTP:
+ OTP:
+ Regionalny:
+ Okręgowy:
+ Klubowy: + +
+
+
+
+
+
+
+
+ +
PKL za 1 m = śr.WK×WAGA + il.zaw×WSP




%
%
 
%%%
 
TYP ZAWODÓW
+
+
+ +

LICZBA ROZDAŃ
+
+ +
RANGA ZAWODÓW
+
+
+
+
+
+
+
+
+ +
UCZESTNIKÓW
+
+ W zależności od typu
ilość indywidualistów,
par lub teamów
ZAWODNIKÓW
+
+ To pole jest wyliczane
automatycznie, ale możesz poprawić je
dla teamów nieczterosobowych.
SUMA WK
+
+ Suma WK wszystkich
zawodników.
Średnie WK zawodnika w turnieju:  +
+
 
+ +
+ +
+
+
+ + +
Miejsce   PKL   
SUMA PKL
+
+
+
+
Cierpliwości, liczę...
+ + -- cgit v1.2.3