diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..069d557 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,71 @@ +kind: pipeline +type: docker +name: CI + +trigger: + when: + branch: + - master + - dev + - CI/CD + event: + - push + +steps: + - name: build-Models + image: mcr.microsoft.com/dotnet/sdk:8.0 + commands: + - cd source/Trek-12/Models + - dotnet restore + - dotnet build -c Release --no-restore + - dotnet publish -c Release --no-restore -o $CI_PROJECT_DIR/build/release + + - name: build-ConsoleApp + image: mcr.microsoft.com/dotnet/sdk:8.0 + commands: + - cd source/Trek-12/ConsoleApp + - dotnet restore + - dotnet build -c Release --no-restore + - dotnet publish -c Release --no-restore -o $CI_PROJECT_DIR/build/release + depends_on: [build-Models] + + - name: tests + image: mcr.microsoft.com/dotnet/sdk:8.0 + commands: + - cd source/Trek-12 + - dotnet restore CI-Trek-12.sln + - dotnet test CI-Trek-12.sln --no-restore + depends_on: [build-Models] + + - name: code-analysis + image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dronesonarplugin-dotnet8 + secrets: [ SECRET_SONAR_LOGIN ] + settings: + # accessible en ligne de commande par ${PLUGIN_SONAR_HOST} + sonar_host: https://codefirst.iut.uca.fr/sonar/ + # accessible en ligne de commande par ${PLUGIN_SONAR_TOKEN} + sonar_token: + from_secret: SECRET_SONAR_LOGIN + commands: + - cd source/Trek-12 + - dotnet restore CI-Trek-12.sln + - dotnet sonarscanner begin /k:"Trek-12" /d:sonar.host.url=$${PLUGIN_SONAR_HOST} /d:sonar.coverageReportPaths="coveragereport/SonarQube.xml" /d:sonar.coverage.exclusions="Tests/**" /d:sonar.login=$${PLUGIN_SONAR_TOKEN} + - dotnet build CI-Trek-12.sln -c Release --no-restore + - dotnet test CI-Trek-12.sln --logger trx --no-restore /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura --collect "XPlat Code Coverage" + - reportgenerator -reports:"**/coverage.cobertura.xml" -reporttypes:SonarQube -targetdir:"coveragereport" + - dotnet publish CI-Trek-12.sln -c Release --no-restore -o $CI_PROJECT_DIR/build/release + - dotnet sonarscanner end /d:sonar.login=$${PLUGIN_SONAR_TOKEN} + depends_on: [tests] + + - name: generate-and-deploy-docs + image: hub.codefirst.iut.uca.fr/maxime.batista/codefirst-docdeployer:latest + failure: ignore + commands: + - /entrypoint.sh -l documentation/doxygen -t doxygen + when: + branch: + - master + - dev + event: + - push + depends_on: [ tests ] diff --git a/README.md b/README.md index 7779a13..8aad201 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,21 @@ ![Static Badge](https://img.shields.io/badge/Trek12-En_Production-red) +
+ Sonarcube Ratings + + [![Maintainability Rating](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Trek-12&metric=sqale_rating&token=7584294f89189be7a1ed771405ce4114938dca12)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Trek-12) +[![Reliability Rating](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Trek-12&metric=reliability_rating&token=7584294f89189be7a1ed771405ce4114938dca12)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Trek-12) +[![Security Rating](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Trek-12&metric=security_rating&token=7584294f89189be7a1ed771405ce4114938dca12)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Trek-12) +
+ +[![Build Status](https://codefirst.iut.uca.fr/api/badges/remi.lavergne/Trek-12/status.svg)](https://codefirst.iut.uca.fr/remi.lavergne/Trek-12) +[![Quality Gate Status](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Trek-12&metric=alert_status&token=7584294f89189be7a1ed771405ce4114938dca12)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Trek-12) +[![Bugs](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Trek-12&metric=bugs&token=7584294f89189be7a1ed771405ce4114938dca12)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Trek-12) +[![Coverage](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Trek-12&metric=coverage&token=7584294f89189be7a1ed771405ce4114938dca12)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Trek-12) +[![Vulnerabilities](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Trek-12&metric=vulnerabilities&token=7584294f89189be7a1ed771405ce4114938dca12)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Trek-12) + + + Trek12
diff --git a/documentation/doxygen/Doxyfile b/documentation/doxygen/Doxyfile new file mode 100644 index 0000000..d3d4895 --- /dev/null +++ b/documentation/doxygen/Doxyfile @@ -0,0 +1,428 @@ +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "Trek 12" +PROJECT_NUMBER = 1.0.0 +PROJECT_BRIEF = "Application de jeu plateau en roll & write sur le framework .NET MAUI avec XAML et C#" +PROJECT_LOGO = /trek12.png +OUTPUT_DIRECTORY = /documentation/doxygen +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = French +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +JAVADOC_BANNER = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +PYTHON_DOCSTRING = YES +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +# Well... the one for Java looks so similar to the one for C#... +OPTIMIZE_OUTPUT_JAVA = YES +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +OPTIMIZE_OUTPUT_SLICE = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +TOC_INCLUDE_HEADINGS = 5 +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +NUM_PROC_THREADS = 1 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +EXTRACT_ALL = YES +# I do not like other members to see my private members... but you can set it to YES if you prefer. +EXTRACT_PRIVATE = NO +EXTRACT_PRIV_VIRTUAL = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +RESOLVE_UNNAMED_PARAMS = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_HEADERFILE = YES +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_IF_INCOMPLETE_DOC = YES +WARN_NO_PARAMDOC = NO +WARN_AS_ERROR = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +INPUT = source +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.l \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f18 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = */Tests/* +EXCLUDE_PATTERNS += */bin/* +EXCLUDE_PATTERNS += */obj/* +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +CLANG_ASSISTED_PARSING = NO +CLANG_ADD_INC_PATHS = YES +CLANG_OPTIONS = +CLANG_DATABASE_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +ALPHABETICAL_INDEX = YES +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = images/CodeFirst.png images/clubinfo.png +HTML_COLORSTYLE_HUE = 215 +HTML_COLORSTYLE_SAT = 45 +HTML_COLORSTYLE_GAMMA = 240 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_MENUS = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_FEEDURL = +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +FULL_SIDEBAR = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +OBFUSCATE_EMAILS = YES +HTML_FORMULA_FORMAT = png +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = +USE_MATHJAX = NO +MATHJAX_VERSION = MathJax_2 +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = +MAKEINDEX_CMD_NAME = makeindex +LATEX_MAKEINDEX_CMD = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_BIB_STYLE = plain +LATEX_TIMESTAMP = NO +LATEX_EMOJI_DIRECTORY = + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +GENERATE_XML = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +XML_NS_MEMB_FILE_SCOPE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to Sqlite3 output +#--------------------------------------------------------------------------- + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +DIA_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +DOT_UML_DETAILS = NO +DOT_WRAP_THRESHOLD = 17 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DIR_GRAPH_MAX_DEPTH = 1 +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_CFG_FILE = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES \ No newline at end of file diff --git a/source/Trek-12/CI-Trek-12.sln b/source/Trek-12/CI-Trek-12.sln new file mode 100644 index 0000000..cf5f81d --- /dev/null +++ b/source/Trek-12/CI-Trek-12.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34408.163 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models", "Models\Models.csproj", "{807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{383C4215-C680-4C2E-BC7E-B62F0B164370}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}.Release|Any CPU.Build.0 = Release|Any CPU + {383C4215-C680-4C2E-BC7E-B62F0B164370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {383C4215-C680-4C2E-BC7E-B62F0B164370}.Debug|Any CPU.Build.0 = Debug|Any CPU + {383C4215-C680-4C2E-BC7E-B62F0B164370}.Release|Any CPU.ActiveCfg = Release|Any CPU + {383C4215-C680-4C2E-BC7E-B62F0B164370}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {50EAA59B-6857-44DC-86B9-E8D258C0DC86} + EndGlobalSection +EndGlobal diff --git a/source/Trek-12/ConsoleApp/ConsoleApp.csproj b/source/Trek-12/ConsoleApp/ConsoleApp.csproj new file mode 100644 index 0000000..229387b --- /dev/null +++ b/source/Trek-12/ConsoleApp/ConsoleApp.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + diff --git a/source/Trek-12/ConsoleApp/Program.cs b/source/Trek-12/ConsoleApp/Program.cs new file mode 100644 index 0000000..117e7cb --- /dev/null +++ b/source/Trek-12/ConsoleApp/Program.cs @@ -0,0 +1,246 @@ +// See https://aka.ms/new-console-template for more information + +using Models; +using Models.Events; +using Models.Exceptions; +using Models.Game; + +namespace ConsoleApp; + +class Program +{ + /// + /// Main function of the console app + /// + /// + static void Main(string[] args) + { + Console.WriteLine("Enter your pseudo:"); + string? pseudo = Console.ReadLine(); + if (pseudo != null) + { + Player player = new Player(pseudo); + + Map map = new Map("background"); + Game game = new Game(player, map); + + // Abonnement aux événements + game.GameStarted += OnGameStarted!; + game.GameEnded += OnGameEnded!; + game.BoardUpdated += OnBoardUpdated!; + game.DiceRolled += OnDiceRolled!; + game.OperationChosen += OnOperationChosen!; + game.CellChosen += OnCellChosen!; + + // Initialisation + game.InitializeGame(); + } + } + + /// + /// Handles the event when the game has started. + /// + /// + /// + static void OnGameStarted(object sender, GameStartedEventArgs e) + { + Console.WriteLine($"The game has started! Player: {e.CurrentPlayer.Pseudo}"); + } + + /// + /// Handles the event when the game has ended. + /// + /// + /// + static void OnGameEnded(object sender, GameEndedEventArgs e) + { + Console.WriteLine($"The game has ended! Player: {e.CurrentPlayer.Pseudo}"); + } + + /// + /// Handles the event when the board is updated. + /// + /// + /// + static void OnBoardUpdated(object sender, EventArgs e) + { + DisplayBoard(((Game)sender).UsedMap); + DisplayOperationTable(((Game)sender).UsedMap.OperationGrid); + } + + /// + /// Handles the event when the dice are rolled. + /// + /// + /// + static void OnDiceRolled(object sender, DiceRolledEventArgs e) + { + Console.WriteLine($"Dice 1: {e.Dice1Value} | Dice 2: {e.Dice2Value}"); + Operation playerOperation = GetPlayerOperation(); + ((Game)sender).HandlePlayerOperation(playerOperation); + } + + /// + /// Handles the event when an operation is chosen by the player. + /// + /// + /// + static void OnOperationChosen(object sender, OperationChosenEventArgs e) + { + Console.WriteLine($"Operation: {e.Operation}, Result: {e.Result}"); + DisplayOperationTable(((Game)sender).UsedMap.OperationGrid); + Cell playerChoice = GetPlayerChoice(); + try + { + ((Game)sender).HandlePlayerChoice(playerChoice, e.Result); + } + catch (InvalidCellCoordinatesException err) + { + Console.WriteLine(err.Message); + playerChoice = GetPlayerChoice(); + ((Game)sender).HandlePlayerChoice(playerChoice, e.Result); + } + catch (InvalidCellException err) + { + Console.WriteLine(err.Message); + playerChoice = GetPlayerChoice(); + ((Game)sender).HandlePlayerChoice(playerChoice, e.Result); + } + } + + /// + /// Handles the event when a cell is chosen by the player. + /// + /// + /// + static void OnCellChosen(object sender, CellChosenEventArgs e) + { + Console.WriteLine($"Cell chosen: ({e.Cell.X}, {e.Cell.Y}) with result: {e.Result}"); + DisplayBoard(((Game)sender).UsedMap); + } + + /// + /// Displays the game board. + /// + /// Used map to display + static void DisplayBoard(Map map) + { + int cpt = 0; + for (int i = 0; i < map.Boards.Count; i++) + { + if (cpt % 6 == 0) + { + Console.Write("| "); + } + + if (map.Boards[i].Value.HasValue) + { + Console.Write(map.Boards[i].Value?.ToString().PadLeft(2)); + } + else + { + Console.Write(" O"); + } + + cpt++; + if (cpt % 6 == 0) + { + Console.Write(" |"); + Console.WriteLine(); + } + } + } + + /// + /// Displays the operation table. + /// + /// The operation table to display. + static void DisplayOperationTable(List operationTable) + { + Console.WriteLine("Operation Table:"); + string[] operations = { "Addition (+)", "Subtraction (-)", "Multiplication (*)", "Lower Dice (less)", "Higher Dice (high)" }; + + for (int i = 0; i < operations.Length; i++) + { + Console.Write(operations[i].PadRight(18)); + + for (int j = 0; j < 4; j++) + { + int index = i * 4 + j; + if (index < operationTable.Count) + { + string status = operationTable[index].IsChecked ? "X" : " "; + Console.Write($" | {status}"); + } + } + Console.WriteLine(); + } + } + + /// + /// Gets the cell chosen by the player. + /// + /// The cell chosen by the player. + static Cell GetPlayerChoice() + { + int row, column; + while (true) + { + Console.WriteLine("Enter the position of the cell you want to play"); + Console.WriteLine("Enter the row number (0-5)"); + if (!int.TryParse(Console.ReadLine(), out row) || row < 0 || row >= 6) + { + Console.WriteLine("Invalid row number. Please enter a number between 0 and 5."); + continue; + } + + Console.WriteLine("Enter the column number (0-5)"); + if (!int.TryParse(Console.ReadLine(), out column) || column < 0 || column >= 6) + { + Console.WriteLine("Invalid column number. Please enter a number between 0 and 5."); + continue; + } + + return new Cell(row, column); + } + } + + /// + /// Gets the operation chosen by the player. + /// + /// + /// + static Operation GetPlayerOperation() + { + DisplayOperationOptions(); + string? op = Console.ReadLine(); + while (op != "1" && op != "2" && op != "3" && op != "4" && op != "5") + { + Console.WriteLine("Invalid operation. Please choose again."); + op = Console.ReadLine(); + } + + return op switch + { + "1" => Operation.ADDITION, + "2" => Operation.SUBTRACTION, + "3" => Operation.MULTIPLICATION, + "4" => Operation.LOWER, + "5" => Operation.HIGHER, + _ => throw new ArgumentOutOfRangeException() + }; + } + + /// + /// Displays the operation options for the player to choose from. + /// + static void DisplayOperationOptions() + { + Console.WriteLine("Choose an operation:"); + Console.WriteLine("1: Addition (+)"); + Console.WriteLine("2: Subtraction (-)"); + Console.WriteLine("3: Multiplication (*)"); + Console.WriteLine("4: Lower Dice (less)"); + Console.WriteLine("5: Higher Dice (high)"); + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Events/CellChosenEventArgs.cs b/source/Trek-12/Models/Events/CellChosenEventArgs.cs new file mode 100644 index 0000000..9c2040c --- /dev/null +++ b/source/Trek-12/Models/Events/CellChosenEventArgs.cs @@ -0,0 +1,19 @@ +using Models.Game; + +namespace Models.Events +{ + /// + /// Event arguments for when a cell is chosen. + /// + public class CellChosenEventArgs : EventArgs + { + public Cell Cell { get; } + public int Result { get; } + + public CellChosenEventArgs(Cell cell, int result) + { + Cell = cell; + Result = result; + } + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Events/DiceRolledEventArgs.cs b/source/Trek-12/Models/Events/DiceRolledEventArgs.cs new file mode 100644 index 0000000..fd77f54 --- /dev/null +++ b/source/Trek-12/Models/Events/DiceRolledEventArgs.cs @@ -0,0 +1,19 @@ +using Models.Game; + +namespace Models.Events +{ + /// + /// Event arguments for when the dice are rolled. + /// + public class DiceRolledEventArgs : EventArgs + { + public int Dice1Value { get; } + public int Dice2Value { get; } + + public DiceRolledEventArgs(int dice1Value, int dice2Value) + { + Dice1Value = dice1Value; + Dice2Value = dice2Value; + } + } +} diff --git a/source/Trek-12/Models/Events/GameEndedEventArgs.cs b/source/Trek-12/Models/Events/GameEndedEventArgs.cs new file mode 100644 index 0000000..7148eeb --- /dev/null +++ b/source/Trek-12/Models/Events/GameEndedEventArgs.cs @@ -0,0 +1,17 @@ +using Models.Game; + +namespace Models.Events +{ + /// + /// Event arguments for when the game ends. + /// + public class GameEndedEventArgs : EventArgs + { + public Player CurrentPlayer { get; } + + public GameEndedEventArgs(Player winner) + { + CurrentPlayer = winner; + } + } +} diff --git a/source/Trek-12/Models/Events/GameStartedEventArgs.cs b/source/Trek-12/Models/Events/GameStartedEventArgs.cs new file mode 100644 index 0000000..1f1e157 --- /dev/null +++ b/source/Trek-12/Models/Events/GameStartedEventArgs.cs @@ -0,0 +1,18 @@ +using Models.Game; + +namespace Models.Events +{ + /// + /// Event arguments for when the game starts. + /// + public class GameStartedEventArgs : EventArgs + { + public Player CurrentPlayer { get; } + + public GameStartedEventArgs(Player selectedPlayer) + { + CurrentPlayer = selectedPlayer; + } + } +} + diff --git a/source/Trek-12/Models/Events/OperationChosenEventArgs.cs b/source/Trek-12/Models/Events/OperationChosenEventArgs.cs new file mode 100644 index 0000000..af43c76 --- /dev/null +++ b/source/Trek-12/Models/Events/OperationChosenEventArgs.cs @@ -0,0 +1,19 @@ +using Models.Game; + +namespace Models.Events +{ + /// + /// Event arguments for when an operation is chosen. + /// + public class OperationChosenEventArgs : EventArgs + { + public Operation Operation { get; } + public int Result { get; } + + public OperationChosenEventArgs(Operation operation, int result) + { + Operation = operation; + Result = result; + } + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Exceptions/InvalidCellCoordinatesException.cs b/source/Trek-12/Models/Exceptions/InvalidCellCoordinatesException.cs new file mode 100644 index 0000000..4f4e53d --- /dev/null +++ b/source/Trek-12/Models/Exceptions/InvalidCellCoordinatesException.cs @@ -0,0 +1,11 @@ +namespace Models.Exceptions +{ + /// + /// Exception for when the cell coordinates are invalid. + /// + public class InvalidCellCoordinatesException : Exception + { + public InvalidCellCoordinatesException(string message) : base(message) { } + } +} + diff --git a/source/Trek-12/Models/Exceptions/InvalidCellException.cs b/source/Trek-12/Models/Exceptions/InvalidCellException.cs new file mode 100644 index 0000000..7556c26 --- /dev/null +++ b/source/Trek-12/Models/Exceptions/InvalidCellException.cs @@ -0,0 +1,11 @@ +namespace Models.Exceptions +{ + /// + /// Exception for when the cell is invalid. + /// + public class InvalidCellException : Exception + { + public InvalidCellException(string message) : base(message) { } + } +} + diff --git a/source/Trek-12/Models/Game/BestScore.cs b/source/Trek-12/Models/Game/BestScore.cs new file mode 100644 index 0000000..c2c5ca4 --- /dev/null +++ b/source/Trek-12/Models/Game/BestScore.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Game +{ + /// + /// This class represents the best score of a player. + /// + public class BestScore + { + /// + /// Initialize a new instance of the BestScore class. + /// + /// Number of games played by the new user + /// Best score + public BestScore(int gamesPlayed, int score) + { + GamesPlayed = gamesPlayed; + Score = score; + if (GamesPlayed < 0) + GamesPlayed = 0; + if (Score < 0) + Score = 0; + } + + /// + /// Number of games played by the user. + /// + public int GamesPlayed { get; private set; } + + /// + /// Best score of the player. + /// + private int _score; + public int Score + { + get + { + return _score; + } + private set + { + if (value > _score) + _score = value; + } + } + + /// + /// Increment the number of games played by the user. + /// + public void IncrGamesPlayed() + { + GamesPlayed += 1; + } + + /// + /// Update the best score of the player. + /// + /// New best score + public void UpdateScore(int newScore) + { + Score = newScore; + } + } +} diff --git a/source/Trek-12/Models/Game/Cell.cs b/source/Trek-12/Models/Game/Cell.cs new file mode 100644 index 0000000..49fe4bb --- /dev/null +++ b/source/Trek-12/Models/Game/Cell.cs @@ -0,0 +1,64 @@ +namespace Models.Game +{ + /// + /// The Cell class represents a cell in the application. + /// + public class Cell : Position, IEquatable + { + /// + /// The value of the cell. + /// + private int? _value; + public int? Value { + get => _value; + set + { + if (value < 0) + { + throw new Exception("La valeur doit être supérieure à 0"); + } + this._value = value; + } + } + + /// + /// The fact that the cell is dangerous or not. + /// + private bool IsDangerous { get; set; } + + /// + /// Atribute to know if the cell is a penalty cell. + /// + private bool Penalty { get; set; } + + /// + /// Constructor of the Cell class. + /// + /// the x position + /// the y position + /// if the cell is a dangerous cell or not + public Cell(int x, int y,bool isDangerous = false):base(x,y) + { + IsDangerous = isDangerous; + Penalty = false; + } + + /// + /// Function in order to return the fact that the cell is dangerous or not. + /// + /// If the cell is dangerous or not + public bool GetCellType() => IsDangerous; + + /// + /// Redefine the equal operation between cells. + /// + /// The object to compare with the current cell. + /// true if the specified object is equal to the current cell; otherwise, false. + public bool Equals(Cell? other) + { + if (other == null) return false; + if (this.X == other.X && this.Y == other.Y) return true; + return false; + } + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Game/Dice.cs b/source/Trek-12/Models/Game/Dice.cs new file mode 100644 index 0000000..2d47fe3 --- /dev/null +++ b/source/Trek-12/Models/Game/Dice.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Game +{ + /// + /// The Dice class represents a dice in the application. + /// + public class Dice + { + /// + /// Lowest number on the dice. + /// + public int NbMin { get; private set; } + + /// + /// Highest number on the dice. + /// + public int NbMax { get; private set; } + + /// + /// Value of the dice. + /// + private int _value; + public int Value { + get => _value; + private set + { + if (value < NbMin || value > NbMax) + { + value = NbMin; + } + _value = value; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The lowest number on the dice, on which the highest number is set + public Dice(int nbmin) + { + if (nbmin < 0) nbmin = 0; + if (nbmin > 1) nbmin = 1; + NbMin = nbmin; + NbMax = nbmin + 5; + } + + /// + /// Initializes a new instance of the class. + /// + public Dice() + { + NbMin = 0; + NbMax = 5; + } + + public override string ToString() + { + return $"Ce dé a pour valeur {Value} et est entre {NbMin} et {NbMax}"; + } + + /// + /// Rolls the dice. + /// + public void Roll() + { + Value = new Random().Next(NbMin, NbMax + 1); + } + + /// + /// Compare 2 dice values. + /// + /// Another dice + /// true if the dice2 is higher than the dice1; otherwise, false. + public bool IsLower(Dice dice2) + { + return dice2.Value > this.Value; + } + + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Game/Game.cs b/source/Trek-12/Models/Game/Game.cs new file mode 100644 index 0000000..ca6ede7 --- /dev/null +++ b/source/Trek-12/Models/Game/Game.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Threading.Tasks.Dataflow; +using Models.Events; +using Models.Exceptions; +using Models.Rules; + +namespace Models.Game +{ + /// + /// The Game class represents a game session in the application. + /// It contains all the necessary properties and methods to manage a game, including the game loop, dice rolling, and use of the game rules. + /// + public class Game + { + private bool _isRunning; + public Player CurrentPlayer { get; private set; } + + public Map UsedMap { get; private set; } + + private Dice Dice1 { get; } + private Dice Dice2 { get; } + + private int Turn { get; set; } + + public Rules.Rules GameRules { get; } + + + // == Events == + public event EventHandler GameStarted; + public event EventHandler GameEnded; + public event EventHandler BoardUpdated; + public event EventHandler DiceRolled; + public event EventHandler OperationChosen; + public event EventHandler CellChosen; + + + /// + /// Initializes a new instance of the class. + /// + /// The player who play the game. + /// The map to be used in the game. + public Game(Player player, Map map) + { + _isRunning = false; + UsedMap = map; + CurrentPlayer = player; + Dice1 = new Dice(); + Dice2 = new Dice(1); + Turn = 1; + GameRules = new Rules.Rules(); + } + + /// + /// Rolls all the dice. + /// + private void RollAllDice() + { + Dice1.Roll(); + Dice2.Roll(); + DiceRolled?.Invoke(this, new DiceRolledEventArgs(Dice1.Value, Dice2.Value)); + } + + /// + /// Marks an operation as checked in the operation grid of the game. + /// + /// + private void MarkOperationAsChecked(Operation operation) + { + int operationIndex = (int)operation; + int operationsPerType = 4; // Chaque type d'opération peut être fait 4 fois + + for (int i = operationIndex * operationsPerType; i < (operationIndex + 1) * operationsPerType; i++) + { + if (!UsedMap.OperationGrid[i].IsChecked) + { + UsedMap.OperationGrid[i].Check(); + break; + } + } + } + + /// + /// Performs an operation on the values of two dice based on the provided operation. + /// + /// The operation to perform. This can be LOWER, HIGHER, SUBTRACTION, ADDITION, or MULTIPLICATION. + /// + /// The result of the operation. If the operation is LOWER or HIGHER, it returns the lower or higher value of the two dice respectively. + /// If the operation is SUBTRACTION, it returns the difference between the higher and lower value of the two dice. + /// If the operation is ADDITION, it returns the sum of the values of the two dice. + /// If the operation is MULTIPLICATION, it returns the product of the values of the two dice. + /// If the operation is not one of the operations, it throws an ArgumentOutOfRangeException. + /// + private int ResultOperation(Operation o) + { + int result = o switch + { + Operation.LOWER => Dice1.IsLower(Dice2) ? Dice1.Value : Dice2.Value, + Operation.HIGHER => Dice1.IsLower(Dice2) ? Dice2.Value : Dice1.Value, + Operation.SUBTRACTION => Dice1.IsLower(Dice2) ? Dice2.Value - Dice1.Value : Dice1.Value - Dice2.Value, + Operation.ADDITION => Dice2.Value + Dice1.Value, + Operation.MULTIPLICATION => Dice2.Value * Dice1.Value, + _ => throw new ArgumentOutOfRangeException() + }; + + MarkOperationAsChecked(o); + return result; + } + + + /// + /// Places the result of a dice operation into a chosen cell on the game board. + /// The result can be placed in the chosen cell if it's the first turn or if the chosen cell is valid according to the game rules. + /// + /// The cell chosen by the player to place the result. + /// The result of the dice operation to be placed in the cell. + private void PlaceResult(Cell playerChoice, int result) + { + if (Turn == 1 || GameRules.NearCellIsValid(playerChoice, UsedMap.Boards)) + { + playerChoice.Value = result; + BoardUpdated?.Invoke(this, EventArgs.Empty); + } + } + + /// + /// Add the choosen cell to a rope path if it's possible. + /// + /// + /// + private void AddToRopePath(Cell playerChoice,List adjacentes) + { + int index =0; + + foreach (var cells in adjacentes) + { + // La cellule choisi peut creer/s'ajouter a un chemin de corde + if (cells.Value - playerChoice.Value == 1 || cells.Value - playerChoice.Value == -1) + { + // Le cas si il n'existe aucun chemin de corde + if (UsedMap.RopePaths.Count == 0) + { + // Creer un nouveau chemin de corde avec la cellule choisi par le joueur et celle adjacente + UsedMap.RopePaths.Add(new List {playerChoice, cells}); + } + + + // A modifier dans le cas ou il est possible de fusionner deux chemins de corde + if (GameRules.IsInRopePaths(playerChoice, UsedMap.RopePaths, index)) break; + + // Le cas si il existe des chemins de corde + + // Est-ce que la cellule adjacentes fait parti d'un chemin de corde + if (!GameRules.IsInRopePaths(cells,UsedMap.RopePaths,index)) + { + UsedMap.RopePaths.Add(new List { playerChoice, cells }); + continue; + } + + if (!GameRules.AsValue(playerChoice,UsedMap.RopePaths,index)) + { + UsedMap.RopePaths[index].Add(playerChoice); + } + + // Si oui, est-ce que le chemin possede deja la valeur correspondante a la valeur de la cellule du joueur choisi + // {playerChoice.Value} n'est pas dans le chemin de corde + // Ajouter au chemin + // {playerChoice.Value} existe dans le chemin de corde pas possible + + } + } + + } + + /// + /// Initializes the game. + /// + public void InitializeGame() + { + _isRunning = true; + GameStarted?.Invoke(this, new GameStartedEventArgs(CurrentPlayer)); + GameLoop(); + } + + /// + /// Ends the game. + /// + private void EndGame() + { + _isRunning = false; + GameEnded?.Invoke(this, new GameEndedEventArgs(CurrentPlayer)); + } + + /// + /// The main game loop that runs while the game is active. + /// + private void GameLoop() + { + while (_isRunning) + { + if (Turn == 20) + { + EndGame(); + break; + } + + RollAllDice(); + + Turn++; + } + } + + /// + /// Handles the player's choice of an operation based on the dice values.s + /// + /// The operation chosen by the player. + public void HandlePlayerOperation(Operation operation) + { + int result = ResultOperation(operation); + OperationChosen?.Invoke(this, new OperationChosenEventArgs(operation, result)); + } + + /// + /// Handles the player's choice of a cell on the game board. + /// + /// + /// + /// + /// + public void HandlePlayerChoice(Cell cell, int result) + { + if (cell.X < 0 || cell.X >= UsedMap.Boards.Count / 6 || cell.Y < 0 || cell.Y >= 6) + { + throw new InvalidCellCoordinatesException("Invalid cell coordinates. Please choose again."); + } + + if (!GameRules.IsCellValid(cell, UsedMap.Boards)) + { + throw new InvalidCellException("Cell is not valid. Please choose again."); + } + + PlaceResult(cell, result); + GameRules.IsZoneValidAndAddToZones(cell, UsedMap); + AddToRopePath(cell, GameRules.EveryAdjacentCells(cell, UsedMap.Boards)); + CellChosen?.Invoke(this, new CellChosenEventArgs(cell, result)); + BoardUpdated?.Invoke(this, EventArgs.Empty); + } + } +} diff --git a/source/Trek-12/Models/Game/Map.cs b/source/Trek-12/Models/Game/Map.cs new file mode 100644 index 0000000..56dbb69 --- /dev/null +++ b/source/Trek-12/Models/Game/Map.cs @@ -0,0 +1,78 @@ +namespace Models.Game +{ + + /// + /// The Map class is the representation of the game map with the board and the operations table. + /// + public class Map + { + /// + /// It is the list of cells on the map. + /// + public List Boards { get; private set; } + + /// + /// It is the backgrond image of the map + /// + public string Background { get; private set; } + + /// + /// It is the grid of the possible operation in the game + /// + public List OperationGrid { get; private set; } + + /// + /// It is a list of a list containing user's rope paths in the current game + /// + public List> RopePaths { get; private set; } + + /// + /// It is a list of a list containing user's zones in the current game + /// + public List> Zones { get; private set; } + + /// + /// Initializes a new instance of the Map class. + /// + /// The background of the map. + public Map(string background) + { + Boards = InitializeBoards(); + Background = background; + OperationGrid = InitializeOperationGrid(); + RopePaths = new List>(); + Zones = new List>(); + } + + /// + /// Initializes the boards of the map. + /// + /// Return the boards + private List InitializeBoards() + { + var boards = new List(); + for (int i = 0; i < 36; i++) // 6x6 board + { + boards.Add(new Cell(i / 6, i % 6)); + } + return boards; + } + + /// + /// Initializes the operation grid of the map. + /// + /// Return the operation grid + private List InitializeOperationGrid() + { + var operationGrid = new List(); + for (int i = 0; i < 5; i++) // 5 operations + { + for (int j = 0; j < 4; j++) // 4 cells per operation + { + operationGrid.Add(new OperationCell(i, j)); + } + } + return operationGrid; + } + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Game/Operation.cs b/source/Trek-12/Models/Game/Operation.cs new file mode 100644 index 0000000..2eca1fe --- /dev/null +++ b/source/Trek-12/Models/Game/Operation.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Game +{ + /// + /// Represents the available operations in the game. + /// + public enum Operation + { + LOWER, + HIGHER, + SUBTRACTION, + ADDITION, + MULTIPLICATION + } +} diff --git a/source/Trek-12/Models/Game/OperationCell.cs b/source/Trek-12/Models/Game/OperationCell.cs new file mode 100644 index 0000000..d8ac6da --- /dev/null +++ b/source/Trek-12/Models/Game/OperationCell.cs @@ -0,0 +1,30 @@ +namespace Models.Game +{ + /// + /// Represents a cell in the operation grid of the game. + /// + public class OperationCell : Position + { + /// + /// It tells if the operation is checked or not in the operation grid of the game. + /// + public bool IsChecked { get; private set; } + + /// + /// Constructor of the OperationCell class. + /// + /// + /// + public OperationCell(int x, int y) : base(x, y) + { + } + + /// + /// Check the operation cell. + /// + public void Check() + { + IsChecked = true; + } + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Game/Player.cs b/source/Trek-12/Models/Game/Player.cs new file mode 100644 index 0000000..f363eb4 --- /dev/null +++ b/source/Trek-12/Models/Game/Player.cs @@ -0,0 +1,82 @@ +namespace Models.Game +{ + + /// + /// Represents a player in the game. + /// + public class Player + { + /// + /// It is he pseudo of the player. + /// + public string Pseudo { get; private set; } + + /// + /// It is the profile picture of the player. + /// + public string ProfilePicture { get; private set; } + + /// + /// It is the creation date of the player. + /// + public string? CreationDate { get; private set; } + + /// + /// It tells when was the last time the player played. + /// + public string? LastPlayed { get; private set; } + + /// + /// Constructor with default values. + /// + public Player() + { + Pseudo = "Player"; + ProfilePicture = "DefaultProfilePicture"; + } + + /// + /// Construct a new instance of Player with specified pseudo and profile picture. + /// + /// The pseudo of the player. + /// The profile picture of the player. + public Player(string pseudo, string profilePicture = "DefaultProfilePicture") + { + Pseudo = pseudo; + ProfilePicture = profilePicture; + } + + /// + /// Chooses the operation for the player. + /// + /// The chosen operation. + public Operation ChooseOperation() + { + return Operation.LOWER; + } + + /// + /// Redefine the equal operation between player. + /// + /// The object to compare with the current player. + /// true if the specified object is equal to the current player; otherwise, false. + public override bool Equals(object? obj) + { + if (obj == null || GetType() != obj.GetType()) + { + return false; + } + Player c = (Player)obj; + return (Pseudo == c.Pseudo); + } + + /// + /// Returns the hash code for the current player, in order for the Equals operation to work + /// + /// The hash code for the current player. + public override int GetHashCode() + { + return Pseudo.GetHashCode(); + } + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Game/Position.cs b/source/Trek-12/Models/Game/Position.cs new file mode 100644 index 0000000..c1b75da --- /dev/null +++ b/source/Trek-12/Models/Game/Position.cs @@ -0,0 +1,30 @@ +namespace Models.Game +{ + + /// + /// The Position (x,y) of a cell in the game. + /// + public class Position + { + /// + /// The X coordinate. + /// + public int X { get; set; } + + /// + /// The Y coordinate. + /// + public int Y { get; set; } + + /// + /// Constructor of the Position class. + /// + /// The X coordinate. + /// The Y coordinate. + public Position(int x, int y) + { + X = x; + Y = y; + } + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Interfaces/IRules.cs b/source/Trek-12/Models/Interfaces/IRules.cs new file mode 100644 index 0000000..1b9cb8d --- /dev/null +++ b/source/Trek-12/Models/Interfaces/IRules.cs @@ -0,0 +1,128 @@ +using Models.Game; + +namespace Models.Interfaces +{ + + /// + /// Interface for the rules of the game. + /// + public interface IRules + { + //public bool NearCellIsValid(Position playerChoicePosition, SortedDictionary cells); + + /// + /// Return true if the cell is empty, otherwise false. + /// + /// The cell that the player chose + /// Return true if the cell is empty, otherwise false. + public bool IsCellEmpty(Cell playerChoice); + + /// + /// Check if the cell is valid. + /// + /// The cell that the player chose + /// Boards of the actual game + /// true if the cell is valid; otherwise, false + public bool IsCellValid(Cell playerChoicePosition, List cells); + + //public bool IsRopePath(Cell playerChoice, HashSet ropePaths); + + //public bool IsAdjacent(Cell cell1, Cell cell2, List cells); + + //public int HowMany(Cell playerChoice, List cells); + + //public void SetValueAndPenalty(int valueChoice, Cell playerChoice, List cells); + + + /// + /// Check if the given cell is adjacent to the target cell. + /// + /// The chosen cell. + /// The target cell. + /// True if the given cell is adjacent to the target cell; otherwise false. + public bool IsCellAdjacent(Cell choosenCell, Cell targetCell); + + /// + /// Check if the given cell can be played there. + /// If there isn't any adjacent cell with a value, or if the cell is null, it returns false. + /// + /// The chosen cell. + /// The list of cells. + /// True if the chosen cell can be played here; otherwise false. + public bool NearCellIsValid(Cell choosenCell, List cells); + + /// + /// Check if the chosen cell is valid and add it to the matching zone. + /// If there is a nearby cell with matching value but no zone already created, it creates one + /// + /// The chosen cell. + /// The map. + /// + public void IsZoneValidAndAddToZones(Cell chosenCell, Map map); + + /// + /// Check if the value of the chosen cell is in the zones of the player. + /// + /// The cell chosen by the player. + /// The list of the player's zones. + /// True if the value is in the zones; otherwise false. + public bool IsValueInZones(Cell chosenCell, List> zones); + + /// + /// Check if the chosen cell is in any of the player's zones. + /// + /// The chosen cell. + /// The list of the player's zones. + /// True if the cell is in any of the zones; otherwise false. + public bool IsCellInZone(Cell chosenCell, List> zones); + + /// + /// Add the chosen cell to the list of zones. + /// The zone must be created before. + /// + /// The chosen cell. + /// The list of zones. + public void AddToZone(Cell chosenCell, List> zones); + + /// + /// Create a new zone with the two cells and add it to the map. + /// + /// The first cell. + /// The second cell. + /// The map. + public void NewZoneIsCreated(Cell firstCell, Cell secondCell, Map map); + + /// + /// Get every adjacent cell of the chosen cell. + /// + /// The chosen cell. + /// The list of cells. + /// The list of adjacent cells. + public List EveryAdjacentCells(Cell choosenCell, List cells); + + /// + /// Calculate the final score by summing up the values of all the zones. + /// + /// The list of zones. + /// The final score. + public int? FinalCalculusOfZones(List> zones); + + /// + /// Check if the adjacent cell is in any of the rope paths. + /// + /// The adjacent cell. + /// The list of rope paths. + /// The index of the rope path. + /// True if the adjacent cell is in the rope path; otherwise false. + public bool IsInRopePaths(Cell adjacente, List> ropePaths, int index); + + /// + /// Check if the chosen cell has the same value as the rope path at the given index. + /// + /// The chosen cell. + /// The list of rope paths. + /// The index of the rope path. + /// True if the chosen cell has the same value as the rope path; otherwise false. + public bool AsValue(Cell choosenCell, List> ropePaths, int index); + } +} \ No newline at end of file diff --git a/source/Trek-12/Models/Models.csproj b/source/Trek-12/Models/Models.csproj new file mode 100644 index 0000000..0119668 --- /dev/null +++ b/source/Trek-12/Models/Models.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + + + + + + + + + diff --git a/source/Trek-12/Models/Rules/Rules.cs b/source/Trek-12/Models/Rules/Rules.cs new file mode 100644 index 0000000..8a7dc43 --- /dev/null +++ b/source/Trek-12/Models/Rules/Rules.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Models.Game; +using Models.Interfaces; + +namespace Models.Rules +{ + /// + /// The Rules class contains all the rules of the game. It is used to check if a move is valid or not. + /// + public class Rules : IRules + { + + public bool IsCellEmpty(Cell playerChoice) + { + if (playerChoice == null || playerChoice.Value == null) return true; + return false; + } + + public bool IsCellValid(Cell playerChoicePosition, List cells) + { + if (!IsCellEmpty(playerChoicePosition)) return false; + + if (EveryAdjacentCells(playerChoicePosition, cells).Count == 1) return false; + + return true; + } + + public bool IsCellAdjacent(Cell choosenCell, Cell targetCell) + { + if (Math.Abs(choosenCell.X - targetCell.X) > 1 || Math.Abs(choosenCell.Y - targetCell.Y) > 1) + return false; + if (Math.Abs(choosenCell.X - targetCell.X) > 1 && Math.Abs(choosenCell.Y - targetCell.Y) > 1) + return false; + if (choosenCell.X == 0 && targetCell.X == 4) + return false; + if (choosenCell.Y == 0 && targetCell.Y == 4) + return false; + if (choosenCell.X == 4 && targetCell.X == 0) + return false; + if (choosenCell.Y == 4 && targetCell.Y == 0) + return false; + if (choosenCell.X == targetCell.X && choosenCell.Y == targetCell.Y) + return false; + + return true; + } + + public bool IsInRopePaths (Cell adjacente,List> ropePaths,int index) + { + foreach (List path in ropePaths) + { + if (path.Contains(adjacente)) + { + index=ropePaths.IndexOf(path); + return true; + } + } + return false; + } + + public bool AsValue (Cell choosenCell, List> ropePaths,int index) + { + foreach (var item in ropePaths[index]) + { + if (choosenCell.Value == item.Value) return true; + } + return false; + } + public bool NearCellIsValid(Cell choosenCell, List cells) + { + if (choosenCell == null || cells == null) return false; + + IEnumerable PlayedCellsQuery = + from cell in cells + where cell.Value != null + select cell; + + foreach (var cell in PlayedCellsQuery) + { + if(!IsCellAdjacent(choosenCell, cell)) continue; + + return true; + } + + return false; + } + + public void IsZoneValidAndAddToZones(Cell chosenCell, Map map) + { + if (chosenCell == null ||chosenCell.Value == null) return; + + List adjacentCells = new List(); + + adjacentCells = EveryAdjacentCells(chosenCell, map.Boards); + + foreach(var cells in adjacentCells) + { + if (cells.Value == chosenCell.Value) + { + if(IsValueInZones(cells, map.Zones)) + { + AddToZone(chosenCell, map.Zones); + } + else + { + NewZoneIsCreated(chosenCell, cells, map); + } + //return true; // Il y a une cellule adjacente avec la même valeur donc une zone est créée si elle n'est pas déjà existante + // Si il return true, tout c'est bien passer + } + } + + return; + } + + public bool IsValueInZones(Cell chosenCell, List> zones) + { + if (chosenCell == null) return false; + + for (int i = 0; i < zones.Count; i++) + { + if (zones[i][0].Value == chosenCell.Value) + { + return true; + } + } + return false; + } + + public bool IsCellInZone(Cell chosenCell, List> zones) + { + if (chosenCell == null) return false; + + for (int i = 0; i < zones.Count; i++) + { + if (zones[i].Contains(chosenCell)) + { + return true; + } + } + return false; + } + + public void AddToZone(Cell chosenCell, List> zones) + { + if (chosenCell == null || chosenCell.Value == null) return; + + if (IsCellInZone(chosenCell, zones)) return; + + for (int i = 0; i < zones.Count; i++) + { + if (zones[i][0].Value == chosenCell.Value) + { + zones[i].Add(chosenCell); + return; + } + } + return; + } + + public void NewZoneIsCreated(Cell firstCell, Cell secondCell, Map map) + { + if (firstCell == null || secondCell == null || firstCell.Value == null || secondCell.Value == null) return; + List newZone = new List(); + newZone.Add(firstCell); + newZone.Add(secondCell); + map.Zones.Add(newZone); + } + + public List EveryAdjacentCells(Cell choosenCell, List cells) + { + List adjacentCells = new List(); + + foreach (var cell in cells) + { + if (choosenCell == cell) continue; + if (IsCellAdjacent(choosenCell, cell)) + { + adjacentCells.Add(cell); + } + } + + return adjacentCells; + } + + public int? FinalCalculusOfZones(List> zones) + { + int? calculus = 0; + for(int i = 0; i < zones.Count; i++) + { + calculus += zones[i].Count - 1 + zones[i][0].Value; + if (zones[i].Count > 9) + { + calculus += (zones[i].Count - 9) * 5; + } + } + return calculus; + } + + } +} \ No newline at end of file diff --git a/source/Trek-12/Tests/BestScoreTests.cs b/source/Trek-12/Tests/BestScoreTests.cs new file mode 100644 index 0000000..951989c --- /dev/null +++ b/source/Trek-12/Tests/BestScoreTests.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Models.Game; + +namespace Tests +{ + public class BestScoreTests + { + [Fact] + public void Constructor_WithNegativeInputs_SetsPropertiesToZero() + { + var bestScore = new BestScore(-5, -10); + Assert.Equal(0, bestScore.GamesPlayed); + Assert.Equal(0, bestScore.Score); + } + + [Fact] + public void Constructor_WithPositiveInputs_SetsPropertiesCorrectly() + { + var bestScore = new BestScore(5, 10); + Assert.Equal(5, bestScore.GamesPlayed); + Assert.Equal(10, bestScore.Score); + } + + [Fact] + public void IncrGamesPlayed_IncrementsGamesPlayed() + { + var bestScore = new BestScore(0, 0); + bestScore.IncrGamesPlayed(); + Assert.Equal(1, bestScore.GamesPlayed); + } + + [Fact] + public void ScoreSetter_WithLowerValue_DoesNotChangeScore() + { + var bestScore = new BestScore(0, 10); + bestScore.UpdateScore(5); + Assert.Equal(10, bestScore.Score); + } + + [Fact] + public void ScoreSetter_WithHigherValue_ChangesScore() + { + var bestScore = new BestScore(0, 5); + bestScore.UpdateScore(10); + Assert.Equal(10, bestScore.Score); + } + } +} diff --git a/source/Trek-12/Tests/CellTests.cs b/source/Trek-12/Tests/CellTests.cs new file mode 100644 index 0000000..e967bf1 --- /dev/null +++ b/source/Trek-12/Tests/CellTests.cs @@ -0,0 +1,50 @@ +namespace Tests; +using Models.Game; + +public class CellTests +{ + [Fact] + public void CellConstructor_SetsCorrectValues() + { + Cell cell = new Cell(1, 2, true); + + Assert.Equal(1, cell.X); + Assert.Equal(2, cell.Y); + Assert.True(cell.GetCellType()); + } + + [Fact] + public void CellConstructor_SetsDefaultValues() + { + Cell cell = new Cell(1, 2); + + Assert.Equal(1, cell.X); + Assert.Equal(2, cell.Y); + Assert.False(cell.GetCellType()); + } + + [Fact] + public void ValueSetter_ThrowsException_WhenValueIsNegative() + { + Cell cell = new Cell(1, 2); + + Assert.Throws(() => cell.Value = -1); + } + + [Fact] + public void ValueSetter_SetsValue_WhenValueIsPositive() + { + Cell cell = new Cell(1, 2); + + cell.Value = 5; + + Assert.Equal(5, cell.Value); + } + + [Fact] + public void ValueSetter_SetsValue_WhenValueIsNull() + { + Cell cell = new Cell(1, 2); + Assert.Null(cell.Value); + } +} \ No newline at end of file diff --git a/source/Trek-12/Tests/DiceTests.cs b/source/Trek-12/Tests/DiceTests.cs new file mode 100644 index 0000000..7831db6 --- /dev/null +++ b/source/Trek-12/Tests/DiceTests.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Models.Game; + +namespace Tests; + +public class DiceTests +{ + [Fact] + public void Constructor_WithNegativeNbMin_SetsNbMinToZero() + { + Dice dice = new Dice(-1); + Assert.Equal(0, dice.NbMin); + } + + [Fact] + public void Constructor_WithNbMinGreaterThanOne_SetsNbMinToOne() + { + Dice dice = new Dice(2); + Assert.Equal(1, dice.NbMin); + } + + [Fact] + public void Constructor_WithValidNbMin_SetsNbMinAndNbMaxCorrectly() + { + Dice dice = new Dice(1); + Assert.Equal(1, dice.NbMin); + Assert.Equal(6, dice.NbMax); + } + + [Fact] + public void DefaultConstructor_SetsNbMinToZeroAndNbMaxToFive() + { + Dice dice = new Dice(); + Assert.Equal(0, dice.NbMin); + Assert.Equal(5, dice.NbMax); + } + + [Fact] + public void Roll_SetsValueBetweenNbMinAndNbMax() + { + Dice dice = new Dice(); + dice.Roll(); + Assert.True(dice.Value >= dice.NbMin && dice.Value <= dice.NbMax); + } +} diff --git a/source/Trek-12/Tests/GlobalUsings.cs b/source/Trek-12/Tests/GlobalUsings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/source/Trek-12/Tests/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/source/Trek-12/Tests/MapTests.cs b/source/Trek-12/Tests/MapTests.cs new file mode 100644 index 0000000..027ed94 --- /dev/null +++ b/source/Trek-12/Tests/MapTests.cs @@ -0,0 +1,44 @@ +using Models; +using Models.Game; + +namespace Tests; + +public class MapTests +{ + [Fact] + public void Map_Initialization_SetsBackground() + { + string background = "test_background"; + + var map = new Map(background); + + Assert.Equal(background, map.Background); + } + + [Fact] + public void Map_Initialization_InitializesBoards() + { + string background = "test_background"; + + var map = new Map(background); + + Assert.Equal(36, map.Boards.Count); + for (int i = 0; i < 36; i++) + { + Assert.Equal(new Cell(i / 6, i % 6), map.Boards[i]); + } + } + + [Fact] + public void Map_Initialization_InitializesRopePathsAndZones() + { + string background = "test_background"; + + var map = new Map(background); + + Assert.NotNull(map.RopePaths); + Assert.NotNull(map.Zones); + Assert.Empty(map.RopePaths); + Assert.Empty(map.Zones); + } +} diff --git a/source/Trek-12/Tests/OperationCellTests.cs b/source/Trek-12/Tests/OperationCellTests.cs new file mode 100644 index 0000000..673200d --- /dev/null +++ b/source/Trek-12/Tests/OperationCellTests.cs @@ -0,0 +1,27 @@ +using Models.Game; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tests +{ + public class OperationCellTests + { + [Fact] + public void Constructor_WithValidCoordinates_SetsCoordinatesCorrectly() + { + OperationCell operationCell = new OperationCell(1, 2); + Assert.Equal(1, operationCell.X); + Assert.Equal(2, operationCell.Y); + } + + [Fact] + public void Constructor_WithValidCoordinates_SetsIsCheckedToFalse() + { + OperationCell operationCell = new OperationCell(1, 2); + Assert.False(operationCell.IsChecked); + } + } +} diff --git a/source/Trek-12/Tests/PlayerTests.cs b/source/Trek-12/Tests/PlayerTests.cs new file mode 100644 index 0000000..194fa85 --- /dev/null +++ b/source/Trek-12/Tests/PlayerTests.cs @@ -0,0 +1,43 @@ +namespace Tests; +using Models.Game; + +public class PlayerTests +{ + [Theory] + [InlineData("Player", "DefaultProfilePicture")] + [InlineData("John Doe", "N/A.png")] + public void Constructor_WithPseudoAndProfilePicture_SetsPseudoAndProfilePictureCorrectly(string pseudo, string profilePicture) + { + var player = new Player(pseudo, profilePicture); + Assert.Equal(pseudo, player.Pseudo); + Assert.Equal(profilePicture, player.ProfilePicture); + } + + [Fact] + public void Constructor_WithPseudoAndWithoutProfilePicture_SetsPseudoAndDefaultProfilePicture() + { + var player = new Player("MyPlayer"); + Assert.Equal("MyPlayer", player.Pseudo); + Assert.Equal("DefaultProfilePicture", player.ProfilePicture); + } + + [Theory] + [InlineData("John Doe", "John Doe", true)] + [InlineData("John Doe", "Jane Doe", false)] + public void Equals_WithSameOrDifferentPseudo_ReturnsExpectedResult(string pseudo1, string pseudo2, bool expectedResult) + { + var player1 = new Player(pseudo1); + var player2 = new Player(pseudo2); + Assert.Equal(expectedResult, player1.Equals(player2)); + } + + [Theory] + [InlineData("John Doe", "John Doe", true)] + [InlineData("John Doe", "Jane Doe", false)] + public void GetHashCode_ReturnsSameOrDifferentHashCodeForPseudo(string pseudo1, string pseudo2, bool expectedResult) + { + var player1 = new Player(pseudo1); + var player2 = new Player(pseudo2); + Assert.Equal(expectedResult, player1.GetHashCode() == player2.GetHashCode()); + } +} \ No newline at end of file diff --git a/source/Trek-12/Tests/Tests.csproj b/source/Trek-12/Tests/Tests.csproj new file mode 100644 index 0000000..2fea905 --- /dev/null +++ b/source/Trek-12/Tests/Tests.csproj @@ -0,0 +1,29 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/source/Trek-12/Trek-12.sln b/source/Trek-12/Trek-12.sln index 4dee142..23e752e 100644 --- a/source/Trek-12/Trek-12.sln +++ b/source/Trek-12/Trek-12.sln @@ -5,6 +5,12 @@ VisualStudioVersion = 17.8.34408.163 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trek-12", "Trek-12\Trek-12.csproj", "{41EE7BF8-DDE6-4B00-9434-076589C0B419}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models", "Models\Models.csproj", "{807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "ConsoleApp\ConsoleApp.csproj", "{795F2C88-3C43-4795-9764-E52F7330888D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{383C4215-C680-4C2E-BC7E-B62F0B164370}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -17,6 +23,18 @@ Global {41EE7BF8-DDE6-4B00-9434-076589C0B419}.Release|Any CPU.ActiveCfg = Release|Any CPU {41EE7BF8-DDE6-4B00-9434-076589C0B419}.Release|Any CPU.Build.0 = Release|Any CPU {41EE7BF8-DDE6-4B00-9434-076589C0B419}.Release|Any CPU.Deploy.0 = Release|Any CPU + {807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}.Release|Any CPU.Build.0 = Release|Any CPU + {795F2C88-3C43-4795-9764-E52F7330888D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {795F2C88-3C43-4795-9764-E52F7330888D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {795F2C88-3C43-4795-9764-E52F7330888D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {795F2C88-3C43-4795-9764-E52F7330888D}.Release|Any CPU.Build.0 = Release|Any CPU + {383C4215-C680-4C2E-BC7E-B62F0B164370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {383C4215-C680-4C2E-BC7E-B62F0B164370}.Debug|Any CPU.Build.0 = Debug|Any CPU + {383C4215-C680-4C2E-BC7E-B62F0B164370}.Release|Any CPU.ActiveCfg = Release|Any CPU + {383C4215-C680-4C2E-BC7E-B62F0B164370}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/source/Trek-12/Trek-12/AppShell.xaml b/source/Trek-12/Trek-12/AppShell.xaml index 09d5f2a..4eda938 100644 --- a/source/Trek-12/Trek-12/AppShell.xaml +++ b/source/Trek-12/Trek-12/AppShell.xaml @@ -6,16 +6,37 @@ xmlns:local="clr-namespace:Trek_12" xmlns:views="clr-namespace:Trek_12.Views" Shell.FlyoutBehavior="Flyout" - Title="Trek_12"> + Title="Trek_12" + Shell.NavBarIsVisible="False"> + Route="MenuPrincipal" /> + + + + + + + + diff --git a/source/Trek-12/Trek-12/Resources/Images/bg_regles.jpg b/source/Trek-12/Trek-12/Resources/Images/bg_regles.jpg new file mode 100644 index 0000000..edbea5e Binary files /dev/null and b/source/Trek-12/Trek-12/Resources/Images/bg_regles.jpg differ diff --git a/source/Trek-12/Trek-12/Trek-12.csproj b/source/Trek-12/Trek-12/Trek-12.csproj index fb3ad58..51d65e3 100644 --- a/source/Trek-12/Trek-12/Trek-12.csproj +++ b/source/Trek-12/Trek-12/Trek-12.csproj @@ -57,6 +57,7 @@ + @@ -66,10 +67,16 @@ PageLeaderBoard.xaml + + PageProfils.xaml + + + PageRegles.xaml + - + MSBuild:Compile diff --git a/source/Trek-12/Trek-12/Views/component/ContentLeaderBoard.xaml b/source/Trek-12/Trek-12/Views/Components/ContentLeaderBoard.xaml similarity index 92% rename from source/Trek-12/Trek-12/Views/component/ContentLeaderBoard.xaml rename to source/Trek-12/Trek-12/Views/Components/ContentLeaderBoard.xaml index abcf339..639b6f3 100644 --- a/source/Trek-12/Trek-12/Views/component/ContentLeaderBoard.xaml +++ b/source/Trek-12/Trek-12/Views/Components/ContentLeaderBoard.xaml @@ -1,46 +1,46 @@ - - - - - - - - + + + + + + + + diff --git a/source/Trek-12/Trek-12/Views/component/ContentLeaderBoard.xaml.cs b/source/Trek-12/Trek-12/Views/Components/ContentLeaderBoard.xaml.cs similarity index 72% rename from source/Trek-12/Trek-12/Views/component/ContentLeaderBoard.xaml.cs rename to source/Trek-12/Trek-12/Views/Components/ContentLeaderBoard.xaml.cs index 28e9706..da9bf40 100644 --- a/source/Trek-12/Trek-12/Views/component/ContentLeaderBoard.xaml.cs +++ b/source/Trek-12/Trek-12/Views/Components/ContentLeaderBoard.xaml.cs @@ -1,9 +1,9 @@ -namespace Trek_12.Views.component; - -public partial class ContentLeaderBoard : ContentView -{ - public ContentLeaderBoard() - { - InitializeComponent(); - } +namespace Trek_12.Views.Components; + +public partial class ContentLeaderBoard : ContentView +{ + public ContentLeaderBoard() + { + InitializeComponent(); + } } \ No newline at end of file diff --git a/source/Trek-12/Trek-12/Views/viewsProfils.xaml b/source/Trek-12/Trek-12/Views/Components/viewsProfils.xaml similarity index 90% rename from source/Trek-12/Trek-12/Views/viewsProfils.xaml rename to source/Trek-12/Trek-12/Views/Components/viewsProfils.xaml index f0a3ca0..3b15b2c 100644 --- a/source/Trek-12/Trek-12/Views/viewsProfils.xaml +++ b/source/Trek-12/Trek-12/Views/Components/viewsProfils.xaml @@ -1,8 +1,7 @@ + x:Class="Trek_12.Views.Components.viewsProfils"> - - - - - - + + + + + +