|
|
@ -5,7 +5,7 @@ |
|
|
|
#define OLC_IMAGE_STB |
|
|
|
#define OLC_IMAGE_STB |
|
|
|
#define OLC_PGE_APPLICATION |
|
|
|
#define OLC_PGE_APPLICATION |
|
|
|
#include "olcPixelGameEngine.h" |
|
|
|
#include "olcPixelGameEngine.h" |
|
|
|
|
|
|
|
#include <optional> |
|
|
|
using namespace olc; |
|
|
|
using namespace olc; |
|
|
|
|
|
|
|
|
|
|
|
enum Run{ |
|
|
|
enum Run{ |
|
|
@ -51,18 +51,21 @@ struct Pipe{ |
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<Pipe>>tiles; |
|
|
|
std::vector<std::vector<Pipe>>tiles; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<vi2d>pipeEdges; |
|
|
|
|
|
|
|
|
|
|
|
vi2d startingPipe; |
|
|
|
vi2d startingPipe; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int tileCounts=0; |
|
|
|
|
|
|
|
|
|
|
|
std::optional<Pipe*>GetPipe(vi2d coords){ |
|
|
|
std::optional<Pipe*>GetPipe(vi2d coords){ |
|
|
|
if(coords.x<0||coords.y<0||coords.y>=tiles.size()||coords.x>=tiles[coords.y].size())return {}; |
|
|
|
if(coords.x<0||coords.y<0||coords.y>=tiles.size()||coords.x>=tiles[coords.y].size())return {}; |
|
|
|
return &tiles[coords.y][coords.x]; |
|
|
|
return &tiles[coords.y][coords.x]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::vector<vi2d>tilesRemaining; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MarkAndMove(vi2d&pos,Direction dir){ |
|
|
|
void MarkAndMove(vi2d&pos,Direction dir){ |
|
|
|
tiles[pos.y][pos.x].partOfLoop=true; |
|
|
|
tiles[pos.y][pos.x].partOfLoop=true; |
|
|
|
tiles[pos.y][pos.x].traversed=true; |
|
|
|
tiles[pos.y][pos.x].traversed=true; |
|
|
|
|
|
|
|
pipeEdges.push_back(pos); |
|
|
|
switch(dir){ |
|
|
|
switch(dir){ |
|
|
|
case UP:{ |
|
|
|
case UP:{ |
|
|
|
pos.y-=1; |
|
|
|
pos.y-=1; |
|
|
@ -117,6 +120,41 @@ void AddPipe(std::string row1,std::string row2,std::string row3,std::vector<Pipe |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool HitEdge(vi2d coord,Direction dir){ |
|
|
|
|
|
|
|
while(true){ |
|
|
|
|
|
|
|
switch(dir){ |
|
|
|
|
|
|
|
case DOWN:coord+={0,1};break; |
|
|
|
|
|
|
|
case UP:coord+={0,-1};break; |
|
|
|
|
|
|
|
case RIGHT:coord+={1,0};break; |
|
|
|
|
|
|
|
case LEFT:coord+={-1,0};break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
auto pipe=GetPipe(coord); |
|
|
|
|
|
|
|
if(pipe){ |
|
|
|
|
|
|
|
if(pipe.value()->partOfLoop){ |
|
|
|
|
|
|
|
return false; //Hit one of our edge pipes.
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}else{ |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FloodFill(vi2d coord){ |
|
|
|
|
|
|
|
auto pipe=GetPipe(coord); |
|
|
|
|
|
|
|
if(pipe&&!pipe.value()->partOfLoop&&!pipe.value()->originalChar!=' '){ |
|
|
|
|
|
|
|
pipe.value()->originalChar=' '; |
|
|
|
|
|
|
|
auto downPipe=GetPipe(coord+vi2d{0,1}); |
|
|
|
|
|
|
|
if(downPipe&&!downPipe.value()->partOfLoop&&downPipe.value()->originalChar!=' ')FloodFill(coord+vi2d{0,1}); |
|
|
|
|
|
|
|
auto upPipe=GetPipe(coord+vi2d{0,-1}); |
|
|
|
|
|
|
|
if(upPipe&&!upPipe.value()->partOfLoop&&upPipe.value()->originalChar!=' ')FloodFill(coord+vi2d{0,-1}); |
|
|
|
|
|
|
|
auto leftPipe=GetPipe(coord+vi2d{-1,0}); |
|
|
|
|
|
|
|
if(leftPipe&&!leftPipe.value()->partOfLoop&&leftPipe.value()->originalChar!=' ')FloodFill(coord+vi2d{-1,0}); |
|
|
|
|
|
|
|
auto rightPipe=GetPipe(coord+vi2d{1,0}); |
|
|
|
|
|
|
|
if(rightPipe&&!rightPipe.value()->partOfLoop&&rightPipe.value()->originalChar!=' ')FloodFill(coord+vi2d{1,0}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void doStuff2(){ |
|
|
|
void doStuff2(){ |
|
|
|
while(true){ //lines is accessible as a global.
|
|
|
|
while(true){ //lines is accessible as a global.
|
|
|
|
for(std::string&line:lines){ |
|
|
|
for(std::string&line:lines){ |
|
|
@ -176,11 +214,14 @@ void doStuff2(){ |
|
|
|
throw; |
|
|
|
throw; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
tileCounts++; |
|
|
|
} |
|
|
|
} |
|
|
|
tiles.push_back(upperRow); |
|
|
|
tiles.push_back(upperRow); |
|
|
|
tiles.push_back(middleRow); |
|
|
|
tiles.push_back(middleRow); |
|
|
|
tiles.push_back(lowerRow); |
|
|
|
tiles.push_back(lowerRow); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::cout<<tileCounts<<std::endl; |
|
|
|
|
|
|
|
|
|
|
|
//tilesRemaining.push_back(startingPipe);
|
|
|
|
//tilesRemaining.push_back(startingPipe);
|
|
|
|
auto initialPipe=GetPipe(startingPipe); |
|
|
|
auto initialPipe=GetPipe(startingPipe); |
|
|
@ -212,10 +253,10 @@ void doStuff2(){ |
|
|
|
|
|
|
|
|
|
|
|
if(symbol=='\0')throw; |
|
|
|
if(symbol=='\0')throw; |
|
|
|
|
|
|
|
|
|
|
|
if(initialPipe.value()->down)tiles[startingPipe.y+2][startingPipe.x+1].originalChar=symbol; |
|
|
|
if(initialPipe.value()->down){tiles[startingPipe.y+2][startingPipe.x+1].originalChar=symbol;tiles[startingPipe.y+2][startingPipe.x+1].partOfLoop=true;} |
|
|
|
if(initialPipe.value()->right)tiles[startingPipe.y+1][startingPipe.x+2].originalChar=symbol; |
|
|
|
if(initialPipe.value()->right){tiles[startingPipe.y+1][startingPipe.x+2].originalChar=symbol;tiles[startingPipe.y+1][startingPipe.x+2].partOfLoop=true;} |
|
|
|
if(initialPipe.value()->up)tiles[startingPipe.y][startingPipe.x+1].originalChar=symbol; |
|
|
|
if(initialPipe.value()->up){tiles[startingPipe.y][startingPipe.x+1].originalChar=symbol;tiles[startingPipe.y][startingPipe.x+1].partOfLoop=true;} |
|
|
|
if(initialPipe.value()->left)tiles[startingPipe.y+1][startingPipe.x].originalChar=symbol; |
|
|
|
if(initialPipe.value()->left){tiles[startingPipe.y+1][startingPipe.x].originalChar=symbol;tiles[startingPipe.y+1][startingPipe.x].partOfLoop=true;} |
|
|
|
tiles[startingPipe.y+1][startingPipe.x+1].originalChar=symbol; |
|
|
|
tiles[startingPipe.y+1][startingPipe.x+1].originalChar=symbol; |
|
|
|
|
|
|
|
|
|
|
|
vi2d currentPos=startingPipe+vi2d{1,1}; |
|
|
|
vi2d currentPos=startingPipe+vi2d{1,1}; |
|
|
@ -248,6 +289,25 @@ void doStuff2(){ |
|
|
|
//Test runs in all directions of looped pipes, see if they hit outer walls.
|
|
|
|
//Test runs in all directions of looped pipes, see if they hit outer walls.
|
|
|
|
//If they do, starting from the wall, flood fill all adjacent tiles.
|
|
|
|
//If they do, starting from the wall, flood fill all adjacent tiles.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Start at any other edge, traverse in all directions and try to find a way out.
|
|
|
|
|
|
|
|
for(vi2d&coord:pipeEdges){ |
|
|
|
|
|
|
|
//Try to draw a line going in all directions and see if we hit an edge.
|
|
|
|
|
|
|
|
vi2d tempCoord=coord; |
|
|
|
|
|
|
|
if(HitEdge(coord,DOWN)){std::cout<<"Flood Fill from "<<coord+vi2d{0,1}<<std::endl;FloodFill(coord+vi2d{0,1});break;} |
|
|
|
|
|
|
|
if(HitEdge(coord,UP)){std::cout<<"Flood Fill from "<<coord+vi2d{0,-1}<<std::endl;FloodFill(coord+vi2d{0,-1});break;} |
|
|
|
|
|
|
|
if(HitEdge(coord,RIGHT)){std::cout<<"Flood Fill from "<<coord+vi2d{1,0}<<std::endl;FloodFill(coord+vi2d{1,0});break;} |
|
|
|
|
|
|
|
if(HitEdge(coord,LEFT)){std::cout<<"Flood Fill from "<<coord+vi2d{-1,0}<<std::endl;FloodFill(coord+vi2d{-1,0});break;} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int y=0;y<tiles.size()/3;y++){ |
|
|
|
|
|
|
|
for(int x=0;x<tiles[y].size()/3;x++){ |
|
|
|
|
|
|
|
vi2d coords=vi2d{x,y}*3+vi2d{1,1}; |
|
|
|
|
|
|
|
if(tiles[coords.y][coords.x].originalChar==' '||tiles[coords.y][coords.x].partOfLoop)tileCounts--; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::cout<<tileCounts<<std::endl; |
|
|
|
|
|
|
|
|
|
|
|
wait(0); |
|
|
|
wait(0); |
|
|
|
break; |
|
|
|
break; |
|
|
|
//Wait for 0ms and render the screen (calls draw())
|
|
|
|
//Wait for 0ms and render the screen (calls draw())
|
|
|
@ -381,7 +441,7 @@ public: |
|
|
|
int main() |
|
|
|
int main() |
|
|
|
{ |
|
|
|
{ |
|
|
|
AoC2023 game; |
|
|
|
AoC2023 game; |
|
|
|
if (game.Construct(3360,3360, 2, 2)) |
|
|
|
if (game.Construct(480,480, 2, 2)) |
|
|
|
game.Start(); |
|
|
|
game.Start(); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|