2026-08-03 22:18:02 -05:00
|
|
|
;;; card-games.el --- Play card games (console + SVG) -*- lexical-binding: t; -*-
|
2026-06-23 19:34:36 -05:00
|
|
|
|
|
|
|
|
;; Copyright (C) 2026 Corwin Brust
|
|
|
|
|
|
|
|
|
|
;; Author: Corwin Brust <corwin@bru.st>
|
|
|
|
|
;; Maintainer: Corwin Brust <corwin@bru.st>
|
2026-07-01 14:32:32 -05:00
|
|
|
;; Version: 1.0.91
|
2026-06-23 19:34:36 -05:00
|
|
|
;; Package-Requires: ((emacs "26.1"))
|
|
|
|
|
;; Keywords: games
|
2026-06-23 21:56:31 -05:00
|
|
|
;; URL: https://code.bru.st/corwin/card-game.el
|
2026-06-23 19:34:36 -05:00
|
|
|
|
|
|
|
|
;; This program is free software; you can redistribute it and/or modify
|
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
;; This program is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; Card games for Emacs, rendered as UNICODE text in a terminal and as
|
|
|
|
|
;; SVG cards on a graphical display. This file is the umbrella: it
|
|
|
|
|
;; pulls in the individual games and offers a chooser.
|
|
|
|
|
;;
|
2026-08-03 23:21:57 -05:00
|
|
|
;; Run `M-x card-games' for a menu, or start a game directly:
|
2026-06-23 19:34:36 -05:00
|
|
|
;;
|
2026-08-03 23:21:57 -05:00
|
|
|
;; `card-games-bid' -- 500, the four-handed partnership trick-taking game,
|
2026-06-23 19:34:36 -05:00
|
|
|
;; played against three computer opponents.
|
2026-08-03 23:21:57 -05:00
|
|
|
;; `card-games-gaps' -- Gaps / Montana / "Hell's Half-Acre" solitaire.
|
2026-06-23 19:34:36 -05:00
|
|
|
;;
|
|
|
|
|
;; New games register themselves by adding to `card-games-list'.
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
2026-08-03 23:21:57 -05:00
|
|
|
(require 'card-games-core)
|
|
|
|
|
(require 'card-games-render)
|
|
|
|
|
(require 'card-games-net)
|
|
|
|
|
(require 'card-games-gaps)
|
|
|
|
|
(require 'card-games-bid-ui)
|
|
|
|
|
(require 'card-games-bid-net)
|
|
|
|
|
(require 'card-games-solitaire)
|
|
|
|
|
(require 'card-games-trick)
|
|
|
|
|
(require 'card-games-eights)
|
|
|
|
|
(require 'card-games-patience)
|
|
|
|
|
(require 'card-games-president)
|
|
|
|
|
(require 'card-games-rummy)
|
|
|
|
|
(require 'card-games-rum500)
|
|
|
|
|
(require 'card-games-handfoot)
|
|
|
|
|
(require 'card-games-match)
|
|
|
|
|
(require 'card-games-cribbage)
|
|
|
|
|
(require 'card-games-scopa)
|
|
|
|
|
(require 'card-games-trick-ext)
|
|
|
|
|
(require 'card-games-spite)
|
|
|
|
|
(require 'card-games-bridge)
|
|
|
|
|
(require 'card-games-crapette)
|
2026-06-23 19:34:36 -05:00
|
|
|
|
|
|
|
|
(defvar card-games-list
|
2026-08-03 23:21:57 -05:00
|
|
|
'(("500 (Bid)" card-games-bid
|
2026-06-23 19:34:36 -05:00
|
|
|
"Four-handed partnership trick-taking versus three AI opponents.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Gaps (Montana)" card-games-montana
|
2026-06-23 19:34:36 -05:00
|
|
|
"Solitaire: a Two anchors each row; build up 2 through King.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Hell's Half-Acre" card-games-hells-half-acre
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: a King anchors each row; build down King through 2.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Klondike" card-games-klondike
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: the classic; build the foundations up by suit from the Ace.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("FreeCell" card-games-freecell
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: every card in view, four free cells, a game of skill.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Spider" card-games-spider
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: two decks; build down and clear eight same-suit runs.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Yukon" card-games-yukon
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: Klondike's layout, all face up; move any buried group.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Hearts" card-games-hearts
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Trick-taking: dodge every heart and the Queen of Spades.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Spades" card-games-spades
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Trick-taking: partnership bidding to 500; spades are always trump.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Crazy Eights" card-games-eights
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Shedding: match the suit or rank; eights are wild.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Canfield" card-games-canfield
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: a 13-card reserve and a shifting foundation base rank.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Russian Bank" card-games-russian-bank
|
Add two-player Russian Bank (Crapette) vs the computer
* cg-crapette.el: new game on cg-core — eight foundations (up by suit,
two decks), eight shared houses (down, alternating colour), per-player
reserve/waste/hand; foundation priority; loading onto the opponent; a
greedy AI; text UI with cursor pick/drop, undo, and q-to-menu.
* card-games.el: require cg-crapette and add the chooser entry.
* Makefile (EL): add cg-crapette.el.
* test/card-games-tests.el: 5 ERT (deal, legality, win, AI turn, AI foundation).
2026-07-01 03:09:27 -05:00
|
|
|
"Solitaire: eight houses down by alternating colour; a reserve feeds them.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Forty Thieves" card-games-forty-thieves
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: two decks, ten columns, eight foundations, no redeal.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Scorpion" card-games-scorpion
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: build down by suit and free four buried King-to-Ace runs.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Golf" card-games-golf
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: clear the layout one rank at a time onto the waste.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("TriPeaks" card-games-tripeaks
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: clear three peaks with Ace-King wrapping chains.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Pyramid" card-games-pyramid
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Solitaire: remove pairs of cards that sum to thirteen.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Whist" card-games-whist
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Trick-taking: fixed trump, no bidding, race past the book of six.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Oh Hell" card-games-ohhell
|
Add 16 games and known-games research; bump to 1.0.60
Console UNICODE games on the cg-core EIEIO engine, all ERT-tested (88/88):
- Tableau solitaire (cg-solitaire.el): Klondike, FreeCell, Spider, Yukon,
Canfield, Forty Thieves, Scorpion.
- Pile solitaire (cg-patience.el): Golf, TriPeaks, Pyramid.
- Trick-taking (cg-trick.el): Hearts, Spades, Whist, Oh Hell.
- Shedding/climbing: Crazy Eights (cg-eights.el), President (cg-president.el).
Wire all into the card-game chooser, Makefile, and README; add
known-games.org research collation; bump every file to 1.0.60.
2026-06-25 01:58:24 -05:00
|
|
|
"Trick-taking: shrinking hands; bid the exact tricks you will take.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("President" card-games-president
|
Add the rummy family: meld engine + Gin, Rummy, Rummy 500, Hand & Foot
Introduce a shared meld engine and four games built on it, all on
cg-core/EIEIO with console UNICODE rendering.
* cg-rummy.el: the meld engine and Gin Rummy. Set/run validation,
candidate-meld enumeration, a bitmask-DP minimum-deadwood partition,
and a layoff finder, plus the abstract cg-rummy-game base and shared
render helpers. Gin is two-handed with draw/take/discard/knock, gin
and undercut bonuses, opponent layoffs, and play to 100.
* cg-rum500.el: the abstract cg-tablemeld-game (one mode and command
set, dispatching on the subclass) driving Basic Rummy (meld out;
score the cards left in other hands; to 100) and Rummy 500 (score the
cards you lay down, lose those left in hand; ace high and worth 15;
to 500).
* cg-handfoot.el: Hand & Foot, a partnership Canasta cousin. Hand and
foot packets, Twos and Jokers wild, rank books with clean/dirty piles,
go-out bonus, and partnership scoring to 5000. Deliberately
2026-06-25 05:53:02 -05:00
|
|
|
"Climbing: shed your hand; first out rules, last out scrubs.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Gin Rummy" card-games-gin
|
Add the rummy family: meld engine + Gin, Rummy, Rummy 500, Hand & Foot
Introduce a shared meld engine and four games built on it, all on
cg-core/EIEIO with console UNICODE rendering.
* cg-rummy.el: the meld engine and Gin Rummy. Set/run validation,
candidate-meld enumeration, a bitmask-DP minimum-deadwood partition,
and a layoff finder, plus the abstract cg-rummy-game base and shared
render helpers. Gin is two-handed with draw/take/discard/knock, gin
and undercut bonuses, opponent layoffs, and play to 100.
* cg-rum500.el: the abstract cg-tablemeld-game (one mode and command
set, dispatching on the subclass) driving Basic Rummy (meld out;
score the cards left in other hands; to 100) and Rummy 500 (score the
cards you lay down, lose those left in hand; ace high and worth 15;
to 500).
* cg-handfoot.el: Hand & Foot, a partnership Canasta cousin. Hand and
foot packets, Twos and Jokers wild, rank books with clean/dirty piles,
go-out bonus, and partnership scoring to 5000. Deliberately
2026-06-25 05:53:02 -05:00
|
|
|
"Rummy: form melds, knock with little deadwood; head to head to 100.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Rummy" card-games-rummy-basic
|
Add the rummy family: meld engine + Gin, Rummy, Rummy 500, Hand & Foot
Introduce a shared meld engine and four games built on it, all on
cg-core/EIEIO with console UNICODE rendering.
* cg-rummy.el: the meld engine and Gin Rummy. Set/run validation,
candidate-meld enumeration, a bitmask-DP minimum-deadwood partition,
and a layoff finder, plus the abstract cg-rummy-game base and shared
render helpers. Gin is two-handed with draw/take/discard/knock, gin
and undercut bonuses, opponent layoffs, and play to 100.
* cg-rum500.el: the abstract cg-tablemeld-game (one mode and command
set, dispatching on the subclass) driving Basic Rummy (meld out;
score the cards left in other hands; to 100) and Rummy 500 (score the
cards you lay down, lose those left in hand; ace high and worth 15;
to 500).
* cg-handfoot.el: Hand & Foot, a partnership Canasta cousin. Hand and
foot packets, Twos and Jokers wild, rank books with clean/dirty piles,
go-out bonus, and partnership scoring to 5000. Deliberately
2026-06-25 05:53:02 -05:00
|
|
|
"Rummy: meld your whole hand to the table to go out.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Rummy 500" card-games-rum500
|
Add the rummy family: meld engine + Gin, Rummy, Rummy 500, Hand & Foot
Introduce a shared meld engine and four games built on it, all on
cg-core/EIEIO with console UNICODE rendering.
* cg-rummy.el: the meld engine and Gin Rummy. Set/run validation,
candidate-meld enumeration, a bitmask-DP minimum-deadwood partition,
and a layoff finder, plus the abstract cg-rummy-game base and shared
render helpers. Gin is two-handed with draw/take/discard/knock, gin
and undercut bonuses, opponent layoffs, and play to 100.
* cg-rum500.el: the abstract cg-tablemeld-game (one mode and command
set, dispatching on the subclass) driving Basic Rummy (meld out;
score the cards left in other hands; to 100) and Rummy 500 (score the
cards you lay down, lose those left in hand; ace high and worth 15;
to 500).
* cg-handfoot.el: Hand & Foot, a partnership Canasta cousin. Hand and
foot packets, Twos and Jokers wild, rank books with clean/dirty piles,
go-out bonus, and partnership scoring to 5000. Deliberately
2026-06-25 05:53:02 -05:00
|
|
|
"Rummy: score the cards you lay down; race past 500.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Hand & Foot" card-games-handfoot
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Rummy: partnership Canasta cousin; build books from hand and foot.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Go Fish" card-games-go-fish
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Matching: ask for ranks and collect books of four.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Old Maid" card-games-old-maid
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Matching: shed pairs and avoid the leftover Queen.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Cribbage" card-games-cribbage
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Pegging and the show: fifteens, pairs, runs, and his nobs to 121.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Scopa" card-games-scopa
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Capturing: take table cards by value; sweep for a scopa.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Casino" card-games-casino
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Capturing: pairs and sums; big and little casino, aces, sweeps.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Euchre" card-games-euchre
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Trick-taking: 24 cards, bowers, order up; partnership to 10.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Pitch" card-games-pitch
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Trick-taking: bid, pitch to set trump, score High-Low-Jack-Game.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Briscola" card-games-briscola
|
Add nine games: Go Fish, Old Maid, Cribbage, Scopa, Casino,
Euchre, Pitch, Briscola, and Spite & Malice
Five new files, each reusing or extending an existing engine.
* cg-match.el: Go Fish and Old Maid, matching games on a shared
helper set (completes the original wishlist).
* cg-cribbage.el: two-handed Cribbage to 121 -- the crib, the cut,
pegging, and a full show scorer (fifteens, pairs, runs, flush, nobs).
* cg-scopa.el: a capture-by-sum engine driving Scopa (40-card, sette
bello, primiera, scopas) and Casino (pairs and sums, big/little
casino, aces, sweeps). Casino omits builds.
* cg-trick-ext.el: Euchre (24-card with both bowers), Auction Pitch
(bid, pitch sets trump, High/Low/Jack/Game), and Briscola (fixed
trump, no follow), as subclasses of the cg-trick engine.
* cg-spite.el: Spite & Malice, a competitive patience to empty the
goal pile onto shared Ace-to-Queen centre piles; Kings are wild.
Wire all nine commands into the card-game chooser, extend the Makefile
EL list, and add README sections. Add ten ERT tests covering each
game's engine and a full AI-driven game; the suite is now 107/107 and
every file byte-compiles cleanly.
New files at Version 1.0.60 to match the tree; post-1.0.60 work
toward 1.0.90.
2026-06-25 06:31:44 -05:00
|
|
|
"Trick-taking: fixed trump, no follow; capture the points to 61.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Spite & Malice" card-games-spite
|
Add Contract Bridge: auction, dummy play, and rubber scoring
New cg-bridge.el: a four-handed Bridge game (you are South, partnering
North against East and West) on the shared cg-game base.
* Auction: level/strain bids plus pass, double, and redouble, with the
three-pass end rule, pass-outs, doubling state, and declarer
determination (first of the side to name the strain).
* Play: follow-suit with the dummy exposed after the opening lead; the
declarer plays both hands. Trick resolution honours trump and no-trump.
* Scoring: classic rubber -- trick points below the line toward game;
overtricks, slam, insult, and undertrick penalties above; vulnerability
and the rubber bonus. Verified against known results.
* A small natural bidding AI (openings, NT, raises with a fit, simple
overcalls) that always terminates the auction, plus a greedy
card-play AI.
Wire cg-bridge into the chooser, the Makefile, and the README, and add
two ERT tests (scoring math and a dozen full AI-driven deals). The suite
is now 109/109 and every file byte-compiles cleanly.
2026-06-25 06:53:51 -05:00
|
|
|
"Climbing patience: race to empty your goal pile; Kings are wild.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Bridge" card-games-bridge
|
Add two-player Russian Bank (Crapette) vs the computer
* cg-crapette.el: new game on cg-core — eight foundations (up by suit,
two decks), eight shared houses (down, alternating colour), per-player
reserve/waste/hand; foundation priority; loading onto the opponent; a
greedy AI; text UI with cursor pick/drop, undo, and q-to-menu.
* card-games.el: require cg-crapette and add the chooser entry.
* Makefile (EL): add cg-crapette.el.
* test/card-games-tests.el: 5 ERT (deal, legality, win, AI turn, AI foundation).
2026-07-01 03:09:27 -05:00
|
|
|
"Trick-taking: the auction, the dummy, and rubber scoring, to 121.")
|
2026-08-03 23:21:57 -05:00
|
|
|
("Crapette (Russian Bank)" card-games-crapette
|
Add two-player Russian Bank (Crapette) vs the computer
* cg-crapette.el: new game on cg-core — eight foundations (up by suit,
two decks), eight shared houses (down, alternating colour), per-player
reserve/waste/hand; foundation priority; loading onto the opponent; a
greedy AI; text UI with cursor pick/drop, undo, and q-to-menu.
* card-games.el: require cg-crapette and add the chooser entry.
* Makefile (EL): add cg-crapette.el.
* test/card-games-tests.el: 5 ERT (deal, legality, win, AI turn, AI foundation).
2026-07-01 03:09:27 -05:00
|
|
|
"Two-player Russian Bank versus the computer; empty your reserve, hand, and waste."))
|
2026-06-23 19:34:36 -05:00
|
|
|
"Registry of playable games.
|
2026-08-03 23:21:57 -05:00
|
|
|
Each entry is (NAME COMMAND DESCRIPTION); `card-games' lists them.")
|
2026-06-23 19:34:36 -05:00
|
|
|
|
2026-07-01 11:46:00 -05:00
|
|
|
(defvar card-games--svg-card-vars
|
2026-08-03 23:21:57 -05:00
|
|
|
'(card-games-sol-svg-cards card-games-trick-svg-cards card-games-rummy-svg-cards card-games-eights-svg-cards
|
|
|
|
|
card-games-bridge-svg-cards card-games-crapette-svg-cards card-games-pat-svg-cards card-games-pres-svg-cards)
|
2026-07-01 11:46:00 -05:00
|
|
|
"Per-game SVG-cards toggles that `card-games-set-treatment' flips together.")
|
|
|
|
|
|
|
|
|
|
(defvar card-games--full-svg-vars
|
2026-08-03 23:21:57 -05:00
|
|
|
'(card-games-gaps-svg-ui card-games-bid-svg-ui)
|
2026-07-01 11:46:00 -05:00
|
|
|
"Full-window SVG toggles (Gaps and 500) used by the `full' treatment.")
|
|
|
|
|
|
|
|
|
|
(defvar card-games-treatment 'svg
|
|
|
|
|
"Display treatment chosen from the menu: `text', `svg', or `full'.")
|
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun card-games-set-treatment (treatment)
|
|
|
|
|
"Set how games are drawn: `text' (UNICODE), `svg' (cards), or `full'.
|
|
|
|
|
`full' also uses the full-window SVG table where a game has one (Gaps and
|
|
|
|
|
500). Takes effect the next time a game is drawn -- press g to redraw an
|
|
|
|
|
open game. Gaps and 500 are always graphical on a window system."
|
|
|
|
|
(interactive
|
|
|
|
|
(list (intern (completing-read "Treatment: " '("text" "svg" "full") nil t))))
|
|
|
|
|
(setq card-games-treatment treatment)
|
|
|
|
|
(let ((cards (and (memq treatment '(svg full)) t))
|
|
|
|
|
(full (and (eq treatment 'full) t)))
|
|
|
|
|
(dolist (v card-games--svg-card-vars) (when (boundp v) (set v cards)))
|
|
|
|
|
(dolist (v card-games--full-svg-vars) (when (boundp v) (set v full))))
|
|
|
|
|
(when (called-interactively-p 'interactive)
|
|
|
|
|
(message "Display treatment: %s" treatment)))
|
|
|
|
|
|
2026-08-03 23:21:57 -05:00
|
|
|
(defun card-games--cycle-treatment (_button)
|
2026-07-01 11:46:00 -05:00
|
|
|
"Cycle the display treatment and refresh the chooser."
|
|
|
|
|
(card-games-set-treatment
|
|
|
|
|
(pcase card-games-treatment ('text 'svg) ('svg 'full) (_ 'text)))
|
2026-08-03 23:21:57 -05:00
|
|
|
(card-games))
|
2026-07-01 11:46:00 -05:00
|
|
|
|
2026-08-03 23:21:57 -05:00
|
|
|
(defun card-games--cycle-ai (_button)
|
|
|
|
|
"Cycle the AI difficulty (`card-games-ai-level') and refresh the chooser."
|
|
|
|
|
(setq card-games-ai-level (pcase card-games-ai-level ('easy 'normal) ('normal 'hard) (_ 'easy)))
|
|
|
|
|
(card-games))
|
2026-07-01 11:40:55 -05:00
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun card-games-set-ai-level (level)
|
|
|
|
|
"Set the computer-opponent difficulty to LEVEL (easy, normal, or hard)."
|
|
|
|
|
(interactive
|
|
|
|
|
(list (intern (completing-read "AI level: " '("easy" "normal" "hard") nil t))))
|
2026-08-03 23:21:57 -05:00
|
|
|
(setq card-games-ai-level level)
|
2026-07-01 11:40:55 -05:00
|
|
|
(message "AI level: %s" level))
|
|
|
|
|
|
2026-08-03 23:21:57 -05:00
|
|
|
(defun card-games--launch (button)
|
2026-06-23 19:34:36 -05:00
|
|
|
"Start the game whose command is stored on BUTTON."
|
2026-08-03 23:21:57 -05:00
|
|
|
(let ((cmd (button-get button 'card-games-command)))
|
2026-06-23 19:34:36 -05:00
|
|
|
(quit-window)
|
|
|
|
|
(call-interactively cmd)))
|
|
|
|
|
|
2026-08-03 23:21:57 -05:00
|
|
|
(defvar card-games-mode-map
|
2026-06-23 19:34:36 -05:00
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(set-keymap-parent map special-mode-map)
|
|
|
|
|
(define-key map "n" #'forward-button)
|
|
|
|
|
(define-key map "p" #'backward-button)
|
|
|
|
|
(define-key map (kbd "TAB") #'forward-button)
|
|
|
|
|
(define-key map (kbd "<backtab>") #'backward-button)
|
|
|
|
|
map)
|
2026-08-03 23:21:57 -05:00
|
|
|
"Keymap for `card-games-mode'.")
|
2026-06-23 19:34:36 -05:00
|
|
|
|
2026-08-03 23:21:57 -05:00
|
|
|
(define-derived-mode card-games-mode special-mode "Card-Games"
|
|
|
|
|
"Major mode for the `card-games' chooser."
|
|
|
|
|
(setq-local cursor-type card-games-cursor-type))
|
2026-06-23 19:34:36 -05:00
|
|
|
|
|
|
|
|
;;;###autoload
|
2026-08-03 23:21:57 -05:00
|
|
|
(defun card-games ()
|
2026-06-23 19:34:36 -05:00
|
|
|
"Open a chooser listing the available card games.
|
|
|
|
|
Press RET (or click) on a game to start it."
|
|
|
|
|
(interactive)
|
2026-08-03 23:21:57 -05:00
|
|
|
(when (and (boundp 'card-games-svg-card-back) (eq card-games-svg-card-back 'random)
|
|
|
|
|
(fboundp 'card-games-svg--roll-back))
|
|
|
|
|
(card-games-svg--roll-back)) ; a fresh random back per menu visit
|
2026-06-23 19:34:36 -05:00
|
|
|
(let ((buf (get-buffer-create "*Card Games*")))
|
|
|
|
|
(with-current-buffer buf
|
2026-08-03 23:21:57 -05:00
|
|
|
(card-games-mode)
|
2026-06-23 19:34:36 -05:00
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(insert (propertize " Card Games for Emacs\n" 'face 'bold))
|
|
|
|
|
(insert (propertize
|
2026-07-01 11:40:55 -05:00
|
|
|
" Choose a game with RET or the mouse. q to quit.\n"
|
2026-06-23 19:34:36 -05:00
|
|
|
'face 'shadow))
|
2026-07-01 11:40:55 -05:00
|
|
|
(insert " AI opponents: ")
|
|
|
|
|
(insert-text-button
|
2026-08-03 23:21:57 -05:00
|
|
|
(symbol-name card-games-ai-level)
|
2026-07-01 11:40:55 -05:00
|
|
|
'face 'link
|
|
|
|
|
'help-echo "Click to change the AI difficulty (easy/normal/hard)"
|
2026-08-03 23:21:57 -05:00
|
|
|
'action #'card-games--cycle-ai)
|
2026-07-01 11:46:00 -05:00
|
|
|
(insert (propertize " (click to cycle easy/normal/hard)\n" 'face 'shadow))
|
|
|
|
|
(insert " Cards: ")
|
|
|
|
|
(insert-text-button
|
|
|
|
|
(symbol-name card-games-treatment)
|
|
|
|
|
'face 'link
|
|
|
|
|
'help-echo "Click to cycle the display: text / svg / full"
|
2026-08-03 23:21:57 -05:00
|
|
|
'action #'card-games--cycle-treatment)
|
2026-07-01 11:46:00 -05:00
|
|
|
(insert (propertize " (click to cycle text/svg/full)\n\n" 'face 'shadow))
|
2026-06-23 19:34:36 -05:00
|
|
|
(dolist (g card-games-list)
|
|
|
|
|
(insert " ")
|
|
|
|
|
(insert-text-button
|
|
|
|
|
(format "%-26s" (nth 0 g))
|
|
|
|
|
'face 'link
|
|
|
|
|
'help-echo (nth 2 g)
|
2026-08-03 23:21:57 -05:00
|
|
|
'card-games-command (nth 1 g)
|
|
|
|
|
'action #'card-games--launch)
|
2026-06-23 19:34:36 -05:00
|
|
|
(insert (propertize (concat " " (nth 2 g) "\n") 'face 'shadow)))
|
|
|
|
|
(insert "\n")))
|
|
|
|
|
(switch-to-buffer buf)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(forward-button 1)))
|
|
|
|
|
|
|
|
|
|
(defconst card-games-themes
|
|
|
|
|
'((classic :felt "#15692f" :theme t)
|
|
|
|
|
(dark :felt "#23272e" :back "#3b4252" :highlight "#88c0d0" :theme nil)
|
|
|
|
|
(contrast :felt "#0a0a0a" :back "#000000" :highlight "#ffd400" :theme nil))
|
|
|
|
|
"Named table/card colour presets for `card-games-set-theme'.")
|
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun card-games-set-theme (name)
|
|
|
|
|
"Apply the card-games colour preset NAME (see `card-games-themes')."
|
|
|
|
|
(interactive
|
|
|
|
|
(list (intern (completing-read
|
|
|
|
|
"Card-games theme: "
|
|
|
|
|
(mapcar (lambda (e) (symbol-name (car e))) card-games-themes)
|
|
|
|
|
nil t))))
|
|
|
|
|
(let ((p (alist-get name card-games-themes)))
|
|
|
|
|
(unless p (user-error "No such card-games theme: %s" name))
|
2026-08-03 23:21:57 -05:00
|
|
|
(setq card-games-bid-felt-color (plist-get p :felt))
|
2026-06-23 19:34:36 -05:00
|
|
|
(when (plist-member p :theme)
|
2026-08-03 23:21:57 -05:00
|
|
|
(setq card-games-svg-theme-colors (plist-get p :theme)))
|
|
|
|
|
(when (plist-get p :back) (setq card-games-svg-back-color (plist-get p :back)))
|
2026-06-23 19:34:36 -05:00
|
|
|
(when (plist-get p :highlight)
|
2026-08-03 23:21:57 -05:00
|
|
|
(setq card-games-svg-highlight-color (plist-get p :highlight)))
|
2026-06-23 19:34:36 -05:00
|
|
|
(message "card-games theme: %s" name)))
|
|
|
|
|
|
|
|
|
|
(provide 'card-games)
|
|
|
|
|
;;; card-games.el ends here
|