Skip to content

Instantly share code, notes, and snippets.

@jweinst1
Last active December 19, 2024 06:25
Show Gist options
  • Save jweinst1/c1fbeec4a6fb1faee4bf43aee5f3aba6 to your computer and use it in GitHub Desktop.
Save jweinst1/c1fbeec4a6fb1faee4bf43aee5f3aba6 to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <cstdio>
#include <vector>
enum class Color {
Red,
Blue,
Yellow
};
struct State {
bool deleted = false;
};
class Square {
public:
State state;
int xPos = 0;
int xVeloc = 0;
//int xMaxVeloc = 10;
int xAcc = 0;
int yPos = 0;
int yVeloc = 0;
//int yMaxVeloc = 10;
int yAcc = 0;
int width = 20;
int length = 20;
virtual ~Square(){}
void advancePos() {
xVeloc += xAcc;
xPos += xVeloc;
yVeloc += yAcc;
yPos += yVeloc;
}
void revertPos() {
xPos -= xVeloc;
xVeloc -= xAcc;
yPos -= yVeloc;
yVeloc -= yAcc;
}
int getXEnd() const {
return xPos + width;
}
int getYEnd() const {
return yPos + length;
}
bool collidesWith(const Square* other) {
return (xPos <= (other->xPos + other->width)) && ((xPos + width) >= other->xPos) && (yPos <= (other->yPos + other->length)) && ((yPos + length) >= other->yPos);
// (R1.topLeft.x < R2.bottomRight.x) && (R1.bottomRight.x > R2.topLeft.x) && (R1.topLeft.y < R2.bottomRight.y) && (R1.bottomRight.y > R2.topLeft.y),
}
void print() const {
printf("SQ: x %d xv %d w %d y %d yv %d l %d\n", xPos, xVeloc, width, yPos, yVeloc, length);
}
virtual void sideEffect(Square* collider) {
(void)collider;
revertPos();
}
};
class FragileSquare : public Square {
void sideEffect(Square* collider) override {
(void)collider;
state.deleted = true;
}
};
struct Collision {
Square* s1 = nullptr;
Square* s2 = nullptr;
Collision(Square* s1 = nullptr, Square* s2 = nullptr): s1(s1), s2(s2) {}
void print() {
printf("COLL: \n");
s1->print();
s2->print();
printf("COLL END: \n");
}
};
struct Board {
int xSize = 100;
int ySize = 100;
size_t tickCount = 0;
std::vector<Square*> _squares;
std::vector<Collision> _colls;
void addSquare(Square* sq) {
_squares.push_back(sq);
}
void processMovement() {
for (auto* square : _squares)
{
square->advancePos();
}
}
void gatherCollisions() {
_colls.clear();
for (size_t i = 0; i < _squares.size() - 1; ++i) {
for (size_t j = i + 1; j < _squares.size(); ++j) {
if (_squares[i]->collidesWith(_squares[j])) {
_colls.emplace_back(_squares[i], _squares[j]);
}
}
}
}
void processCollisions() {
printf("Tick %zu\n", tickCount);
for (auto& coll : _colls) {
coll.print();
coll.s1->sideEffect(coll.s2);
coll.s2->sideEffect(coll.s1);
}
}
void processDeletes() {
auto it = _squares.begin();
while (it != _squares.end()) {
if ((*it)->state.deleted) {
it = _squares.erase(it);
} else {
++it;
}
}
}
void tick() {
processMovement();
gatherCollisions();
processCollisions();
processDeletes();
++tickCount;
}
};
static unsigned _failures = 0;
static void check_cond(int cond, const char* condstr, unsigned line) {
if (!cond) {
fprintf(stderr, "Failed cond '%s' at line %u\n", condstr, line);
++_failures;
}
}
#define CHECKIT(cnd) check_cond(cnd, #cnd, __LINE__)
static void testCollides() {
Square* s1 = new Square();
Square* s1c = new Square();
*s1c = *s1;
s1->xVeloc = 5;
s1->xPos = 4;
s1->width = 20;
s1->advancePos();
Square* s2 = new Square();
*s2 = *s1;
s1c->print();
s2->print();
CHECKIT(s2->collidesWith(s1c));
s2->xVeloc = 20;
s2->advancePos();
s2->print();
CHECKIT(!s2->collidesWith(s1c));
}
static void testBoardCollides() {
Square* s1 = new Square();
s1->xVeloc = 5;
s1->xPos = 4;
s1->width = 5;
s1->length = 5;
Square* s2 = new Square();
s2->xVeloc = 0;
s2->xPos = 15;
s2->width = 2;
s2->length = 5;
Board b1;
CHECKIT(b1._colls.size() == 0);
b1.addSquare(s1);
b1.addSquare(s2);
b1.tick();
CHECKIT(b1._colls.size() == 0);
b1.tick();
CHECKIT(b1._colls.size() == 1);
std::vector<Collision> prevColls = b1._colls;
b1.tick();
CHECKIT(b1._colls.size() == 1);
CHECKIT(prevColls[0].s1 == b1._colls[0].s1);
}
static void testCustomSideEffect() {
Square* s1 = new Square();
s1->xVeloc = 5;
s1->xPos = 4;
s1->width = 5;
s1->length = 5;
FragileSquare* s2 = new FragileSquare();
s2->xVeloc = 0;
s2->xPos = 15;
s2->width = 2;
s2->length = 5;
Board b1;
CHECKIT(b1._colls.size() == 0);
b1.addSquare(s1);
b1.addSquare(s2);
b1.tick();
CHECKIT(b1._colls.size() == 0);
CHECKIT(b1._squares.size() == 2);
b1.tick();
CHECKIT(b1._colls.size() == 1);
CHECKIT(b1._squares.size() == 1);
}
int main(int argc, char const *argv[])
{
testCollides();
testBoardCollides();
testCustomSideEffect();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment