Commit 9e03ca56 authored by M1888's avatar M1888

aamupäiväkoodailut

parent 1ad184e4
...@@ -28,6 +28,12 @@ ...@@ -28,6 +28,12 @@
<setting name="ArparivitVoimassa" serializeAs="String"> <setting name="ArparivitVoimassa" serializeAs="String">
<value>6</value> <value>6</value>
</setting> </setting>
<setting name="Rivihinta" serializeAs="String">
<value>1</value>
</setting>
<setting name="Vakiorivit" serializeAs="String">
<value>0</value>
</setting>
</Lottokone.Properties.Settings> </Lottokone.Properties.Settings>
</userSettings> </userSettings>
</configuration> </configuration>
\ No newline at end of file
...@@ -7,14 +7,24 @@ ...@@ -7,14 +7,24 @@
<!-- Globaaleja tyylejä eri kontrolleille --> <!-- Globaaleja tyylejä eri kontrolleille -->
<Style TargetType="TextBlock"> <Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="WrapWithOverflow" /> <Setter Property="TextWrapping" Value="WrapWithOverflow" />
<Setter Property="FontSize" Value="10" /> <Setter Property="FontSize" Value="12" />
</Style> </Style>
<Style TargetType="ListViewItem">
<Setter Property="FontSize" Value="14" />
</Style>
<!-- Erikseen Style-propertyn käyttä käytettävät tyylit --> <!-- Erikseen Style-propertyn käyttä käytettävät tyylit -->
<Style TargetType="TextBox" x:Key="Asetusboksi"> <Style TargetType="TextBox" x:Key="Asetusboksi">
<Setter Property="DockPanel.Dock" Value="Right" /> <Setter Property="DockPanel.Dock" Value="Right" />
<Setter Property="Width" Value="150" /> <Setter Property="Width" Value="150" />
<Setter Property="Margin" Value="5" /> <Setter Property="Margin" Value="5" />
</Style> </Style>
<Style TargetType="Label" x:Key="Isompi">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="16" />
</Style>
</Application.Resources> </Application.Resources>
</Application> </Application>
...@@ -35,6 +35,14 @@ ...@@ -35,6 +35,14 @@
<TextBlock Margin="25,-5,0,0">Kuinka monta kierrosta simuloitujen pelaajien rivit pysyvät voimassa, kunnes ne arvotaan uudelleen.</TextBlock> <TextBlock Margin="25,-5,0,0">Kuinka monta kierrosta simuloitujen pelaajien rivit pysyvät voimassa, kunnes ne arvotaan uudelleen.</TextBlock>
</StackPanel> </StackPanel>
<StackPanel>
<DockPanel Margin="5">
<Label>Rivihinta</Label>
<TextBox Style="{StaticResource Asetusboksi}" x:Name="txbHinta" Text="{Binding Rivihinta, Mode=TwoWay}" />
</DockPanel>
<TextBlock Margin="25,-5,0,0">Paljonko yksi lottorivi maksaa?</TextBlock>
</StackPanel>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<Label FontWeight="Bold">Omat asetukset</Label> <Label FontWeight="Bold">Omat asetukset</Label>
...@@ -61,8 +69,17 @@ ...@@ -61,8 +69,17 @@
</DockPanel> </DockPanel>
<TextBlock Margin="25,-5,0,0">Kuinka monen kierroksen välein rivisi arvotaan uudelleen?</TextBlock> <TextBlock Margin="25,-5,0,0">Kuinka monen kierroksen välein rivisi arvotaan uudelleen?</TextBlock>
</StackPanel> </StackPanel>
<StackPanel>
<DockPanel Margin="5">
<Label>Vakiorivejä</Label>
<TextBox Style="{StaticResource Asetusboksi}" x:Name="txbVakiorivit" Text="{Binding Vakiorivit, Mode=TwoWay}" />
</DockPanel>
<TextBlock Margin="25,-5,0,0">Montako vakioriviä haluat pelata?</TextBlock>
</StackPanel>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
<Button x:Name="btnSave" Content="Tallenna &amp; sulje" Click="btnSave_Click" Margin="15" /> <Button x:Name="btnSave" Content="Tallenna &amp; sulje" Click="btnSave_Click" Margin="15" />
</StackPanel> </StackPanel>
......
...@@ -30,5 +30,10 @@ namespace Lottokone ...@@ -30,5 +30,10 @@ namespace Lottokone
Properties.Settings.Default.Save(); Properties.Settings.Default.Save();
this.Close(); this.Close();
} }
private void BtnRivit_Click(object sender, RoutedEventArgs e)
{
}
} }
} }
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="MedallionRandom, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\MedallionRandom.1.1.0\lib\net452\MedallionRandom.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
...@@ -81,7 +84,6 @@ ...@@ -81,7 +84,6 @@
<Compile Include="Model\Pelaaja.cs" /> <Compile Include="Model\Pelaaja.cs" />
<Compile Include="Model\Rivi.cs" /> <Compile Include="Model\Rivi.cs" />
<Compile Include="Model\Voittorivi.cs" /> <Compile Include="Model\Voittorivi.cs" />
<Compile Include="ObservableCollectionEx.cs" />
<Compile Include="Properties\AssemblyInfo.cs"> <Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
...@@ -99,6 +101,7 @@ ...@@ -99,6 +101,7 @@
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput> <LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings"> <None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput> <LastGenOutput>Settings.Designer.cs</LastGenOutput>
...@@ -107,5 +110,8 @@ ...@@ -107,5 +110,8 @@
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Resource Include="Resources\lotto.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>
\ No newline at end of file
<Window x:Class="Lottokone.Lottorivit"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Lottokone"
mc:Ignorable="d"
Title="Lottorivit" Height="450" Width="800">
<Grid>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Lottokone
{
/// <summary>
/// Interaction logic for Lottorivit.xaml
/// </summary>
public partial class Lottorivit : Window
{
public Lottorivit()
{
InitializeComponent();
NaytaKontrollit();
}
public void NaytaKontrollit()
{
StackPanel rivit = new StackPanel();
for (int i = 0; i < Properties.Settings.Default.Vakiorivit; i++)
{
StackPanel rivi = new StackPanel();
rivi.Orientation = Orientation.Horizontal;
rivi.Name = "spRivi{i}";
for (int j = 0; j < 7; j++)
{
TextBox tb = new TextBox();
tb.Style = Resources["Lottonumero"] as Style;
tb.TextChanged += txbChanged;
rivi.Children.Add(tb);
}
rivit.Children.Add(rivi);
}
grdRivit.Children.Add(rivit);
}
public void txbChanged(object sender, TextChangedEventArgs e)
{
TextBox tb = sender as TextBox;
if(tb != null)
{
if(int.TryParse(tb.Text, out int result))
{
if(result < 1)
{
tb.Text = "1";
}
else if (result > 40)
{
tb.Text = "40";
}
}
else
{
MessageBox.Show("Syötä vain numeroita 1-40");
}
}
}
}
}
...@@ -5,30 +5,37 @@ ...@@ -5,30 +5,37 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Lottokone" xmlns:local="clr-namespace:Lottokone"
mc:Ignorable="d" mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"> Title="Lottokone" Height="450" Width="950">
<Window.Background>
<ImageBrush ImageSource="Resources/lotto.png" />
</Window.Background>
<Grid> <Grid>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<StackPanel> <StackPanel Margin="0,10,0,0">
<Button x:Name="btnNext" Content="Seuraava viikko" Click="btnNext_Click"/> <Button x:Name="btnNext" Margin="0,5,0,0" Content="Seuraava viikko" Click="btnNext_Click"/>
<Button x:Name="btnStart" Content="Käynnistä" Click="btnStart_Click"/> <Button x:Name="btnStart" Margin="0,5,0,0" Content="Käynnistä" Click="btnStart_Click"/>
<Button x:Name="btnStop" Content="Pysäytä" Click="btnStop_Click"/> <Button x:Name="btnStop" Margin="0,5,0,0" Content="Pysäytä" Click="btnStop_Click"/>
<Button x:Name="btnSettings" Content="Asetukset" Click="btnSettings_Click" Margin="0,50,0,0"/> <Button x:Name="btnSettings" Margin="0,50,0,0" Content="Asetukset" Click="btnSettings_Click" />
</StackPanel> </StackPanel>
<StackPanel x:Name="spLotto" Width="250"> <StackPanel x:Name="spLotto" Width="250">
<Label Content="Vuosi:"/> <Label Style="{StaticResource Isompi}" Content="{Binding Vuosi}" ContentStringFormat="Vuosi: {0}"/>
<Label Content="{Binding Vuosi}" /> <Label Style="{StaticResource Isompi}" Content="{Binding Viikko}" ContentStringFormat="Viikko: {0}"/>
<Label Content="Viikko:"/> <Label Style="{StaticResource Isompi}" Content="{Binding Rivimaara}" ContentStringFormat="Rivejä: {0:N0}"/>
<Label Content="{Binding Viikko}" /> <Label Style="{StaticResource Isompi}" Content="{Binding Potti}" ContentStringFormat="Potti: {0:C0}"/>
<Label Content="Rivejä:"/> <Label Style="{StaticResource Isompi}">Voittorivi:</Label>
<Label Content="{Binding Rivimaara}"/> <Label Style="{StaticResource Isompi}" Content="{Binding Voittorivi}" />
<Label Content="Potti:"/>
<Label Content="{Binding Potti}"/>
<Label Content="Voittorivi:"/>
<Label Content="{Binding Voittorivi}"/>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<Label Content="Status:"/> <Label Style="{StaticResource Isompi}" Content="Status:"/>
<ListView Height="350" Width="300" x:Name="lstStatus" ItemsSource="{Binding Value, UpdateSourceTrigger=PropertyChanged}"/> <ListView Height="350" Width="300" x:Name="lstStatus" ItemsSource="{Binding Value, UpdateSourceTrigger=PropertyChanged}" Opacity="0.7"/>
</StackPanel>
<StackPanel x:Name="spPlayer" Width="300" Margin="5,0,0,0">
<Label Style="{StaticResource Isompi}" Content="{Binding Nimi}" ContentStringFormat="Nimi: {0}" />
<Label Style="{StaticResource Isompi}" Content="{Binding Saldo}" ContentStringFormat="Tilin saldo: {0:C0}" />
<Label Style="{StaticResource Isompi}" Content="{Binding Riveja}" ContentStringFormat="Rivejä: {0:N0}" />
<Label Style="{StaticResource Isompi}" Content="Omat voitot:" Margin="0,100,0,0"/>
<ListView x:Name="lstVoitot" Height="180" Width="300" Opacity="0.7">
</ListView>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
...@@ -22,50 +26,155 @@ namespace Lottokone ...@@ -22,50 +26,155 @@ namespace Lottokone
/// </summary> /// </summary>
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
// Lottokoneen pääolio // Lottokoneen pääolio
private Lotto kone; private Lotto kone;
// Meidän pelaaja
private Pelaaja pelaaja;
// Meidän voitot, ja lukko-objekti jotta voidaan käyttää sitä threadeista
private ObservableCollection<string> voitot;
private object voittolukko;
// Tämä ajaa meidän pelilooppia kun starttia painetaan
private Thread runner;
private bool kaynnissa = false;
// Tässä kyseinen pelilooppi
// Tämä olisi ollut ehkä järkevä toteuttaa muualla kuin täällä MainWindow.xaml.cs:ssä,
// mutta tällä nyt mennään....
private void GameLoop()
{
do
{
kone.Tick();
// meidän pitää tarkistaa täällä käsin pelaajamme voitot uudestaan, jotta
// saadaan niistä tieto myös toiseen listaikkunaan.
foreach (Lottorivi r in pelaaja.Rivit)
{
string s = "";
switch (r.Oikein(kone.Voittorivi))
{
case 3:
if (r.Numerot.Contains(kone.Voittorivi.Lisanumero))
{
s = $"Kierros {kone.Kierros}: 3+1 oikein";
}
break;
case 4:
s = $"Kierros {kone.Kierros}: 4 oikein";
break;
case 5:
s = $"Kierros {kone.Kierros}: 5 oikein";
break;
case 6:
s = $"Kierros {kone.Kierros}: ";
// taas lisänumeron tarkistus
if (r.Numerot.Contains(kone.Voittorivi.Lisanumero))
s += "6+1 oikein!!! Melkein jo kannattaa?!";
else
s += "6 oikein!";
break;
case 7:
// Päävoitto jos osuu, niin pelin voinee pysäyttää.
s = $"Kierros {kone.Kierros}: PÄÄVOITTO!!!! JUMANTSUIKKA! Kannattaa ehkä lotota oikeastikin?! " +
"Ellet käyttänyt kaikkea onneasi tähän....";
kaynnissa = false;
break;
default:
break;
}
if(s.Length > 0)
{
lock(voittolukko)
{
voitot.Insert(0, s);
}
}
}
} while (kaynnissa);
}
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
kone = new Lotto();
// sidotaan lottokone stackpanelin datacontekstiksi // 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");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new
FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
// luodaan lottokone ja sidotaan se stackpanelin datacontekstiksi
kone = new Lotto();
spLotto.DataContext = kone; spLotto.DataContext = kone;
// luodaan meidän pelaaja, ja lisätään se lottoon.
pelaaja = new Pelaaja(Properties.Settings.Default.Nimi);
pelaaja.Riveja = Properties.Settings.Default.Arparivit + Properties.Settings.Default.Vakiorivit;
pelaaja.RivitVoimassa = Properties.Settings.Default.ArparivitVoimassa;
kone.Pelaajat.Add(pelaaja);
// sidotaan meidät pelaajan tietoikkunaan
spPlayer.DataContext = pelaaja;
// status-ikkunaan skrollaava historia eventeistä // status-ikkunaan skrollaava historia eventeistä
// EnableCollectionSynchronization() mahdollistaa listan käyttämisen muista
// threadeista, ja UI-thread saa siitä silti CollectionUpdated eventin.
BindingOperations.EnableCollectionSynchronization(kone.StatusHistory, kone.StatusLock);
lstStatus.ItemsSource = kone.StatusHistory; lstStatus.ItemsSource = kone.StatusHistory;
((INotifyCollectionChanged)lstStatus.Items).CollectionChanged += lstStatus_CollectionChanged;
// voitoille samat kun ylempi
voitot = new ObservableCollection<string>();
voittolukko = new object();
BindingOperations.EnableCollectionSynchronization(voitot, voittolukko);
lstVoitot.ItemsSource = voitot;
btnStop.IsEnabled = false;
} }
private void btnNext_Click(object sender, RoutedEventArgs e) private void btnNext_Click(object sender, RoutedEventArgs e)
{ {
kone.Tick(); btnStart.IsEnabled = false;
} btnNext.IsEnabled = false;
private void lstStatus_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) // ajetaan looppi kerran. kun kaynnissa = false, niin se palautuu heti.
{ GameLoop();
if (e.Action == NotifyCollectionChangedAction.Add)
{
} btnNext.IsEnabled = true;
btnStart.IsEnabled = true;
} }
private void btnStart_Click(object sender, RoutedEventArgs e) private void btnStart_Click(object sender, RoutedEventArgs e)
{ {
kone.Start(); btnStop.IsEnabled = true;
btnStart.IsEnabled = false;
btnNext.IsEnabled = false;
btnSettings.IsEnabled = false;
kaynnissa = true;
runner = new Thread(GameLoop);
runner.IsBackground = true;
runner.Start();
} }
private void btnStop_Click(object sender, RoutedEventArgs e) private void btnStop_Click(object sender, RoutedEventArgs e)
{ {
kone.Stop(); kaynnissa = false;
// odotetaan max 2sek
runner.Join(2000);
btnNext.IsEnabled = true;
btnStart.IsEnabled = true;
btnStop.IsEnabled = false;
btnSettings.IsEnabled = true;
} }
private void btnSettings_Click(object sender, RoutedEventArgs e) private void btnSettings_Click(object sender, RoutedEventArgs e)
{ {
Asetukset a = new Asetukset(); new Asetukset().ShowDialog();
a.Show();
} }
} }
} }
using Custom.Collections; // ObservableCollectionEx using System;
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
...@@ -16,14 +15,12 @@ namespace Lottokone.Model ...@@ -16,14 +15,12 @@ namespace Lottokone.Model
{ {
public class Lotto : INotifyPropertyChanged public class Lotto : INotifyPropertyChanged
{ {
private bool kaynnissa = false;
// Mitataan kunkin kierroksen kesto, jotta // Mitataan kunkin kierroksen kesto, jotta
// osataan näyttää nättiä statistiikkaa. // osataan näyttää nättiä statistiikkaa.
private Stopwatch stopwatch; private Stopwatch stopwatch;
// Kolme eri listaa eri voittotasoille: // Neljä eri listaa eri voittotasoille:
// 5, 6 ja 7 oikein. // 5, 6, 6+1 ja 7 oikein.
// Näihin laitetaan joka kierroksella voittaneet pelaajat, // Näihin laitetaan joka kierroksella voittaneet pelaajat,
// ja sitten jaetaan niistä tarkistuksen jälkeen voitot. // ja sitten jaetaan niistä tarkistuksen jälkeen voitot.
// //
...@@ -36,8 +33,19 @@ namespace Lottokone.Model ...@@ -36,8 +33,19 @@ namespace Lottokone.Model
// thread-safe ConcurrentBagien käyttö on järkevämpää, vaikkakin rumaa. // thread-safe ConcurrentBagien käyttö on järkevämpää, vaikkakin rumaa.
private ConcurrentBag<Pelaaja> oikein5; private ConcurrentBag<Pelaaja> oikein5;
private ConcurrentBag<Pelaaja> oikein6; private ConcurrentBag<Pelaaja> oikein6;
private ConcurrentBag<Pelaaja> oikein6_1;
private ConcurrentBag<Pelaaja> oikein7; private ConcurrentBag<Pelaaja> oikein7;
// Lista kaikista kierroksen voittajista. Tämä voidaan käydä läpi lottokoneen
// ulkopuolella, ja tarkistaa onko meidän pelaaja listalla.
public IEnumerable<Pelaaja> Voittajat
{
get
{
return oikein5.Concat(oikein6).Concat(oikein6_1).Concat(oikein7);
}
}
private short viikko; private short viikko;
public short Viikko public short Viikko
{ {
...@@ -48,7 +56,7 @@ namespace Lottokone.Model ...@@ -48,7 +56,7 @@ namespace Lottokone.Model
set set
{ {
viikko = value; viikko = value;
if(viikko > 52) if (viikko > 52)
{ {
viikko = 1; viikko = 1;
Vuosi++; Vuosi++;
...@@ -71,6 +79,14 @@ namespace Lottokone.Model ...@@ -71,6 +79,14 @@ namespace Lottokone.Model
} }
} }
public int Kierros
{
get
{
return ((Vuosi - 1) * 52) + Viikko;
}
}
public ConcurrentBag<Pelaaja> Pelaajat { get; set; } public ConcurrentBag<Pelaaja> Pelaajat { get; set; }
private int potti; private int potti;
...@@ -87,8 +103,8 @@ namespace Lottokone.Model ...@@ -87,8 +103,8 @@ namespace Lottokone.Model
} }
} }
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
private Voittorivi voittorivi; private Voittorivi voittorivi;
public Voittorivi Voittorivi public Voittorivi Voittorivi
{ {
...@@ -103,7 +119,16 @@ namespace Lottokone.Model ...@@ -103,7 +119,16 @@ namespace Lottokone.Model
} }
} }
public ObservableCollectionEx<string> StatusHistory; // StatusHistory pitää sisällään kaikki tilaviestit, jotka lottokone suustaan päästää.
// Status-string taas on wrapperi historian ympärille, niin saadaan helposti viimeisin
// viesti sekä voidaan lisätä viestejä historiaan helposti vain asettamalla Statukseen jotain.
// Esim. Status = "Jee";
// StatusLock on objekti joka lukitaan kun StatusHistorya päivitetään.
// UI threadissa kutsutaan BindingOperations.EnableCollectionSynchronization(),
// jolle annetaan tämä sama objekti, niin UI-thread ei sörki kokoelmaa samalla
// kun me päivitetään sitä muualla.
public object StatusLock { get; set; }
public ObservableCollection<string> StatusHistory;
public string Status public string Status
{ {
get get
...@@ -112,8 +137,13 @@ namespace Lottokone.Model ...@@ -112,8 +137,13 @@ namespace Lottokone.Model
} }
set set
{ {
StatusHistory.Insert(0, value); lock (StatusLock)
RaisePropertyChanged(); {
// En saanut ListBoxin autoskrollausta toimimaan uusimpaan itemiin (joka siis tulee
// alimmaiseksi), joten lisätään uudet viestit ylimmäiseksi ja ongelma poistuu. :)
StatusHistory.Insert(0, value);
RaisePropertyChanged();
}
} }
} }
...@@ -123,7 +153,7 @@ namespace Lottokone.Model ...@@ -123,7 +153,7 @@ namespace Lottokone.Model
get get
{ {
int n = 0; int n = 0;
foreach(Pelaaja p in Pelaajat) foreach (Pelaaja p in Pelaajat)
{ {
n += p.Rivit.Count(); n += p.Rivit.Count();
} }
...@@ -134,57 +164,60 @@ namespace Lottokone.Model ...@@ -134,57 +164,60 @@ namespace Lottokone.Model
// Konstruktori lottokoneen pääluokalle // Konstruktori lottokoneen pääluokalle
public Lotto() public Lotto()
{ {
viikko = 0; Potti = 0;
vuosi = 1; Viikko = 0;
Vuosi = 1;
Pelaajat = new ConcurrentBag<Pelaaja>(); Pelaajat = new ConcurrentBag<Pelaaja>();
StatusHistory = new ObservableCollectionEx<string>(new List<string>()); oikein5 = new ConcurrentBag<Pelaaja>();
Status = "Veikkaus: Pelaa maltillisesti :):):):)"; oikein6 = new ConcurrentBag<Pelaaja>();
oikein6_1 = new ConcurrentBag<Pelaaja>();
oikein7 = new ConcurrentBag<Pelaaja>();
StatusLock = new object();
StatusHistory = new ObservableCollection<string>();
Status = "Veikkaus: Pelaa maltilla :):):):)";
stopwatch = Stopwatch.StartNew(); stopwatch = Stopwatch.StartNew();
LisaaPelaajia(Properties.Settings.Default.Pelaajia, Properties.Settings.Default.Riveja); LisaaPelaajia(Properties.Settings.Default.Pelaajia, Properties.Settings.Default.Riveja);
stopwatch.Stop(); stopwatch.Stop();
Status = $"Lisätty {Pelaajat.Count()} pelaajaa ({stopwatch.ElapsedMilliseconds}ms)"; Status = $"Lisätty {Pelaajat.Count():N0} pelaajaa ({stopwatch.ElapsedMilliseconds}ms)";
} }
public void LisaaPelaajia(int pelaajia, int riveja) public void LisaaPelaajia(int pelaajia, int riveja)
{ {
for(int i = 0; i < pelaajia; i++) for (int i = 0; i < pelaajia; i++)
{ {
Pelaajat.Add(new Pelaaja(riveja)); Pelaajat.Add(new Pelaaja(riveja, Properties.Settings.Default.Voimassa));
} }
} }