import math
import random

words = [
  (8, ' AAA '),
  (6, ' BBB '),
  (8, ' CCC '),
  (8, ' DDD '),
  (3, ' EEE '),
  (8, ' FFF '),
  (2, ' GGG '),
]

height = 30
width = 40

middle = (20, 15)

grid = [[] for x in range(height + 1)]

grid[middle[1]].append((middle[0] * 2, (middle[0] * 2 + 1), 'X'))

def space_available (grid, start, end, line):
  other_words = grid[line]

  for other_start, other_end, _ in other_words:
    if start < other_end and end > other_start:
      return False

  return True

for distance, word in words:
  placed = False

  angle = random.random() * math.pi * 2
  step = 0
  steps = 20
  while (not placed) and step < steps:
  
    x = int(round(math.cos(angle) * distance) + middle[0]) * 2
    y = int(round(math.sin(angle) * distance) + middle[1])

    start = x - max(0, int(math.floor(len(word) / 2)))
    end = start + len(word)

    if space_available(grid, start, end, y):
      grid[y].append((start, end, word))
      placed = True

    angle += (math.pi * 2 / steps)

  # print(angle, x, y)

print(grid)

for row in grid:
  # Sort by first key of the tuples, start of the word
  row = sorted(row, key=lambda r: r[0])

  if not len(row):
    print (width * ' ')
  else:
    line = ''
    for start, _, word in row:
      line += (start - len(line)) * ' ' + word
    
    line += (width - len(line)) * ' '
    
    print(line)