# Composite Image objects

Updated: April 13, 2022, for GS ver. 4.012

Since version 3.*, the Game Server supports Image-and-property-based objects. This document discusses a particular class of such objects, the composite image objects introduced in GS 4.009. Unlike the images for the objects previously available in the Game Server, the composite image objects are not pre-generated and stored in /opt/tomcat/game-data (and the GitHub repository); instead, they are generated dynamically in the Game Server whenever they are needed.

## What are composite image objects?

A composite image object, as proposed by Paul in March 2022, consists of 3 small shapes, or elements (circles, squares, triangles, or stars), each of which has its own size, color, and opacity level. The elements can be arranged either horizontally or vertically. For example:

- `/composite/h/d=313/b=333/rt/bq/gc`
- `/composite/v/d=123/b=321/bt/rs/gc`
- `/composite/h/b=321/rq/rq/rq`

One can also use composite image objects with fewer or more than 3 elements. One element is allowed too:

- `/composite/h1/d=3/b=3/gc`
- `/composite/h1/d=2/b=2/gc`
- `/composite/h1/d=1/b=1/gc`
- `/composite/h5/d=11233/b=31313/rs/rs/rs/rs/rs`
- `/composite/v2/d=31/b=13/bt/bt`

Since GS 4.011, as proposed by Charles, the Game Server also supports "grid" composite objects. This is a generalization of the "h" and "v" objects; they are assembled from elements arranged into a rectangular grid with an arbitrary number of rows and columns.

`/composite/g33/d=123123123/b=111222333` | `/composite/g34/d=111122223333/bq/bc/bt/bs/gq/gc/gt/gs/rq/rc/rt/rs` | `/composite/g33/rq/rq/rq/gq/xx/gq/bq/bq/bq`

### Comparative sizes

Two elements are notionally considered to be of the same size if squares of the same size can be circumscribed around them. Thus, a circle of diameter D is considered of the same size as a square or equilateral triangle whose sides are of the length D, or a star in which the distance between two most remote points (vertices) is D. Since a triangle or a star of a given size occupies smaller surface area than a circle or square of the same (by the above defnition) size, the former may visually appear smaller than the latter.

This is illustrated by following table; within each cell of the table, the 3 elements are considered to be of the same size.

Small (d=1) | Medium (d=2) | Large (d=3)
--- | --- | ---
`/composite/h/d=111/rs/gq/bt` | `/composite/h/d=222/rs/gq/bt` | `/composite/h/d=333/rs/gq/bt`
`/composite/v/d=111/rt/gq/bs` | `/composite/v/d=222/rt/gq/bs` | `/composite/v/d=333/rt/gq/bs`

## How to use composite image objects?

Like other objects (whether the legacy shape-and-color based ones, or the image-and-properties-based ones), composite image objects can be used to define a game in a trial list file. All the same rules described in Image-and-property-based objects | Controlling the initial board generation apply. That is, in any parameter set (= a line of a trial list file) you can either specify the set of composite image objects from which such objects will be randomly drawn, or you can specify a set of initial board files (and then create those board files).

As with any image-and-property-based object, a composite image object has a set of properties, which can be accessed in rules

The rest of this document describes how composite image objects are defined, and what properties they have.

## Names of composite image objects

Each individual composite image object is identified by its name, which describes the elements from which the composite image is constructed. Consider the following image object names as examples:

- `/composite/h3/d=331/b=313/rt/bq/gc`

The above name consists of the following parts:

1. `/composite` -- this is a mandatory prefix, which tells the Game Server that the object needs to be dynamically generated inside the server, rather than read in from a pre-created SVG file and property file.s
2. Orientation, e.g. `/h3` (3 elements, horizontally arranged) or `/v2` (2 elements, vertically arranged). Since Paul's proposal talked primarily of composite objects made out of 3 elements, this is the default number of elements in a composite object, and you can omit the digit `3`. Thus, /h means the same as /h3.
   For grid objects, the orientation part has the form `/gRC`, consisting of `/g` and two digits specifying the number of rows and columns, respectively. E.g. `/g34` for a grid with 12 elements (3 rows and 4 columns).
3. Changing defaults. An optional part, not shown here, using for providing certain defaults, which are particularly useful when wildcards are used (as discussed in the next section). This may include:
   - `/allColors=gr` : the colors (when "wildcarded" or "defaulted") will be chosen from the set of green and red.
   - `/allShapes=qx` : the shapes (when "wildcarded" or "defaulted") will be chosen from the set of "square" and "blank"
