Beispiel #1
0
        private int LaskeSuoritusluku(Ottelulista ottelut)
        {
            if (ottelut == null)
            {
                throw new ArgumentNullException(nameof(ottelut));
            }

            double low  = MinRating;
            double high = MaxRating;

            double guess, we;
            int    i;
            int    elo;

            int scorex100 = (int)Math.Round(100F * (TurnauksenTulos2x / 2F));

            if (scorex100 < 50)
            {
                return(-9999);
            }
            if (100 * VastustajienLkm - scorex100 < 1)
            {
                return(9999);
            }

            while (high - low > Epsilon)
            {
                we = 0.0; guess = (low + high) / 2.0;
                for (i = 0; i < VastustajienLkm; i++)
                {
                    elo = (i == 0) ? ottelut.HaeEnsimmainen().Item1 : ottelut.HaeSeuraava().Item1;
                    we += 0.5 * (1 + Erf((guess - elo) / 400F));
                }
                if (100 * we < scorex100)
                {
                    low = guess;
                }
                else
                {
                    high = guess;
                }
            }
            return((int)Math.Round(high + 0.000001));
        }
Beispiel #2
0
        // XXX: REFACTOR TarkistaVastustajanSelo()

        // ************ TARKISTA VASTUSTAJAN SELO-KENTTÄ ************
        //
        // Ottelut (selot ja tulokset) tallennetaan listaan
        //
        // Syöte voi olla annettu kolmella eri formaatilla:
        //  1)  1720   -> ja sitten tulos valintanapeilla
        //  2)  2,5 1624 1700 1685 1400    Eli aloitetaan kokonaispistemäärällä.
        //                                 SELOt ilman erillisiä tuloksia.
        //  3)  +1624 -1700 =1685 +1400    jossa  '+' voitto, '=' tasapeli ja '-' tappio.
        //                                 Tasapeli voidaan myös antaa ilman '='-merkkiä.
        //
        // Yhden ottelun tulos voidaan antaa kolmella tavalla:
        //   1)  1720      ja tulos erikseen valintanapeilla, esim. 1=voitto, 1/2=tasapeli tai 0=tappio
        //   2)  -1720  (tappio), =1720    (tasapeli) tai +1720  (voitto)
        //   3)  0 1720 (tappio), 0.5 1720 (tasapeli) tai 1 1720 (voitto)
        //
        // Kahden tai useamman ottelun tulos voidaan syöttää kahdella eri tavalla
        //   1) 2,5 1624 1700 1685 1400
        //   2) +1624 -1700 =1685 +1400  (Huom! myös -1624 +1700 +1685 1400 laskee saman vahvuusluvun)
        // HUOM! Jos tuloksessa on desimaalit väärin, esim. 2.37 tai 0,9,
        //       niin ylimääräiset desimaalit "pyöristyvät" alas -> 2,0 tai 0,5.
        //
        // Paluuarvo joko kelvollinen seloluku (vain yksi vastustaja annettu), nolla (jos ottelut ovat listassa) tai virhestatus.
        //
        // Jos syote sisältää '/' -merkin, on laskettava sitä edeltävät tulokset uuden pelaajan kaavalla
        // ja sen jälkeen normaalilla laskentakaavalla
        private int TarkistaVastustajanSelo(Ottelulista ottelut, string syote)
        {
            int vastustajanSelo = 0;   // palautettava vastustajan selo tai nolla tai virhestatus
            int virhekoodi      = 0;

            bool  onko_turnauksen_tulos = false; // oliko tulos ensimmäisenä?
            float syotetty_tulos        = 0F;    // tähän sitten sen tulos desimaalilukuna (esim. 2,5)

            // kentässä voidaan antaa alussa turnauksen tulos, esim. 0.5, 2.0, 2.5, 7.5 eli saadut pisteet
            selopelaaja.SetAnnettuTurnauksenTulos(Vakiot.TURNAUKSEN_TULOS_ANTAMATTA);  // oletus: ei annettu turnauksen tulosta

            // Ensin helpot tarkistukset:
            // 1) Kenttä ei saa olla tyhjä
            if (string.IsNullOrWhiteSpace(syote))
            {
                virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;
            }
            else if (syote.Length == Vakiot.SELO_PITUUS)
            {
                if (int.TryParse(syote, out vastustajanSelo) == false)
                {
                    // 2) Jos on annettu neljä merkkiä (esim. 1728), niin sen on oltava numero
                    virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;
                }
                else if (vastustajanSelo < Vakiot.MIN_SELO || vastustajanSelo > Vakiot.MAX_SELO)
                {
                    // 3) Numeron on oltava sallitulla lukualueella
                    //    Mutta jos oli OK, niin vastustajanSelo sisältää nyt sallitun vahvuusluvun eikä tulla tähän
                    virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;
                }
                // Jos OK, yhden ottelun tulosta ei kuitenkaan vielä tallenneta listaan
                // vaan nyt palataan tästä funktiosta ja seuraavaksi selvitetään ottelun tulos
            }
            else
            {
                // Jäljellä vielä hankalammat tapaukset:
                // 4) turnauksen tulos+vahvuusluvut, esim. 2,5 1624 1700 1685 1400
                // 5) vahvuusluvut, joissa kussakin tulos  +1624 -1700 =1685 +1400
                // 6) vahvuusluvut tuloksineen ja välissä '/'-merkki +1624 -1700 / =1685 +1400
                //
                // TULOSSA:
                // 7) turnauksen_tulos turnauksen_ottelumäärä vastustajien_selokeskiarvo, esim. 12.5 18 1885.2

                // Apumuuttujat
                bool status = true;
                int  selo1;               // = Vakiot.MIN_SELO;
                bool ensimmainen = true;  // ensimmäinen syötekentän numero tai merkkijono
                bool toinen      = false; // toinen syötekenttä

                List <string> SyotteenOsat = syote.Split(' ').ToList();

                // Tutki vastustajanSelo_comboBox-kenttä välilyönnein erotettu merkkijono kerrallaan
                foreach (string vastustaja in SyotteenOsat)
                {
                    if (ensimmainen)
                    {
                        // need to use temporary variable because can't modify foreach iteration variable
                        string tempString = vastustaja;

                        // 4) Onko annettu kokonaispistemäärä? (eli useamman ottelun yhteistulos)
                        ensimmainen = false;
                        toinen      = true;

                        // Laita molemmat 1.5 ja 1,5 toimimaan, InvariantCulture
                        // Huom! Pilkkua ei voidakaan käyttää, jos halutaan
                        // että CSV-formaatti toimii - pilkulla erotetut arvot
                        if (tempString.Contains(','))  // korvaa pilkku pisteellä...
                        {
                            tempString = tempString.Replace(',', '.');
                        }

                        // Jos ottelutulon lopussa on puolikas, niin muuta se ".5":ksi, esim. 10½ -> 10.5
                        // Jos ottelutulos on ½, niin tässä se muutetaan "0.5":ksi
                        if (tempString.IndexOf('½') == tempString.Length - 1)
                        {
                            if (tempString.Length > 1)
                            {
                                tempString = tempString.Replace("½", ".5");
                            }
                            else
                            {
                                tempString = "0.5";  // muutetaan suoraan, koska oli pelkästään "½"
                            }
                        }

                        if (float.TryParse(tempString, System.Globalization.NumberStyles.AllowDecimalPoint,
                                           System.Globalization.CultureInfo.InvariantCulture, out syotetty_tulos) == true)
                        {
                            if (syotetty_tulos >= 0.0F && syotetty_tulos <= Vakiot.TURNAUKSEN_TULOS_MAX)
                            {
                                // HUOM! Jos tuloksessa on desimaalit väärin, esim. 2.37 tai 0,9,
                                //       niin ylimääräiset desimaalit "pyöristyvät" alas -> 2,0 tai 0,5.
                                onko_turnauksen_tulos = true;
                                selopelaaja.SetAnnettuTurnauksenTulos(syotetty_tulos);

                                // alussa oli annettu turnauksen lopputulos, jatka SELOjen tarkistamista
                                // Nyt selojen on oltava ilman tulosmerkintää!
                                continue;
                            }
                            // Jos ei saatu kelvollista lukua, joka käy tuloksena, niin jatketaan
                            // ja katsotaan, saadaanko vahvuusluku sen sijaan (jossa voi olla +/=/-)
                        }



                        // XXX: EI MUKANA VIELÄ
                        //}
                        //else if (toinen && onko_turnauksen_tulos && (vastustaja.Length == 1 || vastustaja.Length == 2) && !vastustaja.Equals("/") && SyotteenOsat.Count == 3)
                        //{
                        //    // Format 7) This must be number of matches N or NN, and then 3rd item should be average SELO of the opponents
                        //    string pelimaara_str = SyotteenOsat[1];
                        //    string keskiselo_str = SyotteenOsat[2];
                        //    int pelimaara;
                        //    float keskiselo;
                        //    toinen = false;
                        //    if (int.TryParse(pelimaara_str, out pelimaara) == true)
                        //    {
                        //        // pelimaara >= GetAnnettu
                        //        if (pelimaara * 2 < selopelaaja.GetAnnettuTurnauksenTulos2x())
                        //        {
                        //            virhekoodi = Vakiot.SYOTE_VIRHE_TURNAUKSEN_TULOS;
                        //            status = false;
                        //            break;
                        //        }

                        //        selopelaaja.VastustajienLkm = pelimaara;

                        //        // keskiselo yhdellä desimaalilla, piste tai pilkku
                        //        if (float.TryParse(keskiselo_str, System.Globalization.NumberStyles.AllowDecimalPoint,
                        //        System.Globalization.CultureInfo.InvariantCulture, out keskiselo))
                        //        {
                        //            if (keskiselo < Vakiot.MIN_SELO || keskiselo > Vakiot.MAX_SELO)
                        //            {
                        //                virhekoodi = Vakiot.SYOTE_VIRHE_KESKIVAHVUUS;
                        //                status = false;
                        //                break;
                        //            }
                        //            selopelaaja.TurnauksenKeskivahvuus = (int)(keskiselo + 0.5 + 0.001);
                        //            selopelaaja.TurnauksenKeskivahvuus10x = (int)(10 * keskiselo + 0.001);
                        //            vastustajanSelo = selopelaaja.TurnauksenKeskivahvuus;
                        //            // status edelleen true
                        //            break;

                        //        }
                        //        virhekoodi = Vakiot.SYOTE_VIRHE_KESKIVAHVUUS;
                        //        status = false;
                        //        break;
                        //    }
                    }
                    else if (vastustaja.Equals("/"))
                    {
                        toinen = false;
                        if (selopelaaja.UudenPelaajanPelitLKM > 0)
                        {
                            // joko oli kauttamerkki? Ei saa olla kahta!
                            virhekoodi = Vakiot.SYOTE_VIRHE_UUDEN_PELAAJAN_OTTELUT_KAKSI_KAUTTAMERKKIA;
                            status     = false;
                            break;
                        }
                        // '/' ei voi olla ensimmäisenä
                        // '/' ei saa olla, jos oli annettu turnauksen tulos
                        // täytyy olla ainakin yksi ottelutulos ja sen jälkeen pitäisi olla (ei pakko) lisää otteluita
                        //
                        // Jos alkuperäinen pelimäärä oli 0, niin on laskettava ainakin 11 peliä uuden kaavalla
                        // tarkistus kutsuvalla tasolla
                        if (onko_turnauksen_tulos || ottelut.Lukumaara < 1)
                        {
                            virhekoodi = Vakiot.SYOTE_VIRHE_UUDEN_PELAAJAN_OTTELUT_ENINT_10;
                            status     = false;
                            break;
                        }
                        selopelaaja.UudenPelaajanPelitLKM = ottelut.Lukumaara;
                        continue;
                    }

                    toinen = false;

                    // Tarkista yksittäiset vastustajien vahvuusluvut

                    // merkkijono voi alkaa merkillä '+', '=' tai '-'
                    // Mutta tasapeli voidaan antaa myös ilman '='-merkkiä
                    // Jos oli annettu turnauksen tulos, niin selot on syötettävä näin ilman tulosta
                    if (vastustaja.Length == Vakiot.SELO_PITUUS)    // numero (4 merkkiä)
                    {
                        if (int.TryParse(vastustaja, out selo1) == false)
                        {
                            virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;  // -> virheilmoitus, ei ollut numero
                            status     = false;
                            break;
                        }
                        else if (selo1 < Vakiot.MIN_SELO || selo1 > Vakiot.MAX_SELO)
                        {
                            virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;  // -> virheilmoitus, ei sallittu numero
                            status     = false;
                            break;
                        }

                        // Hm... miten tallennus?
                        //
                        //if (onko_turnauksen_tulos) {
                        //    Jos annettu turnauksen tulos, ei merkitystä, koska tehdään uusi laskenta, jossa käytetään turnauksen tulosta
                        //    ottelut.LisaaOttelunTulos(selo1, Vakiot.OttelunTulos_enum.TULOS_EI_ANNETTU);
                        //} else {
                        //    // Tallenna tasapeli, jos tulokset formaatissa +1624 -1700 =1685 +1400, jossa tasapeli
                        //    // on annettu ilman '='-merkkiä eli vaikkapa "+1624 -1700 1685 +1400"
                        //    ottelut.LisaaOttelunTulos(selo1, Vakiot.OttelunTulos_enum.TULOS_TASAPELI);
                        //}

                        // Jos ottelun tulosta ei annettu, niin sitä ei tallenneta
                        // Laskennassa tämä otetaan kuitenkin huomioon tasapelinä, jolloin "+1624 -1700 1685 +1400" menee oikein
                        // Ks. Selopelaaja PelaaOttelu()
                        //
                        // Näin myös yksikkötestauksessa on helpompi tarkistaa tiedot,
                        // koska syötteen "=1234" on eri tapaus kuin "1234".
                        ottelut.LisaaOttelunTulos(selo1, Vakiot.OttelunTulos_enum.TULOS_EI_ANNETTU); // OK
                    }
                    else if (onko_turnauksen_tulos == false && vastustaja.Length == Vakiot.MAX_PITUUS)
                    {
                        // 5)
                        // Erillisten tulosten antaminen hyväksytään vain, jos turnauksen
                        // lopputulosta ei oltu jo annettu (onko_turnauksen_tulos false)

                        Vakiot.OttelunTulos_enum tulos1 = Vakiot.OttelunTulos_enum.TULOS_MAARITTELEMATON;

                        if (vastustaja[0] >= '0' && vastustaja[0] <= '9')
                        {
                            // tarkistetaan, voidaan olla annettu viisinumeroinen luku
                            // 10000 - 99999... joten anna virheilmoitus vahvuusluvusta
                            virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;
                            status     = false;
                        }
                        else
                        {
                            // Ensimmäinen merkki kertoo tuloksen
                            switch (vastustaja[0])
                            {
                            case '+':
                                tulos1 = Vakiot.OttelunTulos_enum.TULOS_VOITTO;
                                break;

                            case '=':
                                tulos1 = Vakiot.OttelunTulos_enum.TULOS_TASAPELI;
                                break;

                            case '-':
                                tulos1 = Vakiot.OttelunTulos_enum.TULOS_TAPPIO;
                                break;

                            default:     // ei sallittu tuloksen kertova merkki
                                virhekoodi = Vakiot.SYOTE_VIRHE_YKSITTAINEN_TULOS;
                                status     = false;
                                break;
                            }
                        }

                        // jos virhe, pois foreach-loopista
                        if (!status)
                        {
                            break;
                        }

                        // Selvitä vielä tuloksen perässä oleva numero
                        // tarkista sitten, että on sallitulla alueella
                        if (int.TryParse(vastustaja.Substring(1), out selo1) == false)
                        {
                            virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;  // -> virheilmoitus, ei ollut numero
                            status     = false;
                        }
                        else if (selo1 < Vakiot.MIN_SELO || selo1 > Vakiot.MAX_SELO)
                        {
                            status = false;
                            break;
                        }

                        // Tallennetaan tulos: vahvuusluku ja +/-/=-merkeistä selvitetty tulos listaan
                        ottelut.LisaaOttelunTulos(selo1, tulos1);
                    }
                    else
                    {
                        // pituus ei ollut
                        //   - SELO_PITUUS (esim. 1234)
                        //   - MAX_PITUUS (esim. +1234) silloin kun tulos voidaan antaa
                        // Tähän tullaan myös, jos turnauksen kokonaistulos oli annettu ennen vahvuuslukuja,
                        // koska silloin annetaan vain pelkät vahvuusluvut ilman yksittäisiä tuloksia.
                        // Ei ole sallittu  2,5 +1624 =1700 -1685 +1400 (oikein on 2,5 1624 1700 1685 1400)
                        virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;
                        status     = false;
                        break;
                    }

                    // Oliko asetettu virhe, mutta ei vielä poistuttu foreach-loopista?
                    if (!status)
                    {
                        break;
                    }
                } // foreach (käydään läpi syötteen numerot)

                // Lisää tarkastuksia
                // 6) Annettu turnauksen tulos ei saa olla suurempi kuin pelaajien lukumäärä
                //    Jos tulos on sama kuin pelaajien lkm, on voitettu kaikki ottelut.
                if (status && onko_turnauksen_tulos)
                {
                    if (ottelut.Lukumaara == 0)
                    {
                        // jos ei otteluita, mutta oli saatu turnauksen tulos N tai NN,
                        // niin annetaan virheilmoitus vastustajan selo virheellinen
                        virhekoodi = Vakiot.SYOTE_VIRHE_VASTUSTAJAN_SELO;
                    }
                    // Vertailu kokonaislukuina, esim. syötetty tulos 3.5 ja pelaajia 4, vertailu 7 > 8.
                    else if ((int)(2 * syotetty_tulos + 0.01F) > 2 * ottelut.Lukumaara)
                    {
                        virhekoodi = Vakiot.SYOTE_VIRHE_TURNAUKSEN_TULOS;  // tästä oma virheilmoitus
                        //status = false; // no need to clear status any more
                    }
                }
            }

            // Palauta virhekoodi tai selvitetty yksittäisen vastustajan selo (joka on 0, jos ottelut listassa)
            return(virhekoodi < 0 ? virhekoodi : vastustajanSelo);
        }
