Пример #1
0
        internal RantDictionaryEntry GetEntry(Carrier carrier, int subtypeIndex, IEnumerable<RantDictionaryEntry> pool, RNG rng)
        {
            if (carrier == null) return pool.PickEntry(rng);
            
            RantDictionaryEntry result = null;

            // Handle match carriers
            foreach(var match in carrier.GetCarriers(CarrierComponent.Match))
                if (_matchTable.TryGetValue(match, out result)) return result;

            // Handle associative carriers
            foreach(var assoc in carrier.GetCarriers(CarrierComponent.Associative))
            {
                if (_assocTable.TryGetValue(assoc, out result))
                    pool = pool.Where(e => e.AssociatesWith(result));
                break;
            }

            // Handle match-associative carriers
            foreach(var massoc in carrier.GetCarriers(CarrierComponent.MatchAssociative))
            {
                if (_matchTable.TryGetValue(massoc, out result))
                    pool = pool.Where(e => e.AssociatesWith(result));
                break;
            }

            // Handle unique carriers
            foreach(var unique in carrier.GetCarriers(CarrierComponent.Unique))
            {
                HashSet<RantDictionaryEntry> usedSet;
                if (!_uniqueTable.TryGetValue(unique, out usedSet))
                {
                    usedSet = _uniqueTable[unique] = new HashSet<RantDictionaryEntry>();
                }

                pool = pool.Except(usedSet);
            }

            // Handle match-unique carriers
            foreach (var munique in carrier.GetCarriers(CarrierComponent.Unique))
            {
                if (_matchTable.TryGetValue(munique, out result))
                    pool = pool.Where(e => e != result);
            }

            // Handle relational carriers
            foreach(var relate in carrier.GetCarriers(CarrierComponent.Relational))
            {
                if (_assocTable.TryGetValue(relate, out result))
                    pool = pool.Where(e => e.RelatesWith(result));
            }

            // Handle match-relational carriers
            foreach (var relate in carrier.GetCarriers(CarrierComponent.MatchRelational))
            {
                if (_matchTable.TryGetValue(relate, out result))
                    pool = pool.Where(e => e.RelatesWith(result));
            }

            // Handle dissociative carriers
            foreach (var relate in carrier.GetCarriers(CarrierComponent.Dissociative))
            {
                if (_assocTable.TryGetValue(relate, out result))
                    pool = pool.Where(e => !e.RelatesWith(result));
            }

            // Handle match-dissociative carriers
            foreach (var relate in carrier.GetCarriers(CarrierComponent.MatchDissociative))
            {
                if (_matchTable.TryGetValue(relate, out result))
                    pool = pool.Where(e => !e.RelatesWith(result));
            }

            // Handle divergent carriers
            foreach (var diverge in carrier.GetCarriers(CarrierComponent.Divergent))
            {
                if (_assocTable.TryGetValue(diverge, out result))
                    pool = pool.Where(e => e.DivergesFrom(result));
            }

            // Handle match-divergent carriers
            foreach (var diverge in carrier.GetCarriers(CarrierComponent.MatchDivergent))
            {
                if (_matchTable.TryGetValue(diverge, out result))
                    pool = pool.Where(e => e.DivergesFrom(result));
            }

            result = pool.PickEntry(rng);

            // Handle rhyme carrier
            foreach (var rhyme in carrier.GetCarriers(CarrierComponent.Rhyme))
            {
                _<RantDictionaryTerm, HashSet<RantDictionaryEntry>> rhymeState;
                if (!_rhymeTable.TryGetValue(rhyme, out rhymeState))
                {
                    result = pool
                        .Where(e => !Util.IsNullOrWhiteSpace(e.Terms[subtypeIndex].Pronunciation))
                        .PickEntry(rng);
                    _rhymeTable[rhyme] = _.Create(result.Terms[subtypeIndex], new HashSet<RantDictionaryEntry>(new[] { result }));
                    break;
                }
                result =
                    pool.Except(rhymeState.Item2)
                        .Where(e =>
                                !Util.IsNullOrWhiteSpace(e.Terms[subtypeIndex].Pronunciation) &&
                                _rhymer.Rhyme(rhymeState.Item1, e.Terms[subtypeIndex]))
                        .PickEntry(rng);

                if (result != null) rhymeState.Item2.Add(result);
                break; // Ignore any extra rhyme carriers
            }

            if (result == null) return result;

            foreach (var a in carrier.GetCarriers(CarrierComponent.Associative))
                if (!_assocTable.ContainsKey(a)) _assocTable[a] = result;

            foreach (var a in carrier.GetCarriers(CarrierComponent.Dissociative))
                if (!_assocTable.ContainsKey(a)) _assocTable[a] = result;

            foreach (var a in carrier.GetCarriers(CarrierComponent.Divergent))
                if (!_assocTable.ContainsKey(a)) _assocTable[a] = result;

            foreach (var a in carrier.GetCarriers(CarrierComponent.Relational))
                if (!_assocTable.ContainsKey(a)) _assocTable[a] = result;

            foreach (var unique in carrier.GetCarriers(CarrierComponent.Unique))
                _uniqueTable[unique].Add(result);

            foreach (var match in carrier.GetCarriers(CarrierComponent.Match))
            {
                _matchTable[match] = result;
                break;
            }

            return result;
        }
