diff --git a/Ability.class b/Ability.class new file mode 100644 index 0000000..e61e593 Binary files /dev/null and b/Ability.class differ diff --git a/Ability.ctxt b/Ability.ctxt new file mode 100644 index 0000000..1567d0f --- /dev/null +++ b/Ability.ctxt @@ -0,0 +1,6 @@ +#BlueJ class context +comment0.target=String\ toString() +comment1.target=int\ uses() +comment2.params=deck\ discardPile\ players +comment2.target=void\ use(LStack,\ LStack,\ ArrayList) +numComments=3 diff --git a/Ability.java b/Ability.java new file mode 100644 index 0000000..a88723d --- /dev/null +++ b/Ability.java @@ -0,0 +1,10 @@ +import java.util.ArrayList; + +public interface Ability +{ + public String toString(); + public String name(); + public int uses(); + public boolean endTurn(); + public void use(Deck deck, DiscardPile discardPile, ArrayList players); +} diff --git a/AggressiveCycle.class b/AggressiveCycle.class new file mode 100644 index 0000000..74d7d26 Binary files /dev/null and b/AggressiveCycle.class differ diff --git a/AggressiveCycle.ctxt b/AggressiveCycle.ctxt new file mode 100644 index 0000000..096d215 --- /dev/null +++ b/AggressiveCycle.ctxt @@ -0,0 +1,7 @@ +#BlueJ class context +comment0.params=owner +comment0.target=AggressiveCycle(Player) +comment1.params=deck\ playerList\ discardPile +comment1.target=void\ play(LStack,\ ArrayList,\ LStack) +comment1.text=\n@param\ deck\ The\ current\ deck\ we're\ playing\ with.\n@param\ playerList\ The\ list\ of\ playrs\ we're\ playing\ with.\n@param\ discardPile\ The\ growing\ discardPile\ in\ the\ game.\n\n +numComments=2 diff --git a/AggressiveBehavior.java b/AggressiveCycle.java similarity index 83% rename from AggressiveBehavior.java rename to AggressiveCycle.java index fd76020..9fff649 100644 --- a/AggressiveBehavior.java +++ b/AggressiveCycle.java @@ -6,11 +6,11 @@ * in any situation. If the AI can play several cards in one turn, it will always play those. It will play a matching * card by number than by suit. If it cannot play a card, it will draw until it has a playable card. */ -public class AggressiveBehavior implements Behavior +public class AggressiveCycle implements Behavior { public Player owner; - public AggressiveBehavior(Player owner) + public AggressiveCycle(Player owner) { this.owner = owner; } @@ -20,7 +20,7 @@ public AggressiveBehavior(Player owner) * @param playerList The list of playrs we're playing with. * @param discardPile The growing discardPile in the game. */ - public void play(LStack deck, ArrayList playerList, LStack discardPile) + public void play(Deck deck, ArrayList playerList, DiscardPile discardPile) { ArrayList hand = owner.hand; Card topCard = discardPile.peek(); @@ -51,6 +51,8 @@ public void play(LStack deck, ArrayList playerList, LStack d // DecisonReached will be set to 'true' as soon as any card is played. boolean decisionReached = false; + boolean cardDrawn = false; + int cardsDrawn = 0; while(!decisionReached) { // Check the active suit, this will be changed later. @@ -82,6 +84,8 @@ public void play(LStack deck, ArrayList playerList, LStack d { for(Card card : playableCardsByValue) { + if(owner.hand.size() == 1) + System.out.println(owner.say(owner.tauntText, "shouted")); owner.hand.remove(card); discardPile.push(card); System.out.println(owner + " played a " + card); @@ -102,18 +106,29 @@ public void play(LStack deck, ArrayList playerList, LStack d // Play the first card from this list if we can play from it. if(playableCardsBySuit.size() >= 1) { + if(owner.hand.size() == 1) + System.out.println("Thrall shouted, \"" + owner.tauntText + "\""); + owner.hand.remove(playableCardsBySuit.get(0)); discardPile.push(playableCardsBySuit.get(0)); System.out.println(owner + " played a " + playableCardsBySuit.get(0)); decisionReached = true; } - else + else if(!cardDrawn) { // We can't play a single card, so draw. Card drawCard = deck.pop(); owner.hand.add(drawCard); - System.out.println(owner + " drew a " + drawCard); + System.out.println(owner + " drew a card."); + cardDrawn = true; + cardsDrawn++; } + else if(cardDrawn) + { + owner.ability.use(deck, discardPile, playerList); + decisionReached = true; + } + else if(cardsDrawn == 3) decisionReached = true; } } } diff --git a/AggressiveFabricate.class b/AggressiveFabricate.class new file mode 100644 index 0000000..4727f90 Binary files /dev/null and b/AggressiveFabricate.class differ diff --git a/AggressiveFabricate.ctxt b/AggressiveFabricate.ctxt new file mode 100644 index 0000000..fd89105 --- /dev/null +++ b/AggressiveFabricate.ctxt @@ -0,0 +1,7 @@ +#BlueJ class context +comment0.params=owner +comment0.target=AggressiveFabricate(Player) +comment1.params=deck\ playerList\ discardPile +comment1.target=void\ play(LStack,\ ArrayList,\ LStack) +comment1.text=\n@param\ deck\ The\ current\ deck\ we're\ playing\ with.\n@param\ playerList\ The\ list\ of\ playrs\ we're\ playing\ with.\n@param\ discardPile\ The\ growing\ discardPile\ in\ the\ game.\n\n +numComments=2 diff --git a/AggressiveFabricate.java b/AggressiveFabricate.java new file mode 100644 index 0000000..b8be2ae --- /dev/null +++ b/AggressiveFabricate.java @@ -0,0 +1,141 @@ + +import java.util.ArrayList; + +/** + * AggressiveBehavior is the basic AI behavior characters will use. AggressiveBehavior favors playing the most cards + * in any situation. If the AI can play several cards in one turn, it will always play those. It will play a matching + * card by number than by suit. If it cannot play a card, it will draw until it has a playable card. + */ +public class AggressiveFabricate implements Behavior +{ + public Player owner; + + public AggressiveFabricate(Player owner) + { + this.owner = owner; + } + + /** + * @param deck The current deck we're playing with. + * @param playerList The list of playrs we're playing with. + * @param discardPile The growing discardPile in the game. + */ + public void play(Deck deck, ArrayList playerList, DiscardPile discardPile) + { + ArrayList hand = owner.hand; + Card topCard = discardPile.peek(); + ArrayList eightSuits = new ArrayList(); // The different suits we have for our eight cards. + + // NumSuits will store the number of cards we have for each suit. The order of this array is: + // diamond heart club space + // So if we have 4 hearts, 2 clubs, and 2 spades, our array will be {0, 4, 2, 2} + int[] numSuits = {0, 0, 0, 0}; + for(Card card : hand) + { + int suitSelector = -1; + // Because suits are stored as strings, and we're selecting by integer, we need + // to appropriately associate our suits with appropriate integer values. + if(card.suit.equals("diamond")) suitSelector = 0; + else if(card.suit.equals("heart")) suitSelector = 1; + else if(card.suit.equals("club")) suitSelector = 2; + else if(card.suit.equals("spade")) suitSelector = 3; + + // Select the suit that we'll increment. + if(suitSelector > -1) numSuits[suitSelector]++; + + if(card.value == 8) + { + eightSuits.add(suitSelector); + } + } + + // DecisonReached will be set to 'true' as soon as any card is played. + boolean decisionReached = false; + boolean cardDrawn = false; + int cardsDrawn = 0; + int abilityUsed = 0; + while(!decisionReached) + { + // Check the active suit, this will be changed later. + String activeSuitName = discardPile.peek().suit; + int activeSuit = -1; // The actual integer value we'll use to select a suit with. + int suitSelector = -1; // Mirrored function above, but activeSuit may differ later on. + if(activeSuitName.equals("diamond")) suitSelector = 0; + else if(activeSuitName.equals("heart")) suitSelector = 1; + else if(activeSuitName.equals("club")) suitSelector = 2; + else if(activeSuitName.equals("spade")) suitSelector = 3; + + // Similar to suit. + int activeValue = discardPile.peek().value; + boolean multipleCardPlay = false; // Are we going to play multiple cards? + ArrayList playableCardsByValue = new ArrayList(); + + // Fill a list of cards that we can play from our hand that match with the current card. + for(Card card : hand) + { + if(card.value == discardPile.peek().value) + { + playableCardsByValue.add(card); + } + } + + // If we have playable cards from the above list, play all of them since we can play multiple + // cards that all match the active card. + if(playableCardsByValue.size() >= 1) + { + for(Card card : playableCardsByValue) + { + if(owner.hand.size() == 1) + System.out.println("Thrall shouted, \"" + owner.tauntText + "\""); + owner.hand.remove(card); + discardPile.push(card); + System.out.println(owner + " played a " + card); + } + decisionReached = true; + } + else + { + // We didn't have any playable cards by value. Do it by suit instead. + ArrayList playableCardsBySuit = new ArrayList(); + + for(Card card : hand) + { + if(card.suit.equals(discardPile.peek().suit)) + playableCardsBySuit.add(card); + } + + // Play the first card from this list if we can play from it. + if(playableCardsBySuit.size() >= 1) + { + if(owner.hand.size() == 1) + System.out.println(owner.say(owner.tauntText, "shouted")); + + owner.hand.remove(playableCardsBySuit.get(0)); + discardPile.push(playableCardsBySuit.get(0)); + System.out.println(owner + " played a " + playableCardsBySuit.get(0)); + decisionReached = true; + } + else if(abilityUsed < owner.ability.uses()) + { + owner.ability.use(deck, discardPile, playerList); + abilityUsed += 1; + } + else if(cardsDrawn < 3) + { + // We can't play a single card, so draw. + Card drawCard = deck.pop(); + owner.hand.add(drawCard); + System.out.println(owner + " drew a card."); + cardDrawn = true; + cardsDrawn++; + } + else + { + decisionReached = true; + } + } + } + + System.out.println("\n\n"); + } +} diff --git a/Behavior.class b/Behavior.class new file mode 100644 index 0000000..0d8eec3 Binary files /dev/null and b/Behavior.class differ diff --git a/Behavior.ctxt b/Behavior.ctxt new file mode 100644 index 0000000..cd87d8b --- /dev/null +++ b/Behavior.ctxt @@ -0,0 +1,4 @@ +#BlueJ class context +comment0.params=deck\ playerList\ discardPile +comment0.target=void\ play(LStack,\ ArrayList,\ LStack) +numComments=1 diff --git a/Behavior.java b/Behavior.java index 51bf423..e7f6d4b 100644 --- a/Behavior.java +++ b/Behavior.java @@ -7,5 +7,5 @@ */ public interface Behavior { - public void play(LStack deck, ArrayList playerList, LStack discardPile); + public void play(Deck deck, ArrayList playerList, DiscardPile discardPile); } diff --git a/Card.class b/Card.class index 0f339b4..f44e592 100644 Binary files a/Card.class and b/Card.class differ diff --git a/Card.ctxt b/Card.ctxt new file mode 100644 index 0000000..fd434e7 --- /dev/null +++ b/Card.ctxt @@ -0,0 +1,10 @@ +#BlueJ class context +comment0.params=newValue\ newSuit +comment0.target=Card(int,\ String) +comment0.text=\nConstructor\ for\ objects\ of\ class\ Card\n\n +comment1.target=String\ toString() +comment1.text=\n@return\ This\ card\ in\ the\ format\ of\:\ "{Value}\ of\ {suit}\ ({shorthand})"\n\n +comment2.params=other +comment2.target=int\ compareTo(Card) +comment2.text=\nProvide\ a\ method\ that\ allows\ us\ to\ compare\ to\ cards.\ Card\ order\ is\ determined\ firstly\ by\ suit\ in\ this\ fashion\:\nDiamonds\ >\ Hearts\ >\ Spades\ >\ Clubs\nIf\ the\ suit\ of\ two\ cards\ is\ the\ same,\ then\ compare\ their\ value.\ne.g.\ A\ 2\ of\ Diamonds\ is\ greater\ than\ an\ Ace\ of\ Spaces\nA\ 9\ of\ Diamonds\ is\ less\ than\ a\ King\ of\ Diamonds\nA\ Queen\ of\ Hearts\ is\ greater\ than\ a\ Queen\ of\ Clubs.\nA\ card\ not\ of\ the\ four\ cardinal\ suits\ is\ ALWAYS\ considered\ less\ than\ a\ card\ form\ these\ suits.\n\n@param\ other\ The\ other\ card\ to\ compare\ this\ card\ to.\n@return\ -1,\ 0,\ 1\ Pending\ if\ this\ card\ are\ less\ than,\ equal\ to,\ or\ greater\ than\ the\ other.\n\n +numComments=3 diff --git a/Card.java b/Card.java index 5e6df12..3a647a7 100644 --- a/Card.java +++ b/Card.java @@ -1,5 +1,5 @@ - import java.lang.Comparable; +import java.util.ArrayList; /** * The Card class holds information on a card's name, it's suit, value. It also includes methods to print @@ -86,22 +86,36 @@ public int compareTo(Card other) // If one card is of a greater suit, return appropriately. // If not, work it out based on their values. Two cards are only equal if their suit matches as well as their values. if(ranks[0] > ranks[1]) - { - ret = 1; - } + return 1; else if(ranks[1] > ranks[0]) - { - ret = -1; - } + return -1; else { // We now know this to be the same suit. // We are now just comparing the integer value of the card, so why not reuse ranks? ranks[0] = this.value; ranks[1] = other.value; - if(ranks[0] > ranks[1]) ret = 1; - if(ranks[1] > ranks[0]) ret = -1; + if(ranks[0] > ranks[1]) return 1; + if(ranks[1] > ranks[0]) return -1; } - return ret; + return 0; + } + + //Checks if the card is a valid play. + public boolean validPlay(Card other) + { + if(this.value == other.value || this.suit == other.suit) + return true; + else + return false; + } + + //Extra method to check that we can have multiple cards played + // in one turn. + // All of the ranks being played must be the same as the discard Pile's top card. + public boolean sameRank(ArrayList hand, int amount) + { + if(amount == 0) return (this.value == hand.get(0).value); + return (this.value == hand.get(amount).value) && sameRank(hand, amount-1); } -} +} \ No newline at end of file diff --git a/Classic/c00.png b/Classic/c00.png new file mode 100644 index 0000000..c30721c Binary files /dev/null and b/Classic/c00.png differ diff --git a/Classic/d00.png b/Classic/d00.png new file mode 100644 index 0000000..e7e1859 Binary files /dev/null and b/Classic/d00.png differ diff --git a/Classic/h00.png b/Classic/h00.png new file mode 100644 index 0000000..8e4a72d Binary files /dev/null and b/Classic/h00.png differ diff --git a/Classic/s00.png b/Classic/s00.png new file mode 100644 index 0000000..3f25891 Binary files /dev/null and b/Classic/s00.png differ diff --git a/Crazy8Driver.class b/Crazy8Driver.class index e7cef1f..319807f 100644 Binary files a/Crazy8Driver.class and b/Crazy8Driver.class differ diff --git a/Crazy8Driver.ctxt b/Crazy8Driver.ctxt new file mode 100644 index 0000000..aeec142 --- /dev/null +++ b/Crazy8Driver.ctxt @@ -0,0 +1,26 @@ +#BlueJ class context +comment0.params=args +comment0.target=void\ main(String[]) +comment1.params=deck\ playerList\ cardStack +comment1.target=void\ playerTurn(LStack,\ ArrayList,\ LStack) +comment1.text=\nThis\ class\ should\ handle\ everything\ that\ goes\ on\ during\ a\ player's\ turn.\n@param\ deck\ The\ deck\ we\ might\ be\ drawing\ from.\n@param\ The\ list\ of\ players\ (their\ hands\ included)\ we're\ working\ with.\n@param\ cardStack\ The\ growing\ stack\ of\ cards.\n\n +comment2.params=userin\ player\ discardPile +comment2.target=boolean\ discard(Scanner,\ Player,\ LStack) +comment2.text=\n@param\ userin\ The\ scanner\ to\ read\ from.\n@param\ player\ Our\ player.\n@param\ discardPile\ The\ growing\ discard\ pile.\n@return\ If\ a\ card\ was\ discarded\ or\ not.\n\n +comment3.params=player\ deck +comment3.target=Card\ drawCard(Player,\ LStack) +comment4.params=dialogue\ character +comment4.target=void\ pacedDialogue(String,\ Player) +comment4.text=\npacedDialogue\ is\ a\ method\ we\ use\ that\ enters\ input\ and\ then\ tells\ the\ computer\ to\ wait.\ This\ makes\ it\ so\ that\ the\ player\ can\ notice\ and\ process\nthe\ dialogue,\ instead\ of\ it\ all\ happening\ at\ once.\ Usually,\ .pacedDialogue()\ will\ be\ followed\ another\ call\ to\ this\ method,\ resembling\ some\nartificial\ pause\ in\ speech.\n@param\ dialogue\ The\ string\ to\ print\ out.\n@param\ character\ The\ speaker\ for\ this\ line\ of\ dialogue.\n\n +comment5.target=void\ helpMenu() +comment5.text=\nPrint\ out\ and\ handle\ user\ input\ for\ a\ series\ of\ interactive\ menus\ that\ offer\ rules,\ context,\ and\ assistance\ to\ players.\n\n +comment6.params=playerCache +comment6.target=ArrayList\ instantiatePlayers(ArrayList) +comment6.text=\nThis\ class\ is\ used\ to\ offer\ the\ player\ input\ to\ select\ a\ character\ to\ play\ as,\ how\ many\ AI\ opponents\ they\ will\ face,\nand\ randomly\ select\ their\ AI\ opponents.\n@param\ playerCache\ The\ cache\ of\ players\ to\ take\ a\ character\ from.\n@return\ A\ list\ of\ players\ for\ the\ game.\n\n +comment7.params=deck\ players\ playerList +comment7.target=ArrayList>\ dealCards(LStack,\ int,\ ArrayList) +comment7.text=\n@param\ deck\ A\ collection\ of\ cards\ to\ randomly\ deal\ cards\ from.\n@param\ players\ The\ number\ of\ players\ to\ deal\ a\ hand\ to.\n@param\ playerList\ The\ list\ of\ players\ to\ deal\ cards\ to.\n@return\ A\ collection\ of\ hands\ filled\ with\ 8\ cards\ from\ the\ deck.\n\n@precondition\ That\ the\ deck\ passed\ into\ is\ greater\ than\ the\ number\ of\ players\ times\ eight.\n@postcondition\ That\ the\ deck\ passed\ into\ has\ decreased\ in\ size\ by\ a\ multiple\ of\ eight.\n\n +comment8.target=LStack\ makeDeck() +comment8.text=\n@return\ A\ new,\ randomly\ filled\ deck\ of\ the\ four\ suits,\ 1\ through\ Ace.\n\n +comment9.target=ArrayList\ populatePlayerCache() +numComments=10 diff --git a/Crazy8Driver.java b/Crazy8Driver.java index 23d0499..e289743 100644 --- a/Crazy8Driver.java +++ b/Crazy8Driver.java @@ -7,6 +7,9 @@ public class Crazy8Driver { + public static final int MAXRM = 3; + public static final int CHEAT = -2; + public static void main(String[] args) { /* Here we'll instantiate a cache of of players for the program to choose from later on. There is a better way to declare a bunch of Players @@ -18,29 +21,40 @@ public static void main(String[] args) * Uncommented due to testing and fills the list with Gul'dan and Thrall. */ ArrayList players = new ArrayList(); - //players = instantiatePlayers(playerCache); - players.add(playerCache.get(1)); players.add(playerCache.get(8)); // --- This line is for debugging + players = instantiatePlayers(playerCache); + //players.add(playerCache.get(8)); players.add(playerCache.get(4)); // --- This line is for debugging + // Let's make our new, randomly shuffled deck, using makeDeck(). // Let's also deal cards from this deck into player hands. - LStack deck = Crazy8Driver.makeDeck(); + Deck deck = new Deck(); ArrayList> hands = Crazy8Driver.dealCards(deck, players.size(), players); // The current pile of cards we'll be working with will be in the card stack. - LStack cardStack = new LStack(); + DiscardPile cardStack = new DiscardPile(); // Tell the player what's going on, draw a card, and put it into play. System.out.println("You go first."); Card firstCard = deck.pop(); - System.out.println("The first card drawn is a(n) " + firstCard); + System.out.println("The first card drawn is a(n) " + firstCard + "\n\n"); + System.out.println("Enter 'help' for assistance."); cardStack.push(firstCard); boolean exitGame = false; while(!exitGame) { - players.get(1).behavior.play(deck, players, cardStack); - //Crazy8Driver.playerTurn(deck, players, cardStack); - exitGame = true; + for(int i = 0; i < players.size(); i++) + { + if(i == 0) playerTurn(deck, players, cardStack); + else players.get(i).behavior.play(deck, players, cardStack); + if(players.get(i).hand.size() == 0) + { + System.out.println(players.get(i) + " has emptied their hand!"); + System.out.println(players.get(i) + " has won the game!"); + i = 444; + exitGame = true; + } + } } } @@ -50,7 +64,7 @@ public static void main(String[] args) * @param The list of players (their hands included) we're working with. * @param cardStack The growing stack of cards. */ - private static void playerTurn(LStack deck, ArrayList playerList, LStack cardStack) + private static void playerTurn(Deck deck, ArrayList playerList, DiscardPile cardStack) { // So we don't have to repeatedly call playerList.get(0) to refer to the player, let's just make a // variable that does that for us. @@ -63,20 +77,7 @@ private static void playerTurn(LStack deck, ArrayList playerList, String outText = String.format("%-20s %-13s %-20s %-20s\n\n", " ", "Top of stack: ", cardStack.peek(), "Current suit: " + currentSuit + "s"); System.out.println(outText); - // Here we are scrolling through every card in the player's hand and printing it, using .format() to make sure - // everything is spaced correctly. - // Note on this format: The specific %-20s merely specifies a left-aligned message of 20 characters in length. - // So if the string we're passing in place of that argument is not 20 characters in length, the rest of the space - // will be filled in with whitespace. - String handText = ""; - for(Card card : player.hand) - { - handText += String.format("%-25s", card); - // Make every row 4 cards in length, for less wide displays. - if(player.hand.indexOf(card) == 3) handText += "\n"; - } - handText += "\n\n"; - System.out.println(handText); + player.printHand(); // Now we're going to print out the hand size of every player. // Hand size is formatted similarily to the hand above. @@ -100,15 +101,19 @@ private static void playerTurn(LStack deck, ArrayList playerList, legalWords.add("greeting"); legalWords.add("taunt"); legalWords.add("forfeit"); legalWords.add("draw"); legalWords.add("pass"); legalWords.add("discard"); + legalWords.add("ability"); legalWords.add("hand"); // When we need to decide the audience of the player's emotes, it's useful to store the each players' name in a list // so we can easily verify that an enterd name is a valid player. ArrayList playerNames = new ArrayList(); for(Player character : playerList) playerNames.add(character.name); + int abilityUses = 0; + Scanner userIn = new Scanner(System.in); boolean decisionReached = false; String decision = ""; + int cardsDrawn = 0; String errorText = "Invalid input.\n"; // Print this out everytime the user enters bad input. // General note when using scanners that take input from System.in: // If you use scanner.hasNext() when that scaner is taking input from System.in, unless it reads en EOF (Ctrl+D), @@ -126,6 +131,10 @@ private static void playerTurn(LStack deck, ArrayList playerList, // Call the helpMenu method. Crazy8Driver.helpMenu(); } + else if(decision.equals("hand")) + { + player.printHand(); + } else if(decision.equals("greeting")) { responseType = "greeting"; @@ -140,12 +149,32 @@ else if(decision.equals("forfeit")) } else if(decision.equals("draw")) { - // Implement the draw mechanic. + if(deck.size > 0) + { + Card drawCard = player.draw(deck); + cardsDrawn++; + System.out.println("You drew a " + drawCard); + } + else + { + System.out.println("The deck is empty, no cards drawn."); + } } else if(decision.equals("pass")) { - // Flesh out this mechanic. - decisionReached = true; + if(cardsDrawn >= 3 || deck.size == 0) + decisionReached = true; + else + System.out.println("You can't pass until you've drawn at least three cards."); + } + else if(decision.equals("ability")) + { + if(abilityUses < player.ability.uses()) + { + player.ability.use(deck, cardStack, playerList); + abilityUses++; + } + if(player.ability.endTurn()) decisionReached = true; } else if(decision.equals("discard")) { @@ -216,81 +245,132 @@ else if(responseType.equals("taunt") && responder != null) * @param player Our player. * @param discardPile The growing discard pile. * @return If a card was discarded or not. + * + * Things to work on for discard: + * Checking the validity of THREE cards in one go. */ - private static boolean discard(Scanner userin, Player player, LStack discardPile) + private static boolean discard(Scanner userin, Player player, DiscardPile discardPile) { + Scanner line; boolean discarded = false; + boolean[] valid = {false,false,false}; //Store validity of cards + ArrayList rmNum = new ArrayList<>(); //Indexes that will be removed from hand. + int cardsRemoved = 0, j = 0, count = 0, chosenCard = -1; + String currentSuit = ""; + Card disCard = new Card(0,"A"); + + //Needs to be implemented to wait until cards are discarded. + System.out.println("\nEnter the number for each card you would like to discard(max: 3).\nEnter any character to stop."); + //Asks for index input and stores it into an ArrayList. - // This patter matches any text that suits the shourthand we use for cards. - Pattern pattern = Pattern.compile("(10)[a-zA-Z]|[1-9ajkqAJKQ][a-zA-Z]"); - System.out.println("\n\n Enter the shorthand for each card you would like to discard."); - int i = 0; - int cardsRemoved = 0; - int cardIndex = -1; - while(userin.hasNext(pattern) && cardsRemoved < 3) + while(count < MAXRM) { - /* While the next input follows our shorthand pattern, and we haven't discarded more than 3 cards, process - * the user input to determine if we can discard the card. - * - */ - - String discardText = ""; - if(cardsRemoved < 3) discardText = userin.next(); - boolean nextInHand = false; - for(Card card : player.hand) + if(userin.hasNextInt() && count < MAXRM) { - if(discardText.equals(card.shortText)) - { - System.out.println("Discarding a " + card); - nextInHand = true; - discarded = true; - - if(player.hand.indexOf(card) > -1) - { - discardPile.push(card); - cardIndex = player.hand.indexOf(card); - } - else - { - cardIndex = -1; - } - - - cardsRemoved++; - } + rmNum.add(userin.nextInt()-1); + count++; } - - if(cardIndex > -1) player.hand.remove(cardIndex); - - String handText = ""; - for(Card card : player.hand) + else { - handText += String.format("%-25s", card); - // Make every row 4 cards in length, for less wide displays. - if(player.hand.indexOf(card) == 3) handText += "\n"; + System.out.println("Ending 'discard' input..."); + break; } - handText += "\n\n"; - System.out.println(handText); - - if(!nextInHand) + } + + /* + * This section responds to the input indexes and sets the validity of the cards in + * 'valid' array. + * CHEAT = -2, and it auto-plays the first card in your hand. + */ + for(int i = 0; i < rmNum.size(); i++) + { + disCard = (rmNum.get(i) == CHEAT)? player.hand.get(0) : player.hand.get(rmNum.get(i)); + if(rmNum.get(i) == CHEAT) { - System.out.println("\n'" + discardText + "' not a valid card in your hand."); - System.out.println("Will end after 3 cards have been discarded. \n\n\n"); + System.out.println("You're cheating! Discarding "+player.hand.get(i).toString()); + valid[i] = discarded = true; + } + else if(rmNum.get(i) >= player.hand.size() || rmNum.get(i) < 0) + { + System.out.println("\n'" + disCard + "' not a valid card in your hand."); + System.out.println("Will end after 3 cards max have been discarded. \n\n\n"); + valid[i] = false; + } + else + { + if(cardsRemoved == 0 && disCard.value == discardPile.EIGHT) + { + disCard.suit = Crazy8Driver.getSuit(); + System.out.println("Discarding a "+player.hand.get(rmNum.get(i)).toString()); + valid[i] = discarded = true; + cardsRemoved += 1; + } + else if((cardsRemoved == 0 && discardPile.peek().validPlay(disCard)) || + (cardsRemoved > 0 && valid[i-1] && discardPile.peek().value == disCard.value)) + { + System.out.println("Discarding a "+player.hand.get(rmNum.get(i)).toString()); + valid[i] = discarded = true; + cardsRemoved += 1; + } + else + { + System.out.println("Cannot play "+player.hand.get(rmNum.get(i)).toString()+" from your hand. Moving on."); + valid[i] = false; + } } } - userin.next(); - System.out.println("\nDiscard phase complete."); + //Now, we remove all of the valid cards from the hand. + for(int i = 0; i < rmNum.size(); i++) + { + int offset = 0; + if(valid[i]) + { + if(rmNum.get(i) == CHEAT) + discardPile.push(player.hand.remove(0)); + else + { + if(i > 0 && rmNum.get(i-1) < rmNum.get(i)) offset += 1; //Increase offset if removing cards from a lower index. + if(i > 1 && rmNum.get(i-2) < rmNum.get(i)) offset += 1; + //Check to see if there is an eight in the played cards. + discardPile.discard(player.hand.remove((int)rmNum.get(i)-offset)); + } + } + } + if(count > 3) + System.out.println("Could not discard the rest of the cards: Max 3 card plays in one turn."); + System.out.println("Discard phase complete."); + userin.nextLine(); return discarded; } - private static Card drawCard(Player player, LStack deck) + //discard(...) helper method + public static String getSuit() { - Card newCard = deck.pop(); - player.hand.add(newCard); - System.out.println(player.name +" drew a "+ newCard +"!"); - return newCard; + Scanner input = new Scanner(System.in); + ArrayList suits = new ArrayList<>(); + suits.add("diamond"); + suits.add("heart"); + suits.add("club"); + suits.add("spade"); + String temp = ""; + + boolean valid = false; + while(true) + { + System.out.println("What suit would you like to choose? "); + temp = input.nextLine(); + if(suits.contains(temp)) + return temp; + else + { + valid = false; + input.nextLine(); + System.out.println("Invalid input for suit."); + System.out.println("Please use all lowercase letters and no numbers."); + } + } } - + /** * pacedDialogue is a method we use that enters input and then tells the computer to wait. This makes it so that the player can notice and process * the dialogue, instead of it all happening at once. Usually, .pacedDialogue() will be followed another call to this method, resembling some @@ -335,17 +415,18 @@ private static void helpMenu() { System.out.println("\n\nThe premise of Crazy 8s is to empty your hand before your opponents, the first to do so wins. \n" + "* You may only discard a card when it matches either the rank or suit of the card at the top of the pile. \n" - + "\t To do this, enter: 'discard' followed by the card you would like to discard in its shorthand form.\n" - + "\t For example, a 6 of Heart's shorthand would be a 6h. An Ace of diamonds would be Ad.\n" + + "\t To do this, enter: 'discard' followed by the index of the card you would like to discard as its presented to you\n" + + "\t For example, to discard the 3rd card from your hand, enter: 'discard' followed by '1'.\n" + "* You may discard several cards of the same rank, all at once. To do this, follow the input:\n" - + "\t discard 4c 4d 4h" - + "\t The shorthands must be seperated by spaces. The last card in the list will be the card at the top of the discard pile.\n" + + "\t discard 1 2 3 \t Where cards 1, 2, and 3 are cards of equal value." + + "\t To exit the discard phase, enter any non-integer input. (For example: 'discard 1 2 a' will work.)\n" + "* You may play an 8 at any time. When an 8 is played, you can change the suit that the other plays must match.\n" - + "\t If the first card to be discarded from the deck is an 8, any suit may be played.\n" + "* If you have no possible cards to discard, you must draw from the pile. To do this, enter 'draw.'\n" + "\t You can draw as many times from the deck as you would like.\n" + "\t Once you may have drawn at least 3 cards, you may pass your turn.\n" - + "\t If the deck has been exhausted, and you have no available cards to play, you may also pass your turn.\n"); + + "\t If the deck has been exhausted, and you have no available cards to play, you may also pass your turn.\n" + + "* And lastly, every character has an ability which they can use to influence the game. To use your character's ability\n" + + "\t enter 'ability' to use it. Take note, however, that some abilities will end your turn.\n"); } else if(decision.equals("emotes")) { @@ -360,6 +441,7 @@ else if(decision.equals("[misc]")) System.out.println(String.format("%-10s %-30s", "greeting", "Say a greeting to the AI.")); System.out.println(String.format("%-10s %-30s", "taunt", "Taunt the AI.")); System.out.println(String.format("%-10s %-30s", "players", "List the players in the current game.")); + System.out.println(String.format("%-10s %-30s", "ability", "Use your player ability.")); System.out.println(String.format("%-10s %-30s", "forfeit", "Forfeit the game.")); } else if(decision.equals("menu")) System.out.println(menuText); @@ -414,8 +496,8 @@ private static ArrayList instantiatePlayers(ArrayList playerCach while(!kill2) { System.out.println("\n " + playerOfChoice); - System.out.println("Flavor text will go here."); - System.out.println("Maybe some other stuff too?"); + System.out.println("Ability: " + playerOfChoice.ability.name()); + System.out.println("\n" + playerOfChoice.ability + "\n"); System.out.println("Enter 'yes' to select this character, enter 'no' to go back to selection.\n"); choiceName = playerChoice.next(); if(choiceName.equals("yes")) kill2 = true; @@ -630,7 +712,34 @@ private static ArrayList populatePlayerCache() playerCache.add(new Player("Garrosh", "Victory or death!", "Heh, greetings.", "I will crush you!")); playerCache.add(new Player("Thrall", "Elements guide me!", "Greetings, friend.", "The elements will destroy you!")); - playerCache.get(8).behavior = new AggressiveBehavior(playerCache.get(8)); + playerCache.get(8).behavior = new AggressiveFabricate(playerCache.get(8)); + playerCache.get(8).ability = new FabricateAbility(playerCache.get(8)); + + playerCache.get(7).behavior = new AggressiveCycle(playerCache.get(7)); + playerCache.get(7).ability = new CycleAbility(playerCache.get(7)); + + playerCache.get(6).behavior = new AggressiveFabricate(playerCache.get(6)); + playerCache.get(6).ability = new FabricateAbility(playerCache.get(6)); + + playerCache.get(5).behavior = new AggressiveCycle(playerCache.get(5)); + playerCache.get(5).ability = new CycleAbility(playerCache.get(5)); + + playerCache.get(4).behavior = new AggressiveFabricate(playerCache.get(4)); + playerCache.get(4).ability = new FabricateAbility(playerCache.get(4)); + + playerCache.get(3).behavior = new AggressiveCycle(playerCache.get(3)); + playerCache.get(3).ability = new CycleAbility(playerCache.get(3)); + + playerCache.get(2).behavior = new AggressiveFabricate(playerCache.get(2)); + playerCache.get(2).ability = new FabricateAbility(playerCache.get(2)); + + playerCache.get(1).behavior = new AggressiveCycle(playerCache.get(1)); + playerCache.get(1).ability = new CycleAbility(playerCache.get(1)); + + playerCache.get(0).behavior = new AggressiveFabricate(playerCache.get(0)); + playerCache.get(0).ability = new RefreshAbility(playerCache.get(0)); + + return playerCache; } } diff --git a/CycleAbility.class b/CycleAbility.class new file mode 100644 index 0000000..2783f42 Binary files /dev/null and b/CycleAbility.class differ diff --git a/CycleAbility.ctxt b/CycleAbility.ctxt new file mode 100644 index 0000000..48f42be --- /dev/null +++ b/CycleAbility.ctxt @@ -0,0 +1,8 @@ +#BlueJ class context +comment0.params=player +comment0.target=CycleAbility(Player) +comment1.target=int\ uses() +comment2.target=String\ toString() +comment3.params=deck\ discardPile\ players +comment3.target=void\ use(LStack,\ LStack,\ ArrayList) +numComments=4 diff --git a/CycleAbility.java b/CycleAbility.java new file mode 100644 index 0000000..e641760 --- /dev/null +++ b/CycleAbility.java @@ -0,0 +1,54 @@ +import java.util.ArrayList; +import java.util.Random; + +/** + * The Cycle ability allows a character to discard randomly from their hand onto the pile and draw a card. + */ +public class CycleAbility implements Ability +{ + private Player owner; + public String name = "Cycle"; + + /** + * @param player The player that 'owns' this skill. + */ + public CycleAbility(Player player) + { + this.owner = player; + } + + /** + * Cycle is supposed to end your turn right away, so its uses doesn't matter. + */ + public int uses() { return 2;} + + public String name() { return this.name; } + + public boolean endTurn() { return true; } + + /** + * A description of Cycle. Call ability.name instead for its name. + */ + public String toString() + { + return "Cycle a card from your hand into the discard pile, and draw a card from the deck. End your turn.\n\n\n\n"; + } + + /** + * Generate a random integer to select from the hand, discard it, draw a card. + * @param deck Refer to interface documentation. + * @param discardPile Refer to interface documentation. + * @param players Refer to interface documentation. + */ + public void use(Deck deck, DiscardPile discardPile, ArrayList players) + { + Random randomIndexGenerator = new Random(); + int randomIndex = randomIndexGenerator.nextInt(owner.hand.size()); + Card discard = owner.hand.remove(randomIndex); + System.out.println(owner + " used 'Cycle!'"); + System.out.println(owner + " discarded a " + discard + " onto the pile."); + discardPile.push(discard); + System.out.println(owner + " drew a card."); + owner.hand.add(deck.pop()); + } +} diff --git a/Deck.java b/Deck.java new file mode 100644 index 0000000..7de20d8 --- /dev/null +++ b/Deck.java @@ -0,0 +1,108 @@ +import java.util.*; + +public class Deck extends LStack +{ + /** + * Inherits: push(...), pop(), isEmpty(), get(...), peek(), search(...) + * @return A new, randomly filled deck of the four suits, 1 through Ace. + */ + public Deck() + { + // First we need to establish the cards we are using. It's easier to just load the cards + // into suits, and then randomly pick from within the suits when we're filling the deck. + // Here, we're just declaring lists of Cards, and filling them sequentially with 14 cards. + //LinkedList newDeck = new LinkedList(); + ArrayList diamonds = new ArrayList(); + ArrayList hearts = new ArrayList(); + ArrayList clubs = new ArrayList(); + ArrayList spades = new ArrayList(); + for(int i = 2; i <= 14; i++) diamonds.add(new Card(i, "diamond")); + for(int i = 2; i <= 14; i++) hearts.add(new Card(i, "heart")); + for(int i = 2; i <= 14; i++) clubs.add(new Card(i, "club")); + for(int i = 2; i <= 14; i++) spades.add(new Card(i, "spade")); + + // Now we need to randomly select from the above suits and add each one to the deck + // removing from their suit's list. We do this until all suits are empty. + boolean suitsUsed = false; // If all suits are used up, exit the loop. + Random ran = new Random(); + int ranNum = 0; // This determines the random index from the suit list we'll take from. + int ranSuit = 0; // This determines the random suit we'll select. + // We'll store the suits that are currently empty, so we have a nice collection of empty suits + // as they are used up. + ArrayList emptySuits = new ArrayList(); + while(!suitsUsed) + { + // Here, we declare which suit we'll be working with -- however, what if we recieve a + // random integer for a matching suit that is EMPTY? The following while loop examines + // what we get, and makes sure we only progress until we know we'll be working with a suit + // that is not empty. + ranSuit = ran.nextInt(4); + while(emptySuits.contains(ranSuit)) ranSuit = ran.nextInt(4); + + // Here, suit will be pointing to one of the non-empty declared suits above. This way, + // we don't need to hardcode for each suit, but we can just refer to the suit we're + // working with as "suit." + ArrayList suit = new ArrayList(); + switch(ranSuit) + { + case 0: + suit = diamonds; + break; + case 1: + suit = hearts; + break; + case 2: + suit = clubs; + break; + case 3: + suit = spades; + break; + } + + // Currently, if we randomly select an empty suit that hasn't been added to emptySuits, + // this is where we'd add that suit to emptySuits. + // + // The first else condition is the portion of the method that actually adds a randomly + // selected card, and pushes that card into LStack deck. Once we do that, we're then sure + // to remove that card from its suit. + // + // The final else statement flips the kill condition "suitsUsed" once every suit is emptied. + if(suit.size() == 0) emptySuits.add(ranSuit); + else if(suit.size() != 0) + { + // We declare ranNum to be a number from 0 to the size of the current suit we're working with. + // This size decreases overtime as we remove cards from that particular suit, so in this way, + // we can randomly select a card from that decreasing list. + ranNum = ran.nextInt(suit.size()); + this.push(suit.remove(ranNum)); + //suit.remove(ranNum); + //System.out.println("Deck Size: " + this.size); + } + if(diamonds.size() == 0 && hearts.size() == 0 && clubs.size() == 0 && spades.size() == 0) + suitsUsed = true; + } + } + + public Card draw() + { + return this.pop(); + } + + public void shuffle() + { + ArrayList tempDeck = new ArrayList(); + // Fill the new list of cards with the cards still in the deck. + while(!this.isEmpty()) + { + tempDeck.add(this.pop()); + } + // Randomly push the cards from tempDeck to the original Deck. + Random randy = new Random(); + int ranInt; + while(!tempDeck.isEmpty()) + { + ranInt = randy.nextInt(tempDeck.size()); + this.push(tempDeck.remove(ranInt)); + } + } +} \ No newline at end of file diff --git a/DiscardPile.java b/DiscardPile.java new file mode 100644 index 0000000..49f8ed2 --- /dev/null +++ b/DiscardPile.java @@ -0,0 +1,26 @@ +import java.util.*; + +public class DiscardPile extends LStack +{ + public final static int EIGHT = 8; + public String topSuit = ""; + + /* + * @return String top suit + */ + public void push(Card other) + { + super.push(other); + topSuit = this.peek().suit; + } + + /** + * Discard a card other than an eight. + * Actually, this method is unnecessary for the implementation of the game. + */ + public void discard(Card top) + { + this.push(top); + topSuit = top.suit; + } +} \ No newline at end of file diff --git a/FabricateAbility.class b/FabricateAbility.class new file mode 100644 index 0000000..46e39d4 Binary files /dev/null and b/FabricateAbility.class differ diff --git a/FabricateAbility.ctxt b/FabricateAbility.ctxt new file mode 100644 index 0000000..4363720 --- /dev/null +++ b/FabricateAbility.ctxt @@ -0,0 +1,8 @@ +#BlueJ class context +comment0.params=player +comment0.target=FabricateAbility(Player) +comment1.target=String\ toString() +comment2.target=int\ uses() +comment3.params=deck\ discardPile\ players +comment3.target=void\ use(LStack,\ LStack,\ ArrayList) +numComments=4 diff --git a/FabricateAbility.java b/FabricateAbility.java new file mode 100644 index 0000000..4cfb1f1 --- /dev/null +++ b/FabricateAbility.java @@ -0,0 +1,42 @@ +import java.util.ArrayList; +import java.util.Random; + +public class FabricateAbility implements Ability +{ + private Player owner; + public String name = "Fabricate"; + + public FabricateAbility(Player player) + { + this.owner = player; + } + + public String toString() + { + return "Once per turn, you can create a valueless card of a random suit and place it on the top of the discard pile.\n\n\n\n"; + } + + public int uses() { return 1; } + + public String name() { return this.name; } + + public boolean endTurn() { return false; } + + public void use(Deck deck, DiscardPile discardPile, ArrayList players) + { + Random randomIndexGenerator = new Random(); + int randomSuitNum = randomIndexGenerator.nextInt(4); + String randomSuit = "default"; + if(randomSuitNum == 0) randomSuit = "diamond"; + else if(randomSuitNum == 1) randomSuit = "heart"; + else if(randomSuitNum == 2) randomSuit = "spade"; + else if(randomSuitNum == 3) randomSuit = "club"; + + Card fabricatedCard = new Card(0, randomSuit); + discardPile.push(fabricatedCard); + System.out.println(owner + " used 'Fabricate!'"); + System.out.println(owner + " fabricated a " + fabricatedCard); + System.out.println(owner + " discarded it to the top of the pile."); + + } +} diff --git a/LStack.class b/LStack.class index d972ec1..23c7e0c 100644 Binary files a/LStack.class and b/LStack.class differ diff --git a/LStack.ctxt b/LStack.ctxt new file mode 100644 index 0000000..81f4a30 --- /dev/null +++ b/LStack.ctxt @@ -0,0 +1,18 @@ +#BlueJ class context +comment0.target=void\ LStack() +comment1.target=boolean\ isEmpty() +comment1.text=\n@return\ A\ boolean\ telling\ if\ the\ stack\ is\ empty\ or\ not.\n\n +comment2.params=key +comment2.target=int\ search(T) +comment2.text=\nIterate\ through\ the\ stack\ for\ the\ desired\ element.\n@return\ An\ int\ containing\ the\ index\ of\ a\ found\ element.\ -1\ if\ it\ is\ not\ discovered.\n\n +comment3.params=value +comment3.target=void\ push(T) +comment3.text=\nThe\ stack\ push\ method.\n@param\ value\ The\ value\ to\ push.\n\n +comment4.target=T\ pop() +comment4.text=\nThe\ stack\ pop\ method.\n@return\ The\ popped\ item.\n\n +comment5.target=T\ peek() +comment5.text=\nThe\ stack\ peek\ method.\n@return\ The\ top\ of\ the\ stack.\n\n +comment6.params=index +comment6.target=T\ get(int) +comment6.text=\nGet\ the\ value\ of\ an\ item\ at\ a\ certain\ index\ with\ the\ stack.\nNOTE\:\ Stack\ indices\ begin\ from\ 1,\ not\ zero.\n@param\ index\ The\ index\ in\ the\ stack\ you\ want\ to\ get.\n@return\ The\ item\ at\ the\ specified\ index.\n\n +numComments=7 diff --git a/LStack.java b/LStack.java index 3c93641..d69b851 100644 --- a/LStack.java +++ b/LStack.java @@ -1,5 +1,3 @@ - - import java.util.LinkedList; import java.util.Iterator; import java.lang.Comparable; diff --git a/Player.class b/Player.class index 3708fd2..66e41b8 100644 Binary files a/Player.class and b/Player.class differ diff --git a/Player.ctxt b/Player.ctxt new file mode 100644 index 0000000..2c7fd01 --- /dev/null +++ b/Player.ctxt @@ -0,0 +1,7 @@ +#BlueJ class context +comment0.params=newName\ opening\ greeting\ taunt +comment0.target=Player(String,\ String,\ String,\ String) +comment0.text=\n@param\ newName\ Their\ new\ name.\n@param\ opening\ Their\ opening\ line.\n@param\ greeting\ Their\ greeting\ line.\n@param\ taunt\ Their\ taunt\ response.\n\n +comment1.target=Player() +comment2.target=String\ toString() +numComments=3 diff --git a/Player.java b/Player.java index fb816db..4dfa96c 100644 --- a/Player.java +++ b/Player.java @@ -1,5 +1,3 @@ - - import java.util.ArrayList; /** @@ -18,9 +16,12 @@ public class Player /** Their hand of cards. */ public ArrayList hand; + /** Manually set the AI behavior when you create this object. */ public Behavior behavior; + public Ability ability; + /** * @param newName Their new name. * @param opening Their opening line. @@ -35,8 +36,53 @@ public Player(String newName, String opening, String greeting, String taunt) this.openingText = opening; } + /** + * A lazy way to create -somewhat- descriptive dialogue. This method will return a string like: + * Jaina shouted, "My magic will tear you apart!" + * Malfurion lazily mumbled, "This game is crazy." + * + * @param message What you want the character to say. + * @param description How you want them to say it. + * @return A string in the form: {Character.name} {description} "{message}" + */ + public String say(String message, String description) + { + String dialogue = this.name + " " + description + " \"" + message + "\""; + return dialogue; + } + public Player() {} + /** + * Print the player's hand in a list from 1-8. + * + */ + public void printHand() + { + // Here we are scrolling through every card in the player's hand and printing it, using .format() to make sure + // everything is spaced correctly. + // Note on this format: The specific %-20s merely specifies a left-aligned message of 20 characters in length. + // So if the string we're passing in place of that argument is not 20 characters in length, the rest of the space + // will be filled in with whitespace. + String handText = ""; + for(Card card : this.hand) + { + int cardIndex = this.hand.indexOf(card) + 1; + handText += String.format("%-3s %-25s", cardIndex + ")", card); + // Make every row 4 cards in length, for less wide displays. + if(((this.hand.indexOf(card) + 1) % 4) == 0) handText += "\n"; + } + handText += "\n\n"; + System.out.println(handText); + } + + public Card draw(Deck deck) + { + Card drawCard = deck.pop(); + hand.add(drawCard); + return drawCard; + } + public String toString() { return this.name; diff --git a/RefreshAbility.java b/RefreshAbility.java new file mode 100644 index 0000000..175d7d1 --- /dev/null +++ b/RefreshAbility.java @@ -0,0 +1,39 @@ +import java.util.ArrayList; +import java.util.Random; + +public class RefreshAbility implements Ability +{ + private Player owner; + public String name = "Fabricate"; + + public RefreshAbility(Player player) + { + this.owner = player; + } + + public String toString() + { + return "Once per turn, you can shuffle your entire hand into the deck and end your turn.\n\n\n\n"; + } + + public int uses() { return 1; } + + public String name() { return this.name; } + + public boolean endTurn() { return true; } + + public void use(Deck deck, DiscardPile discardPile, ArrayList players) + { + System.out.println(owner + " used " + this.name + "!"); + + int handSize = owner.hand.size(); + + System.out.println(owner + " emptied their hand into the deck. The deck was reshuffled and they drew " + handSize + " cards.\n\n"); + + while(owner.hand.size() > 0) deck.push(owner.hand.remove(0)); + + deck.shuffle(); + + for(int i = 0; i < handSize; i++) owner.draw(deck); + } +} diff --git a/bluej.pkg b/bluej.pkg new file mode 100644 index 0000000..749950d --- /dev/null +++ b/bluej.pkg @@ -0,0 +1,235 @@ +#BlueJ package file +dependency1.from=Behavior +dependency1.to=LStack +dependency1.type=UsesDependency +dependency10.from=Crazy8Driver +dependency10.to=Player +dependency10.type=UsesDependency +dependency11.from=Crazy8Driver +dependency11.to=Card +dependency11.type=UsesDependency +dependency12.from=Ability +dependency12.to=LStack +dependency12.type=UsesDependency +dependency13.from=CycleAbility +dependency13.to=LStack +dependency13.type=UsesDependency +dependency14.from=CycleAbility +dependency14.to=Player +dependency14.type=UsesDependency +dependency15.from=CycleAbility +dependency15.to=Card +dependency15.type=UsesDependency +dependency16.from=Player +dependency16.to=Ability +dependency16.type=UsesDependency +dependency17.from=Crazy8Driver +dependency17.to=CycleAbility +dependency17.type=UsesDependency +dependency18.from=AggressiveCycle +dependency18.to=LStack +dependency18.type=UsesDependency +dependency19.from=AggressiveCycle +dependency19.to=Player +dependency19.type=UsesDependency +dependency2.from=Player +dependency2.to=Behavior +dependency2.type=UsesDependency +dependency20.from=AggressiveCycle +dependency20.to=Card +dependency20.type=UsesDependency +dependency21.from=Crazy8Driver +dependency21.to=AggressiveCycle +dependency21.type=UsesDependency +dependency22.from=FabricateAbility +dependency22.to=LStack +dependency22.type=UsesDependency +dependency23.from=FabricateAbility +dependency23.to=Player +dependency23.type=UsesDependency +dependency24.from=FabricateAbility +dependency24.to=Card +dependency24.type=UsesDependency +dependency25.from=AggressiveFabricate +dependency25.to=LStack +dependency25.type=UsesDependency +dependency26.from=AggressiveFabricate +dependency26.to=Player +dependency26.type=UsesDependency +dependency27.from=AggressiveFabricate +dependency27.to=Card +dependency27.type=UsesDependency +dependency28.from=Crazy8Driver +dependency28.to=FabricateAbility +dependency28.type=UsesDependency +dependency29.from=Crazy8Driver +dependency29.to=AggressiveFabricate +dependency29.type=UsesDependency +dependency3.from=CrazyEightGUI +dependency3.to=LStack +dependency3.type=UsesDependency +dependency4.from=CrazyEightGUI +dependency4.to=Player +dependency4.type=UsesDependency +dependency5.from=CrazyEightGUI +dependency5.to=Card +dependency5.type=UsesDependency +dependency6.from=AggressiveBehavior +dependency6.to=LStack +dependency6.type=UsesDependency +dependency7.from=AggressiveBehavior +dependency7.to=Player +dependency7.type=UsesDependency +dependency8.from=AggressiveBehavior +dependency8.to=Card +dependency8.type=UsesDependency +dependency9.from=Crazy8Driver +dependency9.to=LStack +dependency9.type=UsesDependency +package.editor.height=868 +package.editor.width=1796 +package.editor.x=-9 +package.editor.y=-9 +package.numDependencies=29 +package.numTargets=13 +package.showExtends=true +package.showUses=true +target1.editor.height=539 +target1.editor.width=628 +target1.editor.x=0 +target1.editor.y=0 +target1.height=50 +target1.name=LStack +target1.showInterface=false +target1.type=ClassTarget +target1.width=90 +target1.x=60 +target1.y=10 +target10.editor.height=1050 +target10.editor.width=1938 +target10.editor.x=-9 +target10.editor.y=-9 +target10.height=50 +target10.name=CycleAbility +target10.showInterface=false +target10.type=ClassTarget +target10.width=90 +target10.x=890 +target10.y=380 +target11.editor.height=539 +target11.editor.width=628 +target11.editor.x=0 +target11.editor.y=0 +target11.height=50 +target11.name=CrazyEightGUI +target11.showInterface=false +target11.type=ClassTarget +target11.width=100 +target11.x=0 +target11.y=520 +target12.editor.height=1050 +target12.editor.width=1938 +target12.editor.x=-9 +target12.editor.y=-9 +target12.height=50 +target12.name=AggressiveFabricate +target12.showInterface=false +target12.type=ClassTarget +target12.width=140 +target12.x=1250 +target12.y=260 +target13.editor.height=539 +target13.editor.width=628 +target13.editor.x=0 +target13.editor.y=0 +target13.height=50 +target13.name=Card +target13.showInterface=false +target13.type=ClassTarget +target13.width=80 +target13.x=400 +target13.y=530 +target2.editor.height=1050 +target2.editor.width=1938 +target2.editor.x=-9 +target2.editor.y=-9 +target2.height=50 +target2.name=Player +target2.showInterface=false +target2.type=ClassTarget +target2.width=80 +target2.x=290 +target2.y=150 +target3.height=50 +target3.name=CardTest +target3.showInterface=false +target3.type=UnitTestTarget +target3.width=80 +target3.x=640 +target3.y=70 +target4.editor.height=877 +target4.editor.width=1045 +target4.editor.x=794 +target4.editor.y=79 +target4.height=50 +target4.name=FabricateAbility +target4.showInterface=false +target4.type=ClassTarget +target4.width=110 +target4.x=990 +target4.y=380 +target5.editor.height=1050 +target5.editor.width=1932 +target5.editor.x=-9 +target5.editor.y=-9 +target5.height=50 +target5.name=Crazy8Driver +target5.showInterface=false +target5.type=ClassTarget +target5.width=100 +target5.x=510 +target5.y=200 +target6.editor.height=794 +target6.editor.width=1552 +target6.editor.x=0 +target6.editor.y=0 +target6.height=50 +target6.name=AggressiveBehavior +target6.showInterface=false +target6.type=ClassTarget +target6.width=140 +target6.x=90 +target6.y=80 +target7.editor.height=1050 +target7.editor.width=1938 +target7.editor.x=-9 +target7.editor.y=-9 +target7.height=50 +target7.name=AggressiveCycle +target7.showInterface=false +target7.type=ClassTarget +target7.width=120 +target7.x=1110 +target7.y=260 +target8.editor.height=539 +target8.editor.width=628 +target8.editor.x=0 +target8.editor.y=0 +target8.height=50 +target8.name=Behavior +target8.showInterface=false +target8.type=InterfaceTarget +target8.width=80 +target8.x=280 +target8.y=60 +target9.editor.height=539 +target9.editor.width=628 +target9.editor.x=1190 +target9.editor.y=153 +target9.height=50 +target9.name=Ability +target9.showInterface=false +target9.type=InterfaceTarget +target9.width=80 +target9.x=780 +target9.y=380 diff --git a/package.bluej b/package.bluej new file mode 100644 index 0000000..749950d --- /dev/null +++ b/package.bluej @@ -0,0 +1,235 @@ +#BlueJ package file +dependency1.from=Behavior +dependency1.to=LStack +dependency1.type=UsesDependency +dependency10.from=Crazy8Driver +dependency10.to=Player +dependency10.type=UsesDependency +dependency11.from=Crazy8Driver +dependency11.to=Card +dependency11.type=UsesDependency +dependency12.from=Ability +dependency12.to=LStack +dependency12.type=UsesDependency +dependency13.from=CycleAbility +dependency13.to=LStack +dependency13.type=UsesDependency +dependency14.from=CycleAbility +dependency14.to=Player +dependency14.type=UsesDependency +dependency15.from=CycleAbility +dependency15.to=Card +dependency15.type=UsesDependency +dependency16.from=Player +dependency16.to=Ability +dependency16.type=UsesDependency +dependency17.from=Crazy8Driver +dependency17.to=CycleAbility +dependency17.type=UsesDependency +dependency18.from=AggressiveCycle +dependency18.to=LStack +dependency18.type=UsesDependency +dependency19.from=AggressiveCycle +dependency19.to=Player +dependency19.type=UsesDependency +dependency2.from=Player +dependency2.to=Behavior +dependency2.type=UsesDependency +dependency20.from=AggressiveCycle +dependency20.to=Card +dependency20.type=UsesDependency +dependency21.from=Crazy8Driver +dependency21.to=AggressiveCycle +dependency21.type=UsesDependency +dependency22.from=FabricateAbility +dependency22.to=LStack +dependency22.type=UsesDependency +dependency23.from=FabricateAbility +dependency23.to=Player +dependency23.type=UsesDependency +dependency24.from=FabricateAbility +dependency24.to=Card +dependency24.type=UsesDependency +dependency25.from=AggressiveFabricate +dependency25.to=LStack +dependency25.type=UsesDependency +dependency26.from=AggressiveFabricate +dependency26.to=Player +dependency26.type=UsesDependency +dependency27.from=AggressiveFabricate +dependency27.to=Card +dependency27.type=UsesDependency +dependency28.from=Crazy8Driver +dependency28.to=FabricateAbility +dependency28.type=UsesDependency +dependency29.from=Crazy8Driver +dependency29.to=AggressiveFabricate +dependency29.type=UsesDependency +dependency3.from=CrazyEightGUI +dependency3.to=LStack +dependency3.type=UsesDependency +dependency4.from=CrazyEightGUI +dependency4.to=Player +dependency4.type=UsesDependency +dependency5.from=CrazyEightGUI +dependency5.to=Card +dependency5.type=UsesDependency +dependency6.from=AggressiveBehavior +dependency6.to=LStack +dependency6.type=UsesDependency +dependency7.from=AggressiveBehavior +dependency7.to=Player +dependency7.type=UsesDependency +dependency8.from=AggressiveBehavior +dependency8.to=Card +dependency8.type=UsesDependency +dependency9.from=Crazy8Driver +dependency9.to=LStack +dependency9.type=UsesDependency +package.editor.height=868 +package.editor.width=1796 +package.editor.x=-9 +package.editor.y=-9 +package.numDependencies=29 +package.numTargets=13 +package.showExtends=true +package.showUses=true +target1.editor.height=539 +target1.editor.width=628 +target1.editor.x=0 +target1.editor.y=0 +target1.height=50 +target1.name=LStack +target1.showInterface=false +target1.type=ClassTarget +target1.width=90 +target1.x=60 +target1.y=10 +target10.editor.height=1050 +target10.editor.width=1938 +target10.editor.x=-9 +target10.editor.y=-9 +target10.height=50 +target10.name=CycleAbility +target10.showInterface=false +target10.type=ClassTarget +target10.width=90 +target10.x=890 +target10.y=380 +target11.editor.height=539 +target11.editor.width=628 +target11.editor.x=0 +target11.editor.y=0 +target11.height=50 +target11.name=CrazyEightGUI +target11.showInterface=false +target11.type=ClassTarget +target11.width=100 +target11.x=0 +target11.y=520 +target12.editor.height=1050 +target12.editor.width=1938 +target12.editor.x=-9 +target12.editor.y=-9 +target12.height=50 +target12.name=AggressiveFabricate +target12.showInterface=false +target12.type=ClassTarget +target12.width=140 +target12.x=1250 +target12.y=260 +target13.editor.height=539 +target13.editor.width=628 +target13.editor.x=0 +target13.editor.y=0 +target13.height=50 +target13.name=Card +target13.showInterface=false +target13.type=ClassTarget +target13.width=80 +target13.x=400 +target13.y=530 +target2.editor.height=1050 +target2.editor.width=1938 +target2.editor.x=-9 +target2.editor.y=-9 +target2.height=50 +target2.name=Player +target2.showInterface=false +target2.type=ClassTarget +target2.width=80 +target2.x=290 +target2.y=150 +target3.height=50 +target3.name=CardTest +target3.showInterface=false +target3.type=UnitTestTarget +target3.width=80 +target3.x=640 +target3.y=70 +target4.editor.height=877 +target4.editor.width=1045 +target4.editor.x=794 +target4.editor.y=79 +target4.height=50 +target4.name=FabricateAbility +target4.showInterface=false +target4.type=ClassTarget +target4.width=110 +target4.x=990 +target4.y=380 +target5.editor.height=1050 +target5.editor.width=1932 +target5.editor.x=-9 +target5.editor.y=-9 +target5.height=50 +target5.name=Crazy8Driver +target5.showInterface=false +target5.type=ClassTarget +target5.width=100 +target5.x=510 +target5.y=200 +target6.editor.height=794 +target6.editor.width=1552 +target6.editor.x=0 +target6.editor.y=0 +target6.height=50 +target6.name=AggressiveBehavior +target6.showInterface=false +target6.type=ClassTarget +target6.width=140 +target6.x=90 +target6.y=80 +target7.editor.height=1050 +target7.editor.width=1938 +target7.editor.x=-9 +target7.editor.y=-9 +target7.height=50 +target7.name=AggressiveCycle +target7.showInterface=false +target7.type=ClassTarget +target7.width=120 +target7.x=1110 +target7.y=260 +target8.editor.height=539 +target8.editor.width=628 +target8.editor.x=0 +target8.editor.y=0 +target8.height=50 +target8.name=Behavior +target8.showInterface=false +target8.type=InterfaceTarget +target8.width=80 +target8.x=280 +target8.y=60 +target9.editor.height=539 +target9.editor.width=628 +target9.editor.x=1190 +target9.editor.y=153 +target9.height=50 +target9.name=Ability +target9.showInterface=false +target9.type=InterfaceTarget +target9.width=80 +target9.x=780 +target9.y=380