Intro

The purpose of this document is to provide a quick example of how to use the Sista library.

I will use the sista.cpp file as the example to explain.

Include

The first thing you need to do is include the Sista library.

#include "include/sista/sista.hpp"

Namespace

The next thing you should do is to use the sista namespace [1].

using namespace sista;

Input/Output

The next thing to do is to set the input and output streams.

std::ios_base::sync_with_stdio(false);
std::cout.tie(nullptr);

This two lines of code will make I/O faster.

ANSI::reset(); // Reset the settings

This line of code will reset the ANSI settings of the terminal [2].

std::cout << HIDE_CURSOR;

This line of code will hide the cursor [3] to reduce that noisy flickering.

ℹ️ - You don’t need to do this since the sista::Field class includes a private sista::Cursor object that will hide the cursor when the constructor is called.

sista::clearScreen();

The clearScreen() [4] function will clear the screen and the buffer [5], and move the cursor to the top left corner.

ℹ️ - You don’t need to do this since the sista::Field class includes a private sista::Cursor object that will call sista::clearScreen().

Pawn

The next thing to do is to create a std::vector<sista::Pawn*> object as a list of the Pawns.

std::vector<sista::Pawn*> pawns;

The Pawn is allocated on the heap, so you need to use the new keyword to create one.

pawns = {
    new sista::Pawn(
        'X', sista::Coordinates(0, 0),
        ANSI::Settings(
            ANSI::ForegroundColor::F_RED,
            ANSI::BackgroundColor::B_BLACK,
            ANSI::Attribute::BRIGHT
        )
    ) // You can add more pawns here
};

This line of code will add a Pawn object with the following properties:

  • Character: 'X'

  • Coordinates: 0, 0

  • ANSI Settings: Foreground Color: Red, Background Color: Black, Attribute: Bright

Border

The next thing to do is to create a Border object.

sista::Border border(
    ' ', ANSI::Settings(
        ANSI::ForegroundColor::F_BLACK,
        ANSI::BackgroundColor::B_WHITE,
        ANSI::Attribute::BRIGHT
    )
);

The Border is allocated on the stack, so you don’t need to use the new keyword to create it.

I do so because I don’t need to use the Border object outside of the main() function.

This line of code will create a Border object with the following properties:

  • Character: ' ' (Space)

  • ANSI Settings: Foreground Color: Black, Background Color: White, Attribute: Bright

Field

The next thing to do is to create a Field object [6].

sista::SwappableField field(TEST_SIZE, TEST_SIZE);

In this case I am creating a sista::SwappableField [7] object with the following properties:

  • Width: 50

  • Height: 50

Now that we have created the Field object, we can add the Pawn* to it.

for (auto pawn : pawns)
    field.addPawn(pawn);

This line of code will add the pawns to the Field object at the pawn->coordinates coordinates.

std::vector<sista::Coordinates> coords(pawns.size());

This line of code will create a std::vector<sista::Coordinates> object with the same size as the pawns object, to precalculate the coordinates and then assign them.

Main Loop

The next thing to do is to create the main loop to test the SwappableField object and the Pawn movement.

field.print(border);

First of all, we need to print the Field object with the Border object.

for (int i=0; i<TEST_SIZE*TEST_SIZE; i++) {
    coords[0] = field.movingByCoordinates(pawns[0], 1, 1, PACMAN_EFFECT);
    coords[1] = field.movingByCoordinates(pawns[1], -1, -1, PACMAN_EFFECT);
    coords[2] = field.movingByCoordinates(pawns[2], -1, 1, PACMAN_EFFECT);
    coords[3] = field.movingByCoordinates(pawns[3], 1, -1, PACMAN_EFFECT);
    coords[4] = field.movingByCoordinates(pawns[4], 1, 0, PACMAN_EFFECT);
    coords[5] = field.movingByCoordinates(pawns[5], 0, 1, PACMAN_EFFECT);
    try {
        for (int k=0; k<(int)pawns.size(); k++) {
            field.movePawn(pawns[k], coords[k]);
        }
    } catch (const std::invalid_argument& e) {
        for (int k=0; k<(int)pawns.size(); k++) {
            field.addPawnToSwap(pawns[k], coords[k]);
        }
        field.applySwaps();
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    std::cout << std::flush;
}

Since now we’ll never going to re-print the Field object, we’ll edit only the needed characters in the stdout stream.

After applying all the movements, we’ll swap the characters in the stdout stream, and then we’ll flush the stdout stream.

Notes