public static int EstimatedEuclideanDistanceFromX10(pos p1,pos p2) { return EstimatedEuclideanDistanceFromX10(p1.r,p1.c,p2.r,p2.c); }
/*public int RotateDir(int dir,bool clockwise){ return RotateDir(dir,clockwise,1); } public int RotateDir(int dir,bool clockwise,int times){ if(dir == 5){ return 5; } for(int i=0;i<times;++i){ switch(dir){ case 7: dir = clockwise?8:4; break; case 8: dir = clockwise?9:7; break; case 9: dir = clockwise?6:8; break; case 4: dir = clockwise?7:1; break; case 6: dir = clockwise?3:9; break; case 1: dir = clockwise?4:2; break; case 2: dir = clockwise?1:3; break; case 3: dir = clockwise?2:6; break; default: return 0; } } return dir; } public pos PosInDir(int r,int c,int dir){ return PosInDir(new pos(r,c),dir); } public pos PosInDir(pos p,int dir){ switch(dir){ case 7: return new pos(p.r-1,p.c-1); case 8: return new pos(p.r-1,p.c); case 9: return new pos(p.r-1,p.c+1); case 4: return new pos(p.r,p.c-1); case 5: return p; case 6: return new pos(p.r,p.c+1); case 1: return new pos(p.r+1,p.c-1); case 2: return new pos(p.r+1,p.c); case 3: return new pos(p.r+1,p.c+1); default: return new pos(-1,-1); } }*/ public void RemoveDiagonals() { List<pos> walls = new List<pos>(); for(int i=1;i<H-2;++i){ for(int j=1;j<W-2;++j){ if(ConvertedChar(map[i,j]) == "." && ConvertedChar(map[i,j+1]) == "#"){ if(ConvertedChar(map[i+1,j]) == "#" && ConvertedChar(map[i+1,j+1]) == "."){ walls.Add(new pos(i,j+1)); walls.Add(new pos(i+1,j)); } } if(ConvertedChar(map[i,j]) == "#" && ConvertedChar(map[i,j+1]) == "."){ if(ConvertedChar(map[i+1,j]) == "." && ConvertedChar(map[i+1,j+1]) == "#"){ walls.Add(new pos(i,j)); walls.Add(new pos(i+1,j+1)); } } if(walls.Count > 0){ pos wall0 = walls[0]; pos wall1 = walls[1]; while(walls.Count > 0){ pos p = walls[Roll(walls.Count)-1]; walls.Remove(p); int direction_of_other_wall = 0; string[] rotated = new string[8]; for(int ii=0;ii<8;++ii){ rotated[ii] = Map(PosInDir(p,RotateDir(8,true,ii))); pos other_wall = new pos(-1,-1); if(p.r == wall0.r && p.c == wall0.c){ other_wall = wall1; } else{ other_wall = wall0; } if(PosInDir(p,RotateDir(8,true,ii)).r == other_wall.r && PosInDir(p,RotateDir(8,true,ii)).c == other_wall.c){ direction_of_other_wall = RotateDir(8,true,ii); } } int successive_walls = 0; for(int ii=5;ii<8;++ii){ if(ConvertedChar(rotated[ii]) == "#"){ successive_walls++; } else{ successive_walls = 0; } } for(int ii=0;ii<8;++ii){ if(ConvertedChar(rotated[ii]) == "#"){ successive_walls++; } else{ successive_walls = 0; } if((successive_walls == 4) || (ConvertedChar(Map(PosInDir(p,RotateDir(direction_of_other_wall,true,3)))) == "#" && ConvertedChar(Map(PosInDir(p,RotateDir(direction_of_other_wall,true,4)))) == "#" && ConvertedChar(Map(PosInDir(p,RotateDir(direction_of_other_wall,true,5)))) == "#")){ map[p.r,p.c] = "i"; if(IsLegal(p.r,p.c)){ walls.Clear(); } else{ map[p.r,p.c] = "#"; } break; } } } } } } }
public bool Equals(pos tgt) { return tgt != null && r == tgt.r && c == tgt.c; }
public bool IsCorridor(pos p) { if(!IsRoom(p) && ConvertedChar(Map(p)) != "#"){ return true; } return false; }
public bool IsRoom(pos p) { if(!IsRoomOrGenericFloor(Map(p))){ return false; } for(int i=2;i<=8;i+=2){ if(IsRoomOrGenericFloor(Map(PosInDir(p,i))) && IsRoomOrGenericFloor(Map(PosInDir(p,RotateDir(i,true,1)))) && IsRoomOrGenericFloor(Map(PosInDir(p,RotateDir(i,true,2))))){ return true; } } return false; }
public string FindFloorType(int r,int c) { pos p = new pos(r,c); if(ConvertedChar(Map(p)) != "."){ return ConvertedChar(Map(p)); } if(IsRoom(r,c)){ //int num_walls = ForEachDirection(r,c,ch => ConvertedChar(ch)=="#",true); int num_walls = 0; for(int i=1;i<=8;++i){ int dir = i; if(dir == 5){ dir = 9; } if(!IsRoom(PosInDir(p,dir))){ ++num_walls; } } if(num_walls == 0){ return "r"; } int num_dirs_with_walls = 0; for(int i=2;i<=8;i+=2){ if(!IsRoom(PosInDir(p,i)) && !IsRoom(PosInDir(p,RotateDir(i,true,1))) && !IsRoom(PosInDir(p,RotateDir(i,false,1)))){ num_dirs_with_walls++; } } if(num_walls == 3 && num_dirs_with_walls == 1){ return "E"; } if(num_walls == 5 && num_dirs_with_walls == 2){ return "c"; } } else{ if(ConvertedChar(Map(PosInDir(p,8))) == "#" && ConvertedChar(Map(PosInDir(p,2))) == "#"){ return "h"; } if(ConvertedChar(Map(PosInDir(p,4))) == "#" && ConvertedChar(Map(PosInDir(p,6))) == "#"){ return "v"; } if(ConvertedChar(Map(PosInDir(p,1))) == "#" && ConvertedChar(Map(PosInDir(p,9))) == "#"){ return "i"; } if(ConvertedChar(Map(PosInDir(p,7))) == "#" && ConvertedChar(Map(PosInDir(p,3))) == "#"){ return "i"; } } return "N"; }
public string Map(pos p) { return map[p.r,p.c]; }
public bool CreateCorridor(int rr,int rc,int count,int dir) { bool result = false; pos endpoint = new pos(rr,rc); pos potential_endpoint; List<pos> chain = null; if(count > 1){ chain = new List<pos>(); } int tries = 0; while(count > 0 && tries < 100){ //assume there's no room for a corridor if it fails 25 times in a row tries++; rr = endpoint.r; rc = endpoint.c; potential_endpoint = endpoint; if(chain != null && chain.Count > 0){ //reroll direction ONLY after the first part of the chain. dir = Roll(4)*2; } //int length = Roll(5)+2; //again, these 2 lines are still accurate, but have been generalized for //if(CoinFlip()){ length += 8; } //testing purposes below: int length = Roll(corridor_length_max - (corridor_length_min-1)) + (corridor_length_min-1); if(CoinFlip()){ length += corridor_length_addition; } switch(dir){ case 8: //make them all point either down.. dir = 2; rr -= length-1; potential_endpoint.r = rr; break; case 2: potential_endpoint.r += length-1; break; case 4: //..or right dir = 6; rc -= length-1; potential_endpoint.c = rc; break; case 6: potential_endpoint.c += length-1; break; } switch(dir){ case 2: { bool valid_position = true; for(int i=rr;i<rr+length;++i){ if(!BoundsCheck(i,rc)){ valid_position = false; break; } if(true/*corridor_chains_overlap_themselves == false*/){ if(chain != null && chain.Count > 0 && i != endpoint.r && chain.Contains(new pos(i,rc))){ valid_position = false; break; } } } if(valid_position){ string[] submap = new string[length+2]; for(int i=0;i<length+2;++i){ submap[i] = map[i+rr-1,rc]; } bool good = true; for(int i=0;i<length;++i){ if(map[i+rr,rc] == "h" || map[i+rr,rc-1] == "h" || map[i+rr,rc+1] == "h"){ map[i+rr,rc] = "i"; } else{ switch(map[i+rr,rc]){ case "i": case "E": case "r": break; case "c": if(allow_all_corner_connections == false){ good = false; } break; case "X": good = false; break; default: map[i+rr,rc] = "v"; break; } } } if(good && map[rr-1,rc] == "h"){ map[rr-1,rc] = "i"; } if(good && map[rr+length,rc] == "h"){ map[rr+length,rc] = "i"; } for(int i=rr-1;i<rr+length+1 && good;++i){ //note that it doesn't check the bottom or right, since for(int j=rc-1;j<rc+2;++j){ //they are checked by the others if(i != rr+length && j != rc+1){ if(ConvertedChar(map[i,j]) == "."){ if(ConvertedChar(map[i,j+1]) == "." && ConvertedChar(map[i+1,j]) == "." && ConvertedChar(map[i+1,j+1]) == "."){ good = false; break; } } } if(!IsLegal(i,j)){ good = false; break; } } } /*Draw(); if(chain != null){ foreach(pos p in chain){ Console.SetCursorPosition(25+p.c,p.r); if(ConvertedChar(map[p.r,p.c]) == "."){ Console.Write("X"); } else{ Console.Write("x"); } } } Console.ReadKey(true);*/ if(!good){ //if this addition is illegal... for(int i=0;i<length+2;++i){ map[i+rr-1,rc] = submap[i]; } } else{ count--; tries = 0; if(chain != null){ if(chain.Count == 0){ chain.Add(endpoint); } for(int i=rr;i<rr+length;++i){ pos p = new pos(i,rc); if(!(p.Equals(endpoint))){ chain.Add(p); } } } endpoint = potential_endpoint; result = true; } } break; } case 6: { bool valid_position = true; for(int j=rc;j<rc+length;++j){ if(!BoundsCheck(rr,j)){ valid_position = false; break; } if(true/*corridor_chains_overlap_themselves == false*/){ if(chain != null && chain.Count > 0 && j != endpoint.c && chain.Contains(new pos(rr,j))){ valid_position = false; break; } } } if(valid_position){ string[] submap = new string[length+2]; for(int j=0;j<length+2;++j){ submap[j] = map[rr,j+rc-1]; } bool good = true; for(int j=0;j<length;++j){ if(map[rr,j+rc] == "v" || map[rr-1,j+rc] == "v" || map[rr+1,j+rc] == "v"){ map[rr,j+rc] = "i"; } else{ switch(map[rr,j+rc]){ case "i": case "E": case "r": break; case "c": if(allow_all_corner_connections == false){ good = false; } break; case "X": good = false; break; default: map[rr,j+rc] = "h"; break; } } } if(good && map[rr,rc-1] == "v"){ map[rr,rc-1] = "i"; } if(good && map[rr,rc+length] == "v"){ map[rr,rc+length] = "i"; } for(int i=rr-1;i<rr+2 && good;++i){ //note that it doesn't check the bottom or right, since for(int j=rc-1;j<rc+length+1;++j){ //they are checked by the others if(i != rr+1 && j != rc+length){ if(IsCorridor(map[i,j])){ if(IsCorridor(map[i,j+1]) && IsCorridor(map[i+1,j]) && IsCorridor(map[i+1,j+1])){ good = false; break; } } } if(!IsLegal(i,j)){ good = false; break; } } } /*Draw(); if(chain != null){ foreach(pos p in chain){ Console.SetCursorPosition(25+p.c,p.r); if(ConvertedChar(map[p.r,p.c]) == "."){ Console.Write("X"); } else{ Console.Write("x"); } } } Console.ReadKey(true);*/ if(!good){ //if this addition is illegal... for(int j=0;j<length+2;++j){ map[rr,j+rc-1] = submap[j]; } } else{ count--; tries = 0; if(chain != null){ if(chain.Count == 0){ chain.Add(endpoint); } for(int j=rc;j<rc+length;++j){ pos p = new pos(rr,j); if(!(p.Equals(endpoint))){ chain.Add(p); } } } endpoint = potential_endpoint; result = true; } } break; } } } return result; }
public static pos PosInDir(pos p,int dir) { switch(dir){ case 7: return new pos(p.r-1,p.c-1); case 8: return new pos(p.r-1,p.c); case 9: return new pos(p.r-1,p.c+1); case 4: return new pos(p.r,p.c-1); case 5: return p; case 6: return new pos(p.r,p.c+1); case 1: return new pos(p.r+1,p.c-1); case 2: return new pos(p.r+1,p.c); case 3: return new pos(p.r+1,p.c+1); default: return new pos(-1,-1); } }
public void AddFirePits() { int num_firepits = 0; switch(Roll(5)){ case 1: num_firepits = 1; break; case 2: num_firepits = Roll(4)+1; break; } for(int i=0;i<num_firepits;++i){ int tries = 0; for(bool done=false;!done && tries < 100;++tries){ int rr = Roll(H-4) + 1; int rc = Roll(W-4) + 1; if(ConvertedChar(map[rr,rc]) == "."){ bool floors = true; pos temp = new pos(rr,rc); for(int ii=1;ii<=8;++ii){ int dir = ii; if(dir == 5){ dir = 9; } if(ConvertedChar(Map(PosInDir(temp,dir))) != "."){ floors = false; break; } } if(floors){ map[rr,rc] = "0"; done = true; } } } } }