public void ToExitStatus_ReturnExpected_Yes(Winner winner, ExitStatus es)
 {
     Assert.Equal(es, winner.ToExitStatus());
 }
        /// <summary>
        /// Run a session of ColorShapeLinks matches.
        /// </summary>
        /// <param name="complete">
        /// Is the session complete, i.e., should thinkers compete against each
        /// other two times, home and away?
        /// </param>
        /// <returns>
        /// An exit status according to what is defined in
        /// <see cref="ExitStatus"/>.
        /// </returns>
        public ExitStatus Run(bool complete)
        {
            // The exit status
            ExitStatus exitStatus = default;

            // Create a new session (the model in MVC)
            session = new Session(thinkerPrototypes, sessionConfig, complete);

            // Notify listeners that session is about to start
            BeforeSession?.Invoke(this);

            // Play each match defined by the session
            while (session.NextMatch(out currentMatch))
            {
                // Create a new board for the current match
                board = new Board(matchConfig.Rows, matchConfig.Cols,
                                  matchConfig.WinSequence, matchConfig.RoundPiecesPerPlayer,
                                  matchConfig.SquarePiecesPerPlayer);

                // Instantiate thinkers for the current match
                currentThinkers[(int)PColor.White] =
                    currentMatch.thinkerWhite.Create();
                currentThinkers[(int)PColor.Red] =
                    currentMatch.thinkerRed.Create();

                // Add registered listeners to the thinker instances
                foreach (IThinkerListener listener in thinkerListeners)
                {
                    foreach (IThinker thinker in currentThinkers)
                    {
                        listener.ListenTo(thinker);
                    }
                }

                // Create a match controller for the current match
                MatchController mc = new MatchController(matchConfig, this);

                // Register match listeners with the match controller
                foreach (IMatchListener listener in matchListeners)
                {
                    listener.ListenTo(mc);
                }

                // Notify listeners that a match is about to start
                BeforeMatch?.Invoke(currentMatch);

                // Ask the controller to run the match and keep the result
                lastMatchResult = mc.Run();

                // Update variables and properties related to the match result
                exitStatus = lastMatchResult.ToExitStatus();

                // Update the winner string
                if (lastMatchResult != Winner.Draw)
                {
                    PColor winnerColor = lastMatchResult.ToPColor();
                    WinnerString = winnerColor.FormatName(
                        currentThinkers[(int)winnerColor].ToString());
                }
                else
                {
                    WinnerString = lastMatchResult.ToString();
                }

                // Notify result to session
                session.SetResult(lastMatchResult);

                // Notify listeners that a match is over
                AfterMatch?.Invoke(currentMatch, this);
            }

            // Notify listeners that sessions is about to end
            AfterSession?.Invoke(this);

            // The exit status will either be for a complete session of
            // associated with the match result
            return(complete ? ExitStatus.Session : exitStatus);
        }