Пример #2
0
        internal RantDictionaryEntry GetEntry(Carrier carrier, int subtypeIndex, IEnumerable <RantDictionaryEntry> pool, RNG rng)
        {
            if (carrier == null)
            {
                return(pool.PickWeighted(rng, e => e.Weight));
            }

            RantDictionaryEntry result = null;

            // Handle match carriers
            foreach (var match in carrier.GetCarriers(CarrierComponent.Match))
            {
                if (_matchTable.TryGetValue(match, out result))
                {
                    return(result);
                }
            }

            // Handle associative carriers
            foreach (var assoc in carrier.GetCarriers(CarrierComponent.Associative))
            {
                if (_assocTable.TryGetValue(assoc, out result))
                {
                    pool = pool.Where(e => e.AssociatesWith(result));
                }
                break;
            }

            // Handle match-associative carriers
            foreach (var massoc in carrier.GetCarriers(CarrierComponent.MatchAssociative))
            {
                if (_matchTable.TryGetValue(massoc, out result))
                {
                    pool = pool.Where(e => e.AssociatesWith(result));
                }
                break;
            }

            // Handle unique carriers
            foreach (var unique in carrier.GetCarriers(CarrierComponent.Unique))
            {
                HashSet <RantDictionaryEntry> usedSet;
                if (!_uniqueTable.TryGetValue(unique, out usedSet))
                {
                    usedSet = _uniqueTable[unique] = new HashSet <RantDictionaryEntry>();
                }

                pool = pool.Except(usedSet);
            }

            // Handle match-unique carriers
            foreach (var munique in carrier.GetCarriers(CarrierComponent.Unique))
            {
                if (_matchTable.TryGetValue(munique, out result))
                {
                    pool = pool.Where(e => e != result);
                }
            }

            // Handle relational carriers
            foreach (var relate in carrier.GetCarriers(CarrierComponent.Relational))
            {
                if (_assocTable.TryGetValue(relate, out result))
                {
                    pool = pool.Where(e => e.RelatesWith(result));
                }
            }

            // Handle match-relational carriers
            foreach (var relate in carrier.GetCarriers(CarrierComponent.MatchRelational))
            {
                if (_matchTable.TryGetValue(relate, out result))
                {
                    pool = pool.Where(e => e.RelatesWith(result));
                }
            }

            // Handle dissociative carriers
            foreach (var relate in carrier.GetCarriers(CarrierComponent.Dissociative))
            {
                if (_assocTable.TryGetValue(relate, out result))
                {
                    pool = pool.Where(e => !e.RelatesWith(result));
                }
            }

            // Handle match-dissociative carriers
            foreach (var relate in carrier.GetCarriers(CarrierComponent.MatchDissociative))
            {
                if (_matchTable.TryGetValue(relate, out result))
                {
                    pool = pool.Where(e => !e.RelatesWith(result));
                }
            }

            // Handle divergent carriers
            foreach (var diverge in carrier.GetCarriers(CarrierComponent.Divergent))
            {
                if (_assocTable.TryGetValue(diverge, out result))
                {
                    pool = pool.Where(e => e.DivergesFrom(result));
                }
            }

            // Handle match-divergent carriers
            foreach (var diverge in carrier.GetCarriers(CarrierComponent.MatchDivergent))
            {
                if (_matchTable.TryGetValue(diverge, out result))
                {
                    pool = pool.Where(e => e.DivergesFrom(result));
                }
            }

            result = pool.PickWeighted(rng, e => e.Weight);

            // Handle rhyme carrier
            foreach (var rhyme in carrier.GetCarriers(CarrierComponent.Rhyme))
            {
                _ <RantDictionaryTerm, HashSet <RantDictionaryEntry> > rhymeState;
                if (!_rhymeTable.TryGetValue(rhyme, out rhymeState))
                {
                    result = pool
                             .Where(e => !Util.IsNullOrWhiteSpace(e.Terms[subtypeIndex].Pronunciation))
                             .PickWeighted(rng, e => e.Weight);
                    _rhymeTable[rhyme] = _.Create(result.Terms[subtypeIndex], new HashSet <RantDictionaryEntry>(new[] { result }));
                    break;
                }
                result =
                    pool.Except(rhymeState.Item2)
                    .Where(e => !Util.IsNullOrWhiteSpace(e.Terms[subtypeIndex].Pronunciation))
                    .PickWeighted(rng, e => e.Weight * (_rhymer.Rhyme(rhymeState.Item1, e.Terms[subtypeIndex]) ? rhymeState.Item1.SyllableCount : 0));

                if (result != null)
                {
                    rhymeState.Item2.Add(result);
                }
                break; // Ignore any extra rhyme carriers
            }

            if (result == null)
            {
                return(result);
            }

            foreach (var a in carrier.GetCarriers(CarrierComponent.Associative))
            {
                if (!_assocTable.ContainsKey(a))
                {
                    _assocTable[a] = result;
                }
            }

            foreach (var a in carrier.GetCarriers(CarrierComponent.Dissociative))
            {
                if (!_assocTable.ContainsKey(a))
                {
                    _assocTable[a] = result;
                }
            }

            foreach (var a in carrier.GetCarriers(CarrierComponent.Divergent))
            {
                if (!_assocTable.ContainsKey(a))
                {
                    _assocTable[a] = result;
                }
            }

            foreach (var a in carrier.GetCarriers(CarrierComponent.Relational))
            {
                if (!_assocTable.ContainsKey(a))
                {
                    _assocTable[a] = result;
                }
            }

            foreach (var unique in carrier.GetCarriers(CarrierComponent.Unique))
            {
                _uniqueTable[unique].Add(result);
            }

            foreach (var match in carrier.GetCarriers(CarrierComponent.Match))
            {
                _matchTable[match] = result;
                break;
            }

            return(result);
        }