Skip to content
Snippets Groups Projects
Commit e5230655 authored by Vincent Nivoliers's avatar Vincent Nivoliers
Browse files

ajout du code de base

parent 0e929278
No related branches found
No related tags found
No related merge requests found
Pipeline #
list-build:
stage: build
image: gcc
script:
- cd Src
- make test_liste
artifacts:
paths:
- Src/test_liste
list-test:
stage: test
script:
- Src/test_liste
dependencies:
- list-build
...@@ -141,6 +141,14 @@ l'éxécution. Vous pouvez en ajouter à votre guise. ...@@ -141,6 +141,14 @@ l'éxécution. Vous pouvez en ajouter à votre guise.
<a name="listes_chainees"></a> <a name="listes_chainees"></a>
## Listes chaînées ## Listes chaînées
Dans un premier temps, vous travaillerez sur les fichiers :
* Src/cellule.hpp/cpp
* Src/liste.hpp/cpp
* Src/test_liste.hpp/cpp
Un Makefile vous est fourni et préparé pour compiler le code.
Une liste chaînée est une structure de données dont le but est de stocker une Une liste chaînée est une structure de données dont le but est de stocker une
séquence de valeurs. La liste est composée d'un ensemble de *cellules*. Chaque séquence de valeurs. La liste est composée d'un ensemble de *cellules*. Chaque
cellule contient une valeur, ainsi que l'adresse de la cellule suivante. Une cellule contient une valeur, ainsi que l'adresse de la cellule suivante. Une
...@@ -316,6 +324,10 @@ sont adaptées pour réaliser un jeu de *serpent*. Une base vous est fournie, à ...@@ -316,6 +324,10 @@ sont adaptées pour réaliser un jeu de *serpent*. Une base vous est fournie, à
vous de l'étendre pour ajouter l'apparition de bonus à manger, des niveaux plus vous de l'étendre pour ajouter l'apparition de bonus à manger, des niveaux plus
complexes, l'éventuel changement de niveau, le score, ... complexes, l'éventuel changement de niveau, le score, ...
Vous pouvez désormais commencer à examiner les autres fichiers. Le fichier
contenant le programme principal du jeu est `jeu_serpent.cpp`. Sa compilation
est réalisée via `make jeu_serpent`.
<a name="rappels"></a> <a name="rappels"></a>
## Rappels ## Rappels
......
CXX = g++
.DEFAULT_GOAL := test_liste
SOURCES =
SOURCES += cellule.cpp
SOURCES += liste.cpp
OBJECTS = $(SOURCES:.cpp=.o)
CXXFLAGS += -g -Wall -std=c++11 -pedantic
LDFLAGS +=
$(OBJECTS) : %.o : %.cpp
$(CXX) -MMD $(CXXFLAGS) -c $< -o $@
CLEAN_OBJECTS = $(OBJECTS)
TARGETS =
########## test_liste ##########
LISTE_SOURCES = test_liste.cpp
LISTE_OBJECTS = $(LISTE_SOURCES:.cpp=.o)
test_liste : $(LISTE_OBJECTS) $(OBJECTS) $(HEADERS)
$(CXX) $(LISTE_OBJECTS) $(OBJECTS) -o $@ $(LDFLAGS)
$(LISTE_OBJECTS): %.o : %.cpp
$(CXX) -MMD $(CXXFLAGS) -c $< -o $@
all : test_liste
TARGETS += test_liste
CLEAN_OBJECTS += $(LISTE_OBJECTS)
########## serpent ##########
SERPENT_SOURCES = coordonnees.cpp
SERPENT_SOURCES += niveau.cpp
SERPENT_SOURCES += serpent.cpp
SERPENT_SOURCES += jeu_serpent.cpp
SERPENT_OBJECTS = $(SERPENT_SOURCES:.cpp=.o)
jeu_serpent : $(SERPENT_OBJECTS) $(OBJECTS) $(HEADERS)
$(CXX) $(SERPENT_OBJECTS) $(OBJECTS) -o $@ $(LDFLAGS) -lncurses
$(SERPENT_OBJECTS): %.o : %.cpp
$(CXX) -MMD $(CXXFLAGS) -c $< -o $@
all : jeu_serpent
TARGETS += jeu_serpent
CLEAN_OBJECTS += $(SERPENT_OBJECTS)
########## cleanup ##########
DEPS = $(CLEAN_OBJECTS:.o=.d)
clean:
@rm -f $(DEPS) $(TARGETS) $(CLEAN_OBJECTS)
-include $(DEPS)
#include "cellule.hpp"
#ifndef LIFAP6_LISTE_CELLULE_HPP
#define LIFAP6_LISTE_CELLULE_HPP
class Cellule {
/* votre code ici */
} ;
#endif
#include "coordonnees.hpp"
int encode(short int ligne, short int colonne) {
return ((int) ligne & 0xffff) | ((int) colonne << 16) ;
}
short int ligne(int segment) {
return segment & 0xffff ;
}
short int colonne(int segment) {
return segment >> 16 ;
}
#ifndef LIFAP6_LISTES_COORDONNEES_HPP
#define LIFAP6_LISTES_COORDONNEES_HPP
/* encodage ligne / colonne short int dans un int */
int encode(short int l, short int c) ;
short ligne(int segment) ;
short colonne(int segment) ;
#endif
#include "niveau.hpp"
#include "serpent.hpp"
#include <iostream>
#include <ncurses.h>
#include <unistd.h>
int main() {
/* vitesse */
float delay = 0.05 ;
/* elements de jeu */
Niveau niveau(40, 40) ;
Serpent serpent(20, 20) ;
/* debut de ncurses */
initscr() ;
curs_set(0) ;
noecho() ;
keypad(stdscr, TRUE) ;
start_color() ;
/* dessin initial */
niveau.dessiner() ;
serpent.dessiner() ;
refresh() ;
/* attente d'une premiere touche */
std::cin.peek() ;
/* plus d'attente sur les carracteres */
nodelay(stdscr, TRUE) ;
/* boucle d'evenements */
try {
while(1) {
/* handle typed keys */
usleep(delay * 1E6) ;
int c = getch() ;
if(c != ERR) {
/* arrow keys */
if(c == KEY_RIGHT) {
serpent.direction = Serpent::DROITE ;
} else if (c == KEY_UP) {
serpent.direction = Serpent::HAUT ;
} else if (c == KEY_LEFT) {
serpent.direction = Serpent::GAUCHE ;
} else if (c == KEY_DOWN) {
serpent.direction = Serpent::BAS ;
} else {
/* quit if any other key is typed */
break ;
}
}
serpent.avancer(niveau) ;
serpent.rafraichir() ;
refresh() ;
}
/* fin de ncurses */
endwin() ;
} catch (std::runtime_error &e) {
endwin() ;
std::cout << "perdu !" << std::endl ;
}
return 0 ;
}
#include "liste.hpp"
#include <iostream>
#include <cassert>
Liste::Liste() {
/* votre code ici */
}
Liste::Liste(const Liste& autre) {
/* votre code ici */
}
Liste& Liste::operator=(const Liste& autre) {
/* votre code ici */
return *this ;
}
Liste::~Liste() {
/* votre code ici */
}
void Liste::ajouter_en_tete(int valeur) {
/* votre code ici */
}
void Liste::ajouter_en_queue(int valeur) {
/* votre code ici */
}
void Liste::supprimer_en_tete() {
/* votre code ici */
}
Cellule* Liste::tete() {
/* votre code ici */
return nullptr ;
}
const Cellule* Liste::tete() const {
/* votre code ici */
return nullptr ;
}
Cellule* Liste::queue() {
/* votre code ici */
return nullptr ;
}
const Cellule* Liste::queue() const {
/* votre code ici */
return nullptr ;
}
int Liste::taille() const {
/* votre code ici */
return 0 ;
}
Cellule* Liste::recherche(int valeur) {
/* votre code ici */
return nullptr ;
}
const Cellule* Liste::recherche(int valeur) const {
/* votre code ici */
return nullptr ;
}
void Liste::afficher() const {
/* votre code ici */
}
#ifndef LIFAP6_LISTE_LISTE_HPP
#define LIFAP6_LISTE_LISTE_HPP
#include "cellule.hpp"
class Liste {
public :
/* construction d'une liste vide */
Liste() ;
/* construction par copie */
Liste(const Liste& autre) ;
/* affectation */
Liste& operator=(const Liste& autre) ;
/* destruction */
~Liste() ;
/* ajout en tete */
void ajouter_en_tete(int valeur) ;
/* ajout en queue */
void ajouter_en_queue(int valeur) ;
/* suppression en tete */
void supprimer_en_tete() ;
/* consultation de la tete */
const Cellule* tete() const ;
Cellule* tete() ;
/* consultation de la queue */
const Cellule* queue() const ;
Cellule* queue() ;
/* taille de la liste */
int taille() const ;
/* recherche dans la liste */
const Cellule* recherche(int valeur) const ;
Cellule* recherche(int valeur) ;
/* affichage */
void afficher() const ;
private :
/* votre code ici */
} ;
#endif
#include "niveau.hpp"
#include "coordonnees.hpp"
#include <ncurses.h>
Niveau::Niveau(short int hauteur, short int largeur) {
/* bords horizontaux */
for(int i = 0; i < largeur; ++i) {
murs.ajouter_en_tete(encode(0, i)) ;
murs.ajouter_en_tete(encode(hauteur - 1, i)) ;
}
/* bords verticaux */
for(int i = 0; i < largeur; ++i) {
murs.ajouter_en_tete(encode(i, 0)) ;
murs.ajouter_en_tete(encode(i, largeur - 1)) ;
}
}
void Niveau::dessiner() {
/* couleur bleue */
init_pair(1, COLOR_BLUE, COLOR_BLUE) ;
attron(COLOR_PAIR(1)) ;
/* dessin des murs */
Cellule* mur = murs.tete() ;
while(mur) {
short int ml = ligne(mur->valeur) ;
short int mc = colonne(mur->valeur) ;
mvaddch(ml, 2*mc, ' ') ;
mvaddch(ml, 2*mc + 1, ' ') ;
mur = mur->suivante ;
}
/* couleur normale */
attroff(COLOR_PAIR(1)) ;
}
#ifndef LIFAP6_LISTES_NIVEAU_HPP
#define LIFAP6_LISTES_NIVEAU_HPP
#include "liste.hpp"
class Niveau {
public :
/* construction */
Niveau(short int hauteur, short int largeur) ;
/* murs */
Liste murs ;
/* affichage */
void dessiner() ;
} ;
#endif
#include "serpent.hpp"
#include "coordonnees.hpp"
#include <stdexcept>
#include <cassert>
#include <ncurses.h>
Serpent::Serpent(short int ligne, short int colonne) {
direction = HAUT ;
m_etat = GRANDISSANT ;
m_jauge = 5 ;
m_segments.ajouter_en_queue(encode(ligne, colonne)) ;
}
void Serpent::avancer(const Niveau& niveau) {
/* position de la tete */
int tl = ligne(m_segments.queue()->valeur) ;
int tc = colonne(m_segments.queue()->valeur) ;
/* deplacement de la tete dans la bonne direction */
switch(direction) {
case GAUCHE :
--tc ;
break ;
case HAUT :
--tl ;
break ;
case DROITE :
++tc ;
break ;
case BAS :
++tl ;
break ;
default :
assert(0 && "direction inconnue") ;
break ;
}
/* suppression de la queue si stable */
if(m_etat == STABLE) {
m_segments.supprimer_en_tete() ;
} else {
--m_jauge ;
if(m_jauge == 0) {
m_etat = STABLE ;
}
}
/* test de collision */
int tete = encode(tl, tc) ;
if(m_segments.recherche(tete)) {
throw(std::runtime_error("collision")) ;
}
if(niveau.murs.recherche(tete)) {
throw(std::runtime_error("collision")) ;
}
/* ajout de la tete deplacee */
m_segments.ajouter_en_queue(tete) ;
}
void Serpent::dessiner() {
/* couleur bleue */
init_pair(1, COLOR_BLUE, COLOR_BLUE) ;
attron(COLOR_PAIR(1)) ;
/* itération sur les segments */
Cellule* segment = m_segments.tete() ;
while(segment) {
short int sl = ligne(segment->valeur) ;
short int sc = colonne(segment->valeur) ;
mvaddch(sl, 2*sc, ' ') ;
mvaddch(sl, 2*sc + 1, ' ') ;
segment = segment->suivante ;
}
/* couleur normale */
attroff(COLOR_PAIR(1)) ;
}
void Serpent::rafraichir() {
/* couleur bleue */
init_pair(1, COLOR_BLUE, COLOR_BLUE) ;
attron(COLOR_PAIR(1)) ;
/* dessin de la tete */
short int tl = ligne(m_segments.queue()->valeur) ;
short int tc = colonne(m_segments.queue()->valeur) ;
mvaddch(tl, 2*tc, ' ') ;
mvaddch(tl, 2*tc + 1, ' ') ;
/* couleur normale */
attroff(COLOR_PAIR(1)) ;
if(m_etat == STABLE) {
/* effacement de la queue */
short int ql = ligne(m_segments.tete()->valeur) ;
short int qc = colonne(m_segments.tete()->valeur) ;
mvaddch(ql, 2*qc, ' ') ;
mvaddch(ql, 2*qc + 1, ' ') ;
}
}
#ifndef LIFAP6_LISTE_SERPENT_HPP
#define LIFAP6_LISTE_SERPENT_HPP
#include "liste.hpp"
#include "niveau.hpp"
class Serpent {
public :
/* creation a une position donnee */
Serpent(short int ligne, short int colonne) ;
/* direction courante de deplacement */
enum Direction {
DROITE,
HAUT,
GAUCHE,
BAS
} ;
Direction direction ;
/* deplacement */
void avancer(const Niveau& niveau) ;
/* dessin */
void dessiner() ;
void rafraichir() ;
private :
/* etat du serpent */
enum Etat {
STABLE,
GRANDISSANT
} ;
Etat m_etat ;
int m_jauge ;
/* morceaux de serpent */
Liste m_segments ;
} ;
#endif
#include "liste.hpp"
#include <iostream>
#include <cassert>
int main() {
/* adaptez ce fichier selon votre structure */
Liste l1 ;
l1.ajouter_en_tete(10) ;
l1.ajouter_en_tete(11) ;
std::cout << "attendu : [ 11 10 ]" << std::endl ;
l1.afficher() ; // [ 11 10 ]
assert(l1.tete()->valeur == 11) ;
assert(l1.queue()->valeur == 10) ;
assert(l1.recherche(11)) ;
assert(l1.recherche(10)) ;
assert(!l1.recherche(12)) ;
assert(l1.taille() == 2) ;
Liste l2(l1) ;
l2.ajouter_en_tete(20) ;
std::cout << "attendu : [ 20 11 10 ]" << std::endl ;
l2.afficher() ; // [ 20 11 10 ]
assert(l2.tete()->valeur == 20) ;
assert(l2.queue()->valeur == 10) ;
assert(l2.recherche(20)) ;
assert(l2.recherche(11)) ;
assert(l2.recherche(10)) ;
assert(!l2.recherche(21)) ;
Liste l3 ;
l3.ajouter_en_tete(30) ;
l3 = l1 ;
std::cout << "attendu : [ 11 10 ]" << std::endl ;
l3.afficher() ; // [ 11 10 ]
assert(l3.tete()->valeur == 11) ;
assert(l3.queue()->valeur == 10) ;
assert(l3.recherche(11)) ;
assert(l3.recherche(10)) ;
assert(!l3.recherche(30)) ;
l1.supprimer_en_tete() ;
l1.afficher() ; // [ 10 ]
assert(l1.tete()->valeur == 10) ;
assert(l1.queue()->valeur == 10) ;
assert(l1.recherche(10)) ;
assert(!l1.recherche(11)) ;
l1.ajouter_en_tete(12) ;
std::cout << "attendu : [ 12 10 ]" << std::endl ;
l1.afficher() ; // [ 12 10 ]
assert(l1.tete()->valeur == 12) ;
assert(l1.recherche(10)) ;
std::cout << "attendu : [ 20 11 10 ]" << std::endl ;
l2.afficher() ; // [ 20 11 10 ]
assert(l2.tete()->valeur == 20) ;
assert(l2.recherche(11)) ;
assert(l2.recherche(10)) ;
std::cout << "attendu : [ 11 10 ]" << std::endl ;
l3.afficher() ; // [ 11 10 ]
assert(l3.tete()->valeur == 11) ;
assert(l3.recherche(10)) ;
l3.ajouter_en_queue(31) ;
std::cout << "attendu : [ 11 10 31 ]" << std::endl ;
l3.afficher() ; // [ 11 10 31 ]
assert(l3.tete()->valeur == 11) ;
assert(l3.queue()->valeur == 31) ;
assert(l3.recherche(11)) ;
assert(l3.recherche(10)) ;
assert(l3.recherche(31)) ;
return 0 ;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment