Exemplo n.º 1
0
        static void SaveMergedMGScript(List <AlignmentPoint> alignmentPoints, string outputPath, List <string> mgLeftovers)
        {
            using (StreamWriter swOut = FileUtils.CreateDirectoriesAndOpen(outputPath, FileMode.Create))
            {
                //iterate through each dialogue in PS3 list
                List <string> currentPS3ToSave        = new List <string>();
                List <string> currentMangaGamerToSave = new List <string>();

                foreach (AlignmentPoint alignmentPoint in alignmentPoints)
                {
                    if (alignmentPoint.ps3DialogFragment != null)
                    {
                        PS3DialogueFragment ps3 = alignmentPoint.ps3DialogFragment;
                        currentPS3ToSave.AddRange(ps3.previousLinesOrInstructions);
                        if (ps3.fragmentID == 0)
                        {
                            currentPS3ToSave.Add(ps3.parent.translatedRawXML);
                        }
                        //add a comment detailing the fragment information. NOTE: double hypen (--) is not allowed in XML comments
                        currentPS3ToSave.Add($"<!-- [{ps3.ID}.{ps3.fragmentID} > {(ps3.otherDialogue == null ? "NULL" : ps3.otherDialogue.ID.ToString())}]: {ps3.data} -->");
                    }

                    if (alignmentPoint.mangaGamerDialogue != null)
                    {
                        MangaGamerDialogue mg = alignmentPoint.mangaGamerDialogue;
                        currentMangaGamerToSave.AddRange(mg.previousLinesOrInstructions);
                        currentMangaGamerToSave.Add(mg.data);
                    }

                    if (alignmentPoint.ps3DialogFragment != null && alignmentPoint.mangaGamerDialogue != null)
                    {
                        WriteAssociatedPS3StringChunksFormatted(swOut, currentMangaGamerToSave, currentPS3ToSave);

                        currentPS3ToSave.Clear();
                        currentMangaGamerToSave.Clear();
                    }
                }

                //write out any leftover ps3 lines
                WriteAssociatedPS3StringChunksFormatted(swOut, currentMangaGamerToSave, currentPS3ToSave);

                //write out any leftover manga gamer lines
                StringUtils.WriteStringList(swOut, mgLeftovers);
            }
        }
Exemplo n.º 2
0
        public static void PrintSideBySideDiff(List <AlignmentPoint> alignmentPoints, out string mg_debug, out string ps3_debug)
        {
            StringWriter swMG  = new StringWriter();
            StringWriter swPS3 = new StringWriter();

            //iterate through each dialogue in PS3 list
            List <string> currentPS3ToSave        = new List <string>();
            List <string> currentMangaGamerToSave = new List <string>();

            foreach (AlignmentPoint alignmentPoint in alignmentPoints)
            {
                //add the previous lines (instructions

                if (alignmentPoint.ps3DialogFragment != null)
                {
                    PS3DialogueFragment ps3 = alignmentPoint.ps3DialogFragment;
                    currentPS3ToSave.AddRange(ps3.previousLinesOrInstructions);
                    currentPS3ToSave.Add($">>>> [{ps3.ID}.{ps3.fragmentID} -> {(ps3.otherDialogue == null ? "NoMatch" : ps3.otherDialogue.ID.ToString())}]: {ps3.data}");
                }

                if (alignmentPoint.mangaGamerDialogue != null)
                {
                    MangaGamerDialogue mg = alignmentPoint.mangaGamerDialogue;
                    currentMangaGamerToSave.AddRange(mg.previousLinesOrInstructions);
                    currentMangaGamerToSave.Add($">>>> [{mg.ID} -> {(mg.otherDialogue == null ? "NoMatch" : mg.otherDialogue.ID.ToString())}]: {mg.data}");
                }

                if (alignmentPoint.ps3DialogFragment != null && alignmentPoint.mangaGamerDialogue != null)
                {
                    //Finally, top-pad the file with enough spaces so they line up (printing could be its own function)
                    WriteSideBySideTopPad(swMG, swPS3, currentMangaGamerToSave, currentPS3ToSave);
                    currentPS3ToSave.Clear();
                    currentMangaGamerToSave.Clear();
                }
            }

            WriteSideBySideTopPad(swMG, swPS3, currentMangaGamerToSave, currentPS3ToSave);
            currentPS3ToSave.Clear();
            currentMangaGamerToSave.Clear();

            mg_debug  = swMG.ToString();
            ps3_debug = swPS3.ToString();
        }
