PC Review


Reply
Thread Tools Rate Thread

Design and Creating a black Jack game

 
 
Tony Johansson
Guest
Posts: n/a
 
      15th Mar 2011
Hello!

I'm in the progress of creating a Black Jack game. I have created these
classes.
Game, Deck, Card, Player and Hand. A Game contains a Deck and a Deck
contains an array of Cards.
A Game also contains a List<Player> and a player contains a hand which is a
List of Cards.
None of these Game,Deck,Card,Player and Hand is instansiated in The MainGUI.
There is a second class called GameManager that is instansiating the Game
and this GameManager is instansiated in the MainGUI

The mainGUI contains a DataGridView and some buttons and some user controls
where each user control represent each player that will participate in this
Black jack game. We call this user control PlayerGUI.
The user control(PlayerGUI) that represent the player contains a TextBox for
the player name and some labels and two Buttons and a panel where each drawn
card should be displayed. The Card that is to be displayed in the panel of
the PlayerGUI is also a user control called CardGUI.

At the beginning of the game I create the PlayerGUI and place it in the form
and enter the name in the DataGridView cell where the column is called name
and when this cell go out of focus the TextBox in the PlayerGUI gets updated
with the same name.
I have a binding between the List<Player> and the DataGridView DataDource
and the List<Player> is placed in the Game class as I mentioned previously.

The MainGUI have four Buttons(NewPlayer, StartGame, CalculateWinner and
NewGame)
Now when I click on the StartGame I want to place some cards which
represented by the CardGUI in the Panel
of the PlayerGUI.

Now to my question which class should be responsible to deal the initial two
cards to each player where the croupier is also a player ?

It's only the MainGUI that know about the PlayerGUI so first I thought
MainGUI class would be a good choice
but I don't think that is good design.

The Game class would otherwise be a good choice but I don't have a reference
to the playerGUI where the CardGUI should be placed ?

So assume I choose to place the Deal method in the Game class how do I best
get access to all PlayerGUI that is placed in the MainGUI form class ?

//Tony


 
Reply With Quote
 
 
 
 
Tony Johansson
Guest
Posts: n/a
 
      15th Mar 2011
"Tony Johansson" <(E-Mail Removed)> skrev i meddelandet
news:iln6ud$dt5$(E-Mail Removed)...
> Hello!
>
> I'm in the progress of creating a Black Jack game. I have created these
> classes.
> Game, Deck, Card, Player and Hand. A Game contains a Deck and a Deck
> contains an array of Cards.
> A Game also contains a List<Player> and a player contains a hand which is
> a List of Cards.
> None of these Game,Deck,Card,Player and Hand is instansiated in The
> MainGUI.
> There is a second class called GameManager that is instansiating the Game
> and this GameManager is instansiated in the MainGUI
>
> The mainGUI contains a DataGridView and some buttons and some user
> controls where each user control represent each player that will
> participate in this Black jack game. We call this user control PlayerGUI.
> The user control(PlayerGUI) that represent the player contains a TextBox
> for the player name and some labels and two Buttons and a panel where each
> drawn card should be displayed. The Card that is to be displayed in the
> panel of the PlayerGUI is also a user control called CardGUI.
>
> At the beginning of the game I create the PlayerGUI and place it in the
> form and enter the name in the DataGridView cell where the column is
> called name and when this cell go out of focus the TextBox in the
> PlayerGUI gets updated with the same name.
> I have a binding between the List<Player> and the DataGridView DataDource
> and the List<Player> is placed in the Game class as I mentioned
> previously.
>
> The MainGUI have four Buttons(NewPlayer, StartGame, CalculateWinner and
> NewGame)
> Now when I click on the StartGame I want to place some cards which
> represented by the CardGUI in the Panel
> of the PlayerGUI.
>
> Now to my question which class should be responsible to deal the initial
> two cards to each player where the croupier is also a player ?
>
> It's only the MainGUI that know about the PlayerGUI so first I thought
> MainGUI class would be a good choice
> but I don't think that is good design.
>
> The Game class would otherwise be a good choice but I don't have a
> reference to the playerGUI where the CardGUI should be placed ?
>
> So assume I choose to place the Deal method in the Game class how do I
> best get access to all PlayerGUI that is placed in the MainGUI form class
> ?
>
> //Tony
>


When I click on the GameStart I can pass pnlPlayers.Controls as an argument.
This pnlPlayers.Controls holds the PlayerGUI that is of type
System.Windows.Forms.ControlCollection but is it acceptable oop design to
use Windows.Forms in so to speak business classes like the Game class and
GameManager ?

//Tony


 
Reply With Quote
 
