commit 8b9636305cd81c2ae1e2514269e6b9caed311a08 Author: cubernetes Date: Fri Aug 11 16:38:00 2023 +0200 All diff --git a/assets/img/42.png b/assets/img/42.png new file mode 100755 index 0000000..9a7847f Binary files /dev/null and b/assets/img/42.png differ diff --git a/assets/misc/terms_without_blink.txt b/assets/misc/terms_without_blink.txt new file mode 100755 index 0000000..cec264d --- /dev/null +++ b/assets/misc/terms_without_blink.txt @@ -0,0 +1,1274 @@ +ibmaed +iris-ansi-net +ibmapa8c +ibm-system1 +interix +ibm8514-c +iris-color +ibm+color +intertec +ibmapa16 +ibm-pc +intext2 +intextii +ims-ansi +intext +ibmapa8 +ibcs2 +intertube2 +i3101 +ibm327x +infoton2 +infoton +ipsi +ibm5051 +ibm5154-c +iris-ansi +ibmmpel-c +ims950 +ibmmono +ibmapa8c-c +ibm+16color +ibm3101 +ibm6153-40 +iq140 +ibmvga-c +ims950-b +iq120 +i100 +ibmvga +ibmega +ibm6154-c +ims950-rv +interix-nti +iris-ansi-ap +ibm-apl +ibmega-c +ibm8514 +ips +ibm5081-c +ifmr +intertube +iris40 +i400 +MtxOrb +MtxOrb204 +MtxOrb162 +X-hpterm +X-hpterm-color2 +lpr +ln03 +ln03-w +liswb +layer +luna +lisa +linux+decid +luna68k +linux+sfkeys +la120 +fox +f1720 +fixterm +fenixw +f100-rv +fenix +f100 +falco-p +falco +freedom +freedom-rv +f1720a +freedom100 +2621A +2621-wl +2621 +2621a +regent25 +regent40+ +rxvt+pcfkeys +rtpc +report+version +regent60 +rcons +regent100 +regent +regent200 +regent40 +report+da2 +rca +regent20 +rcons-color +darwin-256x96-m +dwk-vt +diablo1620-m8 +datagraphix +dm1520 +dg+fixed +dialogue80 +darwin-200x75 +dataspeed40 +d800 +digilog +dwk +dgkeys+15 +dgkeys+11 +dp3360 +darwin-160x64 +dw1 +dt110 +darwin-80x30-m +dd5000 +dt-100 +dgunix+fixed +darwin-100x37-m +darwin-90x30 +dg6053-old +dgkeys+7b +dg100 +darwin-f +darwin-160x64-m +dg+color +dtc300s +diablo1620 +darwin-128x40 +dw4 +dt100w +diablo1640-m8 +dmchat +diablo1740 +darwin-80x30 +dgkeys+8b +dtc382 +d132 +dp8242 +dec+sl +djgpp203 +diablo1640-lm +dt-100w +darwin-90x30-m +darwin-128x48-m +diablo450 +darwin-256x96 +darwin +darwin-80x25 +datamedia2500 +diablo1740-lm +dumb +diablo1640 +dg-ansi +dgmode+color8 +dgmode+color +delta +dmterm +dm3045 +decwriter +dmd1 +dg200 +darwin-80x25-m +dmd-24 +dgunix+ccc +dg211 +diablo1720 +darwin-200x75-m +ds40-2 +darwin-200x64 +darwin-112x37-m +decid+cpr +darwin-m +darwin-128x48 +darwin-128x40-m +dg450 +diablo +dw +dg210 +darwin-200x64-m +decpro +ds40 +dec+pp +darwin-m-b +dm2500 +darwin-f2 +dg+color8 +dmd +diablo630 +dt100 +dumb-emacs-ansi +dw2 +darwin-b +dm3025 +diablo1730 +darwin-m-f2 +darwin-100x37 +dg6134 +dmd-34 +d80 +darwin-144x48-m +dialogue +darwin-112x37 +dku7003-dumb +dg+ccc +dm1521 +datapoint +dw3 +darwin-144x48 +darwin-m-f +dt80-sas +diablo-lm +8510 +ep4080 +esprit-am +elks +elks-glasstty +elks-vt52 +ecma+italics +elks-ansi +ep40 +ecma+color +ecma+index +ecma+strikeout +ergo4000 +eterm +ep4000 +ep48 +esprit +ex155 +ultima2 +unknown +ultimaII +630-lm +qdss +qvt119+-w +qvt119p-25-w +qvt119+ +qvt119p +qvt101 +qvt119 +qvt119+-25 +qvt108 +qdcons +qvt119+-25-w +qume5 +qvt119-25-w +qvt101+ +qume +qvt119p-25 +qvt119-w +qvt102 +qvt119p-w +qvt101p +bg1.25 +bantam +bh4 +beehiveIIIm +beterm +bg1.25nv +bg2.0rv +bobcat +bracketed+paste +bg3.10nv +beehive3 +bitgraph +beehive4 +bg3.10 +bterm +bee +blit +bg1.25rv +bg2.0nv +bh3m +bsdos-sparc +b-128 +bg3.10rv +beehive +basis +bg2.0 +superbrain +swtp +sc410 +superbee +sbi +simterm +sun-17 +sun-e +sun-cmd +sc415 +sun-cgsix +soroc120 +sun1 +system1 +superbee-xsb +sune +screen+fkeys +sun-color +sun-s-e +sbobcat +sb2 +sun-e-s +sun-1 +sun-34 +sun-ss5 +screen.xterm-r6 +spinwriter +st52-color +scanset +sun +sun-type4 +soroc140 +sun-48 +sv80 +screen+italics +synertek380 +sun+sl +st52 +sb1 +sun-12 +sibo +sun-s +screwpoint +st52-m +screen-bce.gnome +simpleterm +sun-c +sun-24 +superbeeic +sun-il +synertek +screen2 +sun2 +st52-old +sb3 +soroc +sun-nic +screen.gnome +xterm+pcc3 +xterm+alt+title +x10term +xterm+sl-twm +xtermc +xnuppc+80x25 +xterm+sm+1006 +xnuppc+128x40 +xterm+tmux +xnuppc-256x96 +x820 +xterm-pcolor +xerox-lm +xterm+noalt +xterm+focus +xterm+pce2 +xnuppc+f +xterm+keypad +xnuppc-f +xterm+sl +xfce +xnuppc+200x75 +xterm+88color2 +xterm+tmux2 +xnuppc-128x48 +xnuppc+80x30 +xnuppc-m-b +xterm-24 +xtalk +xterms +xnuppc-200x64 +xterm+edit +xterm+direct2 +xnuppc-100x37 +xterm+pcc2 +xerox820 +xl83 +xterm+pcc0 +xterm+pcf0 +xnuppc+90x30 +xterm+meta +xterm-color +xterm+indirect +xiterm +xterm+256color2 +xterm+vt+edit +xnuppc+256x96 +xnuppc-m +xterm+sm+1002 +xterm+pc+edit +xgterm +xnuppc-80x30 +xterm+256color +xterm+direct256 +xnuppc+basic +xterm+kbs +xterm+app +xnuppc+100x37 +xnuppc-128x48-m +xwsh +xterm+sm+1005 +x10term+sl +xnuppc-200x75 +xterm+alt1049 +xterm+titlestack +xnuppc-80x25 +xterm+noapp +xerox +xnuppc+b +xterm-old +xnuppc-144x48-m +xnuppc-90x30-m +xnuppc-112x37 +xterm+nopcfkeys +xerox1720 +xnuppc-200x75-m +xterm+pcfkeys +xterm+direct +xnuppc-m-f2 +xterm+alt47 +xnuppc+144x48 +xterm-xf86-v33 +xnuppc-200x64-m +x1750 +xnuppc-128x40-m +xterm+direct16 +xnuppc+200x64 +xnuppc-112x37-m +xterm+88color +xnuppc-160x64 +xterm+acs +xnuppc+112x37 +xnuppc+f2 +xnuppc-80x30-m +x1700 +xnuppc+c +xnuppc-90x30 +xnuppc-80x25-m +xterm-mono +xterm-bold +xterm-vt52 +xnuppc-256x96-m +xnuppc-m-f +x1700-lm +xnuppc+160x64 +xnuppc-144x48 +xterm-xi +xnuppc-100x37-m +xterm+pcf2 +xterm-r5 +xterm-xf86-v32 +xnuppc+128x48 +xterm+x10mouse +xterm+256setaf +xterm+x11mouse +xnuppc-f2 +xterm+r6f2 +x1720 +xterm+x11hilite +xterm-r6 +xnuppc +xterm+pcc1 +xterm+sm+1003 +xnuppc-160x64-m +xnuppc-b +xterm+sl-alt +xnuppc-128x40 +xterm+osc104 +wy75-vb +wy50-vb +wy75-w +wy50 +wy30 +wy160-tek +wyse30-vb +wyse-75ap +wy50-w +wyse75ap +wy100q +wren +wyse75-w +wyse75-vb +wyse75 +wyse50-w +wy100 +wy50-wvb +wyse50-vb +wyse50 +wyse+sl +wy75-wvb +wyse30 +wyse50-wvb +wyse-vp +wy75ap +wy370-tek +wyse75-wvb +wsiris +wy99gt-tek +wy75 +wrenw +wy30-vb +wy-75ap +opennt-25-w-vt +o85h +opennt-25-nti +opennt-60-w +opennt-60 +oabm85h +oldsun +old-st +opennt-100 +opennt-nti +opennt-25 +opennt-35 +otek4115 +ojerq +osborne-w +opennt-25-w +osexec +osborne +opennt-w +opennt-35-w +otek4112 +otek4113 +osborne1-w +opennt-35-nti +otek4114 +owl +opennt-100-nti +o31 +oldpc3 +osborne1 +opennt-60-nti +opennt-50-w +opennt-w-vt +oblit +origibmpc3 +o4112-nd +origpc3 +opennt +opennt-50-nti +omron +oldibmpc3 +opennt-50 +kitty+common +klone+acs +kitty +kermit-am +kvt +klone+color +k45 +kaypro2 +kitty-direct +kt7 +klone+koi8acs +kermit +ktm +konsole+pcfkeys +kterm-color +kterm +kitty+setal +kterm-co +kaypro +ntconsole-100 +ncr260vt+sl +ntconsole-60-nti +ntconsole-35-nti +nec +nwp511 +ntconsole-60 +ntconsole +ntconsole-25-w-vt +ntconsole-50-nti +nwp-511 +ndr9500-25-nl +newhpkeyboard +nd9500 +northstar +ntconsole-100-nti +ntconsole-25-w +nsterm+c41 +ntconsole-35-w +no+brackets +ntconsole-35 +ntconsole-25 +ntconsole-w +nextshell +ncr260vp+sl +ntconsole-60-w +ntconsole-w-vt +ntconsole-50 +nsterm+s +ndr9500-25 +nxterm +ndr9500 +ncr7900iv +ntconsole-50-w +next +nsterm+c +nec5520 +ntconsole-25-nti +ndr9500-nl +apollo +ansi+enq +apple-uterm +ansi+local +ansi-mtabs +ansi+cup +ampex80 +att5320 +alt2 +atari_st +adm2 +aixterm-16color +appleIIe +atarist-m +abm85 +abm85h-old +adds980 +ansi-nt +ansi77 +apple-ae +altoheath +adm+sgr +ansi+inittabs +att4415+nl +apple2e +att2300 +awsc +atari_st-color +a80 +adm21 +altos-4 +altos4 +atari-color +appleIIgs +ansi+tabs +act4 +altos2 +aa4080 +att5310 +atari-old +abm85h +adm42 +appleIIc +atari-m +att610+cvis0 +adm1178 +adm1a +aixterm +adm3a +att4424m +a210 +aj832 +addsvp60 +adm3 +adm5 +ampex175 +adm22 +ansi-mini +at +alto-heath +ansi+erase +aaa+dec +apple2e-p +apple-uterm-vb +appleII +abm85e +att5620-1 +abm80 +ansi+cpr +ampex-232 +aixterm-m +aj +ampex232 +apple-vm80 +att5620-34 +aws +ampex210 +apple-soroc +ampex232w +ampex175-b +avt+s +altos-2 +ansi+rep +apple-videx2 +aepro +apl +alto-h19 +ansi-mr +aas1901 +at-color +adm20 +aixterm+sl +altoh19 +atari +ansi+sgrso +ansi+csr +annarbor4080 +ansi+arrows +adm31-old +apple80p +aj510 +adm1 +addrinfo +ansi+local1 +ansi+idc +apple-videx3 +ansi+rca2 +ap-vm80 +att5620 +aixterm-m-old +apple-videx +adm3a+ +att5420+nl +att5620-24 +aj830 +att4420 +apple-80 +att5620-s +ansi+pp +addsviewpoint +att4426 +adds200 +att2350 +ansi+sgrul +ansi+idc1 +ansi+idl +a980 +act5 +adm12 +adm42-ns +ansi+idl1 +alt4 +adm31 +ansi+rca +at-m +9term +1730-lm +1178 +z-100bw +zen30 +z100 +zenith29 +z50 +ztx-1-a +zen50 +z110bw +z-100 +z100bw +ztx +z29 +z30 +z19 +z110 +zenith +ztx11 +zt-1 +z29b +5620 +5051 +gigi +gnome-rh62 +guru+rv +gnome-rh80 +gt42 +gnome-2008 +gnome-rh72 +go140w +gt100a +guru+s +graphos-30 +gnome-2007 +gator-t +graphos +glasstty +gator-52t +go140 +gator +gnome-256color +gnome-2012 +gnome-rh90 +gnome-fc5 +gt100 +gsi +gnome +gator-52 +gnome+pcfkeys +gt40 +cit101e-n132 +cdc756 +cdc456 +citoh +contel320 +ct8500 +c301 +ca22851 +chromatics +cg7900 +ct82 +cyb110 +cbblit +contel301 +cops10 +cit101e-132 +citoh-comp +contel321 +cgc2 +ci8510 +citoh-elite +cyb83 +citoh-pica +cygwin +citc +cs10 +cops-10 +cgc3 +cit101e-n +contel300 +cx100 +cad68-3 +cbunix +color_xterm +colorscan +coherent +cit80 +citoh-prop +citoh-8lpi +c300 +c321 +cit101 +cad68-2 +cdc721ll +cdc721 +cops +citoh-ps +cdc752 +cx +cit-80 +cs10-w +cit101e +commodore +citoh-6lpi +jaixterm +jerq +jaixterm-m +mimeii +mgr-sun +mimei +msk227am +mskermit227am +mime3ax +mime1 +mime314 +mt4520-rv +microbee +modgraph2 +masscomp +mime-3ax +mono-emx +mime2a-s +macterminal-w +mlterm+pcfkeys +mime-hb +mime2 +mime-fb +masscomp2 +mime340 +mlterm2 +mdl110 +msk22714 +mterm +mime2a +microterm +microb +mskermit227 +mac-w +mime3a +mm314 +mt70 +mime2a-v +mouse-sun +mime +mgr-linux +masscomp1 +mm340 +mgr +mskermit22714 +megatek +microterm5 +mt-70 +msk227 +4025ex +4027ex +tek4025a +tty40 +t653x +tvi920c +tty5620-1 +t3800 +tvi920b-p +tty43 +ti707-w +tvi970-2p +tek4012 +trsII +tvi912b+dim +tvi912c-p-vb +tek4027-ex +tvi920b-2p-p +ti707 +teletec +terminator +terminet300 +tvipt +termite +tvi912b-p-vb +tkterm +tvi920b-vb-p +terminet1200 +tty5620 +tty5620-34 +tvi914 +tek4112-5 +trs16 +tek4013 +tvi920c-vb +tvi912c-2p +tek4112-nd +tandem6510 +teken-vt +tvi912c-vb +tek4015-sm +tvi925-hi +tvi910 +tvi920b +ts1 +tvi92D +ts1p +tvi92B +ts-1p +tty35 +tvi912c-unk-2p +tvi912c-p +tvi921 +teken +tvi920b-unk-vb +tek4025 +tvi920b-vb +tek4112 +tvi910+ +tek4113-nd +ti745 +tvi912b-2p-unk +tek4113-34 +tek4025-cr +tek4014-sm +tvi912cc +tvi912b +tt +tt52 +tty4426 +t10 +ti703-w +tvi920c-p-2p +tty37 +tvi920c-vb-unk +tek4113 +tvi912b-unk +tty4424m +ti800 +tvi912b+2p +tvi920b+fn +tek +tvi925 +tvi912b-vb-p +tw52-color +tty4420 +terminology-1.0.0 +tvi912b-p-2p +tvi950 +tvi803 +tandem653 +tvi920b-p-vb +tvi920c-p-vb +tvi912b-2p-p +tvi920b-unk-2p +ti703 +tvi920b-2p-unk +tvi970-vb +ti735 +tvi912 +tvi912b-vb +tvi920b-vb-unk +t3700 +tvi920c-unk +tty33 +tvi912b-2p +tvi912b+printer +terminet +tek4025-17 +tvi920b-2p +trs80II +tvi970 +tvi920c-vb-p +tvi912c-vb-unk +tvi920c-2p +tvi920c-p +tw52-m +t1061f +tty5620-s +ti700 +tvi912c-unk +teken-sc+fkeys +ttydmd +tek4025ex +tek4025-ex +t1061 +tvi950-rv-2p +tvi920b-p-2p +teken-sc +tvi912b+vb +tek4023 +tek4027 +tvi920c-2p-unk +teken-vt+fkeys +tvi912b-unk-2p +tvi950-4p +t16 +tvi912b-p +ti733 +tgtelnet +teken-2022 +tvi950-rv-4p +tek4114 +tvi950-2p +tty5420+nl +tvi912c-vb-p +tek4015 +teleray +tw52 +tvi912c-2p-p +tek4024 +tn300 +tvi912c-2p-unk +tvi950-rv +tvi912b-vb-unk +tek4014 +tvi912c-unk-vb +tty5620-24 +ts-1 +tvi920b-unk +tvi912b-unk-vb +trs2 +tvi912c-p-2p +tvi920c-unk-2p +teken-16color +tvi920 +tvi920c-unk-vb +tvi912c +tek4025-17-ws +tvi920c-2p-p +tn1200 +hp2621b-kx-p +hp+pfk+cr +hpansi +hp98720 +hp2621b-kx +h19-b +hz1520-noesc +hz1500 +h-100bw +hpex +hp2621a +hp2627a-rev +hp2392 +hz1552 +hp2621-fl +hz1520 +h19k +hpterm-color2 +hpterm-color +hp98550a-color +h100bw +hp+arrows +hz1510 +hp2621-a +hp9845 +h19kermit +hp9837 +h19 +hp236 +hz1000 +heath +hp2621 +hpgeneric +hp2621-48 +hp98550-color +h19-g +hp2627c +hp2621b +h100 +heathkit-a +heath-ansi +hp110 +hp2645a +hz1420 +hp2621-k45 +hp2621k45 +h-100 +hp2621p +hp2621A +hp98721 +h19-smul +hp2621-ba +heathkit +hp+printer +hp2621b-p +hp+pfk-cr +heath-19 +h19-u +ha8686 +hp2621-wl +hp+pfk+arrows +h19-bs +hp2621a-a +hp2647a +hp2 +hpterm +h19a +h19us +h19-us +hp2621-nt +hp2621-nl +hp700 +hp2627a +htx11 +hp+labels +ha8675 +hpex2 +hp2621p-a +hp2641a +h19g +hp+color +hz1552-rv +h19-a +hp700-wy +hp300h +hz2000 +hp +hmod1 +hpsub +putty+fnkeys+xterm +putty+fnkeys+linux +pccon0 +pe550 +pcix +pt250 +pc-coherent +pmcons +pccon0-m +pe1100 +pe6300 +pe7000c +psx_ansi +pccon+sgr+acs +pe6312 +putty+fnkeys +putty+fnkeys+vt100 +printer +pccon+sgr+acs0 +pcz19 +pckermit12 +p19 +pro350 +pt250w +putty+keypad +pckermit120 +pmconsole +pt100w +pckermit +pccons +pccon +putty+fnkeys+sco +putty+fnkeys+vt400 +pt100 +pe6100 +pt210 +pccon+colors +pccon-m +pty +pt200w +pilot +putty+screen +prism2 +pe1251 +pccon+keys +pccon+base +pt200 +putty+fnkeys+esc +pcconsole +pe7000m +pc-venix +pe1200 +vte-2017 +vt-61 +vc203 +vt100-nav-w +vi50adm +vt100+pfkeys +vc404-s +vi50 +vk100 +vt200-js +vc414 +venix +vt61 +vi200-rv +vt52 +vc404 +vapple +vc415 +vte+pcfkeys +vt420+lrmm +vt100+fnkeys +vanilla +vsc +vt220+cvis8 +vitty +vp60 +vi550 +vc303 +vi300 +viewdata-o +viewdata +vt102+enq +vi500 +viewdata-rv +vte-2008 +viewpoint +vt220+vtedit +vi55 +viewpoint90 +vt220-js +vte-2014 +vte-2012 +vs100 +vp90 +vc403a +vte-2007 +vremote +vt100-w-nav +vt220+keypad +vt52+keypad +v3220 +vc103 +vt52-basic +vt100+enq +vi200-f +vt220+pcedit +vs100-x10 +vc414h +vt50 +vi200 +vt220+cvis +viewpoint60 +vc303a +vt100+keypad +vi300-old +vt61.5 +vt50h diff --git a/assets/sound/background_music.mp3 b/assets/sound/background_music.mp3 new file mode 100755 index 0000000..7f9c6fb Binary files /dev/null and b/assets/sound/background_music.mp3 differ diff --git a/assets/sound/collect.mp3 b/assets/sound/collect.mp3 new file mode 100755 index 0000000..19d6153 Binary files /dev/null and b/assets/sound/collect.mp3 differ diff --git a/assets/sound/lost.mp3 b/assets/sound/lost.mp3 new file mode 100755 index 0000000..bd5c42f Binary files /dev/null and b/assets/sound/lost.mp3 differ diff --git a/assets/sound/rick.mp3 b/assets/sound/rick.mp3 new file mode 100755 index 0000000..70f1c5e Binary files /dev/null and b/assets/sound/rick.mp3 differ diff --git a/assets/sound/start.mp3 b/assets/sound/start.mp3 new file mode 100755 index 0000000..98d875b Binary files /dev/null and b/assets/sound/start.mp3 differ diff --git a/assets/video/rick.mp4 b/assets/video/rick.mp4 new file mode 100755 index 0000000..86e60ba Binary files /dev/null and b/assets/video/rick.mp4 differ diff --git a/assets/video/rick2.mp4 b/assets/video/rick2.mp4 new file mode 100755 index 0000000..0927819 Binary files /dev/null and b/assets/video/rick2.mp4 differ diff --git a/bootstrap.cmd b/bootstrap.cmd new file mode 100755 index 0000000..56d3844 --- /dev/null +++ b/bootstrap.cmd @@ -0,0 +1,5 @@ +python3 -m venv env +.\env\bin\activate.bat +python3 -m pip install -r requirements.txt +echo Ready +pause diff --git a/game.py b/game.py new file mode 100755 index 0000000..5254dcd --- /dev/null +++ b/game.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python3 + +import sys +import random + +from time import sleep +import numpy as np +import cv2 +import requests + +from utils import * + +def get_42_img( + img_path: str, + margin_top: int, + margin_bottom: int, + margin_left: int, + margin_right: int, +) -> np.ndarray: + global img42_side_len + + img: np.ndarray = cv2.imread(img_path, 0) + + if len(img.shape) in [1, 2]: + img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) + + img_height, img_width = img.shape[:2] + img = img[ + margin_top:img_height-margin_bottom, + margin_left:img_width-margin_right, + ] + + b_top, b_bottom, b_left, b_right = [10]*4 + img = cv2.copyMakeBorder(img, b_top, b_bottom, b_left, b_right, cv2.BORDER_CONSTANT, value=(0, 0, 0)) + + img = cv2.resize(img, (img42_side_len, img42_side_len)) + + return img + +img42_side_len: int = 100 +img42: np.ndarray = get_42_img( + "./assets/img/42.png", + margin_top = 100 + 20, + margin_bottom = 100 + 20, + margin_left = 100, + margin_right = 100, +) + +def touches_42(x: int, y: int, img42_x: int, img42_y: int) -> bool: + global collected_42 + + return ( + img42_x <= x <= img42_x + img42_side_len + and img42_y <= y <= img42_y + img42_side_len + ) + +def add_directional_triangle( + frame: np.ndarray, + x1: int, + y1: int, + x2: int, + y2: int, + rgb: tuple[int, int, int], + side_len: int, + stretch: float, +) -> tuple[int, int]: + dir_vector: np.ndarray = np.array([ + x1 - x2, y1 - y2 + ]).astype(np.float64) + + # normalize + norm = np.linalg.norm(dir_vector) + dir_vector /= (norm or 1) + + # TODO: Fix type issue + side_len *= norm / 15 + # stretch /= (norm/30) + + triangle_height: float = side_len * (3**0.5) / 2 + half_base: float = side_len / 2 + + perp_vector: np.ndarray = np.array([-dir_vector[1], dir_vector[0]]) + + apex_vertex = (int(x1 + dir_vector[0] * triangle_height * 2/3 * stretch), int(y1 + dir_vector[1] * triangle_height * 2/3 * stretch)) + left_vertex = (int(x1 - perp_vector[0] * half_base - dir_vector[0] * triangle_height/3), + int(y1 - perp_vector[1] * half_base - dir_vector[1] * triangle_height/3)) + right_vertex = (int(x1 + perp_vector[0] * half_base - dir_vector[0] * triangle_height/3), + int(y1 + perp_vector[1] * half_base - dir_vector[1] * triangle_height/3)) + + triangle: np.ndarray = np.array([apex_vertex, left_vertex, right_vertex]) + cv2.drawContours(frame, [triangle], 0, rgb, -1) + + return apex_vertex + +def show_frame(frame: np.ndarray, to_stdout: bool=False) -> None: + if to_stdout: + sys.stdout.buffer.write(frame.tobytes()) + else: + cv2.namedWindow("Image", cv2.WND_PROP_FULLSCREEN) + cv2.setWindowProperty("Image", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) + cv2.imshow("Image", frame) + cv2.waitKey(1) + +def collect_vfx() -> None: + requests.post('http://10.11.250.225:8080/api/v1/composition/layers/2/clips/5/connect') + sleep(1) + requests.post('http://10.11.250.225:8080/api/v1/composition/layers/2/clips/7/connect') + +def die_vfx() -> None: + requests.post('http://10.11.250.225:8080/api/v1/composition/layers/2/clips/6/connect') + sleep(3) + requests.post('http://10.11.250.225:8080/api/v1/composition/layers/2/clips/7/connect') + +def green() -> None: + threading.Thread(target=collect_vfx).start() + +def die() -> None: + threading.Thread(target=die_vfx).start() + +def main() -> int: + music = start_game_sfx() + + capture: cv2.VideoCapture = cv2.VideoCapture(0) + hands: mp.solutions.hands.Hands = mp_hands.Hands(max_num_hands=3) + collected_42: bool = True + noise_42img: int = 5 + img42_x: int = -img42_side_len - 1 - noise_42img + img42_y: int = -img42_side_len - 1 - noise_42img + no_fingers: int = 0 + score: int = 0 + finger_x: int = -1 + finger_y: int = -1 + no_collect_ratio = 0 + no_finger_ratio = 0 + timer = 200 + + i: int = 0 + while True: + success: bool + frame: np.ndarray + success, frame = capture.read() + if not success: + continue + + frame = cv2.flip(frame, 1) + ratio = max(no_finger_ratio, no_collect_ratio) + frame = cv2.addWeighted(frame, 1 - ratio, np.ones(frame.shape, dtype=frame.dtype), ratio, 0) + if i > 30: + if collected_42: + collected_42 = False + frame_height, frame_width = frame.shape[:2] + img42_x = random.randint(0, frame_width - img42_side_len - 1 - noise_42img) + img42_y = random.randint(0, frame_height - img42_side_len - 1 - noise_42img) + while ((finger_x - img42_x) ** 2 + (finger_y - img42_y) ** 2) ** .5 < 200: + img42_x = random.randint(0, frame_width - img42_side_len - 1 - noise_42img) + img42_y = random.randint(0, frame_height - img42_side_len - 1 - noise_42img) + rand_noise_y = random.randint(0, noise_42img) + rand_noise_x = random.randint(0, noise_42img) + frame[ + img42_y + rand_noise_y : img42_y + img42_side_len + rand_noise_y, + img42_x + rand_noise_x : img42_x + img42_side_len + rand_noise_x, + ] = img42 + no_collect_ratio = min(i, timer) / timer + + finger_positions = list(get_finger_positions(frame, hands, add_landmarks=True)) + if finger_positions == []: + no_fingers += 1 + no_finger_ratio = min(no_fingers, 255) / 255 + else: + no_fingers = 0 + + if ratio > 0.99: + if music: + music.kill() + lost_sfx() + die() + return score + + for positions in finger_positions: + index_knuckle_1_pos: tuple[int, int] = (-1, -1) + for finger_id, finger_x, finger_y in positions: + if finger_id == FingerType.INDEX_KNUCKLE_2: + index_knuckle_1_pos = (finger_x, finger_y) + elif finger_id == FingerType.INDEX_TIP and index_knuckle_1_pos != (-1, -1): + apex_x, apex_y = add_directional_triangle( + frame, + finger_x, + finger_y, + *index_knuckle_1_pos, + (0, 0, 0,), + side_len=70, + stretch=2.0, + ) + if not collected_42 and ( + touches_42(apex_x, apex_y, img42_x, img42_y) + or touches_42(finger_x, finger_y, img42_x, img42_y) + ): + collected_42 = True + i = 0 + score += 42 + if score == 4200 / 4: # that's 25 collects + initiate_rick() + timer = 60 + (timer - 60) * .9 + collect_sfx() + green() + show_frame(frame, to_stdout=(not sys.stdout.isatty())) + i += 1 + +if __name__ == '__main__': + save_score(main()) diff --git a/requirements.txt b/requirements.txt new file mode 100755 index 0000000..248b063 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,24 @@ +absl-py==1.4.0 +attrs==23.1.0 +cffi==1.15.1 +contourpy==1.1.0 +cycler==0.11.0 +flatbuffers==23.5.26 +fonttools==4.42.0 +kiwisolver==1.4.4 +matplotlib==3.7.2 +mediapipe==0.10.3 +numpy==1.25.2 +opencv-contrib-python==4.8.0.76 +opencv-python==4.8.0.76 +packaging==23.1 +Pillow==10.0.0 +playsound==1.3.0 +protobuf==3.20.3 +pycairo==1.24.0 +pycparser==2.21 +# PyGObject==3.44.1 +pyparsing==3.0.9 +python-dateutil==2.8.2 +six==1.16.0 +sounddevice==0.4.6 diff --git a/utils.py b/utils.py new file mode 100755 index 0000000..29a9684 --- /dev/null +++ b/utils.py @@ -0,0 +1,118 @@ +import sys +import time +from enum import Enum +from subprocess import Popen +from typing import Generator +from types import ModuleType +import threading + +# import sounddevice as sd +# import soundfile as sf + +import numpy as np +import mediapipe as mp +import cv2 +from playsound import playsound + +mp_hands = mp.solutions.hands +mp_draw: ModuleType = mp.solutions.drawing_utils + +class FingerType(Enum): + BASE = 0 + BASE_RIGHT = 1 + THUMB_BASE = 2 + THUMB_KNUCKLE_1 = 3 + THUMB_TIP = 4 + INDEX_BASE = 5 + INDEX_KNUCKLE_1 = 6 + INDEX_KNUCKLE_2 = 7 + INDEX_TIP = 8 + MIDDLE_BASE = 9 + MIDDLE_KNUCKLE_1 = 10 + MIDDLE_KNUCKLE_2 = 11 + MIDDLE_TIP = 12 + RING_BASE = 13 + RING_KNUCKLE_1 = 14 + RING_KNUCKLE_2 = 15 + RING_TIP = 16 + PINKY_BASE = 17 + PINKY_KNUCKLE_1 = 18 + PINKY_KNUCKLE_2 = 19 + PINKY_TIP = 20 + +def save_score(score: int) -> None: + with open('./.score', 'w') as score_file: + score_file.write(str(score)) + +def play_audio(file_name: str) -> None: + # Read the audio file + data, samplerate = sf.read(file_name) + + # Play the audio file + sd.play(data, samplerate) + sd.wait() # Wait for the audio playback to complete + +def start_game_sfx() -> None: + # play_audio('./assets/sound/start.mp3') + playsound('./assets/sound/start.mp3') + time.sleep(.5) + # playsound('./assets/sound/background_music.mp3') + # threading.Thread(target=playsound, args=('./assets/sound/background_music.mp3',), daemon=True).start() + +def collect_sfx() -> None: + pass + # threading.Thread(target=play_audio, args=('./assets/sound/collect.mp3',), daemon=True).start() + +def lost_sfx() -> None: + playsound('./assets/sound/lost.mp3') + +def show_matrix() -> None: + Popen(['tmatrix']) + +def initiate_rick() -> None: + # threading.Thread(target=play_audio, args=('./assets/sound/rick.mp3',), daemon=True).start() + cap = cv2.VideoCapture('./assets/video/rick2.mp4') + fps: int = int(cap.get(cv2.CAP_PROP_FPS)) + desired_delay: float = 1 / fps + + while True: + start_time = time.time() + ret, frame = cap.read() + if not ret: + break + sys.stdout.buffer.write(frame.tobytes()) + elapsed_time = time.time() - start_time + remaining_delay = max(desired_delay - elapsed_time, 0) + time.sleep(remaining_delay) + cap.release() + + +def found_hands() -> bool: + capture: cv2.VideoCapture = cv2.VideoCapture(0) + hands = mp_hands.Hands(max_num_hands=1) + success, frame = capture.read() + if not success: + return False + + return list(get_finger_positions(frame, hands)) != [] + +def get_finger_positions( + frame: np.ndarray, + hands: mp.solutions.hands.Hands, + add_landmarks: bool=False, +) -> Generator[list[tuple[int, int, int]], None, None]: + height, width = frame.shape[:2] + + img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + results = hands.process(img_rgb) + + if results.multi_hand_landmarks: + for hand_landmarks in results.multi_hand_landmarks: + positions = [] + for id, lm in enumerate(hand_landmarks.landmark): + x = int(lm.x * width) + y = int(lm.y * height) + positions.append((FingerType(id), x, y)) + yield positions + if add_landmarks: + mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)