Commit 4911110e authored by M1888's avatar M1888

viimeiset muutokset

parent 4fc40862
......@@ -23,17 +23,21 @@ namespace Lottokone
public Asetukset()
{
InitializeComponent();
// sidotaan asetukset ikkunaan
spSettings.DataContext = Properties.Settings.Default;
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
// tallennetaan asetukset ja suljetaan ikkuna
Properties.Settings.Default.Save();
this.Close();
}
private void BtnRivit_Click(object sender, RoutedEventArgs e)
{
// lottorivit-ikkuna aukeaa uutena dialogina
new Lottorivit().ShowDialog();
}
public void txbChanged(object sender, TextChangedEventArgs e)
......@@ -91,6 +95,8 @@ namespace Lottokone
private void TxbVakiorivit_TextChanged(object sender, TextChangedEventArgs e)
{
// vakiorivit pitää validoida erikseen, jotta voidaan säätää vakiorivien säädön
// ikkunan avaavan napin aktiivisuutta samalla.
TextBox tb = sender as TextBox;
if(tb != null)
{
......
......@@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Lottokone"
mc:Ignorable="d"
Title="Lottokone" Height="450" Width="950" Background="Black">
Title="Lottokone" Height="450" Width="960" Background="Black">
<StackPanel Orientation="Horizontal">
<StackPanel Margin="5,10,5,0">
<Button x:Name="btnNext" Margin="0,5,0,0" Content="Seuraava viikko" Click="btnNext_Click"/>
......
......@@ -36,13 +36,11 @@ namespace Lottokone
private ObservableCollection<string> voitot;
private object voittolukko;
// Tämä ajaa meidän pelilooppia kun starttia painetaan
private Thread runner;
private bool kaynnissa = false;
// tähän tallennetaan oletuksena imgLotto-kuvassa oleva kuva.
// Se voidaan sitten helposti palauttaa, kun ollaan hetki näytetty jotain muuta kuvaa
private ImageSource oletuskuva;
// eri voittoluokkien kuvat, ja laskuri joka kertoo missä kuvassa ollaan menossa.
private BitmapImage img5oikein;
private BitmapImage img6oikein;
private BitmapImage img7oikein;
......@@ -51,9 +49,23 @@ namespace Lottokone
// Tällä katsotaan, joko kuva pitäisi vaihtaa takaisin oletukseen.
private Stopwatch kuvakello;
// Tässä kyseinen pelilooppi
// Tämä ajaa meidän pelilooppia kun starttia painetaan
private Thread runner;
private bool kaynnissa = false;
// konstruktori
public MainWindow()
{
InitializeComponent();
InitializeLottokone();
}
// Tässä yllä mainittu pelilooppi.
// Tämä olisi ollut ehkä järkevä toteuttaa muualla kuin täällä MainWindow.xaml.cs:ssä,
// mutta tällä nyt mennään....
//
// Itse lottokone ja sen simulaatio toimii siis ilman tätäkin pelilooppia, vaikka toisessa ohjelmassa:
// Tämä pitää vain huolen meidän pelaajasta, joka on simulaatiossa mukana.
private void GameLoop()
{
do
......@@ -63,6 +75,8 @@ namespace Lottokone
// saadaan niistä tieto myös toiseen listaikkunaan.
foreach (Lottorivi r in pelaaja.Rivit)
{
// tähän stringiin tallennetaan pelaajan voittoikkunaan tuleva teksti,
// jos sellaista on.
string s = "";
switch (r.Oikein(kone.Voittorivi))
{
......@@ -138,10 +152,15 @@ namespace Lottokone
{
s = $"Pisteiden talletus tietokantaan ei onnistunut: ${ex.Message}";
}
// Avataan voitto-ikkuna
new Voitto().Show();
break;
default:
break;
}
// Asetetaan uusi teksti voitot-ikkunaan, jos tarve.
if (s.Length > 0)
{
lock (voittolukko)
......@@ -168,10 +187,10 @@ namespace Lottokone
} while (kaynnissa);
}
public MainWindow()
{
InitializeComponent();
// Alustetaan lottokone ja pelaaja ja kaikki muu tarvittava.
public void InitializeLottokone()
{
// tällä saadaan käyttöliittymässä luvut ja rahamäärät näkymään oikein.
// https://stackoverflow.com/questions/7454024/setting-culture-en-in-globally-in-wpf-app
var culture = new CultureInfo("fi-FI");
......@@ -188,6 +207,8 @@ namespace Lottokone
// status-ikkunaan skrollaava historia eventeistä
// EnableCollectionSynchronization() mahdollistaa listan käyttämisen muista
// threadeista, ja UI-thread saa siitä silti CollectionUpdated eventin.
// Lukko-objekti annetaan sitä varten, ettei UI thread mene sörkkimään listaa sillä aikaa
// kun me lisätään sinne asioita toisesta threadista.
BindingOperations.EnableCollectionSynchronization(kone.StatusHistory, kone.StatusLock);
lstStatus.ItemsSource = kone.StatusHistory;
......@@ -285,23 +306,29 @@ namespace Lottokone
private void btnSettings_Click(object sender, RoutedEventArgs e)
{
var a = new Asetukset();
a.ShowDialog();
new Asetukset().ShowDialog();
// kun asetuksista palataan, voidaan ottaa uudet asetukset käyttöön.
// ensin tarkistetaan, onko pelaajamäärä muuttunut
// Ensin otetaan "keskivertopelaaja" jostain meidän listan keskivälistä.
// Kunhan tarvittavat pelaajat on sitten saatu lisättyä tai poistettua, saadaan
// verrattua vanhojen pelaajien tietoja tähän keskivertojäbään. Jos muutoksia tarvitaan,
// niin sitten tehdään ne.
// ConcurrentBag ei sinänsä takaa elementtien järjestystä mitenkään, ja me ollaan lisätty
// meidän pelaaja tänne luultavasti viimeisimpänä joten se voi olla ensimmäisenä tai viimeisenä.
// Tuskin kuitenkaan keskellä.
Pelaaja tmp = kone.Pelaajat.ElementAt(kone.Pelaajat.Count() / 2);
// Tarkistetaan, onko pelaajamäärä muuttunut
int curr = kone.Pelaajat.Count();
// + 1 koska pelaajissa on myös meidän pelaajaolio
// Asetusten pelaajiin pitää lisätä vielä 1 koska pelaajissa on myös meidän pelaajaolio
int uusi = Properties.Settings.Default.Pelaajia + 1;
if (curr < uusi)
kone.LisaaPelaajia(uusi - curr, Properties.Settings.Default.Riveja);
else if (curr > uusi)
kone.PoistaPelaajia(curr - uusi);
// otetaan joku satunnainen pelaaja, ja verrataan sen tietoja uusiin.
// Näin saadaan selville, pitääkö pelaajien tietoja muuttaa.
Pelaaja tmp = kone.Pelaajat.ElementAt(kone.Pelaajat.Count() / 2);
if (tmp.RivitVoimassa != Properties.Settings.Default.Voimassa)
{
kone.Status = $"Rivit voimassa {tmp.RivitVoimassa} -> {Properties.Settings.Default.Voimassa} viikkoa";
......
......@@ -20,6 +20,9 @@ namespace Lottokone.Model
// osataan näyttää nättiä statistiikkaa.
private Stopwatch stopwatch;
// Lista lottokoneen pelaajista
public ConcurrentBag<Pelaaja> Pelaajat { get; set; }
// Neljä eri listaa eri voittotasoille:
// 5, 6, 6+1 ja 7 oikein.
// Näihin laitetaan joka kierroksella voittaneet pelaajat,
......@@ -37,6 +40,9 @@ namespace Lottokone.Model
private ConcurrentBag<Pelaaja> oikein6_1;
private ConcurrentBag<Pelaaja> oikein7;
// Viikolla on laskin, joka nostaa myös vuosia.
// Lottokoneen loopissa voidaan siis vaan kutsua Viikko++,
// ja kun vuosi tulee täyteen, alkaa viikot alusta automaattisesti.
private short viikko;
public short Viikko
{
......@@ -56,6 +62,7 @@ namespace Lottokone.Model
}
}
// monesko vuosi on menossa
private short vuosi;
public short Vuosi
{
......@@ -70,6 +77,7 @@ namespace Lottokone.Model
}
}
// Kuinka mones kierros on menossa?
public int Kierros
{
get
......@@ -78,7 +86,6 @@ namespace Lottokone.Model
}
}
public ConcurrentBag<Pelaaja> Pelaajat { get; set; }
// Nämä voi olla pelkkiä listoja, koska threadeissa vain lueataan niistä.
public List<string> Etunimet { get; set; }
......@@ -95,6 +102,7 @@ namespace Lottokone.Model
}
}
// Joka kierroksella jaossa oleva potti
private int potti;
public int Potti
{
......@@ -111,6 +119,7 @@ namespace Lottokone.Model
public event PropertyChangedEventHandler PropertyChanged;
// Kierroksen voittorivi
private Voittorivi voittorivi;
public Voittorivi Voittorivi
{
......@@ -207,15 +216,15 @@ namespace Lottokone.Model
{
Status = $"Nimien lataus epäonnistui: {ex.Message}";
}
stopwatch.Stop();
Status = $"Alustettu lottokone ({stopwatch.ElapsedMilliseconds}ms)";
// LisaaPelaajia hoitaa kellon pysäytyksen
LisaaPelaajia(Properties.Settings.Default.Pelaajia, Properties.Settings.Default.Riveja);
}
public void LisaaPelaajia(int pelaajia, int riveja)
{
// Ei nollata kelloa tämän alussa, niin saadaan aika ohjelman käynnistyksestä paremmin.
stopwatch.Start();
stopwatch.Restart();
//for (int i = 0; i < pelaajia; i++)
Parallel.For(0, pelaajia,
......@@ -237,10 +246,10 @@ namespace Lottokone.Model
Status = $"Poistettu {maara} pelaajaa ({stopwatch.ElapsedMilliseconds}ms)";
}
// Tämä metodi edistää lottokoneen simulaatiota viikolla.
public void Tick()
{
stopwatch.Restart();
Viikko++;
// Tyhjennetään voittajien listat vain jos viime kierroksella oli voittajia.
......@@ -254,17 +263,26 @@ namespace Lottokone.Model
if (!oikein7.IsEmpty)
oikein7 = new ConcurrentBag<Pelaaja>();
// Arvotaan uusi voittorivi
Voittorivi = new Voittorivi();
// Etsitään voitot (tämä kutsuu myös pelaajien Pelaaja.Tick() metodia,
// joka päivittää lottorivit ja arpoo ne tarvittaessa uudelleen,
// sekä päivittää pelaajien saldot.
EtsiVoittajat();
// Rivimäärä on laskettu ominaisuus, johon ei aseteta suoraan mitään arvoa.
// Kun se päviittyy, pitää siitä kertoa UI:lle, jonne luku on sidottu.
RaisePropertyChanged("Rivimaara");
// Lasketaan kierroksen uusi potti
Potti = (int)(Rivimaara * Properties.Settings.Default.Rivihinta);
// Lopuksi jaetaan kierroksen voitot
JaaVoitot();
stopwatch.Stop();
stopwatch.Stop();
Status = $"-Kierros {Kierros} ({stopwatch.ElapsedMilliseconds}ms)-";
}
// Voittajat täytyy erikseen etsiä ja sitten vasta jakaa voitot.
......@@ -331,11 +349,15 @@ namespace Lottokone.Model
// listoilla ole pelaajia joiden rivit eivät ole voittaneet...
private void JaaVoitot()
{
// lasketaan prosentit voitoille alkuperäisestä potista, vaikka
// voittoja jakaessa jo vähennetään kierroksen oikeasta potista.
int alkupotti = potti;
if (!oikein5.IsEmpty)
{
int voittajia = oikein5.Count();
voitot[3] = ((potti / 100) * 3) / voittajia;
// 3% voittajien kesken
voitot[3] = ((alkupotti / 100) * 3) / voittajia;
Status = $"5 oikein voittoja {voittajia:N0} kpl ({voitot[3]:C0})";
......@@ -349,7 +371,8 @@ namespace Lottokone.Model
if (!oikein6.IsEmpty)
{
int voittajia = oikein6.Count();
voitot[2] = (int)((potti / 100) * 2.5) / voittajia;
// 2.5% voittajien kesken
voitot[2] = (int)((alkupotti / 100) * 2.5) / voittajia;
Status = $"6 oikein voittoja {voittajia:N0} kpl ({voitot[2]:C0})";
......@@ -363,7 +386,8 @@ namespace Lottokone.Model
if (!oikein6_1.IsEmpty)
{
int voittajia = oikein6_1.Count();
voitot[1] = (int)((potti / 100) * 3.8) / voittajia;
// 3.8% voittajien kesken
voitot[1] = (int)((alkupotti / 100) * 3.8) / voittajia;
Status = $"6+1 oikein voittoja {voittajia:N0} kpl ({voitot[1]:C0})";
......
......@@ -122,7 +122,7 @@ namespace Lottokone.Model
// Käydään rivit takaperin läpi, niin voidaan tarvittaessa
// poistaa indeksistä jossa ollaan ja jatkaa looppia turvallisesti.
for (int i = Rivit.Count() - 1; i > 0; i--)
for (int i = Rivit.Count() - 1; i >= 0; i--)
{
Lottorivi r = Rivit[i];
// jos rivi on tässä vaiheessa nolla viikkoa voimassa,
......
......@@ -12,12 +12,14 @@ namespace Lottokone.Model
public short[] Numerot { get; set; }
public Rivi()
{
// oletuksena uusi rivi arvotaan
Numerot = new short[7];
ArvoRivi();
}
public Rivi(short[] numerot)
{
// jos saadaan taulukko numeroita, niin varmistetaan että pituus on oikea.
if (numerot.Length != 7)
throw new ArgumentException("Rivin pituus pitää olla 7 numeroa");
Numerot = numerot;
......@@ -25,15 +27,16 @@ namespace Lottokone.Model
public Rivi(Rivi r)
{
// olemassaolevalta riviltä kopioidaan numerot
Numerot = r.Numerot;
}
public virtual void ArvoRivi()
{
// Otetaan numerot 1-40, järjestellään satunnaisesti, valitaan 7 ekaa, ja tehdään niistä taulukko
// Enumerable.Range tuottaa inttejä, jotka pitää sitten muuntaa shorteiksi
Numerot = Array.ConvertAll(
// otetaan numerot 1-40, järjestellään satunnaisesti, valitaan 7 ekaa, ja tehdään niistä taulukko
Enumerable.Range(1, 40).OrderBy(x => Rand.Next(0, Int32.MaxValue)).Take(7).ToArray(),
// Enumerable.Range tuottaa inttejä, jotka pitää sitten muuntaa shorteiksi
Convert.ToInt16);
// järjestellään rivi arpomisen jälkeen heti
......@@ -52,6 +55,7 @@ namespace Lottokone.Model
return Numerot.Intersect(r.Numerot).Count();
}
// Jos rivin numerot on täysin samat, niin ne ovat sama rivi.
public override bool Equals(object obj)
{
Rivi r = obj as Rivi;
......
......@@ -24,7 +24,11 @@ namespace Lottokone
public Rikkaimmat(ConcurrentBag<Pelaaja> pelaajat)
{
InitializeComponent();
// 15 rikkainta listalle
lstRikkaimmat.ItemsSource = pelaajat.OrderByDescending(p => p.Saldo).Take(15);
// scoreboardille tietokannasta rivit.
try
{
dgScoreboard.ItemsSource = ViewModel.Scoreboard.HaePelaajat();
......
......@@ -13,7 +13,7 @@ namespace Lottokone.ViewModel
{
public static DataView HaePelaajat()
{
const string sql = "SELECT Pvm, Nimi, Saldo FROM Scoreboard ORDER BY Saldo DESC";
const string sql = "SELECT Nimi, Saldo, Pvm FROM Scoreboard ORDER BY Saldo DESC";
DataSet ds = new DataSet();
try
{
......
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment