Not sure if I need to edit this class or not since the cards ARE changing. Just not in order
import java.lang.Integer;
/**
* This class is used to keep track of playing cards.
*
* #author (name)
* #version (date)
*/
public class Card implements Comparable<Card>
{
public int compareTo(Card otherCard) {
// instance variables - replace the example below with your own
private String denom, suit;
/**
* Card is to be passed in as a denomination and suit
*/
public Card(String description)
{
description = description.toUpperCase();
if( description.length() == 2)
{
suit = description.substring(1);
denom = description.substring(0,1);
} else if(description.length() == 3) {
suit = description.substring(2);
denom = description.substring(0,2);
} else {
System.out.print("Error: An invalid card code was given.");
}
}
/**
* This will give a string that states a description of the card.
* #return Card description as a string.
*/
public String getDis()
{
//get the description
String denomMessage = denom;
if(denom.equals("A"))
denomMessage = "Ace";
else if(denom.equals("K"))
denomMessage = "King";
else if(denom.equals("Q"))
denomMessage = "Queen";
else if(denom.equals("J"))
denomMessage = "Jack";
//get the suit
String suitMessage = suit;
if(suit.equals("S"))
suitMessage = "Spades";
else if(suit.equals("D"))
suitMessage = "Dimonds";
else if(suit.equals("C"))
suitMessage = "Clubs";
else if(suit.equals("H"))
suitMessage = "Hearts";
else
suitMessage = "There was a problem";
return denomMessage + " of " + suitMessage;
}
/**
* This was written for the purpose of helping to select a card image.
* #return clubs are 1, hearts are 2, spades are 3, diamonds are 4
*/
public int numSuit()
{
int value = 0;
if(suit.equals("C"))
value = 1;
else if(suit.equals("H"))
value = 2;
else if(suit.equals("S"))
value = 3;
else if(suit.equals("D"))
value = 4;
return value;
}
/**
* This class was written for the purpose of selecting a card image
* #return ace is a 1, jack is a 11, queen is a 12, king is a 13
*/
public int numDenom()
{
int value = 0;
if(denom.equals("A"))
value = 1;
else if(denom.equals("J"))
value = 11;
else if(denom.equals("Q"))
value = 12;
else if(denom.equals("K"))
value = 13;
else
value = Integer.parseInt(denom);
return value;
}
/**
* Are the two cards the same suit and denomination?
* #return true or false
*/
public boolean equals(Card a)
{
if(denom.equals(a.denom) && suit.equals(a.suit))
return true;
else
return false;
}
/**
* I would suggest that you write this method
*/
public int denomCompareTo(Card a)
{
return a.numDenom() - numDenom();
}
}
All it's doing is changing it's card to the lowest card entered. I have to make it go in order from smallest to largest. no matter what face.
import java.awt.*;
import java.io.*;
import java.applet.*;
import java.awt.image.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* This applet is currently working. It will run in a webpage. It will take in card codes such as
* 2h for the two of heart and "paint" the image of five cards when all five text fields each have a
* card coding entered into them. Your assignment will be to write the part of the code
* that will sort the cards once they have been entered so that the will be "painted" from smallest
* to largest denomination regardless of suit as long "None" is selected in the drop down box. In
* the event one of the suits is selected that suit will be placed in order first then followed by
* the rest of the cards in order. To complete the assignment you should read through this class' code
* but you will only need to change the section that state that you should change it and possibly
* the card class.
*
* #author (Put your name here.)
* #version (Put the date here.)
*/
public class CardApplet extends Applet {
Image ic1,ic2,ic3,ic4,ic5;
Card c1,c2,c3,c4,c5;
private TextField cardIn1,cardIn2,cardIn3,cardIn4,cardIn5;
private String message;
private Button enter,sort;
private ButtonListener buttonListen;
private Choice trump;
static final int CARD_WIDTH = 73;
static final int CARD_HEIGHT = 98;
/**
* This is called an inner class as it is a class writen inside of another class. It is here so
* that the buttons will be able to trigger an event.
*/
class ButtonListener implements ActionListener
{
/**
* The name of this method is important and should not be changed. This will take in the
* "action" of a button being pushed and store reference to it in the object variable e.
*/
public void actionPerformed(ActionEvent e)
{
String action = e.paramString();
if( action.indexOf("Enter") >= 0)
{
//get text
String text1 = cardIn1.getText();
String text2 = cardIn2.getText();
String text3 = cardIn3.getText();
String text4 = cardIn4.getText();
String text5 = cardIn5.getText();
//Get rid of whitespace before and after string
text1 = text1.trim();
text2 = text2.trim();
text3 = text3.trim();
text4 = text4.trim();
text5 = text5.trim();
message = "Cards Entered";
//setup cards and card images
c1 = new Card(text1);
ic1 = getCardImage(c1);
c2 = new Card(text2);
ic2 = getCardImage(c2);
c3 = new Card(text3);
ic3 = getCardImage(c3);
c4 = new Card(text4);
ic4 = getCardImage(c4);
c5 = new Card(text5);
ic5 = getCardImage(c5);
//this method call is to this class and tells the applet to follow the code of paint again.
repaint();
}
else if( action.indexOf("Sort") >= 0)
{
//ADD YOUR CODE HERE.
if(c1.denomCompareTo(c2) < 0 )
ic1 = ic2;
c1 = c2;
if(c1.denomCompareTo(c3) < 0 )
ic1 = ic3;
c1 = c3;
if(c1.denomCompareTo(c4) < 0 )
ic1 = ic4;
c1 = c4;
if(c1.denomCompareTo(c5) < 0 )
ic1 = ic5;
c1 = c5;
if(c2.denomCompareTo(c1) < 0 )
ic2 = ic1;
c2 = c1;
if(c2.denomCompareTo(c3) < 0 )
ic2 = ic3;
c2 = c3;
if(c2.denomCompareTo(c4) < 0 )
ic2 = ic4;
c2 = c4;
if(c2.denomCompareTo(c5) < 0 )
ic2 = ic5;
c2 = c5;
if(c3.denomCompareTo(c1) < 0 )
ic3 = ic1;
c3 = c1;
if(c3.denomCompareTo(c2) < 0 )
ic3 = ic2;
c3 = c2;
if(c3.denomCompareTo(c4) < 0 )
ic3 = ic4;
c3 = c4;
if(c3.denomCompareTo(c5) < 0 )
ic3 = ic5;
c3 = c5;
if(c4.denomCompareTo(c1) < 0 )
ic4 = ic1;
c4 = c1;
if(c4.denomCompareTo(c2) < 0 )
ic4 = ic2;
c4 = c2;
if(c4.denomCompareTo(c3) < 0 )
ic4 = ic3;
c4= c3;
if(c4.denomCompareTo(c5) < 0 )
ic4 = ic5;
c4 = c5;
if(c5.denomCompareTo(c1) < 0 )
ic5 = ic1;
c5 = c1;
if(c5.denomCompareTo(c2) < 0 )
ic5 = ic2;
c5 = c2;
if(c5.denomCompareTo(c3) < 0 )
ic5 = ic3;
c5 = c3;
if(c5.denomCompareTo(c4) < 0 )
ic5 = ic4;
c5 = c4;
//DO NOT CHANGE CODE PAST THIS LINE.
message = "Sorted";
repaint();
}
}
} //end of inner class.
/**
* This method is called when the applet is first started. It will setup the layout of the applet.
*/
public void init() {
//This is the text that prints in the gray box towards the bottem of the applet.
message="Let us get started ";
//Sets the back ground color of the the applet
setBackground(Color.GREEN);
// Set default layout manager
setLayout(new FlowLayout() );
//setup textboxes for entering in cards
cardIn1 = new TextField("Enter",4);
add(cardIn1);
cardIn2 = new TextField("cards ",4);
add(cardIn2);
cardIn3 = new TextField("using",4);
add(cardIn3);
cardIn4 = new TextField("Chap 5",4);
add(cardIn4);
cardIn5 = new TextField("coding",4);
add(cardIn5);
//place buttons
buttonListen = new ButtonListener();
enter = new Button("Enter");
enter.addActionListener(buttonListen);
add(enter);
sort = new Button("Sort");
sort.addActionListener(buttonListen);
add(sort);
//setup dropdown
trump = new Choice();
trump.addItem("None");
trump.addItem("Hearts");
trump.addItem("Diamonds");
trump.addItem("Spades");
trump.addItem("Clubs");
add(trump);
//Since the card object variables are null each image object variable
//will hold reference to a card back image.
ic1 = getCardImage(c1);
ic2 = getCardImage(c2);
ic3 = getCardImage(c3);
ic4 = getCardImage(c4);
ic5 = getCardImage(c5);
}
/*
* This class is used to place graphics on an applet.
*/
public void paint(Graphics g) {
//places cards on applet
int linePos = 70;
g.drawImage(ic1,19,linePos,this);
g.drawImage(ic2,19+CARD_WIDTH,linePos,this);
g.drawImage(ic3,19+2*CARD_WIDTH,linePos,this);
g.drawImage(ic4,19+3*CARD_WIDTH,linePos,this);
g.drawImage(ic5,19+4*CARD_WIDTH,linePos,this);
// simple text displayed on applet
g.setColor(Color.lightGray);
g.draw3DRect(2, 175, 200, 20, true);
g.fillRect(2, 175, 200, 20);
g.setColor(Color.black);
g.drawString(message, 4, 190);
}
/**
* This will select either the correct portion of the cards image based on the suit and denomination or
* the card back image.
* #param a The card object holds the suit and denomination in state.
* #return It returns an image object variable with holds reference to a image that was created for a card that was passed in.
* #throws MalformedURLException
*/
public Image getCardImage(final Card a)
{
int cardDenom,cardSuit;
Image playingCards = null;
ImageFilter cardFilter;
ImageProducer cardProducer;
if( a == null)
{
playingCards = getImage(getCodeBase(), "cardBack.png");
}else{
playingCards = getImage(getCodeBase(),"cards.png");
cardDenom = (a.numDenom()*CARD_WIDTH)- CARD_WIDTH;
cardSuit = (a.numSuit()*CARD_HEIGHT) - CARD_HEIGHT;
cardFilter = new CropImageFilter(cardDenom,cardSuit,CARD_WIDTH,CARD_HEIGHT);
cardProducer = new FilteredImageSource(playingCards.getSource(),cardFilter);
playingCards = createImage(cardProducer);
}
return playingCards;
}
}
nIcE cOw is correct in mentioning Comparable
from http://docs.oracle.com/javase/6/docs/api/java/lang/Comparable.html
Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
Which means that your implementation of Comparable for your objects (cards) should follow that convention.
In your top code section
public int denomCompareTo(Card a)
{
if ( a.numDenom() < this.numDenom() ) //the value of card a is less
{ return -1; }
else if ( a.numDenom() == this.numDenom() ) //equality
{ return 0; }
else //otherwise.. whatever's left (a must be greater)
{ return 1;}
}
Read that over until you understand it. Comparable is the method you want to definitely work. It's going to be invoked by calling
FirstCard.CompareTo( SecondCard );
that line of code is going to return a value of either -1, 0, or 1. Depending on which is greater, or 0 if they are equal. That's all a sorting algorithm really /needs/ to be able to figure out an ordering.
So that's the code you need for Comparable. Please look it over until you understand it.
The code in the second portion,
else if( action.indexOf("Sort") >= 0)
{
//ADD YOUR CODE HERE.
...
}
Needs to be updated to reflect how Comparable works.
So I am guessing this is a button or action thingy, and if you specify Sort then we want to sort the cards. Fair enough. Well, where are the cards stored? It looks like in a bunch of variables named c(number) and ic(number) for the image. Like c1 and ic1, c2 and ic2. In the future, look into using arrays.
So your code is almost correct for this portion! It's just that you need a temporary value to store the old card. Otherwise you're overwriting it everytime.
For example: First basket is an apple, Second basket is a grape.
If you say "Hey, put the contents of the 2nd basket into the 1st" then the first one becomes grape. The second one is also (still) grape. Where did apple go? We lost it because computers are mercilessly true to your instructions. We need to store the old card in a new variable.
So when you say
if(c1.denomCompareTo(c2) < 0 ) { //for the love of jobe please use braces for multiline if statements
ic1 = ic2;
c1 = c2;
}
The original ic1 and c1 are being overwritten and lost.
You can fix this by using a temporary variable or swapping variable, or when you get really clever, using XOR (ask your nerdy friends)
Image tempImg;
Card tempCard;
if(c1.denomCompareTo(c2) < 0 ) { //meaning if card1 is less than card2
tempImg = ic1; //store card1 temporarily
tempCard = c1;
ic1 = ic2; //copy vals of card2 to card1 slots
c1 = c2;
ic2 = tempImg; //slide the original val of ic1 here
c2 = tempCard;
}
Granted, your sorting algorithm is accurate, but will require many passes if the cards are in any funky ordering. Which is why you'll probably have to loop over these instructions several times. You're doing something incrementally usually referred to as "bubble sort" ... If you need help looping over your sorting, just let us know.
Here are some examples:
I am posting a very quick reference example for you to look at. It is not that tough to understand, though, once you will understand it, things will become a bit more easier.
import java.util.*;
enum Suit {
HEART,
DIAMOND,
CLUB,
SPADE
}
class Card implements Comparable<Card> {
private int rank;
private Suit suit;
public Card ( int rank, Suit suit ) {
this.rank = rank;
this.suit = suit;
}
public int getRank () {
return rank;
}
public void setRank ( int rank ) {
this.rank = rank;
}
public Suit getSuit () {
return suit;
}
public void setSuit ( Suit suit ) {
this.suit = suit;
}
#Override
public int compareTo ( Card anotherCard ) {
return this.rank - anotherCard.rank;
}
#Override
public String toString () {
return String.format ("Suit: %8s Rank: %8s", suit, rank);
}
}
public class CardsExample {
private static final int TOTAL_CARDS = 52;
private static final int CARDS_PER_SUIT = 13;
private static final int TOTAL_SUITS = 4;
private List<Card> deck;
public CardsExample () {
deck = new ArrayList<Card> ();
}
private void createDeck () {
for ( Suit suit : Suit.values () ) {
for ( int i = 0; i < CARDS_PER_SUIT; ++i ) {
deck.add ( new Card ( i, suit ) );
}
}
}
private void displayDeck () {
for ( Card card : deck ) {
System.out.println ( card );
}
}
private void performTask () {
createDeck ();
Collections.shuffle ( deck );
System.out.println ( "Before SORTING" );
displayDeck ();
Collections.sort ( deck );
System.out.println ( "After SORTING" );
displayDeck ();
}
public static void main ( String[] args ) {
new CardsExample ().performTask ();
}
}
EDIT:
If one wants to sort cards, in terms of their Suit first, then one can use Comparatortoo, in this example, for which not much of a change is required, just change the enum part, as shown below and provide implementation for Comparator < Card >, within the Cardclass, and let Collections.sort ( deck, suitComparator )do the work, as shown in this example.
import java.util.*;
enum Suit {
HEART ( 0 ),
DIAMOND ( 1 ),
CLUB ( 2 ),
SPADE ( 3 );
private int value;
private Suit ( int value ) {
this.value = value;
}
public int retrieveValue () {
return value;
}
}
class Card implements Comparable < Card > {
private int rank;
private Suit suit;
public static Comparator < Card > suitComparator =
new Comparator < Card > () {
#Override
public int compare ( Card someCard, Card anotherCard ) {
return someCard.suit.retrieveValue () - anotherCard.suit.retrieveValue ();
}
};
public Card ( int rank, Suit suit ) {
this.rank = rank;
this.suit = suit;
}
public int getRank () {
return rank;
}
public void setRank ( int rank ) {
this.rank = rank;
}
public Suit getSuit () {
return suit;
}
public void setSuit ( Suit suit ) {
this.suit = suit;
}
#Override
public int compareTo ( Card anotherCard ) {
return this.rank - anotherCard.rank;
}
#Override
public String toString () {
return String.format ( "Suit: %8s Rank: %8s", suit, rank );
}
}
public class CardsExample {
private static final int TOTAL_CARDS = 52;
private static final int CARDS_PER_SUIT = 13;
private static final int TOTAL_SUITS = 4;
private List < Card > deck;
public CardsExample () {
deck = new ArrayList < Card > ();
}
private void createDeck () {
for ( Suit suit : Suit.values () ) {
for ( int i = 0; i < CARDS_PER_SUIT; ++i ) {
deck.add ( new Card ( i, suit ) );
}
}
}
private void displayDeck () {
for ( Card card : deck ) {
System.out.println ( card );
}
}
private void performTask () {
createDeck ();
Collections.shuffle ( deck );
System.out.println ( "Before SORTING" );
displayDeck ();
Collections.sort ( deck );
Collections.sort ( deck, Card.suitComparator );
System.out.println ( "After SORTING" );
displayDeck ();
}
public static void main ( String[] args ) {
new CardsExample ().performTask ();
}
}
Good luck
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
With this code, i want to develop a program that enables the user to enter 5 int values into a single textfield. These values will be stored in an array and upon pressing the button, a bar graph will be drawn to represent the entered values. Class BtnHandler handles the button click event and class gegHandler handles the textfield enter event. I can't get the user input to be collected in the array. Here is my code.
package voorbeeld0805;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Vb0805 extends JFrame {
public static void main( String args[] ) {
JFrame frame = new Vb0805();
frame.setSize( 300, 300 );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setTitle( "Voorbeeld 0805" );
frame.setContentPane( new Tekenpaneel() );
frame.setVisible( true );
}
}
class Tekenpaneel extends JPanel {
private Staafdiagram staafdiagram;
private JButton knopTeken;
private JTextField gegevensVak;
private JLabel lblNo;
private int[] lengtes = new int [5];
public Tekenpaneel() {
setBackground( Color.ORANGE );
knopTeken = new JButton("Teken");
knopTeken.addActionListener(new BtnHandler());
gegevensVak = new JTextField(5);
gegevensVak.addActionListener(new gegHandler());
lblNo = new JLabel("Enter Value");
add(knopTeken);
add (gegevensVak);
add (lblNo);
}
public void paintComponent( Graphics g ) {
super.paintComponent( g );
if (staafdiagram != null)
{
staafdiagram.teken( g, 50, 250 );
}
this.requestFocusInWindow();
}
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//To test using the first constructor. Works perfectly
/*int [] lengtes = { 144, 98, 117, 130, 172, 173 };
staafdiagram = new Staafdiagram( lengtes, 30 );*/
repaint();
}
}
class gegHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//Here user input should be collected, placed in an array and
//saved in staafdiagram.setLengtes();
for (int i = 0; i < lengtes.length; i++){
lblNo.setText("Next Value Is " + i++);
lengtes[i] = Integer.parseInt( gegevensVak.getText());
gegevensVak.setText("");//clear textfield after entering a value
}
}
}
}
class Staafdiagram {
private int[] lengtes;
private int witruimte;//this generates the spaces between the bars
//First contructor with 2 arguments array en space
public Staafdiagram( int[] lengtes, int witruimte ) {
this.lengtes = lengtes;
this.witruimte = witruimte;
}
//Second constructor with only 1 argument space
public Staafdiagram(int witruimte ) {
this.witruimte = witruimte;
}
//With this, i want the user input to be collected in an array
public void setLengtes(int[] lengtes) {
this.lengtes = lengtes;
}
//To calculate the bar with the highest value
public int bepaalMax(){
int maximum = lengtes [0];
for (int i = 1; i < lengtes.length; i++){
if (lengtes[i] > maximum)
{
maximum = lengtes[i];
}
}
return maximum;
}
//To calculate the bar with the lowest value
public int bepaalMin(){
int minimum = lengtes [0];
for (int i = 1; i < lengtes.length; i++){
if (lengtes[i] < minimum)
{
minimum = lengtes[i];
}
}
return minimum;
}
public void teken( Graphics g, int x, int y ) {
int startX = x;
// Draw the bars
for( int lengte : lengtes ) {
if (lengte == bepaalMax())
g.setColor(Color.red);
else if (lengte == bepaalMin())
g.setColor(Color.green);
else
g.setColor(Color.black);
g.fillRect( x, y - 20 - lengte, 20, lengte );
x += witruimte;
}
// Display the values under the bars
x = startX;
for( int lengte : lengtes ) {
g.drawString( String.format( "%d", lengte ), x, y );
x += witruimte;
}
}
}
If you add an ActionListener on a JTextField, the actionPerformed() method is called when you "action" this field : here is the enter key pressed.
If you want associate the button to your action, you should rather enrich the ActionListener you defined on the JButton to also get the values entered by the user. The idea is chaining the both as both operations should performed one after the other one :
These values will be stored in an array and upon pressing the button,
a bar graph will be drawn to represent the entered values.
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
// collection information from textfield
for (int i = 0; i < lengtes.length; i++){
lblNo.setText("Next Value Is " + i++);
lengtes[i] = Integer.parseInt( gegevensVak.getText());
gegevensVak.setText("");//clear textfield after entering a value
}
// rendering
staafdiagram = new Staafdiagram( lengtes, 30 );*/
repaint();
}
}
Get the input from the text field as text
split to string array
Convert to int
MOdify your code as follows.
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//To test using the first constructor. Works perfectly
/*int [] lengtes = { 144, 98, 117, 130, 172, 173 };
staafdiagram = new Staafdiagram( lengtes, 30 );*/
String textInt=gegevensVak .getText(); //gegevensVak is the name of the textfield you mentioned
String[] strArray = textInt.split();
//now convert the string to int and add to a new array
repaint();
}
}
All of the program's templates. This was a past assignment but at this point, I'm just trying to understand what's going on.
Under the Apartment class, I'm confused on how to correctly return an array of window orders for one unit, all units, and then the #Override method under ThreeBedroom.
Just for reference of what I've done so far (probably not all correct):
public class Window {
private final int width, height;
public Window(int width, int height) {
this.width = width;
this.height = height;
}
// print text like: 4 X 6 window
public String toString() {
String s = "";
s = width + " x " + height + " window";
return s;
}
// compare window objects by their dimensions
public boolean equals(Object that) {
if (that instanceof Window) {
Window w = (Window) that;
return this.width == w.width && this.height == w.height;
}
else { return false; }
}
}
class WindowOrder {
final Window window; // window description (its width and height)
int num; // number of windows for this order
WindowOrder(Window window, int num) {
this.window = window;
this.num = num;
}
// add the num field of the parameter to the num field of this object
//
// BUT
//
// do the merging only of two windows have the same size
// do nothing if the size does not match
//
// return the current object
WindowOrder add(WindowOrder order) {
if (order.equals(window)) {
this.num -= num;
return order;
}
else {
return order;
}
}
// update the num field of this object by multiplying it with the parameter
// and then return the current object
WindowOrder times(int number) {
WindowOrder window = new WindowOrder(this.window, this.num);
this.num *= number;
return window;
}
// print text like: 20 4 X 6 window
#Override
public String toString() {
String s = "";
s = num + " " + window.toString();
return s;
}
// Two orders are equal if they contain the same number of windows of the same size.
#Override
public boolean equals(Object that) {
if (that instanceof WindowOrder) {
WindowOrder order = (WindowOrder) that;
return this.num == order.num && this.window == order.window;
}
else { return false; }
}
}
public class Room {
Window window;
int numOfWindows;
Room(Window window, int numOfWindows) {
this.window = window;
this.numOfWindows = numOfWindows;
}
WindowOrder order() {
return new WindowOrder(window, numOfWindows);
}
// Print text like: 5 (6 X 8 window)
#Override
public String toString() {
String s = "";
s = numOfWindows + " (" + window.toString() + ")";
return s;
}
// Two rooms are equal if they contain the same number of windows of the same size
#Override
public boolean equals(Object that) {
if (that instanceof Room) {
Room room = (Room) that;
return this.window == room.window && this.numOfWindows == room.numOfWindows;
}
else { return false; }
}
}
class MasterBedroom extends Room {
MasterBedroom() {
super(new Window(4, 6), 3);
}
// Call parent's toString method
//
// return text like: Master bedroom: 3 (4 X 6 window)
#Override
public String toString() {
String s = "";
s = "Master bedroom: " + numOfWindows + " " + window.toString();
return s;
}
}
class GuestRoom extends Room {
GuestRoom() {
super(new Window(5, 6), 2);
}
// Call parent's toString method
//
// return text like: Guest room: 2 (5 X 6 window)
#Override
public String toString() {
String s = "";
s = "Guest room: " + numOfWindows + " " + window.toString();
return s;
}
}
class LivingRoom extends Room {
LivingRoom() {
super(new Window(6, 8), 5);
}
// Call parent's toString method
//
// return text like: Living room: 5 (6 X 8 window)
#Override
public String toString() {
String s = "";
s = "Living room: " + numOfWindows + " " + window.toString();
return s;
}
}
For Apartment's orderForOneUnit() method, I wrote this, but it seems to simplistic and I feel like I should be using a for loop..
WindowOrder[] orderForOneUnit() {
WindowOrder[] order = new WindowOrder[rooms.length];
return order;
}
Am I even close to correctly understanding this? What should be under the Apartment methods?
Didn't looks at the templates but from what you've provided, you're close. All you've done so far is create a WindowOrder[] array of length rooms. You need to add new WindowOrder(desc, num) to these arrays before return order;
/**
* All apartment rooms have the same number of windows, with the
* same size window for each of those.
*/
public class Apartment
{
private int numRooms_;
private int windowsPerRoom_;
private Window window_;
/**
* Constructor
*/
public Apartment(numRooms, windowsPerRoom, desiredWindowHeight, desiredWindowLength)
{
numRooms_ = numRooms;
windowsPerRoom_ = windowsPerRoom;
window_ = new Window(desiredWindowHeight, desiredWindowLenght);
}
/**
* Orders for one room in apartment
*/
public WindowOrder orderForOneUnit()
{
WindowOrder order = new WindowOrder(window_, 1);
return order;
}
/**
* Orders for all rooms in apartment
*/
public List<WindowOrder> orderForAllUnits()
{
List<WindowOrder> orders = new ArrayList<WindowOrder>();
WindowOrder order;
for(i=0; i<numRooms_; i++)
{
orders.add(new WindowOrder(window_, windowsPerRoom_);
}
return orders;
}
}
Now when you're in your code and you're ready for a new Apartment(x, x, x, x) you can do the following (I'll assume you're just in main())
public class ApartmentComplex
{
public static void main(String[] args)
{
int numWindowsPerRoom = 3;
int desiredWindowHeight = 10;
int desiredWindowWidth = 10;
int numRooms = 5;
Apartment aptWithFiveRooms = new Apartment(numRooms, numWindowsPerRoom, desiredWindowHeight, desiredWindowWidth);
WindowOrder singleSingleOrder = apt.orderForOneUnit();
List<WindowOrder> allRoomsOrder = apt.orderForAllUnits();
numRooms = 3;
Apartment aptWithThreeRooms = new Apartment(numRooms, numWindowsPerRoom, desiredWindowHeight, desiredWindowWidth);
List<WindowOrder> threeRoomsOrder = apt.orderForAllUnits();
}
}
You do need a for loop. At the moment you are returning an Array where each entry in the array is null.
Here is an example of filling an array:
for (int i = 0; i < array.length; i++) { // iterate over an array
array[i] = getValueFor(i); // put value in the array
}
I'm making a game similar to solitaire, and when the user recognizes they have lost I have a button to reset the game. Currently I'm unsure how I can reset the game. I know ill have to make a new deck and clear my array to recreate everything as if the game was starting for the first time, but I don't know how to do this. How can I reset my game when a user presses reset?
/**
* This is a class that tests the Deck class.
*/
public class DeckTester {
/**
* The main method in this class checks the Deck operations for consistency.
* #param args is not used.
*/
public static void main(String[] args) {
Board board = new Board();
board.startGame();
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* The Deck class represents a shuffled deck of cards.
* It provides several operations including
* initialize, shuffle, deal, and check if empty.
*/
public class Deck {
/**
* cards contains all the cards in the deck.
*/
private List<Card> cards;
/**
* size is the number of not-yet-dealt cards.
* Cards are dealt from the top (highest index) down.
* The next card to be dealt is at size - 1.
*/
private int size;
/**
* Creates a new <code>Deck</code> instance.<BR>
* It pairs each element of ranks with each element of suits,
* and produces one of the corresponding card.
* #param ranks is an array containing all of the card ranks.
* #param suits is an array containing all of the card suits.
* #param values is an array containing all of the card point values.
*/
ArrayList<Card> cardList = new ArrayList<>();
String[] ranks = {"Ace","Two","Three","Four","Five","Six" , "Seven" , "Eight","Nine","Ten", "Jack", "Queen","King"};
String[] suits = {"spades" , "diamonds" , "clubs" , "hearts"};
int[] values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
boolean selected = false;
public Deck() {
cards = new ArrayList<Card>();
for (int j = 0; j < ranks.length; j++) {
for (String suitString : suits) {
cards.add(new Card(ranks[j], suitString, values[j], selected));
}
}
size = cards.size();
}
public Card nextCard() {
if(cards.size() > 0) {
System.out.println(cards.get(0).toString());
return cards.remove(0);
}else{
return null;
}
}
/**
* Determines if this deck is empty (no undealt cards).
* #return true if this deck is empty, false otherwise.
*/
public boolean isEmpty() {
return size == 0;
}
/**
* Accesses the number of undealt cards in this deck.
* #return the number of undealt cards in this deck.
*/
public int size() {
return cards.size();
}
/**
* Randomly permute the given collection of cards
* and reset the size to represent the entire deck.
*/
List<Card> shuffledDeck;
ArrayList<Integer> usedNumbers = new ArrayList<Integer>();
public void shuffle() {
shuffledDeck = new ArrayList<>();
Random random = new Random();
for(usedNumbers.size(); usedNumbers.size() < 52;) {
int randomNum = random.nextInt(52);
if(!usedNumbers.contains(randomNum)) {
shuffledDeck.add(usedNumbers.size(), cards.get(randomNum));
usedNumbers.add(randomNum);
}
}
size = shuffledDeck.size();
cards = shuffledDeck;
}
/**
* Generates and returns a string representation of this deck.
* #return a string representation of this deck.
*/
#Override
public String toString() {
String rtn = "size = " + size + "\nUndealt cards: \n";
for (int k = cards.size() - 1; k >= 0; k--) {
rtn = rtn + cards.get(k);
if (k != 0) {
rtn = rtn + ", ";
}
if ((size - k) % 2 == 0) {
// Insert carriage returns so entire deck is visible on console.
rtn = rtn + "\n";
}
}
rtn = rtn + "\nDealt cards: \n";
for (int k = cards.size() - 1; k >= size; k--) {
rtn = rtn + cards.get(k);
if (k != size) {
rtn = rtn + ", ";
}
if ((k - cards.size()) % 2 == 0) {
// Insert carriage returns so entire deck is visible on console.
rtn = rtn + "\n";
}
}
rtn = rtn + "\n";
return rtn;
}
}
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Board extends JFrame implements ActionListener {
Deck deck = new Deck();
Card card;
JPanel buttonPanel = new JPanel();
JPanel menuPanel = new JPanel();
JButton cardOne = new JButton();
JButton cardTwo = new JButton();
JButton cardThree = new JButton();
JButton cardFour = new JButton();
JButton cardFive = new JButton();
JButton cardSix = new JButton();
JButton cardSeven = new JButton();
JButton[] buttons = {cardOne, cardTwo, cardThree, cardFour, cardFive, cardSix, cardSeven};
int winCount = 0;
int lossCount = 0;
int deckCount = 52;
JButton replace = new JButton("Replace");
JButton reset = new JButton("Reset");
JLabel cardsLeft = new JLabel("Cards left:" + deckCount);
JLabel winLossLabel = new JLabel("Win: " + winCount + "\tLoss: " + lossCount);
public Board() {
initGUI();
}
ArrayList<Card> boardArray = new ArrayList<>();
public void startGame() {
deck.shuffle();
Card card;
for(int i = 0 ; i <=6 ; i++) {
boardArray.add(card = deck.nextCard());
buttons[i].setIcon(card.cardImage);
}
}
public void initGUI() {
setTitle("Elevens");
setLayout(new GridLayout(1,2));
buttonPanel.setLayout(new GridLayout(2,4));
menuPanel.setLayout(new GridLayout(4,1));
setResizable(false);
buttonPanel.add(cardOne);
buttonPanel.add(cardTwo);
buttonPanel.add(cardThree);
buttonPanel.add(cardFour);
buttonPanel.add(cardFive);
buttonPanel.add(cardSix);
buttonPanel.add(cardSeven);
menuPanel.add(replace);
menuPanel.add(reset);
menuPanel.add(cardsLeft);
menuPanel.add(winLossLabel);
add(buttonPanel);
add(menuPanel);
for(int i = 0; i < buttons.length; i++){
buttons[i].addActionListener(this);
}
replace.addActionListener(this);
reset.addActionListener(this);
replace.setSize(new Dimension (100,10));
pack();
setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(600,300);
}
ImageIcon selectedIcon;
Boolean selected = false;
String newPathString;
int buttonNumber;
public void getPath(int buttonNumber) {
String path = "/Users/AlecR/Documents/workspace/Elevens Lab Midyear Exam/src/";
if(boardArray.get(buttonNumber).rank() == "Ace" || boardArray.get(buttonNumber).rank() == "Jack" || boardArray.get(buttonNumber).rank() == "Queen" || boardArray.get(buttonNumber).rank() == "King") {
newPathString = path + boardArray.get(buttonNumber).rank() + boardArray.get(buttonNumber).suit() + "S.GIF";
}else{
newPathString = path + Integer.toString(boardArray.get(buttonNumber).pointValue()) + boardArray.get(buttonNumber).suit() + "S.GIF";
}
selectedIcon = new ImageIcon(newPathString);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == cardOne) {
if(boardArray.get(0).selected == false) {
getPath(0);
buttons[0].setIcon(selectedIcon);
boardArray.get(0).selected = true;
}else{
boardArray.get(0).selected = false;
buttons[0].setIcon(boardArray.get(0).cardImage);
}
}
if(e.getSource() == cardTwo) {
if(boardArray.get(1).selected == false) {
getPath(1);
buttons[1].setIcon(selectedIcon);
boardArray.get(1).selected = true;
}else{
boardArray.get(1).selected = false;
buttons[1].setIcon(boardArray.get(1).cardImage);
}
}
if(e.getSource() == cardThree) {
if(boardArray.get(2).selected == false) {
getPath(2);
buttons[2].setIcon(selectedIcon);
boardArray.get(2).selected = true;
}else{
boardArray.get(2).selected = false;
buttons[2].setIcon(boardArray.get(2).cardImage);
}
}
if(e.getSource() == cardFour) {
if(boardArray.get(3).selected == false) {
getPath(3);
buttons[3].setIcon(selectedIcon);
boardArray.get(3).selected = true;
}else{
boardArray.get(3).selected = false;
buttons[3].setIcon(boardArray.get(3).cardImage);
}
}
if(e.getSource() == cardFive) {
if(boardArray.get(4).selected == false) {
getPath(4);
buttons[4].setIcon(selectedIcon);
boardArray.get(4).selected = true;
}else{
boardArray.get(4).selected = false;
buttons[4].setIcon(boardArray.get(4).cardImage);
}
}
if(e.getSource() == cardSix) {
if(boardArray.get(5).selected == false) {
getPath(5);
buttons[5].setIcon(selectedIcon);
boardArray.get(5).selected = true;
}else{
boardArray.get(5).selected = false;
buttons[5].setIcon(boardArray.get(5).cardImage);
}
}
if(e.getSource() == cardSeven) {
if(boardArray.get(6).selected == false) {
getPath(6);
buttons[6].setIcon(selectedIcon);
boardArray.get(6).selected = true;
}else{
boardArray.get(6).selected = false;
buttons[6].setIcon(boardArray.get(6).cardImage);
}
}
if(e.getSource() == replace) {
checkWin();
}
if(e.getSource() == reset) {
System.out.println("Feature In Progress. Exit game to reset.");
}
}
int total;
int buttonsSelected = 0;
public void checkWin() {
for(int i = 0; i <= 6; i++) {
if(boardArray.get(i).selected == true) {
int pointValue = boardArray.get(i).pointValue();
total = total + pointValue;
buttonsSelected++;
}
}
if((buttonsSelected == 3 && total == 36) || (buttonsSelected == 2 && total == 11)) {
for(int i = 0; i <= 6; i++) {
if(boardArray.get(i).selected == true) {
boardArray.set(i, deck.nextCard());
buttons[i].setIcon(boardArray.get(i).cardImage);
deckCount--;
cardsLeft.setText("Cards left:" + deckCount);
}
}
}
total = 0;
buttonsSelected = 0;
}
}
import javax.swing.ImageIcon;
/**
* Card.java
*
* <code>Card</code> represents a playing card.
*/
public class Card {
/**
* String value that holds the suit of the card
*/
private String suit;
/**
* String value that holds the rank of the card
*/
private String rank;
/**
* int value that holds the point value.
*/
private int pointValue;
/**
* Creates a new <code>Card</code> instance.
*
* #param cardRank
* a <code>String</code> value containing the rank of the card
* #param cardSuit
* a <code>String</code> value containing the suit of the card
* #param cardPointValue
* an <code>int</code> value containing the point value of the
* card
*/
ImageIcon cardImage;
Card card;
Boolean selected = false;
int picNumber = 1;
public Card(String cardRank, String cardSuit, int cardPointValue, Boolean selected) {
// initializes a new Card with the given rank, suit, and point value
rank = cardRank;
suit = cardSuit;
pointValue = cardPointValue;
selected = false;
String pointString = Integer.toString(pointValue);
String path = "/Users/AlecR/Documents/workspace/Elevens Lab Midyear Exam/src/";
if (cardPointValue >= 2 && cardPointValue <= 10) {
String cardImageString = path + pointString + cardSuit + ".GIF";
cardImage = new ImageIcon(cardImageString);
}
if (cardPointValue == 1) {
}
switch (pointValue) {
case 1:
cardImage = new ImageIcon(path + "ace" + cardSuit + ".GIF");
break;
case 11:
cardImage = new ImageIcon(path + "jack" + cardSuit + ".GIF");
break;
case 12:
cardImage = new ImageIcon(path + "queen" + cardSuit + ".GIF");
break;
case 13:
cardImage = new ImageIcon(path + "king" + cardSuit + ".GIF");
break;
}
}
public String getCardImage() {
return cardImage.toString();
}
/**
* Accesses this <code>Card's</code> suit.
*
* #return this <code>Card's</code> suit.
*/
public String suit() {
return suit;
}
/**
* Accesses this <code>Card's</code> rank.
*
* #return this <code>Card's</code> rank.
*/
public String rank() {
return rank;
}
/**
* Accesses this <code>Card's</code> point value.
*
* #return this <code>Card's</code> point value.
*/
public int pointValue() {
return pointValue;
}
/**
* Compare this card with the argument.
*
* #param otherCard
* the other card to compare to this
* #return true if the rank, suit, and point value of this card are equal to
* those of the argument; false otherwise.
*/
public boolean matches(Card otherCard) {
return otherCard.suit().equals(this.suit())
&& otherCard.rank().equals(this.rank())
&& otherCard.pointValue() == this.pointValue();
}
/**
* Converts the rank, suit, and point value into a string in the format
* "[Rank] of [Suit] (point value = [PointValue])". This provides a useful
* way of printing the contents of a <code>Deck</code> in an easily readable
* format or performing other similar functions.
*
* #return a <code>String</code> containing the rank, suit, and point value
* of the card.
*/
#Override
public String toString() {
return rank + " of " + suit + " (point value = " + pointValue + ")";
}
}
When it resets, it is basically same as the state when you start a new game.
When starting a new game:
1) Create deck
2) Shuffle deck
3) Draw images(cards) or reset the image in swing
So when you reset, basically you repeat the same process as above.
You can have something like this:
public static void startNewGame() //use this for reset
{
ArrayList<Card> deck = createNewDeck();
ShuffleCards(deck);
ResetImages(deck); //reset card images
ResetComponents(); //reset all buttons/display to initial state
}
Something like this:
board.this.setVisible(false);
board.this.dispose();
new Board();
You can assign board = new Board(); but you need to make it static in the main class.
The best way is to make it using
public class DeckTester {
.
.
private static Board board;
public static void newBoard(){
board = new Board();
}
Then, refresh what you need.
All you have to do to restart is redefine the attributes as you would at the beginning so if you populate a deck and shuffle it at startup, you should so the same at restart. Try using a function for both scenarios, I'll give you a generic example.
public void setup() {
populate() // populate deck
shuffle() // and shuffle it
// anything else like ...
score = 0;
}
Question (short version): How do I compare elements in an ArrayList to each other?
I've got most of the basics of ArrayList down pretty well (add, get, set, size...). I'm having trouble stepping into the ArrayList to compare objects (playing cards' values and suits) in order to determine best poker hands. I have a class to store information about a card.
Card class:
/** class Card : for creating playing card objects
* it is an immutable class.
* Rank - valid values are 1 to 13
* Suit - valid values are 0 to 3
* Do not modify this class!
*/
class Card {
/* constant suits and ranks */
static final String[] Suit = {"Clubs", "Diamonds", "Hearts", "Spades" };
static final String[] Rank = {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"};
/* Data field of a card: rank and suit */
private int cardRank; /* values: 1-13 (see Rank[] above) */
private int cardSuit; /* values: 0-3 (see Suit[] above) */
/* Constructor to create a card */
/* throw PlayingCardException if rank or suit is invalid */
public Card(int rank, int suit) throws PlayingCardException {
if ((rank < 1) || (rank > 13))
throw new PlayingCardException("Invalid rank:"+rank);
else
cardRank = rank;
if ((suit < 0) || (suit > 3))
throw new PlayingCardException("Invalid suit:"+suit);
else
cardSuit = suit;
}
/* Accessor and toString */
/* You may impelemnt equals(), but it will not be used */
public int getRank() { return cardRank; }
public int getSuit() { return cardSuit; }
public String toString() { return Rank[cardRank] + " " + Suit[cardSuit]; }
/* Few quick tests here */
public static void main(String args[])
{
try {
Card c1 = new Card(1,3); // A Spades
System.out.println(c1);
c1 = new Card(10,0); // 10 Clubs
System.out.println(c1);
//c1 = new Card(10,5); // generate exception here
}
catch (PlayingCardException e)
{
System.out.println("PlayingCardException: "+e.getMessage());
}
}
}
And a class to check each hand of cards (this is the class I'm having trouble figuring out). I have currently added code to make this add an ArrayList and print each hand over again (just to make sure I can create a separate ArrayList because I wasn't too comfortable with my ability), but I can't figure out how to compare elements of each card (rank and suit).
Check hands class:
/** Check current currentHand using multipliers and goodHandTypes arrays
* Must print yourHandType (default is "Sorry, you lost") at the end o function.
* This can be checked by testCheckHands() and main() method.
*/
private void checkHands()
{
// implement this method!
ArrayList<Card> multiplierCheck = new ArrayList<Card>();
String yourhandtype = "Sorry, you lost";
for (int toList = 0; toList<5; toList++) {
multiplierCheck.add(currentHand.get(toList));
}
System.out.println(multiplierCheck);
System.out.println(yourhandtype);
}
And a method to test check hands that creates hands which are winning hands (straight, flush, three of a kind). I can't figure out how to compare the cards to each other in my Check Hands Class.
testCheckHands() Method
public void testCheckHands()
{
try {
currentHand = new ArrayList<Card>();
// set Royal Flush
currentHand.add(new Card(1,3));
currentHand.add(new Card(10,3));
currentHand.add(new Card(12,3));
currentHand.add(new Card(11,3));
currentHand.add(new Card(13,3));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// set Straight Flush
currentHand.set(0,new Card(9,3));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// set Straight
currentHand.set(4, new Card(8,1));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// set Flush
currentHand.set(4, new Card(5,3));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// "Royal Pair" , "Two Pairs" , "Three of a Kind", "Straight", "Flush ",
// "Full House", "Four of a Kind", "Straight Flush", "Royal Flush" };
// set Four of a Kind
currentHand.clear();
currentHand.add(new Card(8,3));
currentHand.add(new Card(8,0));
currentHand.add(new Card(12,3));
currentHand.add(new Card(8,1));
currentHand.add(new Card(8,2));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// set Three of a Kind
currentHand.set(4, new Card(11,3));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// set Full House
currentHand.set(2, new Card(11,1));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// set Two Pairs
currentHand.set(1, new Card(9,1));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// set Royal Pair
currentHand.set(0, new Card(3,1));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
// non Royal Pair
currentHand.set(2, new Card(3,3));
System.out.println(currentHand);
checkHands();
System.out.println("-----------------------------------");
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
To evaluate Poker hands probably the most common thing you're going to do is loop through the data structure (could be an array, list, whatever) and compare the cards to each other. For example here's some pseudo-Java to compare a straight:
for (int i = 1; i < /* length of hand */; i++) {
if (/* rank for card i is not 1 greater
than rank for card i - 1 */) {
/* not a straight */
}
}
Note that the above assumes the structure is sorted which I'll get to. Also since Poker hands are so different there's not really a 'best way' to do all of them. You will have to write a routine for each one. So I would recommend you come up with some abstraction that helps you out. What I would do is use Enum. Here's a basic example:
enum PokerHand {
STRAIGHT {
#Override
boolean matches(List<Card> hand) {
for (int i = 1; i < hand.size(); i++) {
if (
card.get(i).getRank() !=
card.get(i - 1).getRank() + 1
) {
return false;
}
}
return true;
}
},
FOUR_OF_A_KIND {
#Override
boolean matches(List<Card> hand) {
int[] rankCount = new int[14];
/* count up the ranks in the hand */
for (Card card : hand) {
rankCount[card.getRank()]++;
}
boolean foundHasOne = false;
boolean foundHasFour = false;
/* now evaluate exclusively
* there must be only a 1 count and a 4 count
*/
for (int i = 1; i < rankCount.length; i++) {
if (rankCount[i] == 1) {
if (!foundHasOne) {
foundHasOne = true;
} else {
return false;
}
} else if (rankCount[i] == 4) {
if (!foundHasFour) {
foundHasFour = true;
} else {
return false;
}
} else if (rankCount[i] != 0) {
return false;
}
}
return true;
}
},
ROYAL_FLUSH {
final int[] rfRanks = {
1, 10, 11, 12, 13
};
#Override
boolean matches(List<Card> hand) {
for (int i = 0; i < rfRanks.length; i++) {
if (rfRanks[i] != hand.get(i).getRank())
return false;
}
return true;
}
};
abstract boolean matches(List<Card> hand);
}
Of course the above does not cover all Poker hands, just a few examples. Also I don't play Poker so those could be a little wrong but the point is to show some evaluation examples.
As I said before this becomes much simpler if you sort your lists ahead of time. java.util.Collections and java.util.Arrays have utility methods for this so it is fairly trivial. Just make sure to make a copy before sorting if you don't want the sort to persist after you check the hands.
/* make a shallow copy */
List<Card> sortedHand = new ArrayList<Card>(playerHand);
/* sort based on rank */
Collections.sort(sortedHand, new Comparator<Card>() {
#Override
public int compare(Card card1, Card card2) {
int rank1 = card1.getRank();
int rank2 = card2.getRank();
if (rank1 > rank2) {
return 1;
if (rank1 < rank2)
return -1;
return 0;
}
});
See Comparator#compare for a description of how that works but that's basically it to sort.
Using an enum or something like it then makes the evaluation fairly trivial logically.
Now what I recommend is to make a method for the evaluation because then you can conveniently return the constant for what the hand is.
static PokerHand evaluateHand(List<Card> hand) {
for (PokerHand potential : PokerHand.values()) {
if (potential.matches(hand))
return potential;
}
/* imply there is not a matching hand */
return null;
}
So after you make your copy of the hand and have sorted it you can call to evaluate it:
PokerHand evaluated = evaluateHand(sortedHand);
if (evaluated != null) {
/* it's a recognized hand */
}
You don't have to make a method, you could do something like the following:
PokerHand evaluated = null;
for (PokerHand potential : PokerHand.values()) {
if (potential.matches(sortedHand)) {
evaluated = potential;
break;
}
}
if (evaluated != null) {
/* it's a recognized hand */
}
But using helper methods helps organize your code.
I hope that helps. If you also need to score the hands to decide if there is a winner, just add another method to the enum that returns a score. Then see which one is the biggest.
Not sure if you said how it isn't working, but to iterate through an arrayList..
for (String s : arrayList)
if (s.equals(value))
// ...
String can be replaced for int, ect..
I am doing a quick card game project in Java. I am storing the deck of cards as a node list. I think I am having trouble properly adding and removing from the list. Do you see anything that doesn't look right? I've been banging my head off the desk trying to figure this one out. EDIT: Posted all the classes for you to see
Card class
public class Card
{
private CardType theCard;
private CardSuit theSuit;
private Card nextCard = null, previousCard = null;
Card(Card card)
{
/*
* Question - If I just set "this = c", would this
* object be pointing to the same object c? Or will
* a separate object be created from Card c
*/
this.theCard = card.getTheCard();
this.theSuit = card.getTheSuit();
this.nextCard = card.getNext();
this.previousCard = card.getPrevious();
}
Card(CardType theCard, CardSuit theSuit)
{
this.theCard = theCard;
this.theSuit = theSuit;
}
Card(CardType theCard, CardSuit theSuit, Card nextCard, Card previousCard)
{
this.theCard = theCard;
this.theSuit = theSuit;
this.nextCard = nextCard;
this.previousCard = previousCard;
}
//the suit order is spade, heart, diamond, and then club.
public int getTotValue()
{
return theCard.getValue() + theCard.getFaceValue() + theSuit.getValue();
}
public int getFaceValue()
{
return theCard.getFaceValue();
}
public int getSuitValue()
{
return theSuit.getValue();
}
public String getFace()
{
return theSuit.getFace();
}
public String getSuit()
{
return theSuit.getFace();
}
public int getValue()
{
return theCard.getValue();
}
public Card getNext()
{
return nextCard;
}
public void setNext(Card nextCard)
{
this.nextCard = nextCard;
}
public Card getPrevious()
{
return previousCard;
}
public void setPrevious(Card previousCard)
{
this.previousCard = previousCard;
}
/**
* #return the theCard
*/
public CardType getTheCard() {
return theCard;
}
/**
* #param theCard the theCard to set
*/
public void setTheCard(CardType theCard) {
this.theCard = theCard;
}
/**
* #return the theSuit
*/
public CardSuit getTheSuit() {
return theSuit;
}
/**
* #param theSuit the theSuit to set
*/
public void setTheSuit(CardSuit theSuit) {
this.theSuit = theSuit;
}
public String toString()
{
return (theCard.getFace() + " of " + theSuit.getFace());
}
}
CardSuit
public enum CardSuit
{
SPADE("Spade", 4),
HEART("Heart", 3),
DIAMOND("Diamond", 2),
CLUB("Club", 1);
private final String face;
private final int value;
CardSuit(String face, int value)
{
this.face = face;
this.value = value;
}
public String getFace()
{
return face;
}
public int getValue()
{
return value;
}
}
CardType
public enum CardType
{
ACE("Ace", 11),
KING("King", 3, 10),
QUEEN("Queen", 2, 10),
JACK("Jack", 1, 10),
TEN("Ten", 10),
NINE("Nine", 9),
EIGHT("Eight", 8),
SEVEN("Seven", 7),
SIX("Six", 6),
FIVE("Five", 5),
FOUR("Four", 4),
THREE("Three", 3),
DEUCE("Deuce", 2);
private final String face;
private final int value;
private int faceValue = 0;
CardType(String f, int v)
{
this.face = f;
this.value = v;
}
CardType(String f, int fv, int v)
{
this.face = f;
this.faceValue = fv;
this.value = v;
}
public String getFace()
{
return face;
}
public int getValue()
{
return value;
}
public int getFaceValue()
{
return faceValue;
}
}
Deck
/**
*
*/
/**
* #author Andrew-Desktop
*
*/
public class Deck extends Pile
{
/**
* the suit order is spade, heart, diamond, and then club.
*/
public Deck()
{
for(CardType card: CardType.values())
{
for(CardSuit suit: CardSuit.values())
{
this.addLastCard(new Card(card, suit));
}
}
}
/**
* #param topCard
* #param bottomCard
*/
public Deck(Card topCard, Card bottomCard)
{
super(topCard, bottomCard);
// TODO Auto-generated constructor stub
}
/**
* #param topCard
* #param bottomCard
* #param nCard
*/
public Deck(Card topCard, Card bottomCard, int nCard)
{
super(topCard, bottomCard, nCard);
// TODO Auto-generated constructor stub
}
}
Pile
import java.util.Random;
public class Pile
{
private static final int GREATER_THAN = 1;
private static final int EQUAL_TO = 0;
private static final int LESS_THAN = -1;
Card topCard, bottomCard;
int nCard;
Random ran = new Random();
int ranNum;
Pile()
{
topCard = null;
bottomCard = null;
nCard = 0;
}
Pile(Card topCard, Card bottomCard)
{
this.topCard = topCard;
this.bottomCard = bottomCard;
this.nCard = 52;
}
Pile(Card topCard, Card bottomCard, int nCard)
{
this.topCard = topCard;
this.bottomCard = bottomCard;
this.nCard = nCard;
}
public void
shuffle() throws InterruptedException
{
for(int i = ran.nextInt(10000);0<i;i--)
{
Card tempCard = remove(1);
this.insert(tempCard, (ran.nextInt(52)+1));
}
}
public boolean
thereIsDuplicates()
{
Card travCard = topCard;
for(int x = 1; x<=nCard && travCard != null; x++)
{
for(int y = x+1; y<=nCard; y++)
{
if(travCard == this.getCardAtIndex(y))
{
// System.out.println(this.getIndexOfCard(travCard) + ": " + travCard);
System.out.println(travCard.toString());
return true;
}
}
travCard = travCard.getNext();
}
return false;
}
public
Card remove(Card c)
{
assert !isEmpty();//Don't know if this even works
if(c == topCard)// if topCard
{
topCard = topCard.getNext();
topCard.setPrevious(null);
}
else if(c == bottomCard) // if bottom card
{
bottomCard = bottomCard.getPrevious();
bottomCard.setNext(null);
}
else
{
Card tempCard = c.getPrevious();
tempCard.setNext(c.getNext());
tempCard.getNext().setPrevious(tempCard);
}
nCard--;
return null;
}
// public void
// remove(int i)
// {
// assert (i>0 && i <= nCard && !isEmpty());
// if(i == 1)// if topCard
// {
// topCard = topCard.getNext();
// topCard.setPrevious(null);
// }
// else if(this.getCardAtIndex(i).getNext()==null) // if bottom card
// {
// bottomCard = bottomCard.getPrevious();
// bottomCard.setNext(null);
// }
// else
// {
// Card cardBefore = this.getCardAtIndex(i-1);
// cardBefore.setNext(cardBefore.getNext().getNext());
// cardBefore.getNext().setPrevious(cardBefore);
// }
// nCard--;
//
// }
public Card remove(int givenPosition) throws InterruptedException
{
Card result = null; // return value
if ((givenPosition >= 1) && (givenPosition <= nCard))
{
if (givenPosition == 1) // case 1: remove first entry
{
result = topCard; // save entry to be removed
topCard = topCard.getNext();
topCard.setPrevious(null);
}
else // case 2: givenPosition > 1
{
Card cardBefore = getCardAtIndex(givenPosition - 1);
Card cardToRemove = cardBefore.getNext();
Card cardAfter = cardToRemove.getNext();
cardBefore.setNext(cardAfter); // disconnect the node to be removed
cardAfter.setPrevious(cardBefore);
result = cardToRemove; // save entry to be removed
} // end if
nCard--;
} // end if
if(result == null)
{
this.printCards();
Thread.sleep(1000);
}
return result;
}
/**
* <p>Precondition: index must be 0<i and i<53 or less than the number of cards
* <p>Postcondition:
* #param i - The index of the card.
* #return Card at that index.
*
*/
public Card getCardAtIndex(int i)
{
Card travCard = topCard;
assert (i>0 && i<=nCard && !isEmpty());
for(int x = 1; x<=i && travCard != null; x++)
{
travCard = travCard.getNext();
}
return travCard;
}
public int
getIndexOfCard(Card c, int i)
{
Card travCard = topCard;
for(int x = i; x<=nCard; x++)
{
if(travCard == c)
return x;
travCard = travCard.getNext();
}
return -1;
}
public Card
getCard(Card c)//don't think I'll need this method
{
Card travCard = topCard;
assert (!isEmpty());
while(c!=travCard && null != travCard)
{
travCard = travCard.getNext();
}
return travCard;
}
/**
* Sorts from highest(Ace) to lowest 2
* the suit order is spade, heart, diamond, and then club.
*/
public void
addLastCard(Card c)
{
if(isEmpty())
{
topCard = c;
bottomCard = c;
}
else
{
bottomCard.setNext(c);
c.setPrevious(bottomCard);
bottomCard = c;
}
nCard++;
}
public void
sort()
{
quickSort(topCard, bottomCard);
}
private void
quickSort(Card start, Card end)
{
Card left = start;
Card right = end;
if (start != end)
{
Card pivot = start;
while (!(left.getNext()!=right))
{
while (compare(left, pivot) == LESS_THAN && left != end && left!=right)
{
left = left.getNext();
}
while (compare(right, pivot) == GREATER_THAN && right!=start && right!=left)
{
right = right.getPrevious();
}
if (left!=right)
{
swap(left, right);
}
}
swap(start, right);
quickSort(start, right.getPrevious());
quickSort(right.getNext(), end);
}
else // if there is only one element in the partition, do not do any sorting
{
return; // the array is sorted, so exit
}
}
public void
swap(Card one, Card two)
{
Card temp = new Card(one);
one = two;
two = temp;
}
public void
insert(Card theCard, int givenPosition)
{
if(givenPosition>0 && givenPosition<=nCard)
{
if(isEmpty())// if an empty list
{
topCard = theCard;
bottomCard = theCard;
System.out.println("EmptyList");
}
else if(1==givenPosition)// if adding to the top of the pile
{
theCard.setNext(topCard);
topCard.setPrevious(theCard);
topCard = theCard;
}
else if(nCard == givenPosition) // if adding to the bottom of the pile
{
this.addLastCard(theCard);
nCard--;
}
else
{
Card tempCard = getCardAtIndex(givenPosition);
theCard.setNext(tempCard.getNext());
tempCard.setNext(theCard);
theCard.setPrevious(tempCard);
}
nCard++;
}
}
//the suit order is spade, heart, diamond, and then club.
public int
compare(Card one, Card two)
{
if(one.getValue()<two.getValue() || (one.getValue() == two.getValue() && one.getTotValue()<two.getTotValue()))
{
return LESS_THAN;
}
else if(one.getValue() == two.getValue() && one.getTotValue() == two.getTotValue())
{
return EQUAL_TO;
}
else if(one.getValue()>two.getValue() || (one.getValue() == two.getValue() && one.getTotValue()>two.getTotValue()))
{
return GREATER_THAN;
}
return -5;
}
public boolean
isEmpty()
{
if(0 == nCard && null == topCard)
return true;
else
return false;
}
public void
printCards()
{
Card travCard = topCard;
int i = 1;
while(travCard!=null)
{
System.out.println(i + ": " + travCard.toString());
travCard = travCard.getNext();
i++;
}
}
/**
* #return the topCard
*/
public Card
getTopCard()
{
return topCard;
}
/**
* #param topCard the topCard to set
*/
public void
setTopCard(Card topCard)
{
this.topCard = topCard;
}
/**
* #return the bottomCard
*/
public Card
getBottomCard()
{
return bottomCard;
}
/**
* #param bottomCard the bottomCard to set
*/
public void
setBottomCard(Card bottomCard)
{
this.bottomCard = bottomCard;
}
/**
* #return the nCard
*/
public int
getnCard()
{
return nCard;
}
/**
* #param nCard the nCard to set
*/
public void
setnCard(int nCard)
{
this.nCard = nCard;
}
}
TwentyOne
public class TwentyOne
{
/**
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException
{
Deck theDeck = new Deck();
theDeck.printCards();
theDeck.shuffle();
theDeck.printCards();
}
}
The output looks something like this:
577625: Ace of Spade
577626: Nine of Spade
577627: Five of Diamond
577628: Ten of Heart
577629: Eight of Heart
577630: Nine of Club
577631: Jack of Heart
577632: Eight of Spade
577633: Queen of Heart
577634: Seven of Heart
577635: Deuce of Club
577636: Jack of Diamond
577637: Four of Club
577638: Five of Club
577639: Ace of Spade
577640: Nine of Spade
577641: Five of Diamond
577642: Ten of Heart
577643: Eight of Heart
577644: Nine of Club
577645: Jack of Heart
577646: Eight of Spade
577647: Queen of Heart
577648: Seven of Heart
577649: Deuce of Club
577650: Jack of Diamond
577651: Four of Club
577652: Five of Club
577653: Ace of Spade
577654: Nine of Spade
577655: Five of Diamond
577656: Ten of Heart
577657: Eight of Heart
577658: Nine of Club
577659: Jack of Heart
577660: Eight of Spade
577661: Queen of Heart
577662: Seven of Heart
577663: Deuce of Club
577664: Jack of Diamond
577665: Four of Club
577666: Five of Club
577667: Ace of Spade
577668: Nine of Spade
577669: Five of Diamond
577670: Ten of Heart
577671: Eight of Heart
577672: Nine of Club
577673: Jack of Heart
577674: Eight of Spade
577675: Queen of Heart
577676: Seven of Heart
577677: Deuce of Club
577678: Jack of Diamond
577679: Four of Club
577680: Five of Club
577681: Ace of Spade
577682: Nine of Spade
577683: Five of Diamond
577684: Ten of Heart
577685: Eight of Heart
577686: Nine of Club
577687: Jack of Heart
577688: Eight of Spade
577689: Queen of Heart
577690: Seven of Heart
577691: Deuce of Club
577692: Jack of Diamond
577693: Four of Club
577694: Five of Club
577695: Ace of Spade
577696: Nine of Spade
577697: Five of Diamond
Use one of the java.util.List subclasses. Either ArrayList (probably what you should pick) or LinkedList (in case your feeling froggy like you need something that implements Queue). Then look at using Collections.shuffle() method to shuffle the cards.
http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html
http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#shuffle(java.util.List)
LinkedList won't perform as well as ArrayList when it comes to random access.
Looking at the output like this makes it hard to figure out what is going on. Something is wrong as the Queen of Hearts appears multiple times. Try testing your insert method without calling shuffle and remove. Testing one method at a time helps isolate the problem.
When you can see that you are able to insert all of your cards in order, see what happens when you remove a single card.