예제 #1
0
class Glider(Mode):
    def start(self, count, randomize, step, **params):
        info("start life")
        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        mask = self.fluepdot.buffer.read()

        self.life = life.Life(mask=mask)

        if randomize:
            for c in range(count):
                a, b = int(2. * (random.getrandbits(1) - 0.5)), (int(
                    2. * (random.getrandbits(1) - 0.5)))
                log("got random {:d},{:d}".format(a, b))
                direction = Direction((a, b))
                log("got direction {:s}".format(str(direction)))
                pos = Position(random.randint(0, FRAMESIZE.w - 1),
                               random.randint(0, FRAMESIZE.h - 1))
                step = random.randint(0, 3)
                log("add glider #{:d} at {:d}/{:d} course {:s}".format(
                    c, pos.x, pos.y, str(direction)))
                self.life.spawn(life.Pattern.glider, pos=pos, step=step)

        else:
            d = int(FRAMESIZE.w / count)
            direction = Direction.southeast
            stp = step % 4
            pos = Position(int(FRAMESIZE.w / 2), int(FRAMESIZE.h / 2))
            for c in range(count):
                log("add glider #{:d} at {:d}/{:d} course {:s}".format(
                    c, pos.x, pos.y, str(direction)))
                self.life.spawn(life.Pattern.glider, pos=pos, step=stp)
                pos = Position((pos.x + d) % FRAMESIZE.w, pos.y)
                lon, lat = direction.value
                direction = Direction((lon * -1, lat * -1))
                stp = (stp + 1) % 5

#        self.life.addGlider(direction=Direction.SouthEast)
#        self.life.addGlider(pos=(25,4),step=2,direction=Direction.NorthEast)
#        self.life.addGlider(pos=(50,6),step=4,direction=Direction.SouthWest)
#        self.life.addGlider(pos=(100,8),step=3,direction=Direction.NorthWest)

        self.mask = self.draw(**params)
        return True

    def draw(self, **params):

        prev = self.fluepdot.buffer.read()

        mask = Mask(mask=self.life)
        self.fluepdot.buffer.write(mask)

        info(str(mask))
        return mask

    flags = [
        Mode.FLAG("count"),
        Mode.FLAG("randomize"),
        Mode.FLAG("step"),
    ]
예제 #2
0
class Flueptext(Mode):
    def start(self, randomize, x, y, fluepfont, msg=None, **params):
        #        self.fluepdot.rendering.setMode(Fluepdot.Mode.full)
        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)
        self.randomize = randomize
        self.font = font

        self.msg = "hello, world."
        if msg:
            self.msg = msg

        info("start flueptext {:s}: {:s}".format(fluepfont, self.msg))

        self.mask = self.draw(x, y, fluepfont, **params)
        log(str(self.mask))
        return True

    def draw(self, x, y, fluepfont, **params):
        self.mask = self.fluepdot.text(x, y, fluepfont, self.msg)
        return self.mask

    flags = [
        ("F:", "fluepfont=", "fluepfont", "fixed_10x20", "fluepdot font",
         None),
        Mode.FLAG("x"),
        Mode.FLAG("y"),
        Mode.FLAG("randomize"),
        (None, None, "msg", "hello, world.", "message", None),
    ]
예제 #3
0
class Pixel(Mode):
    def start(self, x, y, invert, **params):
        info("start pixel {:d}/{:d}".format(x, y))

        pxl = self.fluepdot.pixel.read(x, y)
        if pxl:
            log("pixel {:d}/{:d} ⬛︎ bright".format(x, y))
        else:
            log("pixel {:d}/{:d} ⬜︎ dark".format(x, y))

        if not invert and not pxl:
            log("pixel {:d}/{:d} flip bright: ⬛︎".format(x, y))
            self.fluepdot.pixel.flip(x, y, True)

        if invert and pxl:
            log("pixel {:d}/{:d} flip dark: ⬜︎".format(x, y))
            self.fluepdot.pixel.flip(x, y, False)

        mask = self.fluepdot.buffer.read()
        log(str(mask))
        return False

    def draw(self, **params):
        log(str(self.mask))
        return self.mask

    flags = [
        Mode.FLAG("x"),
        Mode.FLAG("y"),
        Mode.FLAG("invert"),
    ]
