private string provDate;        // [SC] set to DEF_DATE in the constructor

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the TwoA.DifficultyAdapter class.
        ///
        /// Assign default values if max play frequency and max non-play delay values
        /// are not provided.
        ///
        /// Add a reference to the TwoA asset so we can use it.
        /// </summary>
        ///
        /// <remarks>
        /// Alternative for the asset parameter would be to ask the AssetManager for
        /// a reference.
        /// </remarks>
        ///
        /// <param name="asset"> The asset. </param>
        internal DifficultyAdapter(TwoA asset)
        {
            maxPlay  = DEF_MAX_PLAY;
            maxDelay = DEF_MAX_DELAY;

            kConst = DEF_K;
            kUp    = DEF_K_UP;
            kDown  = DEF_K_DOWN;

            provU = DEF_U;

            provDate = DEF_DATE;

            this.asset = asset; // [ASSET]
        }
Example #2
0
 /// <summary>
 /// Initializes a new instance of the TwoA.KSGenerator class with a default threshold value.
 /// </summary>
 ///
 /// <param name="asset">The asset.</param>
 public KSGenerator(TwoA asset) : this(asset, KSGenerator.DEFAULT_THRESHOLD)
 {
     // [SC] blank constructor body
 }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the TwoA.KSGenerator class with a custom threshold.
 /// </summary>
 ///
 /// <param name="asset">        The asset. </param>
 /// <param name="threshold">    A custom threshold value. </param>
 public KSGenerator(TwoA asset, double threshold)
 {
     this.asset           = asset;
     this.Threshold       = threshold;
     this.SameProbability = KSGenerator.DEFAULT_SAME_PROBABILITY;
 }
