Part 1 is done!

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent ae6bf67771
commit 85eca18a60
  1. BIN
      C++ProjectTemplate
  2. 202
      input
  3. 309
      main.cpp
  4. 14
      testinput

Binary file not shown.

202
input

File diff suppressed because one or more lines are too long

@ -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;
enum Direction{
RIGHT,
DOWN,
LEFT,
UP
};
struct Instruction{
int number=-1;
Direction turn;
};
int main()
{
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;
}
}
}
}
}
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);
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 {
DrawCircle(originPoint,5,RED);
std::cout<<instructions[i].number;
}
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;
}
};
}
std::cout<<std::endl;
int main()
{
Example demo;
if (demo.Construct(128, 120, 8, 8))
demo.Start();
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;
}

@ -0,0 +1,14 @@
...#
.#..
#...
....
...#.......#
........#...
..#....#....
..........#.
...#....
.....#..
.#......
......#.
10L5L5L10L4L5L5
Loading…
Cancel
Save