예제 #4
0
class Life(Mode):
    
    
    def start(self,count,**params):
        info("start life")
        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        mask = self.fluepdot.buffer.read()
        self.life = life.Life(mask=mask)
        self.draw(**params)
        
        return True
        
    
    def draw(self,**params):

        self.life.step()

        return Mask(mask=self.life)


    
    flags = [
        Mode.FLAG("count"),
    ]
예제 #5
0
class Grow(Mode):
    
    
    def start(self,**params):
        info("start grow")

        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)
        self.mask = self.draw(**params)
        return True
        
    
    def draw(self,invert,**params):
        cx = int(FRAMESIZE.w/2)
        cy = int(FRAMESIZE.h/2)
        
        r0 = random.gauss(0.,1.)
        r1 = random.gauss(0.,1.)

        x = cx + int(r0*(cx/4.))
        y = cy + int(r1*(cy/4.))


        pxl = self.fluepdot.pixel.read(x,y)
        
        
        if invert:

            if pxl:
                self.fluepdot.pixel.flip(x,y,False)
                self.mask = self.fluepdot.buffer.read()
                log(str(self.mask))


        else:
                
            if not pxl:
                self.fluepdot.pixel.flip(x,y,True)
                self.mask = self.fluepdot.buffer.read()
                log(str(self.mask))
        

        return self.mask


    flags = [
        Mode.FLAG("invert"),
    ]
예제 #6
0
class Spawn(Mode):
    

    Pattern = life.Pattern
    DefaultPattern = life.Pattern.glider
    DefaultPosition = Position(0,0)
    

    
    def start(self,x,y,randomize,pattern,step,count,flip,**params):
    
        
        info("start spawn {:s}".format(pattern.name.lower()))
        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        self.life = life.Life(mask=self.mask)



        if randomize:
            for c in range(count):
                pos = Position(random.randint(0,FRAMESIZE.w-1),random.randint(0,FRAMESIZE.h-1))
                self.life.spawn(pattern,pos,step,random.choice( list(Flip) ))

        else:
            pos = Position(x,y)
            self.life.spawn(pattern,pos,step,flip)            
        
        self.draw(**params)
        return True


    
    def draw(self,**params):
        
        self.life.step()
        mask = Mask(mask=self.life)

        self.fluepdot.buffer.write(mask)
        
        return mask
    
    
    

    flags = [
        Mode.FLAG("pattern",DefaultPattern),
        Mode.FLAG("step"),
        Mode.FLAG("count"),
        Mode.FLAG("randomize"),
        ("F:","flip=","flip",Flip.noflip,"flip pattern?",lambda x: Flip[x]),
        Mode.FLAG("x"),
        Mode.FLAG("y"),
    ]
예제 #7
0
class Dots(Mode):
    def start(self, **params):
        info("start dots")
        self.count = 0

        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        self.mask = self.fluepdot.buffer.read()
        self.mask = self.draw(**params)

        return True

    def draw(self, invert, **params):

        cx = int(FRAMESIZE.w / 2)
        cy = int(FRAMESIZE.h / 2)

        r0 = random.gauss(0., 1.5)
        r1 = random.gauss(0., 2.)

        x = cx + int(r0 * (cx / 4.))
        y = cy + int(r1 * (cy / 4.))

        prev = Mask(mask=self.mask)

        self.mask[x, y] ^= True
        self.mask[x, y - 1] ^= True
        self.mask[x + 1, y] ^= True
        self.mask[x, y + 1] ^= True
        self.mask[x - 1, y] ^= True

        self.fluepdot.pixel.flip(x, y, self.mask[x, y])
        self.fluepdot.pixel.flip(x, y - 1, self.mask[x, y - 1])
        self.fluepdot.pixel.flip(x - 1, y, self.mask[x - 1, y])
        self.fluepdot.pixel.flip(x + 1, y, self.mask[x + 1, y])
        self.fluepdot.pixel.flip(x, y + 1, self.mask[x, y + 1])

        log(str(self.mask))
        return self.mask

    flags = [
        Mode.FLAG("invert"),
    ]
예제 #8
0
class Guns(Mode):
    def start(self, randomize, **params):
        info("start guns")
        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        self.life = life.Life(mask=self.mask)

        pos1 = Position(10, 2)
        pos2 = Position(60, 7)
        off1 = Position(x=24, y=10)
        off2 = Position(x=24, y=-5)

        self.life.spawn(life.Pattern.gun, pos=pos1)
        self.life.spawn(life.Pattern.eater, pos=pos1 + off1)

        self.life.spawn(life.Pattern.gun, pos=pos2, flip=Flip.horizontal)
        self.life.spawn(life.Pattern.eater,
                        pos=pos2 + off2,
                        flip=Flip.horizontal)

        self.mask = Mask(self.life)

        self.draw(**params)

        return True

    def draw(self, **params):

        self.life.step()
        self.mask = Mask(mask=self.life)

        self.fluepdot.buffer.write(self.mask)
        info(str(self.mask))
        return self.mask

    flags = [
        Mode.FLAG("randomize"),
    ]
예제 #9
0
class Smooth(Mode):

    DefaultFont = FONT.font3x5

    def start(self, font, msg=None, **params):
        #        self.fluepdot.rendering.setMode(Fluepdot.Mode.full)
        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        self.font = Font(font)
        debug(str(self.font))

        self.msg = "hello, world."
        if msg:
            self.msg = msg

        info("start scroll: {:s}".format(self.msg))

        self.mask = Mask()
        self.text = self.font.render(self.msg, fixed=True)

        p0 = int(math.floor(FRAMESIZE.w / (self.font.size.w + 1)))

        p1 = p0 - len(self.msg)

        self.pos0 = Position((self.font.size.w + 1) * int(p1 / 2), 0)

        #        self.pos0 = Position(int(FRAMESIZE.w/2)-int(self.text.w/2), 0 )

        self.mask.addMask(self.text, pos=self.pos0, wrap=True)

        self.fluepdot.buffer.write(self.mask)

        self.l = self.text.w
        self.k = 0

        return True

    def draw(self, **params):

        ret = []

        k = self.k
        L = self.l

        W, H = self.font.size.w + 1, self.font.size.h + 1

        next = Mask()
        pos0 = Position(k, 0)

        next = Mask()
        next.addMask(self.text, pos=self.pos0 + pos0, wrap=True)

        log("from\n" + str(self.mask))
        log("to\n" + str(next))

        #        steps = Morph2(self.mask,next)
        #        steps = Scan(self.mask,next)
        #        steps = [self.mask,next]

        steps = [self.mask, next]

        return next

        for i in range(len(steps)):
            step = steps[i]
            ret += [step]
            self.mask = step

        self.k += 1

        if self.k >= self.l:
            log("step")
            self.k = 0
            self.pos0.x += self.l
            if self.pos0.x + self.l >= FRAMESIZE.w:
                self.pos0.x -= FRAMESIZE.w

        return ret

    flags = [
        Mode.FLAG("font", DefaultFont),
        ("P:", "pause=", "pause", 1.0, "pause", lambda x: int(x)),
        (None, None, "msg", "hello, world.", "message", None),
    ]