Example #4
0
        static void doTileZeroSimulation()
        {
            string adaptID  = "Game difficulty - Player skill";
            string gameID   = "TileZeroSimul";
            string playerID = "EvolvingAI";

            // [SC] do not update xml files
            bool updateDatafiles = false;

            // [SC] to randomly decide which player moves first
            Random rnd = new Random();
            // [SC] creating a game object
            Game tzGame = new Game();

            // [SC] disable logging to speed-up simulation
            Cfg.enableLog(false);

            double numberOfSimulations = 10;
            double numberOfMatches     = 400; // [SC] the number of games to be played with each AI evolution
            int    playableTileCount   = 54;
            double minRT = 60000;

            double distMean   = 0.75;
            double distSD     = 0.1;
            double lowerLimit = 0.5;
            double upperLimit = 1.0;

            // [SC] a player is represented by an AI evolving from Very Easy AI to Very Hard AI
            string[] aiOneEvolution = { TileZero.Cfg.VERY_EASY_AI
                                        , TileZero.Cfg.EASY_AI
                                        , TileZero.Cfg.MEDIUM_COLOR_AI
                                        , TileZero.Cfg.MEDIUM_SHAPE_AI
                                        , TileZero.Cfg.HARD_AI
                                        , TileZero.Cfg.VERY_HARD_AI };

            // [SC] start simulations
            for (int simIndex = 0; simIndex < numberOfSimulations; simIndex++)
            {
                TwoA twoA = new TwoA(new MyBridge());
                twoA.SetTargetDistribution(distMean, distSD, lowerLimit, upperLimit);
                double avgAccuracy = 0;

                // [SC] start AI player evolution from easiest to hardest
                foreach (string aiOneID in aiOneEvolution)
                {
                    // [SC] play a number of games before eacg evolution
                    for (int matchIndex = 0; matchIndex < numberOfMatches; matchIndex++)
                    {
                        // [SC] get a recommended opponent AI from TwoA
                        string aiTwoID = null;

                        aiTwoID = twoA.TargetScenarioID(adaptID, gameID, playerID);

                        Cfg.clearLog();

                        // [SC] start one match simualtion
                        int startPlayerIndex = rnd.Next(2); // [SC] decide whether the player or the opponent moves first
                        tzGame.initNewGame(aiOneID, aiTwoID, playableTileCount, startPlayerIndex);
                        tzGame.startNewGame();

                        // [SC] simulate player's response time
                        SimpleRNG.SetSeedFromRandom();
                        double rt = SimpleRNG.GetNormal(120000, 10000); // [SC] max is 900000
                        if (rt < minRT)
                        {
                            rt = minRT;
                        }

                        // [SC] obtain player's accuracy
                        double correctAnswer = 0;
                        if (tzGame.getPlayerByIndex(0).WinFlag)
                        {
                            correctAnswer = 1;
                        }

                        avgAccuracy += correctAnswer;

                        printMsg("Counter: " + (matchIndex + 1) + "; Start index: " + startPlayerIndex);
                        //printMsg(TileZero.Cfg.getLog());

                        // [SC] update ratings
                        twoA.UpdateRatings(adaptID, gameID, playerID, aiTwoID, rt, correctAnswer, updateDatafiles);
                    }
                }

                printMsg(String.Format("Accurracy for simulation {0}: {1}", simIndex, avgAccuracy / (numberOfMatches * aiOneEvolution.Length)));

                // [SC] creating a file with final ratings
                using (StreamWriter ratingfile = new StreamWriter("S4/ratingfile" + simIndex + ".txt")) {
                    string line = ""
                                  + "\"ScenarioID\""
                                  + "\t" + "\"Rating\""
                                  + "\t" + "\"PlayCount\""
                                  + "\t" + "\"Uncertainty\"";

                    ratingfile.WriteLine(line);

                    foreach (string scenarioID in aiOneEvolution)
                    {
                        line = ""
                               + "\"" + scenarioID + "\""
                               + "\t" + "\"" + twoA.ScenarioRating(adaptID, gameID, scenarioID) + "\""
                               + "\t" + "\"" + twoA.ScenarioPlayCount(adaptID, gameID, scenarioID) + "\""
                               + "\t" + "\"" + twoA.ScenarioUncertainty(adaptID, gameID, scenarioID) + "\"";

                        ratingfile.WriteLine(line);
                    }
                }

                // [SC] creating a file with history of gameplays including player and scenario ratings
                using (StreamWriter datafile = new StreamWriter("S4/datafile" + simIndex + ".txt")) {
                    GameplaysData  gameplays = twoA.GameplaysData;
                    TwoAAdaptation adaptNode = gameplays.Adaptation.First(p => p.AdaptationID.Equals(adaptID));
                    TwoAGame       gameNode  = adaptNode.Game.First(p => p.GameID.Equals(gameID));

                    string line = ""
                                  + "\"ID\""
                                  + "\t" + "\"PlayerID\""
                                  + "\t" + "\"ScenarioID\""
                                  + "\t" + "\"Timestamp\""
                                  + "\t" + "\"RT\""
                                  + "\t" + "\"Accuracy\""
                                  + "\t" + "\"PlayerRating\""
                                  + "\t" + "\"ScenarioRating\"";

                    datafile.WriteLine(line);

                    int id = 1;
                    foreach (TwoAGameplay gp in gameNode.Gameplay)
                    {
                        line = ""
                               + "\"" + id++ + "\""
                               + "\t" + "\"" + gp.PlayerID + "\""
                               + "\t" + "\"" + gp.ScenarioID + "\""
                               + "\t" + "\"" + gp.Timestamp + "\""
                               + "\t" + "\"" + gp.RT + "\""
                               + "\t" + "\"" + gp.Accuracy + "\""
                               + "\t" + "\"" + gp.PlayerRating + "\""
                               + "\t" + "\"" + gp.ScenarioRating + "\"";

                        datafile.WriteLine(line);
                    }
                }
            }
        }
