You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.8 KiB
128 lines
3.8 KiB
// 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> 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);
|
|
}
|
|
} |