Beispiel #3
0
        // Pelaa kaikki listalta (syotteet.Ottelut) löytyvät ottelut!
        //
        // Tapaukset:
        // 1) Uuden pelaajan laskenta, jossa tulokset formaatissa "1.5 1622 1880 1683"
        // 2) Normaali laskenta, jossa käydään kaikki listan ottelut läpi, tulokset "+1525 =1600 -1611 +1558"
        // 3) Uuden pelaajan laskenta, jossa tulokset formaatissa "1.5 1622 1880 1683"
        //
        // Päivittää: UusiSelo, UusiPelimaara, turnauksenTulos, MinSelo ja MaxSelo
        // Palauttaa: -
        //
        public void PelaaKaikkiOttelut(Syotetiedot syotteet)
        {
            if (syotteet == null)
            {
                throw new ArgumentNullException(nameof(syotteet));
            }

            // XXX: KÄSITTELE ERIKOISTAPAUS, JOSSA ON VAIN annettuTurnauksenTulos2x, VastustajienLkm ja Turnauksenkeskivahvuus
            // XXX: silloin ei ole ottelulistaa

            Ottelulista ottelulista = syotteet.Ottelut;

            // asettaa omat tiedot (selo ja pelimäärä) seloPelaaja-luokkaan, nollaa tilastotiedot ym.
            AlustaLaskenta(syotteet);

            VastustajaMin = ottelulista.VastustajaMin;
            VastustajaMax = ottelulista.VastustajaMax;

            // XXX: Kun ensimmäinen ottelu, niin UusiSelo ja UusiPelimaara ovat käyttäjän antamat alkuarvot omaSelo ja pelimaara
            // XXX: Laskennan edetessä niitä päivitetään

            // Erikoistapauksena uuden pelaajan tuloksien laskenta turnauksesta,
            // jossa tulokset on ilmoitettu formaatissa "1.5 1622 1880 1683"
            //

            if (OnkoAnnettuTurnauksenTulos && UudenPelaajanLaskenta)
            {
                //  selo += pistemäärä - ottelut/2 * 200
                // 1 ottelu:
                //    1525 + 0.5 1525 -> tulos 1525
                // 2 ottelua:
                //  2    1525 1441   summa: 2966  keskim. 1483   tulos on keskim+200
                // keskitulos/matsi = 1

                // apumuuttujia (lausekkeiden selkiyttämiseksi ja lyhentämiseksi)
                float keskimTulos = (annettuTurnauksenTulos2x / 2F) / VastustajienLkm; // 0.0 - 1.0
                float muutos      = 400 * (keskimTulos - 0.5F) + 0.5F;                 // tuloksella tasapeli pysytään samassa kuin keskimTulos

                // vanhan selon painoarvo ja uuden lasketun selon painoarvo riippuvat pelimääristä
                UusiSelo       = ((UusiSelo * UusiPelimaara) + (int)(TurnauksenKeskivahvuus + muutos) * VastustajienLkm) / (UusiPelimaara + VastustajienLkm);
                UusiPelimaara += VastustajienLkm;

                // turnauksen tulos annettu, joten ei laskettavaa
                TurnauksenTulos2x = annettuTurnauksenTulos2x;

                // koska laskenta tehtiin kerralla, ei saatu minSeloa ja maxSeloa
                MinSelo = UusiSelo;
                MaxSelo = UusiSelo;
                //return;
            }
            else
            {
                // Varsinainen laskenta: Käydään läpi kaikki listan ottelut, jotka olivat formaatissa
                // "+1525 =1600 -1611 +1558". Tällöin myös MinSelo ja MaxSelo voidaan selvittää.
                //
                var ottelu     = ottelulista.HaeEnsimmainen(); // vastustajanSelo, ottelunTulos
                int pelattuLKM = 0;

                // Kun lista on tyhjä, saadaan ottelun tulos TULOS_MAARITTELEMATON
                while (ottelu.Item2 != Vakiot.OttelunTulos_enum.TULOS_MAARITTELEMATON)
                {
                    // päivitä seloa ja tilastoja jokaisen ottelun laskennassa, myös laske Odotustulos
                    UusiSelo = PelaaOttelu(ottelu.Item1, ottelu.Item2,
                                           (syotteet.UudenPelaajanPelitEnsinLKM > 0 && pelattuLKM >= syotteet.UudenPelaajanPelitEnsinLKM));

                    // päivitä pelimäärää vain jos oli annettu
                    if (UusiPelimaara != Vakiot.PELIMAARA_TYHJA)
                    {
                        UusiPelimaara++;
                        pelattuLKM++;
                    }
                    ottelu = ottelulista.HaeSeuraava();
                }

                // Onko pikashakin pelit annettu "väärässä formaatissa", kun pitäisi olla esim. "1.5 1622 1880 1683"
                if (!OnkoAnnettuTurnauksenTulos && alkuperaisetSyotteet.Miettimisaika <= Vakiot.Miettimisaika_enum.MIETTIMISAIKA_ENINT_10MIN)
                {
                    // asetetaan turnauksen tulokseksi otteluista "laskettu" tulos
                    // ja sitten voidaan käyttää oikeaa pikashakin vahvuusluvun laskentakaavaa
                    SetAnnettuTurnauksenTulos(TurnauksenTulos2x / 2.0F);
                }

                // Entä jos vanhan pelaajan ottelut olivatkin formaatissa "1.5 1622 1880 1683"?
                // Jos näin oli, niin unohdetaan vanha laskenta, josta käytetään vain Odotustulos sekä UusiPelimaara.
                //
                // HUOM! Seuraava ei toimisi uudella pelaajalla, mutta se erikoistapaus onkin käsitelty aiemmin
                //
                if (OnkoAnnettuTurnauksenTulos)
                {
                    //
                    // Aiemmasta laskennasta tarvitaan Odotustulos
                    // apumuuttuja selo, koska sitä tarvitaan kaavassa usein
                    //
                    int vanha = alkuperaisetSyotteet.AlkuperainenSelo; // aloitetaan alusta, oma apumuuttuja
                    TurnauksenTulos2x = annettuTurnauksenTulos2x;      // turnauksen tulos annettu, joten ei laskettavaa

                    if (alkuperaisetSyotteet.Miettimisaika <= Vakiot.Miettimisaika_enum.MIETTIMISAIKA_ENINT_10MIN)
                    {
                        //
                        // PELO: pikashakilla on oma laskentakaavansa
                        //
                        // http://skore.users.paivola.fi/selo.html kertoo:
                        // Pikashakin laskennassa Odotustulos lasketaan samoin, mutta ilman 0,85 - sääntöä.
                        // Itse laskentakaava onkin sitten hieman vaikeampi:
                        // pelo = vanha pelo + 200 - 200 * e(Odotustulos - tulos) / 10 , kun saavutettu tulos on odotustulosta suurempi
                        // pelo = vanha pelo - 200 + 200 * e(tulos - Odotustulos) / 10 , kun saavutettu tulos on odotustulosta pienempi
                        //            Loppuosan pitää olla e((tulos - Odotustulos) / 10)  eli sulut lisää, jakolasku ensin.
                        //
                        // turnauksen tulos on kokonaislukuna, pitää jakaa 2:lla
                        // Odotustulos on kokonaisluku ja pitää jakaa 100:lla
                        //
                        // Laskentakaavaan lisätty pyöristys Math.Round, jonka jälkeen kaikista Joukkuepikashakin laskennoista saadaan samat tulokset
                        if ((annettuTurnauksenTulos2x / 2.0) > (Odotustulos / 100.0))
                        {
                            UusiSelo =
                                (int)Math.Round(vanha + 200.0 - 200.0 * Math.Pow(Math.E, (Odotustulos / 100.0 - annettuTurnauksenTulos2x / 2.0) / 10.0) + 0.0001);
                        }
                        else
                        {
                            UusiSelo =
                                (int)Math.Round(vanha - 200.0 + 200.0 * Math.Pow(Math.E, (annettuTurnauksenTulos2x / 2.0 - Odotustulos / 100.0) / 10.0) + 0.0001);
                        }
                    }
                    else
                    {
                        //
                        // SELO: pidemmän miettimisajan pelit eli > 10 min
                        //
                        float lisakerroin = MaaritaLisakerroin(vanha, alkuperaisetSyotteet.Miettimisaika);
                        // Lisätään vielä pelattujen pelien lkm * 0.1
                        UusiSelo =
                            (int)Math.Round((vanha + MaaritaKerroin(vanha) * lisakerroin * (annettuTurnauksenTulos2x / 2.0 - Odotustulos / 100.0)) + ottelulista.Lukumaara * 0.1 + 0.0001);
                    }

                    // koska laskenta tehtiin kerralla, ei saatu minSeloa ja maxSeloa
                    MinSelo = UusiSelo;
                    MaxSelo = UusiSelo;
                }
            }
            Suoritusluku            = LaskeSuoritusluku(syotteet.Ottelut);
            SuorituslukuFIDE        = LaskeSuorituslukuFIDE();
            SuorituslukuLineaarinen = LaskeSuorituslukuLineaarinen();
        }