4. Orderable features. Some features of elements, namely their size and opacity are considered "orderable". That is, a player is supposed to figure that there is something special about a composite image consisting e.g. of elements ordered in the order of increasing sizes:
   - `/composite/h/d=123/rc/bc/gc`
   or decreasing opacities:
   - `/composite/h/b=321/rs/rs/rs`
   These features of the elements are described in the format featureName=featureValue. E.g. the component `d=123` means that the three elements, ordered from the left to the right or from the top to the bottom, have sizes ("diameters") "small", "medium", and "large", respectively. (Each orderable property currently has 3 possible levels, described by values 1 thru 3). The component `b=321` means that the 3 elements have the opacity ("brightness") values "high", "medium", and "low" (i.e. 3, 2, 1).
   All orderable features have default values (for size, "large", i.e. 3; for opacity, "high", i.e. 3 as well). If you omit any component in the name of a composite image, all of its elements will have the default value of the respective property. For example, in the following example, all 5 elements are high-opacity, but vary in sizes.
   - `/composite/h5/d=32123/rs/gs/bs/gs/rs`
   We can add more orderable features in the future, e.g. texture pattern or tilt.
   For a grid composite object, the number of digits in the `d=...` and `b=...` strings should be equal to the number of rows times the number of columns. They describe the elements one by one, arrangede by row.
5. Colors and shapes of elements. The last section of the name decribes the colors and shapes of individual elements, in the /ColorShape/ColorShape/... format, with the one-letter codes as follows:

   Colors
   r | red
   g | green
   b | blue
   x | Used in /xx to describe a skipped (empty) element

   Shapes
   c | circle
   s | star
   q | square
   t | triangle
   x | empty element (leaves the appropriate section of the composite object empty)

   This part of the name can be omitted as well. If omitted, the default element, red square, will be used.
   For brevity, you can use /x (instead of the normal /xx) to describe a blank element. After all, blanks don't have colors.
   For a grid composite objects with R rows and C columns, this component needs to describe all R*C elements, arranged by row, unless you want to use the default color and shape (red squares, or whatever is provided as the first elements of your "allColors" and "allShapes").
   To save space, one can use the caret ("`^`") notation for multiple identical items. E.g. you can write `/bc^10` to specify 10 blue circles; you can write `/*^5` instead of `/*/*/*/*/*` or `/??/??/??/??/??` to indicate 5 elements of random shapes and colors.

Names of individual composite objects will appear in initial board files saved by the Game Server. If you create a game that uses pre-defined initial boards, you will use names of individual composite objects in the board description files as well.

## Test form

You can use the form below to see the image and properties associated with any legal composite-object name. (You can use a wildcard expression too, and will be shown one of the matching composite objects).

## Using wildcards to describe a family of composite image objects

When you create a parameter set for a game in which initial boards are genereated randomly, populated with game pieces drawn from a certain set of objects, you need to specify the set of objects in the column `images`. While it is possible to describe the set of objects by explicitly listing all of its elements, e.g.

    "/composite/h/d=123/rc/bc/gc;/composite/h/d=321/rc/bc/gc;/composite/h/d=222/rc/bc/gc"

, it is often possible and convenient to describe an entire family of composite objects by using a single wildcard expression.

The wildcard syntax used for desribing composite image objects is similar to the wildcard syntax for file names used e.g. in MS Windows or in UNIX shells. However, it is somewhat more primitive. Wildcards can be used in each component of the object name, wherever it makes sense.

- The character `?` match any letter or digit that's allowed in a given position. For example, `/d=1?1` will match `/d=111`, `/d=121`, and `/d=123`.
- The character `*` can be used to match any string, and can only be used at the end of a component. For example, `/b=*` will match any sequence of brightness values; `/b=3*` will match any sequence that starts with 3.

Examples of families of composite image objects described with wildcards:

- `/composite/?/d=1??/*/r?/*` -- 3 (default number) of elements, arranged either way (horizontal or vertical); the first element is small (size rank 1), the other of any size; default opacity (high). The first and third element of arbitrary colors and shapes; the second is red, of an arbitrary shape.
- `/composite/h2/b=13/?q/?q` -- 2 elements, arranged horizontally. They are of the default size (large); the first is of low opacity (1), the second, of high brightness (3). Both are squares, of arbitrary colors.

## Properties of composite image objects

To create rules for playing with composite image objects, you need to access their properties (or "features", as our ML/AI colleagues refer to them). Presently the following properties of composite objects are accessible:

