From 0b296666f77d2431a26be5be4856499c5e0c2cd8 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 10 Jun 2012 03:24:22 +0200 Subject: [PATCH] Support translation of templates via po4a. Add an English translation as an example. --- include/common.pm | 26 ++- po/en.po | 313 +++++++++++++++++++++++++++ po/wloh.pot | 318 ++++++++++++++++++++++++++++ po4a.config | 5 + templates/index.en.xml | 117 ++++++++++ templates/rating.en.xml | 85 ++++++++ templates/scenario-not-found.en.xml | 13 ++ templates/scenario.en.xml | 16 ++ www/index.pl | 18 +- www/rating.pl | 4 +- 10 files changed, 902 insertions(+), 13 deletions(-) create mode 100644 po/en.po create mode 100644 po/wloh.pot create mode 100644 po4a.config create mode 100644 templates/index.en.xml create mode 100644 templates/rating.en.xml create mode 100644 templates/scenario-not-found.en.xml create mode 100644 templates/scenario.en.xml diff --git a/include/common.pm b/include/common.pm index 6ad6ae4..7ffaeee 100644 --- a/include/common.pm +++ b/include/common.pm @@ -35,6 +35,12 @@ sub get_locale { return $1; } +sub set_locale { + my $locale = shift; + $locale =~ s/-/_/; + POSIX::setlocale(&POSIX::LC_ALL, $locale . '.UTF-8'); +} + sub get_auxillary_parameters { my ($dbh, $locale) = @_; @@ -106,10 +112,26 @@ sub print_navbar { print "

\n"; } +# mapping from locale to translation to use (if not found, "en" is used) +my %translation_mapping = ( + 'nb-NO' => 'no', + 'nn-NO' => 'no', + 'da-DK' => 'no', + 'sv-SE' => 'no', + 'nl-NL' => 'en', +); + sub process_template { - my ($filename, $parms) = @_; + my ($filename, $locale, $parms) = @_; - my $doc = XML::Template::process_file('../templates/' . $filename, $parms); + my $translation = $translation_mapping{$locale} // 'en'; + my $doc; + if (-r "../templates/$filename.$translation.xml") { + $parms->{'html/xml:lang'} = $translation; + $doc = XML::Template::process_file("../templates/$filename.$translation.xml", $parms); + } else { + $doc = XML::Template::process_file("../templates/$filename.xml", $parms); + } print $doc->toString; } diff --git a/po/en.po b/po/en.po new file mode 100644 index 0000000..2c84281 --- /dev/null +++ b/po/en.po @@ -0,0 +1,313 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2012-06-10 03:20+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Content of: +#: templates/index.xml:7 templates/index.xml:31 templates/scenario.xml:7 +#: templates/scenario-not-found.xml:7 +#, no-wrap +msgid "WLoH-plasseringsannsynlighetsberegning" +msgstr "WLoH ranking probability calculation" + +#. type: Content of: <html><body><p><t:languages><t:separator> +#: templates/index.xml:25 templates/rating.xml:13 +#, no-wrap +msgid "::" +msgstr "::" + +#. type: Content of: <html><body><p><em> +#: templates/index.xml:33 templates/rating.xml:21 +#, no-wrap +msgid "" +"Dette er et hobbyprosjekt fra tredjepart, og ikke en offisiell del av\n" +" " +msgstr "This is a hobby project from a third party, and not an official part of " + +#. type: Content of: <html><body><p><em><a> +#: templates/index.xml:34 templates/rating.xml:22 +#, no-wrap +msgid "Wordfeud League of Honour" +msgstr "Wordfeud League of Honour" + +#. type: Content of: <html><body><p> +#: templates/index.xml:34 templates/index.xml:79 templates/index.xml:121 +#: templates/index.xml:122 templates/rating.xml:22 templates/rating.xml:28 +#: templates/rating.xml:41 templates/rating.xml:95 +#, no-wrap +msgid "." +msgstr "." + +#. type: Content of: <html><body><p> +#: templates/index.xml:36 +#, no-wrap +msgid "" +"Beregningen tar ikke hensyn til ujevn spillestyrke, ting som er sagt i forumet e.l.;\n" +" den antar at samtlige uspilte kamper trekkes fra en normalfordeling med standardavvik\n" +" " +msgstr "The calculation does not take into account uneven playing strength, information from the forum etc.; it assumes that any unplayed games are drawn from a Gaussian distribution with standard deviation " + +#. type: Content of: <html><body><p> +#: templates/index.xml:38 +#, no-wrap +msgid "" +" poeng. Sannsynlighetene kan summere til andre tall enn 100% pga. avrunding.\n" +" Tallene vil variere litt fra gang til gang fordi utregningen skjer ved randomisering.\n" +" For scenarioeksempel, klikk i en rute." +msgstr " points. The probabilities might not sum to 100%, due to roundoff errors. The numbers will vary a bit between runs, since the calculation is stochastic. For scenario example, click in a cell." + +#. type: Content of: <html><body><p> +#: templates/index.xml:42 +#, no-wrap +msgid "Spillerne er sortert etter nick." +msgstr "The players are sorted by nickname." + +#. type: Content of: <html><body><form><p> +#: templates/index.xml:45 +#, no-wrap +msgid "" +"Divisjon:\n" +" " +msgstr "Division:" + +#. type: Content of: <html><body><form><p> +#: templates/index.xml:49 +#, no-wrap +msgid "" +" Avdeling:\n" +" " +msgstr "Subdivision:" + +#. type: Content of: <html><body><p> +#: templates/index.xml:78 +#, no-wrap +msgid "" +"Under er en variant som tar relativ spillestyrke med i beregningen;\n" +" se " +msgstr "Below is a variant that takes relative playing strength into account; see " + +#. type: Content of: <html><body><p><a> +#: templates/index.xml:79 +#, no-wrap +msgid "ratingsiden" +msgstr "the ratings page" + +#. type: Content of: <html><body><t:cov-table><p> +#: templates/index.xml:103 +#, no-wrap +msgid "Kovarianstabell:" +msgstr "Covariance matrix:" + +#. type: Content of: <html><body><p> +#: templates/index.xml:121 +#, no-wrap +msgid "Gjennomsnittlig rating i denne avdelingen er " +msgstr "Average rating in this subdivision is " + +#. type: Content of: <html><body><p> +#: templates/index.xml:122 templates/rating.xml:95 +#, no-wrap +msgid "Databasen ble sist synkronisert " +msgstr "The database was last synchronized " + +#. type: Content of: <html><body><h1> +#: templates/rating.xml:7 templates/rating.xml:19 +#, no-wrap +msgid "WLoH-rating" +msgstr "WLoH rating" + +#. type: Content of: <html><body><p> +#: templates/rating.xml:24 +#, no-wrap +msgid "" +"Ratingen er dog basert på spilledata fra WLoH (takk til Lobotommy\n" +" for tilgang!), og oppdateres\n" +" hver hele time. Den er fullstendig uoffisiell, og har ingen innflytelse\n" +" på WLoH, men brukes for å estimere vinnersannsynligheter i\n" +" " +msgstr "Even so, the rating is based on play data from WLoH (thanks to Lobotommy for access!), and is updated every hour. It is completely unofficial and has no bearing on WLoH, but is used to estimate win probabilities in " + +#. type: Content of: <html><body><p><a> +#: templates/rating.xml:28 +#, no-wrap +msgid "sannsynlighetsberegningen" +msgstr "the probability calculation" + +#. type: Content of: <html><body><p> +#: templates/rating.xml:30 +#, no-wrap +msgid "" +"Modellen kan endre seg når som helst når jeg føler for det :-)\n" +" Ikke ta ratingen alt for alvorlig, selv om den er basert på\n" +" relativt fornuftige matematiske modeller. Husk at all statistikk\n" +" sier mer om fortiden enn om framtiden." +msgstr "The model can change at any time I feel like it :-) Do not take the rating too seriously, even though it is based on relatively reasonable mathematical models. Remember that all statistics say more about the past than about the future." + +#. type: Content of: <html><body><h2> +#: templates/rating.xml:35 +#, no-wrap +msgid "Modellparametre" +msgstr "Model parameters" + +#. type: Content of: <html><body><p> +#: templates/rating.xml:37 +#, no-wrap +msgid "" +"For de som vet litt om slikt. Det finnes også en lengre, mer detaljert\n" +" " +msgstr "For those so inclined. There is also a longer, more detailed " + +#. type: Content of: <html><body><p><a> +#: templates/rating.xml:38 +#, no-wrap +msgid "forklaring" +msgstr "explanation" + +#. type: Content of: <html><body><p> +#: templates/rating.xml:38 +#, no-wrap +msgid " beregnet på ikke-matematikere." +msgstr " intended for non-mathematicians." + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:41 +#, no-wrap +msgid "MLE-basert modell med én skalar (styrke) per spiller og to globale skalarer (begge standardavvik, se under), løst med syklisk MM (minorization-maximization). Antall iterasjoner før konvergens: " +msgstr "MLE-based model with one scalar (strength) per player and to global scalars (both standard deviations; see below), solved using cyclic MM (minorization-maximization). Number of iterations to convergence: " + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:42 +#, no-wrap +msgid "Rimelighetfunksjon, prior: Normalfordeling med µ=500, σ=" +msgstr "Likelihood function, prior: Gaussian distribution with µ=500, σ=" + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:42 templates/rating.xml:43 +#, no-wrap +msgid " (est.)" +msgstr " (est.)" + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:43 +#, no-wrap +msgid "Rimelighetfunksjon, per kamp: Normalfordeling med µ=(score1 - score2), σ=" +msgstr "Likelihood function, for each match: Gaussian distribution with µ=(score1 - score2), σ=" + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:44 +#, no-wrap +msgid "" +"Vekting: Inneværende sesong samt de tre siste vektes fullt ut\n" +"\t(likt med prior). Deretter eksponentielt synkende vekting, med\n" +" halveringstid på tre sesonger. Spill som er registrert med\n" +" 0-0, 150-0, 0-150 eller 150-150 ignoreres." +msgstr "Weight: Current and previous three seasons are given full weight (equal to the prior). Older seasons are weighted exponentially less, with half-life of three seasons. Matches stored as 0-0, 150-0, 0-150 eller 150-150 are ignored." + +#. type: Content of: <html><body><h2> +#: templates/rating.xml:50 +#, no-wrap +msgid "Divisjonsoversikt" +msgstr "List of divisions" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:55 +#, no-wrap +msgid "Div." +msgstr "Div." + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:56 +#, no-wrap +msgid "Snitt" +msgstr "Average" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:57 templates/rating.xml:80 +#, no-wrap +msgid "Std.avvik" +msgstr "Std.dev" + +#. type: Content of: <html><body><h2> +#: templates/rating.xml:72 +#, no-wrap +msgid "Rankingliste" +msgstr "Ranking list" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:78 +#, no-wrap +msgid "Nick" +msgstr "Nickname" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:79 +#, no-wrap +msgid "Rating" +msgstr "Rating" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:81 +#, no-wrap +msgid "Sist sett" +msgstr "Last seen" + +#. type: Content of: <html><body><p> +#: templates/scenario.xml:11 +#, no-wrap +msgid "Scenario der " +msgstr "Scenario where " + +#. type: Content of: <html><body><p> +#: templates/scenario.xml:11 +#, no-wrap +msgid " ender på " +msgstr " ends in " + +#. type: Content of: <html><body><p> +#: templates/scenario.xml:11 +#, no-wrap +msgid " plass:" +msgstr " place:" + +#. type: Content of: <html><body><ul><li> +#: templates/scenario.xml:13 +#, no-wrap +msgid " – " +msgstr " – " + +#. type: Content of: <html><body><ul><li> +#: templates/scenario.xml:13 +#, no-wrap +msgid ": " +msgstr ": " + +#. type: Content of: <html><body><p> +#: templates/scenario-not-found.xml:11 +#, no-wrap +msgid "Fant ingen måte " +msgstr "Couldn't find a situation where " + +#. type: Content of: <html><body><p> +#: templates/scenario-not-found.xml:11 +#, no-wrap +msgid " kan ende på " +msgstr " ends up in " + +#. type: Content of: <html><body><p> +#: templates/scenario-not-found.xml:11 +#, no-wrap +msgid " plass på." +msgstr " place." diff --git a/po/wloh.pot b/po/wloh.pot new file mode 100644 index 0000000..a386454 --- /dev/null +++ b/po/wloh.pot @@ -0,0 +1,318 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2012-06-10 03:20+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: Content of: <html><head><title> +#: templates/index.xml:7 templates/index.xml:31 templates/scenario.xml:7 templates/scenario-not-found.xml:7 +#, no-wrap +msgid "WLoH-plasseringsannsynlighetsberegning" +msgstr "" + +#. type: Content of: <html><body><p><t:languages><t:separator> +#: templates/index.xml:25 templates/rating.xml:13 +#, no-wrap +msgid "::" +msgstr "" + +#. type: Content of: <html><body><p><em> +#: templates/index.xml:33 templates/rating.xml:21 +#, no-wrap +msgid "" +"Dette er et hobbyprosjekt fra tredjepart, og ikke en offisiell del av\n" +" " +msgstr "" + +#. type: Content of: <html><body><p><em><a> +#: templates/index.xml:34 templates/rating.xml:22 +#, no-wrap +msgid "Wordfeud League of Honour" +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/index.xml:34 templates/index.xml:79 templates/index.xml:121 templates/index.xml:122 templates/rating.xml:22 templates/rating.xml:28 templates/rating.xml:41 templates/rating.xml:95 +#, no-wrap +msgid "." +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/index.xml:36 +#, no-wrap +msgid "" +"Beregningen tar ikke hensyn til ujevn spillestyrke, ting som er sagt i " +"forumet e.l.;\n" +" den antar at samtlige uspilte kamper trekkes fra en normalfordeling " +"med standardavvik\n" +" " +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/index.xml:38 +#, no-wrap +msgid "" +" poeng. Sannsynlighetene kan summere til andre tall enn 100% " +"pga. avrunding.\n" +" Tallene vil variere litt fra gang til gang fordi utregningen skjer ved " +"randomisering.\n" +" For scenarioeksempel, klikk i en rute." +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/index.xml:42 +#, no-wrap +msgid "Spillerne er sortert etter nick." +msgstr "" + +#. type: Content of: <html><body><form><p> +#: templates/index.xml:45 +#, no-wrap +msgid "" +"Divisjon:\n" +" " +msgstr "" + +#. type: Content of: <html><body><form><p> +#: templates/index.xml:49 +#, no-wrap +msgid "" +" Avdeling:\n" +" " +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/index.xml:78 +#, no-wrap +msgid "" +"Under er en variant som tar relativ spillestyrke med i beregningen;\n" +" se " +msgstr "" + +#. type: Content of: <html><body><p><a> +#: templates/index.xml:79 +#, no-wrap +msgid "ratingsiden" +msgstr "" + +#. type: Content of: <html><body><t:cov-table><p> +#: templates/index.xml:103 +#, no-wrap +msgid "Kovarianstabell:" +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/index.xml:121 +#, no-wrap +msgid "Gjennomsnittlig rating i denne avdelingen er " +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/index.xml:122 templates/rating.xml:95 +#, no-wrap +msgid "Databasen ble sist synkronisert " +msgstr "" + +#. type: Content of: <html><body><h1> +#: templates/rating.xml:7 templates/rating.xml:19 +#, no-wrap +msgid "WLoH-rating" +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/rating.xml:24 +#, no-wrap +msgid "" +"Ratingen er dog basert på spilledata fra WLoH (takk til Lobotommy\n" +" for tilgang!), og oppdateres\n" +" hver hele time. Den er fullstendig uoffisiell, og har ingen " +"innflytelse\n" +" på WLoH, men brukes for å estimere vinnersannsynligheter i\n" +" " +msgstr "" + +#. type: Content of: <html><body><p><a> +#: templates/rating.xml:28 +#, no-wrap +msgid "sannsynlighetsberegningen" +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/rating.xml:30 +#, no-wrap +msgid "" +"Modellen kan endre seg når som helst når jeg føler for det :-)\n" +" Ikke ta ratingen alt for alvorlig, selv om den er basert på\n" +" relativt fornuftige matematiske modeller. Husk at all statistikk\n" +" sier mer om fortiden enn om framtiden." +msgstr "" + +#. type: Content of: <html><body><h2> +#: templates/rating.xml:35 +#, no-wrap +msgid "Modellparametre" +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/rating.xml:37 +#, no-wrap +msgid "" +"For de som vet litt om slikt. Det finnes også en lengre, mer detaljert\n" +" " +msgstr "" + +#. type: Content of: <html><body><p><a> +#: templates/rating.xml:38 +#, no-wrap +msgid "forklaring" +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/rating.xml:38 +#, no-wrap +msgid " beregnet på ikke-matematikere." +msgstr "" + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:41 +#, no-wrap +msgid "" +"MLE-basert modell med én skalar (styrke) per spiller og to globale skalarer " +"(begge standardavvik, se under), løst med syklisk MM " +"(minorization-maximization). Antall iterasjoner før konvergens: " +msgstr "" + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:42 +#, no-wrap +msgid "Rimelighetfunksjon, prior: Normalfordeling med µ=500, σ=" +msgstr "" + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:42 templates/rating.xml:43 +#, no-wrap +msgid " (est.)" +msgstr "" + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:43 +#, no-wrap +msgid "Rimelighetfunksjon, per kamp: Normalfordeling med µ=(score1 - score2), σ=" +msgstr "" + +#. type: Content of: <html><body><ul><li> +#: templates/rating.xml:44 +#, no-wrap +msgid "" +"Vekting: Inneværende sesong samt de tre siste vektes fullt ut\n" +"\t(likt med prior). Deretter eksponentielt synkende vekting, med\n" +" halveringstid på tre sesonger. Spill som er registrert med\n" +" 0-0, 150-0, 0-150 eller 150-150 ignoreres." +msgstr "" + +#. type: Content of: <html><body><h2> +#: templates/rating.xml:50 +#, no-wrap +msgid "Divisjonsoversikt" +msgstr "" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:55 +#, no-wrap +msgid "Div." +msgstr "" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:56 +#, no-wrap +msgid "Snitt" +msgstr "" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:57 templates/rating.xml:80 +#, no-wrap +msgid "Std.avvik" +msgstr "" + +#. type: Content of: <html><body><h2> +#: templates/rating.xml:72 +#, no-wrap +msgid "Rankingliste" +msgstr "" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:78 +#, no-wrap +msgid "Nick" +msgstr "" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:79 +#, no-wrap +msgid "Rating" +msgstr "" + +#. type: Content of: <html><body><table><thead><tr><th> +#: templates/rating.xml:81 +#, no-wrap +msgid "Sist sett" +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/scenario.xml:11 +#, no-wrap +msgid "Scenario der " +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/scenario.xml:11 +#, no-wrap +msgid " ender på " +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/scenario.xml:11 +#, no-wrap +msgid " plass:" +msgstr "" + +#. type: Content of: <html><body><ul><li> +#: templates/scenario.xml:13 +#, no-wrap +msgid " – " +msgstr "" + +#. type: Content of: <html><body><ul><li> +#: templates/scenario.xml:13 +#, no-wrap +msgid ": " +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/scenario-not-found.xml:11 +#, no-wrap +msgid "Fant ingen måte " +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/scenario-not-found.xml:11 +#, no-wrap +msgid " kan ende på " +msgstr "" + +#. type: Content of: <html><body><p> +#: templates/scenario-not-found.xml:11 +#, no-wrap +msgid " plass på." +msgstr "" diff --git a/po4a.config b/po4a.config new file mode 100644 index 0000000..65fa2c5 --- /dev/null +++ b/po4a.config @@ -0,0 +1,5 @@ +[po_directory] po/ +[type:xml] templates/index.xml en:templates/index.en.xml +[type:xml] templates/rating.xml en:templates/rating.en.xml +[type:xml] templates/scenario.xml en:templates/scenario.en.xml +[type:xml] templates/scenario-not-found.xml en:templates/scenario-not-found.en.xml diff --git a/templates/index.en.xml b/templates/index.en.xml new file mode 100644 index 0000000..90e9354 --- /dev/null +++ b/templates/index.en.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE + html PUBLIC "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="no" xmlns:t="http://template.sesse.net/"> + <head> + <title>WLoH ranking probability calculation + + + + +

