Justin Coombs wrote:
so the player should no make the deck.
Am I missing something here? The player does not make the deck. I don't understand where you're making that assumption. Look at the code for class Player I posted. It has 2 methods, one to display an ArrayList and the other to simply receive 2 cards from the Card class. The player does not have anything to do with instantiating or initializing the fields of a deck, or the Card objects contained within that deck. deck is called in class Card, but class Player has nothing to do with making a deck. In fact, if you look at game manager and the order in which the stack would execute, you would see that by the time the execution gets to touching class Player, the preDeck had already been created, filled with Card objects and all necessary fields stamped on each card, and ArrayList deck had already had 52 card objects appended to it.
That is where you are wrong. The manager makes a Card, and initializes its deck. The Player makes a new Card. The new card has its own deck - therefore by making a new Card the player is making the new deck. The player never initializes the new deck, which is part of the new Card. So the new deck is empty. So the player tries to get the cards from the new deck (inside the new Card) you get the NoSuchElementException.
The Card that the player makes (named temp) is not the same Card that the manager makes (named c). It is a different instance, and the new instance is never initialized with the cards. I told you this in my first reply.
The rest has been why your design led to this mistake (and others).
I don't see how player has anything to do with making a deck.
I hope you do now. Let me know if you don't because it is the fundamental problem that both causes the error and my concerns about the design.
Why is it bad style to basically say "A Card has such and such instance variables, and when we take 2 or more cards and add them to an ArrayList of type Card, we shall call it something different to indicate its nature of plurality, such as - in this case - Card(Singular) vs deck(2 or more Cards). I don't understand how that is bad design style.
A class should do one thing, and do it well. It makes it a lot more modular, easy to code, and easy to troubleshoot. Your Card is doing two different things. It represents both a playing card, and a collection of playing cards. No one single instance of the Card class is meant to do both - you mean to have the Card you make in the main method be used to initialize the collection of cards, and you mean the cards in the player's hands represent playing cards. The inter-mixing of these two separate and unrelated tasks makes the Card class more complicated than it should be, and makes using the class harder than it should be.
Also, local variables are consumables. They can be just arbitrary things you don't give a hoot about; you only use it as a means to an end. And when that local variable goes out of scope, its all fine and well because I never intended to keep the thing around anyway...so why should I bother to initialize its fields in the case of the Player.receiveHand?
The deck is part of the Card instance. If you don't initialize the deck in the Card than you do not have cards in the deck, and you can't get cards from the deck. Your tool is vapor, useless. In order to make it do something it needs the substance to work with. In your scenario, the substance is the deck, and the deck is empty.
If its only a tool card to simply allow access to class card and I don't want to keep it afterwards, why make it a King of spades for example?
First: again, this a sign of bad design. I am not trying to rag on you, I am trying to explain the concept because I know you are a beginner and this stuff is hard to grasp. But once you do it makes the rest of your coding career easier.
So back to the problem: You have a Card which does not act as a Card. That is the first tip that you have things wrong. A Card should always act like a Card. The fundamental definition of a playing card is its face and suit. If you are making a Card where that doesn't matter, then that should trigger something in your brain that says 'aha! this is not the way to do this, let me try a different approach.'
It's just gonna disappear when I execution passes the closing brace anyway.
It isn't really about the life of the Object. That doesn't matter. What matters is how you use the Class. Give a Class too many divergent tasks and it becomes hard to use. You wrote the Card class, gave it two distinctly different things to do, and now you are having a hard time using it.
Not only that, but also, why in the heck would I want to make ANOTHER King of Spades when there's already one in Card.deck.
Oh, and therein lies the major design flaw. Since every Card has its own deck, if you were to properly initialize each Card such that you could actually use it, each Card would have it's own deck, and each deck would have its own King of Spades. You won't have one King of Spades, you would have 52.
Okay, you say, I just won't initialize the deck in the Cards that I will be playing with. I will only initialize the Cards I need to create hands and get new cards from - these transient Cards in the method that go away as soon as I am done with them. But still, each Card you use for this case has its own deck, and in order to get a hand from the Card's deck, you need to initialize it. That means every receiveHand method has its own new Card instance, each of the getHand's Card instances has its own deck (which must be initialized to function) and so each receiveHand method has its own King of Spades. That means at least one King of Spades for each Player, but probably more once you get to drawing new cards. Pull the deck out of the Card class, put it into the control of the GameManager, and this problem goes away.
I was always taught to think about programming design in terms of tangible objects. Like "what does a Card object know about itself(i.e. face, suit) and what does and object do(its methods)." In keeping with that approach to object oriented design, I don't understand why a deck in class card is such a bad idea.
Does each card in a pack of playing cards have a deck? When you try to get a hand of cards, do you pull out the blank no-face un-suited card and take your hand from it? No. The deck is a separate entity, a thing which contains Cards. The Card is a separate entity, with no connection to any other card. It can be moved about and handled independently. Your class describes a situation where each Card has a collection of Cards, and you use special throw-away Cards to access a deck of Cards. This special temporary card is responsible for the other cards. This card does not know about its face or suit, since that stuff is not important. It does know about the rest of the cards, and their order, and which ones should be dealt next. Does that sound like it models real life?
All a deck is is a collection of cards.
Right. A deck is a collection of Cards. A deck is not a property of a Card, like the face and suit are. It is a separate container.
All an ArrayList, in this program, is a collection of objects. The getHand method essentially just takes Cards from the bigger pile dubbed "deck" and arranges them into a smaller pile dubbed "temp" which can then be passed to the player to become his own hand, quite like in real life.
That makes sense, but look at what is doing the action, and what the big pile of cards is. Who is doing the action: a Card. A Card takes Cards from a pile and gives them to the Player. What is the big pile of cards? A property of the Card. This is not like the real world at all. A player does not go to a Card to get a hand, he either goes to a dealer or a stack of cards on the table (a deck).
The only way to make it more proper i guess would be to make a dealer class that handles the passing of cards...
Right - but really you already have something that could act like a dealer (even if not named as such) - and that is the GameManager.
but then the dealer class would still have to create a card in order to access the card objects of the card class, and as you said, a [dealer/player] in real life does not simply snap their fingers and CREATE a card(especially not a BLANK one), so again, back to the same issue.
Right - exactly. The biggest problem is the link between the Card and the Deck - and mainly because that connection is in the wrong direction, and is managed by the wrong class.
I understand that there are certain standards in object oriented design that must be adhered to for code to be readable and maintainable and things like that, as well as make sense to people adding to or patching previously written code, but you're not going to get java whizzes in the "beginning java" section of the forums.
No, that isn't my intent. My intent is to try to get you thinking about the design and how it affects the flow of data through your application. You should learn to think about that, and when you do that it makes your life easier. Passing it off as 'I am new here' is a cop-out, because you can come up with a good design when you think about it. I am not talking 'patterns' or anything.
As a newbie, its extremely frustrating trying to learn and understand how to use the colossal library of tools available in the java API without getting error messages, and its difficult to get so much advise about proper design patterns and things like that when you try to reach out for help about a specific issue that personally is what you are stuck on at the moment.
Sorry about the frustration. I know it can be intimidating. What I see in your code indicates that fixing the immediate problem (which I told you how to do already) will just lead to more problems. Many more. Whereas sitting back, thinking about the issues I brought up, and thinking about data flow, and planning your application rather than reacting to error messages, will make it easier.
I'm not stuck on proper class layout and software design principles. I haven't even got there yet.
I disagree. Your main problem here is class layout. You should think bout class layout before you ever touch a keyboard.
I'm still trying to figure out how to make the machine count to 10.
Not quite. You are stuck using a class you wrote because you made it do too many things, and don't quite understand how it works. The problem is not that you have the NoSuchElementException - I told you the solution to that (first paragraph of my first response). The problem is that you don't under stand why you should have to do that (as per your questions in the quoted post). And that really comes from the fact that the Card doesn't really act the way you think it does - that you don't have a single deck, like you want, you have a deck per Card instance. So even when you get past the exception by initializing the deck in the receiveHand method you will get unexpected behavior. And that is all about class design.