JSFiddle - React, Tailwind, and code Playground

by bowheart

HTML

<div id="wrapper"></div>

SCSS

body {
  align-items: center;
  display: flex;
  height: 100vh;
  font-size: 0;
  justify-content: center;
  margin: 0;
}

#wrapper {
  position: relative;
}

.room {
  border: 1px solid #eee;
  display: inline-block;
  font-size: 11px;
  height: 50px;
  position: absolute;
  width: 50px;
  
  &:after, &:before {
    background: #ccc;
    content: '';
    position: absolute;
  }
}

.crit {
  background: repeating-linear-gradient(135deg, #fff 0, #fff 6px, #ccc 7px, #ccc 8px, #fff 9px);
}

.end {
  background: rgba(255, 150, 150, 0.2);
}

.start {
  background: rgba(150, 255, 150, 0.2);
}

.a:before {
  height: 10px;
  right: 0;
  top: 20px;
  width: 30px;
}

.b:before {
  bottom: 0;
  height: 30px;
  left: 20px;
  width: 10px;
}

.c:before {
  height: 10px;
  left: 0;
  top: 20px;
  width: 30px;
}

.d:before {
  height: 30px;
  left: 20px;
  top: 0;
  width: 10px;
}

.e:before {
  height: 10px;
  left: 0;
  top: 20px;
  width: 50px;
}

.f:before {
  height: 50px;
  left: 20px;
  top: 0;
  width: 10px;
}

.g {
  &:after {
    height: 10px;
    right: 0;
    top: 20px;
    width: 30px;
  }
  
  &:before {
    height: 30px;
    left: 20px;
    top: 0;
    width: 10px;
  }
}

.h {
  &:after {
    height: 10px;
    right: 0;
    top: 20px;
    width: 30px;
  }
  
  &:before {
    height: 30px;
    left: 20px;
    bottom: 0;
    width: 10px;
  }
}

.i {
  &:after {
    height: 10px;
    left: 0;
    top: 20px;
    width: 30px;
  }
  
  &:before {
    height: 30px;
    left: 20px;
    bottom: 0;
    width: 10px;
  }
}

.j {
  &:after {
    height: 10px;
    left: 0;
    top: 20px;
    width: 30px;
  }
  
  &:before {
    height: 30px;
    left: 20px;
    top: 0;
    width: 10px;
  }
}

.k {
  &:after {
    height: 10px;
    right: 0;
    top: 20px;
    width: 30px;
  }
  
  &:before {
    height: 50px;
    left: 20px;
    top: 0;
    width: 10px;
  }
}

.l {
  &:after {
    height: 10px;
    right: 0;
    top: 20px;
    width: 50px;
  }
  
  &:before {
    height: 30px;
...

JavaScript

const a = { type: 'a', right: true }
const b = { type: 'b', bottom: true }
const c = { type: 'c', left: true }
const d = { type: 'd', top: true }

const e = { type: 'e', right: true, left: true }
const f = { type: 'f', bottom: true, top: true }

const g = { type: 'g', right: true, top: true }
const h = { type: 'h', right: true, bottom: true }
const i = { type: 'i', bottom: true, left: true }
const j = { type: 'j', left: true, top: true }

const k = { type: 'k', right: true, bottom: true, top: true }
const l = { type: 'l', right: true, bottom: true, left: true }
const m = { type: 'm', bottom: true, left: true, top: true }
const n = { type: 'n', right: true, left: true, top: true }

const o = { type: 'o', right: true, bottom: true, left: true, top: true }

const deadEndRooms = [a, b, c, d]
const pathRooms = [e, f, g, h, i, j, k, l, m, n, o]
const allRooms = [...deadEndRooms, ...pathRooms]

const checkRoom = (coords, rooms, neededRooms) => {
	const roomStr = coords.join(',')
  
  if (rooms[roomStr] | neededRooms[roomStr]) return false
  
  return coords
}

const chooseRoomType = (numRoomsLeft, numRooms, coords, dirToPrevRoom, rooms, neededRooms) => {
	const allAvailableRoomTypes = numRoomsLeft === numRooms
  	? allRooms // the first room can be any type
    : numRoomsLeft === 1
    	? deadEndRooms // the last room must be a dead end
      : pathRooms
      
  // can only pick rooms that have exits pointing to the previous room (if any)
  let availableRoomTypes = dirToPrevRoom
  	? allAvailableRoomTypes.filter(room => room[dirToPrevRoom])
    : allAvailableRoomTypes
    
  let roomType
    
  // keep picking room types until we find one that works or we run out of options
  while (availableRoomTypes.length) {
  	roomType = pick(availableRoomTypes)
    
    if (isValidRoomType(roomType, coords, dirToPrevRoom, rooms, neededRooms)) break
    
    // nope - remove this room type from the list of available room types and try another
    availableRoomTypes =...