Can you beat my Neural Network at Blackjack?
Flecko

Well, since I never post anything meaningful, I thought I'd show you guys something I made for my final project in Neural Networks at my final year of college. (Keep in mind I hate college, and carry no huge amount of pride in this project.)

Anyways, the basic premise is this. You play blackjack versus a dealer (or optionally, you can watch 2 neural networks duke it out versus the dealer) with a set rule. The dealer will hit if he has less than 17, and stand if he has more than 17, and more than or equal to your total. Player 1 is a reinforcement learning neural network(buzzword!!) that has been trained 10,000 iterations before the game even starts. You play as player 2 and try to keep up.

Knowing the odds of the game of blackjack, this came out pretty interesting really. Maybe its boring to you guys, I mean...its just blackjack.

Oh, and yes, I hand made all the cards...the Queen card has my face on it, and the King card has my partners face on it.

Download here: Blackjack

Screenshot: http://www.zerolust.com/flecko/files/blackjack.png

And YESSS...the source is included. As well as our presentation slides...if you're interested. Anywho, let me know what you guys think of it.

Lastly, no whining abut the download size, the fact that I didn't use packfiles, or that I included the allegro dll. Its 880k, suck it up.

And thanks everyone for keeping the allegro community alive, I love this place.
-Flecko

kazzmir

there were a whole bunch of programming errors in it, things like passing NULL instead of 0 for player.hit(), and things like this:

for ( int i = 0; i < 2; i++ ){
...
}
for ( i = 0; i < 3; i++ ){
}

you only declared i in the first for loop, not the second. For some reason, I have seen a bunch of people doing that. Are you using MSVC? It obviously produces terrible coding practices..

The most notable hack I had to perform was changing

temp=(int) 52 * rand() / (RAND_MAX + 1);

to this
temp = (int)( rand() % 52 );
rand() returns an integer, you dont have to divide it by RAND_MAX or multiply by 52.

[edit]one more important hack, this code

deck = new BITMAP**[13];
for(int i = 0;i<14;i++)

needs to be

deck = new BITMAP**[13];
for(int i = 0;i<13;i++)

After alot of hacking, I eventually got it to run but it locked up after one game. I got tired of debugging so Im not going to try to complete an entire game.

What exactly do you need a "neural network" for? Doesnt the AI just consist of hitting under 17 and staying over 17?

Flecko

>:(

Man, i'm sorry it didn't run well kazzmir. I normally use Dev-cpp for my stuff...so I'm more ANSI compatible, but my partner used msvc for all his NN code (I did the allegro stuff) and he did use some rather sloppy-ish code that led to hours of debugging on my part.

So I take it you're running under linux and can't get it to run?

My linux partition was recently hacked (thats what I get for running an old kernel) so I was planning on building/testing it this weekend.

Is there anyone who is running winows and can just test the included exe?

Don't worry, I haven't forgotenn our gcc* bretheren, I just have a boatload of finals to take tomorrow.
Rock on,
-Flecko

CGamesPlay

Are you saying you have a backprop network trained to hit below 17? That doesn't sound too great... If it had leared its own threshold, then yeah, it would be a lot better. Anyways, I have too much homework to test that just now, sorry :)

Bruce Perry
for (int i = 0; i < 10; i++) { ... }
for (i = ...

is not a "terrible coding practice". It is legacy from the days before C++ was standardised. And yes, MSVC 6 accepts that code and rejects the 'correct' alternative.

If you use MSVC 6, or you think your users might, you can get around it with

#define for if (0) ; else for

Maybe the neural network also gauges what risk to take according to the other player's situation. I don't know the rules. :)

"19." "Hit me." "20." "Hit me." "21." "Hit me." "22."

"D'oh!"

Inphernic

A simplified Blackjack dealer. :)

#define dealer_limit      17
#define dealer_variance       2

if (dealer_variance)
  dealer_current_limit=dealer_limit+(rand()%(dealer_risk*2))-dealer_risk;
else dealer_current_limit=dealer_limit;

if (player_hand>dealer_hand) dealer_hit();
else if (dealer_hand<=dealer_current_limit) dealer_hit();
else dealer_pass();

Rick
Quote:

for ( int i = 0; i < 2; i++ ){
...
}
for ( i = 0; i < 3; i++ ){
}

There is nothing wrong with this. Since in C++ you can declare variables anywhere (doesn't have to be the first statements in a function). If you declare it again in the second for you get an error. It's really not a big deal.

Mars

No, if it's in the for loop, it's only valid for the for loop. At least in standard C++.

Variable definitions are only valid for the block they are contained in, it doesn't matter if the block is a whole function or not. However, this is yet another differnt case, because the definition is somehow mangled into the for loop initialization. That's why it wasn't totally clear before the standardization -- you have to define what it is valid for.

Oscar Giner

Guys, read his first post. The dealer doesn't use a neural network, is the other player who uses a neural network for tha AI. And it plays quite well. I played this last night and IIRC the dealer won 18, the NN AI won 36 and I won 38.

Evert
Quote:

The most notable hack I had to perform was changing
temp=(int) 52 * rand() / (RAND_MAX + 1);

to this
temp = (int)( rand() % 52 );

The original was better.

Rick
Quote:

No, if it's in the for loop, it's only valid for the for loop.

A block is noted by { }, and since the initialization isn't inside the for loops { }, it's not part of the for loop.

Oscar Giner

Nope, the standard says that the variable declared there is only available inside the loop. gcc does that correctly, MSVC6 doesn't.

Krzysztof Kluczek
Quote:

temp=(int) 52 * rand() / (RAND_MAX + 1);

Doesn't it assume that RAND_MAX*52 fits in int range? It doesn't have to work if it's not true although idea is better than % operator.

Quote:

Nope, the standard says that the variable declared there is only available inside the loop. gcc does that correctly, MSVC6 doesn't.

And this code is perfectly fine: ;D

for(int i=0;i<10;i++)
  for(int i=0;i<10;i++)
    for(int i=0;i<10;i++)
      for(int i=0;i<10;i++)
        for(int i=0;i<10;i++)
          do_something_100000_times();

Quote:

things like passing NULL instead of 0 for player.hit()

This is fine for me. I know that you are supposed to use 0 in C++, but NULL is much more readable and it would be really surprising if NULL wasn't defined as 0. ;)

Rick

So since I use MSVC and do this the wrong way, will someone who tries to compile it using another get an error?

Oscar Giner
Quote:

And this code is perfectly fine:

yup, the problem comes when you do this:

for (int i=0; i<10; i++)
    do_something();

for (int i=0; i<10; i++)
    do_something();

it should compile, but it doesn't with MSVC6.

Problem is, if you try this:

for (int i=0; i<10; i++)
    do_something();

for (i=0; i<10; i++)
    do_something();

Now it won't compile with mingw:

 name lookup of `i' changed for new ISO `for' scoping
   using obsolete binding at `i'

Rick

sucks to be whoever tries to compile my programs not using MSVC6 :)

Krzysztof Kluczek

It seems that best solution is to just use:

int i;

for (i=0; i<10; i++)
    do_something();

for (i=0; i<10; i++)
    do_something();

:)

Oscar Giner

Yeah, that's what I always do :)

CGamesPlay

Or, having read the thread like good little boys, you would have seen the#define for if(0); else for, Which causes the variable to be in it's own scope.

Bruce Perry

What's wrong with my suggestion? Namely

#define for if (0) ; else for

Guys, stop flaming MSVC6. I assume it was released before the relevant C++ standard.

[EDIT]
CGames, have a ★ :)
(Poll: who can see that character? It's supposed to be a star. I see it in Mozilla but not in Konqueror.)

Chris Katko
Quote:

And this code is perfectly fine:

for(int i=0;i<10;i++)
for(int i=0;i<10;i++)
for(int i=0;i<10;i++)
for(int i=0;i<10;i++)
for(int i=0;i<10;i++)
do_something_100000_times();

That wouldn't kill MSVC6 because each one is in the next scope, right?

What I'm seeing is MSVC6 doing this:

{
/*scopeA*/

for(int x, ...) //x is a part of scopeA
{
/*scopeB*/
for(int y, ...){ /*scopeC*/} //y is a part of scopeB
}

}

Is that correct?

Quote:

yup, the problem comes when you do this:

for (int i=0; i<10; i++)
do_something();

for (int i=0; i<10; i++)
do_something();

it should compile, but it doesn't with MSVC6.

Well... true. Unless if you apply the patches that have been around for years. In which case, MSVC6 works fine with the exception of C99 support (which it never had to begin with). Unless I'm forgetting something.

Bruce Perry

Patches? News to me. Even less excuse for people to flame Microsoft! ;D

Boy will I be unpopular.

Thomas Fjellstrom

Its still way out of date. And is likely out of MSs support phase.

Chris Katko
Oscar Giner
Quote:

Well... true. Unless if you apply the patches that have been around for years. In which case, MSVC6 works fine with the exception of C99 support

Ah, the patches solve that? I know it fails with an unpatched MSVC, but I never tried it again, when I updated.

Thomas Fjellstrom

Chris: When was that released?

Oscar Giner

Thomas, they already have released 5 or 6 patches. I'd say more than a year since the last one.

Thomas Fjellstrom

And now that MSVC.NET has been released, they'll probably not release much of anything for MSVC6, just like with what they do for windows itself. 95 is out of support, and 98 is on the way out.

CGamesPlay

Etwinox: That is how MSVC handles it, and that is the wrong way to handle it :)

Flecko

I'm sorry for the "MSVC 6" only code.

I don't wanna play the blame game here, but my partner did alot of the coding with "tricky" stuff like you're all seeing.

I plan on cleaning it all up and have it be able to compile under linux/gcc and windows/dev-cpp.

And just so everyone knows, the dealer uses a flat rule, and the players use a reinforcement rule NN that is trained to 10,000 iterations before the game starts.

Thats all, I'm glad that its generating this much talk...although I wish less of the talk was on the poor code ;D
-Flecko

Thread #357986. Printed from Allegro.cc