public GeneralGameManager(string gameDescriptionFileName, int startClock, int playClock, string wcfSvcHostExePath = null, string tempFilePath = null)
        {
            string error;

            AllMoves = new List <Move>();

            MilliSecondsBetweenFreeRunningMoves      = 0;
            AllowFreeRunningOfTurnsWithNoPlayerMoves = true;

            TheGeneralGame = new GeneralGame(wcfSvcHostExePath)
            {
                TempFilePath = tempFilePath
            };

            DebugAndTraceHelper.WriteTraceLine("Loading and parsing game description...", DebugAndTraceHelper.StatusStripChannelId);
            DebugAndTraceHelper.WriteTraceLine(String.Format("Started loading and parsing game description at {0}", DateTime.Now.ToLongTimeString()), DebugAndTraceHelper.ManagerChannelId);
            TheGeneralGame.LoadDescriptionFromKIFFile(gameDescriptionFileName);
            DebugAndTraceHelper.WriteTraceLine(String.Format("Finished loading and parsing game description at {0}", DateTime.Now.ToLongTimeString()), DebugAndTraceHelper.ManagerChannelId);

            DebugAndTraceHelper.WriteTraceLine("Initializing game...", DebugAndTraceHelper.StatusStripChannelId);
            DebugAndTraceHelper.WriteTraceLine(String.Format("Started initializing game at {0}", DateTime.Now.ToLongTimeString()), DebugAndTraceHelper.ManagerChannelId);
            TheGeneralGame.InitializeGame(out error);
            DebugAndTraceHelper.WriteTraceLine(String.Format("Finished initializing game at {0}", DateTime.Now.ToLongTimeString()), DebugAndTraceHelper.ManagerChannelId);

            StartClock = startClock;
            PlayClock  = playClock;

            MatchId = DateTime.Now.ToString() + TheGeneralGame.Name;

            DebugAndTraceHelper.AddLogFileListener(DebugAndTraceHelper.ManagerChannelId);

            DebugAndTraceHelper.WriteTraceLine("Creating players...", DebugAndTraceHelper.StatusStripChannelId);
            Players = new List <IGeneralGamePlayer>();
            var roles = TheGeneralGame.FindRoles().ToArray();

            if (TheGeneralGame.Name == "DarkChess")
            {
                for (int i = 0; i < roles.Count(); i++)
                {
                    if (roles[i] != "random")
                    {
                        var newPlayer = new FirstDarkChessPlayer(roles[i], wcfSvcHostExePath, tempFilePath);
                        DebugAndTraceHelper.AddLogFileListener(roles[i]);
                        Players.Add(newPlayer);
                    }
                    else
                    {
                        var newPlayer = new FirstGeneralGamePlayer(roles[i], wcfSvcHostExePath, tempFilePath);
                        DebugAndTraceHelper.AddLogFileListener(roles[i]);
                        Players.Add(newPlayer);
                    }
                }
            }
            else
            {
                for (int i = 0; i < roles.Count(); i++)
                {
                    var newPlayer = new FirstGeneralGamePlayer(roles[i], wcfSvcHostExePath, tempFilePath);
                    DebugAndTraceHelper.AddLogFileListener(roles[i]);
                    Players.Add(newPlayer);
                }
            }

            foreach (TraceListener traceListener in DebugAndTraceHelper.GetListeners(DebugAndTraceHelper.StateChannelId))
            {
                var ieWebBrowserListener = traceListener as IEWebBrowserListener;
                if (ieWebBrowserListener != null)
                {
                    ieWebBrowserListener.xslFilePath = TheGeneralGame.XMLStyleSheetFilePath;
                }
            }
        }
        public bool Play()
        {
            IEnumerable <HornClause> satisfiedTerminalClauses;

            try
            {
                if (!CheckIfAllPlayersAreUpAndRunning())
                {
                    return(false);
                }

                var traceListener        = DebugAndTraceHelper.GetListeners(DebugAndTraceHelper.StateChannelId).FirstOrDefault();
                var ieWebBrowserListener = traceListener as IEWebBrowserListener;

                // show this in the game manager's web browser
                var initialStateAsXML = TheGeneralGame.GetStateAsCompleteXML();
                DebugAndTraceHelper.WriteTraceLine(initialStateAsXML, DebugAndTraceHelper.StateChannelId);

                TurnRecord initialTurnRecord = new TurnRecord();
                initialTurnRecord.IsInitialState           = true;
                initialTurnRecord.GameState.GameStateAsXML = initialStateAsXML;
                //initialTurnRecord.GameState.GameStateAsHTML = ieWebBrowserListener == null ? "" : ieWebBrowserListener.ieWebBrowser.DocumentText;
                TurnRecords.Add(initialTurnRecord);

                IFormatter formatter       = new BinaryFormatter();
                var        historyFileName = DebugAndTraceHelper.CustomLocation + DebugAndTraceHelper.BaseFileName + "_" +
                                             (DateTime.Now.ToShortDateString() + "_" + DateTime.Now.ToLongTimeString()).Replace(" ", "_").Replace(@"/", "-").Replace(":", "-") + ".his";

                DebugAndTraceHelper.WriteTraceLine("Starting Players...", DebugAndTraceHelper.StatusStripChannelId);
                StartAllPlayers();

                var prevMoves = new List <Move>();
                DebugAndTraceHelper.WriteTraceLine("Checking for game termination...", DebugAndTraceHelper.StatusStripChannelId);
                bool gameHasTerminated = TheGeneralGame.FindTerminal(out satisfiedTerminalClauses);
                Move terminalMove      = null;
                while (!gameHasTerminated)
                {
                    DebugAndTraceHelper.WriteTraceLine("Waiting for next moves...", DebugAndTraceHelper.StatusStripChannelId);
                    var nextMoves = GetNextMoves(prevMoves);
                    RecordMoves(nextMoves);

                    DebugAndTraceHelper.WriteTraceLine("**** moves ****", DebugAndTraceHelper.ManagerChannelId);
                    foreach (Move nextMove in nextMoves)
                    {
                        DebugAndTraceHelper.WriteTraceLine(nextMove.Role + " makes move " + nextMove.TheMove, DebugAndTraceHelper.ManagerChannelId);
                    }

                    // ToDo:
                    DebugAndTraceHelper.WriteTraceLine("Checking for game termination...", DebugAndTraceHelper.StatusStripChannelId);

                    TheGeneralGame.ApplyMoves(nextMoves);
                    if (TheGeneralGame.FindTerminal(out satisfiedTerminalClauses))
                    {
                        gameHasTerminated = true;
                        DebugAndTraceHelper.WriteTraceLine(
                            String.Format("******** Game Ended for reason(s) {0} ********",
                                          String.Join(", ", satisfiedTerminalClauses)), DebugAndTraceHelper.ManagerChannelId);
                        terminalMove = nextMoves.Where(n => !n.IsNoop()).FirstOrDefault();
                    }

                    var stateAsXML = TheGeneralGame.GetStateAsCompleteXML();
                    DebugAndTraceHelper.WriteTraceLine(stateAsXML, DebugAndTraceHelper.StateChannelId);

                    prevMoves = nextMoves;

                    // serialize the history information
                    TurnRecord thisTurnRecord = new TurnRecord();
                    thisTurnRecord.Turn = TheGeneralGame.CurrentTurn;
                    thisTurnRecord.GameState.GameStateAsXML      = stateAsXML;
                    thisTurnRecord.GameState.GameStateFromProlog =
                        TheGeneralGame.PrologEngine.ListAll(sortAlphabetically: false).Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                    thisTurnRecord.Moves = nextMoves;
                    //thisTurnRecord.GameState.GameStateAsHTML = ieWebBrowserListener == null ? "" : ieWebBrowserListener.ieWebBrowser.DocumentText;
                    thisTurnRecord.IsTerminalState = gameHasTerminated;
                    TurnRecords.Add(thisTurnRecord);
                    using (FileStream s = File.Create(historyFileName))
                    {
                        formatter.Serialize(s, TurnRecords);
                    }

                    if (gameHasTerminated)
                    {
                        DebugAndTraceHelper.WriteTraceLine("Game has ended", DebugAndTraceHelper.StatusStripChannelId);
                    }
                    else
                    {
                        if (StartNextMoveEvent != null && (!AllowFreeRunningOfTurnsWithNoPlayerMoves || nextMoves.Where(n => !n.IsTheRandomRole() && !n.IsNoop()).Any()))
                        {
                            DebugAndTraceHelper.WriteTraceLine("Please click next turn button to go to next turn...", DebugAndTraceHelper.StatusStripChannelId);
                            StartNextMoveEvent.WaitOne();
                        }
                        else
                        {
                            if (MilliSecondsBetweenFreeRunningMoves >= 0)
                            {
                                if (AllowFreeRunningOfTurnsWithNoPlayerMoves && !nextMoves.Where(n => !n.IsTheRandomRole() && !n.IsNoop()).Any())
                                {
                                    Thread.Sleep(MilliSecondsBetweenFreeRunningMoves / 4);
                                }
                                else
                                {
                                    Thread.Sleep(MilliSecondsBetweenFreeRunningMoves);
                                }
                            }
                        }
                    }
                }

                var scores = TheGeneralGame.FindScores();
                DebugAndTraceHelper.WriteTraceLine("**** scores ****", DebugAndTraceHelper.ManagerChannelId);
                foreach (Score score in scores)
                {
                    DebugAndTraceHelper.WriteTraceLine(score, DebugAndTraceHelper.ManagerChannelId);
                }

                StopAllPlayers(terminalMove);

                return(true);
            }
            catch (Exception ex)
            {
                throw;
            }
        }