Card Images

K

Ken Smith

I have a little video poker game I created in Javascript.
It uses Tables and inner html stuff - for example: (psudo-code)

imagePicked=random card image (2h.gif);
getElementById(cellNum).innerHTML="<img src='imagePicked'>";

I use small 1k.gif images for the cards.
Sometimes on the net the 1k.gifs take a while to load & kills bandwith
traffic.

Is there a way to load 53(52 + 1 back-of-card image) images into memory
before game starts for a 1 time load?

then use the getElementById(cellNum) example above?

I've tried even displaying all cards on screen during game play, but it does
nothing.

Thanx in advance
 
N

Nathan White

I wrote a simple Blackjack engine as an exercise a while back, I
elimiated the need for graphics altogether by using css to format my
cards. The css solved a lot of these issue and made it faster, this way
I could store my cards as simple js arrays and whenever I needed to
display a card I had a wrapper object that created the html code that
was injected into the correct place.

here is a sample of my css, and a few cards. I know it may have a few
browser compatibilty issues, but that was not my goal.

<html>
<head>
<title></title>

<style type="text/css">

..red {
color: Red;
}

..card {
position: relative;
float: left;
margin: 3px 3px 3px 3px;
width: 90px;
height: 120px;
border: 1px solid black;
overflow: hidden;
}

..top, .bottom {
position: relative;
font: bold 18px Arial;
padding: 1px 3px 1px 3px;
width: 100%;
}

..bottom {

text-align: right;
margin-left: -6px;
}

..suit {
font: 48px "Gill Sans Ultra Bold";
width: 100%;
text-align: center;
}
</style>


</head>

<body>

<div class="card">
<div class="top">3</div>

<div class="suit">&spades;</div>
<div class="bottom">3</div>
</div>

<div class="card red">
<div class="top">A</div>
<div class="suit">&hearts;</div>
<div class="bottom">A</div>
</div>

<div class="card">
<div class="top">10</div>
<div class="suit">&clubs;</div>
<div class="bottom">10</div>
</div>

</body>
</html>
 
L

Lee

Ken Smith said:
I have a little video poker game I created in Javascript.
It uses Tables and inner html stuff - for example: (psudo-code)

imagePicked=random card image (2h.gif);
getElementById(cellNum).innerHTML="<img src='imagePicked'>";

I use small 1k.gif images for the cards.
Sometimes on the net the 1k.gifs take a while to load & kills bandwith
traffic.

Is there a way to load 53(52 + 1 back-of-card image) images into memory
before game starts for a 1 time load?

then use the getElementById(cellNum) example above?

I've tried even displaying all cards on screen during game play, but it does
nothing.

Pre-loading images is very common and examples should be easy to find.
It's much more efficient to change images by modifying the src attribute
of the existing image than to change innerHTML:

<html>
<head>
<title>demo</title>
<script type="text/javascript">
srcList=[ "http://www.azphx.com/dhtml/tmp/alpha6464.jpg",
"http://www.azphx.com/dhtml/tmp/beta6464.jpg",
"http://www.azphx.com/dhtml/tmp/gamma6464.jpg",
"http://www.azphx.com/dhtml/tmp/delta6464.jpg"
];
imgList=[];
for(var i=0;i<srcList.length;i++) {
imgList=new Image(64,64);
imgList.src=srcList;
}
function changeImg() {
shuffle(imgList);
for (var i=1;i<4;i++) {
document.images["c"+i].src=imgList.src;
}
}
function shuffle(deck) {
for (var i=0;i<deck.length;i++) {
var j=Math.floor(Math.random()*(i+1));
var t=deck;
deck=deck[j];
deck[j]=t;
}
}
</script>
</head>
<body onload="changeImg()">
<table border>
<tr>
<td><img name="c1"
src="http://www.azphx.com/dhtml/tmp/blank.gif"
width="64"
height="64"></td>
<td><img name="c2"
src="http://www.azphx.com/dhtml/tmp/blank.gif"
width="64"
height="64"></td>
<td><img name="c3"
src="http://www.azphx.com/dhtml/tmp/blank.gif"\
width="64"
height="64"></td>
</tr>
</table>
<button onclick="changeImg()">Change IMG sources</button>
</body>
</html>
 
A

ASM

Ken said:
I have a little video poker game I created in Javascript.
It uses Tables and inner html stuff - for example: (psudo-code) [snip]
Is there a way to load 53(52 + 1 back-of-card image) images into memory
before game starts for a 1 time load?

do an external stylesheet with your 53 images

td { empty-cells: show; width: 15px; height: 15px;}
..i00 { background: url(1a.gif) center center no-repeat; }
..i01 { background: url(1b.gif) center center no-repeat; }
..i02 { background: url(1c.gif) center center no-repeat; }
.... / ...
..i52 { background: url(6x.gif) center center noreapeat; }

do a JS

// array of cards
Cards = 'i01,i02,i03, ... etc ... ,i52';
Cards = Cards.split(',');
// array of cells to display cards
Board = document.getElementById('cardsBoard');
Board = Board.getElementsBytagName('TD');
function playCards() {
your function to radomize and sort array 'Cards'
then
for(i=0;i<53;i++) {
Board.className = Cards;
}
}

<table id="cardsBoard">
<tr>
<td></td>
<td></td>
<td></td>


perhaps will you need a transparent gif image in each cell

<table id="cardsBoard">
<tr>
<td><img src="empty.gif"></td>
<td><img src="empty.gif"></td>
<td><img src="empty.gif"></td>
 
R

RobG

Nathan said:
I wrote a simple Blackjack engine as an exercise a while back, I
elimiated the need for graphics altogether by using css to format my
cards. The css solved a lot of these issue and made it faster, this way
I could store my cards as simple js arrays and whenever I needed to
display a card I had a wrapper object that created the html code that
was injected into the correct place.

Wouldn't it have been easier to have the cards as DOM objects that you
move about? Then you only need deal with position, z-index and
display/visibility so no messing with HTML at all.
here is a sample of my css, and a few cards. I know it may have a few
browser compatibilty issues, but that was not my goal.

Neat.

[...]
 
N

Nathan White

Wouldn't it have been easier to have the cards as DOM objects that you
move about? Then you only need deal with position, z-index and
display/visibility so no messing with HTML at all.

Rob,

actually that is what I have done, but to deal with the card logic of
shuffling the deck and dealing the cards its easiers when they are in a
more pure form. Only worrying about the card image once it needs to be
displayed.

To create a deck I use this function:

function Deck () {
var S,N,A,j,i,v;
S=["H","D","C","S"];
N=[2,3,4,5,6,7,8,9,10,"J","Q","K","A"];
A= new Array();
for(j=0;j<S.length;j++)
{
for(i=0;i<N.length;i++)
{
v = (i >= 8)?( (i == 12)? 1 : 10 ): N;
A[A.length]= {suit: S[j], card:N,val:v};
}
}
return A;
}

I have a Game object:

function Game () {
var self = this;
this.type = 'blackjack';
this.you = new Player(this,'you');
this.dealer = new Player(this,'dealer');
this.deck = Deck();
}

which contains my deck and player objects and to shuffle I do:

Game.prototype.shuffle= function(times){
var i,j,t,v,l=this.deck.length;
while(times--){
with(Math){i=floor(random()*l);j=floor(random()*l);}
t=this.deck;this.deck=this.deck[j];this.deck[j]=t;
}
return this.deck;
}

And calculating player hand is much easier with the array like so:

Player.prototype.Calculate = function() {
var t=0,a=0,i,h=this.hand,l=this.hand.length,v=new Array();
for (i=0;i<l;i++){
if (h.val != 1) t += h.val;
else { a++ }
}
if ( a > 0 ) t = ( (t+(a-1)+11)>21)?(t+a):(t+(a-1)+11);
return t;
}

finally to render a card I just do:

function _toCard (suit, card) {
var c, s,html,top,bottom,glyph;
switch (suit)
{
case 'H': c = 'red'; s = '\u2665'; break;
case 'D': c = 'red'; s = '\u2726'; break;
case 'C': c = 'black'; s = '\u2663'; break;
case 'S': c = 'black'; s = '\u2660'; break;
}
html = document.createElement('DIV');
html.className = 'card '+c;

top = document.createElement('DIV');
top.appendChild( document.createTextNode( card ) );
top.className = 'top';
html.appendChild( top );

glyph = document.createElement('DIV');
t = document.createTextNode(s);
glyph.appendChild( t );
glyph.className = 'suit';
html.appendChild( glyph );

bottom = document.createElement('DIV');
bottom.appendChild( document.createTextNode( card ) );
bottom.className = 'bottom';
html.appendChild( bottom );
return html;
}