Tony Johansson
Guest
Posts: n/a
 
      16th Mar 2011

"Peter Duniho" <(E-Mail Removed)> skrev i meddelandet
news:(E-Mail Removed)...
> On 3/15/11 1:10 AM, Tony Johansson wrote:
>> [...]
>> Now to my question which class should be responsible to deal the initial
>> two
>> cards to each player where the croupier is also a player ?

>
> First suggestion: do not post details about your program that have nothing
> to do with your question. There was a lot of text to read there, much of
> which was irrelevant and just wastes the time of people reading your post.
>
>> It's only the MainGUI that know about the PlayerGUI so first I thought
>> MainGUI class would be a good choice
>> but I don't think that is good design.

>
> From your description, it seems that you have intermingled your GUI and
> game modeling code more than would normally be considered desirable. This
> will generally lead to difficult design problems.
>
>> The Game class would otherwise be a good choice but I don't have a
>> reference
>> to the playerGUI where the CardGUI should be placed ?

>
> Inasmuch as your Game class is essentially a controller for the model,
> encapsulating the game mechanics implementation for the program, it seems
> to me that of the types you've described so far, the Game class best fits
> your card-dealing logic.
>
> The ".GUI" types really shouldn't care about the game mechanics at all.
> They should simply present the current state of other objects to the user.
> The Game class, when dealing cards, will directly affect only the Deck and
> Player objects (the Deck object will lose Card instances, while each
> Player object will gain them). The ".GUI" objects then should respond to
> changes in state of the other objects (e.g. be subscribed to an event that
> is raised when the composition of a deck or hand of cards changes).
>
>> So assume I choose to place the Deal method in the Game class how do I
>> best
>> get access to all PlayerGUI that is placed in the MainGUI form class ?

>
> You don't. The Game class shouldn't know anything at all about the
> PlayerGUI class, nor even the MainGUI class. You should have some
> top-level "controller" type that coordinates connections/data-flow between
> the GUI classes and the model classes, such as the Game class. Updates to
> the ".GUI" objects will occur naturally from whatever mechanism you choose
> for that design goal (e.g. events).
>
> Pete


Here is a method InitialDeal that is responsible to deal two cards to each
player.
pnlPlayer is a Panel type.
gm is an instance of a class called GameManager.
This method is located in the MainGUI class.
I just want your opinion if this kind of design of a method in the MainGUI
is somewhat sensible if we look at the OOP.
I have tried to use some kind of layer arcitecture and put things here that
I mean must be here.
I mean I must have some sort of logic here.

private void InitialDeal()
{
// Here I fetch all controls that is called PlayerGUI
Control[] ctrl = this.pnlPlayers.Controls.Find(PlayerGUI, false);
string cardRank;
string image;

// Deal two cards to each player
for (int cardNr = 0; cardNr < InitialDealRound; cardNr++)
{

//Here we have all the players that is participating in the
Black jack game
for (int playerNr = 0; playerNr < ctrl.Length; playerNr++)
{
// Get the card for the specified Player and the cardnr
Card card = gm.GetPlayerCard(playerNr, cardNr);

// loop through all the PlayerGUI until you find the right
name
for (int i = 0; i < pnlPlayers.Controls.Count; i++)
{

//Check if this PlayerGUI contains the right name
PlayerGUI pg = ctrl[i] as PlayerGUI;
if (pg.PlayerName == gm.Players[playerNr].Name)
{
string imagePath =
Path.Combine(Environment.CurrentDirectory, @"..\..\Images\" + card.Suit+
".ico");

//crete the usercontrol CardGUI and place it in the
PlayerGUI panel
CardGUI cg = new CardGUI(imagePath, card.rankSymbol);

int xPos = (cardNr % 2) * cg.Width;
cg.Location = new Point(xPos, 0);
pg.AddCard(cg);
break;
}
}
}
}
dgvAllPlayers.Refresh();
}
//Tony


 
Reply With Quote
 
Tony Johansson
Guest
Posts: n/a
 
      16th Mar 2011

"Peter Duniho" <(E-Mail Removed)> skrev i meddelandet
news:(E-Mail Removed)...
> On 3/16/11 3:51 AM, Tony Johansson wrote:
>> Here is a method InitialDeal that is responsible to deal two cards to
>> each
>> player.
>> pnlPlayer is a Panel type.

>
> Those first two sentences by themselves tell me your design is incorrect.
> A method that deals cards should have no reason whatsoever to know about a
> Panel instance. It should only be interacting with a non-GUI type that
> manages the state of the game.
>
>> gm is an instance of a class called GameManager.
>> This method is located in the MainGUI class.
>> I just want your opinion if this kind of design of a method in the
>> MainGUI
>> is somewhat sensible if we look at the OOP.