- `orientation: h` or `v` (horiszontal or vertical)
- Properties of an objects include the feature strings from its name, such as
  - d: 123 (the sequence of elements' sizes)
  - b: 321 (the sequence of elements' brightness values)
  More of those can be introduced for any features we may add later, e.g. "t".
- We also have properties that gives you access to the object's elements' shapes and colors, i.e.
  - s: "sqt"
  - c: "rbg"
- In principle, the above properties are sufficient to construct predicates, but obviously this would be very awkward. (E.g. if you want a predicate which hold true on all non-decreasing orders, it would look like (d: [111, 222, 333, 112, 113, 122, 123, 223, 233]), and that's slightly cumbersome. So we also have some "syntactic sugar", that is properties with names such as
  - d_order = one of {-1, 0, 1, 2}. Here, -1 stands for "not monotonous", i.e. the sizes of the elements within the image are neither monotonically non-decreasing nor non-increasing. 0 stands for "all elements are same size" (e.g. h/RS1/BT1/GQ1). 1 stands for "non-decreasing, with at least some increase" (from the left to the right, or from the top to the bottom, as the case may be), e.g. 1/1/2 , 1/3/3, or 1/2/3. -1 stands for "non-increasing, with at least some decrease", e.g. 2/1/1 or 3/2/1. Thus a predicate referring to all non-decreasing orders will haves the form `(d_order: [0,1])`, and that's handier.
  - b_order is a similar property for opacity (brightness).
  Analogous properties can be added for any other orderable features that may be introduced later.
- sameshape = 0 or 1 (with 1 = true)
- samecolor = 0 or 1 (with 1=true)

- `occupied` is an integer-valued property indicating the number of grid cells that contain visible elements, i.e. are not blank. For an R*C grid, the value of this property may range from 0 to R*C .
- `opacity` is an integer-valued property ranging from 0 to 100. It is computed as the average of the opacity-times-size-scale-factor values of all elements of the grid (the opacity of a blank cell being 0), multiplied by 100. If the composite image is composed entirely of squares (of varying opacity and sizes) and blanks, then this value fairly represents percentage the "average opacity" of the object. If you mix shapes (e.g. squares and circles and stars), then, at present (GS 4.12) this measure is not accurate, as it does not take into account the fact that the surface area of a large circle is smaller than that of a large square, and that of a large star is even smaller.
- Translational invariance: A group of "boolean-values" (0 or 1) properties test the invariance of the pattern formed by the elements of the grid with respect to horizontal, vertical, or diagonal translation. Namely, `trans_h` = 1 if each element is identical (same shape, color, brightness) to its neighbors to the right and left (i.e., in the horizontal direction). Thus, it will be 1 for an composite object that looks like a set of horizontal bands; it will be 0 otherwise. Similarly, `trans_v` = 1 for a composite object that looks like a set of vertical bands. `trans_asc` = 1 for a composite object whose elements appear arranged in ascending diagonal stripes (running SW to NE), while `trans_desc` = 1 for a composite object whose elements appear arranged in descending diagonal stripes (running NW to SE). For an example of using this group of properties, see experiment plan `vm/composite-04`.

  ## Sample experiment plans

  To illustrate using composite image objects, an experiment plan (`vm/composite-01`) has been created. You can play it in GS 4.009, starting from the Launch page. (You can also see the text of the trial list files and rule set files on GitHub).

  You may want to try pasting the names of objects from the sample trial list files into the form above, to see how wildcard expressions work, and how properties are computed. Or you can just use the validation tool on those plans; it will give you similar information.

  Other plans are `vm/composite-02` (picking game pieces in the order of the number of "occupied" elements in the piece) and `vm/composite-03` (picking pieces in the order of their average opacity).

  To make the details of composite images more visible, you may want to make the 6x6 board appear as large as possible. To do that, use a compute with a large monitor; maximize the visual area of the web browser window (with F11); turn off the "Debug" mode of the GUI client.

  ## Command-line unit testing

  Since composite image objects are dynamically generated, there is no directory with SVG file and a property file where they are stored. Nonetheless, if you would like to see what the SVG file for a particular object would like, or what the values of its properties are, this can be done with the help of a command-line tool on sapir.

  Example:

        /home/vmenkov/w2020/game/scripts/composite.sh /composite/h/d=123

  In this example, the object has elements of the specified sizes, of the default opacity (high), default color (red), and default shape (square).

        /home/vmenkov/w2020/game/scripts/composite.sh /composite/h/d=123/b=*/r?/g?/b?

  In this example, the script will randomly pick one object from the family of objects matching the description. That is, the sizes and colors are specified, but the opacity values and shapes will be picked randomly.