Part 1 is done!

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
This commit is contained in:
sigonasr2 2022-12-22 17:56:48 -06:00
parent ae6bf67771
commit 85eca18a60
4 changed files with 454 additions and 75 deletions

Binary file not shown.

202
input Normal file

File diff suppressed because one or more lines are too long

313
main.cpp
View File

@ -4,86 +4,249 @@
using namespace olc;
class Example : public olc::PixelGameEngine
{
public:
Example()
{
sAppName = "Example";
}
public:
bool RayVsRect(const vf2d ray_origin, const vf2d ray_dir, const olc::utils::geom2d::rect<float> target, vf2d&contact_point, vf2d&contact_normal, float&t_hit_near){
contact_normal = { 0, 0 };
contact_point = { 0, 0 };
vf2d t_near = {(target.pos.x - ray_origin.x) / ray_dir.x, (target.pos.y - ray_origin.y) / ray_dir.y};
vf2d t_far = {(target.pos.x + target.size.x - ray_origin.x) / ray_dir.x, (target.pos.y + target.size.y - ray_origin.y) / ray_dir.y};
if (t_near.x > t_far.x) {float b; b = t_near.x; t_near.x = t_far.x; t_far.x = b;};
if (t_near.y > t_far.y) {float b; b = t_near.y; t_near.y = t_far.y; t_far.y = b;};
if (t_near.x > t_far.y || t_near.y > t_far.x) return false;
t_hit_near = fmax(t_near.x, t_near.y);
float t_hit_far = fmin(t_far.x, t_far.y);
if (t_hit_far < 0) return false;
contact_point.x = ray_origin.x + t_hit_near * ray_dir.x;
contact_point.y = ray_origin.y + t_hit_near * ray_dir.y;
if (t_near.x > t_near.y)
if ( 1.0f / ray_dir.x < 0)
contact_normal = { 1, 0 };
else
contact_normal = { -1, 0};
else
if ( t_near.x < t_near.y)
if ( 1.0f / ray_dir.y < 0)
contact_normal = { 0, 1 };
else
contact_normal = { 0, -1 };
return true;
}
vf2d originPoint={16,16};
bool OnUserCreate() override
{
// Called once at the start, so create things here
return true;
}
bool OnUserUpdate(float fElapsedTime) override
{
vf2d velocity={(GetKey(D).bHeld-GetKey(A).bHeld)*20*fElapsedTime,(GetKey(S).bHeld-GetKey(W).bHeld)*20*fElapsedTime};
vf2d contact_point;
vf2d contact_normal;
float t_hit_near;
Clear(Pixel(64,64,255));
if (!olc::utils::geom2d::overlaps(olc::utils::geom2d::circle<float>{originPoint+velocity,5},olc::utils::geom2d::rect<float>{{32,32},{64,32}})) {
originPoint+=velocity;
DrawCircle(originPoint,5);
} else {
DrawCircle(originPoint,5,RED);
}
DrawLine(originPoint,GetMousePos());
DrawRect({32,32},{64,32},RayVsRect(originPoint, GetMousePos()-originPoint, olc::utils::geom2d::rect<float>{{32,32},{64,32}},contact_point,contact_normal,t_hit_near)&&t_hit_near<1?YELLOW:WHITE);
return true;
}
enum Direction{
RIGHT,
DOWN,
LEFT,
UP
};
struct Instruction{
int number=-1;
Direction turn;
};
int main()
{
Example demo;
if (demo.Construct(128, 120, 8, 8))
demo.Start();
std::vector<std::vector<char>>map;
std::vector<Instruction>instructions;
std::vector<vi2d>visitedLocs;
std::ifstream file("testinput");
while (file.good()){
std::string line;
std::getline(file,line);
if (line.length()>0){
if (line[0]=='.'||line[0]==' '||line[0]=='#'){
std::vector<char>mapRow;
for (int i=0;i<line.length();i++){
mapRow.push_back(line[i]);
}
map.push_back(mapRow);
} else {
//Parse the instruction set.
bool isNumber=true;
int marker=0;
while(marker<line.length()){
if (isNumber){
std::string acc="";
while (line[marker]>='0'&&line[marker]<='9'){
acc+=line[marker++];
}
instructions.push_back({std::atoi(acc.c_str())});
isNumber=false;
} else {
switch(line[marker++]){
case 'R':{
instructions.push_back({-1,Direction::RIGHT});
}break;
case 'L':{
instructions.push_back({-1,Direction::LEFT});
}break;
}
isNumber=true;
}
}
}
}
}
for (int y=0;y<map.size();y++){
for (int x=0;x<map[y].size();x++){
std::cout<<map[y][x];
}
std::cout<<std::endl;
}
std::cout<<"============="<<std::endl;
for (int i=0;i<instructions.size();i++){
if (instructions[i].number==-1){
if (instructions[i].turn==Direction::RIGHT){
std::cout<<'R';
} else {
std::cout<<'L';
}
} else {
std::cout<<instructions[i].number;
}
}
std::cout<<std::endl;
vi2d pos={0,0};
for (int i=0;i<map[0].size();i++){
if (map[0][i]!=' '){
pos={i,0};
}
}
int instructionMarker=0;
Direction facingDir=Direction::RIGHT;
while (instructionMarker<instructions.size()){
Instruction&instruction=instructions[instructionMarker];
if (instruction.number!=-1){
std::cout<<"Moving "<<instruction.number<<" steps"<<std::endl;
int steps=instruction.number;
while (steps>0){
switch (facingDir){
case Direction::RIGHT:{
char tile=' ';
vi2d targetPos={pos.x+1,pos.y};
if (pos.x+1>=map[pos.y].size()){
for (int i=0;i<map[pos.y].size();i++){
if (map[pos.y][i]=='.'){
targetPos.x=i;
break;
} else
if (map[pos.y][i]=='#'){
//It's a dead end so we can't move. Go next.
goto next;
}
}
}
tile=map[targetPos.y][targetPos.x];
switch (tile){
case '.':{
pos=targetPos;
visitedLocs.push_back(pos);
}break;
case '#':{
goto next;
}break;
case ' ':{
//Impossible when going right.
}break;
}
}break;
case Direction::LEFT:{
char tile=' ';
vi2d targetPos={pos.x-1,pos.y};
if (pos.x-1<0||map[pos.y][pos.x-1]==' '){
if (map[pos.y][map[pos.y].size()-1]=='.'){
targetPos.x=map[pos.y].size()-1;
break;
} else
if (map[pos.y][map[pos.y].size()-1]=='#'){
//It's a dead end so we can't move. Go next.
goto next;
}
}
tile=map[targetPos.y][targetPos.x];
switch (tile){
case '.':{
pos=targetPos;
visitedLocs.push_back(pos);
}break;
case '#':{
goto next;
}break;
case ' ':{
//Impossible when going right.
}break;
}
}break;
case Direction::UP:{
char tile=' ';
vi2d targetPos={pos.x,pos.y-1};
if (pos.y-1<0||map[pos.y-1][pos.x]==' '){
for (int y=map.size()-1;y>0;y--){
if (map[y].size()>pos.x){
if (map[y][pos.x]=='.'){
targetPos.y=y;
break;
}else
if (map[y][pos.x]=='#'){
goto next;
}
}
}
}
tile=map[targetPos.y][targetPos.x];
switch (tile){
case '.':{
pos=targetPos;
visitedLocs.push_back(pos);
}break;
case '#':{
goto next;
}break;
case ' ':{
//Impossible when going right.
}break;
}
}break;
case Direction::DOWN:{
char tile=' ';
vi2d targetPos={pos.x,pos.y+1};
if (pos.y+1>=map.size()||map[pos.y+1].size()<=pos.x||map[pos.y+1][pos.x]==' '){
for (int y=0;y<map.size();y++){
if (map[y].size()>pos.x){
if (map[y][pos.x]=='.'){
std::cout<<"Found a spot. ("<<y<<")"<<std::endl;
targetPos.y=y;
break;
}else
if (map[y][pos.x]=='#'){
std::cout<<"Found a dead end. ("<<y<<")"<<std::endl;
goto next;
}
}
}
}
tile=map[targetPos.y][targetPos.x];
switch (tile){
case '.':{
pos=targetPos;
visitedLocs.push_back(pos);
}break;
case '#':{
goto next;
}break;
case ' ':{
}break;
}
}break;
}
steps--;
}
} else {
if (instruction.turn==Direction::RIGHT){
facingDir=(Direction)((facingDir+1)%4);
} else {
int dir = facingDir-1;
if (dir<0){
dir=3;
}
facingDir=(Direction)dir;
}
std::cout<<"Turned "<<(instruction.turn==Direction::RIGHT?"RIGHT":"LEFT")<<" to face "<<facingDir<<std::endl;
}
next:
instructionMarker++;
}
std::cout<<"Final position: "<<pos<<" Dir:"<<facingDir<<std::endl;
std::cout<<"Sum: "<<1000*(pos.y+1)+4*(pos.x+1)+facingDir<<std::endl;
for (int y=0;y<map.size();y++){
for (int x=0;x<map[y].size();x++){
for (int i=0;i<visitedLocs.size();i++){
if (visitedLocs[i].x==x&&visitedLocs[i].y==y){
std::cout<<'+';
goto nextit;
}
}
std::cout<<map[y][x];
nextit:;
}
std::cout<<std::endl;
}
return 0;
}

14
testinput Normal file
View File

@ -0,0 +1,14 @@
...#
.#..
#...
....
...#.......#
........#...
..#....#....
..........#.
...#....
.....#..
.#......
......#.
10L5L5L10L4L5L5