1 of 17

つぶやきPyxel で 

地頭力を鍛えよう

malo21st 

【オンライン】はんなりPython #33 LT会 2020/10/16

2 of 17

おまえだれよ

  • 田中丸 祐治(たなかまる ゆうじ)

malo21st  もう簡単に「まろ」でいいです。

  • IT業界とは関係のない完全趣味でPythonやってます。
  • 福岡を中心に、Pythonコミュニティに出没しています。
  • Github : https://github.com/malo21st
  • Twitter : @malo21st

なぜ、malo21st なの?

malo は、高校の国語の先生が

「田中麻呂」と呼んだのが始まり。

21st は、今が 21世紀 だから。

3 of 17

はじまりは、PyConJP2020

4 of 17

Pyxelとは?

5 of 17

「つぶやきPyxel」とは?

from pyxel import *

from math import *

a=0

init(128,128)

while 1:

cls(1)

for x in range(0,128,4):

for y in range(0,128,4):

d=sqrt((x-64)**2+(y-64)**2)

b=sin(d*0.2+a)*4

c=(15-d*0.2)%16

circ(x+b,y+sin(b/4)*4,1,c)

a+=0.2

flip()

6 of 17

まずは「Processing.py」の作品を移植

line(sin(j/10)*25+sin(j/5)*10+O, cos(-j/10)*25+sin(j/5)*25+O,

sin(j/10)*50+sin(j)+sin(j)*5+O,-cos(j/20)*50+cos(j/12)*10+O,

   i%8+7)

from pyxel import *

from math import *

W=256

R=0.3

T=0

init(W,W)

def d(O,T,z,u,v,H,D=0):

s=int(u+z*R*cos(H));t=int(v+z*R*sin(H));line(u,v,s,t,O+6)

if O>0:d(O-1,T,z*(1-R),s,t,H-T,D+1);d(O-1,T,z*(1-R),s,t,H+T,D+1)

while 1:

T+=0.02;cls(0);d(9,T,205,W/2,215,-pi/2);flip()

vintage art リサージュ図形

Tree Curve 再帰処理

7 of 17

Life Game をむりやり280文字に収めてみた

from pyxel import *

O=128

S=O*O

C=[0,0,1,1]*O*32

D=[0]*S

init(O,O)

L=range(S)

while 1:

for i in L:

try:t=C[i-1]+C[i+1]+sum(C[i-O-1:i-O+2]+C[i+O-1:i+O+2])

except:t=2

if t<2 or t>3:D[i]=0

elif t==3:D[i]=1

else:D[i]=C[i]

