/**
* Copyright (C) 2017 Jan Schäfer (jansch@users.sourceforge.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jskat.ai.newalgorithm;
import java.util.Random;
import org.jskat.data.Trick;
import org.jskat.player.ImmutablePlayerKnowledge;
import org.jskat.util.Card;
import org.jskat.util.CardList;
import org.jskat.util.GameType;
import org.jskat.util.Rank;
import org.jskat.util.Suit;
/**
* @author Daniel Loreck <br>
*
*/
public abstract class AbstractAlgorithmAI {
protected final AlgorithmAI myPlayer;
protected final ImmutablePlayerKnowledge knowledge;
protected final static Random random = new Random();
protected Situation oSituation;
protected CardList oPlayedCards;
protected CardList oNotOpponentCards;
public AbstractAlgorithmAI(final AlgorithmAI p, GameType pGameType) {
myPlayer = p;
knowledge = p.getKnowledge();
oSituation = new Situation(knowledge, pGameType);
oPlayedCards = new CardList();
oNotOpponentCards = new CardList();
}
public Card playCard() {
// remove last tricks cards from the list of all opponent cards
int currentTrick;
oNotOpponentCards.clear();
if ((currentTrick = knowledge.getNoOfTricks()) != 0) {
addTrickToPlayedCards(knowledge.getCompletedTricks().get(
currentTrick - 1));
}
oNotOpponentCards.addAll(oPlayedCards);
oNotOpponentCards.addAll(knowledge.getOwnCards());
oNotOpponentCards.addAll(knowledge.getSkat());
oPlayedCards.sort(oSituation.getGameType());
oNotOpponentCards.sort(oSituation.getGameType());
// Wenn nur eine Karte vorhanden ist
if (knowledge.getOwnCards().size() == 1) {
return knowledge.getOwnCards().get(0);
}
if (knowledge.getTrickCards() == null
|| knowledge.getTrickCards().isEmpty()) {
if (knowledge.getNoOfTricks() < 1) {
return startGame();
}
return playForehandCard();
}
if (knowledge.getTrickCards().size() == 1) {
return playMiddlehandCard();
}
return playRearhandCard();
}
protected abstract Card startGame();
protected abstract Card playForehandCard();
protected abstract Card playMiddlehandCard();
protected abstract Card playRearhandCard();
public abstract CardList discardSkat(BidEvaluator bidEvaluator);
protected void addTrickToPlayedCards(Trick pTrick) {
Suit tTrickSuit = pTrick.getFirstCard().getSuit();
oPlayedCards.add(pTrick.getFirstCard());
oPlayedCards.add(pTrick.getSecondCard());
// Wenn mit der 2. Karte nicht bedient wurde
// oder 1. Karte nicht Trumpf und 2. Karte ein Bube ist
if (tTrickSuit != pTrick.getSecondCard().getSuit()
|| (tTrickSuit != knowledge.getTrumpSuit() && pTrick
.getSecondCard().getRank() == Rank.JACK)) {
if (pTrick.getMiddleHand() == knowledge.getPlayerPosition()
.getLeftNeighbor())
oSituation.setLeftPlayerBlankColor(tTrickSuit);
else if (pTrick.getMiddleHand() == knowledge.getPlayerPosition()
.getRightNeighbor())
oSituation.setRightPlayerBlankColor(tTrickSuit);
} else if (tTrickSuit == knowledge.getTrumpSuit()
&& !(pTrick.getSecondCard().getSuit() == tTrickSuit || pTrick
.getSecondCard().getRank() == Rank.JACK)) {
if (pTrick.getMiddleHand() == knowledge.getPlayerPosition()
.getLeftNeighbor())
oSituation.setLeftPlayerBlankOnTrump();
else if (pTrick.getMiddleHand() == knowledge.getPlayerPosition()
.getRightNeighbor())
oSituation.setRightPlayerBlankOnTrump();
}
oPlayedCards.add(pTrick.getThirdCard());
// Wenn mit der 3. Karte nicht bedient wurde
// oder 1. Karte nicht Trumpf und 3. Karte ein Bube ist
if (tTrickSuit != pTrick.getThirdCard().getSuit()
|| (tTrickSuit != knowledge.getTrumpSuit() && pTrick
.getThirdCard().getRank() == Rank.JACK)) {
if (pTrick.getRearHand() == knowledge.getPlayerPosition()
.getLeftNeighbor())
oSituation.setLeftPlayerBlankColor(tTrickSuit);
else if (pTrick.getRearHand() == knowledge.getPlayerPosition()
.getRightNeighbor())
oSituation.setRightPlayerBlankColor(tTrickSuit);
} else if (tTrickSuit == knowledge.getTrumpSuit()
&& !(pTrick.getThirdCard().getSuit() == tTrickSuit || pTrick
.getThirdCard().getRank() == Rank.JACK)) {
if (pTrick.getRearHand() == knowledge.getPlayerPosition()
.getLeftNeighbor())
oSituation.setLeftPlayerBlankOnTrump();
else if (pTrick.getRearHand() == knowledge.getPlayerPosition()
.getRightNeighbor())
oSituation.setRightPlayerBlankOnTrump();
}
// Wenn keine Karten mehr beim Gegner sind dann beide blank setzen
// Wenn Farbspiel
if ((knowledge.getGameType() == GameType.CLUBS
|| knowledge.getGameType() == GameType.SPADES
|| knowledge.getGameType() == GameType.HEARTS || knowledge
.getGameType() == GameType.DIAMONDS)) {
// Wenn erste Karte kein Trump war
if (tTrickSuit != knowledge.getTrumpSuit()
&& oNotOpponentCards.getSuitCount(tTrickSuit, false) == 7) {
oSituation.setLeftPlayerBlankColor(tTrickSuit);
oSituation.setRightPlayerBlankColor(tTrickSuit);
} else if (tTrickSuit == knowledge.getTrumpSuit()
&& oNotOpponentCards.getSuitCount(tTrickSuit, false)
+ Helper.countJacks(oNotOpponentCards) == 11) {
oSituation.setLeftPlayerBlankOnTrump();
oSituation.setRightPlayerBlankOnTrump();
}
}
// Wenn Grand-Spiel
// UND keine Karten dieser Farbe mehr beim Gegner (exkl. Buben)
else if (knowledge.getGameType() == GameType.GRAND
&& oNotOpponentCards.getSuitCount(tTrickSuit, false) == 7) {
oSituation.setLeftPlayerBlankColor(tTrickSuit);
oSituation.setRightPlayerBlankColor(tTrickSuit);
}
// Wenn Null-Spiel
// UND keine Karten dieser Farbe mehr beim Gegner (inkl. Buben)
else if (knowledge.getGameType() == GameType.NULL
&& oNotOpponentCards.getSuitCount(tTrickSuit, true) == 8) {
oSituation.setLeftPlayerBlankColor(tTrickSuit);
oSituation.setRightPlayerBlankColor(tTrickSuit);
}
}
// protected boolean isPlayerBlankOnColor(Player pPlayer, Suit pSuit) {
// if(pPlayer == knowledge.getPlayerPosition().getLeftNeighbor())
// return oFreeSuitOpponentLeft.contains(pSuit);
// if(pPlayer == knowledge.getPlayerPosition().getRightNeighbor())
// return oFreeSuitOpponentRight.contains(pSuit);
// return false;
// }
protected static Card getRandomAllowedCard(final CardList cards,
final Card initialCard, final GameType gameType) {
Card result = null;
for (Card c : cards) {
if (c.isAllowed(gameType, initialCard, cards)) {
result = c;
}
}
if (result != null) {
return result;
}
return cards.get(0);
}
protected static Card playRandomCard(CardList pCards) {
return pCards.get((int) (Math.random() * pCards.size()));
}
protected static Card getLowValueTrumpCard(CardList pCards, Suit pTrumpSuit) {
for (int i = pCards.getLastIndexOfSuit(pTrumpSuit); i >= 0; i--) {
if (pCards.get(i).getPoints() < 10) {
return pCards.get(i);
}
}
return pCards.get(pCards.getLastIndexOfSuit(pTrumpSuit));
}
protected static Card playLowestWinningJack(CardList pCards) {
if (pCards.contains(Card.SJ)) {
if (pCards.contains(Card.HJ)) {
if (pCards.contains(Card.DJ)) {
return pCards.get(pCards.indexOf(Card.DJ));
}
return pCards.get(pCards.indexOf(Card.HJ));
}
return pCards.get(pCards.indexOf(Card.SJ));
}
return pCards.get(pCards.indexOf(Card.CJ));
}
protected static Card playRandomJack(CardList pCards) {
int tRandom = (int) (Math.random() * Helper.countJacks(pCards));
return pCards.get(tRandom);
}
protected static Card getLowestBeatingCard(CardList pCards,
GameType pGameType, Card tCardToBeat) {
int counter = -1;
if (pGameType != GameType.GRAND)
counter = pCards.getLastIndexOfSuit(tCardToBeat.getSuit(), false);
if (counter == -1)
counter = Helper.countJacks(pCards) - 1;
// Solange die niedrige Karte die Karte vom Solo-Spieler nicht besiegt,
// weiter hoch gehen im Ranking der Karten
while (!pCards.get(counter).beats(pGameType, tCardToBeat))
counter--;
return pCards.get(counter);
}
protected static CardList getPossibleMaxValueCards(CardList pCards,
int pMaxCardValue) {
CardList possibleCards = new CardList();
for (Suit lSuit : Suit.values()) {
int suitCount = pCards.getSuitCount(lSuit, false);
Card possibleHighCard = pCards.get(pCards.getFirstIndexOfSuit(
lSuit, false));
Card possibleLowCard = pCards.get(pCards.getLastIndexOfSuit(lSuit,
false));
if (suitCount > 0 && possibleHighCard == possibleLowCard
&& possibleLowCard.getPoints() <= pMaxCardValue) {
possibleCards.add(possibleLowCard);
} else if (suitCount > 2
&& possibleLowCard.getPoints() <= pMaxCardValue) {
possibleCards.add(possibleLowCard);
}
}
return possibleCards;
}
}