""" Adapted from pyphoon - Phase of the Moon (Python version) Igor Chubin , 05.03.2016, Based on the original version of Jef Poskanzer 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