// Computer player for Spades
// James Ranson
// August 1999
package net.sf.nebulacards.ui;
import java.util.Enumeration;
import net.sf.nebulacards.main.PileOfCards;
import net.sf.nebulacards.main.PlayingCard;
import net.sf.nebulacards.rules.Spades;
import net.sf.nebulacards.util.Think;
public class SpadesComp
extends net.sf.nebulacards.ui.components.ComputerStub
{
private boolean verbose = false;
private int partner;
// constructor
public SpadesComp()
{
super( new Spades() );
}
public void setPosition( int w )
{
super.setPosition(w);
partner = (w + 2) % 4;
}
/* Thinking methods */
protected int thinkBid()
{
int tally = 0;
Enumeration cards = hand.elements();
while (cards.hasMoreElements())
{
PlayingCard c = (PlayingCard)cards.nextElement();
if (c.getValue() > 11 || c.getValue() == 1)
tally++;
}
if (tally > 0)
return tally;
// some final checks before bidding nil
if ( hand.cardsInSuit( PlayingCard.SPADES ).howManyCardsNotNull() > 4 )
tally = 1;
if ( hasBid[partner] && bids[partner] == 0 )
tally = 2;
if (verbose) System.out.println( "Bid: " + String.valueOf(tally) );
return tally;
}
protected PlayingCard thinkPlay()
{
boolean pWinning, pNil, meNil, pSafe;
PlayingCard myPlay = null;
pNil = (bids[partner] == 0); meNil = (bids[whereAmI] == 0);
pWinning = ( tableau.howManyCardsNotNull() > 1
&& rules.whoWinsTrick(tableau) == partner );
pSafe = (tableau.hasPlayed(partner) && !pWinning) || !pNil;
boolean madeBid = ( tricks[partner] + tricks[whereAmI] >= bids[partner] + bids[whereAmI] );
int wantToWin = 0; // + means we want to win the trick, - means no
if (pNil && !pSafe) wantToWin += 20;
if (meNil && tricks[whereAmI] == 0) wantToWin -= 20;
if (madeBid)
wantToWin -= 5;
else wantToWin += 5;
switch (tableau.howManyCardsNotNull())
{
case 3: // we play the last card.
if (pWinning) wantToWin -= 6;
break;
case 2: // one opponent gets to play after us
if (pWinning &&
Think.canBeat( otherHands[(whereAmI+1) % 4], tableau,
(whereAmI+1) % 4, beenPlayed, rules ) < 0.35
) wantToWin -= 6;
break;
}
PileOfCards vp = Think.validPlays( hand, tableau, beenPlayed, rules );
PileOfCards tl = Think.takeLead( vp, tableau, whereAmI, rules );
if (verbose) {
System.out.print( "Want to Win: " ); System.out.println( wantToWin );
System.out.println( "Tableau: " + tableau );
System.out.println( "Hand: " + hand );
System.out.println( "Valid Plays: " + vp );
System.out.println( "Take Lead: " + tl );
}
if (wantToWin >= 0)
{
if (tl.howManyCardsNotNull() > 0)
{ // want to win and can
if (tableau.howManyCardsNotNull() == 3)
myPlay = Think.lowCard( tl, true );
else
myPlay = Think.highCard( tl, true );
}
else // want to win but can't
myPlay = Think.lowCard( vp, true );
}
else { // don't want to win
if (tl.howManyCardsNotNull() < vp.howManyCardsNotNull())
{ // don't have to win
vp.removeAll( tl ); // disregard winning cards
if (pNil || (pWinning && !meNil) ) myPlay = Think.lowCard( vp, true );
else myPlay = Think.highCard( vp, true );
}
else { // have to take lead
if (tableau.howManyCardsNotNull() == 3) // guaranteed to win
myPlay = Think.highCard( vp, true );
else { // possibility of rescue
// avoid trumping
if (!vp.allThisSuit( PlayingCard.SPADES ))
vp.removeSuit( PlayingCard.SPADES );
myPlay = Think.lowCard( vp, true );
}
}
}
if (verbose) {
System.out.println( "Choice: " + myPlay );
System.out.println();
}
return myPlay;
}
protected PileOfCards thinkPass() { return null; }
public void cardToTableau( int pos, PlayingCard c )
{
// All the processing done in the stub still applies.
super.cardToTableau( pos, c );
// However, we can make stronger statements about what cards
// the other players cannot have. In particular, if the card
// is sluffed, then that player cannot have any cards
// from the lead suit
if (pos != whereAmI
&& pos != tableau.getLead()
&& c.getSuit() != tableau.get( 0 ).getSuit()
)
otherHands[pos].removeSuit( tableau.get(0).getSuit() );
}
// we must provide these functions, but they are not useful to us
public void respond( String q ) {}
public void booted( String why ) {}
public void accepted() {} // we take acceptance for granted
public void rejected()
{
System.err.println( "Panic: play was rejected. Something is wrong!" );
callbacks.wantToQuit();
}
}