+ + :: + + + +

+ +

WLoH ranking probability calculation

+ +

This is a hobby project from a third party, and not an official part of Wordfeud League of Honour.

+ +

The calculation does not take into account uneven playing strength, information from the forum etc.; it assumes that any unplayed games are drawn from a Gaussian distribution with standard deviation points. The probabilities might not sum to 100%, due to roundoff errors. The numbers will vary a bit between runs, since the calculation is stochastic. For scenario example, click in a cell.

+ +

The players are sorted by nickname.

+ +
+

Division: +Subdivision: + +

+
+ + + + + + + + + + + + + + + + +
+ +
+ +

+ +

Below is a variant that takes relative playing strength into account; see the ratings page.

+ + + + + + + + + + + + + + + + +
+ +
+ +

+ + +

Covariance matrix:

+ + + + + + + + + + +
+ +
+ +
+
+ +

Average rating in this subdivision is .

+

The database was last synchronized .

+ + diff --git a/templates/rating.en.xml b/templates/rating.en.xml new file mode 100644 index 0000000..e570bea --- /dev/null +++ b/templates/rating.en.xml @@ -0,0 +1,85 @@ + + + + + WLoH rating + + + +

+ + :: + + + +

+ +

WLoH rating

+ +

This is a hobby project from a third party, and not an official part of Wordfeud League of Honour.

