/**
* 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.data;
import org.jskat.util.CardList;
import org.jskat.util.GameType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Game announcement
*
* An object of this class is returned by a player for game announcement
*/
// FIXME: make member variables private, implement fluent interface for factory
public class GameAnnouncement {
private static Logger log = LoggerFactory.getLogger(GameAnnouncement.class);
/**
* Game type
*/
GameType gameType;
/**
* Discarded cards
*/
CardList discardedCards = new CardList();
/**
* Ouvert announcement
*/
Boolean ouvert = Boolean.FALSE;
/**
* Hand announcement
*/
Boolean hand = Boolean.FALSE;
/**
* Schneider announcement
*/
Boolean schneider = Boolean.FALSE;
/**
* Schwarz announcement
*/
Boolean schwarz = Boolean.FALSE;
/**
* Contra called
*/
Boolean contra = Boolean.FALSE;
/**
* Re called
*/
Boolean re = Boolean.FALSE;
/**
* Constructor
*/
GameAnnouncement() {
}
/**
* Gets the factory for a {@link GameAnnouncement}
*
* @return Factory
*/
public static GameAnnouncementFactory getFactory() {
return new GameAnnouncementFactory();
}
/**
* Factory for a {@link GameAnnouncement}
*/
public final static class GameAnnouncementFactory {
private GameAnnouncement tmpAnnouncement;
GameAnnouncementFactory() {
tmpAnnouncement = new GameAnnouncement();
}
/**
* Gets an empty {@link GameAnnouncement}
*
* @return Empty {@link GameAnnouncement}
*/
public final static GameAnnouncement getEmptyAnnouncement() {
GameAnnouncement result = new GameAnnouncement();
result.hand = true;
return result;
}
/**
* Gets the {@link GameAnnouncement}
*
* @return Game announcement
*/
public final GameAnnouncement getAnnouncement() {
GameAnnouncement result = null;
if (validate()) {
result = tmpAnnouncement;
tmpAnnouncement = new GameAnnouncement();
}
return result;
}
/**
* Sets the {@link GameType}
*
* @param gameType
* Game type
*/
public final void setGameType(final GameType gameType) {
tmpAnnouncement.gameType = gameType;
}
/**
* Sets the discarded cards
*
* @param discardedCards
* Discarded cards
*/
public final void setDiscardedCards(final CardList discardedCards) {
tmpAnnouncement.discardedCards.addAll(discardedCards);
// FIXME: re-activate when factory is fixed
// if (discardedCards != null && discardedCards.size() == 2) {
// tmpAnnouncement.hand = false;
// }
}
/**
* Sets the flag for a hand game
*
* @param isHand
* TRUE, if a hand game was announced
*/
public final void setHand(final Boolean isHand) {
tmpAnnouncement.hand = isHand;
}
/**
* Sets the flag for an ouvert game
*
* @param isOuvert
* TRUE, if an ouvert game was announced
*/
public final void setOuvert(final Boolean isOuvert) {
tmpAnnouncement.ouvert = isOuvert;
}
/**
* Sets the flag for a schneider game
*
* @param isSchneider
* TRUE, if schneider was announced
*/
public final void setSchneider(final Boolean isSchneider) {
tmpAnnouncement.schneider = isSchneider;
}
/**
* Sets the flag for a schwarz game
*
* @param isSchwarz
* TRUE, if a schwarz was announced
*/
public final void setSchwarz(final Boolean isSchwarz) {
tmpAnnouncement.schwarz = isSchwarz;
}
private boolean validate() {
boolean isValid = true;
if (tmpAnnouncement.gameType == null) {
isValid = false;
} else if (tmpAnnouncement.discardedCards.size() != 0
&& tmpAnnouncement.discardedCards.size() != 2) {
isValid = false;
} else if (tmpAnnouncement.gameType == GameType.RAMSCH
|| tmpAnnouncement.gameType == GameType.PASSED_IN) {
if (tmpAnnouncement.hand || tmpAnnouncement.ouvert
|| tmpAnnouncement.isSchneider()
|| tmpAnnouncement.isSchwarz()
|| tmpAnnouncement.discardedCards.size() != 0) {
isValid = false;
}
} else if (tmpAnnouncement.gameType == GameType.NULL) {
if (tmpAnnouncement.hand
&& tmpAnnouncement.discardedCards.size() != 0) {
isValid = false;
} else if (tmpAnnouncement.isSchneider()
|| tmpAnnouncement.isSchwarz()) {
isValid = false;
}
} else if (tmpAnnouncement.gameType == GameType.CLUBS
|| tmpAnnouncement.gameType == GameType.SPADES
|| tmpAnnouncement.gameType == GameType.HEARTS
|| tmpAnnouncement.gameType == GameType.DIAMONDS
|| tmpAnnouncement.gameType == GameType.GRAND) {
if (tmpAnnouncement.hand
&& tmpAnnouncement.discardedCards.size() != 0) {
isValid = false;
} else if (!tmpAnnouncement.hand
&& tmpAnnouncement.discardedCards.size() != 0
&& tmpAnnouncement.discardedCards.size() != 2) {
isValid = false;
} else if (tmpAnnouncement.ouvert
&& (!tmpAnnouncement.hand || !tmpAnnouncement.schneider || !tmpAnnouncement.schwarz)) {
isValid = false;
} else if (tmpAnnouncement.schwarz
&& !tmpAnnouncement.schneider) {
isValid = false;
} else if ((tmpAnnouncement.schwarz || tmpAnnouncement.schneider)
&& !tmpAnnouncement.hand) {
isValid = false;
}
}
if (!isValid) {
log.debug("Invalid " + tmpAnnouncement); //$NON-NLS-1$
}
return isValid;
}
}
/**
* Gets the game type
*
* @return Game type
*/
public final GameType getGameType() {
return gameType;
}
/**
* Gets the discarded cards
*
* @return Discarded cards
*/
public final CardList getDiscardedCards() {
return discardedCards.getImmutableCopy();
}
/**
* Checks whether schneider was announced or not
*
* @return TRUE if schneider was announced
*/
public final boolean isSchneider() {
return schneider.booleanValue();
}
/**
* Checks whether schwarz was announced or not
*
* @return TRUE if schwarz was announced
*/
public final boolean isSchwarz() {
return schwarz.booleanValue();
}
/**
* Checks whether an ouvert game was announced or not
*
* @return TRUE if an ouvert game was announced
*/
public final boolean isOuvert() {
return ouvert.booleanValue();
}
/**
* Checks whether a hand game was announced or not
*
* @return TRUE if a hand game was announced
*/
public final boolean isHand() {
return hand.booleanValue();
}
/**
* @see Object#toString()
*/
@Override
public String toString() {
final StringBuffer result = new StringBuffer();
result.append("Game announcement: ").append(gameType); //$NON-NLS-1$
if (hand.booleanValue()) {
result.append(" hand"); //$NON-NLS-1$
}
if (ouvert.booleanValue()) {
result.append(" ouvert"); //$NON-NLS-1$
}
if (schneider.booleanValue()) {
result.append(" schneider"); //$NON-NLS-1$
}
if (schwarz.booleanValue()) {
result.append(" schwarz"); //$NON-NLS-1$
}
if (discardedCards.size() > 0) {
result.append(" discarded " + discardedCards); //$NON-NLS-1$
}
return result.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ (discardedCards == null ? 0 : discardedCards.hashCode());
result = prime * result + (gameType == null ? 0 : gameType.hashCode());
result = prime * result + (hand == null ? 0 : hand.hashCode());
result = prime * result + (ouvert == null ? 0 : ouvert.hashCode());
result = prime * result
+ (schneider == null ? 0 : schneider.hashCode());
result = prime * result + (schwarz == null ? 0 : schwarz.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final GameAnnouncement other = (GameAnnouncement) obj;
if (discardedCards == null) {
if (other.discardedCards != null) {
return false;
}
} else if (!discardedCards.equals(other.discardedCards)) {
return false;
}
if (gameType != other.gameType) {
return false;
}
if (hand == null) {
if (other.hand != null) {
return false;
}
} else if (!hand.equals(other.hand)) {
return false;
}
if (ouvert == null) {
if (other.ouvert != null) {
return false;
}
} else if (!ouvert.equals(other.ouvert)) {
return false;
}
if (schneider == null) {
if (other.schneider != null) {
return false;
}
} else if (!schneider.equals(other.schneider)) {
return false;
}
if (schwarz == null) {
if (other.schwarz != null) {
return false;
}
} else if (!schwarz.equals(other.schwarz)) {
return false;
}
return true;
}
}