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; }