Card Game

Card Game

A lightweight “addition War” game in the browser. The UI uses Bootstrap 4 and jQuery for layout/interaction, while the game logic is plain JavaScript. Cards are rendered with Unicode playing-card glyphs, so no image sprites are required. Try it here: card game demo.

What it does

  • Deals two cards to the Dealer and two to the Player, sums each side, awards a point to the higher total, and plays to 10 points.
  • Scoring rule: 2–10 are face value; A, J, Q, K count as 10 in this version.
  • Click the deck or press Enter/Space to deal a round.

Implementation details

  • Unicode rendering: builds a list of HTML numeric entities for the playing-card block and excludes non-standard code points, producing clean suit/rank glyphs.
  • Deck model: suits × values become objects like { Value, Suit, cardImage }. Dealing uses random index + splice to remove cards so there are no repeats.
  • DOM updates: jQuery writes the glyphs into the page, colors hearts/diamonds red, and reveals cards with a slide animation.
  • Game flow: prepareGame() resets deck/hands each round start; evaluateScore() tallies and updates the scoreboard; a Bootstrap modal announces “Game Over” at 10 points and the scores reset.

Why it’s interesting

  • Tiny footprint and fast load: Unicode glyphs replace image assets.
  • Clear example of JS state + DOM manipulation + keyboard interaction with minimal dependencies.
  • The deck/Unicode approach is reusable for other card mechanics or ed‑tech demos.

Snippet: Unicode deck + scoring

const suits = ["spades", "hearts", "diamonds", "clubs"];
const values = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"];
const EXCLUDE = new Set([148,151,152,164,167,168,180,183,184,196]); // skip non-standard glyphs
const BASE = 136, PREFIX = "&#127";

function buildDeck() {
	const cardImages = [];
	for (let i = 0; i < 63; i++) {
		const code = BASE + i;
		if (!EXCLUDE.has(code)) cardImages.push(`${PREFIX}${code}`);
	}
	const deck = [];
	let imageIndex = 1; // aligns with glyph ordering used in the demo
	for (const suit of suits) {
		for (const value of values) {
			deck.push({ Value: value, Suit: suit, cardImage: cardImages[imageIndex++] });
		}
	}
	return deck;
}

function cardValue(card) {
	const i = values.indexOf(card.Value);
	return (i < 1 || i > 9) ? 10 : parseInt(card.Value, 10);
}

Ideas to extend

  • Replace the simple swap shuffle with Fisher–Yates.
  • Add “best of N,” streaks, and localStorage high scores.
  • Expand keyboard controls and add subtle animations.