package com.xuezhanmaster.game.service; import com.xuezhanmaster.game.domain.ActionType; import com.xuezhanmaster.game.domain.ResponseActionResolution; import com.xuezhanmaster.game.domain.ResponseActionResolutionBatch; import com.xuezhanmaster.game.domain.ResponseActionWindow; import org.springframework.stereotype.Component; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Optional; @Component public class ResponseActionResolver { public Optional resolve( ResponseActionWindow window, Map selections, int seatCount ) { // 只要有胡牌声明,就按一炮多响返回全部胡牌赢家,其它动作全部失效。 List huResolutions = selections.entrySet().stream() .filter(entry -> entry.getValue() == ActionType.HU) .sorted(Comparator.comparingInt(entry -> seatDistance(window.sourceSeatNo(), entry.getKey(), seatCount))) .map(entry -> new ResponseActionResolution( entry.getValue(), entry.getKey(), window.sourceSeatNo(), window.triggerTile() )) .toList(); if (!huResolutions.isEmpty()) { // 一炮多响时保留所有胡牌赢家,后续由执行层逐个结算。 return Optional.of(new ResponseActionResolutionBatch(ActionType.HU, huResolutions)); } return selections.entrySet().stream() .filter(entry -> entry.getValue() != ActionType.PASS) .min(Comparator .comparingInt((Map.Entry entry) -> priority(entry.getValue())) .thenComparingInt(entry -> seatDistance(window.sourceSeatNo(), entry.getKey(), seatCount))) .map(entry -> new ResponseActionResolutionBatch( entry.getValue(), List.of(new ResponseActionResolution( entry.getValue(), entry.getKey(), window.sourceSeatNo(), window.triggerTile() )) )); } private int priority(ActionType actionType) { return switch (actionType) { case HU -> 0; case GANG -> 1; case PENG -> 2; case PASS -> 3; default -> 99; }; } private int seatDistance(int sourceSeatNo, int targetSeatNo, int seatCount) { return (targetSeatNo - sourceSeatNo + seatCount) % seatCount; } }