mirror of
https://github.com/imjasonh/nescript
synced 2026-07-09 17:28:00 +00:00
A complete, playable port of the card game War: title screen with 0/1/2 player menu, animated deal, sliding cards, deck-count HUD, a "WAR!" tie-break with buried cards, and a victory screen with a fanfare. Source split across examples/war/*.ne (constants, assets, audio, deck/queue logic, RNG, render helpers, and one state file per game state) and pulled in via examples/war.ne. Drives nearly every NEScript subsystem at once: custom 88-tile sprite sheet (card frames, ranks, suits, font, BIG WAR letters); felt background nametable; pulse-1 / pulse-2 / noise sfx; looping march on pulse 2; an 8-bit Galois LFSR PRNG; queue-based decks that conserve cards across rounds; a phase machine inside the Playing state that handles draw/reveal/win/war/check; and an autopilot that boots straight into 0-PLAYERS mode so the headless jsnes harness captures real gameplay at frame 180. While building this I uncovered five compiler bugs / limitations in the v0.1 implementation; each is documented with a minimal reproduction, root cause, current workaround, and proposed fix in examples/war/COMPILER_BUGS.md. The most painful was the parameter-VarId aliasing one (#1b) — two functions sharing a parameter NAME end up sharing a single zero-page slot mapping across the whole program. Once those compiler bugs are fixed, the workarounds in war/*.ne should be reverted in the same PR. https://claude.ai/code/session_0143dTgh3UeRrtfHgQwzcv5z
30 lines
817 B
Text
30 lines
817 B
Text
// war/compare.ne — card rank/suit extraction and round resolution.
|
|
//
|
|
// Cards are packed as `(rank << 4) | suit`; the extractors are
|
|
// one shift or one mask each.
|
|
//
|
|
// Parameter names are unique across the entire program — see
|
|
// COMPILER_BUGS.md §1b for why same-named params in different
|
|
// functions silently corrupt each other through shared VarIds.
|
|
|
|
inline fun card_rank(crk_c: u8) -> u8 {
|
|
return crk_c >> 4
|
|
}
|
|
|
|
inline fun card_suit(csu_c: u8) -> u8 {
|
|
return csu_c & 0x0F
|
|
}
|
|
|
|
// Compare two cards by rank. Returns:
|
|
// 1 if A wins, 2 if B wins, 0 if they tie
|
|
fun compare_cards(cmp_a: u8, cmp_b: u8) -> u8 {
|
|
var cmp_ra: u8 = card_rank(cmp_a)
|
|
var cmp_rb: u8 = card_rank(cmp_b)
|
|
if cmp_ra > cmp_rb {
|
|
return 1
|
|
}
|
|
if cmp_rb > cmp_ra {
|
|
return 2
|
|
}
|
|
return 0
|
|
}
|