generated from sigonasr2/CPlusPlusProjectTemplate
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
8.5 KiB
288 lines
8.5 KiB
#define OLC_PGE_APPLICATION
|
|
#include "pixelGameEngine.h"
|
|
#include "olcutils.h"
|
|
|
|
using namespace olc;
|
|
|
|
|
|
vi2d upperLeftCoords={500,0};
|
|
vi2d lowerRightCoords={500,0};
|
|
std::vector<std::vector<char>>board;
|
|
int sum=0;
|
|
float timePerTick=0.03;
|
|
int frameSkips=0;
|
|
float acc=0;
|
|
float acc2=0;
|
|
vi2d sandCoord={500,0};
|
|
bool simulationDone=false;
|
|
bool showVisual=true;
|
|
float viewX=0;
|
|
|
|
struct Connection{
|
|
std::vector<vi2d>coords;
|
|
};
|
|
|
|
enum ReadState{
|
|
READX,
|
|
READY,
|
|
WAIT
|
|
};
|
|
|
|
vi2d getArrayCoords(vi2d pos){
|
|
return pos-upperLeftCoords;
|
|
}
|
|
|
|
char getBoard(vi2d pos){
|
|
vi2d actualCoords=getArrayCoords(pos);
|
|
if (actualCoords.x<0){
|
|
for (int i=0;i<board.size();i++){
|
|
board[i].insert(board[i].begin(),' ');
|
|
}
|
|
upperLeftCoords.x--;
|
|
|
|
for (int x=0;x<board[0].size();x++){
|
|
board[board.size()-1][x]='#';
|
|
}
|
|
}
|
|
if (actualCoords.y<0){
|
|
std::vector<char>newRow;
|
|
for (int i=0;i<board[0].size();i++){
|
|
newRow.push_back(' ');
|
|
}
|
|
board.insert(board.begin(),newRow);
|
|
upperLeftCoords.y--;
|
|
}
|
|
if (actualCoords.x>=board[0].size()){
|
|
for (int i=0;i<board.size();i++){
|
|
board[i].push_back(' ');
|
|
}
|
|
lowerRightCoords.x++;
|
|
|
|
for (int x=0;x<board[0].size();x++){
|
|
board[board.size()-1][x]='#';
|
|
}
|
|
}
|
|
if (actualCoords.y>=board.size()){
|
|
std::vector<char>newRow;
|
|
for (int i=0;i<board[0].size();i++){
|
|
newRow.push_back(' ');
|
|
}
|
|
board.push_back(newRow);
|
|
lowerRightCoords.y++;
|
|
}
|
|
return board[actualCoords.y][actualCoords.x];
|
|
}
|
|
|
|
void modifyBoard(vi2d pos,char val){
|
|
vi2d actualCoords=getArrayCoords(pos);
|
|
board[actualCoords.y][actualCoords.x]=val;
|
|
}
|
|
|
|
class SandSim : public olc::PixelGameEngine
|
|
{
|
|
public:
|
|
SandSim()
|
|
{
|
|
sAppName = "AoC Day 14 Part II";
|
|
}
|
|
|
|
public:
|
|
bool OnUserCreate() override
|
|
{
|
|
// Called once at the start, so create things here
|
|
return true;
|
|
}
|
|
|
|
void updateGame(){
|
|
if (!simulationDone){
|
|
vi2d boardCoords=getArrayCoords(sandCoord);
|
|
if (getBoard({sandCoord.x,sandCoord.y+1})==' '){
|
|
//Fall straight down.
|
|
sandCoord.y++;
|
|
} else
|
|
if (getBoard({sandCoord.x-1,sandCoord.y+1})==' '){
|
|
sandCoord.x--;
|
|
sandCoord.y++;
|
|
} else
|
|
if (getBoard({sandCoord.x+1,sandCoord.y+1})==' '){
|
|
sandCoord.x++;
|
|
sandCoord.y++;
|
|
} else
|
|
if (sandCoord==vi2d{500,0}){
|
|
sum++;
|
|
simulationDone=true;
|
|
} else {
|
|
if (!simulationDone){
|
|
sum++;
|
|
modifyBoard(sandCoord,'.');
|
|
sandCoord={500,0};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool OnUserUpdate(float fElapsedTime) override
|
|
{
|
|
acc+=fElapsedTime;
|
|
acc2+=fElapsedTime;
|
|
if (acc>=timePerTick){
|
|
acc-=timePerTick;
|
|
int framesToSkip=frameSkips;
|
|
while (framesToSkip-->0){
|
|
updateGame();
|
|
}
|
|
}
|
|
if (acc2>=0.01){
|
|
if (GetKey(RIGHT).bHeld){
|
|
timePerTick=std::clamp(timePerTick+0.001f,0.f,1.f);
|
|
acc2=0;
|
|
}
|
|
if (GetKey(LEFT).bHeld){
|
|
timePerTick=std::clamp(timePerTick-0.001f,0.f,1.f);
|
|
acc2=0;
|
|
}
|
|
if (GetKey(A).bHeld){
|
|
viewX-=60*fElapsedTime;
|
|
}
|
|
if (GetKey(D).bHeld){
|
|
viewX+=60*fElapsedTime;
|
|
}
|
|
if (GetKey(W).bHeld){
|
|
frameSkips=std::clamp(frameSkips+1,0,1000);
|
|
}
|
|
if (GetKey(S).bHeld){
|
|
frameSkips=std::clamp(frameSkips-1,0,1000);
|
|
}
|
|
}
|
|
if (GetKey(SPACE).bPressed){
|
|
showVisual=!showVisual;
|
|
}
|
|
|
|
|
|
DrawStringDecal({0,0},std::to_string((int)(timePerTick*1000))+"ms");
|
|
DrawStringDecal({1,(float)(ScreenHeight()-GetTextSize("S").y*0.4)-1},"Sand Pieces: "+std::to_string(sum),BLACK,{0.4,0.4});
|
|
DrawStringDecal({0,(float)(ScreenHeight()-GetTextSize("S").y*0.4)},"Sand Pieces: "+std::to_string(sum),WHITE,{0.4,0.4});
|
|
if (showVisual) {
|
|
// called once per frame
|
|
for (int x = std::max(0,(int)(upperLeftCoords.x-viewX)); x <= std::min(lowerRightCoords.x,(int)(upperLeftCoords.x-viewX+ScreenWidth())); x++){
|
|
for (int y = upperLeftCoords.y; y <= lowerRightCoords.y; y++){
|
|
vi2d coords=getArrayCoords({x,y});
|
|
if (x==sandCoord.x&&y==sandCoord.y){
|
|
Draw(coords.x+viewX, coords.y,YELLOW);
|
|
} else {
|
|
Draw(coords.x+viewX, coords.y,
|
|
(board[coords.y][coords.x]==' ')?Pixel(40,40,40):
|
|
(board[coords.y][coords.x]=='.')?DARK_YELLOW:
|
|
Pixel(255,255,255));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
int main()
|
|
{
|
|
std::vector<Connection>connections;
|
|
std::ifstream file("input");
|
|
ReadState state=READX;
|
|
while (file.good()){
|
|
std::string line;
|
|
std::getline(file,line);
|
|
std::string num1;
|
|
std::string num2;
|
|
if (line.length()>0){
|
|
state=READX;
|
|
Connection c;
|
|
for (int i=0;i<line.length();i++){
|
|
switch (state){
|
|
case READX:{
|
|
if (line[i]==','){
|
|
state=READY;
|
|
break;
|
|
}
|
|
num1+=line[i];
|
|
}break;
|
|
case READY:{
|
|
if (line[i]==' '){
|
|
state=WAIT;
|
|
int numb1=std::atoi(num1.c_str());
|
|
int numb2=std::atoi(num2.c_str());
|
|
c.coords.push_back({numb1,numb2});
|
|
upperLeftCoords.x=std::min(numb1,upperLeftCoords.x);
|
|
upperLeftCoords.y=std::min(numb2,upperLeftCoords.y);
|
|
lowerRightCoords.x=std::max(numb1,lowerRightCoords.x);
|
|
lowerRightCoords.y=std::max(numb2,lowerRightCoords.y);
|
|
std::cout<<"read "<<num1<<"//"<<num2<<std::endl;
|
|
num1="";
|
|
num2="";
|
|
break;
|
|
}
|
|
num2+=line[i];
|
|
}break;
|
|
case WAIT:{
|
|
if (line[i]==' '){
|
|
state=READX;
|
|
break;
|
|
}
|
|
}break;
|
|
}
|
|
}
|
|
int numb1=std::atoi(num1.c_str());
|
|
int numb2=std::atoi(num2.c_str());
|
|
c.coords.push_back({numb1,numb2});
|
|
upperLeftCoords.x=std::min(numb1,upperLeftCoords.x);
|
|
upperLeftCoords.y=std::min(numb2,upperLeftCoords.y);
|
|
lowerRightCoords.x=std::max(numb1,lowerRightCoords.x);
|
|
lowerRightCoords.y=std::max(numb2,lowerRightCoords.y);
|
|
std::cout<<"read "<<num1<<"//"<<num2<<std::endl;
|
|
num1="";
|
|
num2="";
|
|
connections.push_back(c);
|
|
}
|
|
std::cout<<line<<std::endl;
|
|
}
|
|
|
|
lowerRightCoords.y+=2;
|
|
|
|
std::cout<<"Upper-Left Bounds: "<<upperLeftCoords<<std::endl;
|
|
std::cout<<"Lower-Right Bounds: "<<lowerRightCoords<<std::endl;
|
|
|
|
|
|
for (int y=upperLeftCoords.y;y<=lowerRightCoords.y;y++){
|
|
std::vector<char>b;
|
|
for (int x=upperLeftCoords.x;x<=lowerRightCoords.x;x++){
|
|
b.push_back(' ');
|
|
}
|
|
board.push_back(b);
|
|
}
|
|
|
|
for(int i=0;i<connections.size();i++){
|
|
Connection&c=connections[i];
|
|
vi2d&startPos=c.coords[0];
|
|
for (int j=1;j<c.coords.size();j++){
|
|
vi2d&endPos=c.coords[j];
|
|
modifyBoard(startPos,'#');
|
|
while (startPos!=endPos){
|
|
if (startPos.x!=endPos.x){
|
|
startPos.x+=(endPos.x-startPos.x)/std::abs(startPos.x-endPos.x);
|
|
}
|
|
if (startPos.y!=endPos.y){
|
|
startPos.y+=(endPos.y-startPos.y)/std::abs(startPos.y-endPos.y);
|
|
}
|
|
modifyBoard(startPos,'#');
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int x=0;x<board[0].size();x++){
|
|
board[board.size()-1][x]='#';
|
|
}
|
|
|
|
SandSim demo;
|
|
if (demo.Construct(150, 172, 8, 8))
|
|
demo.Start();
|
|
|
|
return 0;
|
|
}
|
|
|