package controls; import interfaces.IAttack; import interfaces.IBotBehavior; import java.util.*; import static views.Constants.DECK_COUNT; public class BotIntelligence implements IBotBehavior { public BotIntelligence(){ } /** 未確定の数字を列挙する */ List<Integer> calculateCandidate(IAttack iAttack){ //候補の初期化 var candidates = new ArrayList<Integer>(); for(int i=0;i<DECK_COUNT;i++)candidates.add(i); candidates.removeAll(iAttack.getOpponentHands().stream().map(x -> x.getKey()).toList()); candidates.removeAll(iAttack.getMyHands().stream().filter(x -> x.getValue()).map(x -> x.getKey()).toList()); return candidates; } /** * 相手の手札に対して、候補となる数字を割り当てる * @param iAttack * @return 候補のリスト */ List<int[]> assignCandidateNumberEachHand(IAttack iAttack){ var myHands=iAttack.getMyHands(); var result=new ArrayList<int[]>(); for(var card:myHands){//ユーザーの手札を左から見ていく var index=myHands.indexOf(card);//左からindex番目に var candidateList = calculateCandidate(iAttack);//確認するカード if(card.getValue()) { candidateList.clear(); }else{ //裏の場合 //そのカードから右隣のカードを確認していく for(int i=0;i<myHands.size()-index-1;i++){ //今確認していっているカード var currentCard = myHands.get(i+index+1); if(currentCard.getValue()){//確認しているカードが表なら、(YES) candidateList.removeIf(x -> x > currentCard.getKey());//その確認したカードの数字より大きい数字を除外する。 for(int j=1;j<i;j++){//そして、その確認したカードよりjだけ小さいそのカードからj番目の数字を除外する。 candidateList.remove(candidateList.size()-1); } break; } } //そのカードから左隣のカードを確認していく for(int i=1;i<=index;i++){ //今確認していっているカード var currentCard = myHands.get(index-i); if(currentCard.getValue()){//表があれば、それより小さい数字を候補から削除する candidateList.removeIf(x-> x<currentCard.getKey()); } } } var s=(card.getValue()?"+":"-")+card.getKey()+":["; for (var i:candidateList)s+=i+" "; s+="]\n"; System.out.println(s); result.add(candidateList.stream().mapToInt(x -> x).toArray()); } return result; } //公開されていないカードのインデックスを選ぶ(カードにかかれている番号ではない) @Override public int selectAttacker(IAttack iAttack) { var botHands = iAttack.getOpponentHands(); for(var i:botHands){//小さいものから選択 if(!i.getValue())return botHands.indexOf(i); } return 0; } @Override public int selectTarget(IAttack iAttack) { var candidate= assignCandidateNumberEachHand(iAttack); int result=0; int min=DECK_COUNT; for(var i:candidate){ if(i.length<min&&i.length!=0){ result=candidate.indexOf(i); min=i.length; } } return result; } @Override public int declareNumber(IAttack iAttack, int target) { var array =assignCandidateNumberEachHand(iAttack).get(target); return array[new Random().nextInt(array.length)]; } }