Advertisement
SergeySamoylov

city skyline in pure Bash

Apr 20th, 2025
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 3.56 KB | None | 0 0
  1. #!/usr/bin/env bash
  2. # Inspired by Kris Occhipinti's work on YouTube. Thank you!
  3. # https://www.youtube.com/watch?v=io5lIfOdwDM
  4. # GNU General Public License
  5.  
  6. # Terminal Control Abstraction Layer
  7. declare -A term=(
  8.     [hide_cursor]='\033[?25l'
  9.     [show_cursor]='\033[?25h'
  10.     [reset]='\033[0m'
  11.     [move_to]='\033[%d;%dH'  # row, col
  12.     [block]='█'
  13.     [half_block]='▄'
  14.     [ground]='▁'
  15. )
  16.  
  17. # 256-color palette definitions
  18. declare -A colors=(
  19.     [black]=0       [red]=1        [green]=2      [yellow]=3
  20.     [blue]=4        [magenta]=5    [cyan]=6       [white]=7
  21.     [bright_black]=8 [bright_red]=9 [bright_green]=10
  22.     [bright_yellow]=11 [bright_blue]=12 [bright_magenta]=13
  23.     [bright_cyan]=14 [bright_white]=15
  24.     [orange]=208    [purple]=93    [pink]=199
  25. )
  26.  
  27. # Global constants
  28. declare -ri GROUND_ROW=20
  29. declare -ri MIN_WIDTH=6  # 2 left wall + 2 right wall + 2 interior
  30.  
  31. function set_color() {
  32.     printf "\033[38;5;%dm" "${colors[$1]}"
  33. }
  34.  
  35. function move_cursor() {
  36.     printf "${term[move_to]}" "$1" "$2"
  37. }
  38.  
  39. function draw_building() {
  40.     local -i left_col=$1
  41.     local -i width=$2
  42.     local -i height=$3
  43.     local color=${4:-blue}
  44.     local window_color=${5:-yellow}
  45.  
  46.     # Ensure minimum width
  47.     (( width >= MIN_WIDTH )) || width=$MIN_WIDTH
  48.     local -i right_col=$((left_col + width - 1))
  49.     local -i roof_row=$((GROUND_ROW - height))
  50.     local -i interior_start=$((left_col + 2))
  51.     local -i interior_end=$((right_col - 1))
  52.  
  53.     # Hide cursor and set color
  54.     printf "%b" "${term[hide_cursor]}$(set_color "$color")"
  55.  
  56.     # Draw complete walls and interior in one pass per row
  57.     for ((row = roof_row; row < GROUND_ROW; row++)); do
  58.         # Left wall (exactly 2 solid blocks)
  59.         move_cursor "$row" "$left_col"
  60.         printf "%s%s" "${term[block]}" "${term[block]}"
  61.        
  62.         # Interior (full width between walls)
  63.         for ((col = interior_start; col < interior_end; col++)); do
  64.             printf "%s" "${term[block]}"
  65.         done
  66.        
  67.         # Right wall (exactly 2 solid blocks)
  68.         printf "%s%s" "${term[block]}" "${term[block]}"
  69.     done
  70.  
  71.     # Add windows (only on odd rows)
  72.     printf "%b" "$(set_color "$window_color")"
  73.     for ((row = roof_row + 1; row < GROUND_ROW; row += 2)); do
  74.         for ((col = interior_start; col < interior_end; col += 2)); do
  75.             move_cursor "$row" "$col"
  76.             printf "%s" "${term[half_block]}"
  77.         done
  78.     done
  79.  
  80.     # Draw ground shadow
  81.     move_cursor "$GROUND_ROW" "$left_col"
  82.     printf "%b" "$(set_color black)"
  83.     for ((col = left_col; col <= right_col; col++)); do
  84.         printf "%s" "${term[ground]}"
  85.     done
  86. }
  87.  
  88. function draw_city() {
  89.     # Clear screen and hide cursor
  90.     printf "%b" "${term[reset]}\033[2J${term[hide_cursor]}"
  91.  
  92.     # Draw perfectly aligned buildings
  93.     draw_building 3 8 12 blue bright_white     # ██▄▄██
  94.     draw_building 10 10 15 green yellow        # ██▄▄▄▄██
  95.     draw_building 19 15 18 red bright_cyan     # ██▄▄▄▄▄▄██
  96.     draw_building 32 8 14 purple orange        # ██▄▄██
  97.     draw_building 39 13 16 cyan bright_red     # ██▄▄▄▄▄██
  98.  
  99.     # Draw continuous ground line
  100.     printf "%b" "$(set_color white)"
  101.     for ((col = 1; col <= 60; col++)); do
  102.         move_cursor "$GROUND_ROW" "$col"
  103.         printf "%s" "${term[ground]}"
  104.     done
  105.  
  106.     # Reset and show cursor
  107.     printf "%b" "${term[reset]}"
  108.     move_cursor $((GROUND_ROW + 2)) 1
  109.     printf "%b" "${term[show_cursor]}"
  110. }
  111.  
  112. clear
  113. # Run the cityscape
  114. draw_city
  115.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement