/**
* 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 org.jskat.util.Card;
import org.jskat.util.CardList;
import org.jskat.util.GameType;
import org.jskat.util.Rank;
import org.jskat.util.Suit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Daniel Loreck (daniel.loreck@gmail.com)
*
*/
public class Helper {
private static Logger oLog = LoggerFactory.getLogger(Helper.class);
public static Card getHighestSuitTrump(CardList pCards, Suit pSuit) {
return pCards.get(0);
}
public static Card getHighestJack(CardList pCards) {
return pCards.get(0);
}
public static int getHighestSuitTrumpBinary(CardList pCards, Suit pSuit) {
int tJackBinary = getHighestJackBinary(pCards);
if (tJackBinary > 0) {
return tJackBinary;
}
Card tHighestTrump = pCards.get(0);
if (tHighestTrump.getSuit() == pSuit) {
return tHighestTrump.getRank().toBinaryFlag();
}
return 0; // NO Trump
}
public static int getHighestJackBinary(CardList pCards) {
Card tHighestTrump = pCards.get(0);
if (tHighestTrump.getRank() == Rank.JACK) {
if (pCards.contains(Card.CJ)) {
return 1024;
}
if (pCards.contains(Card.SJ)) {
return 512;
}
if (pCards.contains(Card.HJ)) {
return 256;
}
return 128; // DIAMONDS
}
return 0; // NO Jack
}
public static int getSuitCardsToBinary(CardList pCards, Suit pSuit) {
int tBinary = 0;
if (pCards.getSuitCount(pSuit, false) > 0) {
for (int i = pCards.getFirstIndexOfSuit(pSuit, false); i <= pCards
.getLastIndexOfSuit(pSuit, false); i++) {
tBinary += pCards.get(i).getRank().toBinaryFlag();
}
}
return tBinary;
}
public static int getOpponentsTrumpCount(CardList pCards, Suit pSuit) {
return 11 - pCards.getSuitCount(pSuit, false);
}
public static int getGrandBinary(CardList pCards) {
int tBinary = 0;
if (pCards.contains(Card.CJ)) {
tBinary += 1024;
}
if (pCards.contains(Card.SJ)) {
tBinary += 512;
}
if (pCards.contains(Card.HJ)) {
tBinary += 256;
}
if (pCards.contains(Card.DJ)) {
tBinary += 128;
}
return tBinary;
}
public static boolean isHighestTrumpCard(Card pPossibleHighestCard,
GameType pGameType, CardList pPlayedCards) {
if (null == pPlayedCards) {
pPlayedCards = new CardList();
}
if ((pPossibleHighestCard.getRank() == Rank.JACK || pPossibleHighestCard
.getSuit() == pGameType.getTrumpSuit())
&& getTrumpCardsToBinary(pPlayedCards, pGameType.getTrumpSuit())
+ (2 * pPossibleHighestCard.getRank().toBinaryFlag()) > 2047) {
return true;
}
return false;
}
public static boolean isHighestSuitCard(Card pPossibleHighestCard,
GameType pGameType, CardList pPlayedCards, CardList pTrickCards) {
if (pPossibleHighestCard.getSuit() == pGameType.getTrumpSuit()) {
return isHighestTrumpCard(pPossibleHighestCard, pGameType,
pPlayedCards);
}
return isHighestSuitCard(pPossibleHighestCard, pPlayedCards,
pTrickCards);
}
public static boolean isHighestSuitCard(Card pPossibleHighestCard,
CardList pPlayedCards, CardList pTrickCards) {
Suit currentSuit = null;
if (null == pPlayedCards) {
pPlayedCards = new CardList();
}
if (null == pTrickCards) {
pTrickCards = new CardList();
}
if (!pTrickCards.isEmpty()) {
currentSuit = pTrickCards.get(0).getSuit();
} else {
currentSuit = pPossibleHighestCard.getSuit();
}
if (pPossibleHighestCard.getSuit() == currentSuit
&& getSuitCardsToBinary(pPlayedCards, currentSuit)
+ (2 * pPossibleHighestCard.getRank().toBinaryFlag()) > 127) {
return true;
}
return false;
}
public static int getTrumpCardsToBinary(CardList pCards, Suit pSuit) {
int tBinary = getGrandBinary(pCards);
tBinary += getSuitCardsToBinary(pCards, pSuit);
return tBinary;
}
public static int getNullSuitCardsToBinary(CardList pCards, Suit pSuit) {
int counter = 0;
if (pCards.contains(Card.getCard(pSuit, Rank.SEVEN))) {
counter += 128;
}
if (pCards.contains(Card.getCard(pSuit, Rank.EIGHT))) {
counter += 64;
}
if (pCards.contains(Card.getCard(pSuit, Rank.NINE))) {
counter += 32;
}
if (pCards.contains(Card.getCard(pSuit, Rank.TEN))) {
counter += 16;
}
if (pCards.contains(Card.getCard(pSuit, Rank.JACK))) {
counter += 8;
}
if (pCards.contains(Card.getCard(pSuit, Rank.QUEEN))) {
counter += 4;
}
if (pCards.contains(Card.getCard(pSuit, Rank.KING))) {
counter += 2;
}
if (pCards.contains(Card.getCard(pSuit, Rank.ACE))) {
counter += 1;
}
return counter;
}
public static Card getHighestValueCard(CardList pCards, Suit pSuit,
boolean includeJacks) {
if ((!includeJacks && pCards.getSuitCount(pSuit, false) == 0)
|| (includeJacks && pCards.getSuitCount(pSuit, false)
+ Helper.countJacks(pCards) == 0)) {
return null;
}
if (pCards.contains(Card.getCard(pSuit, Rank.ACE))) {
return Card.getCard(pSuit, Rank.ACE);
}
if (pCards.contains(Card.getCard(pSuit, Rank.TEN))) {
return Card.getCard(pSuit, Rank.TEN);
}
if (pCards.contains(Card.getCard(pSuit, Rank.KING))) {
return Card.getCard(pSuit, Rank.KING);
}
if (pCards.contains(Card.getCard(pSuit, Rank.QUEEN))) {
return Card.getCard(pSuit, Rank.QUEEN);
}
if (pCards.contains(Card.DJ) && includeJacks) {
return Card.DJ;
}
if (pCards.contains(Card.HJ) && includeJacks) {
return Card.HJ;
}
if (pCards.contains(Card.SJ) && includeJacks) {
return Card.SJ;
}
if (pCards.contains(Card.CJ) && includeJacks) {
return Card.CJ;
}
if (pCards.contains(Card.getCard(pSuit, Rank.SEVEN))) {
return Card.getCard(pSuit, Rank.SEVEN);
}
if (pCards.contains(Card.getCard(pSuit, Rank.EIGHT))) {
return Card.getCard(pSuit, Rank.EIGHT);
}
if (pCards.contains(Card.getCard(pSuit, Rank.NINE))) {
return Card.getCard(pSuit, Rank.NINE);
}
return null;
}
public static Card getLowestValueCard(CardList pCards, Suit pSuit) {
if (pCards.getSuitCount(pSuit, false) == 0) {
return null;
}
if (pCards.contains(Card.getCard(pSuit, Rank.SEVEN))) {
return Card.getCard(pSuit, Rank.SEVEN);
}
if (pCards.contains(Card.getCard(pSuit, Rank.EIGHT))) {
return Card.getCard(pSuit, Rank.EIGHT);
}
if (pCards.contains(Card.getCard(pSuit, Rank.NINE))) {
return Card.getCard(pSuit, Rank.NINE);
}
if (pCards.contains(Card.getCard(pSuit, Rank.QUEEN))) {
return Card.getCard(pSuit, Rank.QUEEN);
}
if (pCards.contains(Card.getCard(pSuit, Rank.KING))) {
return Card.getCard(pSuit, Rank.KING);
}
if (pCards.contains(Card.getCard(pSuit, Rank.TEN))) {
return Card.getCard(pSuit, Rank.TEN);
}
if (pCards.contains(Card.getCard(pSuit, Rank.ACE))) {
return Card.getCard(pSuit, Rank.ACE);
}
return null;
}
public static Card getLowestTrumpValueCard(CardList pCards, Suit pSuit,
boolean includeJacks) {
if ((!includeJacks && pCards.getSuitCount(pSuit, false) == 0)
|| (includeJacks && pCards.getSuitCount(pSuit, false)
+ Helper.countJacks(pCards) == 0)) {
return null;
}
if (pCards.contains(Card.getCard(pSuit, Rank.SEVEN))) {
return Card.getCard(pSuit, Rank.SEVEN);
}
if (pCards.contains(Card.getCard(pSuit, Rank.EIGHT))) {
return Card.getCard(pSuit, Rank.EIGHT);
}
if (pCards.contains(Card.getCard(pSuit, Rank.NINE))) {
return Card.getCard(pSuit, Rank.NINE);
}
if (pCards.contains(Card.getCard(pSuit, Rank.QUEEN))) {
return Card.getCard(pSuit, Rank.QUEEN);
}
if (pCards.contains(Card.DJ) && includeJacks) {
return Card.DJ;
}
if (pCards.contains(Card.HJ) && includeJacks) {
return Card.HJ;
}
if (pCards.contains(Card.SJ) && includeJacks) {
return Card.SJ;
}
if (pCards.contains(Card.CJ) && includeJacks) {
return Card.CJ;
}
if (pCards.contains(Card.getCard(pSuit, Rank.KING))) {
return Card.getCard(pSuit, Rank.KING);
}
if (pCards.contains(Card.getCard(pSuit, Rank.TEN))) {
return Card.getCard(pSuit, Rank.TEN);
}
if (pCards.contains(Card.getCard(pSuit, Rank.ACE))) {
return Card.getCard(pSuit, Rank.ACE);
}
return null;
}
public static int getGrandMultiplier(CardList pCards) {
int tMultiplier = 2;
if (pCards.contains(Card.CJ)) { // With Jacks
if (pCards.contains(Card.SJ)) {
tMultiplier++;
if (pCards.contains(Card.HJ)) {
tMultiplier++;
if (pCards.contains(Card.DJ)) {
tMultiplier++;
}
}
}
} else { // Without Jacks
if (!pCards.contains(Card.SJ)) {
tMultiplier++;
if (!pCards.contains(Card.HJ)) {
tMultiplier++;
if (!pCards.contains(Card.DJ)) {
tMultiplier++;
}
}
}
}
return tMultiplier;
}
public static int getSuitMultiplier(CardList pCards, Suit pSuit) {
int tMultiplier = 2;
int tCardsBinary = getTrumpCardsToBinary(pCards, pSuit);
int tStartBinary = 1024;
if ((tCardsBinary & tStartBinary) > 0) { // With
while ((tCardsBinary & (tStartBinary = tStartBinary >> 1)) > 0) {
tMultiplier++;
}
} else { // Without
while ((tCardsBinary & (tStartBinary = tStartBinary >> 1)) == 0) {
tMultiplier++;
}
}
return tMultiplier;
}
/**
* Gets a binary representation of the jacks in the given hand
*
* @param cards
* a hand
* @return binary value of the available jacks
*/
public static int getJacks(CardList cards) {
int counter = 0;
if (cards.contains(Card.CJ)) {
counter += 1;
}
if (cards.contains(Card.SJ)) {
counter += 2;
}
if (cards.contains(Card.HJ)) {
counter += 4;
}
if (cards.contains(Card.DJ)) {
counter += 8;
}
return counter;
}
/**
* Gets the number of jacks in the given hand
*
* @param pCards
* a hand
* @return number of jacks
*/
public static int countJacks(CardList pCards) {
CardList x = new CardList(pCards);
x.sort(GameType.GRAND);
int counter = 0;
for (Card lCard : x) {
if (lCard.getRank() == Rank.JACK) {
counter++;
}
}
return counter;
}
/**
* Converts a binary stream to a suit color
*
* @param binary
* binary stream (four bits)
* @return suit color, -1 if more than one bit is set
*/
public static Suit binaryToSuit(int binary) {
Suit result = null;
switch (binary) {
case 1:
return Suit.DIAMONDS;
case 2:
return Suit.HEARTS;
case 3:
return Suit.SPADES;
case 4:
return Suit.CLUBS;
}
oLog.warn(".binaryToSuit(): warning: more than one suit possible! -->"
+ binary);
return result;
}
}