Exemplo n.º 3
0
        /// <summary>
        /// After basic matching, some alignment points will still remain unmatched. This function takes
        /// a single chunk of unmatched alignment points (not the whole list), and attempts to re-match them.
        /// </summary>
        /// <param name="unmatchedSequence"></param>
        /// <returns></returns>
        public static List <AlignmentPoint> ReMatchUnmatchedDialogue(List <AlignmentPoint> unmatchedSequence)
        {
            //if empty list given, just return an empty list
            if (unmatchedSequence.Count == 0)
            {
                return(new List <AlignmentPoint>());
            }

            List <MangaGamerDialogue>     unmatchedMGs          = new List <MangaGamerDialogue>();
            List <PS3DialogueFragment>    unmatchedPS3Fragments = new List <PS3DialogueFragment>();
            List <PS3DialogueInstruction> unmatchedPS3s         = new List <PS3DialogueInstruction>();

            HashSet <int> alreadySeenPS3ParentIDs = new HashSet <int>();
            Dictionary <int, PS3DialogueFragment> ps3DialogueIDToFirstFragmentMapping = new Dictionary <int, PS3DialogueFragment>();

            DebugUtils.Print("------------------------------------");
            foreach (AlignmentPoint ap in unmatchedSequence)
            {
                if (ap.mangaGamerDialogue != null)
                {
                    DebugUtils.Print($"MG line: {ap.mangaGamerDialogue.data}");
                    unmatchedMGs.Add(ap.mangaGamerDialogue);
                }

                if (ap.ps3DialogFragment != null)
                {
                    unmatchedPS3Fragments.Add(ap.ps3DialogFragment);

                    if (!alreadySeenPS3ParentIDs.Contains(ap.ps3DialogFragment.parent.ID))
                    {
                        ps3DialogueIDToFirstFragmentMapping.Add(ap.ps3DialogFragment.parent.ID, ap.ps3DialogFragment);
                        alreadySeenPS3ParentIDs.Add(ap.ps3DialogFragment.parent.ID);
                        DebugUtils.Print($"PS3 parent of below missing fragments [{ap.ps3DialogFragment.parent.ID}]: {ap.ps3DialogFragment.parent.data}");
                        unmatchedPS3s.Add(ap.ps3DialogFragment.parent);
                    }

                    DebugUtils.Print($"PS3 child [{ap.ps3DialogFragment.parent.ID}]: {ap.ps3DialogFragment.data}");
                }
            }

            //Try and match the unmatched lines
            List <InOrderLevenshteinMatcher.LevenshteinResult> greedyMatchResults = InOrderLevenshteinMatcher.DoMatching(unmatchedMGs, unmatchedPS3s);

            //Use the match results to set associations
            foreach (var result in greedyMatchResults)
            {
                MangaGamerDialogue mgToAssign = unmatchedMGs[result.mgIndex];
                //want to get the first ps3 fragment associated with the Dialogue. Use hashmap we made earlier.
                PS3DialogueFragment ps3FragmentToAssign = ps3DialogueIDToFirstFragmentMapping[unmatchedPS3s[result.ps3Index].ID];
                mgToAssign.Associate(ps3FragmentToAssign);
            }

            //iterate through the list and add alignment points appropriately
            List <AlignmentPoint> reAssociatedAlignmentPoints = GetAlignmentPointsFromMGPS3Array(unmatchedMGs, unmatchedPS3Fragments);

            //Debug: Print out re-assigned alignment points for debugging
            foreach (AlignmentPoint ap in reAssociatedAlignmentPoints)
            {
                DebugUtils.Print(ap.ToString());
            }

            return(reAssociatedAlignmentPoints);
        }