Example #5
0
 internal BaseAdapter(TwoA asset)
 {
     this.asset = asset;
 }
        public static void doOneTwoThreeSimControl()
        {
            string adaptID = "Game difficulty - Player skill";
            string gameID  = "OneTwoThree";

            // [SC] create Bridge instance
            MyBridge bridge = new MyBridge();

            // [SC] instantiate the TwoA asset
            TwoA twoA = new TwoA(bridge);

            // [SC] a lis of player in order of gameplays in datafile
            List <DataRecord> dataRecordList = new List <DataRecord>();

            // [SC] contains info about scenarios such as level and mirror group
            Dictionary <string, ScenarioData> scenarioDatabase = new Dictionary <string, ScenarioData>();

            // [SC] load the data file
            Dictionary <int, PlayerData> playerDatabase = parseOneTwoThreeDatafile(twoA, adaptID, gameID, dataRecordList, scenarioDatabase);

            if (playerDatabase == null)
            {
                return;
            }

            foreach (DataRecord dataRecord in dataRecordList)
            {
                twoA.UpdateRatings(adaptID, gameID, "" + dataRecord.PlayerID, dataRecord.ScenarioID, dataRecord.RT, dataRecord.Accuracy, false);
            }

            // [SC] creating a file with final ratings
            using (StreamWriter ratingfile = new StreamWriter(Path.Combine(OneTwoThreeSimResultsPath, "ratings_control.txt"))) {
                string line = ""
                              + "\"ScenarioID\""
                              + "\t" + "\"Rating\""
                              + "\t" + "\"PlayCount\""
                              + "\t" + "\"Uncertainty\""
                              + "\t" + "\"MirrorID\""
                              + "\t" + "\"SetLevel\"";

                ratingfile.WriteLine(line);

                foreach (ScenarioData scenarioData in scenarioDatabase.Values)
                {
                    line = ""
                           + "\"" + scenarioData.ScenarioID + "\""
                           + "\t" + "\"" + twoA.ScenarioRating(adaptID, gameID, scenarioData.ScenarioID) + "\""
                           + "\t" + "\"" + twoA.ScenarioPlayCount(adaptID, gameID, scenarioData.ScenarioID) + "\""
                           + "\t" + "\"" + twoA.ScenarioUncertainty(adaptID, gameID, scenarioData.ScenarioID) + "\""
                           + "\t" + "\"" + scenarioData.MirrorID + "\""
                           + "\t" + "\"" + scenarioData.SetLevel + "\"";

                    ratingfile.WriteLine(line);
                }
            }

            // [SC] creating a file with history of gameplays including player and scenario ratings
            using (StreamWriter datafile = new StreamWriter(Path.Combine(OneTwoThreeSimResultsPath, "gameplay_control.txt"))) {
                GameplaysData  gameplays = twoA.GameplaysData;
                TwoAAdaptation adaptNode = gameplays.Adaptation.First(p => p.AdaptationID.Equals(adaptID));
                TwoAGame       gameNode  = adaptNode.Game.First(p => p.GameID.Equals(gameID));

                string line = ""
                              + "ID"
                              + "\t" + "PlayerID"
                              + "\t" + "ScenarioID"
                              //+ "\t" + "Timestamp"
                              + "\t" + "RT"
                              + "\t" + "ccuracy"
                              + "\t" + "PlayerRating"
                              + "\t" + "ScenarioRating";

                datafile.WriteLine(line);

                int id = 1;
                foreach (TwoAGameplay gp in gameNode.Gameplay)
                {
                    /*line = ""
                     + "\"" + id++ + "\""
                     + "\t" + "\"" + gp.PlayerID + "\""
                     + "\t" + "\"" + gp.ScenarioID + "\""
                     + "\t" + "\"" + gp.Timestamp + "\""
                     + "\t" + "\"" + gp.RT + "\""
                     + "\t" + "\"" + gp.Accuracy + "\""
                     + "\t" + "\"" + gp.PlayerRating + "\""
                     + "\t" + "\"" + gp.ScenarioRating + "\"";*/

                    line = ""
                           + id++
                           + "\t" + gp.PlayerID
                           + "\t" + gp.ScenarioID
                           + "\t" + gp.RT
                           + "\t" + gp.Accuracy
                           + "\t" + Math.Round(gp.PlayerRating, 5)
                           + "\t" + Math.Round(gp.ScenarioRating, 5);

                    datafile.WriteLine(line);
                }
            }
        }
        private static Dictionary <int, PlayerData> parseOneTwoThreeDatafile(TwoA twoA, string adaptId, string gameId, List <DataRecord> dataRecordList, Dictionary <string, ScenarioData> scenarioDatabase)
        {
            using (StreamReader reader = new StreamReader(Path.Combine(contentPath, "user_data.txt"))) {
                string line       = null;
                bool   headerFlag = true;

                char[] separators = new char[] { '\t' };

                Dictionary <int, PlayerData> playerDatabase = new Dictionary <int, PlayerData>();

                int lastCounted     = 0;
                int counter         = 0;
                int counterInterval = 100000;

                while ((line = reader.ReadLine()) != null)
                {
                    if (headerFlag)
                    {
                        // [SC] skip header
                        headerFlag = false;
                        continue;
                        //TrialID	UserID	MirrorID	ItemID	SetLevel	C1	C2	C3	RT	Correct
                    }

                    string[] cols = line.Split(separators);

                    string mirrorId = cols[2];
                    string scenarioId = cols[3];
                    int    trialId, playerId, setLevel, accuracy, rt;
                    if (!(Int32.TryParse(cols[0], out trialId) &&
                          Int32.TryParse(cols[1], out playerId) &&
                          Int32.TryParse(cols[4], out setLevel) &&
                          Int32.TryParse(cols[9], out accuracy) &&
                          Int32.TryParse(cols[8], out rt)
                          ))
                    {
                        // [SC] parsing error
                        return(null);
                    }

                    dataRecordList.Add(new DataRecord {
                        TrialID    = trialId,
                        PlayerID   = playerId,
                        MirrorID   = mirrorId,
                        ScenarioID = scenarioId,
                        SetLevel   = setLevel,
                        RT         = rt,
                        Accuracy   = accuracy
                    });

                    PlayerData playerData;
                    if (!playerDatabase.TryGetValue(playerId, out playerData))
                    {
                        playerData = new PlayerData(playerId);
                        playerDatabase.Add(playerId, playerData);
                        twoA.AddPlayer(adaptId, gameId, "" + playerId);
                    }

                    ScenarioData scenarioData = playerData.AddScenario(mirrorId, scenarioId, setLevel);
                    scenarioData.AddRecord(trialId, accuracy, rt);
                    twoA.AddScenario(adaptId, gameId, scenarioId);

                    if (!scenarioDatabase.ContainsKey(scenarioId))
                    {
                        scenarioDatabase.Add(scenarioId, new ScenarioData(mirrorId, scenarioId, setLevel));
                    }
                    ScenarioData scenarioDataPooled = scenarioDatabase[scenarioId];
                    scenarioDataPooled.AddRecord(trialId, accuracy, rt);

                    if (++counter - lastCounted == counterInterval)
                    {
                        lastCounted = counter;
                        printMsg("" + counter);
                    }
                }

                // [SC] for test purpose only

                /*printMsg(String.Format("Number of trials in the ordered list: {0}", playerOrderedList.Count));
                 *
                 * GameNode gameNode = twoA.AdaptationData.AdaptationList.First(p => p.AdaptationID.Equals(adaptId)).GameList.First(p => p.GameID.Equals(gameId));
                 * printMsg(String.Format("Player count in list and dictionary: {0}, {1} "
                 *  , gameNode.PlayerData.PlayerList.Count, gameNode.PlayerData.playerDict.Count));
                 * printMsg(String.Format("Scenario count in list and in dictionary: {0}, {1}"
                 *  , gameNode.ScenarioData.ScenarioList.Count, gameNode.ScenarioData.scenarioDict.Count));*/

                // [SC] for test purpose only

                /*foreach (KeyValuePair<int, PlayerData> playerDataPair in playerDatabase) {
                 *  PlayerData playerData = playerDataPair.Value;
                 *  printMsg(String.Format("Player key: {0}, {1}", playerDataPair.Key, playerData.PlayerID));
                 *
                 *  foreach (KeyValuePair<string, ScenarioData> scenarioDataPair in playerData.scenarioDatabase) {
                 *      ScenarioData scenarioData = scenarioDataPair.Value;
                 *      printMsg(String.Format("\tScenario key: {0}, {1}", scenarioDataPair.Key, scenarioData.ScenarioID));
                 *      printMsg(String.Format("\tScenario mirror ID: {0}, SetLevel: {1}", scenarioData.MirrorID, scenarioData.SetLevel));
                 *
                 *      foreach (ScenarioRecord record in scenarioData.scenarioRecords) {
                 *          printMsg(String.Format("\t\tTrialID: {0}, RT: {1}, Accuracy: {2}, Used: {3}", record.TrialID, record.RT, record.Accuracy, record.Used));
                 *      }
                 *  }
                 * }*/

                // [SC] for test purpose only

                /*int trialCounter = 0;
                 * foreach (KeyValuePair<int, PlayerData> playerDataPair in playerDatabase) {
                 *  PlayerData playerData = playerDataPair.Value;
                 *
                 *  foreach (KeyValuePair<string, ScenarioData> scenarioDataPair in playerData.scenarioDatabase) {
                 *      ScenarioData scenarioData = scenarioDataPair.Value;
                 *
                 *      trialCounter += scenarioData.scenarioRecords.Count;
                 *  }
                 * }
                 * if (1383964 != trialCounter) {
                 *  printMsg("Invalid number of trial records.");
                 * } else {
                 *  printMsg("All trial records parsed");
                 * }*/

                printMsg("================= Data file parsed.");

                return(playerDatabase);
            }
        }
        public static void doOneTwoThreeSim()
        {
            string adaptID = "Game difficulty - Player skill";
            string gameID  = "OneTwoThree";

            // [SC] create Bridge instance
            MyBridge bridge = new MyBridge();

            // [SC] instantiate the TwoA asset
            TwoA   twoA       = new TwoA(bridge);
            double distMean   = 0.75;
            double distSD     = 0.1;
            double lowerLimit = 0.5;
            double upperLimit = 1.0;

            twoA.SetTargetDistribution(distMean, distSD, lowerLimit, upperLimit);

            // [SC] a lis of player in order of gameplays in datafile
            List <DataRecord> dataRecordList = new List <DataRecord>();

            // [SC] contains info about scenarios such as level and mirror group
            Dictionary <string, ScenarioData> scenarioDatabase = new Dictionary <string, ScenarioData>();

            // [SC] load the data file
            Dictionary <int, PlayerData> playerDatabase = parseOneTwoThreeDatafile(twoA, adaptID, gameID, dataRecordList, scenarioDatabase);

            if (playerDatabase == null)
            {
                return;
            }

            int blockSize = 20;

            foreach (string mode in new string[] { "old", "new" })
            {
                for (int blockIndex = 0; blockIndex < blockSize; blockIndex++)
                {
                    int lastCounted     = 0;
                    int counter         = 0;
                    int counterInterval = 10000;

                    // [SC] approach 1

                    /*foreach (DataRecord dataRecord in dataRecordList) {
                     *  int playerID = dataRecord.PlayerID;
                     *
                     *  // [SC] decide which scenario this player should play
                     *  string scenarioID = twoA.TargetScenarioIDOld(adaptID, gameID, "" + playerID, true);
                     *
                     *  // [SC] obtain response time and accuracy
                     *  PlayerData playerData = playerDatabase[playerID];
                     *  ScenarioData scenarioData = playerData.GetScenario(scenarioID);
                     *  if (scenarioData == null) { // [SC] the player has not played the scenario
                     *      // [SC] use another scenario of similar set level
                     *      int setLevel = scenarioDatabase[scenarioID].SetLevel;
                     *      scenarioData = playerData.GetScenario(setLevel); // [TODO] possible error point
                     *  }
                     *  if (scenarioData == null) {
                     *      ScenarioData scenarioDataOverall = scenarioDatabase[scenarioID];
                     *      twoA.UpdateRatings(adaptID, gameID, "" + playerID, scenarioID
                     *          , scenarioDataOverall.GetAvgRT(), scenarioDataOverall.GetAvgAccuracy(), false);
                     *  }
                     *  else {
                     *      ScenarioRecord scenarioRecord = scenarioData.GetRecord();
                     *      twoA.UpdateRatings(adaptID, gameID, "" + playerID, scenarioID, scenarioRecord.RT, scenarioRecord.Accuracy, false);
                     *  }
                     *
                     *  if (++counter - lastCounted == counterInterval) {
                     *      lastCounted = counter;
                     *      printMsg("" + counter);
                     *  }
                     * }*/

                    // [SC] approach 2
                    foreach (DataRecord dataRecord in dataRecordList)
                    {
                        int playerID = dataRecord.PlayerID;

                        // [SC] decide which scenario this player should play
                        string scenarioID;
                        if (mode.Equals("old"))
                        {
                            scenarioID = twoA.TargetScenarioIDOld(adaptID, gameID, "" + playerID, true);
                        }
                        else
                        {
                            scenarioID = twoA.TargetScenarioID(adaptID, gameID, "" + playerID);
                        }

                        // [SC] obtain response time and accuracy
                        PlayerData     playerData   = playerDatabase[playerID];
                        ScenarioData   scenarioData = playerData.GetScenario(scenarioID);
                        ScenarioRecord scenarioRecord;
                        if (scenarioData == null)   // [SC] the player has not played the scenario
                        // [SC] use a random record from all players of the scenario
                        {
                            ScenarioData scenarioDataOverall = scenarioDatabase[scenarioID];
                            scenarioRecord = scenarioDataOverall.GetRandomRecord();
                        }
                        else
                        {
                            scenarioRecord = scenarioData.GetRecord();
                        }

                        twoA.UpdateRatings(adaptID, gameID, "" + playerID, scenarioID, scenarioRecord.RT, scenarioRecord.Accuracy, false);

                        if (++counter - lastCounted == counterInterval)
                        {
                            lastCounted = counter;
                            printMsg("" + counter);
                        }
                    }

                    // [SC] approach 3

                    /*foreach (DataRecord dataRecord in dataRecordList) {
                     *  //int playerID = dataRecord.PlayerID;
                     *  int playerID = dataRecordList[0].PlayerID;
                     *
                     *  // [SC] decide which scenario this player should play
                     *  string scenarioID;
                     *  if (mode.Equals("old")) {
                     *      scenarioID = twoA.TargetScenarioIDOld(adaptID, gameID, "" + playerID, true);
                     *  }
                     *  else {
                     *      scenarioID = twoA.TargetScenarioID(adaptID, gameID, "" + playerID);
                     *  }
                     *
                     *  ScenarioData scenarioDataOverall = scenarioDatabase[scenarioID];
                     *  ScenarioRecord scenarioRecord = scenarioDataOverall.GetRandomRecord();
                     *  twoA.UpdateRatings(adaptID, gameID, "" + playerID, scenarioID, scenarioRecord.RT, scenarioRecord.Accuracy, false);
                     *
                     *  if (++counter - lastCounted == counterInterval) {
                     *      lastCounted = counter;
                     *      printMsg("" + counter);
                     *  }
                     * }*/

                    // [SC] creating a file with final ratings
                    using (StreamWriter ratingfile = new StreamWriter(Path.Combine(OneTwoThreeSimResultsPath, "ratings_" + mode + "_" + blockIndex + ".txt"))) {
                        string line = ""
                                      + "\"ScenarioID\""
                                      + "\t" + "\"Rating\""
                                      + "\t" + "\"PlayCount\""
                                      + "\t" + "\"Uncertainty\""
                                      + "\t" + "\"MirrorID\""
                                      + "\t" + "\"SetLevel\"";

                        ratingfile.WriteLine(line);

                        foreach (ScenarioData scenarioData in scenarioDatabase.Values)
                        {
                            ScenarioNode scenarioNode = twoA.Scenario(adaptID, gameID, scenarioData.ScenarioID);

                            line = ""
                                   + "\"" + scenarioData.ScenarioID + "\""
                                   + "\t" + "\"" + scenarioNode.Rating + "\""
                                   + "\t" + "\"" + scenarioNode.PlayCount + "\""
                                   + "\t" + "\"" + scenarioNode.Uncertainty + "\""
                                   + "\t" + "\"" + scenarioData.MirrorID + "\""
                                   + "\t" + "\"" + scenarioData.SetLevel + "\"";

                            ratingfile.WriteLine(line);

                            // [SC] reseting scenario data
                            scenarioNode.Rating      = 0.001;
                            scenarioNode.PlayCount   = 0;
                            scenarioNode.KFactor     = 0.0075;
                            scenarioNode.Uncertainty = 1.0;
                            scenarioNode.LastPlayed  = "2012-12-31T11:59:59";
                        }
                    }

                    // [SC] creating a file with history of gameplays including player and scenario ratings
                    using (StreamWriter datafile = new StreamWriter(Path.Combine(OneTwoThreeSimResultsPath, "gameplay_" + mode + "_" + blockIndex + ".txt"))) {
                        GameplaysData  gameplays = twoA.GameplaysData;
                        TwoAAdaptation adaptNode = gameplays.Adaptation.First(p => p.AdaptationID.Equals(adaptID));
                        TwoAGame       gameNode  = adaptNode.Game.First(p => p.GameID.Equals(gameID));

                        string line = ""
                                      + "ID"
                                      + "\t" + "PlayerID"
                                      + "\t" + "ScenarioID"
                                      //+ "\t" + "Timestamp"
                                      + "\t" + "RT"
                                      + "\t" + "Accuracy"
                                      + "\t" + "PlayerRating"
                                      + "\t" + "ScenarioRating";

                        datafile.WriteLine(line);

                        int id = 1;
                        foreach (TwoAGameplay gp in gameNode.Gameplay)
                        {
                            /*line = ""
                             + "\"" + id++ + "\""
                             + "\t" + "\"" + gp.PlayerID + "\""
                             + "\t" + "\"" + gp.ScenarioID + "\""
                             + "\t" + "\"" + gp.Timestamp + "\""
                             + "\t" + "\"" + gp.RT + "\""
                             + "\t" + "\"" + gp.Accuracy + "\""
                             + "\t" + "\"" + gp.PlayerRating + "\""
                             + "\t" + "\"" + gp.ScenarioRating + "\"";*/

                            line = ""
                                   + id++
                                   + "\t" + gp.PlayerID
                                   + "\t" + gp.ScenarioID
                                   + "\t" + gp.RT
                                   + "\t" + gp.Accuracy
                                   + "\t" + Math.Round(gp.PlayerRating, 5)
                                   + "\t" + Math.Round(gp.ScenarioRating, 5);

                            datafile.WriteLine(line);
                        }

                        // [SC] clearing all gameplay
                        gameNode.Gameplay.Clear();
                    }

                    // [SC] resetting player data
                    List <PlayerNode> playerNodeList = twoA.AdaptationData.AdaptationList.First(p => p.AdaptationID.Equals(adaptID)).GameList.First(p => p.GameID.Equals(gameID)).PlayerData.PlayerList;
                    foreach (PlayerNode playerNode in playerNodeList)
                    {
                        playerNode.Rating      = 0.001;
                        playerNode.PlayCount   = 0;
                        playerNode.KFactor     = 0.0075;
                        playerNode.Uncertainty = 1.0;
                        playerNode.LastPlayed  = "2012-12-31T11:59:59";
                    }
                }
            }
        }