1

En attendant d'avoir la motivation pour trouver le temps de me lancer dans de plus gros projets, j'ai voulu me lancer un petit défi.
Faire un jeu Lynx en moins de 4ko, histoire de mettre des limites... et historiquement, ça correspond à une des limites pour les concours de programmation d'antant. Avec 1 et 2ko, mais en utilisant le C, je doute de descendre à 2ko...
Déjà, il faut oublier tout ce qui est texte ou les graphismes trop élaboré d'ou le look à base de rectangles, mais le but, c'était le gameplay, et d'avoir tout de même un jeu qui se renouvelle à chaque partie.

tromb Petit screenshot :
uZcD (limny.JPG)

Pour jouer, c'est assez simple, le but est de faire sortir les 20 "piquets" rouge par la porte jaune avant que l'écran ne soit intégralement rempli "d'eau"...
Pour celà, vous déplacez le curseur noir et pouvez créer ou détruire un bloc dans le labyrinthe...
Au fur et à mesure de leur sortie, les piquets sont listés en bas de l'écran...
Le premier niveau est toujours identique d'une partie à l'autre, mais dès le second, chaque partie est différente...

Il n'y a pas de game over, dès qu'un niveau est fini (victoire ou défaite), on passe au suivant qui est réinitialisé à 0 au niveau du temps restant...

Voilà, pour info, le "jeu" fait pile 4096 octets embarrassed
tromb Fichier joint : limny.o


Et le source C écriture type basic pour les curieux :
/**********************************/
/*  L Y N X                       */ 
/*  Limny                         */ 
/*  Juillet 2008                  */
/**********************************/
 
#include <stdlib.h>
#include <lynx.h>
#include <lynxlib.h>

/* LYNX-specific #defines: */
#define JOY_RIGHT		0x10
#define JOY_LEFT		0x20
#define JOY_DOWN		0x40
#define JOY_UP			0x80

#define BUTTON_OUTER	0x01

char redir[]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
char pal[]={
	0x0F,0x09,0x0C,0x00,0x0D,0x06,0x09,0x04,0x02,0x06,0x09,0x0A,0x0C,0x02,0x0F,0x00,
	0xEF,0xBD,0xFF,0x86,0xDD,0xFB,0xFC,0xB7,0x94,0xD6,0xD9,0xD9,0xE7,0x29,0x0F,0x00};

char SCREEN[8160]       at (0xC038);
char RENDER[8160]       at (0xE018);

char niveau[20][12];
char x_lemmings[20], y_lemmings[20],sens_lemmings[20];
char test;
int fin, i,j,k,x,y,xx,yy,ttimer;

// assembler vertical retrace syncronisation routine
void Vsync() 
{
#asm
vretrace:
	lda $fd0a
	bne vretrace
#endasm
    SwapBuffers();

}

void spr(ax, ay, ac)
char ax, ay, ac;
{
   if (ac > 0)
   {
      DrawFBox(8*ax,8*ay,9,9,5);
      DrawFBox(8*ax+1,8*ay+1,7,7,ac);
   }
}

void fond()
{
    for (i=0;i<160;i+=8)
    {
      DrawFBox(i,-8,8,102,8+i%5);
    }
}

void main() 
{
  InitIRQ();
  CLI;

  SetRGB(pal);
  SetBuffers(SCREEN, RENDER,0);
  voff=-8;
  
  for (;;)
  {
     for (fin=0;fin<20;fin++)
     {
          for (j=0;j<11;j++)
          {
             niveau[fin][j] = 0;
             niveau[0][j] = 4;
             niveau[19][j] = 4;
             k = random()%12;
             if (k < 4)
                niveau[fin][j]=4;
          }   
          niveau[fin][10] = 4;
          niveau[fin][0] = 4;
          x_lemmings[fin]=-3*fin;
          y_lemmings[fin]=-1;
          sens_lemmings[fin]=-1;
     }
     niveau[18][0]=0;
     niveau[k][9]=14;
      
     x = 18;
     y = 1;   
     
     for (ttimer = 102; ttimer>-10;ttimer--)
     {
           fond();
           DrawFBox(0,ttimer,160,105,11);
	       
           for (i=0;i<20;i++)
           {
               for (j=0;j<11;j++)
               {
                     spr(i,j,niveau[i][j]);
               }
               xx = x_lemmings[i];
               yy = y_lemmings[i];
               j = sens_lemmings[i];
               DrawFBox(8*xx+4,8*yy+1,1,7,13);
               if ((xx == k) && (yy == 9))
               {
                   fin--;
                   j=0;
                   xx = i;
                   yy = 11;
                   if (fin == 0)
                      ttimer = -9;
               }
               if (j != 0)
               {
                  if ((yy < 0) && (xx!=18))
                  {
                     xx++;
                  }
                  else
                  {
                     if (niveau[xx][yy+1] != 4)
                     {
                        yy++;
                     }
                     else
                     {
                        if (niveau[xx+j][yy] != 4)
                        {
                           xx+=j;
                        }
                        else
                        {  
                           j=-j;
                        }
                     }
                  }
               }
               x_lemmings[i] = xx;
               y_lemmings[i] = yy;
               sens_lemmings[i] = j;
           }
           DrawFBox(8*x+3,8*y+3,3,3,15);
           
           if (joystick & JOY_RIGHT)
                 x=x%18+1;
           if (joystick & JOY_LEFT)
           {
                 x=(x+16)%18+1;     
           }
           if (joystick & JOY_DOWN)
                 y=y%9+1;
           if (joystick & JOY_UP)
           {
                 y=(y+7)%9+1;     
           }
           if ((joystick & BUTTON_OUTER) && (test == 0))
           {
                 niveau[x][y] = 4 - niveau[x][y];
                 test = 1;
           }
           if (!(joystick & BUTTON_OUTER))
                 test = 0;
           
           Vsync();
           if (ttimer == 102)
              while (!joystick);
     }
     while (joystick != BUTTON_OUTER)
         random();
     while (joystick);
     
  }
}
avatar

2

Alors la chapeau !! Je pensais meme pas que c'etait possible d'ecrire quoique ce soit en 4 Kilos en C !! Moi qui profitait de cette faiblesse d'ailleurs pour tirer sur ce langage, je vais devoir retirer cet argument de mon inventaire, enfin bon, rechapeau comme d'habitude on peux dire avec Fadest !!



GT top
avatar< SCPCD > j'aurais du dire "les doigts dans le cul vu que le java c'est de la merde"
Je suis Goto !

3

Fafa => Président ! top

4

Au niveau du temps limite pour resoudre les tableaux c'est un peu rapide surtout que les déplacements ne repondent pas forcement immediatement.
Je testerais sur une vrai console ce week end pour voir si c'est plus jouable.

En tout cas chapeau, un vrai jeu avec si peu de code ca fait rever !

5

Oui, le temps est très limite, il reste peu de marge entre le 20° gus et la fin de niveau, ça veut donc dire que le chemin doit être prêt au moment ou le 20° rentre dans le tableau...

Pour avoir plus de temps, il est possible de changer ces 2 lignes :
for (ttimer = 204; ttimer>-20;ttimer--)
{
fond();
DrawFBox(0,ttimer/2,160,105,11);

Mais vu qu'il y a une division par 2 d'ajoutée, ça va surement dépasser les 4 ko...


Pour GT, déjà, on est sur Lynx, donc le code minimal (init, startup,...) doit être plus petit que sur ST (et je ne pas pas du PC embarrassed), ensuite, il faut éviter au maximum les appels à des fonctions car ça va linker tout, y compris les parties dont tu n'aurais pas besoin. Par exemple, printf() pour afficher du texte n'existe pas dans le kit BLL, on utilise une fonction spécifique TextOut() qui se base sur des sprites pour chaque caractère... Mais si je veux juste afficher un score, ça va m'inclure tout le code de la fonction TextOut, ainsi que la fonte complete (lettres + chiffres), soit près de 2 ko au final. Alors qu'en fait, je n'ai besoin que d'1/4 de la fonte environ.
Après, c'est comme tout langage, il y a des ruses, il y a sans doute possibilité de faire encore bien mieux, mais j'avoues que je n'ai pas mon 1° dan de code C hyper-optimisé et abscons...
avatar