Exemplo n.º 4
0
        //This function performs the diff given the two lists of dialogue.
        //It then UPDATES the values in the mangaGamerDialogueList and the ps3DialogueList (the DialogueBase.other value is updated on each dialogue object!)
        //If a dialogue cannot be associated, it is set to NULL.
        public static List <AlignmentPoint> DoDiff(string tempFolderPath, List <MangaGamerDialogue> mangaGamerDialogueList, List <PS3DialogueFragment> ps3DialogueFragments, string debugFilenamePrefix = "")
        {
            //Convert PS3 Dialogue list into list of subsections before performing diff - this can be re-assembled later!
            string mangaGamerDiffInputPath = Path.Combine(tempFolderPath, debugFilenamePrefix + "_diffInputA.txt");
            string PS3DiffInputPath        = Path.Combine(tempFolderPath, debugFilenamePrefix + "_diffInputB.txt");
            string diffOutputPath          = Path.Combine(tempFolderPath, debugFilenamePrefix + "_diffOutput.txt");

            //write the diff-prepared manga gamer dialogue to a file
            WriteListOfDialogueToFile(mangaGamerDialogueList, mangaGamerDiffInputPath);

            //write the diff-prepared ps3 dialogue to a file
            WriteListOfDialogueToFile(ps3DialogueFragments, PS3DiffInputPath);

            //do the diff
            string diffResult = RunDiffTool(mangaGamerDiffInputPath, PS3DiffInputPath);

            //save the diff to file for debugging
            using (StreamWriter sw = FileUtils.CreateDirectoriesAndOpen(diffOutputPath, FileMode.Create))
            {
                sw.Write(diffResult);
            }

            List <AlignmentPoint> alignmentPoints = new List <AlignmentPoint>();

            using (StringReader reader = new StringReader(diffResult))
            {
                string line;
                //skip the header information
                while ((line = reader.ReadLine()) != null)
                {
                    if (line[0] == '@')
                    {
                        break;
                    }
                }

                //TODO: need to think of the best way to categorize all mangagamer lines...
                //a ' ' means lines are the same
                //a '+' means line is present in PS3 ONLY           (it was 'added' in the ps3 version)
                //a '-' means line is present in mangagamer ONLY    (it was 'removed' from the ps3 version)
                List <AlignmentPoint> unmatchedSequence = new List <AlignmentPoint>();
                int mgIndex  = 0;
                int ps3Index = 0;
                while ((line = reader.ReadLine()) != null)
                {
                    //classify the line type:
                    char lineType = line[0];
                    if (lineType == ' ') //lines match
                    {
                        PS3DialogueFragment dummyPS3Instruction = ps3DialogueFragments[ps3Index];
                        MangaGamerDialogue  currentMangaGamer   = mangaGamerDialogueList[mgIndex];

                        //associate the fragment with the mangagamer dialogue
                        currentMangaGamer.Associate(dummyPS3Instruction);

                        //re-match the unmatched sequence, then clear it for next iteration
                        alignmentPoints.AddRange(DialogueReMatcher.ReMatchUnmatchedDialogue(unmatchedSequence));
                        unmatchedSequence.Clear();

                        //add the just found instruction
                        alignmentPoints.Add(new AlignmentPoint(currentMangaGamer, dummyPS3Instruction));

                        mgIndex++;
                        ps3Index++;
                    }
                    else if (lineType == '+') //only exist in ps3
                    {
                        PS3DialogueFragment currentDialog = ps3DialogueFragments[ps3Index];
                        unmatchedSequence.Add(new AlignmentPoint(null, currentDialog));
                        ps3Index++;
                    }
                    else if (lineType == '-') //only exist in mangagamer
                    {
                        MangaGamerDialogue currentDialog = mangaGamerDialogueList[mgIndex];
                        unmatchedSequence.Add(new AlignmentPoint(currentDialog, null));
                        mgIndex++;
                    }
                }

                //Deal with any leftover unmatched sequences at the end of the file
                alignmentPoints.AddRange(DialogueReMatcher.ReMatchUnmatchedDialogue(unmatchedSequence));
            }

            return(alignmentPoints);
        }
Exemplo n.º 5
0
 public void Add(MangaGamerDialogue mgDialog)
 {
     otherMangaGamerDialogues.Add(mgDialog);
 }
Exemplo n.º 6
0
 public AlignmentPoint(MangaGamerDialogue mg, PS3DialogueFragment p)
 {
     mangaGamerDialogue = mg;
     ps3DialogFragment  = p;
 }
Exemplo n.º 7
0
        static PS3DialogueFragment SearchForBestPS3Dialogues(List <PS3DialogueFragment> ps3DialogueFragments, MangaGamerDialogue mgDialogueToSearch)
        {
            string mangaGamerChoiceForDiff = Differ.PrepareStringForDiff(mgDialogueToSearch.data);

            float lowestDistance         = float.MaxValue;
            PS3DialogueFragment bestFrag = null;

            foreach (var frag in ps3DialogueFragments)
            {
                string fragmentForDiff = Differ.PrepareStringForDiff(frag.data);

                //if ps3 fragment is of length 0, skip it
                if (fragmentForDiff.Length == 0)
                {
                    continue;
                }

                float rawLevenshtein    = (float)Fastenshtein.Levenshtein.Distance(mangaGamerChoiceForDiff, fragmentForDiff);
                float scaledLevenshtein = rawLevenshtein / Math.Max(mangaGamerChoiceForDiff.Length, fragmentForDiff.Length);

                if (scaledLevenshtein < lowestDistance)
                {
                    lowestDistance = scaledLevenshtein;
                    bestFrag       = frag;
                }
            }

            return(bestFrag);
        }