From e669b10ebc113424b0af43dd22637897772add7a Mon Sep 17 00:00:00 2001 From: Simon Pirkelmann Date: Fri, 10 Sep 2021 13:46:24 +0200 Subject: [PATCH] connected game to web server --- gauss-turing/game/gauss_turing.py | 40 ++- gauss-turing/game/static/-.png | Bin 0 -> 1363 bytes gauss-turing/game/static/P0.png | Bin 0 -> 8265 bytes gauss-turing/game/static/forward.png | Bin 0 -> 846 bytes gauss-turing/game/static/left.png | Bin 0 -> 2480 bytes gauss-turing/game/static/right.png | Bin 0 -> 2488 bytes gauss-turing/game/static/style.css | 105 +++++++ gauss-turing/game/templates/drag_example.html | 287 ++++++++++++++++++ gauss-turing/game/webapp.py | 163 ++++++++++ 9 files changed, 584 insertions(+), 11 deletions(-) create mode 100644 gauss-turing/game/static/-.png create mode 100644 gauss-turing/game/static/P0.png create mode 100644 gauss-turing/game/static/forward.png create mode 100644 gauss-turing/game/static/left.png create mode 100644 gauss-turing/game/static/right.png create mode 100644 gauss-turing/game/static/style.css create mode 100644 gauss-turing/game/templates/drag_example.html create mode 100644 gauss-turing/game/webapp.py diff --git a/gauss-turing/game/gauss_turing.py b/gauss-turing/game/gauss_turing.py index 0b8940d..038da06 100644 --- a/gauss-turing/game/gauss_turing.py +++ b/gauss-turing/game/gauss_turing.py @@ -2,11 +2,15 @@ import numpy as np import random import pygame import os +import threading + +from webapp import app from event_server_comm import move_grid BLACK = np.array([0, 0, 0], dtype=np.uint8) WHITE = np.array([255, 255, 255], dtype=np.uint8) +GRAY = np.array([200, 200, 200], dtype=np.uint8) RED = np.array([255, 0, 0], dtype=np.uint8) BLUE = np.array([0, 0, 255], dtype=np.uint8) YELLOW = np.array([255, 255, 0], dtype=np.uint8) @@ -26,7 +30,7 @@ tiledt = np.dtype([('x', np.uint8), ('y', np.uint8), ('color', np.uint8, 3), ('s class Board: - valid_colors = [WHITE, RED, BLUE] + valid_colors = [GRAY, RED, BLUE] def __init__(self, dim_x, dim_y): self.tiles = np.zeros((dim_y, dim_x), dtype=tiledt) @@ -80,11 +84,12 @@ class Robot: } - def __init__(self, x, y, orientation): + def __init__(self, x, y, orientation, use_real_robot=False): self.x = x self.y = y self.orientation = orientation self.position_changed = False + self.use_real_robot = use_real_robot def get_forward_coordinates(self): # get the coordinates of the neighboring tile in the given direction @@ -112,7 +117,8 @@ class Robot: return robot_surf def update_pos(self, dimx, dimy): - move_grid(self.x, self.y, self.orientation, dimx, dimy) + if self.use_real_robot: + move_grid(self.x, self.y, self.orientation, dimx, dimy) self.position_changed = False def __repr__(self): @@ -122,7 +128,7 @@ class Robot: class Command: valid_actions = {'forward', 'left', 'right', 'P0', '-'} - def __init__(self, action=None, color=WHITE): + def __init__(self, action=None, color=GRAY): if not (action in Command.valid_actions and any([np.all(color == c) for c in Board.valid_colors])): raise ValueError("invalid values for command") self.action = action @@ -157,7 +163,7 @@ class Programmer: def __init__(self, prg): self.prg = prg self.available_inputs = [Command('forward'), Command('left'), Command('right'), Command('P0'), - Command('-', color=RED), Command('-', color=BLUE), Command('-', color=WHITE)] + Command('-', color=RED), Command('-', color=BLUE), Command('-', color=GRAY)] self.command_to_edit = 0 self.screen_rect = None @@ -196,6 +202,8 @@ class Program: self.screen_rect = None def step(self, state='running'): + if self.prg_counter >= len(self.cmds): + return 'game_over' cmd = self.cmds[self.prg_counter] self.prg_counter += 1 @@ -207,7 +215,7 @@ class Program: tile = self.board.tiles[y, x] # apply next instruction of the program - if np.all(cmd.color == WHITE) or np.all(cmd.color == tile['color']): + if np.all(cmd.color == GRAY) or np.all(cmd.color == tile['color']): # matching color -> execute command if cmd.action == 'forward': ynew, xnew = self.robot.get_forward_coordinates() @@ -264,7 +272,7 @@ class Program: cmd_surf = cmd.render(scale_fac) else: cmd_surf = pygame.Surface((scale_fac,scale_fac)) - cmd_surf.fill(WHITE) + cmd_surf.fill(GRAY) if prg_counter is not None and i == prg_counter: pygame.draw.rect(cmd_surf, tuple(GREEN), (0, 0, scale_fac, scale_fac), 5) prg_surf.blit(cmd_surf, (i * scale_fac, 0, scale_fac, scale_fac)) @@ -280,8 +288,8 @@ class Program: class Game: - def __init__(self, dimx, dimy, robotx, roboty): - self.robot = Robot(x=robotx, y=roboty, orientation='v') + def __init__(self, dimx, dimy, robotx, roboty, use_real_robot=False): + self.robot = Robot(x=robotx, y=roboty, orientation='v', use_real_robot=use_real_robot) self.board = Board(dimx, dimy) coin1x = np.random.randint(0, dimx) coin1y = np.random.randint(0, dimy) @@ -290,7 +298,7 @@ class Game: # TODO fix number of commands at 5 self.cmds = [Command('forward'), Command('left', color=RED), Command('left', color=BLUE), Command('P0'), Command('-')] - self.state = 'won' + self.state = 'reset' self.prg = Program(self.robot, self.board, self.cmds) @@ -450,6 +458,12 @@ class Game: self.state = self.prg.step(self.state) elif event.key == pygame.K_r: self.state = 'reset' + elif event.type == pygame.USEREVENT: + for i, cmd in enumerate(event.cmds): + self.cmds[i].action = cmd.action + self.cmds[i].color = np.array(cmd.color, dtype=np.uint8) + self.reset() + self.state = 'running' return self.state def reset(self): @@ -488,10 +502,14 @@ class Game: pygame.time.wait(100) if __name__ == "__main__": + # launch webapp in thread + webserver_thread = threading.Thread(target=app.run, kwargs={'host': '0.0.0.0', 'port': 5000}) + webserver_thread.start() + seed = 2 random.seed(seed) np.random.seed(seed) - game = Game(dimx=7, dimy=4, robotx=3, roboty=1) + game = Game(dimx=7, dimy=4, robotx=3, roboty=1, use_real_robot=False) game.run() # TODOs diff --git a/gauss-turing/game/static/-.png b/gauss-turing/game/static/-.png new file mode 100644 index 0000000000000000000000000000000000000000..493483d869b3c0bd54d32767504ef8f189342bf4 GIT binary patch literal 1363 zcmeAS@N?(olHy`uVBq!ia0vp^b|B2b1|*9Qu5e*sV0v2>5>XPASgue|l%JNFld4cs zS&*ubT9KK?z)*4P?exG&Pt4DKwa|>W;$k^Zd(f?;1}|*SIb>D_i!Ho@yoNs*;PMp48 z-D7CS{YB|hvY6fK`tx?3=Sy!tojk2FyXE9|?j`rT_p8+DwOcFK#Trz${L=a)ard~z z`uy&SOyKSFD)qU z?Uf4hso9j6lE+}0t9Pt*wvS(?nN-e#>qif+{V3U>$9aF}gZ;3b-BS^!cWK6xG=6=Cg&TLi6#8+|?B9koV2{7tGd<0&*#01+aspeWE|kF7q(|gkal}luU1m%kMIaSyC)v)az8g5 z?k~F1_9=5^=IOJuwqMG6t|xok<^0`U-!HxPe0apOa9QyAnp-c^EnhpV<(15QapG`W zztJn-+~B{L>YAi-v-WuS+V5U@Q0k1FVuqZ$)yzf-b*94EECCm6X1Xq)QZZ@vnWV%$ zBBwlp)MsDF6kgD(bL@0@v-l*+`ZrTrtf~wP`~(4$mVRB0MpYR z>cUQD+qGEYFLn!@m1t8*dsVz>M$_{jyW0ETmlw`^8vFhEi{MXc%r#6ObuROES2R~t zUA|=bUf4atGpOTy=W(803LllPr%u0bAujvv^O=r`p67+#J6e<2Ps^V1YV)#jl?e^$ z{q#3-y6Cy+Iaj@Ux4t_WFL5qg`*h55(fEn(2DU&yd${zdbr4UN$XTb_Me zTiSP-UBP*;*Ifqo_5&FcH(j^AclYwm?e*DFe}6Lua2L(wES^;YERfieyxoB%5(xZs z-dzu*I14-?iy0WWg+Z8+Vb&Z8pdfpRr>`sfQ%)`}RZV}j{F^|bFi#i9kc@k8&oeSI vFmNy}c=bPBTFEA1athboDMI38g7+VlzOq#OtemnCXaj?%tDnm{r-UW|a#LSB literal 0 HcmV?d00001 diff --git a/gauss-turing/game/static/P0.png b/gauss-turing/game/static/P0.png new file mode 100644 index 0000000000000000000000000000000000000000..62536c9803f322d762d0e097e5fcb712720eb605 GIT binary patch literal 8265 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 Hu0mjfui49* literal 0 HcmV?d00001 diff --git a/gauss-turing/game/static/forward.png b/gauss-turing/game/static/forward.png new file mode 100644 index 0000000000000000000000000000000000000000..101422c830efae39c67a6b143cda0361b4a3c70b GIT binary patch literal 846 zcmeAS@N?(olHy`uVBq!ia0vp^b|B2b1|*9Qu5bZTY)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPVrxcqW`=jV%%?u1ow>@1PLo)8Yy>0IyoyfrYq5Qt9 zpy>o@7tXgD9nA|)E^2O8TI4Kd-u~dh66XU4kJ>jkCo3%2JXxS1NXBQGj#Jx%`3n;q z1*29<2wr@U;PI|hBVI7)wCdja&il>gafkY&-|ah|sq&e@j?v&@l1GzDi$H-T(}C*@ z4d)pS<^8W#o7}kW^^6%a8rU@(pP28O)7{O@*6hf~%lq-&yFR%m-Rd9y{i|bAU{Dk4 z>}Q-mfByg8X|^^tIe9_^|)uYTLc#Ni>Hf8_w=1q?ihj#%(kK5v!ii(V!ij5IZ z4jgDm-I8M?mmgEHHR|c3M@eThZiZ-Go$=xC-`Z{4wq4^j=V@+rTDb9nxw-k9w{O=< z>ss5{ojZQ~__4<0NgMyWozBb2F=4AIExl@H!obGFC?_xfTYBEvw3`<%CThzt?B2EO z$EQz^{C~WCtGoE(inkdzBXpkGS1b)mRGL`8qdVJ2?Jujng~ftpnSF<=tEy(4fBu(o z|Ni~|AFo~(EGsSj`10k++dpJ&JvDKn;PnfeX3w5|?@)MHSd9DalB{5Ro5?2)M7S#1 z_}dTf*|n=kJWfYUveU)J`Lv&}@5UIt-OT2`lfAvY=PhOoxc;^3{-dn+_wU~QV*2}S z<+~?Ojzs==`BIbj@CQ*D2IYwy+EcrXKLo8j^6+8e{e`K|pFMliK6}~8uU|{=FG{`q za?9Qiix(?z+q(6q+`YSZ&wl<~?ERr(YUV`)o}Ap=g-e$n{Unn)OKscs?SUF1uVxu9 zU%p(h|M6{ecDi%mbUEO?(KW_ym^thIC-^==MPIJc@wU64+x@Z4|WCH z$Gv{=-Rx=6&A@Vo1Lc3DUgi8<5ysKj+REzV=jU{J%dB;(od*v(s^@>}pRe?#;HlY5 SZ3AG+XYh3Ob6Mw<&;$SgtC@oU literal 0 HcmV?d00001 diff --git a/gauss-turing/game/static/left.png b/gauss-turing/game/static/left.png new file mode 100644 index 0000000000000000000000000000000000000000..66ef6526e26f15125bde62f4aeac9543d8ff8666 GIT binary patch literal 2480 zcmV;h2~YNkP)*Xk}?>LAuo-KlISh5G`4gwMH>aXnDwTr%f{Te>#FJHa{)E>*Sw0`}10zeGIObf7gT%k}%j~+cDx7!^O z^ca)ncDr%o#tpdLZoda#M@I)bIy%5G4EUOOxm*sJOa=fD2n3KwBoK*2;5ZIWrxP5< z0RWs%C+v3nxcz$TIgUeNVIeMDxPY>q6x)3ZxJ9nbDw-_Kd7 zZ0IJ-VzE$RVc~?AUUYOcrKF_LzJ2@1ZnsbPusM11BxPk~QEY512?PROV;?zkglslj zXnWe@@zC41Z)wJi86oen=;&z5&d#Q)sw(>S?Hh$lYHDg|)v8q#A0N+aE~ihQCa2TM zADZJhx_OcHce~wG zT3QTsbBoa|^aWOSFH&3a? z%gf9CK9IcS@ZrOwmN>loc_Q}t*CG%ING6jJ%d)h5`EuI2bt_d>RnebHT z2n7WNC@wC>wQJV`K9n9jcz}%?H~w@z{m(vQ(V|88`0-=V0c0{6($mwyvMkhUHF9!t zpx5h>oSclgbLT=N5>1N4-E331!6N7_;ej6tx zC1KvYd0<%%c=2Kg1cE=xtvhGV9Aso<;Khp8a!GUVsygJoH0G#V^hw(O77=6F(6R0N4c;8Tel9Y zSFeUrsr*kzE;x>ZQmI5=U!UItucxO6L<9i<#Ky+{=Yau0rBY$Rf&~E&RFlaBkH-T6 zB1j|>3DVNiAQTGy)|<^{xZUo^f(8JkQW-D=WVhQRPtyP(7K;NyyIih+_H-mkFfXn5 zV?-SE$jC@QaG6X7hG8NP+H5w%&GjgE4r*(aOJw`@G z{I*dj6i7`?jT~r(VNhFJ3zNwdu+7@FYax|NeP1aeWZ}YvL49OxZEe1`5uxd`XV0R& zy**%kR#q0~&Ye4IKZF!L?CR?Jqcm)@*(f(RH>j5H-@iZB1pfdj;{tk1u_d-v{X1@&sJzP^6ksLbWdmjj1&{K>_O z7pbVIh@?{KsBlembTn00S5GVO-Me>b-n@B1W7W%-FQ@+ge*VdGD^{!^wOSpp)0s18 z(&^Kurv?1py?Zo&{`_%cY0sZO4=qjd;lqdHhH?@T5~#AW^0xvvG&BSS_Lk$vj|a>> zL9mmWPv}-6k1fO+@th^Jh{jmAoRCF)=Ze zlaoWWwY6c<@`DEtsIah*lu9M9>S{8Z z&0~V%fn;D{fJ`P6UAc0F^78UXp-}M7Kb1|QhjO_b zQBhG)tJTQQ&qrEX8YB|QsBjSx!R2zHySp2YA3uiCXylzE>XnR)4Aj@xL$BBKewOhT zqtQs^<>eE~02YhIB$LSk7O7MkQlH+oOO`C5*4Ea^r#=T0yWLKgE?t_|TyJlwsHg~- zD;8F0uN{B$<_#4T6if?jW@aWeHa1Q;tz%N}>4AX(x_tTaq_T!XDH$0Vbmq(%GMmkl zGKrIRB5)i>KYsk6n>TM#N=nLY{IP>@-kcl`2fcjxlFG}=Y4+^d zq*AFS1Q`<(Lt3qtN=r-W&Ye4Cx7)*-Z_3+bh3cfU+wEv+X~D;jAJNg#0i)4~&dyHs z^z>kGa1bt+%l8wSTCGNMax%19EmBick)EE8MT-_erBaQGL50ny_B;Ny^msgQxm<9$ uTyVSHzJE4=pQ#^0p%7xRc#I97D)}1*r*!J1DheC`0000Kx95Cs%8#)Ke2;|o!vPsTOA!GkY`#00ko zjRt%%B(5PQ8fBBH5tpz>(jXNyMOj+F0tHG-JLmsk+MhtDoz_-_|4Gh6(|c#`XYQSI z&pqc1LqvrCGm-e}!bAijg4t|_R;$I2A3xC3(}TgmL6}S?Fbo3#2n-CwqD70aeED)j zMMWVzJRA~<1PsI2+qf%(gM$bQ3*+rC@dc<}ugCM}&vF0$eP}cqjE|3FWMl*eg8>$c zWkx@iWf2@4jG&+(`1|`qsZ`?V(WBVDeLDgJ10fQL1dpMutqlhb9KgGG?+_9a!aLAE z7OT}t6B83uUtdqz+1UiZYkKO`DeCO(B(vE}R;$(NIC^_~DIp<&0FYLzY9n zz`y|Ay?d8ZQ&YVPJ6&^gbLqv47c?|9cXwrnKF%Webgsjd>6H+qZ9Y?AWot2J1+R zii&7xXo%X{+GYR)AeLomczF2Fp)D2*y?*_g#9}c4AckRP1=x1qef##2TrTHb6<@x5 zamc|4-KWRL$5B>RhQo&syJgWChJj2bgP)%t06;7j!_UtTVzC$&iv?!0863v}0E|W> z#>dA6U)R;pi;9YH?%X*@BogQH z*siugTPzlE9EXXC36zzU;r{*m&}y|99v+6tWOBMax{~+r-{bV@(=(u5E^mXuK$k9E z6140@A`vZIxR8`eC0)OM-Q!(hbaa$Xo;*oWQBkyD!2*w8gY@)tht}RHwApN?n>TL? zxc#bR*{-PhMA$m!U>e?N_nkNXUk<2Y(=Zl;)+7?0oUJ$v>{abz4qn@lD_hASs0 zhj;V$mQ+_)^X|j$==5=7`jb_w)lP3D5{W1)D{ID*@wQY|RZ(ngtXG_w`uh4Q#thR> zOBXI&aC(8wn>YJ>hU@F=9lDmDYC%E4lu4Qb-QV9&!NI}2otG_JMvosq_8F|fV4!Eu zp3%ycE4}LGMn*=`C-+9a)y8yu3W0&Tw;cGi7FGl0+i$y1%a1>t{k6 z3NG#Y3$8t8O7 z3=9llU|>Ly|80{84;~;pJNwsR#Wv&n_U%JOMTNr-VPRotXlTHyRjXz#f@!f>@b&9g zba!_{rBb1#r3E^j4qaVcP^;B28jVi-D-;SeH8nvhmHs+q84Lz=bae0@;nuEQJFCF9 z)fO8Yi`dv$?A*B%0Kjn^>g(%KSy_p1-@c)%s|%k$e@0JF&y4;fBP00n;|F45Vtzrl zwY5R7*Yh3`&z?Q|PsXoBA`!N3-HNSSw*mlqdwWq`T@95=g}%N%s8lNG^?D2q4WYZc z8+CPc|3RzOYW)29)8U2v{QQuSkufKN_)C{AwFfykj>E@~AEDK1(bd(3+S*!(#o}M9 zhKSJD*T-uVLPA1dwOZ#~7DFTwVcWKC_TNX29QhBL<2Y!wTHg0)!-fqA4Go?1shr;f z|00XU0-a9hu%TEiModhMJ-#(xM8t6%Mn^|^EjMp!WG+J!5hf=md7)XBoqy0axIc+H z&N*m?VGs}yzzaMvF){z3#bPmngM%IZ$#ER7k(<-d5{U$h7cb`ZcUxOqVK5lx7qmzu zLS$ql?@V`ebj&|!0FcY&kV>Tv8<{n0w#3?e+P*{pAeBn7ckf=_Mp~^F#l^)wi z)le#xybq_dvlAsHCG%^hIgX>3FJC&H?WCk6G8hd1)U0)Pce|Y}#q@t7A6h`0?ZRc(`0Hr!!~H2ueB4 z$XfpV`IC~9lbzRAE4dGjVMS+az8QX(TGX~&Ko?iJ6O&1SlK^{UHMNql@fRa8{`Rp5ex0tycg zcR99KuU@%dCOJ4bNV|6Ja#?<{V#Nx|&(F6%RbMUlfq?FHEcQ{$D{EiNvmjT<+TOePbQnG6XDq4xH6_pLWy-dJck6T>hR6cj`$DJk^m z(Ie7owNrA#&ZNJ;pL9AM6%`fH`t|GGDx3=r4yI3^J_)*y;M!1?N`>6qT(q~h3-a`S zuL+Hgjz(%~DwZx?3YKN399%e#gV}6GXJ;pBYips?=`b-dA-F~q0FsiDP+D4wb?er- z=Y|TAwzf9fvSo|gr4bCnkW?zAfPesAWm(pvO5nV_Jkn@1p1Yw!q_3}!^7Hd&wbt9F z_wL=J(a}-2ZG}fg?na}Ls;a64S$1D&T3Q-4H8r{Xro-#saBv()I-QPg-@Z+2*RK65 zu<7aP^zh+B!G_T%AFkLADMLd;R8mqxfq{WOfsKlaqNh)vlF?}Ncy_%C{rk+1j*e1! zc{yceWl?l=wBY@9x`u{^(#n-9DK9UN>gwvqWHNcx(-XX9xe=5A0O<94G&MCrtybgv z_wUeXH0bW`hEAumf0V|uEP{f9uw=;+L`6j*IyxG1xf}|G0!pP4GMNmna&4Z7*P;26 z24=GvlarIMTCG#!=wh)L5{U#X%YtQDx4yRXRQ?CJ9-< + + + + + Drag + + + + + + + + + + + + +
+ +
+ Aktuelles Programm: +
+ {% for cmd in current_program %} +
+ + {{ loop.index0 }} +
+ {% endfor %} +
+
+ + +
+ Mögliche Befehle: +
+ {% for cmd in valid_commands %} +
+ +
+ {% endfor %} +
+
+ + +
+
+ +
+
+
+
+
+ +
+ Viel Spaß beim Spielen! +
+
+ + + + + + \ No newline at end of file diff --git a/gauss-turing/game/webapp.py b/gauss-turing/game/webapp.py new file mode 100644 index 0000000..a5fdc9d --- /dev/null +++ b/gauss-turing/game/webapp.py @@ -0,0 +1,163 @@ +from flask import Flask, render_template, request, session, make_response +import socket +import time +import numpy as np +from playsound import playsound +from itertools import zip_longest +import random +import json +import pygame + +app = Flask(__name__) +app.secret_key = b'RoboRallyRolling' + +probabilities = [0.21428571428571427, 0.14285714285714285, 0.07142857142857142, 0.07142857142857142, + 0.21428571428571427, 0.21428571428571427, 0.07142857142857142] + +#deck = roborally.CardDeck() + +class Cmd: + possible_moves = ['forward', 'left', 'right', 'P0'] + possible_colors = [(200,200,200), (255, 0, 0), (0,0,255)] + + def __init__(self, action, color): + self.action = action + self.color = color + + def __str__(self): + return "Cmd No. " + self.action + + def __repr__(self): + return self.action + " " + str(self.color) + + +available_robots = { + 0: {'id': 11, 'ip': '192.168.1.11', 'x': 1, 'y': 2, 'orientation': '>'}, + 1: {'id': 12, 'ip': '192.168.1.12', 'x': 3, 'y': 3, 'orientation': '>'} +} + + +players = {} + + +class Player: + MAX_PLAYERS = 4 + player_counter = 0 + + def __init__(self): + if Player.player_counter < Player.MAX_PLAYERS: + self.id = Player.player_counter + Player.player_counter += 1 + + self.max_cards = 9 + + self.player_hand = deck.draw_cards(self.max_cards) + print("current hand: ", [str(c) for c in self.player_hand]) + + self.action_count = 5 + self.action_chosen = False + + self.initialize_robot() + + else: + print("max players reached!") + + def initialize_robot(self): + x = available_robots[self.id]['x'] + y = available_robots[self.id]['y'] + marker_id = available_robots[self.id]['id'] + ip = available_robots[self.id]['ip'] + orientation = available_robots[self.id]['orientation'] + self.robot = game.board.create_robot(x, y, orientation, self.id, marker_id) + + if game.comm_socket is not None: + cmd = f"initialize_robot, {marker_id}, {ip}, {x-1}, {y-1}, {orientation}\n" + game.comm_socket.sendall(cmd.encode()) + data = game.comm_socket.recv(32) + + if data.decode() == 'OK\n': + print("robot sucessfully initialized!") + else: + print("error: could not initialize robot!") + self.robot = None + + def draw_new_cards(self): + self.player_hand += deck.draw_cards(self.max_cards - len(self.player_hand)) + + +@app.route('/send_cmds', methods=['POST', 'GET']) +def send_cmds(): + if request.method == 'POST': + cmds = json.loads(request.form['cmds_json']) + + cmd_list = [] + for cmd_nr in [f"cmd{i}" for i in range(5)]: + cmd = cmds[cmd_nr] + action = cmd['action'] + color_str = cmd['color'] + color_str = color_str.strip("()").split(",") + color = tuple(map(int, color_str)) + cmd_list.append(Cmd(action, color)) + print("got commands: ", cmd_list) + ev = pygame.event.Event(pygame.USEREVENT, {'cmds': cmd_list}) + pygame.event.post(ev) + + # send commands to the game + + # if game.ready(): + # game.process_actions() + # + # return 'OK' + # else: + # return 'please wait' + return "OK" + elif request.method == 'GET': + # GET is used when we have to wait for other players to finish + while not game.processing_done: # wait for other players to choose commands and processing to finish + pass + + return 'OK' + +WHITE = (255, 255, 255) +GRAY = (200, 200, 200) +RED = (255, 0, 0) +BLUE = (0, 0, 255) + +@app.route('/', methods=['GET', 'POST']) +def hello_world(): + prg = [Cmd('forward', GRAY), Cmd('left', GRAY), Cmd('right', BLUE), + Cmd('P0', GRAY), Cmd('right', RED)] + valid_cmds = [Cmd('forward', WHITE), Cmd('right', WHITE), Cmd('left', WHITE), + Cmd('P0', WHITE), Cmd('-', RED), Cmd('-', BLUE), Cmd('-', GRAY)] + + if request.method == 'GET': + robot_info = None + return render_template('drag_example.html', current_program=prg, valid_commands=valid_cmds, robot_info=robot_info) + elif request.method == 'POST': + # print(request.form) + + if request.form.get('drag') and request.form.get('drop'): + # swap cards in the current hand + i1 = int(request.form.get('drag')) # number of first card + i2 = int(request.form.get('drop')) # number of second card + + card1 = deck.deck[i1] # get card by number + card2 = deck.deck[i2] + + print("swapping {} and {}".format(card1, card2)) + + j1 = player_hand.index(card1) # get index of card in the hand + j2 = player_hand.index(card2) + + player_hand[j1], player_hand[j2] = player_hand[j2], player_hand[j1] # swap the cards in the list + + # print("current hand: ", [str(c) for c in player_hand[player_id]]) + + return 'OK' + else: + return render_template('drag_example.html', cmds=player_hand, player_id=player_id) + + +if __name__ == '__main__': + #app.run(host='192.168.1.222', port=5000) + app.run(host='0.0.0.0', port=5000)