I am not saying it is perfect but it seperates presentational logic,
and allowed me to accomplish a full blackjack game with css/js/html in
under 8k.
 
R

RobG

Nathan said:
Rob,

actually that is what I have done, but to deal with the card logic of
shuffling the deck and dealing the cards its easiers when they are in a
more pure form. Only worrying about the card image once it needs to be
displayed.

To create a deck I use this function:

You may find the following faster ('modern' machines will not notice,
but older ones may...)
function Deck () {
var S,N,A,j,i,v;
S=["H","D","C","S"];
N=[2,3,4,5,6,7,8,9,10,"J","Q","K","A"];

var V=[2,3,4,5,6,7,8,9,10,10,10,10,1];
A= new Array();
for(j=0;j<S.length;j++)
{
for(i=0;i<N.length;i++)
{
v = (i >= 8)?( (i == 12)? 1 : 10 ): N;
A[A.length]= {suit: S[j], card:N,val:v};
}
}


A = [];
j = S.length;
do {
i = N.length;
do {
A[--i]= {suit: S[--j], card:N, val:V};
} while ( i );
} while ( j );


Fewer look-ups and no ifs - it may help (or not...).
return A;
}

I have a Game object:

function Game () {
var self = this;
this.type = 'blackjack';
this.you = new Player(this,'you');
this.dealer = new Player(this,'dealer');
this.deck = Deck();
}

which contains my deck and player objects and to shuffle I do:

Game.prototype.shuffle= function(times){
var i,j,t,v,l=this.deck.length;
while(times--){
with(Math){i=floor(random()*l);j=floor(random()*l);}

You could use a bitwise OR to do the truncation faster than Math.floor
and it saves a few more keystrokes...

i = (Math.random()*l) | 0;
j = (Math.random()*l) | 0;
t=this.deck;this.deck=this.deck[j];this.deck[j]=t;
}
return this.deck;
}

And calculating player hand is much easier with the array like so:

Player.prototype.Calculate = function() {
var t=0,a=0,i,h=this.hand,l=this.hand.length,v=new Array();
for (i=0;i<l;i++){
if (h.val != 1) t += h.val;
else { a++ }
}
if ( a > 0 ) t = ( ( t+(a-1)+11)>21 )? (t+a) : (t+(a-1)+11);
return t;
}

finally to render a card I just do:


I'll take a guess that you include a reference to the card object in
your deck object, then to place a card you just put it inside a hand
object that knows where to display it - the hand object could also know
how to report its value.
function _toCard (suit, card) { [...]
return html;
}

I am not saying it is perfect but it seperates presentational logic,
and allowed me to accomplish a full blackjack game with css/js/html in
under 8k.

I've played a chess game that was done in pure JS & CSS in under 3k - I
couldn't beat the darn thing!
 
D

Dr John Stockton

JRS: In article <[email protected]>
, dated Wed, 27 Jul 2005 21:18:23, seen in
Nathan White said:
and to shuffle I do:

Game.prototype.shuffle= function(times){
var i,j,t,v,l=this.deck.length;
while(times--){
with(Math){i=floor(random()*l);j=floor(random()*l);}
t=this.deck;this.deck=this.deck[j];this.deck[j]=t;
}
return this.deck;
}


(A) Better not to use l as a variable name in code for others to see; l
looks much like 1 in many fonts.

(B) You use a "with" to cover two uses of "Math"; but you do not use a
"with" for four instances of "this".

(C) Neglecting imperfections in Math.random :
(a) starting with a fixed distribution, your code cannot give all
results with equal probability;
(b) you have the problem of determining a good value of "times", one
that neither under-shuffles nor wastes time.

Knuth has written; why use an inferior method? See FAQ and sig below.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,277
Latest member
VytoKetoReview

Latest Threads

Top