>
> It is not sensible. Again, perhaps if you ignore the bigger picture and
> focus _only_ on the very abstract object-oriented question, you could
> argue in favor of the design. But it's not enough to abstract things in
> an object-oriented way; you have to abstract things in a way that is
> proper in all the ways that matter.
>
> Using GUI objects to maintain or even access/reveal the state of the
> non-GUI aspects of your program is poor design. It causes your types to
> be too involved with matters that aren't relevant to the primary purpose
> of those types.
>
> You keep asking about "OOP" but IMHO that's not really the important
> context for this line of questioning.
>
> From a design point of view, your question is sort of like asking "I am
> designing a new animal; here I have followed the usual technique of
> providing pulmonary, circulatory, lymphatic, muscle, and nervous systems.
> Even though I've put the eyeballs on the soles of the feet, doesn't the
> fact that I've got all the basic networked systems in the body mean that
> my animal is correct?"
>
> OOP is not an end unto itself. It's just a single piece of a larger
> process for making a good program. It's important to have a good OOP
> foundation on which the rest of your program is built, but it's not
> sufficient to concern yourself only with the object-oriented nature of the
> code. You have to look at the big picture.
>
> Pete



From the MainGUI I call a method called Start this is located in the
GameManager. This GameManager was instansiated in MainGUI. From GameManager
I call NewDeal that is located in the Game class and here I deal two card to
each player to put in the hand of the player
What I want now is to put the cards that is stored in the hand of each
player in the PlayerGUI.
What is the best way to establish that. I mean If I use this
NotifyPropertyChanged when I added a new card in the hand of a Player I
can't subscribe to this event from the MainGUI class because I don't have a
reference to the hand class it's only the Player class that has a reference
to the hand class.

It seems impossible to make the GUI subscribe to some sort of event so they
can update the GUI with cards.
So the only option seems to read the hand for each player from the GUI
through GameManager and the Game class

//Tony


 
Reply With Quote
 
Tony Johansson
Guest
Posts: n/a
 
      17th Mar 2011

"Peter Duniho" <(E-Mail Removed)> skrev i meddelandet
news:(E-Mail Removed)...
> On 3/16/11 4:28 PM, Tony Johansson wrote:
>> "Peter Duniho"<(E-Mail Removed)> skrev i meddelandet
>> news:(E-Mail Removed)...
>>> On 3/16/11 3:51 AM, Tony Johansson wrote:
>>>> Here is a method InitialDeal that is responsible to deal two cards to
>>>> each
>>>> player.
>>>> pnlPlayer is a Panel type.
>>>
>>> Those first two sentences by themselves tell me your design is
>>> incorrect.
>>> A method that deals cards should have no reason whatsoever to know about
>>> a
>>> Panel instance. It should only be interacting with a non-GUI type that
>>> manages the state of the game.
>>>
>>>> gm is an instance of a class called GameManager.
>>>> This method is located in the MainGUI class.
>>>> I just want your opinion if this kind of design of a method in the
>>>> MainGUI
>>>> is somewhat sensible if we look at the OOP.
>>>
>>> It is not sensible. Again, perhaps if you ignore the bigger picture and
>>> focus _only_ on the very abstract object-oriented question, you could
>>> argue in favor of the design. But it's not enough to abstract things in
>>> an object-oriented way; you have to abstract things in a way that is
>>> proper in all the ways that matter.
>>>
>>> Using GUI objects to maintain or even access/reveal the state of the
>>> non-GUI aspects of your program is poor design. It causes your types to
>>> be too involved with matters that aren't relevant to the primary purpose
>>> of those types.
>>>
>>> You keep asking about "OOP" but IMHO that's not really the important
>>> context for this line of questioning.
>>>
>>> From a design point of view, your question is sort of like asking "I am
>>> designing a new animal; here I have followed the usual technique of
>>> providing pulmonary, circulatory, lymphatic, muscle, and nervous
>>> systems.
>>> Even though I've put the eyeballs on the soles of the feet, doesn't the
>>> fact that I've got all the basic networked systems in the body mean that
>>> my animal is correct?"
>>>
>>> OOP is not an end unto itself. It's just a single piece of a larger
>>> process for making a good program. It's important to have a good OOP
>>> foundation on which the rest of your program is built, but it's not
>>> sufficient to concern yourself only with the object-oriented nature of
>>> the
>>> code. You have to look at the big picture.
>>>
>>> Pete

>>
>>
>> From the MainGUI I call a method called Start this is located in the
>> GameManager. This GameManager was instansiated in MainGUI. From
>> GameManager
>> I call NewDeal that is located in the Game class and here I deal two card
>> to
>> each player to put in the hand of the player
>> What I want now is to put the cards that is stored in the hand of each
>> player in the PlayerGUI.
>> What is the best way to establish that.

