Jump to content





Black Jack Theta VIII - update

Posted by azure, 15 August 2018 · 130 views

I've completed another small milestone with my project. Most of the updates aren't visible to the user, but I added a new message bar which I think looks a lot better than what was there before. The most significant update is the addition of the discard pile and reshuffling logic. The discard pile prevents duplicate cards from being dealt. A duplicate card in my game is two cards with the same deck, suit, and rank values.
 
The game is still minimal, but the basic play is working much better compared to the last update. The features so far include;

  • basic play for 1 player
  • 4 decks of cards
  • 6 on screen cards
  • cards pushed off screen are stored as a sum
  • tracking of discarded cards
  • deck penetration to 75%
  • reshuffle upon reaching 75%
  • message bar for prompts and win/loss results
  • status bar that displays player and dealer scores
  • event driven loop: it makes it easy to split computations across frames and greatly simplifies game logic
Joystick Controls:
  • Down for hit
  • Up for stand or start new game
  • Fire for start new game
Current Problems:
 
I'm running out of ROM space, so I've had to make significant changes in order to reduce ROM usage. I pushed many of my MACROs into subroutines to reduce repetitive code. The game is very light on the CPU, so I have plenty of CPU to work with. Subroutine overhead is not really an issue even within the kernel, because the gap spaces are available for computation. The player will be idle for 1 to 2 seconds before they make a move, so that gives me more than enough frames for computations.
 
I may have to switch to an 8K ROM if I want to keep most of the features I originally planned for. I will be adding sound and possibly some animations, so realistically that's not going work with my current 4K implementation. I really wanted to remain at 4K, so I'm going to dig deep into refactoring. The sprites can be compressed a little by overlapping whitespace., but more savings can be made by compressing the title screen's graphic. The title screen uses very little RAM and CPU, so decompressing it on the fly to RAM might work if I horizontally split the graphic into three smaller pieces with gaps in between. The gaps provide time for loading the next block.
 
Despite all that, I still think I will eventually end up going to 8K. Maybe I'll have a 4K version and an 8K enhanced version. I'm unsure.
 
As for RAM space, I've still got 25 bytes of RAM free. I'm thinking about cutting out the 2nd player option and reducing the on-screen cards to only 5. Those changes would free up 11 bytes. I'm using 8 bytes for the stack, so I could probably save 2 bytes there. I might be able to save another 3 to 6 bytes by merging a few variables and recalculating scores on the fly. The discard pile uses 26 bytes of RAM, which is at its minimum possible size.
 
I use 2 sets of sprite pointers for displaying the upper and lower halves of the cards. The 2nd set consumes an extra 12 bytes, so this has bothered me from the start, so I'll be thinking about how to free those bytes up. VDEL might work for me here, but I need to understand it better.
 
I had been thinking about supporting 6 and 8 decks of cards, but I can't currently do it, because it needs another 26 bytes of RAM and significant changes to the bit packing. I could support it by cutting out the 2nd player and the ability to split hands, but I'm prioritizing accurate game play, so I will be going ahead with split hands and only 4 decks.
 
There is some infrequent screen bounce that happens when the discard pile is close to 75% capacity. The problem is caused by my card dealing logic, which has to enter retry logic whenever the random number generator selects an already discarded card. I have a plan for fixing it, but it will require rewriting my card dealing routine.
 
I'm still not completely sure how I'm going to display the player's chips and how the betting mechanics are going to work. I have some ideas, but they're rudimentary. I'll be working on that part next along with refactoring the code to reclaim more ROM space.
 
Programming:
 
Here's a quick description of my discard pile's layout and how they're indexed by the cards.

 

The cards are represented as a byte.

 

 

;    card: single packed
;              deck   suit    rank
;       bits:  7 6    5 4    3 2 1 0
;
;       rank:     0 = empty card slot
;              1-13 = ranks ace through king
;             14-15 = unused

 

  
The discard pile is an array of 26 bytes. Each byte represents 8 cards and each nibble is a composite of deck and suit values. A card is flagged as discarded if its bit is set to 1.

 

The card's rank (low nibble) selects the row in the discard pile. The deck and suit (high nibble) select the bit within a row. Furthermore, bit 7 determines which row of decks the card belongs in. 
 
Shuffling the decks simply erases the discard pile and re-inserts cards from the player and dealer's currently active hands.
 
Bit assignments:

  • Diamonds: bit 0 or 4
  • Clubs: bit 1 or 5
  • Hearts: bit 2 or 6
  • Spades: bit 3 or 7
;                 suits             suits
;          |  S | H | C | D  |  S | H | C | D  |
; ---------|----|---|---|----|----|---|---|----|------
; byte|rank|  7 | 6 | 5 | 4  |  3 | 2 | 1 | 0  | index
; ----|----|----|---|---|----|----|---|---|----|------
;   1    A |.................|.................|  0
;   2    2 |.................|.................|  1
;   3    3 |.................|.................|  2
;   4    4 |.................|.................|  3
;   5    5 |.................|.................|  4
;   6    6 |..             ..|..             ..|  5
;   7    7 |.. Deck 1 (01) ..|.. Deck 0 (00) ..|  6
;   8    8 |..             ..|..             ..|  7
;   9    9 |.................|.................|  8
;  10   10 |.................|.................|  9
;  11    J |.................|.................| 10
;  12    Q |.................|.................| 11
;  13    K |.................|.................| 12
; ----|----|-----------------|-----------------|------
;  14    A |.................|.................| 13
;  15    2 |.................|.................| 14
;  16    3 |.................|.................| 15
;  17    4 |.................|.................| 16
;  18    5 |.................|.................| 17
;  19    6 |..             ..|..             ..| 18
;  20    7 |.. Deck 3 (11) ..|.. Deck 2 (10) ..| 19
;  21    8 |..             ..|..             ..| 20
;  22    9 |.................|.................| 21
;  23   10 |.................|.................| 22
;  24    J |.................|.................| 23
;  25    Q |.................|.................| 24
;  26    K |.................|.................| 25
; ----|----|----|---|---|----|----|---|---|----|------
; byte|rank|  7 | 6 | 5 | 4  |  3 | 2 | 1 | 0  | index
; ---------|----|---|---|----|----|---|---|----|------

Attached Thumbnails

  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image

Attached Files