--- title: Colobot documentation tags: college --- # Language specification ## Variables The `var` keyword is used for declaring new variables in the current scope. All variables are dynamically typed. Variables have to be initialized the moment they are being declared. ``` var myVariable = 0 ``` ### Built-in variables |Name|Value| |-|-| |`PI`|3.14159265358979323846| ## Literals There are three types of values: *integers*, *decimal numbers* and *booleans*. ``` a = 42 a = -15 a = 9_000 // underlines in integer literals are ignored ``` ``` b = 1.0 b = -3.69 ``` ``` c = true c = false ``` ## Operators Standard math operations can be done using those basic operators: * `+` -- addition * `-` -- subtraction * `*` -- multiplication * `/` -- division * `%` -- remainder (modulo) Standard math order of operations is used (parentheses before multiplication/division/remainder before addition/subtraction). ``` result = 2 + 2 * 2 // equals 6 result = (2 + 2) * 2 // equals 8 ``` There also exist assignment operator variations for each of the above operators (`+=`, `-=`, `*=`, `/=`, `%=`). ``` // these two statements do exactly the same thing: result = result + 2 result += 2 ``` Values can be compared using operators: * `==` -- are equal * `!=` -- are not equal Additionally, numeric values can be compared using those operators: * `a > b` -- is `a` greater than `b` * `a < b` -- is `a` less than `b` * `a >= b` -- is `a` greater than or equal to `b` * `a <= b` -- is `a` less than or equal to `b` Also, those operators are available for boolean values: * `!a` -- negates `a` (`true` if `a` is `false`, `false` otherwise) * `a && b` -- `true` if both `a` and `b` are `true`, otherwise `false` * `a || b` -- `false` if both `a` and `b` are `false`, otherwise `true` ## Functions Functions can be declared using the below syntax: ``` function <function name>(<function arguments>) <statement> ``` Example: ``` // a function named `addThreeValues`, taking 3 arguments function addThreeValues(a, b, c) { var result = 0 result += a result += b result += c return result } ``` ### Built-in functions |Definition|Description| |-|-| |`int(v)`|Converts the value `v` to an integer.| |`decimal(v)`|Converts the value `v` to a decimal.| |`isDrawing()`|Returns `true` if the actor is currently drawing (default state is `true`).| |`setDrawing(state)`|Sets whether the actor should be drawing or not to the passed `state` value.| |`toggleDrawing()`|Toggles whether the actor should be drawing.| |`getRed()`|Returns the red component of the color currently used to draw (default color is white) as a value between `0.0` and `1.0`.| |`getGreen()`|Returns the green component of the color currently used to draw (default color is white) as a value between `0.0` and `1.0`.| |`getBlue()`|Returns the blue component of the color currently used to draw (default color is white) as a value between `0.0` and `1.0`.| |`setRed(r)`|Sets the red component of the color currently used to draw to the `r` value between `0.0` and `1.0`.| |`setGreen(g)`|Sets the green component of the color currently used to draw to the `g` value between `0.0` and `1.0`.| |`setBlue(b)`|Sets the blue component of the color currently used to draw to the `b` value between `0.0` and `1.0`.| |`setColor(r, g, b)`|Sets all three color components of the color currently used to draw.| |`move(distance)`|Moves the actor the passed `distance`. If the actor is currently drawing, it also draws a line.| |`rotate(degrees)`|Rotates the actor by `degrees` clockwise. To rotate counter-clockwise, pass in negative values.| ## Control flow ### `if` Executes a statement if the condition is passed. ``` var a = 2 var b = 3 if a < b move(10) ``` #### `else if` If the first condition doesn't pass, the next conditions are checked. ``` var a = 3 var b = 2 if a < b move(10) else if a > b rotate(45) ``` #### `else` If none of the conditions passed, the `else` branch is executed. ``` var a = 2 var b = 2 if a < b move(10) else if a > b rotate(45) else toggleDrawing() ``` ### `while` Executes a statement in a loop as long as the condition passes. ``` var a = 10 while a > 0 { move(10) rotate(15) a -= 1 } ``` ### `do (...) while` Executes a statement in a loop. After execution, if a condition does not pass, the loop is stopped (as in, the statement will always be executed at least once). ``` var a = 10 do { move(10) rotate(15) a -= 1 } while a > 0 ``` ### `repeat` Executes a statement a specific number of times. ``` // draw a circle repeat 360 { move(1) rotate(1) } ``` ### `for` A loop consisting of a setup part, a condition part, an increment part and a statement to be executed. First, the setup part is executed. Afterwards, a loop starts. As long as condition part passes, the statement is executed, and the increment part is ran. ``` // basically a `repeat 10` for (i = 0; i < 10; i += 1) { move(10) rotate(10) } ``` ### `break`, `continue` Loops can be stopped early with the `break` statement. The current loop step can also be skipped (and the next one started, if any) with the `continue` statement. ``` var a = 0 while true { if a >= 10 break a += 1 } ``` ``` for (i = 0; i < 10; i += 1) { move(10) rotate(10) if i % 2 == 0 continue move(20) } ``` ## Scoping A new variable/function scope is pushed for: * the whole script when execution starts * statement blocks `{ }` * function calls * loops ``` var a = 0 repeat 1 var a = 1 // at this point there are 2 variables named `a`, with different values // only the initial `a` variable is accessible and its value is still `0` ``` ``` var a = 0 repeat 1 a = 1 // not using `var` means we set the already existing `a` variable // `a` is now `1` ``` # Example scripts ## `script1.csc` ``` var outerCircles = 4 var innerCircles = 30 var stepsPerCircle = 360 repeat outerCircles { move(100) repeat innerCircles { rotate(360.0 / innerCircles) repeat stepsPerCircle { move(1) rotate(360.0 / stepsPerCircle) } } move(-100) rotate(360.0 / outerCircles) } ``` ![](https://i.imgur.com/SUgfzKI.png) ## `script2.csc` ``` repeat 60 { repeat 4 { move(150) rotate(90) } rotate(6) } ``` ![](https://i.imgur.com/83VSXfn.png) ## `script3.csc` ``` function spirala(dlugoscBoku, zwiekszenieBoku, maksymalnaDlugoscBoku, katZmiany) { if dlugoscBoku <= maksymalnaDlugoscBoku { repeat 2 { move(dlugoscBoku) rotate(-katZmiany) } spirala(dlugoscBoku + zwiekszenieBoku, zwiekszenieBoku, maksymalnaDlugoscBoku, katZmiany) } } spirala(10, 10, 600, 90) ``` ![](https://i.imgur.com/M4hsxwm.png) ## `script4.csc` ``` function tree(length, n) { if n > 0 { move(length) rotate(-90) tree(length / 2.0, n - 1) rotate(90) tree(length / 2.0, n - 1) rotate(90) tree(length / 2.0, n - 1) rotate(-90) move(-length) } } tree(10, 8) ``` ![](https://i.imgur.com/0EUbr9d.png) ## `script5.csc` ``` function triangleFractal(length, depth) { if depth == 0 { move(length) return; } repeat 3 { move(length / 3) triangleFractal(length / 3, depth - 1) move(length / 3) rotate(120) } } triangleFractal(200, 4) ``` ![](https://i.imgur.com/ClXPynb.png)