Aggiunta sezione Calcio Virtuale con WebView2 e statistiche

Introdotta una nuova pagina "Calcio Virtuale" con browser WebView2 integrato per navigare siti di virtual football (default Bet365). Aggiunta la possibilità di inserire manualmente i risultati delle partite virtuali, visualizzarli in lista, calcolare statistiche (1/X/2, media gol, over 2.5) e ricevere suggerimenti di puntata dinamici. Creata la classe VirtualMatch per rappresentare i risultati. Aggiornate le dipendenze e l'interfaccia senza impattare le altre sezioni.
This commit is contained in:
2026-03-11 23:28:05 +01:00
parent 0abb8467f2
commit 97951ac6f0
7 changed files with 583418 additions and 6 deletions

View File

@@ -58,6 +58,15 @@
<Reference Include="CsvHelper, Version=33.0.0.0, Culture=neutral, PublicKeyToken=8c4a6d608ce8f59c, processorArchitecture=MSIL"> <Reference Include="CsvHelper, Version=33.0.0.0, Culture=neutral, PublicKeyToken=8c4a6d608ce8f59c, processorArchitecture=MSIL">
<HintPath>..\packages\CsvHelper.33.1.0\lib\net48\CsvHelper.dll</HintPath> <HintPath>..\packages\CsvHelper.33.1.0\lib\net48\CsvHelper.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Web.WebView2.Core, Version=1.0.3800.47, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.3800.47\lib\net462\Microsoft.Web.WebView2.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.WebView2.Wpf, Version=1.0.3800.47, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.3800.47\lib\net462\Microsoft.Web.WebView2.Wpf.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.WebView2.WinForms, Version=1.0.3800.47, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.WebView2.1.0.3800.47\lib\net462\Microsoft.Web.WebView2.WinForms.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
@@ -122,6 +131,7 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="VirtualFootball\VirtualMatch.cs" />
<Page Include="MainWindow.xaml"> <Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
@@ -204,5 +214,6 @@
<Error Condition="!Exists('..\packages\Microsoft.ML.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.ML.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.targets'))" /> <Error Condition="!Exists('..\packages\Microsoft.ML.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.ML.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.ML.FastTree.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.FastTree.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.ML.FastTree.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.FastTree.props'))" /> <Error Condition="!Exists('..\packages\Microsoft.ML.FastTree.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.FastTree.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.ML.FastTree.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.FastTree.props'))" />
</Target> </Target>
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.3800.47\build\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.3800.47\build\Microsoft.Web.WebView2.targets')" />
<Import Project="..\packages\Microsoft.ML.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.targets" Condition="Exists('..\packages\Microsoft.ML.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.targets')" /> <Import Project="..\packages\Microsoft.ML.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.targets" Condition="Exists('..\packages\Microsoft.ML.5.0.0-preview.25503.2\build\netstandard2.0\Microsoft.ML.targets')" />
</Project> </Project>

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,8 @@
<Window x:Class="HorseRacingPredictor.MainWindow" <Window x:Class="HorseRacingPredictor.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Betting Predictor" Width="1100" Height="680" xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
Title="Betting Predictor" Width="1100" Height="680"
MinWidth="900" MinHeight="540" MinWidth="900" MinHeight="540"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
Background="#1E1E2E" Background="#1E1E2E"
@@ -294,6 +295,12 @@
<TextBlock Text="&#xE7C1;" FontFamily="Segoe MDL2 Assets" FontSize="20" <TextBlock Text="&#xE7C1;" FontFamily="Segoe MDL2 Assets" FontSize="20"
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=RadioButton}}"/> Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=RadioButton}}"/>
</RadioButton> </RadioButton>
<RadioButton x:Name="navVirtualFb" Style="{StaticResource NavBtn}"
ToolTip="Calcio Virtuale"
Checked="navVirtualFb_Checked">
<TextBlock Text="&#xE7FC;" FontFamily="Segoe MDL2 Assets" FontSize="20"
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=RadioButton}}"/>
</RadioButton>
<RadioButton x:Name="navSettings" Style="{StaticResource NavBtn}" <RadioButton x:Name="navSettings" Style="{StaticResource NavBtn}"
ToolTip="Impostazioni" ToolTip="Impostazioni"
Checked="navSettings_Checked"> Checked="navSettings_Checked">
@@ -529,6 +536,126 @@
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>
<!-- ==== PAGE: VIRTUAL FOOTBALL ==== -->
<Grid x:Name="pageVirtualFb" Margin="0" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="400"/>
<ColumnDefinition Width="360"/>
</Grid.ColumnDefinitions>
<!-- LEFT: WebBrowser -->
<Border Grid.Column="0" Background="#181825" Margin="8">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="8,8,8,4">
<Button x:Name="btnVfbNavigate" Content="Vai"
Style="{StaticResource AccentBtn}" Background="{StaticResource BrBlue}"
Margin="0,0,8,0" Click="btnVfbNavigate_Click"/>
<TextBox x:Name="txtVfbUrl" Style="{StaticResource FlatTb}"
Text="https://www.bet365.it/#/IP/B151"
Width="500" VerticalContentAlignment="Center"/>
<Button x:Name="btnVfbRefresh" Content="&#xE72C;"
FontFamily="Segoe MDL2 Assets" FontSize="14"
Style="{StaticResource AccentBtn}" Background="{StaticResource BrSurface2}"
Foreground="{StaticResource BrText}" Margin="8,0,0,0"
Click="btnVfbRefresh_Click" ToolTip="Aggiorna"/>
</StackPanel>
<wv2:WebView2 x:Name="wbVirtualFb" Margin="8,0,8,8"/>
</DockPanel>
</Border>
<!-- RIGHT: Results Panel -->
<Border Grid.Column="1" Background="#282A3A" CornerRadius="10" Margin="0,8,8,8" Padding="12">
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="Ultimi Risultati"
FontFamily="Segoe UI Semibold" FontSize="16"
Foreground="{StaticResource BrBlue}" Margin="0,0,0,8"/>
<!-- Add result form -->
<Border DockPanel.Dock="Top" Background="#313244" CornerRadius="8" Padding="10" Margin="0,0,0,8">
<StackPanel>
<TextBlock Text="Aggiungi Risultato" FontSize="13"
Foreground="{StaticResource BrSubtext0}" Margin="0,0,0,6"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="txtVfbHome" Style="{StaticResource FlatTb}"
Text="Casa" FontSize="12"/>
<TextBox x:Name="txtVfbHomeGoals" Grid.Column="1" Style="{StaticResource FlatTb}"
Text="0" FontSize="12" TextAlignment="Center" Margin="4,0"/>
<TextBlock Grid.Column="2" Text="-" Foreground="{StaticResource BrText}"
FontSize="14" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBox x:Name="txtVfbAwayGoals" Grid.Column="3" Style="{StaticResource FlatTb}"
Text="0" FontSize="12" TextAlignment="Center" Margin="4,0"/>
<TextBox x:Name="txtVfbAway" Grid.Column="4" Style="{StaticResource FlatTb}"
Text="Ospite" FontSize="12"/>
</Grid>
<Button x:Name="btnVfbAddResult" Content="Aggiungi"
Style="{StaticResource AccentBtn}" Background="{StaticResource BrBlue}"
HorizontalAlignment="Left" Margin="0,8,0,0"
Click="btnVfbAddResult_Click"/>
</StackPanel>
</Border>
<!-- Suggested bet -->
<Border DockPanel.Dock="Top" Background="#313244" CornerRadius="8" Padding="10" Margin="0,0,0,8">
<StackPanel>
<TextBlock Text="Puntata Consigliata" FontSize="13"
FontFamily="Segoe UI Semibold" Foreground="{StaticResource BrPeach}" Margin="0,0,0,4"/>
<TextBlock x:Name="lblVfbSuggestion" Text="Inserisci almeno 5 risultati"
FontSize="12" Foreground="{StaticResource BrText}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
<!-- Stats -->
<Border DockPanel.Dock="Top" Background="#313244" CornerRadius="8" Padding="10" Margin="0,0,0,8">
<StackPanel>
<TextBlock Text="Statistiche" FontSize="13"
FontFamily="Segoe UI Semibold" Foreground="{StaticResource BrLavender}" Margin="0,0,0,4"/>
<TextBlock x:Name="lblVfbStats" Text="Nessun dato"
FontSize="12" Foreground="{StaticResource BrText}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
<!-- Results list -->
<ListBox x:Name="lbVfbResults" Background="Transparent" BorderThickness="0"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Border CornerRadius="6" Padding="10,6" Margin="0,2"
Background="{Binding RowColor}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Time}"
FontSize="11" Foreground="#A6ADC8"
VerticalAlignment="Center" Margin="0,0,8,0"/>
<TextBlock Grid.Column="1" FontSize="12" VerticalAlignment="Center">
<Run Text="{Binding Home, Mode=OneWay}" Foreground="#CDD6F4"/>
<Run Text=" "/>
<Run Text="{Binding Score, Mode=OneWay}" Foreground="White" FontFamily="Segoe UI Semibold"/>
<Run Text=" "/>
<Run Text="{Binding Away, Mode=OneWay}" Foreground="#CDD6F4"/>
</TextBlock>
<TextBlock Grid.Column="2" Text="{Binding Outcome}"
FontSize="12" FontFamily="Segoe UI Semibold"
Foreground="White" VerticalAlignment="Center" Margin="8,0,0,0"/>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Border>
</Grid>
<!-- Info page removed --> <!-- Info page removed -->
</Grid> </Grid>

