Commit ca254175 authored by Lucas Delcros's avatar Lucas Delcros
Browse files

cleaned code that generates corridors

added RoomTree
endpos is now in the farest room
parent 91077a16
......@@ -173,40 +173,34 @@ public class Map implements Serializable {
int probability=5;
for(int i=0;i<nbRooms-1;i++) {
for(int j=i+1;j<nbRooms;j++) {
LinkedList<Surface> corridors=SurfacesMapGeneration.creationCorridor(rooms[i], rooms[j]);
Surface corridors=SurfacesMapGeneration.creationCorridor(rooms[i], rooms[j]);
if(testCorridorAddPossibility(corridors,i,j)) {
if(r.nextInt(probability)==0) addCorridors(corridors);
}
}
}
}
private void addCorridors(LinkedList<Surface> corridors) {
private void addCorridors(Surface corridors) {
boolean bb=true;
for(int k=0;k<corridors.size();k++) if(!corridors.get(k).checkSurface()) bb=false;
if(!corridors.checkSurface()) bb=false;
if(bb) {
Surface[] corridorsTemp=this.corridors;
this.corridors=new Surface[corridorsTemp.length+corridors.size()];
this.corridors=new Surface[corridorsTemp.length+1];
for(int i=0;i<corridorsTemp.length;i++) {
this.corridors[i]=corridorsTemp[i];
}
for(int i=0;i<corridors.size();i++) {
this.corridors[corridorsTemp.length+i]=corridors.get(i);
}
for(int k=0;k<corridors.size();k++) {
for(int i=corridors.get(k).i1;i<corridors.get(k).i2;i++) {
for(int j=corridors.get(k).j1;j<corridors.get(k).j2;j++) {
this.corridors[corridorsTemp.length]=corridors;
for(int i=corridors.i1;i<corridors.i2;i++) {
for(int j=corridors.j1;j<corridors.j2;j++) {
map[j][i]=new Tile(TileType.GROUND,TileType.GROUND.getTilePropertyVector());
}
}
}
}
}
private boolean testCorridorAddPossibility(LinkedList<Surface> corridors,int room1,int room2) {
private boolean testCorridorAddPossibility(Surface corridor,int room1,int room2) {
boolean bb=true;
for(int k=0;k<corridors.size();k++) {
for(int i=0;i<rooms.length;i++) if(i!=room1 && i!=room2 && intersection(rooms[i],corridors.get(k))) bb=false;
for(int i=0;i<this.corridors.length;i++) if(intersection(this.corridors[i],corridors.get(k))) bb=false;
}
for(int i=0;i<rooms.length;i++) if(i!=room1 && i!=room2 && intersection(rooms[i],corridor)) bb=false;
for(int i=0;i<this.corridors.length;i++) if(intersection(this.corridors[i],corridor)) bb=false;
return(bb);
}
private static boolean intersection(Surface surface1, Surface surface2) {
......
......@@ -2,8 +2,10 @@ package map_generation.map;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import map_generation.map.RoomBuilder.RoomType;
import map_generation.tiles.TileBuilder;
import map_generation.tiles.TileType;
import core.gamestate.Entity;
......@@ -23,24 +25,27 @@ public final class MapBuilder implements Serializable{
private ArrayList<Surface> corridors;
private ArrayList<Surface> doors;
private ArrayList<Entity> entities;
private RoomTree roomTree;
private RoomBuilder start;
private MapPoint positionPlayerAtStart;
private MapPoint stairsPosition;
private int height = 0, width = 0, maxEntities = -1;
public MapBuilder() {
rooms = new ArrayList<>();
corridors = new ArrayList<>();
doors = new ArrayList<>();
entities = new ArrayList<Entity>();
}
public void addRoom(RoomBuilder room){
rooms.add(room);
public void addRooms(RoomBuilder[] rooms, RoomBuilder start){
this.rooms = new ArrayList<RoomBuilder>(Arrays.asList(rooms));
roomTree = new RoomTree(start, this.rooms);
this.start = start;
}
public void addCorridor(Surface corridor){
public void addCorridor(Surface corridor, RoomBuilder room1, RoomBuilder room2){
corridors.add(corridor);
roomTree.linkRooms(room1, room2);
}
public ArrayList<Surface> getCorridors() {
......@@ -60,6 +65,10 @@ public final class MapBuilder implements Serializable{
public int getNbRooms(){
return rooms.size();
}
private void generateEndRoom(){
RoomBuilder end=roomTree.getMostFarNode();
end.setType(RoomType.END);
}
public void setPositionPlayerAtStart(MapPoint positionPlayerAtStart) {
this.positionPlayerAtStart = positionPlayerAtStart;
}
......@@ -80,6 +89,7 @@ public final class MapBuilder implements Serializable{
* @return The map
*/
public Map build(){
generateEndRoom();
TileBuilder[][] map = SurfacesMapGeneration.emptyTiles(height, width);
int nbRooms=rooms.size();
Random r=new Random();
......@@ -91,6 +101,8 @@ public final class MapBuilder implements Serializable{
for (Surface surface: corridors) {
surface.surroundWith(map, TileType.WALL);
}
System.out.println(rooms.size());
//rooms.get(3).setType(RoomType.START);
for (RoomBuilder room : rooms) {
room.build(map, this);
}
......
......@@ -13,7 +13,7 @@ public final class RoomBuilder {
private static int NB_ENTITIES = 0;
private Surface surface;
private RoomType type;
public RoomType type;
public RoomBuilder(Surface surface, RoomType type) {
......@@ -59,7 +59,7 @@ public final class RoomBuilder {
double pp = r.nextDouble();
if( pp <= 0.5 )setType(RoomType.FULL_LAVA);
else setType(RoomType.TORCHES);
}
}
}
private void generateEntities(TileBuilder[][] tb, MapBuilder mapB, String specieName) {
Random r = new Random();
......
package map_generation.map;
import java.util.ArrayList;
import java.util.HashMap;
public class RoomTree {
private RoomNode start;
private HashMap<RoomBuilder, RoomNode> rooms;
public RoomTree(RoomBuilder start, ArrayList<RoomBuilder> rooms) {
this.rooms = new HashMap<RoomBuilder, RoomTree.RoomNode>();
for (RoomBuilder room : rooms) {
this.rooms.put(room, new RoomNode(null, room));
}
this.start = findRoom(start);
if (this.start == null) throw new IllegalArgumentException("Start is not is room list !");
}
private RoomNode findRoom(RoomBuilder room){
return rooms.get(room);
}
private void addRoomTo(RoomNode room, RoomNode fatherNode){
if(fatherNode.voisins == null) fatherNode.voisins = new ArrayList<RoomTree.RoomNode>();
else if (!fatherNode.voisins.contains(room)) fatherNode.voisins.add(room);
}
public void linkRooms(RoomBuilder room1, RoomBuilder room2){
RoomNode fatherNode = findRoom(room1);
RoomNode roomNode = findRoom(room2);
if (fatherNode == null || roomNode == null) throw new IllegalArgumentException("Wrong args : these rooms are not defined");
addRoomTo(roomNode, fatherNode);
addRoomTo(fatherNode, roomNode);
}
private void buildLength_inner(RoomNode top, int l){
if (top.ltostart > -1 && top.ltostart < l) return;
top.ltostart = l;
if(top.voisins == null ) return;
for (RoomNode voisin : top.voisins) {
if(voisin.ltostart == -1) buildLength_inner(voisin, l+1);
}
}
private void buildLength(){
buildLength_inner(start, 0);
}
private RoomNode getMostFarNode_inner (RoomNode top){
if(top.voisins == null) return top;
RoomNode find = top;
for (RoomNode voisin : top.voisins) {
if(voisin.ltostart > top.ltostart){
RoomNode t = getMostFarNode_inner(voisin);
if (t.ltostart > find.ltostart) find = t;
}
}
return find;
}
public RoomBuilder getMostFarNode(){
buildLength();
return getMostFarNode_inner(start).room;
}
class RoomNode {
private ArrayList<RoomNode> voisins;
private RoomBuilder room;
private int ltostart = -1;
public RoomNode(ArrayList<RoomNode> voisins, RoomBuilder room) {
this.voisins = voisins;
this.room = room;
}
}
}
......@@ -110,63 +110,32 @@ public class SurfacesMapGeneration implements Serializable{
return (dY>0 && dX>0)?dX+dY+4:dX+dY; // There's an extra to the distance between rooms that aren't facing each other horizontally or vertically (to avoid corridors with corners in the MST when possible)
}
public static LinkedList<Surface> creationCorridor(Surface room1,Surface room2) {
public static Surface creationCorridor(Surface room1,Surface room2) {
// This method creates a corridor between two rooms
int dNorth=Math.max(room2.j1-room1.j2-1,0);
int dY=Math.max(room2.j1-room1.j2+1,0)+Math.max(room1.j1-room2.j2+1,0);
int dX=Math.max(room2.i1-room1.i2+1,0)+Math.max(room1.i1-room2.i2+1,0);
LinkedList<Surface> corridors=new LinkedList<>();
if (dX==0) {
// Case where the rooms are facing each other vertically
int xTarget=(Math.max(room1.i1,room2.i1)+Math.min(room1.i2,room2.i2))/2;
int yTop=Math.min(room1.j2,room2.j2);
int yBottom=Math.max(room1.j1,room2.j1);
Surface corridor = new Surface(xTarget, yTop, xTarget+1, yBottom);
corridors.addLast(corridor);
return corridors;
return new Surface(xTarget, yTop, xTarget+1, yBottom);
}
else if (dY==0) {
// Case where the rooms are facing each other vertically
int yTarget=(Math.max(room1.j1,room2.j1)+Math.min(room1.j2,room2.j2))/2;
int xLeft=Math.min(room1.i2,room2.i2);
int xRight=Math.max(room1.i1,room2.i1);
Surface corridor = new Surface(xLeft, yTarget, xRight, yTarget+1);
corridors.addLast(corridor);
return corridors;
return new Surface(xLeft, yTarget, xRight, yTarget+1);
}
else {
int xTarget=-1;
int yTarget=-1;
if(dNorth>0) {
xTarget=(room1.i1+room1.i2)/2;
yTarget=(room2.j1+room2.j2)/2;
Surface corridor1 = new Surface(xTarget, room1.j2, xTarget+1, yTarget);
corridors.addLast(corridor1);
if(xTarget<room2.i1) {
Surface corridor2 = new Surface(xTarget, yTarget-1, room2.i1, yTarget);
corridors.addLast(corridor2);
}
else {
Surface corridor2 = new Surface(room2.i2, yTarget-1, xTarget, yTarget);
corridors.addLast(corridor2);
}
}
else {
xTarget=(room2.i1+room2.i2)/2;
yTarget=(room1.j1+room1.j2)/2;
Surface corridor1 = new Surface(xTarget, room2.j2+1, xTarget+1, yTarget);
corridors.addLast(corridor1);
if(xTarget<room1.i1) {
Surface corridor2 = new Surface(xTarget, yTarget-1, room1.i1, yTarget);
corridors.addLast(corridor2);
}
else {
Surface corridor2 = new Surface(room1.i2, yTarget-1, xTarget, yTarget);
corridors.addLast(corridor2);
}
}
return(corridors);
xTarget=(room1.i1+room1.i2)/2;
yTarget=(room2.j1+room2.j2)/2;
if(dNorth>0)return new Surface(xTarget, room1.j2, xTarget+1, yTarget);
return new Surface(xTarget, room2.j2+1, xTarget+1, yTarget);
}
}
......@@ -181,10 +150,8 @@ public class SurfacesMapGeneration implements Serializable{
distance[i][j]=d;
distance[j][i]=d;
if(d<12) { // If we find two rooms with a small distance in between, we add a corridor anyway, independantly of the MST
LinkedList<Surface> corridorsToAdd=creationCorridor(rooms[i].getSurface(),rooms[j].getSurface());
for (int k=0;k<corridorsToAdd.size();k++) {
map.addCorridor(corridorsToAdd.get(k));
}
Surface corridorsToAdd=creationCorridor(rooms[i].getSurface(),rooms[j].getSurface());
map.addCorridor(corridorsToAdd, rooms[i], rooms[j]);
}
}
}
......@@ -209,10 +176,8 @@ public class SurfacesMapGeneration implements Serializable{
}
used[node2]=true;
nbConnected++;
LinkedList<Surface> corridorsToAdd=creationCorridor(rooms[node1].getSurface(),rooms[node2].getSurface());
for (int k=0;k<corridorsToAdd.size();k++) {
map.addCorridor(corridorsToAdd.get(k));
}
Surface corridorsToAdd=creationCorridor(rooms[node1].getSurface(),rooms[node2].getSurface());
map.addCorridor(corridorsToAdd, rooms[node1], rooms[node2]);
}
}
......@@ -254,12 +219,10 @@ public class SurfacesMapGeneration implements Serializable{
}
}
}
for (int i = 0; i < rooms.length; i++) {
map.addRoom(rooms[i]);
}
addCorridorsByMST(rooms, map); // Creation of the set of corridors
RoomBuilder startRoom=defineStartPosition(rooms);
defineStairsPosition(map,heightMap,widthMap,rooms,startRoom);
map.addRooms(rooms, startRoom);
addCorridorsByMST(rooms, map); // Creation of the set of corridors
// defineStairsPosition(map,heightMap,widthMap,rooms,startRoom);
map.setHeight(heightMap);
map.setWidth(widthMap);
......@@ -267,7 +230,6 @@ public class SurfacesMapGeneration implements Serializable{
for (RoomBuilder room : rooms) {
room.setRandomlySpecial(0.3);
}
return map.build();
}
......@@ -277,11 +239,10 @@ public class SurfacesMapGeneration implements Serializable{
map.setHeight(size);
map.setWidth(size);
Surface room=new Surface(2,2,size-3,size-3);
map.addRoom(new RoomBuilder(room, RoomType.NORMAL));
RoomBuilder[] rooms=new RoomBuilder[1];
rooms[0]= new RoomBuilder(room, RoomType.NORMAL);
addCorridorsByMST(rooms, map);
RoomBuilder[] rooms= {new RoomBuilder(room, RoomType.NORMAL)};
RoomBuilder startRoom=defineStartPosition(rooms);
map.addRooms(rooms, startRoom);
addCorridorsByMST(rooms, map);
defineStairsPosition(map,size,size,rooms,startRoom);
return(map.build());
}
......
......@@ -36,6 +36,7 @@ public class MapTests {
@Test
public void testPlayerNotOnWater(){
Map map = SurfacesMapGeneration.roomsRandomGeneration(20, 500);
map.getPositionPlayerStart().getI();
assertFalse("The player has spawn on water !", map.getTileAt(map.getPositionPlayerStart()).getType() == TileType.WATER);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment