{"id":29910357,"url":"https://github.com/nielssp/csol","last_synced_at":"2025-12-30T09:26:19.077Z","repository":{"id":147044595,"uuid":"85507934","full_name":"nielssp/csol","owner":"nielssp","description":"A small collection of solitaire/patience games (Klondike, FreeCell, Spider, Yukon, etc.) to play in the terminal","archived":false,"fork":false,"pushed_at":"2023-11-03T15:54:41.000Z","size":507,"stargazers_count":41,"open_issues_count":0,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2023-11-03T16:40:16.388Z","etag":null,"topics":["c","card-game","dos","dosgame","ncurses","pdcurses","solitaire","solitaire-game","terminal","terminal-game","tty-game","tui","tui-game"],"latest_commit_sha":null,"homepage":"https://nielssp.dk/csol/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nielssp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-03-19T20:54:07.000Z","updated_at":"2023-09-13T17:42:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"e0369a44-0fb0-455e-b828-3d63e10d9bf2","html_url":"https://github.com/nielssp/csol","commit_stats":null,"previous_names":[],"tags_count":8,"template":null,"template_full_name":null,"purl":"pkg:github/nielssp/csol","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nielssp%2Fcsol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nielssp%2Fcsol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nielssp%2Fcsol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nielssp%2Fcsol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nielssp","download_url":"https://codeload.github.com/nielssp/csol/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nielssp%2Fcsol/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268322385,"owners_count":24231817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","card-game","dos","dosgame","ncurses","pdcurses","solitaire","solitaire-game","terminal","terminal-game","tty-game","tui","tui-game"],"created_at":"2025-08-02T01:02:27.555Z","updated_at":"2025-12-30T09:26:19.043Z","avatar_url":"https://github.com/nielssp.png","language":"C","funding_links":[],"categories":["\u003ca name=\"games\"\u003e\u003c/a\u003eGames","Table of Contents"],"sub_categories":[],"readme":"# csol\n\nA small collection of solitaire games implemented in C using ncurses.\n\n![csol](csol.png)\n\n## Usage\n\nCompile and run:\n```\ncmake .\nmake\n./csol\n```\n\n## Games\n\nKlondike (default): `csol klondike`\n\n![Klondike](images/klondike.png)\n\nYukon: `csol yukon`\n\n![Yukon](images/yukon.png)\n\nEight Off: `csol eightoff`\n\n![Eight Off](images/eightoff.png)\n\nFreecell: `csol freecell`\n\n![Freecell](images/freecell.png)\n\nRussian Solitaire: `csol russian`\n\n![Russian Solitaire](images/russian.png)\n\nYukon Freecell: `csol yukonfc`\n\n![Yukon Freecell](images/yukonfc.png)\n\nKlondike Freecell: `csol klondikefc`\n\n![Klondike Freecell](images/klondikefc.png)\n\nSpider 1 Suit: `csol spider1`\n\n![Spider 1 Suit](images/spider1.png)\n\nSpider 2 Suits: `csol spider2`\n\n![Spider 2 Suits](images/spider2.png)\n\nSpider 4 Suits: `csol spider4`\n\n![Spider 4 Suits](images/spider4.png)\n\nGolf: `csol golf`\n\n![Golf](images/golf.png)\n\n## Themes\n\n`csol -t default`\n\n`csol -t default-xl`\n\n![default-xl](images/default-xl.png)\n\n`csol -t ascii`\n\n![ascii](images/ascii.png)\n\n`csol -t compact`\n\n![compact](images/compact.png)\n\n`csol -t compact-ascii`\n\n![compact-ascii](images/compact-ascii.png)\n\n`csol -t ultracompact`\n\n![ultracompact](images/ultracompact.png)\n\n`csol -t corners`\n\n![corners](images/corners.png)\n\n## Options\n\n* `--version`/`-v`: Show version\n* `--help`/`-h`: Show help\n* `--list`/`-l`: List games\n* `--themes`/`-T`: List themes\n* `--theme \u003cname\u003e`/`-t \u003cname\u003e`: Use a theme\n* `--mono`/`-m`: Disable colors\n* `--seed \u003cseed\u003e`/`-s \u003cseed\u003e`: Seed the prng\n* `--config \u003cfile\u003e`/`-c \u003cfile\u003e`: Use a configuration file\n* `--colors`/`-C`: List colors available in the current terminal\n* `--scores`/`-S`: Show stats for all games.\n* `--scores \u003cgame\u003e`/`-S \u003cgame\u003e`: Show history of all scores in a game.\n\n## Keys\n\nMove the cursor using \u003ckbd\u003eH\u003c/kbd\u003e, \u003ckbd\u003eJ\u003c/kbd\u003e, \u003ckbd\u003eK\u003c/kbd\u003e, and \u003ckbd\u003eL\u003c/kbd\u003e or the arrow keys.\n\nMove the cursor to the leftmost position using \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eH\u003c/kbd\u003e or \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003e←\u003c/kbd\u003e.\n\nMove the cursor to the rightmost position using \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eL\u003c/kbd\u003e or \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003e→\u003c/kbd\u003e.\n\nMove the cursor to the bottom of the current pile using \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eJ\u003c/kbd\u003e or \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003e↓\u003c/kbd\u003e.\n\nMove the cursor to the top of the current pile using \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eK\u003c/kbd\u003e or \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003e↑\u003c/kbd\u003e.\n\nSelect the card under the cursor using \u003ckbd\u003eSpace\u003c/kbd\u003e.\n\nMove the selected card to the tableau or foundaton under the cursor using \u003ckbd\u003eM\u003c/kbd\u003e or \u003ckbd\u003eEnter\u003c/kbd\u003e.\n\nIf the card under the cursor is already selected, pressing \u003ckbd\u003eSpace\u003c/kbd\u003e again will move the card to a foundation or a free cell if possible.\n\nPress \u003ckbd\u003eA\u003c/kbd\u003e to automatically move a card (from any tableau or cell) to a foundation if possible.\n\nPress \u003ckbd\u003eS\u003c/kbd\u003e to move a card from the stock to the waste or redeal if stock is empty.\n\nPress \u003ckbd\u003eW\u003c/kbd\u003e to move a card from the waste to the pile under the cursor.\n\nPress \u003ckbd\u003e1\u003c/kbd\u003e \u0026ndash; \u003ckbd\u003e9\u003c/kbd\u003e to move a card from a cell to the tableau or foundation under cursor.\n\nPress \u003ckbd\u003eU\u003c/kbd\u003e or \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eZ\u003c/kbd\u003e to undo one or more moves.\n\nPress \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eU\u003c/kbd\u003e, \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eY\u003c/kbd\u003e, or \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eR\u003c/kbd\u003e to redo.\n\nPress \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eS\u003c/kbd\u003e to toggle smart cursor.\n\nPress \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eV\u003c/kbd\u003e to toggle vertical stabilization for smart cursor.\n\nPress \u003ckbd\u003eEsc\u003c/kbd\u003e to clear the current selection.\n\nPress \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eL\u003c/kbd\u003e to redraw the screen.\n\nPress \u003ckbd\u003eR\u003c/kbd\u003e to play a new game.\n\nPress \u003ckbd\u003eQ\u003c/kbd\u003e to quit.\n\n## Mouse\n\nIn terminals with mouse support it's possible to select cards using the left mouse button (same as \u003ckbd\u003eSPACE\u003c/kbd\u003e) and to move cards using the right mouse button (same as \u003ckbd\u003eM\u003c/kbd\u003e).\n\n## Configuration\n\nThe system-wide configuration file is `/etc/xdg/csol/csolrc` with games in `/etc/xdg/csol/games` and themes in `/etc/xdg/csol/themes`.\n\ncsol will use `$XDG_CONFIG_HOME/csol/csolrc` or `$HOME/.config/csol/csolrc` instead if one of them exists. The `include`-command can be used to include the system-wide-configuration file. An example of a simple configuration file:\n\n```\ninclude /etc/xdg/csol/csolrc\ndefault_game yukon\ndefault_theme default-xl\nscores 1\nstats 1\nscores_file scores.csv\nstats_file stats.csv\nsmart_cursor 0\nkeep_vertical_position 0\nalt_cursor 0\n```\n\nThe `theme_dir` and `game_dir` commands can be used to lazily load theme and game configuration files from a directory.\n\nThe `scores` command enables or disables the use of CSV file to record all scores. `scores_file` can be used to set the file path of the scores file.\n\nThe `stats` command enables or disables the use of CSV file to keep track of total game time and the best scores for each game. `stats_file` can be used to set the file path of the stats file.\n\nOn Linux the default location for `scores.csv` and `stats.csv` is either `$XDG_DATA_HOME/csol/` or `$HOME/.local/share/csol/`. On DOS and Windows the default location is the same directory as `csol.exe`.\n\nThe `smart_cursor` command toggles an alternative cursor movement scheme that always places the cursor on a card. `keep_vertical_position` is used in conjunction with the smart cursor, if it's set to 1, then the cursor won't move vertically when moving left and right.\n\n`alt_cursor` switches between two styles of cursor:\n\n`alt_cursor 0` uses the normal block cursor. Depending on the terminal and color scheme it may be hard to spot:\n\n![alt_cursor 0](images/alt-cursor-0.png)\n\n`alt_cursor 1` uses the new default cursor:\n\n![alt_cursor 1](images/alt-cursor-1.png)\n\n### Themes\n\nThemes are defined with the `theme`-command:\n\n```\ntheme {\n  name test\n  title \"Test theme\"\n  heart   ♥\n  spade   ♠\n  diamond ♦\n  club    ♣\n  width 6\n  height 4\n  x_spacing 2\n  y_spacing 1\n  x_margin 2\n  y_margin 1\n  color my_green 0 500 0\n  bg my_green\n  fg black\n  empty {\n    top    ┌────┐\n    middle │    │\n    bottom └────┘\n    fg white\n    bg my_green\n  }\n  back {\n    top    ┌────┐\n    middle │    │\n    bottom └────┘\n    fg white\n    bg blue\n  }\n  red {\n    top    ┌────┐\n    middle │    │\n    bottom └────┘\n    fg red\n    bg white\n  }\n  black {\n    top    ┌────┐\n    middle │    │\n    bottom └────┘\n    fg black\n    bg white\n  }\n}\n```\n\n`heart`/`spade`/`diamond`/`club` are used to set the symbols used for the different suits.\n\n`width`/`height` are used to set the size of a card.\n\n`x_spacing`/`y_spacing` are used to set the horizontal/vertical spacing between cards.\n\n`x_margin` sets the distance between the left side of the terminal and the first card.\n\n`y_margin` sets the distance between the top of the terminal and the first card.\n\n`rank` followed by a number between 1 and 13 and a symbol redefines the symbol used for a rank.\n\n`utf8` can be set to 0 if the theme doesn't use UTF8 encoding.\n\n`empty`/`back`/`red`/`black` are used to set the characters used to draw cells and the back and front of cards.\n\n`text`-blocks can be placed inside layout-blocks (`empty`, `back` etc.) to add text:\n\n```\ntext {\n  format suit_rank\n  x -1\n  y -1\n  align left\n}\n```\n\n`format` is one of `suit_rank`, `rank_suit`, `rank`, `suit`, or `none` (default).\n\nIf `x` is negative, the x-position will be calculated as `width + x`.\n\nIf `y` is negative, the y-position will be calculated as `height + x`.\n\n`align right` can be used to right align the printed text such that the right-most character is printed on `x`.\n\n#### Colors\n\n`fg` and `bg` are used to set the foreground and background colors used to draw the background and cards.\nThe two commands expect a color index or a color name. The colors assigned to each index depends on the terminal and color scheme of the terminal, but often the values 0\u0026ndash;7 are assigned to black, red, green, yellow, blue, magenta, cyan and white and the values 8\u0026ndash;15 are assigned to brighter versions of those colors.\n\nThe following named default colors are available: `default`, `black`, `blue`, `green`, `cyan`, `red`, `magenta`, `yellow`, `white`, `bright_black`, `bright_blue`, `bright_green`, `bright_cyan`, `bright_red`, `bright_magenta`, `bright_yellow`, and `bright_white`.\n\nIn some terminals it is also possible to redefine colors using the `color`-command. This command takes 4 arguments. The first arguments is either the index of a color to redefine or a name, the following three arguments are the red/green/blue values for the color in the range 0\u0026ndash;1000.\n\n### Games\n\nGames are defined using the `game`-command:\n\n```\ngame {\n  name klondike\n  title Klondike\n  repeat 4 {\n    foundation {\n      x 3+\n      first_rank a\n      next_suit same\n      next_rank up\n    }\n  }\n  repeat 7 {\n    tableau {\n      y 1\n      x 0+\n      deal 1+\n      hide -1\n      first_rank k\n      next_suit diff_color\n      next_rank down\n      move_group group\n    }\n  }\n  stock {\n    deal 52\n  }\n  waste {\n    x 1\n    from stock\n  }\n}\n```\n\nThe command `decks` specified how many decks of cards are used in the game (default is 1).\n\nThe command `deck_suits` specifies which suits are used in a deck. The suits are identified by a letter, e.g. `deck_suits hs` matches hearts and spades.\n\nThere are four types of rule-blocks that can be used inside a `game`-block: `foundation`, `tableau`, `stock`, and `waste`.\n\nThe `repeat` command can be used to repeat a game rule. Inside a `repeat`-block it's possible to use expressions of the form `INIT+INCREMENT` where `INIT` is the value used for the first iteration. Before each additional iteration `INCREMENT` (optional, 1 by default) is added to the value.\nThe following example creates three cells with the (x, y) values (0, 2), (1, 4), and (2, 6):\n\n```\nrepeat 3 {\n  cell {\n    x 0+\n    y 2+2\n  }\n}\n```\n\n#### Game rules\n\nThe following command can be used in a rule block:\n\n* `x`: horizontal position of the pile (default: 0).\n* `y`: vertical position of the pile (default: 0).\n* `deal`: number of cards to initially deal to the pile, `rest` can be used to deal remaining cards from deck (default: 0).\n* `redeal`: maximum number of redeals (for `stock`-pile). -1 for unlimited (default -1).\n* `hide`: number of cards to initially deal face-down. If the number is negative, i.e. `hide -n`, then all cards are hidden except the top n cards (default 0).\n* `first_rank`: rank of first card in pile (see below for possible values) (default: `ace` if foundation, `none` if stock, `any` otherwise).\n* `first_suit`: suit of first card in pile (see below for possible values) (default: `same` if foundation, `none` if stock, `any` otherwise).\n* `next_rank`: rank of next card in pile (see below for possible values) (default: `up` if foundation, `down` if tableau, `none` if stock or cell, `any` otherwise).\n* `next_suit`: suit of next card in pile (see below for possible values) (default: `same` if foundation, `any` if tableau, `none` if stock or cell, `any` otherwise).\n* `move_group`: whether it's possible to move a valid sequence (`group`), a complete sequence (`all`), any sequence (`any`), or just single cards (`one`, default).\n* `from`: which pile type to accept cards from: `foundation`, `cell`, `tableau`, `stock`, `waste`, `any`, or `none` (default: `stock` if waste, `any` otherwise).\n* `to`: which pile type to move stock cards to (default: `waste` if stock, `any` otherwise.\n* `win_rank`: the game is won when the top card of all foundations is of this rank (see below for possible values) (default: `king` if foundation, `none` otherwise).\n* `class`: an integer. Can be used to group together several game rules (default: 0).\n* `turn`: an integer. How many cards to turn from stock. (default: 1 if stock, 0 otherwise).\n* `same_class`: a rule block that applies only when the class of the source and destination is the same.\n* `valid_group`: a rule block that applies when moving sequences of cards.\n\nThe following values can be used with commands that expect a rank:\n\n* `any`: any rank\n* `none`: no cards allowed\n* `empty`: empty pile expected (e.g. `win_rank empty`)\n* `a`/`2`/`3`/`4`/`5`/`6`/`7`/`8`/`9`/`10`/`j`/`q`/`k`: exact rank\n* `same`: must be the same rank as the card below\n* `down`: must be exactly one rank lower than the card below\n* `up`: must be exactly one rank higher than the card below\n* `up_down`: must be exactly one rank higher or lower than the card below\n* `lower`: must be lower rank than the card below\n* `higher`: must be higher rank than the card below\n\nThe follwing values can be used with commands that expect a suit:\n\n* `any`: any suit\n* `none`: no cards allowed\n* `heart`/`diamond`/`spade`/`club`: exact suit\n* `red`/`black`: exact color\n* `same`: must be the same suit as the card below\n* `same_color`: must be the same color as the card below\n* `diff`: must be a different suit than the card below\n* `diff_color`: must be a different color than the card below\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnielssp%2Fcsol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnielssp%2Fcsol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnielssp%2Fcsol/lists"}