+ +

Even so, the rating is based on play data from WLoH (thanks to Lobotommy for access!), and is updated every hour. It is completely unofficial and has no bearing on WLoH, but is used to estimate win probabilities in the probability calculation.

+ +

The model can change at any time I feel like it :-) Do not take the rating too seriously, even though it is based on relatively reasonable mathematical models. Remember that all statistics say more about the past than about the future.

+ +

Model parameters

+ +

For those so inclined. There is also a longer, more detailed explanation intended for non-mathematicians.

+ +
    +
  • MLE-based model with one scalar (strength) per player and to global scalars (both standard deviations; see below), solved using cyclic MM (minorization-maximization). Number of iterations to convergence: .
  • +
  • Likelihood function, prior: Gaussian distribution with µ=500, σ= (est.)
  • +
  • Likelihood function, for each match: Gaussian distribution with µ=(score1 - score2), σ= (est.)
  • +
  • Weight: Current and previous three seasons are given full weight (equal to the prior). Older seasons are weighted exponentially less, with half-life of three seasons. Matches stored as 0-0, 150-0, 0-150 eller 150-150 are ignored.
  • +
+ +

List of divisions

+ + + + + + + + + + + + + + + +
Div.AverageStd.dev
+ + + +
+ +

Ranking list

+ + + + + + + + + + + + + + + + + +
NicknameRatingStd.devLast seen
+ + +
+ +

