110 lines
3.7 KiB
Python
110 lines
3.7 KiB
Python
"""
|
|
Adapted from pyphoon - Phase of the Moon (Python version)
|
|
Igor Chubin <igor@chub.in>, 05.03.2016,
|
|
|
|
Based on the original version of Jef Poskanzer <jef@mail.acme.com>
|
|
written in Pascal in 1979 (and later translated to C)
|
|
|
|
The MIT License (MIT)
|
|
|
|
Copyright (c) 2016 Igor Chubin
|
|
Copyright (c) 2024 Dessa Simpson
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
"""
|
|
import math
|
|
from moons import backgrounds
|
|
|
|
# If you change the aspect ratio, the canned backgrounds won't work.
|
|
ASPECTRATIO = 0.5
|
|
|
|
def putmoon(pctphase, lines, atfiller, hemisphere): # pylint: disable=too-many-locals,too-many-branches,too-many-statements,too-many-arguments
|
|
"""Print the moon"""
|
|
|
|
output = ""
|
|
def putchar(char):
|
|
nonlocal output
|
|
output += char
|
|
|
|
# Find the length of the atfiller string
|
|
atflrlen = len(atfiller)
|
|
|
|
# Fix waxes and wanes direction for south hemisphere
|
|
if hemisphere == 'south':
|
|
pctphase = 1 - pctphase
|
|
|
|
angphase = pctphase * 2.0 * math.pi
|
|
mcap = -math.cos(angphase)
|
|
|
|
# Figure out how big the moon is
|
|
yrad = lines / 2.0
|
|
xrad = yrad / ASPECTRATIO
|
|
|
|
# Now output the moon, a slice at a time
|
|
atflridx = 0
|
|
lin = 0
|
|
while lin < lines:
|
|
# Compute the edges of this slice
|
|
ycoord = lin + 0.5 - yrad
|
|
xright = xrad * math.sqrt(1.0 - (ycoord * ycoord) / (yrad * yrad))
|
|
xleft = -xright
|
|
if math.pi > angphase >= 0.0:
|
|
xleft = mcap * xleft
|
|
else:
|
|
xright = mcap * xright
|
|
|
|
colleft = int(xrad + 0.5) + int(xleft + 0.5)
|
|
colright = int(xrad + 0.5) + int(xright + 0.5)
|
|
|
|
# Now output the slice
|
|
col = 0
|
|
while col < colleft:
|
|
putchar(' ')
|
|
col += 1
|
|
while col <= colright:
|
|
if hemisphere == 'north':
|
|
# north - read moons from upper-left to bottom-right
|
|
if lines in backgrounds:
|
|
char = backgrounds[lines][lin][col]
|
|
else:
|
|
char = '@'
|
|
else:
|
|
# south - read moons from bottom-right to upper-left
|
|
# equivalent to rotate 180 degress or turn upside-down
|
|
if lines in backgrounds:
|
|
char = backgrounds[lines][-1-lin][-col]
|
|
else:
|
|
char = '@'
|
|
|
|
# rotate char upside-down if needed
|
|
char = char.translate(str.maketrans("().`_'",
|
|
"!!!!!!"))
|
|
|
|
if char != '@':
|
|
putchar(char)
|
|
else:
|
|
putchar(atfiller[atflridx])
|
|
atflridx = (atflridx + 1) % atflrlen
|
|
col += 1
|
|
|
|
putchar('\n')
|
|
lin += 1
|
|
|
|
return output
|