// Cours sur les évènements /* Pour la faire courte, y a 3 possibilités pour les affichages : - les Console.WriteLine qui sont absolument interdits dans les classes de logique (Game, Board, Rules, Player) - l'implémentations d'une interface IDisplayer qui permet de définir des méthodes qui seront appelées par les classes de logique - Définition du type délégué (delegate) => ça prend un board, ça rend rien - */ public class Game // Game.cs file { public /*delegate*/ event void GameStarted(); // c'est pas une méthode, c'est un type de méthode !!! // le event est une propriété qui permet de s'abonner à un évènement : elle empêche de faire = public event EventHandler GameStarted; protected virtual void OnGameStarted() { GameStarted?.Invoke(this, EventArgs.Empty); } private GameStarted onGameStarted; private Board board { get; init; } // je sais pas ce que fait le init private IRules Rules { get; init; } private Player Player1 { get; init; } private Player Player2 { get; init; } private IDisplayer displayer public Game(Irules rules, Player player1, Player player2) { Player1 = player1; Player2 = player2; Rules = rules; Board = rules.InitBoard(); } { } public void start() { displayer.OnGameStart(Board); Console.WriteLine("Game started !"); while(true) { // Get next player Player nextPlayer = Rules.GetNextPlayer(Board) == 1 ? Player1 : Player2; // displayer.OnPlayerNotified(nextPlayer); onGameStarted(board); // Notify player to make a move (int chosenRow, int chosenCol) = nextPlayer.ChooseMove(Board, Rules); displayer.OnMoveChosen(nextPlayer, chosenRow, chosenCol); // If move is valid (check with rules) if(Rules.IsValidMove(Board, chosenRow, chosenCol, nextPlayer.Id)) { // true => modify board Board.InsertPiece(chosenRow, chosenCol, nextPlayer.Id); displayer.OnValidMove(nextPlayer, Board, chosenRow, chosenCol, true); displayer.OnGameOver(Board, nextPlayer, Rules); // is game over? (check with rules) if(Rules.IsGameOver(Board, chosenRow, chosenCol, out int winner, out Case[] winningPlaces)) { Console.WriteLine($"Player {winner} won the game !"); for(int row = 0; row < Board.NbRows; row++) { for(int col = 0; col < Board.NbCols; col++) { Console.Write($"{playerSymbol} ") } Console.WriteLine(); } return; } } // gets the winner, winning places, return // false => nothing } } } public abstract class Player // Player.cs file { public string Name { get; private set; } public int Id { get; private init; } public Player(string name, int id) { Id = id; Name = name; } public abstract (int row, int col) ChooseMove(Board board, IRules rules); } public class RandomPlayer : Player // RandomPlayer.cs file { public RandomPlayer(int id) : base(id, "Jérôme") { } public static Random random = new Random(); public override (int row, int col) ChooseMove(Board board, IRules rules) { var moves = rules.GetPossibleMoves(board, Id); var chosenMoveId = random.Next(0, moves.Count()); Case chosenCase = moves.ElementAt(chosenMoveId); return (chosenCase.Row, chosenCase.Col); } }