Go Fish/Java: Difference between revisions
(Creation) |
No edit summary |
||
Line 9: | Line 9: | ||
<lang Java>import java.util.ArrayList; //Java's Collection Framework is really what is |
<lang Java>import java.util.ArrayList; //Java's Collection Framework is really what is |
||
import java.util.Scanner; //powering the whole game: don't underestimate it. |
import java.util.Scanner; //powering the whole game: don't underestimate it. |
||
import java.util.Random; |
|||
public class GoFish |
public class GoFish |
||
{ |
{ |
||
static final Random rng = new Random(); |
|||
static private ArrayList<Card> cards; |
static private ArrayList<Card> cards; |
||
static public Player[] Players; |
static public Player[] Players; |
||
Line 17: | Line 19: | ||
public static Card draw() |
public static Card draw() |
||
{ |
{ |
||
return cards.remove( |
return cards.remove(rng.nextInt(cards.size())); |
||
} |
} |
||
Line 61: | Line 63: | ||
abstract class Player |
abstract class Player |
||
{ |
{ |
||
protected ArrayList<Card> hand; |
protected ArrayList<Card> hand = new ArrayList<Card>(); |
||
private int numBooks; |
private int numBooks; |
||
public Player() |
public Player() |
||
{ |
{ |
||
⚫ | |||
for(int i=0;i<8;i++) |
for(int i=0;i<8;i++) |
||
fish(); |
fish(); |
||
Line 154: | Line 155: | ||
{ |
{ |
||
Scanner scn = new Scanner(System.in); |
Scanner scn = new Scanner(System.in); |
||
boolean playing = true; |
|||
do{ |
|||
⚫ | |||
{ |
|||
⚫ | |||
if(book != null) |
if(book != null) |
||
System.out.println("You got a book of " + book + "s!"); |
System.out.println("You got a book of " + book + "s!"); |
||
Line 176: | Line 176: | ||
System.out.println("Ask opponent for what card?"); |
System.out.println("Ask opponent for what card?"); |
||
⚫ | |||
try{ |
try{ |
||
req = Card.valueOf(scn.next().toUpperCase()); |
req = Card.valueOf(scn.next().toUpperCase()); |
||
Line 192: | Line 193: | ||
System.out.println("You ask for a " + req); |
System.out.println("You ask for a " + req); |
||
playing = askFor(req); //If you get card(s), askFor returns true and loops |
playing = askFor(req); //If you get card(s), askFor returns true and loops |
||
} |
} while(playing); |
||
System.out.println("Go fish!"); |
System.out.println("Go fish!"); |
||
fish(); |
fish(); |
||
Line 200: | Line 201: | ||
class AIPlayer extends Player |
class AIPlayer extends Player |
||
{ |
{ |
||
public ArrayList<Card> queries; |
public ArrayList<Card> queries = new ArrayList<Card>(); |
||
private int age; |
private int age = 0; |
||
public AIPlayer() |
|||
{ |
|||
queries = new ArrayList<Card>(); |
|||
age = 0; |
|||
} |
|||
public void haveTurn() |
public void haveTurn() |
||
{ |
{ |
||
boolean playing; |
|||
do{ |
|||
⚫ | |||
{ |
|||
⚫ | |||
if(book != null) |
if(book != null) |
||
System.out.println("Your opponent got a book of " + book + "s..."); |
System.out.println("Your opponent got a book of " + book + "s..."); |
||
Line 222: | Line 216: | ||
break; |
break; |
||
} |
} |
||
req = aiMagic(); |
Card req = aiMagic(); |
||
System.out.println("Your opponent asks for cards by the name of " + req); |
System.out.println("Your opponent asks for cards by the name of " + req); |
||
playing = askFor(req); |
playing = askFor(req); |
||
age++; |
age++; |
||
} |
} while(playing); |
||
System.out.println("Your opponent goes fishing."); |
System.out.println("Your opponent goes fishing."); |
||
fish(); |
fish(); |
||
Line 245: | Line 239: | ||
return queries.remove(i); //once it extracts a card from you, it will stop |
return queries.remove(i); //once it extracts a card from you, it will stop |
||
} //asking for that card, until YOU ask for it again. |
} //asking for that card, until YOU ask for it again. |
||
return hand.get( |
return hand.get(GoFish.rng.nextInt(hand.size())); |
||
} |
} |
||
}</lang> |
}</lang> |
Revision as of 05:33, 24 November 2011
I read everything on the Go Fish page before starting this implementation -- except for the part about Playing Cards. So no code from that was reused here, although there may be strong similarities. The class architecture and names , as you might have noticed, were stolen from the Ruby version (GoFish was Deck until my storing all the classes in one GoFish file stopped that). Although I didn't look at the Java Playing Cards until after most of my coding was complete, as I said, I have a feeling my using enum was not an original thought, though I don't know where it came from.
As I say in the comments, this implementation was made possible by the JCF and Java's enums. I don't know how I could have done it without them.
<lang Java>import java.util.ArrayList; //Java's Collection Framework is really what is import java.util.Scanner; //powering the whole game: don't underestimate it. import java.util.Random;
public class GoFish {
static final Random rng = new Random(); static private ArrayList<Card> cards; static public Player[] Players;
public static Card draw()
{ return cards.remove(rng.nextInt(cards.size())); }
public static int deckSize() { return cards.size();
}
public static void main(String[] args) {
cards = new ArrayList<Card>(); for(int i=0;i<4;i++) for(Card c: Card.values()) cards.add(c); Player h = new HumanPlayer(); Player ai = new AIPlayer(); Players = new Player[] {h, ai};
while(Players[0].getNumBooks() + Players[1].getNumBooks() < 13) { Players[0].haveTurn(); System.out.println("----------"); Players[1].haveTurn(); System.out.println("----------"); }
int yScore = Players[0].getNumBooks(); int aiScore = Players[1].getNumBooks(); if (yScore > aiScore) System.out.println("Congratulations, you win "+ yScore + " to "+ aiScore +"!"); else if (aiScore > yScore) System.out.println("The terrible AI beat you "+ yScore + " to "+ aiScore +"..."); else System.out.println("It's a tie at "+yScore+" each!"); }
}
enum Card //Java's enums made this possible! {
ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING;
}
abstract class Player {
protected ArrayList<Card> hand = new ArrayList<Card>(); private int numBooks;
public Player() { for(int i=0;i<8;i++) fish(); }
public boolean hasGiven(Card cType) { return hand.contains(cType); }
public ArrayList<Card> giveAll(Card cType) { ArrayList<Card> x = new ArrayList<Card>(); //Complicated because simply taking the cards as they for(int i=0;i<hand.size();i++) //are found would mess up the traversing of the hand if (hand.get(i) == cType) x.add(hand.get(i)); for(int c=0;c<x.size();c++) hand.remove(cType); return x; }
protected boolean askFor(Card cType) { int tmp = 0; if (this instanceof HumanPlayer) tmp = 1; Player other = GoFish.Players[tmp];
//Used for the computer's strategy// if (tmp==1) ((AIPlayer) other).queries.add(cType); // //
if (other.hasGiven(cType)) { for(Card c: other.giveAll(cType)) hand.add(c); return true; } else { return false; } }
protected void fish()
{ if (GoFish.deckSize() > 0) hand.add(GoFish.draw()); else System.out.println("But that's impossible since the deck is empty.");
}
public int getNumBooks() { return numBooks; }
protected Card checkForBooks() { for(Card c: hand) //Not very elegant! { int num = 0; for(Card d: hand) if (c == d) num++; if (num == 4) { for(int i=0;i<4;i++) hand.remove(c); numBooks++; return c; } } return null;
}
public abstract void haveTurn();
}
class HumanPlayer extends Player {
public void haveTurn() { Scanner scn = new Scanner(System.in); boolean playing = true; do{ Card book = checkForBooks(); if(book != null) System.out.println("You got a book of " + book + "s!");
if (hand.size() == 0) { System.out.print("Your hand is empty, you must "); //"Go fish!" break; } else { System.out.print("Your hand:"); for(Card c: hand) System.out.print(c + " "); System.out.println(); }
System.out.println("Ask opponent for what card?");
Card req; try{ req = Card.valueOf(scn.next().toUpperCase()); } catch(IllegalArgumentException e){ //If what you said is not in Card System.out.println("Card not present in this deck. Try again:"); continue; }
if(!hand.contains(req)) { System.out.println("You may not ask for a card you have none of. Try again:"); continue; }
System.out.println("You ask for a " + req); playing = askFor(req); //If you get card(s), askFor returns true and loops } while(playing); System.out.println("Go fish!"); fish(); }
}
class AIPlayer extends Player {
public ArrayList<Card> queries = new ArrayList<Card>(); private int age = 0;
public void haveTurn() { boolean playing; do{ Card book = checkForBooks(); if(book != null) System.out.println("Your opponent got a book of " + book + "s..."); if (hand.size() == 0) { System.out.print("Your opponent's hand is empty."); break; } Card req = aiMagic(); System.out.println("Your opponent asks for cards by the name of " + req); playing = askFor(req); age++; } while(playing); System.out.println("Your opponent goes fishing."); fish(); }
//The AI's strategy is to first ask for things you asked for, since you have those things. //Failing that, it chooses at random.
private Card aiMagic() { if (age>2) { queries.remove(queries.size()-1); //gets rid of oldest entry so it won't age=0; //get stuck asking for the same thing } for(int i=queries.size()-1; i>-1; i--) //(maybe a queue would have been better?) if (hand.contains(queries.get(i))) { return queries.remove(i); //once it extracts a card from you, it will stop } //asking for that card, until YOU ask for it again. return hand.get(GoFish.rng.nextInt(hand.size())); }
}</lang>