// Rules module for Hearts
// James Ranson
// March 2001
package net.sf.nebulacards.rules;
import net.sf.nebulacards.main.GameResult;
import net.sf.nebulacards.main.PassingRules;
import net.sf.nebulacards.main.PileOfCards;
import net.sf.nebulacards.main.Player;
import net.sf.nebulacards.main.PlayingCard;
import net.sf.nebulacards.main.Rules;
import net.sf.nebulacards.main.Tableau;
public class Hearts extends Rules implements PassingRules {
private int handCount;
public Hearts() {
super("Hearts", NO_TRUMP, "No Trump");
handCount = 0;
}
// check that card 'c' is a valid play in this situation
public boolean validPlay(PileOfCards beenPlayed, Tableau tableau,
PileOfCards hand, PlayingCard c) {
// if there is only one suit in the hand, then any play is legal
if (hand.allThisSuit(c.getSuit()))
return true;
boolean weLead = (tableau.howManyCardsNotNull() == 0);
int suitLed = -1;
if (!weLead)
suitLed = tableau.get(tableau.getLead()).getSuit();
if (!weLead && c.getSuit() != suitLed && hand.anyOfThisSuit(suitLed))
return false;
// now we only need to check for leading hearts too soon
else if (weLead && (c.getSuit() == PlayingCard.HEARTS)
&& !beenPlayed.anyOfThisSuit(PlayingCard.HEARTS))
return false;
// if the card has survived this long, then it is valid
return true;
}
// update the scores
public void score(PileOfCards[] hands, Player[] p) {
for (int i = 0; i < 4; i++) {
int points = 0;
points += hands[i].cardsInSuit(PlayingCard.HEARTS)
.howManyCardsNotNull();
if (hands[i].contains(new PlayingCard("Qs")))
points += 13;
// shot the moon?
if (points == 26) {
points = 0;
for (int j = 0; j < 4; j++)
if (j != i)
p[j].setScore(p[j].getScore() + 26);
break;
}
p[i].setScore(p[i].getScore() + points);
}
}
// furnish a result for this game, including whether the game is complete
public GameResult done(Player[] p) {
GameResult gr = new GameResult();
int highest = 0;
boolean tied = false;
// This method is called precisely once per hand, so we
// increment the hand counter here.
handCount++;
gr.winners = new int[1];
for (int i = 0; i < 4; i++) {
int score = p[i].getScore();
if (score == highest)
tied = true;
else if (score > highest) {
highest = score;
gr.winners[0] = i;
}
}
gr.done = (highest >= 100 && !tied);
return gr;
}
// Passing Methods
public int numPass(int p) {
return (handCount % 4 == 3) ? 0 : 3;
}
public int wherePass(int p) {
// where to pass depends on hand count (left,right,across,hold)
final int loc[][] = { { 1, 3, 2, 0 }, // player 0
{ 2, 0, 3, 1 }, // player 1
{ 3, 1, 0, 2 }, // player 2
{ 0, 2, 1, 3 } // player 3
};
return loc[p][handCount % 4];
}
public boolean checkPass(int p, PileOfCards pass) {
return true;
}
}