for i in L:rect(i%O,i//O,1,1,D[i])

C=D[:];flip()

8 of 17

セル・オートマトン(Life Gameの一次元版)

from pyxel import *

w=256

init(w,w)

i=image

b=i(0);d=i(4,system=1)

t=''

u='1'+'0'*w

R={bin(j+8)[3:]:bin(30+w)[10-j] for j in range(8)}

while 1:

b.copy(0,0,4,0,0,w,w);d.copy(0,1,0,0,0,w,w)

for k in range(w):

t+=R[u[(k-1)%w]+u[k]+u[(k+1)%w]];pset(k,0,int(t[k]))

u=t;t='';flip()

R={'000': '0', '001': '1', '010': '1', '011': '1', '100': '1', '101': '0', '110': '0', '111': '0'}

9 of 17

多彩に変化するローズ曲線

from pyxel import *

from math import *

O=128

S=O*2

j=0

init(S,S,fps=6)

while 1:

cls(0)

j+=1;a=j//8;n=j%8+1;d=a%8+1;k=n/d

if k==1:

continue

for i in range(1260*d):

t=i/200

r=100*sin(k*t)

pset(r*cos(t)+O,r*sin(t)+O,j%12+3)

flip()

 1260/200 = 630 ≒ 2π 

描画範囲が分からなかったので、インタラクティブにバラ曲線が描けるアプリをStreamlitで作成

10 of 17

謎の文字列にデータを埋め込む(1)

from pyxel import *

init(81,90,fps=2)

B=""

for c in "솀鲀샼상솀鳁肜胁肀鳼麟삀龁肜胁肀龁胸肁즙肀粒솀飱胁솀飰쎏肀솀鲜鲜胁":B+=bin(ord(c))[2:]

while 1:

i=g=0

for b in B:

C=0 if int(b) else 6+g%9;rect(i%8*9,i//8*9+9,8,8,C);g+=1

if g%64:i+=1

else:flip();i=0

'1100000110000000100111001000000011000000111111001100000011000001110000011000000010011100110000011000000010011100100000001100000110000000100000001001110011111100111110011111001111100111111001111100000010000000100111111000000110000000100111001000000011000001100000001000000010011111100000011000000011111000100000001000000111110001111000011100100110011001100000001000000011111001111110011100000110000000100110001111000111110000100111001000000011000001110000011000000010011000111100001100001110001111100000001000000011100011111000111111001111110011111100111111001111100001111000011100000110000000100111001001110010011100100111001000000011000001'

11000001

10000000

10011100

10000000

11000000

11111100

11000000

11000001

7列×8行の

ビット情報を

謎の文字列に

変換するアプリ

をDashで作成

11 of 17

謎の文字列にデータを埋め込む(2)

from pyxel import *

init(255,255)

B=""

for b in "啕啕啀䕕䀐栔䀁䪠䀀䐨䀀䁐䀀䀅倂栀唀檠䅐䊊䀕䀪栁倀樊攼䀊恿缂樏翰檪翿䊪槿簠䀓缂态䌀䪠䐀䀪橀䀀檤䀀䀪䀀":B+=bin(ord(b))[3:]

def r(x):rect(x*8,i//16*8,8,8,int(B[:2],2)*3)

i=0

while 1:

r(i%16);r(31-i%16);i+=1;flip()

if i<340:B=B[2:]

□□□□□□□□□□□□□□□□

□□□□□□□□□□□□□□□□

□□■■■■□□□□□□■■■■

□■■〇〇■■□□■■■■■■■

□■〇〇〇〇■■■■■■■■■■

□■■〇〇■■■■■■■■■■■

□□■■■■■■■■■■■■■■

□□□■■■■■〇〇〇■■■■■

□□□■■■■〇〇〇〇〇■■■■

□□□■■■■〇〇■〇〇■■■■

□□□■■■■〇〇〇〇〇■■■■

□□■■■■■■〇〇〇■■〇〇〇

□□◇◇■■■■■■〇〇〇■■

□◇◇◇◇◇◇■■■〇〇〇〇■■

◇◇◇◇◇◇◇■■〇〇〇〇〇〇〇

◇◇◇◇◇◇◇■■〇〇〇〇〇〇〇

□◇◇◇◇◇◇■■〇■■■■■■

□■◇◇◇◇■■■〇〇■■■■■

□■■◇■■■■■〇〇〇〇■■■

□■■■■■■■■■〇〇〇〇〇〇

□■■■■■■■■■■〇〇〇〇〇

□■■■■■■■■■■■■〇〇〇

01010101010101010101010101010101

01010101010101010101010101010101

01010000000001010101010100000000

01000010100000010100000000000000

01001010101000000000000000000000

01000010100000000000000000000000

01010000000000000000000000000000

01010100000000001010100000000000

01010100000000101010101000000000

01010100000000101000101000000000

01010100000000101010101000000000

01010000000000001010100000101010

01010011110000000000001010100000

01111111111111000000101010100000

11111111111111000010101010101010

11111111111111000010101010101010

01111111111111000010000000000000

01001111111100000010100000000000

01000011000000000010101010000000

01000000000000000000101010101010

01000000000000000000001010101010

01000000000000000000000000101010

画像データを分割して、Pyxelの16色

に最も近い色

にPILと

numpyで

画像処理

12 of 17

自他共に認める傑作! ハノイの塔

from pyxel import *

D={0:[7,6,5,4,3,2,1],1:[],2:[]}

init(250,80,fps=5)

def g():

cls(0)

for i,d in D.items():

j=0

for k in d:

rect(45+80*i-5*k,64-9*j,10*k,9,k+8);j+=1

flip()

def h(N,f,t,w):

if N>0:

h(N-1,f,w,t);D[t]+=[D[f].pop()];g();h(N-1,w,t,f)

g();h(7,0,2,1);show()

再帰処理の定番

D[t].append(D[f].pop())

13 of 17

評価はイマイチ、だけど好きな作品(1)

from pyxel import *

D={k:bin(ord('÷�¾�ËÝý�ÿß'[k]))[3:] for k in range(10)}

R=[int(ord(c)) for c in '\n\n\t1\n<\t1\n\t7\nd\t2\n\t12<\t1']

init(70,120,fps=2)

c=0

def r(x,y,w,h,s):rect(x,y,w,h,s*10)

while 1:

i=0

for s in D[c%10]:

r(*R[4*i:4*i+4],int(s));i+=1

flip()

c+=1

123文字 → 54文字

D={0:'1110111',1:'0000011',2:'0111110',3:'0011111',4:'1001011',5:'1011101',6:'1111101',7:'0010011',8:'1111111',9:'1011111'}

82文字 → 67文字

R=[10,10,9,49,10,60,9,49,20,10,29,9,20,55,29,10,20,100,29,9,50,10,9,49,50,60,9,49]

7 Digit

14 of 17

評価はイマイチ、だけど好きな作品(2)

from pyxel import *

g=9.8

init(128,255,fps=40)

i=0

L=[]

x=64;y=250;v=0;h=250

def d():circ(x,250-y,5,10)

t=0

while 1:

cls(0);y=h+v*t-0.5*g*t*t;v=v-g*t

if y<0:

if v>-0.2:break

v=-0.26*v;h=0;t=0

if y>h:h=y

d();t+=0.025;flip()

d()

show()

地面に止まる間際の

振動がたまらない!

重力加速度:9.8

1秒:40fps×0.025秒

1秒に拘った結果、

リアルな自由落下が

再現できた。

15 of 17

ま と め

◆「つぶやきPyxel」を通して、感じたこと。

 ・280文字の制限のおかげで、動けばいいアルゴリズム から 一段階上を目指せる。

 ・一見、280文字でコーディングできなさそうな作品は感動を生む。

 ・ネタ探しで、情報が無意識に集まってくる。(カラーバス効果)

 ・付随して、多種多様なスキルを習得する機会がある。

◆向き・不向き

 ・向いてる人 :不自由さの中の自由を楽しめる人。

 ・向いてない人:PEP8 や Pythonista に形から拘る人。

YouTube 英語 がおススメ

16 of 17

ご清聴 ありがとうございました。

【オンライン】はんなりPython #33 LT会 2020/10/16

17 of 17

(参考)関連リンク