KAZIK/tools/tests/blackjack_party_test.inc
Artvasil09 881a0061dc Add native NPC visitors with contracts, Clover slots, Pyramid, and party table scenes
Implement 32x32 BFS visitor navigation and daily contracts system with companion .npc journals; add native assembly scenes for Clover slots, Pyramid cards, Blackjack Party and Russian Party; package animation and sprite packs; add comprehensive offline test suites and rebuild shipping binaries.
2026-10-13 09:47:33 +03:00

364 lines
9.6 KiB
PHP

; Native state-machine regression. Tests never write the real player's profile.
.data
bjPartySeenLo dd 0
bjPartySeenHi dd 0
bjPartySeenCount dd 0
bjPartyShot1 db "build\actions\blackjack-party-1.bmp",0
bjPartyShot2 db "build\actions\blackjack-party-2.bmp",0
bjPartyShot3 db "build\actions\blackjack-party-3.bmp",0
bjPartyShots dd OFFSET bjPartyShot1,OFFSET bjPartyShot2,OFFSET bjPartyShot3
bjPartyFlightShot db "build\actions\blackjack-party-flight.bmp",0
bjPartyResultShot db "build\actions\blackjack-party-result.bmp",0
bjPartyExitShot db "build\actions\blackjack-party-exit.bmp",0
.code
CheckBJPartyHand3D PROC uses ebx esi hand:DWORD,count:DWORD
mov esi,hand
cmp count,2
jb bj_party_hand_bad
cmp count,12
ja bj_party_hand_bad
xor ebx,ebx
bj_party_hand_card:
mov eax,[esi+ebx*4]
cmp eax,52
jae bj_party_hand_bad
cmp eax,32
jb bj_party_hand_low
sub eax,32
bts bjPartySeenHi,eax
jc bj_party_hand_bad
jmp bj_party_hand_next
bj_party_hand_low:
bts bjPartySeenLo,eax
jc bj_party_hand_bad
bj_party_hand_next:
inc bjPartySeenCount
inc ebx
cmp ebx,count
jb bj_party_hand_card
xor eax,eax
ret
bj_party_hand_bad:
mov eax,8104
ret
CheckBJPartyHand3D ENDP
RunBJPartyTest3D PROC uses ebx esi edi
local rounds:DWORD,ticks:DWORD,savedBank:DWORD,savedSeed:DWORD,savedCursor:DWORD,fixtureSeed:DWORD
mov engineMode,MODE_BLACKJACK
mov cbBet3D,100
mov cbBotCount3D,0
call InitNativeBlackjack3D
cmp cbPartyArt3D.pixels,0
je bj_party_fail_art
cmp cbPartyRoom3D.pixels,0
je bj_party_fail_art
; Real mouse selection; changing seats resets the displayed hand, not money.
mov bankroll,10000
mov mouseClick3D,1
mov mouseX3D,270
mov mouseY3D,40
call BJPartyInput3D
cmp cbBotCount3D,2
jne bj_party_fail_input
cmp mouseClick3D,0
jne bj_party_fail_input
cmp bankroll,10000
jne bj_party_fail_input
call StartNativeBlackjack3D
invoke SetBJPartyCount3D,3
cmp cbBotCount3D,2
jne bj_party_fail_input
cmp cbCursor3D,8
jne bj_party_fail_deck
cmp bankroll,9900
jne bj_party_fail_wallet
; A bot decision may see its own total and the dealer's upcard, nothing else.
mov cbBots3D.score,16
mov cbBots3D.count,2
mov cbDealer3D,4
invoke BJBotDecision3D,0
mov savedCursor,eax
mov cbDealer3D[4],12
mov cbPlayer3D,51
mov cbDeck3D[120],33
invoke BJBotDecision3D,0
cmp eax,savedCursor
jne bj_party_fail_hidden
mov cbBots3D[SIZEOF BJBot3D].score,18
mov cbBots3D[SIZEOF BJBot3D].count,2
invoke BJBotDecision3D,1
cmp eax,1
jne bj_party_fail_hidden
mov cbBots3D[SIZEOF BJBot3D*2].score,13
mov cbBots3D[SIZEOF BJBot3D*2].count,2
invoke BJBotDecision3D,2
test eax,eax
jnz bj_party_fail_hidden
; Natural beats a drawn 21, but a dealer natural beats a drawn guest 21.
mov cbBotCount3D,3
mov cbBotsSettled3D,0
mov cbDealerScore3D,21
mov cbDealerCount3D,2
mov cbBots3D.score,21
mov cbBots3D.count,2
mov cbBots3D[SIZEOF BJBot3D].score,21
mov cbBots3D[SIZEOF BJBot3D].count,3
mov cbBots3D[SIZEOF BJBot3D*2].score,22
call ResolveBJParty3D
cmp cbBots3D.outcome,2
jne bj_party_fail_wallet
cmp cbBots3D[SIZEOF BJBot3D].outcome,1
jne bj_party_fail_wallet
cmp cbBots3D[SIZEOF BJBot3D*2].outcome,1
jne bj_party_fail_wallet
mov cbDealerCount3D,3
mov cbBotsSettled3D,0
call ResolveBJParty3D
cmp cbBots3D.outcome,3
jne bj_party_fail_wallet
; Run 200 full rounds with each party size, alternating hits and doubles.
mov edi,1
bj_party_test_size:
mov cbBotCount3D,edi
mov rounds,200
bj_party_test_round:
mov eax,rounds
imul eax,2137
add eax,edi
mov rngSeed3D,eax
mov bankroll,10000
mov cbState3D,CB_IDLE
mov engineMode,MODE_BLACKJACK
call StartNativeBlackjack3D
mov eax,edi
add eax,2
shl eax,1
cmp cbCursor3D,eax
jne bj_party_fail_deck
mov ticks,0
mov deltaTime3D,50
bj_party_test_tick:
cmp cbState3D,CB_RESULT
je bj_party_test_result
cmp cbState3D,CB_PLAYER
jne bj_party_test_handle
mov pressedKeys3D[53h],1
cmp cbPlayerScore3D,16
jae @F
mov pressedKeys3D[53h],0
mov pressedKeys3D[48h],1
@@:
cmp cbPlayerCount3D,2
jne bj_party_test_handle
test rounds,1
jz bj_party_test_handle
mov pressedKeys3D[44h],1
bj_party_test_handle:
call HandleNativeBlackjack3D
call ClearKeys3D
cmp cbBotCount3D,edi
jne bj_party_fail_input
cmp cbCursor3D,52
ja bj_party_fail_deck
inc ticks
cmp ticks,2000
jae bj_party_fail_stuck
jmp bj_party_test_tick
bj_party_test_result:
mov eax,10000
sub eax,cbStake3D
cmp cbOutcome3D,1
je bj_party_expected
add eax,cbStake3D
cmp cbOutcome3D,2
je bj_party_expected
add eax,cbStake3D
cmp cbOutcome3D,3
jne bj_party_expected
mov edx,cbStake3D
shr edx,1
add eax,edx
bj_party_expected:
cmp bankroll,eax
jne bj_party_fail_wallet
mov savedBank,eax
invoke NativeBJSettle3D,cbOutcome3D
mov eax,savedBank
cmp bankroll,eax
jne bj_party_fail_wallet
mov bjPartySeenLo,0
mov bjPartySeenHi,0
mov bjPartySeenCount,0
invoke CheckBJPartyHand3D,OFFSET cbPlayer3D,cbPlayerCount3D
test eax,eax
jnz bj_party_test_done
invoke CheckBJPartyHand3D,OFFSET cbDealer3D,cbDealerCount3D
test eax,eax
jnz bj_party_test_done
xor ebx,ebx
bj_party_check_guests:
mov esi,ebx
imul esi,SIZEOF BJBot3D
add esi,OFFSET cbBots3D
cmp [esi].BJBot3D.state,BJ_BOT_DONE
jne bj_party_fail_stuck
cmp [esi].BJBot3D.outcome,3
ja bj_party_fail_wallet
invoke CheckBJPartyHand3D,esi,[esi].BJBot3D.count
test eax,eax
jnz bj_party_test_done
inc ebx
cmp ebx,edi
jb bj_party_check_guests
mov eax,bjPartySeenCount
cmp cbCursor3D,eax
jne bj_party_fail_deck
xor ebx,ebx
bj_party_check_prefix:
mov eax,cbDeck3D[ebx*4]
cmp eax,32
jb @F
sub eax,32
bt bjPartySeenHi,eax
jnc bj_party_fail_deck
jmp bj_party_prefix_next
@@:
bt bjPartySeenLo,eax
jnc bj_party_fail_deck
bj_party_prefix_next:
inc ebx
cmp ebx,cbCursor3D
jb bj_party_check_prefix
dec rounds
jnz bj_party_test_round
cmp edi,3
jne @F
call RenderNativeBlackjack3D
invoke WriteActionSnapshot3D,OFFSET bjPartyResultShot
@@:
; Actual framebuffer for each seat count, then repeat without state changes.
mov cbState3D,CB_IDLE
mov bankroll,10000
call StartNativeBlackjack3D
mov cbState3D,CB_PLAYER
mov eax,cbInitialFlights3D
imul eax,TABLE_FLIGHT_MS
mov cbTimer3D,eax
mov eax,rngSeed3D
mov savedSeed,eax
mov eax,cbCursor3D
mov savedCursor,eax
mov eax,bankroll
mov savedBank,eax
call RenderNativeBlackjack3D
mov eax,edi
dec eax
invoke WriteActionSnapshot3D,bjPartyShots[eax*4]
mov ebx,8
bj_party_render_repeat:
call RenderNativeBlackjack3D
dec ebx
jnz bj_party_render_repeat
mov eax,savedSeed
cmp rngSeed3D,eax
jne bj_party_fail_render
mov eax,savedCursor
cmp cbCursor3D,eax
jne bj_party_fail_render
mov eax,savedBank
cmp bankroll,eax
jne bj_party_fail_render
inc edi
cmp edi,4
jb bj_party_test_size
; Player bust does not prematurely end or hide the other guests' turns.
invoke FinishBJPlayer3D,1
cmp cbState3D,CB_BOTS
jne bj_party_fail_stuck
; Choose a genuine deal that needs a guest card for the animation capture.
mov fixtureSeed,1001
bj_party_find_flight:
mov eax,fixtureSeed
mov rngSeed3D,eax
mov cbState3D,CB_IDLE
mov bankroll,10000
call StartNativeBlackjack3D
cmp cbPlayerScore3D,21
je bj_party_next_fixture
cmp cbDealerScore3D,21
je bj_party_next_fixture
cmp cbBots3D.score,17
jb bj_party_flight_found
bj_party_next_fixture:
inc fixtureSeed
cmp fixtureSeed,1101
jae bj_party_fail_stuck
jmp bj_party_find_flight
bj_party_flight_found:
invoke FinishBJPlayer3D,-1
mov deltaTime3D,50
mov cbBotTimer3D,BJ_PARTY_MS
call UpdateBJParty3D
cmp cbBots3D.state,BJ_BOT_FLIGHT
jne bj_party_fail_stuck
mov cbBotTimer3D,180
call RenderNativeBlackjack3D
invoke WriteActionSnapshot3D,OFFSET bjPartyFlightShot
; Confirmation pauses bot timers; leaving counts once as player's loss.
call RequestCardExit3D
cmp cardExitActive3D,1
jne bj_party_fail_input
mov savedCursor,180
call HandleNativeBlackjack3D
cmp cbBotTimer3D,180
jne bj_party_fail_input
call RenderNativeBlackjack3D
invoke WriteActionSnapshot3D,OFFSET bjPartyExitShot
mov eax,bankroll
mov savedBank,eax
mov pressedKeys3D[59h],1
call HandleNativeBlackjack3D
cmp engineMode,MODE_WALK
jne bj_party_fail_input
mov eax,savedBank
cmp bankroll,eax
jne bj_party_fail_wallet
mov engineMode,MODE_BLACKJACK
; A result table can return to solo by keyboard, without another settlement.
mov pressedKeys3D[30h],1
call BJPartyInput3D
cmp cbBotCount3D,0
jne bj_party_fail_input
cmp cbState3D,CB_IDLE
jne bj_party_fail_input
cmp cbPlayerCount3D,0
jne bj_party_fail_input
mov eax,savedBank
cmp bankroll,eax
jne bj_party_fail_wallet
xor eax,eax
ret
bj_party_fail_art:
mov eax,8101
ret
bj_party_fail_input:
mov eax,8102
ret
bj_party_fail_wallet:
mov eax,8103
ret
bj_party_fail_deck:
mov eax,8104
ret
bj_party_fail_hidden:
mov eax,8105
ret
bj_party_fail_stuck:
mov eax,8106
ret
bj_party_fail_render:
mov eax,8107
bj_party_test_done:
ret
RunBJPartyTest3D ENDP