The database was last synchronized .

+ + diff --git a/templates/scenario-not-found.en.xml b/templates/scenario-not-found.en.xml new file mode 100644 index 0000000..7c52aa0 --- /dev/null +++ b/templates/scenario-not-found.en.xml @@ -0,0 +1,13 @@ + + + + + WLoH ranking probability calculation + + + +

Couldn't find a situation where ends up in place.

+ + diff --git a/templates/scenario.en.xml b/templates/scenario.en.xml new file mode 100644 index 0000000..27aed09 --- /dev/null +++ b/templates/scenario.en.xml @@ -0,0 +1,16 @@ + + + + + WLoH ranking probability calculation + + + +

Scenario where ends in place:

+
    +
  • – :
  • +
+ + diff --git a/www/index.pl b/www/index.pl index 2b7dcaf..4fef4a7 100755 --- a/www/index.pl +++ b/www/index.pl @@ -138,9 +138,9 @@ sub get_covariance_matrix { } sub write_parms_to_file { - my ($aux_parms, $match_stddev, $used_ratings, $used_cov) = @_; + my ($locale, $aux_parms, $match_stddev, $used_ratings, $used_cov) = @_; - POSIX::setlocale(&POSIX::LC_ALL, 'nb_NO.UTF-8'); + wloh_common::set_locale($locale); my @sorted_players = sort { $players{$a} cmp $players{$b} } keys %players; @@ -175,7 +175,7 @@ sub write_parms_to_file { } close MCCALC; - POSIX::setlocale(&POSIX::LC_ALL, 'nb_NO.UTF-8'); + wloh_common::set_locale($locale); return $tmpnam; } @@ -183,7 +183,7 @@ sub write_parms_to_file { sub make_table { my ($locale, $aux_parms, $match_stddev, $lowest_division, $used_ratings, $used_cov, $division, $subdivision, $table_id) = @_; - my $tmpnam = write_parms_to_file($aux_parms, $match_stddev, $used_ratings, $used_cov); + my $tmpnam = write_parms_to_file($locale, $aux_parms, $match_stddev, $used_ratings, $used_cov); my %prob = (); open MCCALC, "$config::base_dir/mcwordfeud $trials < $tmpnam |" @@ -352,7 +352,7 @@ get_players_and_ratings($dbh, $locale, $season, $division, $subdivision); my $cov = get_covariance_matrix($dbh, keys %players); if (defined($match_player) && defined($match_position)) { - my $tmpnam = write_parms_to_file($aux_parms, $match_stddev, \%ratings, $cov); + my $tmpnam = write_parms_to_file($locale, $aux_parms, $match_stddev, \%ratings, $cov); --$match_player; --$match_position; @@ -377,20 +377,20 @@ if (defined($match_player) && defined($match_position)) { if (scalar @scenario == 0) { print CGI->header(-type=>'text/html; charset=utf-8', -expires=>'+5m'); - wloh_common::process_template('scenario-not-found.xml', { + wloh_common::process_template('scenario-not-found', $locale, { '#nick' => $player_name, '#rank' => sprintf("%d.", $match_position + 1) }); } else { print CGI->header(-type=>'text/html; charset=utf-8', -expires=>'+5m'); - wloh_common::process_template('scenario.xml', { + wloh_common::process_template('scenario', $locale, { '#nick' => $player_name, '#rank' => sprintf("%d.", $match_position + 1), '#results' => \@scenario }); } } else { - POSIX::setlocale(&POSIX::LC_ALL, 'nb_NO.UTF-8'); + wloh_common::set_locale($locale); my $max_division = $divisions[$#divisions]; my $lowest_division = ($division == $max_division); @@ -401,7 +401,7 @@ if (defined($match_player) && defined($match_position)) { my $avg_rating = find_avg_rating(\%ratings); print CGI->header(-type=>'text/html; charset=utf-8', -expires=>'+5m'); - wloh_common::process_template('index.xml', { + wloh_common::process_template('index', $locale, { '#navbar' => wloh_common::get_navbar($cgi, $dbh, $locale), '#division-selector/action' => "/$locale/", '#division' => get_division_selector(\@divisions, $division), diff --git a/www/rating.pl b/www/rating.pl index c69d5a7..dca62d8 100755 --- a/www/rating.pl +++ b/www/rating.pl @@ -26,7 +26,7 @@ my $locale = wloh_common::get_locale($cgi); my $aux_parms = wloh_common::get_auxillary_parameters($dbh, $locale); -POSIX::setlocale(&POSIX::LC_ALL, 'nb_NO.UTF-8'); +wloh_common::set_locale($locale); my $season = wloh_common::get_max_season($dbh, $locale); @@ -98,7 +98,7 @@ while (my $ref = $q->fetchrow_hashref) { } print CGI->header(-type=>'text/html; charset=utf-8', -expires=>'+5m'); -wloh_common::process_template('rating.xml', { +wloh_common::process_template('rating', $locale, { '#navbar' => wloh_common::get_navbar($cgi, $dbh, $locale), 'iterations' => $aux_parms->{'num_iterations'}, 'rating-prior-stddev' => sprintf("%.1f", $aux_parms->{'rating_prior_stddev'}), -- 2.39.2