Ejemplo n.º 1
0
 public Data(ImageSource img, int val, TimeSpan time, IPlayable.IPlayable ia = null)
 {
     this.Val  = val;
     this.img  = img;
     this.Time = time;
     this.IA   = ia;
 }
Ejemplo n.º 2
0
 private void lbIAWhite_SelectionChanged(object sender, SelectionChangedEventArgs e)
 {
     try
     {
         tournamentWhitePlayer = (IPlayable.IPlayable)Activator.CreateInstance(tournamentPlayers[lbIAWhite.SelectedIndex].GetType());
         team2.Content         = tournamentWhitePlayer.GetName();
     }
     catch
     {
         System.Windows.MessageBox.Show("Problème à l'instanciation de la classe IA (White)");
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Method to test the IA is complying with Othello rules
        /// BROKEN (does not work)
        /// Probably that putting random pawns all over the board is not a good way to
        /// initialize a playable board
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuTestIA_Click(object sender, RoutedEventArgs e)
        {
            Referee = new OthelloLib.Board();
            if ((lbIABlack.SelectedIndex == -1) || (tournamentPlayers.Count == 0))
            {
                return;
            }
            IPlayable.IPlayable testBlackPlayer = (IPlayable.IPlayable)Activator.CreateInstance(tournamentPlayers[lbIABlack.SelectedIndex].GetType());
            UI.Title = "TEST RUNNING";
            Tuple <int, int> move;
            bool             blackTurn = true;
            int percent = 0;

            for (int t = 0; t < 100; t++)
            {
                // generate a random board position
                int[,] testBoard = getRandomBoard();

                move = Referee.GetNextMove(testBoard, 5, blackTurn);
                if (move.Item1 != -1)
                {
                    testBlackPlayer.PlayMove(move.Item1, move.Item2, blackTurn);
                    //verify
                    Referee.PlayMove(move.Item1, move.Item2, blackTurn);
                    int[,] board1 = testBlackPlayer.GetBoard();
                    int[,] board2 = Referee.GetBoard();
                    if (boardCompare(board1, board2))
                    {
                        percent++;
                    }
                    UI.Title += ".";
                }
                else
                {
                    percent++;
                    UI.Title += "X";
                }
                System.Threading.Thread.Sleep(30);
            }

            UI.Title = $"TEST COMPLETE ({percent}%)";
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Will look for all DLL in the current folder that implement IPlayable and have a Board class
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuFindIA_Click(object sender, RoutedEventArgs e)
        {
            tournamentPlayers.Clear();
            //find all DLLs with name starting with "OthelloIA" in the executable folder
            List <Assembly> IAPlayers = new List <Assembly>();
            string          path      = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            foreach (string dll in Directory.GetFiles(path, "Othello*.dll"))
            {
                IAPlayers.Add(Assembly.LoadFile(dll));
            }
            foreach (Assembly assembly in IAPlayers)
            {
                try
                {
                    Assembly.Load(assembly.FullName);
                }
                catch
                {
                    System.Windows.MessageBox.Show("Impossible de charger " + assembly.FullName);
                }
                // verify if they implement IPlayable and have a Board class
                IPlayable.IPlayable player = null;
                Type[] types = assembly.GetTypes();
                for (int i = 0; i < types.Count(); i++)
                {
                    if (types[i].Name.Contains("Board"))                                  // the IA's class that implements IPlayable must have "Board" in its name. E.g OthelloBoard, TheBoard, MyBoard, ...
                    {
                        player = (IPlayable.IPlayable)Activator.CreateInstance(types[i]); // requires a default constructore
                    }
                }
                if (player != null) // add it to the players list
                {
                    tournamentPlayers.Add(player);
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// This method will perform the game loop
        /// NOTE: it is required for this method to be async to allow for await
        /// otherwise it will lock the main(UI) thread and the game status is not
        /// visually updated (refreshed)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void MenuStartGame_Click(object sender, RoutedEventArgs e)
        {
            if ((tournamentBlackPlayer == null) || (tournamentWhitePlayer == null))
            {
                System.Windows.MessageBox.Show("You NEED 2 IAs to play a match!");
                return;
            }
            // to prevent crash with some IA when playing a second time
            tournamentBlackPlayer = (IPlayable.IPlayable)Activator.CreateInstance(tournamentPlayers[lbIABlack.SelectedIndex].GetType());
            tournamentWhitePlayer = (IPlayable.IPlayable)Activator.CreateInstance(tournamentPlayers[lbIAWhite.SelectedIndex].GetType());

            RestartGame();
            Referee = new OthelloLib.Board();

            int[,] refBoard  = (Referee as OthelloLib.Board).GetBoard();
            int[,] board1    = refBoard; //tournamentBlackPlayer.GetBoard();   // PLAYER 1
            int[,] board2    = refBoard; //tournamentWhitePlayer.GetBoard();   // PLAYER 2
            team1.Foreground = new SolidColorBrush(Color.FromRgb(0, 0, 0));
            team2.Foreground = new SolidColorBrush(Color.FromRgb(0, 0, 0));
            Tuple <int, int> playerMove = null;
            int  passCount = 0;
            bool testPlayer1, testPlayer2;
            bool whitePlays = false;

            IPlayable.IPlayable activePlayer = tournamentBlackPlayer; // player 1 begins playing black

            //GAME LOOP
            while (boardCompare(refBoard, board1) && boardCompare(refBoard, board2) && (passCount < 2))
            {
                int totalScore = Referee.GetBlackScore() + Referee.GetWhiteScore();
                await Task.Delay(whitePlays? 100 : 100); // slow down game speed

                try
                {
                    playerMove = activePlayer.GetNextMove(refBoard, 5, whitePlays);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "\n\n" + ex.StackTrace);
                }
                // check move validity
                if (playerMove == null)
                {
                    System.Windows.MessageBox.Show($" {activePlayer.GetName()} a renvoyé un coup NULL\nFIN DE LA PARTIE");
                    return;
                }
                if ((playerMove.Item1 == PASS) && (playerMove.Item2 == PASS))
                {
                    Console.WriteLine("PASS");
                    passCount++;
                    ///TODO verify if no move was possible (no playable move otherwise display a msg or throw something
                    if ((Referee as OthelloLib.Board).GetPossibleMoves(whitePlays).Count != 0)
                    {
                        System.Windows.MessageBox.Show($" {activePlayer.GetName()} a passé son tour de manière illégale\nFIN DE LA PARTIE");
                        return;
                    }
                }
                else
                {
                    passCount = 0;
                    Console.WriteLine($"{activePlayer.GetName()}: {(char)('A' + playerMove.Item1)}{1 + playerMove.Item2}");
                    // check validity
                    if ((Referee as OthelloLib.Board).IsPlayable(playerMove, whitePlays))
                    {
                        Console.WriteLine($"Coup valide de {activePlayer}");
                        // play the move for both players and referee
                        Referee.PlayMove(playerMove.Item1, playerMove.Item2, whitePlays);
                        testPlayer1 = tournamentBlackPlayer.PlayMove(playerMove.Item1, playerMove.Item2, whitePlays);  // no verification here
                        testPlayer1 = tournamentWhitePlayer.PlayMove(playerMove.Item1, playerMove.Item2, whitePlays);  // no verification here

                        // compare boards for validity
                        refBoard    = (Referee as OthelloLib.Board).GetBoard();
                        board1      = tournamentBlackPlayer.GetBoard();
                        board2      = tournamentWhitePlayer.GetBoard();
                        testPlayer1 = boardCompare(refBoard, board1);
                        testPlayer2 = boardCompare(refBoard, board2);
                        if (testPlayer1 && testPlayer2)  // the move is valid
                        {
                            PlayMove(playerMove.Item1, playerMove.Item2);
                            UI.Title = $"BLACK:{Referee.GetBlackScore()} WHITE:{Referee.GetWhiteScore()}";
                            //System.Windows.MessageBox.Show(".");
                            await Task.Delay(delay);
                        }
                        else if (!testPlayer1)
                        {
                            System.Windows.MessageBox.Show($"Board state of {tournamentBlackPlayer.GetName()}is incorrect");
                            throw new Exception($"Board state of {tournamentBlackPlayer.GetName()}is incorrect");
                        }
                        else if (!testPlayer2)
                        {
                            System.Windows.MessageBox.Show($"Board state of {tournamentWhitePlayer.GetName()}is incorrect");
                            throw new Exception($"Board state of {tournamentWhitePlayer.GetName()} is incorrect");
                        }
                    }
                    else
                    {
                        Console.WriteLine($"COUP INVALIDE {(char)(playerMove.Item1+'A')}{playerMove.Item2+1}");
                        if (whitePlays == true)
                        {
                            team2.Foreground = new SolidColorBrush(Color.FromRgb(255, 100, 100));
                            System.Windows.MessageBox.Show($"COUP INVALIDE de {tournamentWhitePlayer.GetName()} {(char)playerMove.Item1 + 'A'}{playerMove.Item2 + 1}\nFIN DE LA PARTIE");
                            return;
                        }
                        else
                        {
                            team1.Foreground = new SolidColorBrush(Color.FromRgb(255, 100, 100));
                            System.Windows.MessageBox.Show($"COUP INVALIDE de {tournamentBlackPlayer.GetName()} {(char)(playerMove.Item1 + 'A')}{playerMove.Item2 + 1}\nFIN DE LA PARTIE");
                            return;
                        }
                    }
                }
                // SWAP players and color
                whitePlays   = !whitePlays;
                activePlayer = (activePlayer == tournamentBlackPlayer) ? tournamentWhitePlayer : tournamentBlackPlayer;
            } // end of GAMELOOP
        }
        /// <summary>
        /// Console application that plays an othello game with 2 AIs implementing IPlayable interface
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            #region LOAD_IAs

            //find all DLLs with name starting with "OthelloIA" in the executable folder
            List <Assembly> IAPlayers = new List <Assembly>();
            string          path      = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            foreach (string dll in Directory.GetFiles(path, "OthelloIA*.dll"))
            {
                IAPlayers.Add(Assembly.LoadFile(dll));
            }
            foreach (Assembly assembly in IAPlayers)
            {
                Assembly.Load(assembly.FullName);
            }
            #endregion

            // 1. Connect two players by either loading a)dynamically or b)statically the teams assemblies
            IPlayable.IPlayable player1 = null, player2 = null, serverController = null;

            //a)Recover the types from the DLL assemblies using reflection for the 2 players
            if (IAPlayers.Count >= 2)
            {
                Type[] T1 = IAPlayers[0].GetTypes();
                for (int i = 0; i < T1.Count(); i++)
                {
                    if (T1[i].Name.Contains("Board"))                                   // the IA's class that implements IPlayable must have "Board" in its name. E.g OthelloBoard, TheBoard, MyBoard, ...
                    {
                        player1 = (IPlayable.IPlayable)Activator.CreateInstance(T1[i]); // requires a default constructore
                    }
                }
                if (player1 == null)
                {
                    player1 = new OthelloIA2.OthelloBoard();
                }
                Type[] T2 = IAPlayers[1].GetTypes();        //or    GetType ("OthelloIA2.OthelloBoard");
                for (int i = 0; i < T2.Count(); i++)
                {
                    if (T2[i].Name.Contains("Board"))                                   // the IA's class that implements IPlayable must have "Board" in its name. E.g OthelloBoard, TheBoard, MyBoard, ...
                    {
                        player2 = (IPlayable.IPlayable)Activator.CreateInstance(T2[i]); // requires a default constructore
                    }
                }
                if (player2 == null)
                {
                    player2 = new OthelloIA2.OthelloBoard();
                }
            }
            else // b) add a reference to your class assembly in the project and instantiate it
            {
                player1 = new AlphaBetaTeam11Library.LogicBoard();   // for example
                player2 = new AlphaBetaTeam11Library.LogicBoard();   // for example
            }
            // The Game controller
            serverController = new OthelloLib.Board();             //reference interne au projet

            // Initialize the board for initial display
            int[,] theBoard = (serverController as OthelloLib.Board).GetBoard();

            //UI PART draw the 3 boards: reference, player1, player2
            Console.BackgroundColor = ConsoleColor.DarkBlue;
            Console.WriteLine("REFEREE : " + serverController.GetName());
            Console.WriteLine("TEAM 1  : " + player1.GetName());
            Console.WriteLine("TEAM 2  : " + player2.GetName());
            (serverController as OthelloLib.Board).DrawBoard();
            //DrawBoard(player1.GetBoard(), player1.GetName(), player1.GetBlackScore(), player1.GetWhiteScore());
            //DrawBoard(player2.GetBoard(), player2.GetName(), player2.GetBlackScore(), player2.GetWhiteScore());

            #region GAMELOOP
            //GAME LOOP
            int[,] refBoard = (serverController as OthelloLib.Board).GetBoard();
            int[,] board1   = player1.GetBoard();
            int[,] board2   = player2.GetBoard();

            Tuple <int, int> playerMove = null;
            int  passCount = 0;
            bool testPlayer1, testPlayer2;
            bool whitePlays = false;
            IPlayable.IPlayable activePlayer = player1;     // player 1 begins playing black

            while (boardCompare(refBoard, board1) && boardCompare(refBoard, board2) && (passCount < 2))
            {
                int totalScore = serverController.GetBlackScore() + serverController.GetWhiteScore();
                Console.Clear();
                try
                {
                    playerMove = activePlayer.GetNextMove(theBoard, 5, whitePlays);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message + "\n\n" + e.StackTrace);
                }
                Console.Write(whitePlays ? "\n[O]" : "\n[X]");
                // check move validity
                if ((playerMove.Item1 == PASS) && (playerMove.Item1 == PASS))
                {
                    Console.WriteLine("PASS");
                    passCount++;
                    ///TODO verify if no move was possible (no playable move otherwise display a msg or throw something
                    if ((serverController as OthelloLib.Board).GetPossibleMoves(whitePlays).Count != 0)
                    {
                        throw new Exception($"you shall NOT PASS {activePlayer}!");
                    }
                }
                else
                {
                    passCount = 0;
                    Console.WriteLine($"{activePlayer.GetName()}: {(char)('A' + playerMove.Item1)}{1 + playerMove.Item2}");
                    // check validity
                    if ((serverController as OthelloLib.Board).IsPlayable(playerMove, whitePlays))

                    {
                        Console.WriteLine("Coup valide");
                        // play the move for both players and referee
                        serverController.PlayMove(playerMove.Item1, playerMove.Item2, whitePlays);
                        testPlayer1 = player1.PlayMove(playerMove.Item1, playerMove.Item2, whitePlays);  // no verification here
                        testPlayer1 = player2.PlayMove(playerMove.Item1, playerMove.Item2, whitePlays);  // no verification here

                        // compare boards for validity
                        refBoard    = (serverController as OthelloLib.Board).GetBoard();
                        board1      = player1.GetBoard();
                        board2      = player2.GetBoard();
                        testPlayer1 = boardCompare(refBoard, board1);
                        testPlayer2 = boardCompare(refBoard, board2);
                        if (testPlayer1 && testPlayer2)  // we only need to draw one board now
                        {
                            (serverController as OthelloLib.Board).DrawBoard();
                        }
                        else if (!testPlayer1)
                        {
                            throw new Exception("Board state of player 1 is incorrect");
                        }
                        else if (!testPlayer2)
                        {
                            throw new Exception("Board state of player 2 is incorrect");
                        }
                    }
                }
                // SWAP players and color
                whitePlays   = !whitePlays;
                activePlayer = (activePlayer == player1) ? player2 : player1;

                System.Threading.Thread.Sleep(2000); // slow down game speed or //Console.ReadKey();
            } // end of GAMELOOP
            #endregion

            if (serverController.GetBlackScore() > serverController.GetWhiteScore())
            {
                Console.WriteLine($"{player1.GetName()} WINS!" + player1.GetBlackScore() + " - " + player1.GetWhiteScore());
            }
            else
            {
                Console.WriteLine($"{player2.GetName()} WINS!" + player1.GetWhiteScore() + " - " + player1.GetBlackScore());
            }
            Console.WriteLine("END OF GAME, FAREWELL!");
            Console.ReadKey();
        }
Ejemplo n.º 7
0
 public AI(IPlayable.IPlayable board)
 {
     this.board = board;
 }