The cardwords game - Customizing cardwords

[back] [Abstract] [Copyright Notice] [Contents] [next]

# The cardwords game - Chapter 3
Customizing cardwords

`cardwords` is customized by supplying customized versions of the following files:

- The charset file, see The charset file, section 3.1.

- The dictionary files, see The dictionary files, section 3.2.

- The card set file, see The card set file, section 3.3.

- The card-table file, see The card-table file, section 3.4.

- The bonus file, see The bonus file, section 3.5.

You can put customized versions of these files anywhere you like and point the client programm to them with the options dialog and then save the options, but I suggest that you put these files either in LIBDIR (if you are the system administrator and these files are of interest for some of your users) or in the `.cardwords` subdirectory of your home directory.

If you create a french version of these files for example, and all your users speek french as their native language, you should put these files in LIBDIR and make the symlinks `default.*` point to them.

When you create new versions of these files and make them accessible to other people, you must be careful not to violate anyone's copyright.

Yes, I mean it. It may be possible to customize this game so that it imitates other crossword computer games or real world crossword games. If you create such an customization, and you do not have the copyright for it, you must not distribute it. This does even mean that you must not play a game that is this way customized with other people over the net, because the server sends copies of these files to the clients, and this is an act of distribution and copying.

I rather want to encourage you to be creative and invent your own charsets, card sets, card-tables, bonus and penalty rules etc, and publish them under a free license such as the GPL, BSD, Artistic etc.

## 3.1 The charset file

The charset file has the format

    n
    character 1 equivalents
    character 2 equivalents
    character 3 equivalents
      [...]
    character n equivalents

where n is the number of different characters on your cards and character i[1] equivalents are characters from the computer's charset that this character represents. The character equivalents must not contain white space. This way it is possible to let uppercase and lowercase characters be represented by the same card character. Here is an example charset file for the english language (as distributed in example.charset with cardwords):

    26
    Aa
    Bb
    Cc
    Dd
    Ee
    Ff
    Gg
    Hh
    Ii
    Jj
    Kk
    Ll
    Mm
    Nn
    Oo
    Pp
    Qq
    Rr
    Ss
    Tt
    Uu
    Vv
    Ww
    Xx
    Yy
    Zz

The first character that you give in a set of equivalent characters will always be used by the program's output to refer to that card character, while all given characters are recognized in the input.

If you really want to you can also separate lowercase from uppercase characters, and specify only one character on each line. This could make sense in some languages where several words always start with an uppercase letter, but I think it is generally unnecessarily complicated.

You might wonder why you have to specify the characters in a file, A to Z uppercase and lowercase is not too hard to think of, is it? My main motivation to write `cardwords` was the lack of crossword computer games that featured the german umlauts Ä, Ö and Ü and the ß. While it is common practice to replace these even in german newspaper's crossword puzzles with AE, OE, UE and SS, the result is sometimes ugly. With `cardwords`, this is no more necessary.

The programs I saw also had hardwired assumptions about the distribution of the characters in the language that fits the english language, but is ridiculous in other languages. This distribution of characters can be customized within the card set file described in The card set file, section 3.3.

## 3.2 The dictionary files

You have to use a dictionary file if you want to play against robots. The robots would otherwise have no clue what a valid word is. If you start the server without specifying a dictionary, it will crash currently when a robot tries to make his move. I recommend using a dictionary file. The server sometimes interrupts the connection when a client tries to perform an action that it is not allowed to. If this happens (and remember, the software is alpha, this can happen now) or the connection breaks otherwise, then the remote player is replaced by a robot, even if you started a game with no robots at all.

A dictionary file is just a text file that contains the words that you want the server to allow, like this:

    salt
    pepper
    collapsible
    jaw
    eat
    so

The words do not need to be sorted in any way. The only restrictions are:

- The words must consist of at least 2 characters.

- The words must be build up from characters that you put in the charset file. This implies that they must not contain white space.

The `cardwords` server program can use dictionary files in three different ways:[2]

- As a normal, read-only dictionary. The server could handle several of these, adding all contained words to its internal dictionary, but this is not yet implemented in the client that starts the server.

- As a dictionary file that is read when the server starts and to which new words, that are introduced by the owner of the server, will be appended.

- As a file that contains words to remove from the internal dictionary. This is not implemented yet, and when it is, you should not add a dictionary file which contains many words you do not want to have and then remove them using a remove-file, because it works very slow. I optimized the internal dictionary to quickly find the best move for a given set of cards (the robots need this), and the result was that removing a word is not only slow, but very slow[3].

Dictionaries are a source of conflicts between human players. Find a consensus with your players what kinds of words should go into the dictionary before starting the game.

The robots will of course accept any dictionarys that you provide. With a combination of a read-only file and a read write file, you can have a system wide read-only dictionary that everybody agrees on and a writeable personal dictionary where you put your own special words.

You can also use the writeable dictionary to add just a few words to the dictionary in the beginning and let the program add new words as they occur during the game. I recommend this way, it is the conveniest and it ensures that you win the first games against the robots `:-)`.

## 3.3 The card set file

You can decide what cards you want to play with. Each card shows a character and a points value. You can also create special wildcards that can represent any character the player wants. You can create any combinations of characters and point values.

