Sista v3.1.0
C++ lightweight OS-agnostic library for terminal animations and videogames
Loading...
Searching...
No Matches
field.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2022-2026 FLAK-ZOSO <mattia.marchese.2006@gmail.com>
3 * SPDX-License-Identifier: GPL-3.0-only
4 */
5
31#pragma once
32
33#include <vector> // std::vector
34#include <memory> // std::shared_ptr, std::move
35#include <map> // std::map
36#include <set> // std::set
37#include "pawn.hpp"
38#include "border.hpp"
39#include "cursor.hpp"
40
41namespace sista {
55 enum class Effect { // Effect enum - effect when a coordinate is out of bounds
56 PACMAN = 0, // Pacman effect when a coordinate overflows
57 MATRIX = 1 // Classic C style matrix effect when a coordinate overflows
58 };
59
76 class Field { // Field class - represents the field [parent class]
77 protected:
79 std::vector<std::vector<std::shared_ptr<Pawn>>> pawns;
81 int width;
82 int height;
87 void cleanCoordinates(const Coordinates&) const;
92 void cleanCoordinates(unsigned short, unsigned short) const;
93
94 public:
98 void clear();
99
110 Field(int, int);
112 virtual ~Field() = default;
113
123 void print() const;
134 void print(char) const;
146 void print(Border&) const;
147
162 virtual void addPawn(std::shared_ptr<Pawn>);
175 virtual void removePawn(Pawn*);
188 virtual void removePawn(const Coordinates&);
200 virtual void erasePawn(Pawn*);
212 virtual void erasePawn(const Coordinates&);
213
225 void addPrintPawn(std::shared_ptr<Pawn>);
236 void rePrintPawn(Pawn*);
237
251 void movePawn(Pawn*, const Coordinates&);
268 void movePawn(Pawn*, unsigned short, unsigned short);
269
284 void movePawnBy(Pawn*, const Coordinates&);
300 void movePawnBy(Pawn*, unsigned short, unsigned short);
301
302 // 🎮 movePawnBy() with arcade game effects on coordinates overflow
321 void movePawnBy(Pawn*, const Coordinates&, Effect);
339 void movePawnBy(Pawn*, short int, short int, Effect);
340
357 void movePawnFromTo(const Coordinates&, const Coordinates&);
376 void movePawnFromTo(unsigned short, unsigned short, unsigned short, unsigned short);
377
394 Coordinates movingByCoordinates(Pawn*, short int, short int) const;
413 Coordinates movingByCoordinates(Pawn*, short int, short int, Effect) const; // movingByCoordinates - calculate the coordinates of a pawn after a movement
414
431 Pawn* getPawn(const Coordinates&) const;
446 Pawn* getPawn(unsigned short, unsigned short) const;
447
461 bool isOccupied(const Coordinates&) const;
476 bool isOccupied(unsigned short, unsigned short) const;
491 bool isOccupied(short int, short int) const;
492
503 bool isOutOfBounds(const Coordinates&) const;
515 bool isOutOfBounds(unsigned short, unsigned short) const;
528 bool isOutOfBounds(short int, short int) const;
529
543 bool isFree(const Coordinates&) const;
558 bool isFree(unsigned short, unsigned short) const;
573 bool isFree(short int, short int) const;
574
588 void validateCoordinates(const Coordinates&) const;
603 void validateCoordinates(unsigned short, unsigned short) const;
604 };
605
621 struct Path {
622 static long long int current_priority;
641
652 bool operator|(const Path&) const;
662 bool operator<(const Path&) const;
673 bool operator==(const Path&) const;
674 };
675}
676
677namespace std {
686 template<>
687 struct hash<sista::Path> {
688 std::size_t operator()(const sista::Path& k) const noexcept {
689 auto h1 = std::hash<sista::Coordinates>{}(k.begin);
690 auto h2 = std::hash<sista::Coordinates>{}(k.end);
691 return h1 ^ (h2 << 1);
692 }
693 };
694}
695
696namespace sista {
711 class SwappableField final : public Field {
712 private:
714 std::vector<std::vector<short int>> pawnsCount;
716 std::set<Path> pawnsToSwap;
717
718 Coordinates firstInvalidCell(std::map<Coordinates, short int>&) const; // firstInvalidCell - find the first cell with 2 or more pawns
719
727 void clearPawnsToSwap(); // clearPawnsToSwap - clear the pawnsToSwap
728
729 public:
740 SwappableField(int, int);
743
759 void addPawn(std::shared_ptr<Pawn>) override; // addPawn - add a pawn to the field
773 void removePawn(Pawn*) override; // removePawn - remove a pawn from the field
774
789 void movePawn(Pawn*, const Coordinates&); // movePawn - move a pawn to the coordinates
807 void movePawn(Pawn*, unsigned short, unsigned short); // movePawn - move a pawn to the coordinates
808
826 void addPawnToSwap(Pawn*, const Coordinates&); // addPawnToSwap - add a pawn to the pawnsToSwap
842 void addPawnToSwap(Path&); // addPawnToSwap - add a path to the pawnsToSwap
843
854 void simulateSwaps(); // simulateSwaps - simulate the swaps of the pawnsToSwap
863 void applySwaps(); // applySwaps - apply the swaps of the pawnsToSwap
864
876 void swapTwoPawns(const Coordinates&, const Coordinates&);
887 void swapTwoPawns(Pawn*, Pawn*);
888 };
889};
Border class header file.
Represents a brick of the border with a symbol and ANSI settings.
Definition border.hpp:39
Class representing a terminal Field for pawns and borders.
Definition field.hpp:76
void movePawn(Pawn *, const Coordinates &)
Moves a Pawn to new coordinates.
Definition field.cpp:186
Pawn * getPawn(const Coordinates &) const
Gets the Pawn at specified coordinates.
Definition field.cpp:275
Cursor cursor
Definition field.hpp:80
void addPrintPawn(std::shared_ptr< Pawn >)
Adds a Pawn to the field at its specified coordinates and prints it.
Definition field.cpp:176
int height
Definition field.hpp:82
void cleanCoordinates(const Coordinates &) const
Cleans the coordinates on screen by printing spaces.
Definition field.cpp:166
Coordinates movingByCoordinates(Pawn *, short int, short int) const
Calculates the new coordinates of a Pawn after moving by a relative offset.
Definition field.cpp:408
std::vector< std::vector< std::shared_ptr< Pawn > > > pawns
2D grid of shared pointers to Pawn objects.
Definition field.hpp:79
void validateCoordinates(const Coordinates &) const
Validates that the given coordinates are within bounds and not occupied.
Definition field.cpp:319
virtual ~Field()=default
Destructor to clean up resources.
virtual void erasePawn(Pawn *)
Removes a Pawn from the field at specified coordinates.
Definition field.cpp:156
void movePawnBy(Pawn *, const Coordinates &)
Moves a Pawn by a relative offset.
Definition field.cpp:212
void movePawnFromTo(const Coordinates &, const Coordinates &)
Moves a Pawn from one set of coordinates to another.
Definition field.cpp:262
bool isFree(const Coordinates &) const
Checks if specified coordinates are free (not occupied by a Pawn).
Definition field.cpp:308
virtual void addPawn(std::shared_ptr< Pawn >)
Adds a Pawn to the field at its specified coordinates.
Definition field.cpp:131
int width
Definition field.hpp:81
virtual void removePawn(Pawn *)
Removes a Pawn from the field.
Definition field.cpp:144
void print() const
Prints the entire field to the terminal.
Definition field.cpp:47
void clear()
Clears the field by removing all Pawns and resetting the grid.
Definition field.cpp:31
bool isOutOfBounds(const Coordinates &) const
Checks if specified coordinates are out of bounds.
Definition field.cpp:298
bool isOccupied(const Coordinates &) const
Checks if specified coordinates are occupied by a Pawn.
Definition field.cpp:288
void rePrintPawn(Pawn *)
Reprints a Pawn at its current coordinates.
Definition field.cpp:181
Class representing a Pawn owned by a Field or SwappableField.
Definition pawn.hpp:42
Class representing a terminal SwappableField for pawns and borders.
Definition field.hpp:711
void addPawn(std::shared_ptr< Pawn >) override
Adds a Pawn to the field and updates the pawnsCount grid.
Definition field.cpp:375
void simulateSwaps()
Simulates the swaps of the pawnsToSwap and removes unfeasible paths.
Definition field.cpp:490
void swapTwoPawns(const Coordinates &, const Coordinates &)
Swaps two Pawns at the specified coordinates.
Definition field.cpp:556
~SwappableField()
Destructor to clean up resources.
Definition field.cpp:368
void movePawn(Pawn *, const Coordinates &)
Moves a Pawn to new coordinates and updates the pawnsCount grid.
Definition field.cpp:386
void applySwaps()
Applies the swaps of the pawnsToSwap to the field.
Definition field.cpp:534
void removePawn(Pawn *) override
Removes a Pawn from the field and updates the pawnsCount grid.
Definition field.cpp:380
void addPawnToSwap(Pawn *, const Coordinates &)
Adds a Pawn to the set of pawnsToSwap.
Definition field.cpp:453
Cursor manipulation header file.
Sista library namespace.
Definition ansi.cpp:31
Effect
Enumeration for handling out-of-bounds coordinates.
Definition field.hpp:55
Definition coordinates.hpp:120
Pawn class header file.
Represents 2D coordinates with x and y values.
Definition coordinates.hpp:36
Class representing a terminal cursor for movement operations.
Definition cursor.hpp:137
Represents a movement path for a Pawn, including priority handling.
Definition field.hpp:621
bool operator==(const Path &) const
Overloaded operator to check if two paths are equal (same begin and end coordinates).
Definition field.cpp:345
int priority
Definition field.hpp:623
Coordinates end
Definition field.hpp:625
bool operator|(const Path &) const
Overloaded operator to check if two paths are opposite (reverse of each other).
Definition field.cpp:336
static long long int current_priority
Definition field.hpp:622
bool operator<(const Path &) const
Overloaded operator to compare paths based on priority.
Definition field.cpp:342
Pawn * pawn
Definition field.hpp:626
Coordinates begin
Definition field.hpp:624
std::size_t operator()(const sista::Path &k) const noexcept
Definition field.hpp:688