Beispiel #4
0
        //  - TESTATTAESSA (UnitTest1.cs)
        //     Syotetiedot ottelu =
        //        new Syotetiedot(Vakiot.Miettimisaika_enum.MIETTIMISAIKA_VAH_90MIN, "1725", "1", "1441", Vakiot.OttelunTulos_enum.TULOS_VOITTO, /*doTrim*/true);
        // Testattaessa doTrim=true, koska välilyöntien poistoa ei tehdä yksikkötestauksessa vaan
        // poiston jättäminen tänne on osa testausta.
        public Syotetiedot(Vakiot.Miettimisaika_enum aika1, string selo1, string pelimaara1, string vastustajat1, Vakiot.OttelunTulos_enum tulos1, bool doTrim)
        {
            // XXX: Could check arguments everywhere: arg == null or sometimes string.IsNullOrEmpty(arg)
            if (selo1 == null)
            {
                throw new ArgumentNullException(nameof(selo1));
            }
            if (pelimaara1 == null)
            {
                throw new ArgumentNullException(nameof(pelimaara1));
            }
            if (vastustajat1 == null)
            {
                throw new ArgumentNullException(nameof(vastustajat1));
            }


            // Copy arguments, might be modified
            Vakiot.Miettimisaika_enum aika = aika1;
            string selo        = String.Copy(selo1);
            string pelimaara   = String.Copy(pelimaara1);
            string vastustajat = String.Copy(vastustajat1);

            Vakiot.OttelunTulos_enum tulos = tulos1;


            // If CSV format, values there will override other parameters
            if (vastustajat.Contains(','))
            {
                List <string> tmp = vastustajat.Split(',').ToList();

                if (tmp.Count != 2 || (tmp.Count == 2 && tmp[0].Trim().Length >= 4))
                {
                    //vastustajat = so.SiistiVastustajatKentta(vastustajat.Trim());
                    List <string> data = vastustajat.Split(',').ToList();

                    if (data.Count == 5)
                    {
                        aika        = this.SelvitaMiettimisaikaCSV(data[0]);
                        selo        = data[1];
                        pelimaara   = data[2];
                        vastustajat = data[3];
                        tulos       = this.SelvitaTulosCSV(data[4]);
                    }
                    else if (data.Count == 4)
                    {
                        // viimeinen osa voi sisältää vastustajat tuloksineen tai jos alkuperäinen pelimäärä on enintään 10,
                        // niin ensin lasketaan uuden pelaajan kaavalla ja loput "/"-merkin jälkeen menevät normaalilaskentaan
                        //  "90,1525,0,+1525 +1441 -1973 +1718 -1784 -1660 -1966 +1321 -1678 -1864 -1944 / -1995 +1695 -1930 1901",
                        aika        = this.SelvitaMiettimisaikaCSV(data[0]);
                        selo        = data[1];
                        pelimaara   = data[2];
                        vastustajat = data[3];
                        tulos       = Vakiot.OttelunTulos_enum.TULOS_MAARITTELEMATON;
                    }
                    else if (data.Count == 3)
                    {
                        //aika = aika;
                        selo        = data[0];
                        pelimaara   = data[1];
                        vastustajat = data[2];
                        tulos       = Vakiot.OttelunTulos_enum.TULOS_MAARITTELEMATON;
                    }
                    else if (data.Count == 2)
                    {
                        //aika = aika;
                        selo        = data[0];
                        pelimaara   = "";
                        vastustajat = data[1];
                        tulos       = Vakiot.OttelunTulos_enum.TULOS_MAARITTELEMATON;
                    }
                    else
                    {
                        // XXX: CHECK WHAT HAPPENS HERE
                        // XXX: Virheen pitää olla Vakiot.SYOTE_VIRHE_CSV_FORMAT

                        //aika = aika;
                        selo        = "";
                        pelimaara   = "";
                        vastustajat = "";
                        tulos       = Vakiot.OttelunTulos_enum.TULOS_MAARITTELEMATON;
                    }
                    // The thinking time might be needed from the form if there are 2 or 3 values in CSV format
                    //return so.SelvitaCSV(aika, vastustajat);
                }
            }

            Miettimisaika = aika;
            // if doTrim -> remove leading and trailing white spaces
            AlkuperainenSelo_str      = doTrim ? selo.Trim() : selo;
            AlkuperainenPelimaara_str = doTrim ? pelimaara.Trim() : pelimaara;
            if (doTrim)
            {
                SelolaskuriOperations so = new SelolaskuriOperations();
                vastustajat = so.SiistiVastustajatKentta(vastustajat.Trim());
            }
            VastustajienSelot_str = vastustajat;
            OttelunTulos          = tulos;

            // Clear these too although not actually needed
            AlkuperainenSelo           = 0;
            AlkuperainenPelimaara      = 0;
            UudenPelaajanPelitEnsinLKM = 0;
            YksiVastustajaTulosnapit   = 0;

            // Create en empty list for matches (opponent's selo, match result)
            Ottelut = new Ottelulista();
        }