Console Blackjack

createDeck function not working

Page 1 of 1

11 Replies - 1452 Views - Last Post: 11 July 2009 - 12:15 PM Rate Topic: -----

#1 chuck981996   User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 119
  • Joined: 03-July 08

Console Blackjack

Posted 10 July 2009 - 03:17 AM

Hi all!
I wasn't sure whether this should be in C + C++ so feel free to move this mods if you need to.

The Idea
I have just began a console version of the popular Blackjack (A.K.A 21) game. As I have only just started I have only written the fuction to create a deck. The deck will then be shuffled with another function.
The createDeck function creates an array of 52 integers with all the cards in a deck. Jack = 11, Queen = 12, King = 13 and Ace = 14. The function then returns a pointer to the array.

The Problem
When I print out the cards in the createDeck function, it works, otherwise it prints out a seamingly random series of numbers. I don't understand why though. I have only just learnt about functions returning pointers to arrays, but I am pretty sure what I did SHOULD work. The following code should print out:
222233334444555566667777888899991010101011111111121212121313131314141414



Instead it prints out a HUGE range of numbers from negatives to positives. When I print out the values within the createDeck function, it prints out the desired response.

The Code
#include <iostream>
using namespace std;

int * createDeck()
{
    int deck[52];
    int count = 0;
    int card = 2;

    for(int i = 0; i < 52; i++)
    {
        if(count == 4)
        {
            card++;
            count = 0;
        }
        deck[i] = card;
        count++;
    }

    int * p;
    p = deck;

    return p;
}

int main()
{
    int * p;
    p = createDeck();

    //Test
    for(int i = 0; i<51; i++)
        cout<< p[i];

    return 0;
}



I have attached the Code::Blocks project for this code.

Any help would be appreciated.
Thanks in adavnce.

Attached File(s)



Is This A Good Question/Topic? 0
  • +

Replies To: Console Blackjack

#2 Speedy_92   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 57
  • Joined: 02-July 09

Re: Console Blackjack

Posted 10 July 2009 - 01:58 PM

Hi chuck,
I'm not sure, cause I can just not test it, but I guess you have to declare the
int deck[52];
outside of your function. Otherwise it is not available anymore in the main-function.

Speedy_92
Was This Post Helpful? 0
  • +
  • -

#3 wildgoose   User is offline

  • D.I.C Regular
  • member icon

Reputation: 67
  • View blog
  • Posts: 468
  • Joined: 29-June 09

Re: Console Blackjack

Posted 10 July 2009 - 05:30 PM

What Speedy_92 said. Your deck is on the local stack within that function and goes out of scope when you return.

Pass in your Deck!
It'll work for shuffling algorithms, etc.
Even your 'hand' would be a small deck of N cards!



Also I'd recommend you associate unique values to each card.

Reserve 0 as no card,
Then run your suites 1=Ace, 2,3,4,5,6,7,8,9,10,J,Q,K of suit
followed by the other three suits.
Followed by a Joker, Joker.

To find out your card in your hand.

