Last active
December 19, 2024 06:25
-
-
Save jweinst1/c1fbeec4a6fb1faee4bf43aee5f3aba6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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