예제 #10
0
class Clock(Mode):

    Style = dotlife.clock.Style
    DefaultStyle = dotlife.clock.Style.large

    def start(self, style, stamp, cuckoo, **params):
        self.fluepdot.rendering.setMode(Fluepdot.Mode.full)

        self.clock = dotlife.clock.Clock()
        self.timezone = datetime.timezone(
            datetime.timedelta(seconds=-time.timezone))

        self.now = datetime.datetime.now(self.timezone)
        if stamp != "":
            self.now = datetime.datetime.fromisoformat(stamp)
            self.start = datetime.datetime.now(self.timezone)

        info("start clock: {:s}{:s}".format(self.now.strftime("%F %T"),
                                            " [kuckuck]" if cuckoo else ""))

        self.mask = self.clock.mask(size=FRAMESIZE, now=self.now, style=style)
        self.next = self.mask

        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        self.kuckuck = None
        self.hour = self.now.hour

        return True

    def step(self, style, stamp, **params):
        self.now = datetime.datetime.now(self.timezone)
        if stamp != "":
            self.now = datetime.datetime.fromisoformat(stamp) + (
                datetime.datetime.now(self.timezone) - self.start)

        self.next = self.clock.mask(size=FRAMESIZE, now=self.now, style=style)

    def draw(self, style, stamp, cuckoo, **params):

        if self.kuckuck and self.kuckuck.active():
            hour = int(self.kuckuck.repeat / 1)
            count = int(self.kuckuck.count / 1) + 1
            ret = Mask()

            idx = self.kuckuck.count % 2

            if 1 <= hour <= 4:
                vader = invader.INVADER.one.Mask(idx).double()
                msk = Mask(size=Size((4 + vader.w) * hour, vader.h))
                for c in range(hour):
                    pos = Position(c * (4 + vader.w), 0)
                    msk.addMask(vader, pos=pos)
                ret.addMask(msk)

            elif 5 <= hour <= 8:
                vader = invader.INVADER.one.Mask(idx)
                msk = Mask(size=Size((2 + vader.w) * hour, vader.h))
                for c in range(hour):
                    pos = Position(c * (2 + vader.w), 0)
                    msk.addMask(vader, pos=pos)
                ret.addMask(msk)

            elif 9 <= hour <= 12:
                vader = invader.INVADER.one.Mask(idx)
                msk = Mask(size=Size((2 + vader.w) * ceil(hour / 2), 2 *
                                     (vader.h)))
                for c in range(hour):
                    pos = Position(int(c / 2) * (2 + vader.w), 0)
                    if c % 2 == 1:
                        pos.y += vader.h
                    msk.addMask(vader, pos=pos)
                ret.addMask(msk)

            return ret

        hour = datetime.datetime.now(self.timezone).hour
        if stamp != "":
            hour = (datetime.datetime.fromisoformat(stamp) +
                    (datetime.datetime.now(self.timezone) - self.start)).hour

        if cuckoo == True and hour != self.hour:
            self.step(style, stamp, **params)
            times = hour % 12
            if times == 0:
                times = 12
            self.kuckuck = dotlife.time.Clock.Timer(1500., times)
            debug("KUCKUCK {:}".format(self.kuckuck))
            self.hour = hour
            self.step(style, stamp, **params)
            prev = self.mask
            self.mask = self.next
            return self.draw(style, stamp, cuckoo, **params)  # recurse once!

        if self.next != self.mask:

            if style in [Clock.Style.small, Clock.Style.large]:
                m = Morph2(self.mask, self.next, steps=1, flipcount=1)
                debug("to\n" + str(self.next))
                self.mask = m[1]
            elif style in [Clock.Style.split]:
                m = Morph2(self.mask, self.next, steps=1, flipcount=2)
                debug("to\n" + str(self.next))
                self.mask = m[1]
            else:
                #                debug("to\n"+str(self.next))
                self.mask = self.next

        self.hour = hour
        return self.mask

    flags = [
        Mode.FLAG("style", DefaultStyle),
        ("K", "kuckuck", "cuckoo", True, "kuckuck?", None),
        ("", "stamp=", "stamp", "", "timestamp", None),
    ]
