text: import libtcodpy as libtcod
  import tcod
  from random import uniform, randint
  
  # TODO pass these to the functions
  WORLD_WIDTH = 200
  WORLD_HEIGHT = 80
  
  SCREEN_WIDTH = 200
  SCREEN_HEIGHT = 80
  
  CIVILIZED_CIVS = 2
  TRIBAL_CIVS = 2
  
  MIN_RIVER_LENGHT = 3
  
  CIV_MAX_SITES = 20
  EXPANSION_DISTANCE = 10
  WAR_DISTANCE = 8
  
  # Palette
  Palette = [
      tcod.Color(255, 45, 33),  # Red
      tcod.Color(254, 80, 0),  # Orange
      tcod.Color(0, 35, 156),  # Blue
      tcod.Color(71, 45, 96),  # Purple
      tcod.Color(0, 135, 199),  # Ocean Blue
      tcod.Color(254, 221, 0),  # Yellow
      tcod.Color(255, 255, 255),  # White
      tcod.Color(99, 102, 106),
  ]  # Gray
  
  # - General Functions -
  def ClearConsole():
      for x in range(SCREEN_WIDTH):
          for y in range(SCREEN_HEIGHT):
              tcod.console_put_char_ex(0, x, y, " ", tcod.black, tcod.black)
  
      tcod.console_flush()
  
      return
  
  
  def PointDistRound(pt1x, pt1y, pt2x, pt2y):
      distance = abs(pt2x - pt1x) + abs(pt2y - pt1y)
  
      distance = round(distance)
  
      return distance
  
  
  def FlagGenerator(Color):
      Flag = [[0 for a in range(4)] for b in range(12)]
  
      BackColor1 = Color
      BackColor2 = Palette[randint(0, len(Palette) - 1)]
  
      OverColor1 = Palette[randint(0, len(Palette) - 1)]
      OverColor2 = Palette[randint(0, len(Palette) - 1)]
  
      BackFile = open("./dist/Background.txt", "r")
      OverlayFile = open("./dist/Overlay.txt", "r")
  
      BTypes = (sum(1 for line in BackFile) + 1) / 5
      OTypes = (sum(1 for line in OverlayFile) + 1) / 5
  
      Back = randint(1, BTypes)
      Overlay = randint(1, OTypes)
  
      for a in range(53 * (Back - 1)):
          C = BackFile.read(1)
  
      for a in range(53 * (Overlay - 1)):
          C = OverlayFile.read(1)
  
      for y in range(4):
          for x in range(12):
  
              C = BackFile.read(1)
              while C == "\n":
                  C = BackFile.read(1)
  
              if C == "#":
                  Flag[x][y] = BackColor1
              elif C == '"':
                  Flag[x][y] = BackColor2
  
              C = OverlayFile.read(1)
              while C == "\n":
                  C = OverlayFile.read(1)
  
              if C == "#":
                  Flag[x][y] = OverColor1
              elif C == '"':
                  Flag[x][y] = OverColor2
  
      BackFile.close()
      OverlayFile.close()
  
      return Flag
  
  
  def LowestNeighbour(X, Y, World):  # Diagonals are commented for rivers
      minval = 1
  
      x = 0
      y = 0
  
      if World[X + 1][Y].height < minval and X + 1 < WORLD_WIDTH:
          minval = World[X + 1][Y].height
          x = X + 1
          y = Y
  
      if World[X][Y + 1].height < minval and Y + 1 < WORLD_HEIGHT:
          minval = World[X][Y + 1].height
          x = X
          y = Y + 1
  
      # if libtcod.heightmap_get_value(hm, X + 1, Y + 1) < minval and X + 1 < WORLD_WIDTH and Y + 1 < WORLD_HEIGHT and minval > 0.2:
      # minval = libtcod.heightmap_get_value(hm, X + 1, Y + 1)
      # x = X + 1
      # y = Y + 1
  
      # if libtcod.heightmap_get_value(hm, X - 1, Y - 1) < minval and X - 1 > 0 and Y - 1 > 0 and minval > 0.2:
      # minval = libtcod.heightmap_get_value(hm, X - 1, Y - 1)
      # x = X - 1
      # y = Y - 1
  
      if World[X - 1][Y].height < minval and X - 1 > 0:
          minval = World[X - 1][Y].height
          x = X - 1
          y = Y
  
      if World[X][Y - 1].height < minval and Y - 1 > 0:
          minval = World[X][Y - 1].height
          x = X
          y = Y - 1
  
      # f libtcod.heightmap_get_value(hm, X + 1, Y - 1) < minval and X + 1 < WORLD_WIDTH and Y - 1 > 0 and minval > 0.2:
      # minval = libtcod.heightmap_get_value(hm, X + 1, Y - 1)
      # x = X + 1
      # y = Y - 1
  
      # if libtcod.heightmap_get_value(hm, X - 1, Y + 1) < minval and X - 1 > 0 and Y + 1 < WORLD_HEIGHT and minval > 0.2 :
      # minval = libtcod.heightmap_get_value(hm, X - 1, Y + 1)
      # x = X - 1
      # y = Y + 1
  
      error = 0
  
      if x == 0 and y == 0:
          error = 1
  
      return (x, y, error)
  
  
  # - MapGen Functions -
  
  
  def PoleGen(hm, NS):
  
      if NS == 0:
          rng = randint(2, 5)
          for i in range(WORLD_WIDTH):
              for j in range(rng):
                  tcod.heightmap_set_value(hm, i, WORLD_HEIGHT - 1 - j, 0.31)
              rng += randint(1, 3) - 2
              if rng > 6:
                  rng = 5
              if rng < 2:
                  rng = 2
  
      if NS == 1:
          rng = randint(2, 5)
          for i in range(WORLD_WIDTH):
              for j in range(rng):
                  tcod.heightmap_set_value(hm, i, j, 0.31)
              rng += randint(1, 3) - 2
              if rng > 6:
                  rng = 5
              if rng < 2:
                  rng = 2
  
      return
  
  
  def TectonicGen(hm, hor):
  
      TecTiles = [[0 for y in range(WORLD_HEIGHT)] for x in range(WORLD_WIDTH)]
  
      # Define Tectonic Borders
      if hor == 1:
          pos = randint(WORLD_HEIGHT / 10, WORLD_HEIGHT - WORLD_HEIGHT / 10)
          for x in range(WORLD_WIDTH):
              TecTiles[x][pos] = 1
              pos += randint(1, 5) - 3
              if pos < 0:
                  pos = 0
              if pos > WORLD_HEIGHT - 1:
                  pos = WORLD_HEIGHT - 1
      if hor == 0:
          pos = randint(WORLD_WIDTH / 10, WORLD_WIDTH - WORLD_WIDTH / 10)
          for y in range(WORLD_HEIGHT):
              TecTiles[pos][y] = 1
              pos += randint(1, 5) - 3
              if pos < 0:
                  pos = 0
              if pos > WORLD_WIDTH - 1:
                  pos = WORLD_WIDTH - 1
  
      # Apply elevation to borders
      for x in range(int(WORLD_WIDTH / 10), WORLD_WIDTH - int(WORLD_WIDTH / 10)):
          for y in range(int(WORLD_HEIGHT / 10), WORLD_HEIGHT - int(WORLD_HEIGHT / 10)):
              if TecTiles[x][y] == 1 and tcod.heightmap_get_value(hm, x, y) > 0.3:
                  tcod.heightmap_add_hill(hm, x, y, randint(2, 4), uniform(0.15, 0.18))
  
      return
  
  
  def Temperature(temp, hm):
  
      for x in range(WORLD_WIDTH):
          for y in range(WORLD_HEIGHT):
              heighteffect = 0
              if y > WORLD_HEIGHT / 2:
                  tcod.heightmap_set_value(temp, x, y, WORLD_HEIGHT - y - heighteffect)
              else:
                  tcod.heightmap_set_value(temp, x, y, y - heighteffect)
              heighteffect = tcod.heightmap_get_value(hm, x, y)
              if heighteffect > 0.8:
                  heighteffect = heighteffect * 5
                  if y > WORLD_HEIGHT / 2:
                      tcod.heightmap_set_value(
                          temp, x, y, WORLD_HEIGHT - y - heighteffect
                      )
                  else:
                      tcod.heightmap_set_value(temp, x, y, y - heighteffect)
              if heighteffect < 0.25:
                  heighteffect = heighteffect * 10
                  if y > WORLD_HEIGHT / 2:
                      tcod.heightmap_set_value(
                          temp, x, y, WORLD_HEIGHT - y - heighteffect
                      )
                  else:
                      tcod.heightmap_set_value(temp, x, y, y - heighteffect)
  
      return
  
  
  def Percipitaion(preciphm, temphm):
  
      tcod.heightmap_add(preciphm, 2)
  
      for x in range(WORLD_WIDTH):
          for y in range(WORLD_HEIGHT):
              temp = tcod.heightmap_get_value(temphm, x, y)
  
      precip = tcod.noise_new(
          2, tcod.NOISE_DEFAULT_HURST, tcod.NOISE_DEFAULT_LACUNARITY
      )
  
      # tcod.heightmap_add_fbm(preciphm,precip ,2, 2, 0, 0, 32, 1, 1)
  
      tcod.heightmap_normalize(preciphm, 0.0, 1.0)
  
      # return
  
  
  def RiverGen(World):
  
      X = randint(0, WORLD_WIDTH - 1)
      Y = randint(0, WORLD_HEIGHT - 1)
  
      XCoor = []
      YCoor = []
  
      tries = 0
  
      prev = ""
  
      while World[X][Y].height < 0.8:
          tries += 1
          X = randint(0, WORLD_WIDTH - 1)
          Y = randint(0, WORLD_HEIGHT - 1)
  
          if tries > 2000:
              return
  
      del XCoor[:]
      del YCoor[:]
  
      XCoor.append(X)
      YCoor.append(Y)
  
      while World[X][Y].height >= 0.2:
  
          X, Y, error = LowestNeighbour(X, Y, World)
  
          if error == 1:
              return
  
          try:
              if (
                  World[X][Y].hasRiver
                  or World[X + 1][Y].hasRiver
                  or World[X - 1][Y].hasRiver
                  or World[X][Y + 1].hasRiver
                  or World[X][Y - 1].hasRiver
              ):
                  break
          except IndexError:
              return
  
          if X in XCoor and Y in YCoor:
              break
  
          XCoor.append(X)
          YCoor.append(Y)
  
      if len(XCoor) <= MIN_RIVER_LENGHT:
          return
  
      for x in range(len(XCoor)):
          if World[XCoor[x]][YCoor[x]].height < 0.2:
              break
          World[XCoor[x]][YCoor[x]].hasRiver = True
          if World[XCoor[x]][YCoor[x]].height >= 0.2 and x == len(XCoor):
              World[XCoor[x]][
                  YCoor[x]
              ].hasRiver = True  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Change to Lake later
  
      return
  
  
  def Prosperity(World):
  
      for x in range(WORLD_WIDTH):
          for y in range(WORLD_HEIGHT):
              World[x][y].prosperity = (
                  1.0
                  - abs(World[x][y].precip - 0.6)
                  + 1.0
                  - abs(World[x][y].temp - 0.5)
                  + World[x][y].drainage
              ) / 3
  
      return
  
  
  