1. package test1;
  2.  
  3. import java.awt.*;
  4. import javax.swing.*;
  5. import java.util.*;
  6.  
  7. public class Map1 extends JPanel {
  8.    
  9.     private static int x1, y1, x2, y2, width, height, width2, height2, centerX, centerY, centerX2, centerY2, cellAuto, radius;
  10.     public static final int tileWidth = 10;
  11.     public static final int tileHeight = 10;
  12.     public static final int gridSize = 70;
  13.     public static float a, b, circleX, circleY;
  14.     public static double t;
  15.     public static Random rn = new Random();
  16.    
  17.     // Map array values
  18.     public static final int cave = 0;
  19.     public static final int wall = 1;
  20.     public static final int room = 2;
  21.     public static final int dungeon = 3;
  22.     public static final int dungeonWall = 4;
  23.     public static final int player = 5;
  24.     public static final int mob = 6;
  25.     public static final int door = 7;
  26.    
  27.     public static int [][][][] myMap = new int[gridSize][gridSize][50][10];
  28.    
  29.     // Generate room count and room stats
  30.     public static int roomCount = 5 + rn.nextInt(5);
  31.     public static int [][][] roomList = new int[roomCount][4][100];
  32.    
  33.     // CONSTRUCTOR
  34.     public Map1() {
  35.        
  36.         // Generates caverns
  37.         for (int i = 0; i < roomCount; i++) {  
  38.            
  39.             // Make X coordinates and width
  40.             x1 = 3 + rn.nextInt(55);
  41.             width = 7 + rn.nextInt(10);
  42.             if (x1 + width > myMap.length) {
  43.                 x1 = x1 - width;
  44.             }
  45.            
  46.             // Make Y coordinates and height
  47.             y1 = 3 + rn.nextInt(55);
  48.             height = 7 + rn.nextInt(10);
  49.             if (y1 + height > myMap.length - 1) {
  50.                 y1 = y1 - height;
  51.             }  
  52.            
  53.             // Add to roomList
  54.             centerX = x1 + width / 2;
  55.             centerY = y1 + height / 2;
  56.             roomList[i][0][0] = centerX;
  57.             roomList[i][1][0] = centerY;
  58.             roomList[i][2][0] = width;
  59.             roomList[i][3][0] = height;
  60.            
  61.             // Choose random cavern shape
  62.             if (rn.nextInt(20) < 1) {
  63.                 // Add a rectangular cavern to map
  64.                 for (int x = x1; x < width + x1; x++) {
  65.                     for (int y = y1; y < height + y1; y++) {
  66.                         myMap[x][y][0][0] = room;
  67.                     }
  68.                 }
  69.             } else {
  70.                 // Add a circular cavern to map
  71.                 radius = width / 2;
  72.                 for (int x = -radius; x < radius; x++) {
  73.                     a = x;
  74.                     b = (float) Math.sqrt(radius * radius - a * a);
  75.                    
  76.                     for (int y = (int) Math.round(-b + 1); y < b; y++) {
  77.                         try {
  78.                             myMap[centerX + x][centerY + y][0][0] = room;
  79.                         } catch (Exception ex) {
  80.                             myMap[centerX + x][centerY + y - 2][0][0] = room;
  81.                         }
  82.                     }
  83.                 }
  84.             }
  85.         }
  86.        
  87.         // Draws halls between caverns (before cellular automata)
  88.         for (int i = 0; i + 1 < roomCount; i++) {
  89.             centerX = roomList[i][0][0];
  90.             centerY = roomList[i][1][0];
  91.             width = roomList[i][2][0];
  92.             height = roomList[i][3][0];
  93.             centerX2 = roomList[i + 1][0][0];
  94.             centerY2 = roomList[i + 1][1][0];
  95.             width2 = roomList[i + 1][2][0];
  96.             height2 = roomList[i + 1][3][0];
  97.            
  98.             while (centerX < centerX2) {
  99.                 myMap[centerX][centerY][0][0] = 2;
  100.                 centerX++;
  101.             }  
  102.             while (centerY < centerY2) {
  103.                 myMap[centerX][centerY][0][0] = 2;
  104.                 centerY++;
  105.             }
  106.             while (centerX > centerX2) {
  107.                 myMap[centerX][centerY][0][0] = 2;
  108.                 centerX--;
  109.             }  
  110.             while (centerY > centerY2) {
  111.                 myMap[centerX][centerY][0][0] = 2;
  112.                 centerY--;
  113.             }
  114.         }
  115.        
  116.         // Counts total cavern area before paths
  117.         int cavernArea = 0;
  118.         int caveArea = 0;
  119.        
  120.         for (int x = 0; x < myMap.length; x++) {
  121.             for (int y = 0; y < myMap.length; y++) {
  122.                 if (myMap[x][y][0][0] == 2) {
  123.                     cavernArea++;
  124.                 }
  125.             }
  126.         }
  127.         System.out.println("The area of the caverns is: " + cavernArea + " tiles.");
  128.        
  129.         // Cellular automata algorithm to smooth cavern walls
  130.         for (int p = 0; p < 20; p++) {
  131.             // Scan map
  132.             for (int x = 1; x < gridSize - 1; x++) {
  133.                 for (int y = 1; y < gridSize - 1; y++) {
  134.                     cellAuto = 0;
  135.                     // Scans adjacent tiles
  136.                     for (int adjX = x - 1; adjX < x + 2; adjX++) {
  137.                         for (int adjY = y - 1; adjY < y + 2; adjY++) {
  138.                            
  139.                             if (myMap[adjX][adjY][0][0] == 0) {
  140.                                 cellAuto++;
  141.                             }
  142.                             if (cellAuto == 4 && adjX == x + 1 && adjY == y + 1) {
  143.                                 myMap[adjX - 1][adjY - 1][0][0] = 2;
  144.                             } else if (cellAuto > 6 && adjX == x + 1 && adjY == y + 1) {
  145.                                 myMap[adjX - 1][adjY - 1][0][0] = 0;
  146.                             } else if (cellAuto == 5 && adjX == x + 1 && adjY == y + 1) {
  147.                                 myMap[adjX - 1][adjY - 1][0][0] = 0;
  148.                             } else if (cellAuto == 2 && adjX == x + 1 && adjY == y + 1) {
  149.                                 myMap[adjX - 1][adjY - 1][0][0] = 2;
  150.                             } else if (cellAuto == 1 && adjX == x + 1 && adjY == y + 1) {
  151.                                 myMap[adjX - 1][adjY - 1][0][0] = 2;
  152.                             }
  153.                         }
  154.                     }
  155.                 }
  156.             }
  157.         }
  158.        
  159.         // Draws halls between caverns
  160.         for (int i = 0; i + 1 < roomCount; i++) {
  161.             centerX = roomList[i][0][0];
  162.             centerY = roomList[i][1][0];
  163.             width = roomList[i][2][0];
  164.             height = roomList[i][3][0];
  165.             centerX2 = roomList[i + 1][0][0];
  166.             centerY2 = roomList[i + 1][1][0];
  167.             width2 = roomList[i + 1][2][0];
  168.             height2 = roomList[i + 1][3][0];
  169.            
  170.             // Set bezier start and finish
  171.             int bx1, bx2a, bx2b, bx3, by1, by2a, by2b, by3, btX, btY, timeX, timeY;
  172.             bx1 = centerX;                 
  173.             bx3 = centerX2;    
  174.             by1 = centerY;
  175.             by3 = centerY2;
  176.            
  177.             // Set middle X and Y for bezier path
  178.             bx2a = centerX + (centerX2 - centerX) / 2;
  179.             by2a = centerY + (centerY2 - centerY) / 2;
  180.            
  181.             // Determine length of curve
  182.             if (centerX >= centerX2) {
  183.                 timeX = centerX - centerX2;
  184.             } else {
  185.                 timeX = centerX2 - centerX;
  186.             }
  187.             if (centerY >= centerY2) {
  188.                 timeY = centerY - centerY2;
  189.             } else {
  190.                 timeY = centerY2 - centerY;
  191.             }
  192.            
  193.             // Set random deviation of bezier
  194.             if (rn.nextInt(2) == 0) {
  195.                 bx2b = bx2a + rn.nextInt(5);   
  196.             } else {
  197.                 bx2b = bx2a - rn.nextInt(5);
  198.             }
  199.             if (rn.nextInt(2) == 0) {
  200.                 by2b = by2a + rn.nextInt(5);   
  201.             } else {
  202.                 by2b = by2a - rn.nextInt(5);
  203.             }
  204.            
  205.             // Stop middle X and Y from leaving array
  206.             if (bx2b > 68) {
  207.                 bx2b = 68;
  208.             } else if (bx2b < 2) {
  209.                 bx2b = 2;
  210.             }
  211.             if (by2b > 68) {
  212.                 by2b = 68;
  213.             } else if (by2b < 2) {
  214.                 by2b = 2;
  215.             }
  216.            
  217.             System.out.println("\nX1 is " + bx1 + " and Y1 is " + by1);
  218.             System.out.println("X2 is " + bx2a + " and Y2 is " + by2a);
  219.             System.out.println("X3 is " + bx3 + " and Y3 is " + by3);
  220.             System.out.println("X2 modified is " + bx2b + " and Y2 modified is " + by2b);
  221.             System.out.println("X time is " + timeX + " and Y time is " + timeY + " and total time is " + (1 / (timeX + timeY)) + "\n");
  222.            
  223.            
  224.             // Bezier path from top left to bottom right
  225.             for (double time = (1 / (timeX + timeY)); time < 1;) {
  226.                
  227.                 // Determine point on bezier curve
  228.                 btX = (int) ((1 - (time * time)) * bx1 + 2 * (1 - time) * time * bx2b + (time * time) * bx3);
  229.                 btY = (int) ((1 - (time * time)) * by1 + 2 * (1 - time) * time * by2b + (time * time) * by3);
  230.                
  231.                 // Stop curve leaving array
  232.                 if (btX > 67) {
  233.                     btX = 67;
  234.                 } else if (btX < 3) {
  235.                     btX = 3;
  236.                 }
  237.                 if (btY > 67) {
  238.                     btY = 67;
  239.                 } else if (btY < 3) {
  240.                     btY = 3;
  241.                 }
  242.                
  243.                 // Attempts to draw bezier path
  244.                 try {
  245.                 myMap[btX][btY][0][0] = 2;
  246.                 myMap[btX + 1][btY][0][0] = 2;
  247.                 myMap[btX][btY + 1][0][0] = 2;
  248.                 myMap[btX + 1][btY + 1][0][0] = 2;
  249.                 } catch (Exception ex) {
  250.                     System.out.println("X is " + btX + " and Y is " + btY + " at t " + t);
  251.                     System.out.println(ex + " is wrong");  
  252.                 }
  253.                
  254.                 time = time + 1 / (timeX + timeY);
  255.                 if (btX >= bx3 - 1  && btY >= by3 - 1) {
  256.                     time = 1;
  257.                 }
  258.             }      
  259.         }
  260.        
  261.         // Counts total cave area after paths and then counts path area
  262.         for (int x = 0; x < myMap.length; x++) {
  263.             for (int y = 0; y < myMap.length; y++) {
  264.                 if (myMap[x][y][0][0] == 2) {
  265.                     caveArea++;
  266.                 }
  267.             }
  268.         }
  269.         System.out.println("The area of the cave, including paths, is: " + caveArea + " tiles.");
  270.         System.out.println("The area of the paths is: " + (caveArea - cavernArea) + " tiles.");
  271.        
  272.         // Generates walls around playable areas
  273.         for (int x = 1; x < gridSize - 1; x++) {
  274.             for (int y = 1; y < gridSize - 1; y++) {   
  275.                 if ((myMap[x][y][0][0] == 2) && (x < gridSize - 1) && (1 < x)) {
  276.                     // Scans adjacent tiles
  277.                     for (int adjX = x - 1; adjX < x + 2; adjX++) {
  278.                         for (int adjY = y - 1; adjY < y + 2; adjY++) {
  279.                             if (myMap[adjX][adjY][0][0] == 0) {
  280.                                 myMap[adjX][adjY][0][0] = wall;
  281.                             }
  282.                         }
  283.                     }
  284.                 }
  285.             }
  286.         }
  287.        
  288.         // Draw outer walls
  289.         for (int x = 0; x < myMap.length; x++) {
  290.             for (int y = 0; y < myMap.length; y++) {
  291.                 if (x == 0 || y == 0) {
  292.                     if (myMap[x][y][0][0] == 2) {
  293.                         myMap[x][y][0][0] = wall;
  294.                     }
  295.                 }
  296.                 if (x == myMap.length - 1 || y == myMap.length - 1) {
  297.                     if (myMap[x][y][0][0] == 2) {
  298.                         myMap[x][y][0][0] = wall;
  299.                     }
  300.                 }
  301.             }
  302.         }
  303.        
  304.     }
  305.    
  306.     // Paint myMap to a window
  307.     public void paint(Graphics g) {
  308.         super.paintComponent(g);
  309.         this.setBackground(Color.BLACK);   
  310.        
  311.         for (int x = 0; x < myMap.length; x++) {
  312.             for (int y = 0; y < myMap.length; y++) {
  313.                
  314.                 x2 = tileWidth * x;
  315.                 y2 = tileHeight * y;
  316.                
  317.                 // Draws array tiles
  318.                 if (myMap[x][y][0][0] == room) {
  319.                     g.setColor(Color.GRAY);
  320.                     g.fillRect(x2, y2, tileWidth, tileHeight);
  321.                     g.setColor(Color.BLACK);
  322.                     g.drawRect(x2, y2, tileWidth, tileHeight);
  323.                 } else if (myMap[x][y][0][0] == wall) {
  324.                     g.setColor(Color.DARK_GRAY);
  325.                     g.fillRect(x2, y2, tileWidth, tileHeight);
  326.                 } else if (myMap[x][y][0][1] == dungeon) {
  327.                     g.setColor(Color.RED);
  328.                     g.drawRect(x2, y2, tileWidth, tileHeight);
  329.                 } else {
  330.                     g.setColor(Color.BLACK);
  331.                     g.fillRect(x2, y2, tileWidth, tileHeight);
  332.                     //g.setColor(Color.BLACK);
  333.                     //g.drawRect(x2, y2, tileWidth, tileHeight);
  334.                 }
  335.             }
  336.         }
  337.     }
  338. }