Introduction au langage C/Sources
Jeux
modifierSnake
modifierIntroduction
modifierTout 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. À noter que ce code n’est pas portable et ne fonctionne donc que sous Windows.
Source
modifierExemple
#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écessaires
/*
* Constantes qui représentent les valeurs 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
// Longueur maximale du serpent
#define MAX 100
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);
}
// Créer le cadre de jeu
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 points occupés 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 jeu
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 tête
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 tête 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 debuggage
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érifie que le caractère entré est bien une touche attendue (touche directionnelle ou ECHAP)
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 scores 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 contenant tous les emplacements occupés par la queue
int direction=-1,
longueur=7, // Longueur du serpent de départ
vie=3, // Nombre de vies
level=0, // Niveau
pommeEat=0, // Nombre de pommes mangées
vitesse=230; // Nombre de millisecondes d'attente
srand(time(NULL));
clrscr(); cadre();
info("Press Any key");
temp == getch();
clrscr(); cadre();
snake[0] = tete;
gotoxy(tete.x,tete.y);
while(1){ // 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'elle n’est pas sur le snake)
manger=false;
if(pommeEat%10 == 0) { level++; vitesse -= 20; } // Si le nombre de pomme mangées est multiple de 10 alors on augmente la vitesse du jeu
}
// Si on a pressé une touche et que cette touche fait partie des directions (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 fois on donne soit la première touche (Any Key) soit LEFT par défaut
incDirection(copyTemp, &tete); // On incrémente l'emplacement de la tête
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 pommes
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);// Ralentit la vitesse d'exécution de vitesse/2ms
effaceXY(snake[longueur-1]); // Efface le bout de la queue
Sleep(vitesse/2);// Ralentit la vitesse d'exécution de vitesse/2ms
}
system("PAUSE");
return EXIT_SUCCESS;
}
Dev-C++
modifierRemarque: Dev-C++ ne connait pas deux fonctions de ce programme voici leur code:
Exemple
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");}