11import { getPokerStateForStep } from "./components/getRepeatedPokerStateForStep" ;
22import { acpcCardToDisplay , suitSVGs } from "./components/utils" ;
3+ import poker_chip_1 from "./images/poker_chip_1.svg" ;
4+ import poker_chip_5 from "./images/poker_chip_5.svg" ;
5+ import poker_chip_10 from "./images/poker_chip_10.svg" ;
6+ import poker_chip_25 from "./images/poker_chip_25.svg" ;
7+ import poker_chip_100 from "./images/poker_chip_100.svg" ;
38
49export function renderer ( options ) {
10+ const chipImages = {
11+ 1 : poker_chip_1 ,
12+ 5 : poker_chip_5 ,
13+ 10 : poker_chip_10 ,
14+ 25 : poker_chip_25 ,
15+ 100 : poker_chip_100
16+ } ;
17+
518 const elements = {
619 gameLayout : null ,
720 pokerTableContainer : null ,
@@ -13,6 +26,7 @@ export function renderer(options) {
1326 playerInfoAreas : [ ] ,
1427 playerThumbnails : [ ] ,
1528 dealerButton : null ,
29+ chipStacks : [ ] ,
1630 diagnosticHeader : null ,
1731 stepCounter : null
1832 } ;
@@ -85,6 +99,9 @@ export function renderer(options) {
8599 border-radius: 240px;
86100 pointer-events: none;
87101 z-index: 1;
102+ display: flex;
103+ align-items: center;
104+ justify-content: center;
88105 }
89106 .players-container {
90107 position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 10;
@@ -222,15 +239,67 @@ export function renderer(options) {
222239 outline: 2px solid #20BEFF;
223240 left: 320px
224241 }
225- .dealer-button.dealer-player0 { bottom : 170px; }
226- .dealer-button.dealer-player1 { top : 170px; }
242+ .dealer-button.dealer-player0 { top : 170px; }
243+ .dealer-button.dealer-player1 { bottom : 170px; }
227244 .step-counter {
228245 position: absolute; top: 12px; right: 12px; z-index: 20;
229246 background-color: rgba(60, 64, 67, 0.9); color: #ffffff;
230247 padding: 6px 12px; border-radius: 6px;
231248 font-size: 14px; font-weight: 600;
232249 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
233250 }
251+ .chip-stack {
252+ position: absolute;
253+ display: flex;
254+ flex-direction: row;
255+ align-items: center;
256+ gap: 12px;
257+ z-index: 12;
258+ pointer-events: none;
259+ left: 50%;
260+ transform: translateX(-50%);
261+ }
262+ .chip-stack.chip-stack-player0 {
263+ top: 60px;
264+ }
265+ .chip-stack.chip-stack-player1 {
266+ bottom: 60px;
267+ }
268+ .chip-stack-chips {
269+ display: flex;
270+ flex-direction: row-reverse;
271+ align-items: flex-end;
272+ justify-content: center;
273+ gap: 8px;
274+ position: relative;
275+ }
276+ .chip-denomination-stack {
277+ display: flex;
278+ flex-direction: column-reverse;
279+ align-items: center;
280+ position: relative;
281+ }
282+ .chip {
283+ width: 40px;
284+ height: 40px;
285+ position: relative;
286+ margin-bottom: -34px;
287+ filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
288+ }
289+ .chip:first-child {
290+ margin-bottom: 0;
291+ }
292+ .chip img {
293+ width: 100%;
294+ height: 100%;
295+ display: block;
296+ }
297+ .chip-stack-label {
298+ color: #FFFFFF;
299+ font-size: 18px;
300+ font-weight: bold;
301+ white-space: nowrap;
302+ }
234303 ` ;
235304
236305 function _injectStyles ( passedOptions ) {
@@ -277,6 +346,51 @@ export function renderer(options) {
277346 return cardDiv ;
278347 }
279348
349+ function updateChipStack ( chipStackElement , betAmount ) {
350+ if ( betAmount <= 0 ) {
351+ chipStackElement . style . display = 'none' ;
352+ return ;
353+ }
354+
355+ chipStackElement . style . display = 'flex' ;
356+ const chipsContainer = chipStackElement . querySelector ( '.chip-stack-chips' ) ;
357+ const labelElement = chipStackElement . querySelector ( '.chip-stack-label' ) ;
358+
359+ chipsContainer . innerHTML = '' ;
360+ labelElement . textContent = betAmount ;
361+
362+ // Break down bet into denominations (100, 25, 10, 5, 1)
363+ const denominations = [ 100 , 25 , 10 , 5 , 1 ] ;
364+ let remaining = betAmount ;
365+ const chipCounts = [ ] ;
366+
367+ for ( const denom of denominations ) {
368+ const count = Math . floor ( remaining / denom ) ;
369+ if ( count > 0 ) {
370+ chipCounts . push ( { denom, count : Math . min ( count , 5 ) } ) ; // Max 5 of each denomination
371+ remaining -= count * denom ;
372+ }
373+ }
374+
375+ // Render chips separated by denomination (highest to lowest, left to right)
376+ chipCounts . forEach ( ( { denom, count } ) => {
377+ const denomStack = document . createElement ( 'div' ) ;
378+ denomStack . className = 'chip-denomination-stack' ;
379+
380+ for ( let i = 0 ; i < count ; i ++ ) {
381+ const chip = document . createElement ( 'div' ) ;
382+ chip . className = 'chip' ;
383+ const img = document . createElement ( 'img' ) ;
384+ img . src = chipImages [ denom ] ;
385+ img . alt = `${ denom } chip` ;
386+ chip . appendChild ( img ) ;
387+ denomStack . appendChild ( chip ) ;
388+ }
389+
390+ chipsContainer . appendChild ( denomStack ) ;
391+ } ) ;
392+ }
393+
280394 // --- Board Parsing and Rendering ---
281395 function _ensurePokerTableElements ( parentElement , passedOptions ) {
282396 if ( ! parentElement ) return false ;
@@ -310,6 +424,20 @@ export function renderer(options) {
310424 muckLine . className = 'muck-line' ;
311425 elements . pokerTable . appendChild ( muckLine ) ;
312426
427+ // Create chip stacks for each player inside the table
428+ elements . chipStacks = [ ] ;
429+ for ( let i = 0 ; i < 2 ; i ++ ) {
430+ const chipStack = document . createElement ( 'div' ) ;
431+ chipStack . className = `chip-stack chip-stack-player${ i } ` ;
432+ chipStack . style . display = 'none' ;
433+ chipStack . innerHTML = `
434+ <div class="chip-stack-chips"></div>
435+ <div class="chip-stack-label">0</div>
436+ ` ;
437+ elements . pokerTable . appendChild ( chipStack ) ;
438+ elements . chipStacks . push ( chipStack ) ;
439+ }
440+
313441 const communityArea = document . createElement ( 'div' ) ;
314442 communityArea . className = 'community-cards-area' ;
315443 elements . pokerTable . appendChild ( communityArea ) ;
@@ -510,6 +638,11 @@ export function renderer(options) {
510638 } ) ;
511639 }
512640
641+ // Update chip stacks on the table
642+ if ( elements . chipStacks [ index ] ) {
643+ updateChipStack ( elements . chipStacks [ index ] , playerData . currentBet ) ;
644+ }
645+
513646 // Update info area (right side)
514647 const playerInfoArea = elements . playerInfoAreas [ index ] ;
515648 if ( playerInfoArea ) {
0 commit comments