Skip to content

Commit 043b230

Browse files
committed
feat: integrate Sichuan Mahjong core flow
1 parent 514b05d commit 043b230

25 files changed

Lines changed: 752 additions & 67 deletions

src/main/java/top/ellan/mahjong/command/MahjongCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ private List<String> visibleRootCommands(CommandSender sender) {
526526
: ROOT_COMMANDS.stream().filter(command -> !this.isAdminRootCommand(command)).collect(java.util.stream.Collectors.toCollection(ArrayList::new));
527527
if (sender instanceof Player player) {
528528
MahjongTableSession table = this.tableManager.tableFor(player.getUniqueId());
529-
if (table != null && table.currentVariant() == MahjongVariant.GB) {
529+
if (table != null && table.currentVariant() != MahjongVariant.RIICHI) {
530530
commands.remove("riichi");
531531
commands.remove("kyuushu");
532532
}

src/main/java/top/ellan/mahjong/config/PluginSettings.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public String craftEngineGbTileItemIdPrefix() {
132132
}
133133

134134
public String craftEngineTileItemIdPrefix(MahjongVariant variant) {
135-
if (variant == MahjongVariant.GB) {
135+
if (variant != MahjongVariant.RIICHI) {
136136
return this.craftEngineGbTileItemIdPrefix;
137137
}
138138
return this.craftEngineRiichiTileItemIdPrefix;

src/main/java/top/ellan/mahjong/table/core/MahjongTableSession.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import top.ellan.mahjong.riichi.model.MahjongSoulScoring;
1515
import top.ellan.mahjong.riichi.model.ScoringStick;
1616
import top.ellan.mahjong.table.core.round.GbTableRoundController;
17+
import top.ellan.mahjong.table.core.round.GbRuleProfile;
1718
import top.ellan.mahjong.table.core.round.OpeningDiceRoll;
1819
import top.ellan.mahjong.table.core.round.RiichiTableRoundController;
1920
import top.ellan.mahjong.table.core.round.TableRoundController;
@@ -912,8 +913,14 @@ private TableRoundController createRoundController() {
912913
seats.put(wind, playerId);
913914
displayNames.put(playerId, this.displayName(playerId));
914915
}
915-
if (this.currentVariant() == MahjongVariant.GB) {
916-
return new GbTableRoundController(this.copyRule(), seats, displayNames, new GbNativeRulesGateway());
916+
if (this.currentVariant() != MahjongVariant.RIICHI) {
917+
return new GbTableRoundController(
918+
this.copyRule(),
919+
seats,
920+
displayNames,
921+
new GbNativeRulesGateway(),
922+
GbRuleProfile.forVariant(this.currentVariant())
923+
);
917924
}
918925
List<RiichiPlayerState> players = new ArrayList<>(SeatWind.values().length);
919926
for (SeatWind wind : SeatWind.values()) {

src/main/java/top/ellan/mahjong/table/core/MahjongVariant.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
public enum MahjongVariant {
66
RIICHI,
7-
GB;
7+
GB,
8+
SICHUAN;
89

910
public String translationKey() {
1011
return "rule.variant." + this.name().toLowerCase(Locale.ROOT);

src/main/java/top/ellan/mahjong/table/core/SessionRuleCoordinator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ List<String> ruleKeys() {
6565

6666
List<String> ruleValues(String key) {
6767
return switch (key.toLowerCase(Locale.ROOT)) {
68-
case "preset", "mode" -> List.of("MAJSOUL_TONPUU", "MAJSOUL_HANCHAN", "GB");
69-
case "variant", "ruleset" -> List.of("RIICHI", "GB");
68+
case "preset", "mode" -> List.of("MAJSOUL_TONPUU", "MAJSOUL_HANCHAN", "GB", "SICHUAN");
69+
case "variant", "ruleset" -> List.of("RIICHI", "GB", "SICHUAN");
7070
case "length" -> List.of("ONE_GAME", "EAST", "SOUTH", "TWO_WIND");
7171
case "thinkingtime", "thinking" -> List.of("VERY_SHORT", "SHORT", "NORMAL", "LONG", "VERY_LONG");
7272
case "minimumhan", "minhan" -> List.of("ONE", "TWO", "FOUR", "YAKUMAN");

src/main/java/top/ellan/mahjong/table/core/SessionRulePresetResolver.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ static Preset resolve(String rawValue) {
1818
new Preset(MahjongVariant.RIICHI, majsoulRule(MahjongRule.GameLength.TWO_WIND));
1919
case "GB", "GUOBIAO", "ZHONGGUO", "CHINESE_OFFICIAL" ->
2020
new Preset(MahjongVariant.GB, gbRule());
21+
case "SICHUAN", "SCMJ", "SICHUAN_MAHJONG", "SICHUAN_TOURNAMENT" ->
22+
new Preset(MahjongVariant.SICHUAN, sichuanRule());
2123
default -> null;
2224
};
2325
}
2426

2527
static MahjongRule defaultRuleFor(MahjongVariant variant) {
26-
return variant == MahjongVariant.GB ? gbRule() : majsoulRule(MahjongRule.GameLength.TWO_WIND);
28+
return variant == MahjongVariant.RIICHI ? majsoulRule(MahjongRule.GameLength.TWO_WIND) : gbRule();
2729
}
2830

2931
static MahjongRule majsoulRule(MahjongRule.GameLength length) {
@@ -54,6 +56,10 @@ static MahjongRule gbRule() {
5456
);
5557
}
5658

59+
static MahjongRule sichuanRule() {
60+
return gbRule();
61+
}
62+
5763
record Preset(MahjongVariant variant, MahjongRule rule) {
5864
}
5965
}

src/main/java/top/ellan/mahjong/table/core/round/GbRoundSupport.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,23 @@ static int rollDicePoints() {
163163
}
164164

165165
static List<MahjongTile> buildWall() {
166-
List<MahjongTile> wall = new ArrayList<>(144);
166+
return buildWall(GbRuleProfile.GB);
167+
}
168+
169+
static List<MahjongTile> buildWall(GbRuleProfile profile) {
170+
GbRuleProfile safeProfile = profile == null ? GbRuleProfile.GB : profile;
171+
int initialCapacity = safeProfile.includesHonors() && safeProfile.includesFlowers() ? 144 : 108;
172+
List<MahjongTile> wall = new ArrayList<>(initialCapacity);
167173
for (MahjongTile tile : MahjongTile.values()) {
168174
if (tile == MahjongTile.UNKNOWN || tile.isRedFive()) {
169175
continue;
170176
}
177+
if (!safeProfile.includesHonors() && isHonor(tile)) {
178+
continue;
179+
}
180+
if (!safeProfile.includesFlowers() && tile.isFlower()) {
181+
continue;
182+
}
171183
int copies = tile.isFlower() ? 1 : 4;
172184
for (int i = 0; i < copies; i++) {
173185
wall.add(tile);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package top.ellan.mahjong.table.core.round;
2+
3+
import top.ellan.mahjong.table.core.MahjongVariant;
4+
5+
public enum GbRuleProfile {
6+
GB(MahjongVariant.GB, "GB_MAHJONG", 8, true, true, false),
7+
SICHUAN(MahjongVariant.SICHUAN, "SICHUAN_MAHJONG", 0, false, false, true);
8+
9+
private final MahjongVariant variant;
10+
private final String nativeRuleProfile;
11+
private final int minimumFan;
12+
private final boolean includesHonors;
13+
private final boolean includesFlowers;
14+
private final boolean useSichuanHuEvaluator;
15+
16+
GbRuleProfile(
17+
MahjongVariant variant,
18+
String nativeRuleProfile,
19+
int minimumFan,
20+
boolean includesHonors,
21+
boolean includesFlowers,
22+
boolean useSichuanHuEvaluator
23+
) {
24+
this.variant = variant;
25+
this.nativeRuleProfile = nativeRuleProfile;
26+
this.minimumFan = minimumFan;
27+
this.includesHonors = includesHonors;
28+
this.includesFlowers = includesFlowers;
29+
this.useSichuanHuEvaluator = useSichuanHuEvaluator;
30+
}
31+
32+
public MahjongVariant variant() {
33+
return this.variant;
34+
}
35+
36+
public String nativeRuleProfile() {
37+
return this.nativeRuleProfile;
38+
}
39+
40+
public int minimumFan() {
41+
return this.minimumFan;
42+
}
43+
44+
public boolean includesHonors() {
45+
return this.includesHonors;
46+
}
47+
48+
public boolean includesFlowers() {
49+
return this.includesFlowers;
50+
}
51+
52+
public boolean useSichuanHuEvaluator() {
53+
return this.useSichuanHuEvaluator;
54+
}
55+
56+
public static GbRuleProfile forVariant(MahjongVariant variant) {
57+
if (variant == MahjongVariant.SICHUAN) {
58+
return SICHUAN;
59+
}
60+
return GB;
61+
}
62+
}

0 commit comments

Comments
 (0)