private static void Analyze(IReadOnlyList <ProtoGroup> protoGroups, int[] counts, int[] used, Arrangement arrangement, int currentTileType, int currentProtoGroup, List <Arrangement> results) { if (currentTileType >= counts.Length) { results.Add(arrangement); return; } Analyze(protoGroups, counts, used, arrangement, currentTileType + 1, 0, results); for (var i = currentProtoGroup; i < protoGroups.Count; ++i) { var protoGroup = protoGroups[i]; var isJantou = i <= 1; if (isJantou) { if (arrangement.HasJantou || !protoGroup.CanInsert(counts, used, currentTileType)) { continue; } protoGroup.Insert(counts, used, currentTileType); var added = arrangement.SetJantouValue(protoGroup.Value); Analyze(protoGroups, counts, used, added, currentTileType, i, results); protoGroup.Remove(counts, used, currentTileType); } else { if (arrangement.MentsuCount == 4 || !protoGroup.CanInsert(counts, used, currentTileType)) { continue; } protoGroup.Insert(counts, used, currentTileType); var added = arrangement.AddMentsu(protoGroup.Value); Analyze(protoGroups, counts, used, added, currentTileType, i, results); protoGroup.Remove(counts, used, currentTileType); } } }
private void Analyze(Arrangement arrangement, int currentTileType, int currentProtoGroup) { if (currentTileType >= _tileTypeCount) { _arrangements.Add(arrangement); return; } Analyze(arrangement, currentTileType + 1, 0); // Inlined a bunch of things for about 25% performance gain. var count = _protoGroups.Count; for (var i = currentProtoGroup; i < count; ++i) { var protoGroup = _protoGroups[i]; var isJantou = i <= 1; if (isJantou) { if (_jantouValue != 0 || !protoGroup.CanInsert(_concealed, _used, currentTileType)) { continue; } protoGroup.Insert(_concealed, _used, currentTileType); var oldJantouValue = _jantouValue; _jantouValue = protoGroup.Value; var added = arrangement.SetJantouValue(_jantouValue); Analyze(added, currentTileType, i); protoGroup.Remove(_concealed, _used, currentTileType); _jantouValue = oldJantouValue; } else { if (_usedMelds == 4 || !protoGroup.CanInsert(_concealed, _used, currentTileType)) { continue; } protoGroup.Insert(_concealed, _used, currentTileType); _usedMelds += 1; var added = arrangement.AddMentsu(protoGroup.Value); Analyze(added, currentTileType, i); protoGroup.Remove(_concealed, _used, currentTileType); _usedMelds -= 1; } } }