Skip to content

Instantly share code, notes, and snippets.

@EnzDev
Last active July 22, 2019 22:03
Show Gist options
  • Save EnzDev/7587d2304d8f1ea9fbbaa583bb76634c to your computer and use it in GitHub Desktop.
Save EnzDev/7587d2304d8f1ea9fbbaa583bb76634c to your computer and use it in GitHub Desktop.
generate obduction numbering system
from PIL import ImageDraw, Image
__description__ = """This program convert arabic numbers to a Numerical Notation that is used in the game Obduction.
I did it based on what I remember and the real way of representing the numbers in that game may be a little different.
It's based on a base 4 numbering system where a digit is displayed
on a slanted 3x3 grid and the number is on a 5x5 grid. Let's use cardinal directions to help visualize.
For one digit:
A 0 is no line
A 1 is a slanted line to NW
A 2 is 2 slanted lines to NE and to SE
A 3 is 3 slanted lines to SW, NW and NE
Then to represent a number, each power is represented in clockwise order:
Pow 0: Center
Pow 1: North
Pow 2: East
Pow 3: South
Pow 4: West
"""
PIC_SIZE = 128
# Line width
lw = PIC_SIZE // 64
lhw = lw // 2 # Halves for the points width
lhhw = lw // 4 # Quarters for the line extension
# Divide the drawing in 5 sections
cc = [x * (PIC_SIZE / 4) for x in range(5)]
# Origins for the powers
pa = cc[2], cc[2] # 4**0 = 1
pb = cc[1], cc[1] # 4**1 = 4
pc = cc[3], cc[1] # 4**2 = 16
pd = cc[3], cc[3] # 4**3 = 64
pe = cc[1], cc[3] # 4**4 = 256
points = [pa, pb, pc, pd, pe]
# Corner coordinate to draw the points
draw_points = [((point[0] - lhw, point[1] - lhw), (point[0] + lhw, point[1] + lhw)) for point in points]
# For each representable numbers
for inp in range(1024):
im = Image.new("RGB", (PIC_SIZE, PIC_SIZE), color=(50, 50, 50))
draw = ImageDraw.Draw(im)
rawbits = [int(bit) for bit in bin(inp)[2:].zfill(9)][::-1]
bits = enumerate(rawbits)
# Let's iterate over the bits of the number (Could be easier with a base 4 number)
for p, b in bits:
# get the origin from binary representation by taking half of the power (to make it base 4, 2**n//2)
origin = points[p // 2]
# If it's 0, no need to represent the number
if b == 1:
# Represent 3
if p % 2 == 1 and rawbits[p - 1] == 1:
second = (origin[0], origin[1] + (PIC_SIZE / 4) + lhhw)
third = (origin[0], origin[1] - (PIC_SIZE / 4) - lhhw)
shape = [third, origin, second]
# Represent 1 ( 2**0 )
elif p % 2 == 0:
second = (origin[0] - (PIC_SIZE / 4) - lhhw, origin[1])
shape = [origin, second]
# Represent 0
else:
second = (origin[0], origin[1] - (PIC_SIZE / 4) - lhhw)
third = (origin[0] + (PIC_SIZE / 4) + lhhw, origin[1])
shape = [third, origin, second]
draw.line(shape, fill=(0, 255, 0), width=lw)
# Draw the grid marks
for point in draw_points:
draw.rectangle(point, fill=(255, 0, 0))
# Slant the number representation
rotate = im.rotate(-45, expand=1, fillcolor=(50, 50, 50))
idr = ImageDraw.Draw(rotate)
# Write the base 10 arabic number in the top corner
idr.text((15, 15), str(inp).zfill(4))
rotate.save("./output/number_%s.png" % (str(inp).zfill(4)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment