优化取名逻辑
This commit is contained in:
303
DouyinApi.Services/Naming/BaziCalculator.cs
Normal file
303
DouyinApi.Services/Naming/BaziCalculator.cs
Normal file
@@ -0,0 +1,303 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DouyinApi.Services.Naming;
|
||||
|
||||
internal sealed class BaziCalculator
|
||||
{
|
||||
private static readonly string[] HeavenlyStems =
|
||||
{
|
||||
"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"
|
||||
};
|
||||
|
||||
private static readonly string[] EarthlyBranches =
|
||||
{
|
||||
"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"
|
||||
};
|
||||
|
||||
private static readonly int[] MonthNumberToBranchIndex =
|
||||
{
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1
|
||||
};
|
||||
|
||||
private static readonly string[] ElementOrder = { "木", "火", "土", "金", "水" };
|
||||
|
||||
private static readonly Dictionary<string, string> StemElements = new()
|
||||
{
|
||||
["甲"] = "木",
|
||||
["乙"] = "木",
|
||||
["丙"] = "火",
|
||||
["丁"] = "火",
|
||||
["戊"] = "土",
|
||||
["己"] = "土",
|
||||
["庚"] = "金",
|
||||
["辛"] = "金",
|
||||
["壬"] = "水",
|
||||
["癸"] = "水"
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, string> BranchElements = new()
|
||||
{
|
||||
["子"] = "水",
|
||||
["丑"] = "土",
|
||||
["寅"] = "木",
|
||||
["卯"] = "木",
|
||||
["辰"] = "土",
|
||||
["巳"] = "火",
|
||||
["午"] = "火",
|
||||
["未"] = "土",
|
||||
["申"] = "金",
|
||||
["酉"] = "金",
|
||||
["戌"] = "土",
|
||||
["亥"] = "水"
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, int> HourStemBaseIndex = new()
|
||||
{
|
||||
["甲"] = 0,
|
||||
["己"] = 0,
|
||||
["乙"] = 2,
|
||||
["庚"] = 2,
|
||||
["丙"] = 4,
|
||||
["辛"] = 4,
|
||||
["丁"] = 6,
|
||||
["壬"] = 6,
|
||||
["戊"] = 8,
|
||||
["癸"] = 8
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, int> MonthStemBaseIndex = new()
|
||||
{
|
||||
["甲"] = 2,
|
||||
["己"] = 2,
|
||||
["乙"] = 4,
|
||||
["庚"] = 4,
|
||||
["丙"] = 6,
|
||||
["辛"] = 6,
|
||||
["丁"] = 8,
|
||||
["壬"] = 8,
|
||||
["戊"] = 0,
|
||||
["癸"] = 0
|
||||
};
|
||||
|
||||
private static readonly DateTime DayBaseDate = new(1900, 1, 31);
|
||||
private const int DayBaseIndex = 0; // 1900-01-31 对应甲子日
|
||||
|
||||
public BaziProfile Calculate(DateTime birthDateTime)
|
||||
{
|
||||
var solarYear = birthDateTime.Year;
|
||||
var currentYearSpring = new DateTime(birthDateTime.Year, 2, 4);
|
||||
if (birthDateTime < currentYearSpring)
|
||||
{
|
||||
solarYear -= 1;
|
||||
}
|
||||
|
||||
var yearStemIndex = Mod(solarYear - 4, HeavenlyStems.Length);
|
||||
var yearBranchIndex = Mod(solarYear - 4, EarthlyBranches.Length);
|
||||
|
||||
var monthNumber = ResolveMonthNumber(birthDateTime, solarYear);
|
||||
var monthStemBase = MonthStemBaseIndex[HeavenlyStems[yearStemIndex]];
|
||||
var monthStemIndex = Mod(monthStemBase + monthNumber - 1, HeavenlyStems.Length);
|
||||
var monthBranchIndex = MonthNumberToBranchIndex[monthNumber - 1];
|
||||
|
||||
var dayCycleIndex = Mod(DayBaseIndex + (int)(birthDateTime.Date - DayBaseDate).TotalDays, 60);
|
||||
var dayStemIndex = Mod(dayCycleIndex, HeavenlyStems.Length);
|
||||
var dayBranchIndex = Mod(dayCycleIndex, EarthlyBranches.Length);
|
||||
|
||||
var hourBranchIndex = GetHourBranchIndex(birthDateTime.Hour);
|
||||
var hourStemIndex = Mod(HourStemBaseIndex[HeavenlyStems[dayStemIndex]] + hourBranchIndex, HeavenlyStems.Length);
|
||||
|
||||
var yearStem = HeavenlyStems[yearStemIndex];
|
||||
var yearBranch = EarthlyBranches[yearBranchIndex];
|
||||
var monthStem = HeavenlyStems[monthStemIndex];
|
||||
var monthBranch = EarthlyBranches[monthBranchIndex];
|
||||
var dayStem = HeavenlyStems[dayStemIndex];
|
||||
var dayBranch = EarthlyBranches[dayBranchIndex];
|
||||
var hourStem = HeavenlyStems[hourStemIndex];
|
||||
var hourBranch = EarthlyBranches[hourBranchIndex];
|
||||
|
||||
var elementCounts = ElementOrder.ToDictionary(element => element, _ => 0);
|
||||
IncrementElement(elementCounts, StemElements[yearStem]);
|
||||
IncrementElement(elementCounts, BranchElements[yearBranch]);
|
||||
IncrementElement(elementCounts, StemElements[monthStem]);
|
||||
IncrementElement(elementCounts, BranchElements[monthBranch]);
|
||||
IncrementElement(elementCounts, StemElements[dayStem]);
|
||||
IncrementElement(elementCounts, BranchElements[dayBranch]);
|
||||
IncrementElement(elementCounts, StemElements[hourStem]);
|
||||
IncrementElement(elementCounts, BranchElements[hourBranch]);
|
||||
|
||||
var counts = ElementOrder
|
||||
.Select(element => new KeyValuePair<string, int>(element, elementCounts[element]))
|
||||
.ToList();
|
||||
|
||||
var max = counts.Max(pair => pair.Value);
|
||||
var min = counts.Min(pair => pair.Value);
|
||||
|
||||
var isBalanced = max - min <= 1;
|
||||
var weakElements = isBalanced
|
||||
? Array.Empty<string>()
|
||||
: counts.Where(pair => pair.Value == min).Select(pair => pair.Key).ToArray();
|
||||
var strongElements = counts.Where(pair => pair.Value == max).Select(pair => pair.Key).ToArray();
|
||||
|
||||
return new BaziProfile(
|
||||
yearStem,
|
||||
yearBranch,
|
||||
monthStem,
|
||||
monthBranch,
|
||||
dayStem,
|
||||
dayBranch,
|
||||
hourStem,
|
||||
hourBranch,
|
||||
elementCounts,
|
||||
ElementOrder,
|
||||
weakElements,
|
||||
strongElements,
|
||||
isBalanced);
|
||||
}
|
||||
|
||||
private static int ResolveMonthNumber(DateTime dt, int solarYear)
|
||||
{
|
||||
var springStart = new DateTime(solarYear, 2, 4);
|
||||
var jingZhe = new DateTime(solarYear, 3, 6);
|
||||
var qingMing = new DateTime(solarYear, 4, 5);
|
||||
var liXia = new DateTime(solarYear, 5, 5);
|
||||
var mangZhong = new DateTime(solarYear, 6, 6);
|
||||
var xiaoShu = new DateTime(solarYear, 7, 7);
|
||||
var liQiu = new DateTime(solarYear, 8, 8);
|
||||
var baiLu = new DateTime(solarYear, 9, 8);
|
||||
var hanLu = new DateTime(solarYear, 10, 8);
|
||||
var liDong = new DateTime(solarYear, 11, 7);
|
||||
var daXue = new DateTime(solarYear, 12, 7);
|
||||
var xiaoHan = new DateTime(solarYear + 1, 1, 6);
|
||||
var nextSpring = new DateTime(solarYear + 1, 2, 4);
|
||||
|
||||
if (dt >= springStart && dt < jingZhe)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (dt >= jingZhe && dt < qingMing)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
if (dt >= qingMing && dt < liXia)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
if (dt >= liXia && dt < mangZhong)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if (dt >= mangZhong && dt < xiaoShu)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
if (dt >= xiaoShu && dt < liQiu)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
if (dt >= liQiu && dt < baiLu)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
if (dt >= baiLu && dt < hanLu)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
if (dt >= hanLu && dt < liDong)
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
if (dt >= liDong && dt < daXue)
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
if (dt >= daXue && dt < xiaoHan)
|
||||
{
|
||||
return 11;
|
||||
}
|
||||
if (dt >= xiaoHan && dt < nextSpring)
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
return 11;
|
||||
}
|
||||
|
||||
private static int GetHourBranchIndex(int hour)
|
||||
{
|
||||
return ((hour + 1) / 2) % EarthlyBranches.Length;
|
||||
}
|
||||
|
||||
private static void IncrementElement(IDictionary<string, int> container, string element)
|
||||
{
|
||||
if (container.TryGetValue(element, out var value))
|
||||
{
|
||||
container[element] = value + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int Mod(int value, int modulus)
|
||||
{
|
||||
var result = value % modulus;
|
||||
return result < 0 ? result + modulus : result;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class BaziProfile
|
||||
{
|
||||
public BaziProfile(
|
||||
string yearStem,
|
||||
string yearBranch,
|
||||
string monthStem,
|
||||
string monthBranch,
|
||||
string dayStem,
|
||||
string dayBranch,
|
||||
string hourStem,
|
||||
string hourBranch,
|
||||
IReadOnlyDictionary<string, int> elementCounts,
|
||||
IReadOnlyList<string> elementOrder,
|
||||
IReadOnlyList<string> weakElements,
|
||||
IReadOnlyList<string> strongElements,
|
||||
bool isBalanced)
|
||||
{
|
||||
YearStem = yearStem;
|
||||
YearBranch = yearBranch;
|
||||
MonthStem = monthStem;
|
||||
MonthBranch = monthBranch;
|
||||
DayStem = dayStem;
|
||||
DayBranch = dayBranch;
|
||||
HourStem = hourStem;
|
||||
HourBranch = hourBranch;
|
||||
ElementCounts = elementCounts;
|
||||
ElementOrder = elementOrder;
|
||||
WeakElements = weakElements;
|
||||
StrongElements = strongElements;
|
||||
IsBalanced = isBalanced;
|
||||
}
|
||||
|
||||
public string YearStem { get; }
|
||||
|
||||
public string YearBranch { get; }
|
||||
|
||||
public string MonthStem { get; }
|
||||
|
||||
public string MonthBranch { get; }
|
||||
|
||||
public string DayStem { get; }
|
||||
|
||||
public string DayBranch { get; }
|
||||
|
||||
public string HourStem { get; }
|
||||
|
||||
public string HourBranch { get; }
|
||||
|
||||
public IReadOnlyDictionary<string, int> ElementCounts { get; }
|
||||
|
||||
public IReadOnlyList<string> ElementOrder { get; }
|
||||
|
||||
public IReadOnlyList<string> WeakElements { get; }
|
||||
|
||||
public IReadOnlyList<string> StrongElements { get; }
|
||||
|
||||
public bool IsBalanced { get; }
|
||||
}
|
||||
290
DouyinApi.Services/Naming/FallbackNameGenerator.cs
Normal file
290
DouyinApi.Services/Naming/FallbackNameGenerator.cs
Normal file
@@ -0,0 +1,290 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DouyinApi.Model.Naming;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace DouyinApi.Services.Naming;
|
||||
|
||||
internal sealed class FallbackNameGenerator
|
||||
{
|
||||
private const int TargetCount = 5;
|
||||
|
||||
private static readonly string[] ElementOrder = { "木", "火", "土", "金", "水" };
|
||||
|
||||
private readonly CharacterLibrary _library = new();
|
||||
|
||||
public IReadOnlyList<NamingSuggestion> Generate(NamingRequest request, BaziProfile profile)
|
||||
{
|
||||
var surname = request.Surname;
|
||||
var isSingle = string.Equals(request.NameLength, "single", StringComparison.OrdinalIgnoreCase);
|
||||
var gender = NormalizeGender(request.Gender);
|
||||
|
||||
var results = new List<NamingSuggestion>();
|
||||
var usedCharacters = new HashSet<string>(StringComparer.Ordinal);
|
||||
var usedNames = new HashSet<string>(StringComparer.Ordinal);
|
||||
var sequence = BuildElementSequence(profile);
|
||||
|
||||
var attempts = 0;
|
||||
while (results.Count < TargetCount && attempts < 80)
|
||||
{
|
||||
var primaryElement = sequence[attempts % sequence.Count];
|
||||
var first = _library.Pick(primaryElement, gender, usedCharacters);
|
||||
if (first == null)
|
||||
{
|
||||
attempts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isSingle)
|
||||
{
|
||||
var fullName = surname + first.Character;
|
||||
if (usedNames.Add(fullName))
|
||||
{
|
||||
results.Add(new NamingSuggestion
|
||||
{
|
||||
Name = fullName,
|
||||
Meaning = first.Meaning,
|
||||
ElementReason = BuildSingleReason(profile, first)
|
||||
});
|
||||
usedCharacters.Add(first.Character);
|
||||
}
|
||||
|
||||
attempts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var tempUsed = new HashSet<string>(usedCharacters, StringComparer.Ordinal)
|
||||
{
|
||||
first.Character
|
||||
};
|
||||
|
||||
var secondaryElement = sequence[(attempts + 1) % sequence.Count];
|
||||
var second = _library.Pick(secondaryElement, gender, tempUsed);
|
||||
if (second == null)
|
||||
{
|
||||
attempts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var givenName = first.Character + second.Character;
|
||||
var full = surname + givenName;
|
||||
if (usedNames.Add(full))
|
||||
{
|
||||
results.Add(new NamingSuggestion
|
||||
{
|
||||
Name = full,
|
||||
Meaning = $"{first.Meaning},{second.Meaning}",
|
||||
ElementReason = BuildDoubleReason(profile, first, second)
|
||||
});
|
||||
usedCharacters.Add(first.Character);
|
||||
usedCharacters.Add(second.Character);
|
||||
}
|
||||
|
||||
attempts++;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static string NormalizeGender(string gender)
|
||||
{
|
||||
return string.Equals(gender, "female", StringComparison.OrdinalIgnoreCase) ? "female" : "male";
|
||||
}
|
||||
|
||||
private static List<string> BuildElementSequence(BaziProfile profile)
|
||||
{
|
||||
var sequence = new List<string>();
|
||||
if (profile.WeakElements.Count > 0)
|
||||
{
|
||||
sequence.AddRange(profile.WeakElements);
|
||||
}
|
||||
|
||||
foreach (var element in ElementOrder)
|
||||
{
|
||||
if (!sequence.Contains(element))
|
||||
{
|
||||
sequence.Add(element);
|
||||
}
|
||||
}
|
||||
|
||||
return sequence;
|
||||
}
|
||||
|
||||
private static string BuildSingleReason(BaziProfile profile, CharacterProfile profileChar)
|
||||
{
|
||||
if (!profile.IsBalanced && profile.WeakElements.Contains(profileChar.Element))
|
||||
{
|
||||
return $"命局中{profileChar.Element}势偏弱,选用同属性的“{profileChar.Character}”以补足生机。";
|
||||
}
|
||||
|
||||
return $"“{profileChar.Character}”属{profileChar.Element},与命局相协,凸显个人气韵。";
|
||||
}
|
||||
|
||||
private static string BuildDoubleReason(BaziProfile profile, CharacterProfile first, CharacterProfile second)
|
||||
{
|
||||
var clauses = new List<string>();
|
||||
|
||||
if (!profile.IsBalanced && profile.WeakElements.Contains(first.Element))
|
||||
{
|
||||
clauses.Add($"命局中{first.Element}势弱,首取“{first.Character}”以增添此行之力");
|
||||
}
|
||||
else
|
||||
{
|
||||
clauses.Add($"“{first.Character}”属{first.Element},奠定名字的核心气场");
|
||||
}
|
||||
|
||||
if (first.Element == second.Element)
|
||||
{
|
||||
clauses.Add($"再以同为{second.Element}属性的“{second.Character}”相辅,巩固能量");
|
||||
}
|
||||
else if (!profile.IsBalanced && profile.WeakElements.Contains(second.Element))
|
||||
{
|
||||
clauses.Add($"辅以{second.Element}属性“{second.Character}”同步补益");
|
||||
}
|
||||
else
|
||||
{
|
||||
clauses.Add($"叠加{second.Element}属性“{second.Character}”,使五行流转更趋和谐");
|
||||
}
|
||||
|
||||
return string.Join(",", clauses) + "。";
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class CharacterLibrary
|
||||
{
|
||||
private readonly Dictionary<string, List<CharacterProfile>> _profiles;
|
||||
|
||||
public CharacterLibrary()
|
||||
{
|
||||
_profiles = new Dictionary<string, List<CharacterProfile>>(StringComparer.Ordinal)
|
||||
{
|
||||
["木"] = new List<CharacterProfile>
|
||||
{
|
||||
new("林", "木", 8, "林木森郁,生机盎然", GenderAffinity.Neutral),
|
||||
new("杉", "木", 7, "杉木挺拔,坚韧自持", GenderAffinity.Male),
|
||||
new("柏", "木", 9, "柏树常青,守正不渝", GenderAffinity.Male),
|
||||
new("桐", "木", 10, "梧桐清雅,自带高洁", GenderAffinity.Neutral),
|
||||
new("柯", "木", 9, "柯木坚劲,胸怀正义", GenderAffinity.Male),
|
||||
new("梓", "木", 11, "梓木葱郁,延续家风", GenderAffinity.Neutral),
|
||||
new("芸", "木", 10, "芸草幽香,温婉灵动", GenderAffinity.Female),
|
||||
new("茜", "木", 9, "茜草明艳,朝气蓬勃", GenderAffinity.Female)
|
||||
},
|
||||
["火"] = new List<CharacterProfile>
|
||||
{
|
||||
new("炜", "火", 9, "炜火明亮,奋发向上", GenderAffinity.Male),
|
||||
new("炎", "火", 8, "炎光熠熠,激情澎湃", GenderAffinity.Male),
|
||||
new("晗", "火", 11, "晨晗初照,温暖柔和", GenderAffinity.Female),
|
||||
new("晟", "火", 11, "晟意光盛,事业昌隆", GenderAffinity.Male),
|
||||
new("旭", "火", 6, "旭日东升,胸怀朝阳", GenderAffinity.Neutral),
|
||||
new("烁", "火", 10, "烁光璀璨,灵动敏捷", GenderAffinity.Neutral),
|
||||
new("炫", "火", 9, "炫彩熠熠,才华外露", GenderAffinity.Neutral)
|
||||
},
|
||||
["土"] = new List<CharacterProfile>
|
||||
{
|
||||
new("坤", "土", 8, "坤厚载物,包容从容", GenderAffinity.Neutral),
|
||||
new("均", "土", 7, "均衡端稳,踏实可靠", GenderAffinity.Neutral),
|
||||
new("垣", "土", 9, "垣墙坚实,守护安宁", GenderAffinity.Neutral),
|
||||
new("城", "土", 9, "城池稳固,守正不移", GenderAffinity.Male),
|
||||
new("岳", "土", 8, "山岳巍峨,志向高远", GenderAffinity.Male),
|
||||
new("培", "土", 11, "培土厚植,涵养成长", GenderAffinity.Neutral),
|
||||
new("堇", "土", 12, "堇色沉静,内敛温润", GenderAffinity.Female),
|
||||
new("坦", "土", 8, "坦荡诚笃,胸怀光明", GenderAffinity.Male)
|
||||
},
|
||||
["金"] = new List<CharacterProfile>
|
||||
{
|
||||
new("钧", "金", 9, "钧衡公正,持中守衡", GenderAffinity.Neutral),
|
||||
new("铭", "金", 11, "铭记初心,彰显才华", GenderAffinity.Neutral),
|
||||
new("锐", "金", 11, "锋芒锐利,果敢决断", GenderAffinity.Male),
|
||||
new("钦", "金", 9, "钦敬谦和,端方稳重", GenderAffinity.Neutral),
|
||||
new("钥", "金", 9, "钥启智慧,开拓视野", GenderAffinity.Neutral),
|
||||
new("铠", "金", 12, "铠甲护身,坚毅勇敢", GenderAffinity.Male),
|
||||
new("钰", "金", 10, "钰石珍贵,坚贞明亮", GenderAffinity.Female)
|
||||
},
|
||||
["水"] = new List<CharacterProfile>
|
||||
{
|
||||
new("泽", "水", 9, "泽润万物,胸怀宽广", GenderAffinity.Neutral),
|
||||
new("泓", "水", 8, "泓水清澈,心境澄明", GenderAffinity.Neutral),
|
||||
new("润", "水", 10, "润泽柔润,涵养细腻", GenderAffinity.Female),
|
||||
new("涵", "水", 11, "涵容自守,温婉内敛", GenderAffinity.Female),
|
||||
new("沐", "水", 7, "沐浴春风,清新怡然", GenderAffinity.Neutral),
|
||||
new("泊", "水", 8, "泊舟安然,沉稳淡泊", GenderAffinity.Male),
|
||||
new("洵", "水", 9, "洵美诚笃,信义笃实", GenderAffinity.Male),
|
||||
new("沁", "水", 8, "沁香流淌,气质清雅", GenderAffinity.Female)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public CharacterProfile? Pick(string element, string gender, HashSet<string> usedCharacters)
|
||||
{
|
||||
if (!_profiles.TryGetValue(element, out var candidates))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 优先匹配性别偏好
|
||||
foreach (var profile in candidates)
|
||||
{
|
||||
if (usedCharacters.Contains(profile.Character))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (profile.Affinity == GenderAffinity.Neutral ||
|
||||
(profile.Affinity == GenderAffinity.Male && gender == "male") ||
|
||||
(profile.Affinity == GenderAffinity.Female && gender == "female"))
|
||||
{
|
||||
if (profile.StrokeCount <= 12)
|
||||
{
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 兜底选择中性字
|
||||
foreach (var profile in candidates)
|
||||
{
|
||||
if (usedCharacters.Contains(profile.Character))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (profile.Affinity == GenderAffinity.Neutral && profile.StrokeCount <= 12)
|
||||
{
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class CharacterProfile
|
||||
{
|
||||
public CharacterProfile(string character, string element, int strokeCount, string meaning, GenderAffinity affinity)
|
||||
{
|
||||
Character = character;
|
||||
Element = element;
|
||||
StrokeCount = strokeCount;
|
||||
Meaning = meaning;
|
||||
Affinity = affinity;
|
||||
}
|
||||
|
||||
public string Character { get; }
|
||||
|
||||
public string Element { get; }
|
||||
|
||||
public int StrokeCount { get; }
|
||||
|
||||
public string Meaning { get; }
|
||||
|
||||
public GenderAffinity Affinity { get; }
|
||||
}
|
||||
|
||||
internal enum GenderAffinity
|
||||
{
|
||||
Neutral,
|
||||
Male,
|
||||
Female
|
||||
}
|
||||
Reference in New Issue
Block a user