예제 #11
0
class Pipe(Mode):

    DefaultFont = FONT.font3x5

    def start(self, font, **params):
        #        self.fluepdot.rendering.setMode(Fluepdot.Mode.full)
        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        self.font = Font(font)
        log(str(self.font))

        info("start pipe".format())

        if font == FONT.font3x5:
            self.pos = [Position(0, 2), Position(0, 9)]
            self.buffer = [" ", " "]
        elif font == FONT.font5x5:
            self.pos = [Position(0, 2), Position(0, 9)]
            self.buffer = [" ", " "]
        elif font == FONT.font5x7:
            self.pos = [Position(0, 0), Position(0, 9)]
            self.buffer = [" ", " "]
        else:
            self.pos = [Position(0, 0)]
            self.buffer = [" "]
        self.rows = len(self.buffer)

        #        self.buf = self.font.render(self.msg)
        #        log(str(self.buf))

        self.mask = self.draw(**params)

        while True:
            line = sys.stdin.readline()
            if not line:
                log("end of file.")
                break
            debug("read " + line)
            if len(self.buffer) > 1:
                self.buffer[1] = self.buffer[0]
            self.buffer[0] = line.rstrip()[:30]
            self.draw(**params)

        return False

    def draw(self, **params):

        pos = Position(0, 0)

        self.mask = Mask()  #self.fluepdot.buffer.read()
        for i in range(self.rows):
            try:
                self.mask.addMask(self.font.render(self.buffer[i]),
                                  pos=self.pos[i])
            except Error as x:
                pass

#        self.mask.mask(self.buf,pos=pos)
        ret = self.fluepdot.buffer.write(self.mask)
        info(str(self.mask))
        return ret

    flags = [
        Mode.FLAG("font", DefaultFont),
    ]
예제 #12
0
class Echo(Mode):

    DefaultFont = FONT.font5x5

    def start(self, font, alignv, scroll, msg="hello, world", **params):
        dump(params)
        self.fluepdot.rendering.setMode(Fluepdot.Mode.full)
        self.font = Font(font)
        self.msg = msg

        info("start echo: {:s}".format(self.msg))

        if scroll and alignv == AlignVertical.center:
            log("cannot scroll with center vertical alignment")
            scroll = False

        self.text = self.font.render(self.msg)
        log("text is {:}".format(self.text.size()))
        log(str(self.text))

        self.mask = self.draw(scroll, alignv, **params)
        return False

    def draw(self, scroll, alignv, alignh, **params):

        self.mask = Mask()
        if scroll and alignv in [AlignVertical.top, AlignVertical.bottom]:
            rest = Size(FRAMESIZE.w, FRAMESIZE.h - (self.font.size.h + 1))
            top = Position(0, 0)
            bot = Position(0, self.font.size.h + 1)

            prev = self.fluepdot.buffer.read()
            if alignv == AlignVertical.top:
                tmp = prev.subMask(pos=top, size=rest)
                self.mask.addMask(tmp, pos=bot)
            elif alignv == AlignVertical.bottom:
                tmp = prev.subMask(pos=bot, size=rest)
                self.mask.addMask(tmp, pos=top)

        pos = Position(0, 0)
        if alignv == AlignVertical.top:
            pos.y = 0
        elif alignv == AlignVertical.center:
            pos.y = math.floor(abs(FRAMESIZE.h - self.text.h) / 2)
        elif alignv == AlignVertical.bottom:
            pos.y = FRAMESIZE.h - self.text.h

        if alignh == AlignHorizontal.left:
            pos.x = 0
        elif alignh == AlignHorizontal.center:
            pos.x = math.floor(abs(FRAMESIZE.w - self.text.w) / 2)
        elif alignh == AlignHorizontal.right:
            pos.x = FRAMESIZE.w - self.text.w

        self.mask.addMask(self.text, pos=pos)
        return self.mask

    flags = [
        ("S", "scroll", "scroll", False, "scroll line?", None),
        Mode.FLAG("font", DefaultFont),
        Mode.FLAG("msg"),
        Mode.FLAG("alignv", AlignVertical.center),
        Mode.FLAG("alignh", AlignHorizontal.center),
    ]
