Langage C/Sources
Une page de Wikiversité.
| Chapitre 12 | |||
| Leçon : Langage C | |||
|---|---|---|---|
| Chap. préc. : | Le préprocesseur | ||
| Chap. suiv. : | Allocation dynamique de mémoire | ||
En raison de limitations techniques, la typographie souhaitable du titre, « Langage C : Sources
Langage C/Sources », n'a pu être restituée correctement ci-dessus.
Sommaire |
[modifier] Jeux
[modifier] Snake
[modifier] Introduction
Tout le monde connait ce très célèbre jeux snake
Voici une version simple en langage C. Je pense que pour l'apprentissage d'un langage il est nécessaire de savoir lire du code. Ce code est très simple pas très long et plutôt amusant a débuger je pense donc qu'il est parfait si vous voulez vous familiariser avec le langage et la syntaxe du C.
Je vous invite tous a modifier les commentaires et le code pour qu'il soit plus clair, a condition que les modifications n'apportent pas d'erreur.
[modifier] Source
#include <conio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dos.h> #include <time.h> #include <windows.h> #include <ctype.h> // Certaines de ces libs ne sont peut être pas nécessaire /* * Constante qui représente les Valeur renvoyée par getch() * et donc le code ascii renvoyé par votre clavier */ #define UP 72 #define DOWN 80 #define LEFT 75 #define RIGHT 77 #define ESC 27 #define MAX 100 // Longueur maximal du serpent struct XY {int x,y;}; void gotoxy(int x, int y); // Voir fonctionDeBase void clrscr(); // Voir fonctionDeBase // Affiche dans un cadre void info(const char * txt){ gotoxy(4,5); printf("%c",218); for(int i=0; i<20; i++) printf("%c",196); printf("%c",191); gotoxy(4,6); printf("%c %s",179,txt); gotoxy(4+20+1,6); printf("%c",179); gotoxy(4,7); printf("%c",192); for(int i=0; i<20; i++) printf("%c",196); printf("%c",217); } // Creer le cadre de jeux void cadre(){ printf("\n"); for(int i=0; i < 30; i++) printf("%c",178); printf("\n"); for(int i=0; i < 20; i++) printf("%c %c\n",178,178); for(int i=0; i < 30; i++) printf("%c",178); } // Vérifie si un point fait partie ou non des point occupé par la queue du snake bool isOnSnake(XY e,XY *s,int longueur){ for(int i=2; i< longueur; i++){ if(s[i].x == e.x && s[i].y == e.y){ return true; } } return false; } // Vérifie si un point fait partie du cadre de jeux bool isOutOfRing(XY tete){ if((tete.y == 1 || tete.y == 22 || tete.x == 0 || tete.x == 29)) return true; return false; } // Affiche une pomme avec une position aléatoire et renvoie cette position struct XY makePomme(XY *snake, int longueur){ // Fabrique une pomme XY p; do{ p.x=rand()%27+1; p.y=rand()%20+2; }while(isOnSnake(p, snake, longueur)); // Si cette pomme se trouve sur le snake alors on en fabrique une autre gotoxy(p.x,p.y);printf("%c",5); return p; } // Fonction qui est appelée lorsqu'un nouveau block est ajouté au snake void afficheTete(XY e){ // affiche la tete gotoxy(e.x, e.y); printf("%c",176); } // Efface le bout de la queue void effaceXY(struct XY e){ if(!isOutOfRing(e)) {gotoxy(e.x, e.y); printf(" "); } } // Incrémente l'emplacement de la tete du snake en fonction de la direction void incDirection(int direction, XY *e){ // Incrémente en fonction de la position if(direction == UP ) --(e->y); if(direction == DOWN ) ++(e->y); if(direction == LEFT ) --(e->x); if(direction == RIGHT ) ++(e->x); } // Fonction de debugage. void affDirection(char t){ switch(t){ case UP : printf("UP "); break; case DOWN : printf("DOWN "); break; case LEFT : printf("LEFT "); break; case RIGHT : printf("RIGHT"); break; } } // Vérifier que le caractère entré est bien un direction bool estDirection(char ct, char t, XY p){ if(t == UP && ct != DOWN) return true; if(t == DOWN && ct != UP) return true; if(t == LEFT && ct != RIGHT) return true; if(t == RIGHT && ct != LEFT) return true; if(t == ESC) {info("PAUSE"); getch(); clrscr(); cadre(); gotoxy(p.x,p.y);printf("%c",5);} return false; } // Appelé quand on meurt elle vérifie s'il nous reste encore des vies int die(int vie){ if(vie == 0) { info("GAME OVER"); getch(); return true; } info(" You DIE "); getch(); clrscr(); cadre(); return false; } // Affiche les score ainsi que le nombre de vie void ScoreAffiche(int vie, int level, int pommeEat){ gotoxy(1,0); for(int i=0;i<vie;i++) printf("%c",3); gotoxy(5,0); printf("LEVEL : %d Pomme : %d", level, pommeEat); } int main(int argc, char *argv[]) { char temp, copyTemp; bool manger=true, // Si j'ai mangé je recrée une pomme first= true, // Si c'est le premier tour Mort= false; // Si je suis mort struct XY tete = {20,10}, // Emplacement de départ WherePomme={0,0}, // Emplacement de la pomme snake[MAX] = {0,0}; // Tableau dans lequel tous les emplacement occuper par la qeueu se trouve int direction=-1, longueur=7, // Longueur du serpent de départ vie=3, // Nombre de vie level=0, // Niveau pommeEat=0, // Nombre de pomme mangée vitesse=230; // Nombre de miliseconde d'attente srand(time(NULL)); clrscr(); cadre(); info("Press Any key"); temp == getch(); clrscr(); cadre(); snake[0] = tete; gotoxy(tete.x,tete.y); for(;;){ // Boucle infinie ScoreAffiche(vie, level,pommeEat); if(Mort){ // Si je suis mort vie--; // Je retire une vie tete.x=20; // Je place la tête au centre tete.y=10; longueur = 7; // Je remet la longueur de départ manger= true; // Je met une pomme Mort = false; // Je ne suis plus mort } if(manger){ WherePomme = makePomme(snake, longueur); // Créer une pomme et renvoie son emplacement (vérifie qu'il n'est pas sur le snake manger=false; if(pommeEat%10 == 0) { level++; vitesse -= 20; } // Si le nombre de pomme manger est multiple de 10 alors on augmante la vitesse du jeux } // Si on a frappé sur une touche et que cette touche fait partie des direction (ou ESC) Alors on copie la direction if(kbhit() && estDirection(copyTemp, temp = getch(),WherePomme)){ copyTemp = temp;}else{ if(first) {if(!estDirection(' ',temp,WherePomme)) copyTemp = LEFT; else copyTemp = temp; first = false;} //Si c'est la première foi on donne soit la première touche(Any Key) soit LEFT par défaut incDirection(copyTemp, &tete); // On incrémente l'emplacement de la tete for(int i= longueur-1; i >= 0; i--) // On déplace tous les éléments du serpent pour faire place à la nouvelle tête snake[i] = snake[i-1]; snake[0] = tete; } if(tete.y == WherePomme.y && tete.x == WherePomme.x) { // Si la tête est sur une pomme manger=true; pommeEat++; // Augmente le nombre de pomme longueur++; // Augmente la longueur } if(isOutOfRing(tete) || isOnSnake(tete, snake, longueur)) { // Si on est sur le bord ou si on est sur la queue du serpent if(die(vie)){ // Affiche qu'on est mort ou que c'est la fin du jeu info("GAME OVER"); getch(); system("PAUSE"); return EXIT_SUCCESS; }else Mort = true; }else afficheTete(tete); // Affiche la tête Sleep(vitesse/2);// Ralenti la vitesse d'execution de vitesse/2 millisecondes effaceXY(snake[longueur-1]); // Efface le bout de la queue Sleep(vitesse/2);// Ralentit la vitesse d'exécution de vitesse/2 millisecondes } system("PAUSE"); return EXIT_SUCCESS; }
[modifier] Dev-C++
Remarque: Dev-C++ ne connait pas deux fonctions de ce programme voici leur code:
void gotoxy(int x, int y) { HANDLE hConsoleOutput; COORD dwCursorPosition; //cout.flush(); dwCursorPosition.X = x; dwCursorPosition.Y = y; hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hConsoleOutput,dwCursorPosition); } void clrscr() {system("cls");}