View File

@@ -7,7 +7,9 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Collections.ObjectModel;
using System.Windows.Controls; using System.Windows.Controls;
using Microsoft.Web.WebView2.Core;
namespace HorseRacingPredictor namespace HorseRacingPredictor
{ {
@@ -18,6 +20,9 @@ namespace HorseRacingPredictor
private DataTable _footballData; private DataTable _footballData;
private DataTable _racingData; private DataTable _racingData;
// Virtual Football
private readonly ObservableCollection<VirtualFootball.VirtualMatch> _vfbResults = new ObservableCollection<VirtualFootball.VirtualMatch>();
private const string DefaultRacingUser = "qi1mHOHPquDY9KNDASAeGipy"; private const string DefaultRacingUser = "qi1mHOHPquDY9KNDASAeGipy";
private const string DefaultRacingPass = "RXNFU1YX27R9rTnk8Vop8ZfH"; private const string DefaultRacingPass = "RXNFU1YX27R9rTnk8Vop8ZfH";
@@ -180,6 +185,7 @@ namespace HorseRacingPredictor
if (pageFootball != null) pageFootball.Visibility = name == "football" ? Visibility.Visible : Visibility.Collapsed; if (pageFootball != null) pageFootball.Visibility = name == "football" ? Visibility.Visible : Visibility.Collapsed;
if (pageRacing != null) pageRacing.Visibility = name == "racing" ? Visibility.Visible : Visibility.Collapsed; if (pageRacing != null) pageRacing.Visibility = name == "racing" ? Visibility.Visible : Visibility.Collapsed;
if (pageSettings != null) pageSettings.Visibility = name == "settings" ? Visibility.Visible : Visibility.Collapsed; if (pageSettings != null) pageSettings.Visibility = name == "settings" ? Visibility.Visible : Visibility.Collapsed;
if (pageVirtualFb != null) pageVirtualFb.Visibility = name == "virtualfb" ? Visibility.Visible : Visibility.Collapsed;
// Update title if available // Update title if available
if (lblTitle != null) if (lblTitle != null)
@@ -189,6 +195,7 @@ namespace HorseRacingPredictor
case "football": lblTitle.Text = "Calcio"; break; case "football": lblTitle.Text = "Calcio"; break;
case "racing": lblTitle.Text = "Corse Cavalli"; break; case "racing": lblTitle.Text = "Corse Cavalli"; break;
case "settings": lblTitle.Text = "Impostazioni"; break; case "settings": lblTitle.Text = "Impostazioni"; break;
case "virtualfb": lblTitle.Text = "Calcio Virtuale"; break;
} }
} }
} }
@@ -196,6 +203,55 @@ namespace HorseRacingPredictor
private void navFootball_Checked(object sender, RoutedEventArgs e) => ShowPage("football"); private void navFootball_Checked(object sender, RoutedEventArgs e) => ShowPage("football");
private void navRacing_Checked(object sender, RoutedEventArgs e) => ShowPage("racing"); private void navRacing_Checked(object sender, RoutedEventArgs e) => ShowPage("racing");
private void navSettings_Checked(object sender, RoutedEventArgs e) => ShowPage("settings"); private void navSettings_Checked(object sender, RoutedEventArgs e) => ShowPage("settings");
private bool _vfbInitialized;
private async void navVirtualFb_Checked(object sender, RoutedEventArgs e)
{
ShowPage("virtualfb");
// Bind results list once
if (lbVfbResults.ItemsSource == null)
lbVfbResults.ItemsSource = _vfbResults;
if (!_vfbInitialized)
{
_vfbInitialized = true;
try
{
// Persistent user-data folder so cookies, localStorage and session survive
var userDataFolder = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"BettingPredictor", "WebView2Data");
var env = await CoreWebView2Environment.CreateAsync(
browserExecutableFolder: null,
userDataFolder: userDataFolder,
options: new CoreWebView2EnvironmentOptions());
await wbVirtualFb.EnsureCoreWebView2Async(env);
// Match the real Chrome User-Agent from the HAR capture
wbVirtualFb.CoreWebView2.Settings.UserAgent =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
"(KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36";
// Allow everything the SPA needs
wbVirtualFb.CoreWebView2.Settings.IsScriptEnabled = true;
wbVirtualFb.CoreWebView2.Settings.IsWebMessageEnabled = true;
wbVirtualFb.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = true;
wbVirtualFb.CoreWebView2.Settings.IsStatusBarEnabled = false;
wbVirtualFb.CoreWebView2.Navigate(txtVfbUrl.Text);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"[VFB] WebView2 init error: {ex.Message}");
MessageBox.Show(
$"Impossibile inizializzare WebView2.\n\n" +
$"Assicurati che il Microsoft Edge WebView2 Runtime sia installato.\n\n{ex.Message}",
"Errore WebView2", MessageBoxButton.OK, MessageBoxImage.Warning);
_vfbInitialized = false;
}
}
}
// ???????????????????? FOOTBALL ???????????????????? // ???????????????????? FOOTBALL ????????????????????
@@ -945,5 +1001,114 @@ namespace HorseRacingPredictor
"Errore", MessageBoxButton.OK, MessageBoxImage.Error); "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
// ???????????????????????? VIRTUAL FOOTBALL ????????????????????????
private void btnVfbNavigate_Click(object sender, RoutedEventArgs e)
{
try
{
var url = txtVfbUrl.Text?.Trim();
if (!string.IsNullOrEmpty(url) && wbVirtualFb.CoreWebView2 != null)
wbVirtualFb.CoreWebView2.Navigate(url);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"[VFB] Navigate error: {ex.Message}");
}
}
private void btnVfbRefresh_Click(object sender, RoutedEventArgs e)
{
try { wbVirtualFb.CoreWebView2?.Reload(); }
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"[VFB] Refresh error: {ex.Message}");
}
}
private void btnVfbAddResult_Click(object sender, RoutedEventArgs e)
{
if (!int.TryParse(txtVfbHomeGoals.Text, out int hg)) hg = 0;
if (!int.TryParse(txtVfbAwayGoals.Text, out int ag)) ag = 0;
var match = new VirtualFootball.VirtualMatch
{
Time = DateTime.Now.ToString("HH:mm"),
Home = string.IsNullOrWhiteSpace(txtVfbHome.Text) ? "Casa" : txtVfbHome.Text.Trim(),
HomeGoals = hg,
AwayGoals = ag,
Away = string.IsNullOrWhiteSpace(txtVfbAway.Text) ? "Ospite" : txtVfbAway.Text.Trim()
};
_vfbResults.Insert(0, match);
// Reset input
txtVfbHomeGoals.Text = "0";
txtVfbAwayGoals.Text = "0";
UpdateVfbStats();
UpdateVfbSuggestion();
}
private void UpdateVfbStats()
{
if (_vfbResults.Count == 0) { lblVfbStats.Text = "Nessun dato"; return; }
int total = _vfbResults.Count;
int draws = _vfbResults.Count(m => m.Outcome == "X");
int home = _vfbResults.Count(m => m.Outcome == "1");
int away = _vfbResults.Count(m => m.Outcome == "2");
double drawPct = (double)draws / total * 100;
double homePct = (double)home / total * 100;
double awayPct = (double)away / total * 100;
int totalGoals = _vfbResults.Sum(m => m.HomeGoals + m.AwayGoals);
double avgGoals = (double)totalGoals / total;
int over25 = _vfbResults.Count(m => m.HomeGoals + m.AwayGoals > 2);
lblVfbStats.Text = $"Partite: {total}\n" +
$"1: {home} ({homePct:F1}%) X: {draws} ({drawPct:F1}%) 2: {away} ({awayPct:F1}%)\n" +
$"Media gol: {avgGoals:F1} Over 2.5: {over25} ({(double)over25 / total * 100:F1}%)";
}
private void UpdateVfbSuggestion()
{
if (_vfbResults.Count < 5)
{
lblVfbSuggestion.Text = "Inserisci almeno 5 risultati";
return;
}
// Count consecutive non-draw results (most recent first)
int streak = 0;
foreach (var m in _vfbResults)
{
if (m.Outcome != "X") streak++;
else break;
}
// Simple strategy: after a long streak without draws, suggest betting on draw
if (streak >= 8)
{
lblVfbSuggestion.Text = $"\u26A0 PUNTA X (pareggio) \u2014 {streak} partite consecutive senza pareggio!\n" +
"Puntata alta consigliata.";
}
else if (streak >= 5)
{
lblVfbSuggestion.Text = $"\u2705 Punta X (pareggio) \u2014 {streak} partite senza pareggio.\n" +
"Puntata media consigliata.";
}
else if (streak >= 3)
{
lblVfbSuggestion.Text = $"\u23F3 Possibile X \u2014 {streak} partite senza pareggio.\n" +
"Puntata bassa o attendi.";
}
else
{
double drawPct = (double)_vfbResults.Count(m => m.Outcome == "X") / _vfbResults.Count * 100;
lblVfbSuggestion.Text = $"Pareggio recente \u2014 attendi una serie senza X.\n" +
$"Frequenza X attuale: {drawPct:F1}%";
}
}
} }
} }