예제 #13
0
class Fill(Mode):

    Style = Style
    DefaultStyle = Style.check
    DefaultFont = FONT.font3x5

    def start(self, style, invert, font, offset, **params):
        log("start fill with {:s}{:s}".format(str(style),
                                              " [invert]" if invert else ""))

        self.font = Font(font)
        self.offset = offset

        log("before:\n" + str(self.mask))

        msk = self.render(style, invert, **params)
        self.mask.addMask(msk)
        log("after:\n" + str(self.mask))

        return True

    def render(self, style, invert, cutoff, **params):

        ret = Mask()

        if style == Style.check:
            for y in range(FRAMESIZE.h):
                for x in range(FRAMESIZE.w):
                    if x % 2 != y % 2:
                        ret[x, y] = True

        elif style == Style.gauss:
            for y in range(FRAMESIZE.h):
                for x in range(FRAMESIZE.w):
                    if random.gauss(0., 1.) > cutoff:
                        ret[x, y] = True

        elif style == Style.font:
            fill = self.font.render_repertoire(offset=self.offset,
                                               size=self.mask.size())
            self.offset += 1
            ret.addMask(fill)

        elif style == Style.axis:
            fill = Axis(self.mask.size())
            ret.addMask(fill)

        elif style == Style.border:
            fill = Border(self.mask.size())
            ret.addMask(fill)

        if invert:
            ret = ret.inverse()

        return ret

    def draw(self, style, invert, **params):
        self.offset += 1
        self.mask = self.render(style, invert, **params)
        return self.mask

    flags = [
        ("o:", "offset=", "offset", 0, "offset", lambda x: int(x)),
        ("c:", "cutoff=", "cutoff", 0.5, "cutoff", lambda x: float(x)),
        Mode.FLAG("style", DefaultStyle),
        Mode.FLAG("invert"),
        Mode.FLAG("font", DefaultFont),
    ]
예제 #14
0
class Scroll(Mode):

    DefaultFont = FONT.font3x5

    def start(self, font, msg=None, **params):
        #        self.fluepdot.rendering.setMode(Fluepdot.Mode.full)
        self.fluepdot.rendering.setMode(Fluepdot.Mode.diff)

        self.font = Font(font)
        debug(str(self.font))

        self.msg = "hello, world."
        if msg:
            self.msg = msg

        info("start scroll: {:s}".format(self.msg))

        self.mask = Mask()
        self.text = self.font.render(self.msg, fixed=True)

        p0 = int(math.floor(FRAMESIZE.w / (self.font.size.w + 1)))

        p1 = p0 - len(self.msg)

        self.pos0 = Position((self.font.size.w + 1) * int(p1 / 2), 0)

        #        self.pos0 = Position(int(FRAMESIZE.w/2)-int(self.text.w/2), 0 )

        self.mask.addMask(self.text, pos=self.pos0, wrap=True)

        self.fluepdot.buffer.write(self.mask)

        self.l = int(self.text.w / (self.font.size.w + 1))
        self.k = 0

        return True

    def draw(self, **params):

        ret = []

        k = self.k
        L = self.text.w

        W, H = self.font.size.w + 1, self.font.size.h + 1

        next = Mask()
        pos0 = Position(-W, 0)
        pos1 = Position(k * W, 0)

        if k != 0:
            txt0 = self.text.subMask(size=Size(k * W, H))
            next.addMask(txt0, pos=self.pos0 + pos0, wrap=True)

        if self.l - k != 0:
            txt1 = self.text.subMask(pos=Position((k) * W, 0),
                                     size=Size((self.l - k) * W, H))
            next.addMask(txt1, pos=self.pos0 + pos1, wrap=True)

#        log("from\n"+str(self.mask))
#        log("to\n"+str(next))

        steps = Morph2(self.mask, next)

        if len(steps) >= 2:
            return steps[1]
        return steps[0]

        steps = [self.mask, next]

        for i in range(len(steps)):
            step = steps[i]
            ret += [step]
            self.mask = step

        self.k += 1
        if self.k > self.l:
            log("step")
            self.k = 0
            self.pos0.x -= W
            if self.pos0.x <= -L:
                self.pos0.x += FRAMESIZE.w

        return ret

    flags = [
        Mode.FLAG("font", DefaultFont),
        ("P:", "pause=", "pause", 1.0, "pause", lambda x: int(x)),
        (None, None, "msg", "hello, world.", "message", None),
    ]