The card set file just lists all existing cards, preceeded by the total number of cards. A card in the file has the following format:

       [x #]

where

[ and ]
  are literal brackets.

x
  is a character that is contained in the charset file. This is the character the card shows. For wildcards, this must be a space.

(the space in the middle)
  is a literal space. This is required.

#
  is an int in decimal, the points of that card.

Clients can restrict the points of the cards to certain values, while the server does not. The only client existing by now restricts the points of cards to the range from -9 to 99. This is because of the space where the points are displayed on the screen is designed to hold two digits, or one digit and the minus sign at maximum. Other clients can have other restrictions.

Here is an example card set file that can be used together with the example charset file:

    14
    [A 6] [A 6] [A 6] [A 7]
    [B 2] [B 2] [B 9]
    [E 1] [E 0] [E -1][K 19]
    [  0] [  -2] [  -1]

The card descriptions can be separated from each other by white space. Remember the required space in each card description! The last line in this example shows three wildcards. Theese need two spaces, one to mark it as a wildcard and the other one is the required space.[4]

You might want to count the distribution of characters in documents written in your language, in order to create a card set file. You can use `cardwords_count` to do this. Create `cardwords_count` by typing `make cardwords_count`. `cardwords_count` takes a charset file as argument and parses its standard input. It will ignore all chars that do not occur in the charset file and write the total number of occurrences of every recognized character to its standard output.

I must admit I have no idea if and how the copyright propagates from the document in which you count the characters to the output of `cardwords_count`, and if you base your card set file on it, to this card set file. I think it could be declared as a derivative work. So, unless you know it better than me, you should use only documents that you wrote entirely yourself or that are in the public domain.

You might also want to set the total number of cards in some relation to the total number of places on the card table.

## 3.4 The card-table file

The card-table is the place where the words are created. Because the words should appear crossword-like, the card-table has a grid of cells where the cards can be put. This grid has always the form of a rectangle, but you can customize its width and height.

You can also give a start condition. This means you can restrict the first word to areas where it touches a certain row of the grid, or a certain column, or even a single cell.

Subsequent new words must then touch existing cards on the card-table.

The format of a card-table file that creates a very simple card-table is

    dimensions
    start condition
    end tag

where

`dimensions`
  have the form `width*height`, `width` and `height` being decimal integers describing the width and height of the grid, `*` is a literal asterisk;

`start condition`
  has the form `(column, row)`, with the parentheses and the comma being literal parentheses and comma, with `column` and `row` being decimal integers. If 0 <= `column` < `width`, then this column must be touched by the first word on the card-table. If 0 <= `row` < `height`, then this row must be touched by the first word on the card-table. As you see, valid `column` and `row` row numbers start with 0. `(0,0)` is the upper left corner;

`end tag`

  is a `(column, row)` pair with at least one of the following conditions:

  - `column` >= `width` or

  - `row` >= `height` .

I will give some examples of simple card-table files to make it clear what they look like:

- A file defining a card-table with width 18, height 10 and no start condition:

      18*10
      (18,10)
      (18,10)

- A file defining a card-table with width 18, height 10 and a start condition that restricts the first word to touch the rightmost column:

      18*10
      (17,10)
      (18,10)

- A file defining a card-table with width 18, height 10 and a start condition that restricts the first word to touch the left bottom cell:

      18*10
      (0,9)
      (18,10)

But that is not all that can be specified in card-table files. You can set certain attributes of the card-table grid cells:

- Cells can be unuseable (blocked). This means, they can not hold a card, and no word can cross them. To block a cell add a line

      (column, row) B;

  to the card table file between the `start condition` line and the `end tag` line.

- Cells can have a points value.[5] The player who occupies this cell with a card gets these points. To change the points value of a cell add a line

      (column, row) C points;

  to the card table file between the `start condition` line and the `end tag` line.

- Cells can have a letter factor.[6] This means that the points of the card that is put there are multiplied by this factor when the points are counted. To change the letter factor of a cell add a line

      (column, row) L factor;

  to the card table file between the `start condition` line and the `end tag` line.

- Cells can have a word factor.[7] This means that the points of the card that is put there and the points of all other cards that form a word together with the card in this cell are multiplied by this factor when the points are counted. To change the word factor of a cell add a line

      (column, row) W factor;

  to the card table file between the `start condition` line and the `end tag` line.

Multiple attributes of a single cell can be grouped into a single line like

    (column, row) W word_factor C cell_points;

or any other combination. The gtk client does not support more than 2 non-default cell attributes per cell.

You should perhaps only use one cell attribute per cell at maximum, and let most of the cells have their default values in order to not make it too complicated for humans to play the game. Here is the example card-table file as shipped with `cardwords`:

    19*10
    (10,11)

    (0 ,0) B;
    (0 ,1) B;
    (1 ,0) B;

    (17,0) B;
    (18,0) B;
    (18,1) B;

    (0 ,9) B;
    (1 ,9) B;
    (0 ,8) B;

    (18,9) B;
    (17,9) B;
    (18,8) B;

    (10,0) C 5;
    (10,9) C 5;

    (1 ,1) W 2;

    (17,8) L 2;

    (20,12)

## 3.5 The bonus file

This file has the following format:

There are 2*N+1 pairs int:int with the following restrictions and meanings:

    -N:trade_N_score
    ..:..
    -1:trade_1_score
    0:pass_score
    1:1-bonus
    ..:..
    N:N-bonus

The trade_i_score is added to the player's score when he changes i cards. trade_i_score will usually be <= 0.

The pass_score is added to the players score when he passes. Usually <= 0.

1-bonus, ..., N-Bonus are added to the player's score on top of the move count for a move with that many cards.

N is the number of cards every player has got in his hand. N is only implicitly defined in the bonus file and nowhere else.

Here is an example bonus file:

    -6:-10
    -5:-10
    -4:-10
    -3:-5
    -2:-5
    -1:-5
    0:-1
    1:0
    2:0
    3:0
    4:0
    5:5
    6:10

This bonus file sets the number of cards in every player's hand to 6. Trading cards and passing results in penalty points, putting 5 or 6 cards simultaneously onto the table results in bonus points.

[back] [Abstract] [Copyright Notice] [Contents] [next]

The `cardwords` game