View File

@@ -0,0 +1,30 @@
namespace HorseRacingPredictor.VirtualFootball
{
/// <summary>
/// Represents a single virtual football match result displayed in the results panel.
/// </summary>
public class VirtualMatch
{
public string Time { get; set; }
public string Home { get; set; }
public int HomeGoals { get; set; }
public int AwayGoals { get; set; }
public string Away { get; set; }
public string Score => $"{HomeGoals} - {AwayGoals}";
/// <summary>1, X, or 2</summary>
public string Outcome
{
get
{
if (HomeGoals > AwayGoals) return "1";
if (HomeGoals < AwayGoals) return "2";
return "X";
}
}
/// <summary>Row background colour: green for draw, red for 1/2.</summary>
public string RowColor => Outcome == "X" ? "#2A4A3A" : "#4A2A2A";
}
}

View File

@@ -9,6 +9,7 @@
<package id="Microsoft.ML.CpuMath" version="5.0.0-preview.25503.2" targetFramework="net481" /> <package id="Microsoft.ML.CpuMath" version="5.0.0-preview.25503.2" targetFramework="net481" />
<package id="Microsoft.ML.DataView" version="5.0.0-preview.25503.2" targetFramework="net481" /> <package id="Microsoft.ML.DataView" version="5.0.0-preview.25503.2" targetFramework="net481" />
<package id="Microsoft.ML.FastTree" version="5.0.0-preview.25503.2" targetFramework="net481" /> <package id="Microsoft.ML.FastTree" version="5.0.0-preview.25503.2" targetFramework="net481" />
<package id="Microsoft.Web.WebView2" version="1.0.3800.47" targetFramework="net481" />
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net481" /> <package id="Newtonsoft.Json" version="13.0.4" targetFramework="net481" />
<package id="RestSharp" version="112.1.1-alpha.0.4" targetFramework="net481" /> <package id="RestSharp" version="112.1.1-alpha.0.4" targetFramework="net481" />
<package id="System.Buffers" version="4.6.1" targetFramework="net481" /> <package id="System.Buffers" version="4.6.1" targetFramework="net481" />

Binary file not shown.