>
> The best way to establish that is for the PlayerGUI class to subscribe to
> an event on the Player class that is raised when the hand of the player
> changes. Then the PlayerGUI will update itself based on the new contents
> of the player's hand.
>
>> I mean If I use this
>> NotifyPropertyChanged when I added a new card in the hand of a Player I
>> can't subscribe to this event from the MainGUI class because I don't have
>> a
>> reference to the hand class it's only the Player class that has a
>> reference
>> to the hand class.

>
> You can either expose the Hand class so that the GUI classes can see it,
> or you can write a new event in the Player class that essentially
> delegates the event to the Hand class, by having the Player class
> subscribe to the Hand class's event and then raising its own when the Hand
> class's event is raised.
>
> Without a proper code example, I don't really understand how the PlayerGUI
> can even show the cards in the player's hand if it doesn't know about the
> Hand class. But whatever: the bottom line is, if you're going to follow
> your current design, just put the event wherever the GUI types are
> currently finding out about the cards in the hand already.
>
>> It seems impossible to make the GUI subscribe to some sort of event so
>> they
>> can update the GUI with cards.

>
> It's programming. Nothing is impossible, though lots of choices are
> ill-advised. Sometimes the only available choices are in fact
> ill-advised, which then means you've messed up the overall design. In
> that case, you can either go with fixing the code in an ill-advised way,
> or you have to go back and fix the design first, so that you have options
> that are not ill-advised.
>
> Pete


Here is how my classes talk to each other and I hope it would be possible to
subscribe to the event PropertyChanged
that is raised in the Hand class when a new card is added to the hand of a
Player.
I hope that you can give me some advise how I can do that.

This MainGUI class which is called CardGameTester has a reference two these
two class library CardGameClassLib and CardGameControlLib

CardGameClassLib contains these classes Game,Deck,Card,PLayer and Hand
CardGameControlLib contains these classes PlayerGUI and CardGUI which is
user controls

public partial class CardGameTester : Form
{
private BindingSource bindingSource = new BindingSource();
private GameManager gm = new GameManager();
....

private void BtnStartGame_Click(object sender, EventArgs e)
{
gm.Start();
}
....
}



public class GameManager
{
private Game game = new Game();

public void Start()
{
game.NewDeal();
}
}


public class Game
{
const int InitialDealRound = 2;
private int currentPlayer;
private Deck deck = new Deck();
private int nrOfPlayers;
private List<Player> players = new List<Player>();

public void NewDeal()
{
nrOfPlayers = players.Count;

deck.Shuffle();

for (int cardNr = 0; cardNr < InitialDealRound; cardNr++)
{
for (int playerNr = 0; playerNr < nrOfPlayers; playerNr++)
{
players[playerNr].DrawCard(deck.GetNextCard());
}
}
}
}

public class Deck
{
const int MaxNumOfCardsPerDeck = 52;
private Card[] cards;
private int currentPosition = 0 ;

public Card GetNextCard()
{
if (currentPosition == cards.Length)
{
currentPosition = 0;
Shuffle();
}
return cards[currentPosition++].Clone() as Card;
}
....
}

public class Player
{
private Hand hand = new Hand();
private int playerID;
private int losts;
private string name;
private int wins;
private int sum;
private int currentSum;

public void DrawCard(Card card)
{
hand.AddCard(card);
}
}

public class Hand : INotifyPropertyChanged,ICloneable
{
const int LuckyNumber = 21;
private List<Card> cards = new List<Card>();
public event PropertyChangedEventHandler PropertyChanged;

public void AddCard(Card card)
{
cards.Add(card);
NotifyPropertyChanged("CardAdded");
}

private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}

//Tony


 
Reply With Quote
 
Tony Johansson
Guest
Posts: n/a
 
      17th Mar 2011
Forget this. I found a solution that I can publish the event in the game
class and subscribe to this event in the GUI class and it
works fine.

//Tony


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Screen goes Black after playing game Rainy Windows XP Basics 9 5th Dec 2006 12:17 AM
1394 front panel jack cable/jack heytud@yahoo.com Computer Hardware 2 12th Dec 2005 03:38 PM
Can you use mike jack in lieu of line-in jack on laptop? Videot Windows XP Help 1 30th Apr 2004 05:13 PM
Black & White game.... Alex Windows XP Games 1 16th Nov 2003 05:20 PM
Re: Black & white game Jimmy S. Windows XP Games 0 27th Aug 2003 09:31 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 07:39 PM.