IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

[KiFFGAME] Star Shooter : os court !


Sujet :

Tkinter Python

  1. #1
    Invité
    Invité(e)
    Par défaut [KiFFGAME] Star Shooter : os court !
    Bonjour,

    J'essaie en ce moment de relever le défi KiFFGAME (Kilobyte Fully-Functional Game) à savoir faire tenir un jeu entièrement fonctionnel dans un minuscule Kibibyte soit 1024 bytes/octets.

    Je suis parti sur ce code de référence (2767 bytes) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    from random import *
    from tkinter import *
     
    def init_jeu():
        global spacecraft_id
        reset()
        spacecraft_id = canvas.create_polygon(spacecraft_shape(150), fill="#8ff")
        new_target()
    # end def
     
    def reset():
        global shoots
        shoots = []
        root.after_cancel(ttid)
        canvas.delete(ALL)
    # end def
     
    def move(event):
        canvas.coords(spacecraft_id,spacecraft_shape(max(10,min(event.x,290))))
    # end def
     
    def shoot(event):
        shoots.append(Shoot(event.x))
    # end def
     
    def shoot_loop():
        for s in shoots: s.collide()
        root.after(50,shoot_loop)
    # end def
     
    def collision(iid=0):
        if target_id:
            collisions = canvas.find_overlapping(*canvas.bbox(target_id))
            if iid in collisions:
                destroy_target()
                return True
            elif spacecraft_id in collisions:
                game_over()
                return True
            # end if
        # end if
        return False
    # end def
     
    def destroy_target():
        global target_id
        root.after_cancel(ttid)
        canvas.delete(target_id)
        target_id = 0
        new_target()
    # end def
     
    def new_target():
        root.after(100*randint(5,20), create_target)
    # end def
     
    def create_target():
        global target_id, tx, ty
        ty = 10
        tx = randint(10,260)
        target_id = canvas.create_oval(tx,ty,tx+10,ty+10,fill="#f8f")
        move_target()
    # end def
     
    def move_target():
        global ttid, tx, ty
        x = randint(-10,10)
        y = randint(0,5)
        if ty+y < h:
            if 0 < tx+x < 280:
                canvas.move(target_id, x, y)
                tx += x
                ty += y
            # end if
            if not collision():
                ttid = root.after(100,move_target)
            # end if
        else:
            destroy_target()
        # end if
    # end def
     
    def game_over():
        reset()
        canvas.create_text(w/2,h/2-20,text="GAME OVER", font="sans 20 bold", fill="#ddd")
        canvas.create_window(w/2,h/2+20,window=Button(root,text="Replay", command=init_jeu))
    # end def
     
    class Shoot:
        def __init__(self,x):
            self.i = canvas.create_line(x,350,x,330,fill="#ff8")
            self.y = 330
        # end def
        def collide(self):
            if collision(self.i):
                self.suppress()
            elif self.y > -20:
                canvas.move(self.i,0,-10)
                self.y -= 10
            else:
                self.suppress()
            # end if
        # end def
        def suppress(self):
            canvas.delete(self.i)
            shoots.remove(self)
        # end def
    # end class
     
    root = Tk()
    root.title("Star shooter")
    root.resizable(0,0)
     
    w,h = 300,400
    spacecraft_shape = lambda x:(x-10,h-20,x,h-40,x+10,h-20)
    target_id = ttid = 0
     
    canvas = Canvas(root, width=w, height=h, bg="#000")
     
    canvas.pack()
     
    init_jeu()
     
    shoot_loop()
     
    canvas.bind("<Motion>", move)
     
    canvas.bind("<1>", shoot)
     
    root.mainloop()
    Et je l'ai réduit pour le moment à ça (1341 bytes) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    from random import randint as q
    from tkinter import *
    def f1():global s;f2();s=c.create_polygon(u(k),fill="#8ff");f8()
    def f2():global j;j=[];rc(p);cd(ALL)
    def f3(e):c.coords(s,u(max(d,min(e.x,w-d))))
    def f4(e):j.append(S(e.x))
    def f5():
     for i in j:i.c()
     ra(50,f5)
    def f6(i=0):
     if t:
      a=c.find_overlapping(*c.bbox(t))
      if i in a:f7();return 1
      elif s in a:fb();return 1
     return
    def f7():global t;rc(p);cd(t);t=0;f8()
    def f8():ra(l*q(5,v),f9)
    def f9():global t,tx,ty;ty,tx=d,q(d,260);t=c.create_oval(tx,ty,tx+d,ty+d,fill="#f8f");fa()
    def fa():
     global p,tx,ty;x,y=q(-d,d),q(0,5)
     if ty+y<h:
      if 0<tx+x<w-v:cm(t,x,y);tx+=x;ty+=y
      if not f6():p=ra(l,fa)
     else:f7()
    def fb():f2();c.create_text(k,n-v,text="GAME OVER",font="sans 20 bold",fill="#ddd");c.create_window(k,n+v,window=Button(r,text="Replay",command=f1))
    class S:
     def __init__(m,x):m.i,m.y=c.create_line(x,g+v,x,g,fill="#ff8"),g
     def c(m):
      if f6(m.i):m.s()
      elif m.y>-v:cm(m.i,0,-d);m.y-=d
      else:m.s()
     def s(m):cd(m.i);j.remove(m)
    r=Tk()
    r.title("Star shooter")
    r.resizable(0,0)
    ra,rc,d,v,l,g,w,h=r.after,r.after_cancel,10,20,100,330,300,400
    k,n,u=w/2,h/2,lambda x:(x-d,h-v,x,h-40,x+d,h-v)
    t=p=0
    c=Canvas(r,width=w,height=h,bg="#000")
    c.pack()
    cd,cm=c.delete,c.move
    f1()
    f5()
    c.bind("<Motion>",f3)
    c.bind("<1>",f4)
    r.mainloop()
    Il ne me reste plus que 317 bytes à grappiller.

    Mon problème : je ne trouve plus d'idées pour réduire ce script jusqu'à 1024 bytes sachant que :

    1. le KiFFGame doit impérativement être écrit en Python3 ;
    2. seule tkinter est acceptée comme GUI-lib ;
    3. les en-têtes doivent figurer dans le script ;
    4. le jeu doit rester pleinement fonctionnel conformément au code de référence ;
    5. le script doit pouvoir s'exécuter sans librairie tierce à installer en plus de Python3 et de ses packages par défaut ;
    6. le script ne doit pas faire appel à des ressources extérieures (images, sons, modules additionnels, etc) ;
    7. le script doit être totalement autonome sur seulement 1024 bytes/octets ;


    Si quelqu'un a une idée pour optimiser le truc, je suis preneur.

    S'il le faut en changeant carrément l'approche algorithmique, du moment que le résultat est le même que celui produit par le code de référence.



    @+.
    Dernière modification par Invité ; 10/06/2014 à 12h31.

  2. #2
    Invité
    Invité(e)
    Par défaut Incompressibles
    Bonjour,

    Pour celles et ceux que cela intéresse, je viens de dénombrer les incompressibles du script en question :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    from random import randint
    from tkinter import *
    c.create_polygon(x,fill="#8ff")
    ALL
    c.coords(s,u)
    j.append(s)
    c.find_overlapping(*c.bbox(t))
    c.create_oval(s,fill="#f8f")
    c.create_text(k,text="GAME OVER",font="sans 20 bold",fill="#ddd")
    c.create_window(k,window=Button(r,text="Replay",command=f))
    c.create_line(x,fill="#ff8")
    j.remove(m)
    r=Tk()
    r.title("Star shooter")
    r.resizable(0,0)
    c=Canvas(r,width=w,height=h,bg="#000")
    c.pack()
    c.bind("<Motion>",f)
    c.bind("<1>",f)
    r.mainloop()
    Ces incompressibles ne peuvent pas être résumés et représentent 527 bytes/octets.

    Il faudrait donc trouver un algorithme qui lie les logiques et les interactions en 1024 - 527 = 497 bytes/octets

    Qui pense que ça reste réalisable ?

    Je vais quand même tenter le coup, on ne sait jamais.

    @+.

  3. #3
    Invité
    Invité(e)
    Par défaut Yes!
    Bah, je savais bien que je finirais par trouver !

    Donc voici le KiFFGAME Star Shooter en 1021 bytes/octets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #!/usr/bin/python3
    #-*-coding:utf-8-*-
    from random import randint as q
    from tkinter import*
    def A(e):G(s,u(max(d,min(e.x,w-d))))
    def B(e):j.append(S(e.x))
    def C():global x,y;x,y=k,d
    def D():global s,t;H(ALL);C();s=c.create_polygon(u(k),fill="#8ff");t=c.create_oval([0]*4,fill="#f8f");c.bind("<1>",B);E()
    def E():
     global x,y
     for i in j:
      if i.y>-v:c.move(i.i,0,-d);i.y-=d
      else:H(i.i);j.remove(i)
     x+=q(-d,d);x%=w-d;y+=q(0,5);y%=h-d;z=x,y,x+d,y+d;G(t,z);a=c.find_overlapping(*z)
     if s in a:return F()
     if len(a)>1:H(a[1]);C()
     r.after(50,E)
    def F():c.unbind("<1>");H(ALL);c.create_text(k,n-v,text="GAME OVER",font="sans 20 bold",fill="#ddd");c.create_window(k,n+v,window=Button(r,text="Replay",command=D))
    class S:
     def __init__(s,x):s.i,s.y=c.create_line(x,g+v,x,g,fill="#ff8"),g
    r=Tk()
    r.title("Star shooter")
    r.resizable(0,0)
    d,v,g,w,h,j=10,20,330,300,400,[]
    c=Canvas(r,width=w,height=h,bg="#000")
    c.pack()
    k,n,u,G,H=w/2,h/2,lambda x:(x-d,h-v,x,h-40,x+d,h-v),c.coords,c.delete
    D()
    c.bind("<Motion>",A)
    r.mainloop()
    Bon d'accord, j'ai imperceptiblement triché, mais le code reste conforme au code de référence à près de 99%.

    Pour ma part, j'estime que le défi a été relevé.



    @+.

Discussions similaires

  1. Calcul du plu court chemin entre 2 sommets d'un graphe valué
    Par atlasm dans le forum Algorithmes et structures de données
    Réponses: 25
    Dernier message: 07/08/2005, 17h06
  2. Réponses: 2
    Dernier message: 21/03/2004, 18h57
  3. Réponses: 4
    Dernier message: 16/03/2004, 18h03
  4. Camera First Person Shooter
    Par Martin dans le forum OpenGL
    Réponses: 6
    Dernier message: 15/01/2004, 04h37
  5. [TControl] Récupérer le message court et long du hint ?
    Par Cornell dans le forum Composants VCL
    Réponses: 6
    Dernier message: 19/11/2003, 08h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo