Home

Awesome

<h1 align=center>scrabbler</h1> <h3 align=center>Pick tiles, but not yourself!</h3> <p align=center>Automatic draw TUI for your <i>duplicate</i> Scrabble games</p> <p align=center> <img alt="French" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/FR.svg"> <img alt="English (US)" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/US.svg"> <img alt="English (UK)" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/GB-NIR.svg"> <img alt="German" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/DE.svg"> <img alt="Italian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/IT.svg"> <img alt="Dutch" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/NL.svg"> <img alt="Czech" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/CZ.svg"> <img alt="Icelandic" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/IS.svg"> <img alt="Afrikaans" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/ZA.svg"> <img alt="Bulgarian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/BG.svg"> <img alt="Danish" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/DK.svg"> <img alt="Estonian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/EE.svg"> <img alt="Finnish" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/FI.svg"> <br/> <img alt="Greek" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/GR.svg"> <img alt="Indonesian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/ID.svg"> <img alt="Latvian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/LV.svg"> <img alt="Lithuanian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/LT.svg"> <img alt="Malay" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/MY.svg"> <img alt="Norwegian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/NO.svg"> <img alt="Polish" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/PL.svg"> <img alt="Portuguese" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/PT.svg"> <img alt="Romanian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/RO.svg"> <img alt="Slovak" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/SK.svg"> <img alt="Slovenian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/SI.svg"> <img alt="Swedish" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/SE.svg"> <img alt="Ukrainian" src="https://raw.githubusercontent.com/Yummygum/flagpack-core/main/svg/m/UA.svg"> </p> <br/> <p align=center> <img alt="GitHub Release (latest SemVer)" src="https://img.shields.io/github/v/release/wI2L/scrabbler?color=%238F00FF"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/wI2L/scrabbler/test.yml?logo=github&logoColor=white"> <img alt="License" src="https://img.shields.io/github/license/wI2L/scrabbler?color=blue"> </p>

Features


Installation

Manually

From source

go install github.com/wI2L/scrabbler@latest

[!NOTE] This will install the scrabbler binary in $GOBIN, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set.

Pre-compiled binaries

Download pre-compiled binaries from the Releases page.

Usage

Interface

The application presents itself as a terminal user-interface (TUI) which has two views:

Options

Table of contents

CLI Usage

scrabbler [flags]

Flags:
  -d, --dictionary string            custom dictionary file path
  -l, --distribution string          letter distribution language
      --vowels uint8                 number of required vowel letters
      --consonants uint8             number of required consonant letters
  -w, --word-length uint8            the number of tiles to draw (default 7)
  -p, --show-points                  show letter points in tiles
      --predicates key=[val],...     list of draw predicates
  -t, --timer duration[=5m]          enable play timer (default 5m)
      --debug string[="debug.log"]   enable debug mode
  -h, --help                         help for scrabbler

Word length

The official rule define a word of seven (7) letters, but you can change it using the -w/--word-length flags:

scrabbler --word-length=8

Draw requirements

The official duplicate scrabble rules states that a draw must always contain one vowel and one consonant. You can use the --vowels and --consonants flags to configure this behavior (disabled by default, the draw is completely random).

Unlike the official rules, the draws won't stop automatically once there are no more vowels or consonants to pick. However, you can choose to stop the game yourself.

scrabbler --vowels=1 --consonants=1

[!IMPORTANT] The sum of required vowels and consonants cannot exceed the configured word length.

Predicates

Draw predicates are builtin conditions that can alter or influence the outcome of a draw. Each predicate has a "maximum number of tries", after which it is ignored if it cannot fulfill its condition, to prevent the draw from never succeeding.

Duplicates vowels

The dup-vowels predicate caps duplicate vowel letters to a defined threshold. The threshold doesn't apply per-letter (2 A, 3 E) but for all letters at once (max 2 A and 2 E):

scrabbler --predicates="dup-vowels=2"

Tile points

The tiles of the draw can optionally show the points of each letter using the flags -p/--show-points. This option is disabled by default.

[!IMPORTANT] The subscript characters U+2080 to U+2089 are used to represent the digits from 0 to 9. The number 10 is represented using the U+2093 (Latin Subscript Small Letter X) to preserve equal spacing.

Make sure to use a font that support those characters, such as SF Mono on macOS.

Game timer

It is possible to show a timer during the play phase, once a draw have been accepted. To use the default timer duration of 5 minutes, simply use the -t/--timer flags without specifying a value:

scrabbler --timer

To change the duration, set the flag with a custom value:

scrabbler --timer=3m

[!NOTE] The duration value must be expressed as a stringified Go Duration, as defined by the documentation of the time.ParseDuration function.

Examples:

Letter distribution

Editions of the word board game Scrabble in different languages have differing letter distributions of the tiles, because the frequency of each letter of the alphabet is different for every language. As a general rule, the rarer the letter, the more points it is worth.

Most languages use sets of 100 tiles, since the original distribution of ninety-eight tiles was later augmented with two blank tiles.

—— Wikipedia

By default, if no distribution is chosen with a flag at startup, the application will display a selection menu.

You can change it with the -l/--distribution flags:

scrabbler --distribution=english

Below is the list of official distributions that are supported:

Alternate distributions are also available:

[!NOTE] All information are compiled from the Scrabble letter distributions Wikipedia page.

See the distribution.go file, which define the letter distribution for each language.

[!IMPORTANT] Several editions such as Spanish, Catalan, Hungarian or Welsh (to cite a few) are not included because they use digraphs, which are challenging to deal with in a text-based UI.

They might be added in the future, once I have figured out an intuitive way to handle them.

Custom dictionary

By default, the application loads the official French Scrabble dictionary (ODS8), which is embedded into the binary with the Go embed package.

Alternatively, you can specify the path of a dictionary of your choice with the -d/--dictionary flags:

scrabbler --dictionary=dictionaries/english/twl06.txt.gz

A valid dictionary is a text file which contain one word per line (the words don't need to be sorted).

The file can optionally be gzipped (the file extension doesn't matter, the detection is header-based).

Browse the dictionaries directory, which already contains some official and non-official dictionaries for several languages:

Language       NameDescriptionWord count
:fr: FrenchODS8The 8th version of the official dictionary for Francophone Scrabble411430
:uk: EnglishSOPWODSOfficial word list used in English-language tournament Scrabble in most countries except the US, Thailand and Canada267753
:us: :canada: EnglishTWL06Official word authority for tournament Scrabble in the USA and Canada.178691
:it: ItalianlistediparoleUnofficial word list extracted from the listediparole.it website.664005
:de: Deutschhippler/german-wordlistUnofficial word list compiled by Stefan Hippler685486
:iceland: Icelandicvthorsteinsson/SkraflUnofficial word list compiled by Vilhjalmur Thorsteinsson from the Database of Icelandic Morphology (DIM, BÍN) for the crossword game Netskrafl2543753
:romania: RomanianlistedecuvinteUnofficial word list extracted from the listedecuvinte.com website610767

Key bindings

Credits

License

The code is licensed under the MIT license. Read this or see the LICENSE file.