0, no card,
53, 54 Jokers
otherwise (card# - 1) MOD 13

And if negative or Bit #7 set, (0x80) then it is face down.

Your shuffle will do all the work! So no need for an elaborate deck build!

void BuildPokerDeck( byte *pDeck )
{
   for (uint i = 1; i <= 52; i++ )
  {
	   *pDeck++ = (byte)i;
   }
}


This post has been edited by wildgoose: 10 July 2009 - 05:37 PM

Was This Post Helpful? 0
  • +
  • -

#4 chuck981996   User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 119
  • Joined: 03-July 08

Re: Console Blackjack

Posted 10 July 2009 - 05:40 PM

Thanks for the replys, both of you. But, I know that my code SHOULD work, I have probably just implemented it wrong... You have both suggested using glabal variables, which I don't like to use as they are...messy. My function should return a pointer to the space in the memory where the deck array is stored. It is commonly used loophole to bypass the rule that functions cannot return arrays. Instead, the function returns a pointer to an array of int. If I have to to, I will use that, but I'd prefer not to.

Thanks :D
Was This Post Helpful? 0
  • +
  • -

#5 wildgoose   User is offline

  • D.I.C Regular
  • member icon

Reputation: 67
  • View blog
  • Posts: 468
  • Joined: 29-June 09

Re: Console Blackjack

Posted 10 July 2009 - 05:45 PM

You really should create a set of classes, but you missed what both of us said!

And I said pass in your deck. Nothing about being global!


#include <iostream>
using namespace std;

#define DECK_SIZE	 52

void createPokerDeck( int *deck )
{
	int count = 0;
	int card = 2;

	for(int i = 0; i < DECK_SIZE; i++)
	{
		if(count == 4)
		{
			card++;
			count = 0;
		}
		deck[i] = card;
		count++;
	}
}



int main()
{
   int deck[ DECK_SIZE ];

	createPokerDeck(  deck );

	//Test
	for(int i = 0; i< DECK_SIZE; i++)   // NOTE: You had a mistake here!!! < 51
		cout<< p[i];

	return 0;
}


This post has been edited by wildgoose: 10 July 2009 - 05:49 PM

Was This Post Helpful? 1

#6 wildgoose   User is offline

  • D.I.C Regular
  • member icon

Reputation: 67
  • View blog
  • Posts: 468
  • Joined: 29-June 09

Re: Console Blackjack

Posted 10 July 2009 - 06:00 PM

If you really want to create your deck then...

const int MaxCards = 52;

class Deck
{
private:
	int *pDeck;

public:
	Deck();
	~Deck();

};


Deck::Deck()
{
	pDeck = new int[ MaxCards ];

	int count = 0;
	int card = 2;

	for(int i = 0; i < MaxCards; i++)
	{
		if(count == 4)
		{
			card++;
			count = 0;
		}
		deck[i] = card;
		count++;
	}
}



Deck::~Deck()
{
	if (NULL != pDeck)
		delete[] pDeck;
}



This post has been edited by wildgoose: 10 July 2009 - 06:01 PM

Was This Post Helpful? 0
  • +
  • -

#7 Oler1s   User is offline

  • D.I.C Lover
  • member icon

Reputation: 1397
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: Console Blackjack

Posted 10 July 2009 - 09:06 PM

Quote

Thanks for the replys, both of you. But, I know that my code SHOULD work,
Why come and ask questions here if you are so convinced of your correctness? Do you think perhaps there is a possibility that you don't understand the concepts correctly? Could that possibly be the case?

Quote

My function should return a pointer to the space in the memory where the deck array is stored. It is commonly used loophole to bypass the rule that functions cannot return arrays. Instead, the function returns a pointer to an array of int.
Instead of understanding the concepts, you've tried to memorize an approach (which you did incorrectly) and so you don't understand the mistake you are making. Let me show you some compileable, buildable code (i.e. you get a program) which exhibits invalid behavior.

int* foo()
{
	int bar[10];
	return bar;
}

int main()
{
	int *a = foo();
}


This code will compile. A good modern compiler will also give you a warning about the invalid behavior you invoke here.

- You really need to read about scope and lifetime of objects in C++. You are returning a pointer, but the pointer points to a location that isn't valid. You need to address this issue.
- I'm not sure why wildgoose introduced classes. It's really not necessary here.
Was This Post Helpful? 0
  • +
  • -

#8 chuck981996   User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 119
  • Joined: 03-July 08

Re: Console Blackjack

Posted 10 July 2009 - 09:31 PM

View Postwildgoose, on 10 Jul, 2009 - 04:45 PM, said:

You really should create a set of classes, but you missed what both of us said!

And I said pass in your deck. Nothing about being global!


#include <iostream>
using namespace std;

#define DECK_SIZE	 52

void createPokerDeck( int *deck )
{
	int count = 0;
	int card = 2;

	for(int i = 0; i < DECK_SIZE; i++)
	{
		if(count == 4)
		{
			card++;
			count = 0;
		}
		deck[i] = card;
		count++;
	}
}



int main()
{
   int deck[ DECK_SIZE ];

	createPokerDeck(  deck );

	//Test
	for(int i = 0; i< DECK_SIZE; i++)   // NOTE: You had a mistake here!!! < 51
		cout<< p[i];

	return 0;
}



My apologies, you didn't say anything about a global, but speedy did. Thanks for your help, your method would be better, I will implement it that way instead. Thanks for your help!

To Oler1s:
Actually I asked the question thinking that it should work as I followed this template (That I wrote and figured out myself) also, you took out a few words in my sentance:

Quote

I have probably just implemented it wrong...


#include <iostream>
using namespace std;

char * returnPointerArray()
{
	char a[] = "Hello World!\0";
	char * b;
	b = a;
	return b;
}

int main()
{
	char * p;
	p = returnPointerArray();

	for(int i=0; i<12; i++)
		cout << p[i];

	return 0;
}



That compiled and returned "Helo World!" BTW. That's why I thought it should work.

I didn't "memorize an approach", I actually tried to think it out myself. It usually works. I also know what "buildable" means, thanks.

Oh, also, your code wouldn't compile, it lacks a very simple feature that even the newest programmers don't forget, it obviously slipped your highly advanced mind.


Thanks again for your help, wildgoose.

This post has been edited by chuck981996: 10 July 2009 - 09:33 PM

Was This Post Helpful? 0
  • +
  • -

#9 Oler1s   User is offline

  • D.I.C Lover
  • member icon

Reputation: 1397
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: Console Blackjack

Posted 10 July 2009 - 10:40 PM

Quote

That compiled and returned "Helo World!" BTW. That's why I thought it should work.
But it's still invalid behavior. It may work. It may not. Your program may crash. It may not. The behavior is undefined. It's not defined as "compiler error" or "crash" or anything else. This illusion of working behavior becomes even more troublesome in non-trivial programs, where undefined behavior can show up as odd, inexplicable, and unreproducable bugs. This program is faulty, and you need to recognize it.

Quote

I didn't "memorize an approach", I actually tried to think it out myself. It usually works.
But your defense of why code is correct is "because it worked once before" as opposed to citing the defined behavior of C++. You are utterly convinced your are correct, pointing to what you recall from before. Instead, I'm trying to force you towards understanding some fundamental principles in C++ like scope and object lifetime.

You can curl up into a defensive shell and brush me away. It's not my loss. But you will find yourself struggling to get complex programs working. You lose in the end if you don't view your own knowledge and your code critically.

Quote

Oh, also, your code wouldn't compile, it lacks a very simple feature that even the newest programmers don't forget, it obviously slipped your highly advanced mind.
Explain what makes my code syntactically invalid. Do you have compiler output from a standards conforming compiler? If my code won't compile, what error is your compiler throwing?
Was This Post Helpful? 0
  • +
  • -

#10 Speedy_92   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 57
  • Joined: 02-July 09

Re: Console Blackjack

Posted 11 July 2009 - 12:38 AM

....Was talking rubbish...

This post has been edited by Speedy_92: 11 July 2009 - 12:39 AM

Was This Post Helpful? 0
  • +
  • -

#11 chuck981996   User is offline

  • D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 119
  • Joined: 03-July 08

Re: Console Blackjack

Posted 11 July 2009 - 02:00 AM

View PostOler1s, on 10 Jul, 2009 - 09:40 PM, said:

Quote

That compiled and returned "Helo World!" BTW. That's why I thought it should work.
But it's still invalid behavior. It may work. It may not. Your program may crash. It may not. The behavior is undefined. It's not defined as "compiler error" or "crash" or anything else. This illusion of working behavior becomes even more troublesome in non-trivial programs, where undefined behavior can show up as odd, inexplicable, and unreproducable bugs. This program is faulty, and you need to recognize it.

Quote

I didn't "memorize an approach", I actually tried to think it out myself. It usually works.
But your defense of why code is correct is "because it worked once before" as opposed to citing the defined behavior of C++. You are utterly convinced your are correct, pointing to what you recall from before. Instead, I'm trying to force you towards understanding some fundamental principles in C++ like scope and object lifetime.

You can curl up into a defensive shell and brush me away. It's not my loss. But you will find yourself struggling to get complex programs working. You lose in the end if you don't view your own knowledge and your code critically.

Quote

Oh, also, your code wouldn't compile, it lacks a very simple feature that even the newest programmers don't forget, it obviously slipped your highly advanced mind.
Explain what makes my code syntactically invalid. Do you have compiler output from a standards conforming compiler? If my code won't compile, what error is your compiler throwing?


I'm sorry I was so rude before, I was in a bad mood... Your code didn't return anything in main... (like return 0;) Your right, I musn't have understood the concept properly, but I couldn't find anything documenting it. Your code did show errors.
Was This Post Helpful? 0
  • +
  • -

#12 Oler1s   User is offline

  • D.I.C Lover
  • member icon

Reputation: 1397
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: Console Blackjack

Posted 11 July 2009 - 12:15 PM

Quote

Your code didnít return anything in main... (like return 0;)
main is a special function. One characteristic is an exception in C++ that says if no return statement is encountered at the end of main, itís like having a return 0; at the end. So you can omit the return statement. I usually donít, but I kept the code short in my example.

Quote

I musnít have understood the concept properly, but I couldnít find anything documenting it.
Thatís why I brought up the terms scope and object lifetime. Searching for terms like ďC++ scopeĒ and ďC++ object lifetimeĒ will get you information. Ideally though, you should have a book that introduces these concepts properly. Itís possible your book introduces them a bit later.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1