Skip to content
This repository was archived by the owner on Jul 31, 2022. It is now read-only.

Commit b7267f9

Browse files
committed
Ajoutez des fichiers projet.
1 parent fb96c62 commit b7267f9

File tree

10 files changed

+456
-0
lines changed

10 files changed

+456
-0
lines changed

Pokédex.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.1.32228.430
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pokédex", "Pokédex\Pokédex.csproj", "{51DB0337-3C9F-4AB8-8382-DFF3AA2642C7}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{51DB0337-3C9F-4AB8-8382-DFF3AA2642C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{51DB0337-3C9F-4AB8-8382-DFF3AA2642C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{51DB0337-3C9F-4AB8-8382-DFF3AA2642C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{51DB0337-3C9F-4AB8-8382-DFF3AA2642C7}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {A49E3452-2138-4711-A977-40C1D9269869}
24+
EndGlobalSection
25+
EndGlobal

Pokédex/Actions.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
namespace Pokédex
2+
{
3+
internal class Actions
4+
{
5+
#region Constructors
6+
public Actions(Pokedex pokedex)
7+
{
8+
this.pokedex = pokedex;
9+
}
10+
#endregion
11+
12+
#region Variables
13+
Pokedex pokedex;
14+
#endregion
15+
16+
17+
#region Methods
18+
/// <summary>
19+
/// Affiche la liste des Pokémons
20+
/// </summary>
21+
public void AfficherListePokemons()
22+
{
23+
Console.WriteLine("Liste de tout les Pokémons :");
24+
25+
foreach (var pokemon in pokedex.Pokemons)
26+
Console.Write($"{pokemon.Id} - {pokemon.Name?["fr"]}, ");
27+
28+
Console.WriteLine(Environment.NewLine);
29+
}
30+
31+
/// <summary>
32+
/// Affiche un Pokémon
33+
/// </summary>
34+
/// <param name="id">L'id du Pokémon</param>
35+
public void AfficherPokemon(int id)
36+
{
37+
var pokemon = pokedex[id]; // Récupère le Pokémon par son id
38+
39+
Console.Write("Pokémon : ");
40+
41+
if (pokemon == null)
42+
Console.Write("Ce Pokémon existe pas");
43+
else
44+
Console.Write($"{pokemon.Id} - {pokemon.Name?["fr"]}");
45+
46+
Console.WriteLine(Environment.NewLine);
47+
}
48+
49+
/// <summary>
50+
/// Affiche un Pokémon de type donnés
51+
/// </summary>
52+
/// <param name="type">Le type du Pokémon</param>
53+
public void AfficherPokemonsDeType(string type)
54+
{
55+
var pokemons = pokedex.Pokemons.Where(x => x.Types != null && x.Types.Contains(type)); // Récupère les Pokémon de type donnés
56+
57+
Console.WriteLine($"Liste de tout les Pokémons de type {type} :");
58+
59+
foreach (var pokemon in pokemons)
60+
Console.Write($"{pokemon.Id} - {pokemon.Name?["fr"]}, ");
61+
62+
Console.WriteLine(Environment.NewLine);
63+
}
64+
65+
/// <summary>
66+
/// Affiche des Pokémon de génération donnés
67+
/// </summary>
68+
/// <param name="generation">La généartion du Pokémon</param>
69+
public void AfficherPokemonsDeGeneration(int generation)
70+
{
71+
var pokemons = pokedex.Pokemons.Where(x => x.GetGeneration() == generation); // Récupère les Pokémon de génération donnés
72+
73+
Console.WriteLine($"Liste de tout les Pokémons de génération {generation} :");
74+
75+
foreach (var pokemon in pokemons)
76+
Console.Write($"{pokemon.Id} - {pokemon.Name?["fr"]}, ");
77+
78+
Console.WriteLine(Environment.NewLine);
79+
}
80+
81+
/// <summary>
82+
/// Affiche la moyenne des poids des Pokémon de type Acier
83+
/// </summary>
84+
public void AfficherMoyennePoidsPokemonsDeTypeAcier()
85+
{
86+
var pokemonsAcier = pokedex.Pokemons.Where(x => x.Types != null && x.Types.Contains("Steel")); // Récupère les Pokémon de type Acier
87+
var poidsMoyen = pokemonsAcier.Average(x => x.Weight); // Fait la moyenne
88+
89+
Console.WriteLine($"Le poids moyen des Pokémon de type Acier est de {poidsMoyen:00.00}");
90+
}
91+
#endregion
92+
}
93+
}

Pokédex/AppPath.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace Pokédex
2+
{
3+
public static class AppPath
4+
{
5+
#region Methods
6+
/// <summary>
7+
/// Get the full path of a file inside the app directory
8+
/// </summary>
9+
/// <param name="FileName">Relative path</param>
10+
/// <returns>The full path</returns>
11+
public static string GetFullPath(string FileName)
12+
{
13+
string exeFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
14+
string? workPath = Path.GetDirectoryName(exeFilePath);
15+
string relativePath = Path.Combine(workPath + FileName);
16+
string path = Path.GetFullPath(relativePath);
17+
18+
return path;
19+
}
20+
#endregion
21+
}
22+
}

Pokédex/Pokedex.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System.Diagnostics;
2+
using System.Text.Json;
3+
4+
namespace Pokédex
5+
{
6+
[Serializable]
7+
public class Pokedex
8+
{
9+
#region Constructors
10+
public Pokedex(List<Pokemon> pokemons)
11+
{
12+
this.pokemons = pokemons;
13+
}
14+
#endregion
15+
16+
#region Variables
17+
private readonly List<Pokemon> pokemons;
18+
#endregion
19+
20+
#region Properties
21+
public List<Pokemon> Pokemons => pokemons;
22+
#endregion
23+
24+
#region Methods
25+
/// <summary>
26+
/// Parse a json full of <see cref="Pokemon"/> into a <see cref="Pokedex"/>.
27+
/// </summary>
28+
/// <param name="json">Json string to parse</param>
29+
/// <returns>Return a <see cref="Pokedex"/>, is empty if an error occurred.</returns>
30+
public static Pokedex ParsePokemons(string json)
31+
{
32+
Pokemon[]? pokemons = null;
33+
34+
try
35+
{ pokemons = JsonSerializer.Deserialize<Pokemon[]>(json); }
36+
catch (Exception ex)
37+
{ Debug.WriteLine(ex); }
38+
39+
return pokemons == null ? new Pokedex(new List<Pokemon>()) : new Pokedex(pokemons.ToList());
40+
}
41+
42+
/// <summary>
43+
/// Get a <see cref="Pokemon"/> by name.
44+
/// </summary>
45+
/// <param name="name"><see cref="Pokemon"/> name</param>
46+
/// <returns>Return a <see cref="Pokemon"/></returns>
47+
public Pokemon? this[string name] => pokemons.FirstOrDefault(x => x.Name != null && x.Name.ContainsValue(name));
48+
49+
/// <summary>
50+
/// Get a <see cref="Pokemon"/> by id.
51+
/// </summary>
52+
/// <param name="id"><see cref="Pokemon"/> id</param>
53+
/// <returns>Return a <see cref="Pokemon"/></returns>
54+
public Pokemon? this[int id] => pokemons.FirstOrDefault(x => x.Id == id);
55+
#endregion
56+
}
57+
}

Pokédex/Pokemon.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Pokédex
4+
{
5+
[Serializable]
6+
public class Pokemon
7+
{
8+
#region Properties
9+
[JsonPropertyName("id")] public int Id { get; set; }
10+
[JsonPropertyName("name")] public Dictionary<string, string>? Name { get; set; }
11+
[JsonPropertyName("types")] public string[]? Types { get; set; }
12+
[JsonPropertyName("height")] public int Height { get; set; }
13+
[JsonPropertyName("weight")] public int Weight { get; set; }
14+
[JsonPropertyName("genus")] public Dictionary<string, string>? Genus { get; set; }
15+
[JsonPropertyName("description")] public Dictionary<string, string>? Description { get; set; }
16+
[JsonPropertyName("stats")] public PokemonStat[]? Stats { get; set; }
17+
[JsonPropertyName("lastEdit")] public long LastEdit { get; set; }
18+
#endregion
19+
20+
#region Methods
21+
public int GetGeneration()
22+
{
23+
if (Id is >= 1 and <= 151)
24+
return 1;
25+
else if (Id is >= 152 and <= 251)
26+
return 2;
27+
else if (Id is >= 252 and <= 386)
28+
return 3;
29+
else if (Id is >= 387 and <= 493)
30+
return 4;
31+
else if (Id is >= 494 and <= 649)
32+
return 5;
33+
else if (Id is >= 650 and <= 721)
34+
return 6;
35+
else if (Id is >= 722 and <= 802)
36+
return 7;
37+
else if (Id is >= 802 and <= 898)
38+
return 8;
39+
else return 0;
40+
41+
#endregion
42+
}
43+
}
44+
}

Pokédex/PokemonCache.cs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
using System.Diagnostics;
2+
using System.Text.Json;
3+
4+
namespace Pokédex
5+
{
6+
public static class PokemonCache
7+
{
8+
#region Variables
9+
private readonly static string PokemonsPath = AppPath.GetFullPath(@"/Pokedex.json");
10+
private const string PokemonsUri = "https://tmare.ndelpech.fr/tps/pokemons";
11+
#endregion
12+
13+
#region Methods
14+
/// <summary>
15+
/// Get the list of cached Pokémon
16+
/// </summary>
17+
/// <returns>Returns the list of Pokémon in cache or null if the cache does not exist</returns>
18+
public static Pokedex? GetPokedex()
19+
{
20+
// Check if the pokemon entries have been cached
21+
if (File.Exists(PokemonsPath))
22+
{
23+
string pokemonsJson = File.ReadAllText(PokemonsPath);
24+
25+
return Pokedex.ParsePokemons(pokemonsJson);
26+
}
27+
return null;
28+
}
29+
30+
/// <summary>
31+
/// Download or update cached Pokemon list
32+
/// </summary>
33+
public static async Task RefreshCaches()
34+
{
35+
using HttpClient httpClient = new();
36+
string pokemonEntriesJson = await httpClient.GetStringAsync(PokemonsUri);
37+
38+
// Load the cached pokemon entries
39+
var cachedPokedex = GetPokedex();
40+
PokemonEntry[]? pokemonEntries;
41+
42+
try
43+
{ pokemonEntries = JsonSerializer.Deserialize<PokemonEntry[]>(pokemonEntriesJson); }
44+
catch (Exception ex)
45+
{
46+
Console.WriteLine(ex.Message);
47+
Debug.WriteLine(ex);
48+
return;
49+
}
50+
51+
if (pokemonEntries != null)
52+
{
53+
List<Pokemon> pokemonList = new();
54+
55+
// Asynchronously download Pokémon by generation
56+
Task<ICollection<Pokemon>>[] tasksList = new[]
57+
{
58+
UpdatePokemons(httpClient, cachedPokedex, pokemonEntries[0..150]), // Gen 1
59+
UpdatePokemons(httpClient, cachedPokedex, pokemonEntries[151..250]), // Gen 2
60+
UpdatePokemons(httpClient, cachedPokedex, pokemonEntries[251..385]), // Gen 3
61+
UpdatePokemons(httpClient, cachedPokedex, pokemonEntries[386..492]), // Gen 4
62+
UpdatePokemons(httpClient, cachedPokedex, pokemonEntries[493..648]), // Gen 5
63+
UpdatePokemons(httpClient, cachedPokedex, pokemonEntries[649..720]), // Gen 6
64+
UpdatePokemons(httpClient, cachedPokedex, pokemonEntries[721..801]), // Gen 7
65+
UpdatePokemons(httpClient, cachedPokedex, pokemonEntries[802..897]), // Gen 8
66+
};
67+
68+
// Wait for all downloads to complete
69+
var results = await Task.WhenAll(tasksList);
70+
71+
// Merge all Pokémon
72+
foreach (var result in results)
73+
pokemonList.AddRange(result);
74+
75+
// Save the updated cache is needed
76+
if (pokemonList.Count != 0)
77+
{
78+
#if DEBUG // Make the json is human readable for debugging
79+
var options = new JsonSerializerOptions { WriteIndented = true };
80+
#else // Make the json is compact for saving space
81+
var options = new JsonSerializerOptions { WriteIndented = false };
82+
#endif
83+
var pokemonsJson = JsonSerializer.Serialize(pokemonList, options);
84+
85+
File.WriteAllText(PokemonsPath, pokemonsJson);
86+
}
87+
}
88+
89+
}
90+
91+
/// <summary>
92+
/// Download Pokémons if they doesn't exist in the cache or are expired
93+
/// </summary>
94+
/// <param name="httpClient">HttpClient</param>
95+
/// <param name="cachedPokedex">Cached Pokedex</param>
96+
/// <param name="pokemonEntries">The Pokémons to download</param>
97+
/// <returns>Returns a list of Pokémon that doesn't exist in the cache or are obsolete</returns>
98+
private static async Task<ICollection<Pokemon>> UpdatePokemons(HttpClient httpClient, Pokedex? cachedPokedex, PokemonEntry[] pokemonEntries)
99+
{
100+
List<Pokemon> pokemonList = new();
101+
Pokemon? pokemon;
102+
103+
// Cycle through all Pokémon entries
104+
foreach (var pokemonEntry in pokemonEntries)
105+
{
106+
// Get the updated Pokémon
107+
pokemon = await UpdatePokemon(httpClient, cachedPokedex, pokemonEntry);
108+
109+
// Add if newer
110+
if (pokemon != null)
111+
pokemonList.Add(pokemon);
112+
}
113+
114+
// Returns the newest Pokémon
115+
return pokemonList;
116+
}
117+
118+
/// <summary>
119+
/// Download a Pokémon if it doesn't exist in the cache or is out-of-date
120+
/// </summary>
121+
/// <param name="httpClient">HttpClient</param>
122+
/// <param name="cachedPokedex">Cached Pokedex</param>
123+
/// <param name="pokemonEntry">The Pokémon to download</param>
124+
/// <returns>Return Pokémon if it doesn't exist in the cache or is out-of-date, otherwise returns null</returns>
125+
private static async Task<Pokemon?> UpdatePokemon(HttpClient httpClient, Pokedex? cachedPokedex, PokemonEntry pokemonEntry)
126+
{
127+
Pokemon? pokemon = null;
128+
129+
// If the Pokémon in cache is the same on the API side, we reuse it
130+
if (cachedPokedex != null && pokemonEntry.LastEdit == cachedPokedex[pokemonEntry.Id]?.LastEdit)
131+
pokemon = cachedPokedex[pokemonEntry.Id];
132+
// If the Pokémon is outdated we download the new one
133+
else
134+
{
135+
// Get the Pokémon
136+
string pokemonJson = await httpClient.GetStringAsync(pokemonEntry.Url);
137+
138+
// Parse it
139+
try
140+
{ pokemon = JsonSerializer.Deserialize<Pokemon>(pokemonJson); }
141+
catch (Exception ex)
142+
{ Debug.WriteLine(ex); }
143+
finally { }
144+
}
145+
146+
return pokemon;
147+
}
148+
#endregion
149+
}
150+
}

0 commit comments

Comments
 (0)