#! /usr/local/bin/python3
# -*- coding: utf8 -*-
# Render the 1D liquid flow simulation generated by fluid-1D.sql
# (output in CSV format: ‹iter›|‹x›|‹ground›|‹water›, sorted by ‹iter›, ‹x›)
#
# Usage: ./fluid-1D.py
import sys
import csv
import math
import time
# a column of height 8 is rendered with h/8×█ (base) and a residual character ∈ ▁▂▃▄▅▆▇ (top)
def column(h):
return (int(h / 8), [None, '▁','▂','▃','▄','▅','▆','▇'][int(h) % 8])
def stone(cell):
return cell == '░'
# build ground[iter][x] and water[iter][x] from CSV input
with open(sys.argv[1]) as f:
lines = [line.rstrip() for line in f]
ground = [ int(row[2]) for row in csv.reader(lines) ]
water = [ float(row[3]) for row in csv.reader(lines) ]
# width/height of scenario (in characters)
width = max([ int(row[1]) for row in csv.reader(lines) ])
height = int(max([ gw[0] + gw[1] for gw in zip(ground,water) ]) / 8) + 1
ground = [ ground[i:i+width] for i in range(0, len(ground), width) ]
water = [ water[i:i+width] for i in range(0, len(water) , width) ]
# number of iterations
iters = len(ground)
# ANSI terminal escape codes
esc = chr(27)
cls = esc + "[2J" + esc + "[0;0H"
# liquid/solid colors
liquid = esc + "[34;1m"
solid = esc + "[0m"
# render the grids for all iterations
# NB: each grids[‹iter›] is a list of column strings (flip that by 90° for screen rendering)
grids = [[]] * iters
for iter, gs in enumerate(ground):
grids[iter] = [[]] * width
# render ground
for x, g in enumerate(gs):
(base, _) = column(g)
grids[iter][x] = '░' * base
for iter, ws in enumerate(water):
# render water on top of ground
for x, w in enumerate(ws):
(base, top) = column(w)
grids[iter][x] += '█' * base
if top:
grids[iter][x] += top
grids[iter][x] = grids[iter][x].ljust(height, ' ')
# screen rendering
for iter, grid in enumerate(grids):
print(cls + 'iteration #' + str(iter))
for y in range(height, 0, -1):
for x in range(0, width):
cell = grids[iter][x][y-1]
print((solid if stone(cell) else liquid) + cell, end='')
print('\n', end='')
print('\n')
if iter == 0:
input()
else:
time.sleep(0.05)