Compare commits

1 Commits
main ... main

Author SHA1 Message Date
66df563049 Update R1.02/sae/README.md
Retirer la majuscule parasite qui n'amène pas au fichier mdr
2025-12-30 05:54:49 +01:00
121 changed files with 2 additions and 7738 deletions

Binary file not shown.

View File

@@ -17,7 +17,7 @@ Il donnera lieu à une note en DEV et en COM. Seront jugés :
> - l'url de votre dépot git associé, contenant les sources et le rapport demandé. > - l'url de votre dépot git associé, contenant les sources et le rapport demandé.
> - tous les noms d'étudiants faisant partie du groupe. > - tous les noms d'étudiants faisant partie du groupe.
**Vérifiez [ici](./Groupes.md) que votre mail a été pris en compte.** **Vérifiez [ici](./groupes.md) que votre mail a été pris en compte.**
#### Exigences minimales #### Exigences minimales

View File

@@ -15,21 +15,5 @@
- MERIGOT Antoine / SLIMANI Tajeddine / DUCOURE Ibrahim - MERIGOT Antoine / SLIMANI Tajeddine / DUCOURE Ibrahim
- GILLET Noa / GUINET Djibril / SALVIA Tim - GILLET Noa / GUINET Djibril / SALVIA Tim
- Anthony LIROT / Dylan SOYER - Anthony LIROT / Dylan SOYER
- Emile Ta / Imad Mokhtari / Anthony Millerioux / Johan Garnier - Emile Ta / Imad Mokhtari / Anthony Millerioux
- Matéo POUGET / Nathan LAUNAY / Ender PRADAT-DE CAROLIS - Matéo POUGET / Nathan LAUNAY / Ender PRADAT-DE CAROLIS
- Fabien SELON / Michaellah LAHIKOA / Koutoub Khan KADARALY
- Clement JACKSON GONZALEZ / Rayane MOUHIB / Dayann Sidiqui
- Jossé Maël / Jihad Ghandri / Jdoudi Abderrahmane
- Antoine BERNARD / Antoine MERCIER / Mathias PLACIDE CONTRERAS
- Amrouchi Youssef / Maël Hamon / Baptiste Lecointre
- Bradney LELIEVRE / Arif MOHAMED
- Salgeiro da silva / Pelini / Janicot
- Kenzo BONNET, Bryan Benhamou, Toni LAURENT
- Mohamed Ouissi / Jabrail Mustaev / Talbi Sofiane
- Aktas / Gobe / Tafok
- CHARRIERE Nicolas / BODOL Mathis / TCHISSAFOU Yann-sulivane
- Matie BAMBA
- Colombani Loïc / Badio Ousmane
- Adrien Jackson-Gonzalez / Gomez / Dimambu-Bola
- Fabien SELON / Michaëllah LAHIKOA / Qoutoub Khan KADARALY
- Kelyan Pierre-Louis / Jordan Arstil / Matheo Salavin-Moura / Evan Giloppé

View File

@@ -1,43 +0,0 @@
# Programmation WEB coté serveur R3.01
Ce dépôt contient les ressources utilisées
(cours/td/tp) dans la ressource R3.01.
**Les objectifs**
> Savoir développer une application Web côté serveur, en utilisant le langage PHP.
Les notions suivantes seront abordées :
- Le langage php
On se limitera aux bases du langages. La couche objet sera présenté très succintement.
Toute la suite sera illustré avec PHP.
- Interaction avec le client
URL (Uniform Resource Locator), requêtes, formulaires, transmission des paramètres, des données, etc.
- Applications Web à états
Cookies et sessions
- Organisation de laccès aux données
Bases de données, annuaires, services Web, etc.
- Introduction à la programmation objet en PHP
Introduction au principe MVC
- Sensibilisation à la sécurité des applications web
## Calendrier
| Semaine | Cours | TD/TP |
| ------------------ | -------------------------------------------------------- | ------------------ |
| 1 : 16/03 - 20/03| [Bases du langages](./cours/cm_bases_php.pdf) | |
## Les TPS
#### TP1 : Bases du langage PHP
Le [tp1](./tp/tp1)
permet de se familiariser avec le langage PHP.
À chaque exercice correspond un sous répertoire avec
des fichiers à compléter.

Binary file not shown.

View File

@@ -1,22 +0,0 @@
## Ressources R4.01 + R4.A.10
#### Semaine 1
[Compléments de javascript](cours/jscomp.pdf) javascript, [tp1](./td_tp/tp1)
#### Semaine 2
[DOM](cours/dom.pdf), [tp2](./td_tp/tp2), [tp2mvc](td_tp/tp2mvc)
#### Semaine 3
[DOM](cours/dom.pdf), [tp3](./td_tp/tp3)
#### Semaine 4
[Promesses, Ajax, API de données](cours/ajax.pdf), [tp4](./td_tp/tp4)
#### Semaine 5
[Programmation déclarative, RIOT.js](cours/riot.pdf), [tp5](./td_tp/tp5)
#### Semaine 6
[API REST](cours/api.pdf), service firebase [tp6](./td_tp/tp6)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,54 +0,0 @@
## Thème
Écrire une application web en javascript qui permet de consulter les données de
parcours sup (vœux de poursuite d'études et de réorientation dans l'enseignement
supérieur et réponses des établissements) afin d'aider un(e) lycéén(e) à faire ses choix.
- La partie cliente devra être réaliser au moyen du framework [riotjs](https://riot.js.org/).
- Les données seront consommées au moyen de [l'api](https://data.enseignementsup-recherche.gouv.fr/explore/dataset/fr-esr-parcoursup/api/?timezone=Europe%2FBerlin&sort=tri) opendata. (cf [méthodologie](https://data.enseignementsup-recherche.gouv.fr/api/datasets/1.0/fr-esr-parcoursup/attachments/methodologie_opendata_2025pdf/))
- La localisation utilisera openstreet map et l'api [Leaflet](https://leafletjs.com/).
- Les graphiques seront réalisés au moyen de [chart css](https://chartscss.org/).
## Fonctionnalités
#### Recherche des formations par mots clés, avec localisation sur une carte.
[<a href="img/search.png">exemple</a>]
#### Vue d'une formation particulière, avec accès aux données de parcourssup, entre autres :
- les données lors de la phase d'admission,
- les données lors de la phase complémentaire,
- le profils des admis,
- l'évolution de la selectivité, des mentions au bac depuis 2020.
[<a href="img/formation.png">exemple</a>, <a href="img/profil.png">exemple</a>,
<a href="img/profil1.png">exemple</a>]
#### Aide au choix d'orientation
L'utilisateur doit pouvoir selectionner des formations/filières afin de les comparer et estimer
ses chances d'intégrations en fonction de la série de son bac et de sa moyenne en terminale.
[<a href="img/selection1.png">exemple</a>
, <a href="img/selection2.png">exemple</a>]
Les choix de l'utilisateur devront au moins être persistant localement. Vous pouvez, losque tout fonctionne,
mettre en oeuvre une persistance avec [firebase](https://firebase.com).
## Réalisation
1. Une partie de votre travail consiste à comprendre comment fonctionne l'api (entrées/sorties), et comment l'utiliser. N'hésitez pas à encapsuler/abstraire les informations de l'api dans votre propre modèle.
2. Le but est d'utiliser la programmation déclarative et par composants de RIOT.js. Il faut donc l'architecturer et l'organiser en
conséquence. En particulier, il faut profiter pleinement de l'utilisation de composants le plus génériques possibles.
3. Il faut utiliser des urls routables. Riot.js vient avec un [router](https://github.com/riot/route) très simple d'utilisation.
Je vous expliquerai comment mettre en oeuvre la réécriture d'url avec apache.
4. Il est possible d'utiliser le pattern observable, avec une bibliothèque adhoc ([exemple](https://github.com/riot/observable))
5. Dans le depot GIT de votre projet, il faut une description des composants, leurs entrées, leurs fonctions, et comment
ils communiquent avec le reste du monde.
## Attendus
Un mail (sujet S4WEB) m'indiquant les informations suivantes :
- l'url de votre projet sous la forme : http://dwarves.iut-fbleau.fr/~login/parcoursup
- l'url du dépôt GIT avec vos sources sur dwarves.iut-fbleau.fr
- les noms du binôme.
Le tout est à finaliser avant le Vendredi 03 avril 2025, 18 heures. Une soutenance aura lieu la semaine du 30/03.

View File

@@ -1,17 +0,0 @@
## Groupes projet
- Rayan Lankechari / Ibrahima Bah
- Demrici-Özmen Canpolat / Eliot Maxime
- Ozvann ABRAHAM / Karl FRAMERY
- SOLAR Dimitri / ZAABAY Tarehi
- Nicolas Miekisiak / Loïc Sainton
- Torreblanca Mathys / Poitou Enzo
- WIECZOREK Valentin / PLOUVIER Luka
- Kouami Kpeglo / Alexis Fort
- Ugo Faye / Mathis Leclere
- Nathan Couchot / Théo Anastasio / Adrien Rabot
- Pierre COURTEHOUX / Lukas SIMOES
- CAMILLE Cléo / Warrhen Roland
- Aylane Sehl / Séri-Khane / ??
- Arwa Ben Fraj / Bounni Loubelo Benicia
- Hicham Cherifi / Wael Atik
- DERQSI BILAL / CAMILLE LECHAVLIER

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

View File

@@ -1,207 +0,0 @@
# TP javascript : bases du langages.
Un peu [d'aide](./aide.md).
> - seance 1 : [révisions](#p1)
> - seance 2 : [forEach, filter, map, reduce, etc.](#p2)
### <a name="p1"></a> Séance 1
#### Ex1 : fourmi de Langton
Une fourmi, assimilable à un petit automate, se promène sur une grille de points colorés;
pour commencer, tous les points sont blancs.
- la fourmi est initialement placée au centre de la grille. Elle se déplace dans les quatre directions cardinales. Initialement, elle va vers l'est.
- A chaque pas, elle se déplace d'une case dans sa direction. Son parcours est dicté par les deux règles suivantes :
- Si la case atteinte est noire, elle la repeint en blanc, et tourne de 90° à gauche.
- Si la case est blanche, elle la repeint en noire, et tourne de 90° à droite.
- Elle continue son chemin en suivant ces règles.
<div align="center">
_Les 9 premiers pas de la fourmi_<br>
<img src="./img/fourmi.png">
</div>
Vous disposez de [sources](./src/langton) que vous allez compléter. En particulier, il y a 2 modules :
>- une classe **Ant** qui représente l'univers : la fourmi, et les tuiles sur lesquelles elle se déplace.
>- une fonction **render** qui gére l'affichage graphique.
- La fourmi a une position sur la grille, ainsi qu'une direction. La direction sera codée par un entier (angle 0,90,180 ou 270).
- Les tuiles sont repréntées par un tableau à 2 dimensions. Chaque tuile a 2 valeurs possibles (0 ou 1).
1. Complétez le code de la classe `Ant`.
2. Complétez le code de `app.js`.
3. Ajoutez un bouton/lien qui permet de réinitialiser la simulation.
4. Dissociez, en terme de classe/structure, la fourmi de la grille sur laquelle elle évolue, et modifiez le
code en conséquence.
<div align="center">
<img src="./img/langton.png">
</div>
#### Ex2 : fourmi de Langton
On peut complexifier et généraliser la fourmi précédente, et les règles d'évolution de l'automate correspondant : la fourmi, et les tuiles peuvent avoir
un nombre quelconque d'états. Les règles de l'automate sont alors décrites par une table de transition.
Exemple 1 : on donne la table de transition suivante (T désigne la tuile, a la fourmi) à 2 états pour la fourmi, et 2 états pour les tuiles.
| | T: 0 | T: 1 |
|------|-----------|-----------|
| a: 0 | (1,0,1) | (0,90,1) |
| a: 1 | (0,-90,1) | (1,0,1) |
Chaque triplet représente (Ant State Change, Ant Direction Change, Tile State Change). Ainsi,
- (1,90,0) => on incrémente 1 à l'état de la fourmi, 90 à sa direction, et 0 à l'état de la tuile.
- (0,-90,1) => on incrémente 0 à l'état de la fourmi, -90 à sa direction, et 1 à l'état de la tuile.
Les incrémentations se font modulo le nombre d'états possibles.
Avec cet automate, on obtient la figure :
<div align="center">
<img src="./img/langton1.png">
</div>
Par commodité, on note la table de transition précédente simplement :
```
(1,0,1) (0,90,1)
(0,-90,1) (1,0,1)
```
1. Modifiez le code de l'exercice 1 de manière à pouvoir simuler l'automate ci-dessus. Votre solution doit pouvoir permettre une simulation quelconque.
Quelle est la table correspondante à la fourmi de la première partie du tp ?
2. Testez avec
```
(1,90,0) (0,-90,1)
(0,-90,1) (1,90,1)
```
<div align="center">
<img src="./img/langton2.png">
</div>
3. Testez avec
```
(1, 0, 1) (0, 90, 0)
(0, -90, 1) (1, 0, 1)
```
### <a name="p2"></a> Séance 2
#### Ex1
Soit le tableau d'objets suivant :
```js
let customers = [
{
'id': 1,
'f_name': 'Abby',
'l_name': 'Thomas',
'gender': 'M',
'married': true,
'age': 32,
'expense': 500,
'purchased': ['Shampoo', 'Toys', 'Book']
},
{
'id': 2,
'f_name': 'Jerry',
'l_name': 'Tom',
'gender': 'M',
'married': true,
'age': 64,
'expense': 100,
'purchased': ['Stick', 'Blade']
},
{
'id': 3,
'f_name': 'Dianna',
'l_name': 'Cherry',
'gender': 'F',
'married': true,
'age': 22,
'expense': 1500,
'purchased': ['Lipstik', 'Nail Polish', 'Bag', 'Book']
},
{
'id': 4,
'f_name': 'Dev',
'l_name': 'Currian',
'gender': 'M',
'married': true,
'age': 82,
'expense': 90,
'purchased': ['Book']
},
{
'id': 5,
'f_name': 'Maria',
'l_name': 'Gomes',
'gender': 'F',
'married': false,
'age': 7,
'expense': 300,
'purchased': ['Toys']
},
{
'id': 6,
'f_name': 'Homer',
'l_name': 'Simpson',
'gender': 'M',
'married': true,
'age': 39,
'expense': 500,
'purchased': ['Book']
}
];
```
En utilisant les fonctions/méthodes `forEach, filter, map, reduce, some, every, find`, donnez ou calculez :
1. un tableau des client séniors (dont l'âge est plus de 60 ans).
2. un tableau où chaque client possède un nouvel attribut `full_name`.
3. s'il y a un client de moins de 10 ans.
4. le nombre d'acheteurs de livres.
5. la somme totale d'argent dépensé par les clients marriés.
6. Pour chaque produit, la liste (`id`) des acheteurs.
#### Ex2
Ecrire une fonction qui calcule tous les nombres premiers inférieurs à une valeur entière `n` donnée,
en utilisant le [crible d'Erastosthène](https://fr.wikipedia.org/wiki/Crible_d%27%C3%89ratosth%C3%A8ne).
Le version du crible est volontairement "mal écrite" en terme de performance :
```js
let eratosthene1 = n => {
let numbers = Array.from({length : n - 2}, (v,k) => k + 2);
let p ,primes = [];
while(numbers.length){
[p,...numbers] = numbers;
numbers = numbers.filter( k => k%p != 0);
primes = [...primes,p];
}
return primes;
}
```
1. Expliquez précisément ce code. Testez et dites pourquoi qu'il n'est pas efficace.
2. Écrivez une version plus efficace et comparer les temps de calcul. Vous pourrez compléter le code suivant :
```js
let eratosthene = n => {
let primes = [];
let filterArray = []; // tableau qui permet
// de cribler les multiples des nombres
// premiers
for(let i = 2; i <= n; i++){
// TODO
}
return primes;
}
```

View File

@@ -1,115 +0,0 @@
#### Élement d'un document
```js
let x = document.getElementById(MOVE_VAL_ID)
let images = document.querySelectorAll('img')
```
#### Changer le contenu texte d'un élément
```js
document.getElementById('message').textContent = "hello world !"
```
#### Nombre aléatoire
```js
let r=Math.random();
if (r<0.5)
console.log("Face");
else
console.log("Pile");
```
#### Timers
```js
setTimeout(()=>console.log("3 secondes écoulées"),3000);
let i = setInterval(
() => {
let d = (new Date()).toLocaleTimeString();
document.getElementById("time").innerText = d;
},
1000)
setTimeout(()=>clearInterval(i),10000);
```
#### Réponse à un événement
```js
// inline DOM 0
img.onclick = function(){ console.log("clicked !")}
// DOM >= 2
img.addEventListener("click",()=>console.log("clicked"));
```
#### Itération d'un tableau
```js
let a = [1,2,3];
// forEach
a.forEach( elem => console.log(elem));
// for ... of
// valable pour tous les itérables
// Array, Map, Set, String, etc.
for (let elem of a){
console.log(elem);
}
```
#### Tri d'un tableau
```js
const activities = [
{ title: 'Hiking', date: new Date('2019-06-28') },
{ title: 'Shopping', date: new Date('2019-06-10') },
{ title: 'Trekking', date: new Date('2019-06-22') }
]
const sortedActivities = activities.sort((a, b) => b.date - a.date);
```
#### Itération d'un tableau avec map, filter, reduce et find.
```js
// map
const items = ['a', 'b', 'c']
const newArray = items.map((item) => performSomething(item))
const newArray = items.map(performSomething)
// find
const items = [
{ name: 'a', content: { /* ... */ }},
{ name: 'b', content: { /* ... */ }},
{ name: 'c', content: { /* ... */ }}
]
const b = items.find((item) => item.name === 'b')
//reduce
const items = [
{ name: 'a', content: { value: 1 }},
{ name: 'b', content: { value: 2 }},
{ name: 'c', content: { value: 3 }}
]
const count = items.reduce((result, elem ) => result + elem.content.value, 0)
// en decomposant l'objet !
const count = items.reduce((result, { content: { value } }) => result + value, 0)
```
#### Division d'une chaîne de caractères avec split
```js
const str = 'a,b,c,d,e'
const l = str.split(',')
// l = [ "a","b","c","d","e"]
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<script src="eratosthene.js"></script>
</head>
<body>
<main>
<form role="search">
<input name="limit" type="text">
<input type="submit" value="compute">
</form>
<article>
<p>time : <span id="time1"></span></p>
<p>time : <span id="time2"></span></p>
<p id="primes"></p>
</article>
</main>
<script>
document.querySelector("form").addEventListener("submit",ev => {
ev.preventDefault();
let start,end;
start = performance.now();
primes = eratosthene1(ev.target.limit.value);
end = performance.now();
document.getElementById("time1").textContent = end - start;
document.getElementById("primes").textContent = primes;
})
</script>
</body>
</html>

View File

@@ -1,23 +0,0 @@
function eratosthene(n)
{
let primes = [];
let filterArray = [];
for(let i = 2; i <=n; i++){
// TODO
}
return primes;
}
function eratosthene1(n)
{
let numbers = Array.from({length : n - 2}, (v,k) => k + 2);
let p ,primes = [];
while(numbers.length){
[p,...numbers] = numbers;
numbers = numbers.filter( x => x%p != 0);
primes = [...primes,p];
}
return primes;
}

View File

@@ -1,65 +0,0 @@
import render from "./modules/langton-renderer-canvas2d";
import Ant from "./modules/Ant.js";
const options = {
antStateColors : ['red','yellow'],
tileStateColors : ['white','black'],
tileSize : 5
};
// For the view
const STEP_INTERVAL = 5;
const BTN_AUTOPLAY_ID = 'autoplay';
const BTN_NEXT_MOVE_ID = 'next-move';
const MOVE_VAL_ID = 'move-value';
const BTN_PLUS_100_ID = 'plus-100';
let autoplayInterval;
let canvas = document.querySelector("canvas");
canvas.width = window.innerWidth ;
canvas.height = window.innerHeight;
let ant = new Ant(Math.floor(canvas.width / options.tileSize),Math.floor(canvas.height/options.tileSize));
document.getElementById(BTN_AUTOPLAY_ID).addEventListener('click', () => {
if (autoplayInterval) {
return
}
// TODO
});
document.getElementById(BTN_PLUS_100_ID).addEventListener('click', () => {
if (autoplayInterval) {
clearInterval(autoplayInterval);
autoplayInterval = null;
}
// TODO
});
document.getElementById(BTN_NEXT_MOVE_ID).addEventListener('click', () => {
if (autoplayInterval) {
clearInterval(autoplayInterval);
autoplayInterval = null;
}
ant.moveForward();
updateView(ant,canvas,options)
})
function updateView(ant,canvas,options)
{
document.getElementById(MOVE_VAL_ID).textContent = `${ant.move}`;
render(ant,canvas,options);
}
updateView(ant,canvas,options);

View File

@@ -1,8 +0,0 @@
canvas {
position : absolute ;
top : 0;
left : 0;
z-index : -1;
}

View File

@@ -1,42 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,witdh=device-width">
<title>Fourmi de Langton</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<!--link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css"
-->
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<main>
<h4>
Fourmi de Langton
</h4>
<nav>
<ul>
<li><a href="#" id="next-move">Next</a></li>
<li><a href="#" id="autoplay">Auto</a></li>
<li><a href="#" id="plus-100">+100</a></li>
</ul>
<ul>
<li>
<small>Nombre de mouvements : <span id="move-value"></span></small>
</li>
</ul>
</nav>
</main>
<canvas></canvas>
<script type="module" src="app.js"></script>
</body>
</html>

View File

@@ -1,56 +0,0 @@
class Ant {
x = 0; // position
y = 0;
move = 0;
w = 0; // universe dimensions
h = 0;
direction = 0; // 0 90 180 270
state = 0;
tiles = null;
constructor (w,h)
{
this.tiles = new Array(w).fill(null);
this.tiles.forEach((el,i) => this.tiles[i] = new Array(h).fill(0));
this.w = w;
this.h = h;
this.x = Math.floor(w/2);
this.y = Math.floor(h/2);
}
moveForward()
{
switch (this.direction) {
case 0:
this.x = ((this.x + 1) + this.w) % this.w;
break
case 90:
this.y = ((this.y + 1) + this.h) % this.h;
break
case 180:
this.x = ((this.x - 1) + this.w) % this.w;
break
case 270:
this.y = ((this.y - 1) + this.h) % this.h;
break
}
this.move ++;
this.computeNextState();
}
rotateRight() {
// TODO
}
rotateLeft() {
// TODO
}
computeNextState()
{
// TODO
}
}
export default Ant;

View File

@@ -1,99 +0,0 @@
/**
* render - renders the universe to a 2D canvas.
*
* @param langtonsAnt - the universe.
* @param canvas - The 2D canvas.
* @param options - The rendering options (all optional).
* @returns {undefined} - Nothing is returned.
*/
function render(langtonsAnt, canvas, options) {
// Grab our options.
const {
tileStateColors,
antStateColors,
tileSize
} = options;
// Drawing style.
const backgroundColor = '#FFFFFF';
// Size constants.
const w = canvas.width;
const h = canvas.height;
// Bounds constants.
const gridSizeW = langtonsAnt.tiles.length;
const gridSizeH = langtonsAnt.tiles[0].length;
// We're going to draw each square with a given edge size
const tileSizeW = tileSize;//w / gridSizeW ;
const tileSizeH = tileSize; //h / gridSizeH ;
// Get the drawing context.
var ctx = canvas.getContext('2d');
// Clear the background.
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, w, h);
// Draw the grid.
ctx.strokeStyle='#00000011';
for (let x = 0; x <= gridSizeW; x++) {
ctx.beginPath();
ctx.moveTo(x * tileSizeW , 0);
ctx.lineTo(x * tileSizeW , h);
ctx.closePath();
ctx.stroke();
}
for (let y = 0 ; y <= gridSizeH; y++) {
ctx.beginPath();
ctx.moveTo(0, y * tileSizeH);
ctx.lineTo(w, y * tileSizeH);
ctx.closePath();
ctx.stroke();
}
// Start drawing those tiles.
langtonsAnt.tiles.forEach((tileRow,i) => {
tileRow.forEach((tile,j)=>{
// Get the tile state index.
// Skip state zero tiles (i.e. white tiles)
if (tile !== 0) {
// Set the tile colour, defaulting to grey if it is not set.
ctx.fillStyle = tileStateColors[tile] || '#CCCCCC';
ctx.fillRect(i * tileSizeW + 1, j * tileSizeH +1, tileSizeW - 1, tileSizeH - 1);
}
})
})
// Draw the ant.
var antX = langtonsAnt.x * tileSizeW,
antY = langtonsAnt.y * tileSizeH;
const antState = langtonsAnt.state;
ctx.fillStyle = antStateColors[antState];
// Tranform before we draw the ant, it makes it easier.
//
ctx.save();
ctx.translate(antX + tileSizeW/2, antY+tileSizeH/2);
ctx.rotate((langtonsAnt.direction / 180) * Math.PI);
ctx.beginPath();
ctx.moveTo(-tileSizeW/2, -tileSizeH/2);
ctx.lineTo(tileSizeW/2, 0);
ctx.lineTo(-tileSizeW/2, tileSizeH/2);
ctx.fill();
ctx.closePath();
ctx.restore();
}
export default render;

View File

@@ -1,55 +0,0 @@
# TP javascript : DOM
Un peu [d'aide](./aide.md).
#### Ex0
On stocke dans un objet une liste de favoris :
```js
let favs = [
{
nom:"Google",
url:"http://www.google.fr"
},
{
nom:"Le Monde",
url:"http://www.google.fr"
},
{
nom:"L'Equipe",
url:"http://www.lequipe.fr"
}
];
```
Compléter le fichier `favoris.js` de manière à créer dans la page html la liste de liens
correspondant
![lien}](./img/liens.png?style=centerme)
Il vous faut créer dynamiquement les noeuds nécessaires avec l'api dom de javascript.
#### Ex1
Il s'agit de réaliser une version "simple" du jeu (whac-a-mole)[https://en.wikipedia.org/wiki/Whac-A-Mole].
Le principe du jeu est de frapper à l'aide d'un marteau sur le plus grand nombre
de taupes parmi celles qui sortent pour un temps très limité et aléatoirement
des trous situés sur un panneau de contrôle.
<div align="center">
<img src="./img/mole.png">
</div>
#### Ex2
Vous devez compléter les [sources](./src/ex1) d'un jeu qui consiste à essayer
d'éteindre toutes les lumières d'une grille en utilisant la règle suivante.
Quand on allume/éteint une lumière, on allume/éteint aussi ses voisines.
<div align="center">
<img src="./img/lights.png">
</div>
Chaque lumière, via l'interface dataset, possède un numéro (de 0 à size^2-1).

View File

@@ -1,132 +0,0 @@
#### Selection d'éléments
```js
// le premier
document.querySelector(".box")
// ou tous
document.querySelectorAll(".box")
// avec l'id
document.getElementById("toto")
// selection d'un élément dans un autre
let container = document.querySeletor('.container')
container.querySelector('.box')
```
#### Traverser le dom
```js
var box = document.querySelector(".box")
box.nextElementSibling
box.previousElementSibling
box.parentElement
box.childNodes
```
#### Création/insertion d'éléments
```js
let p = document.createElement('p')
p.textContent="blabla"
document
.getElementById("myDiv")
.appendChild(p)
div.replaceChildren(p)
```
#### Gestionnaire évènementiels
```js
document.querySelector(".button").addEventListener("click", (e) => { /* ... */ })
document.querySelector(".button").addEventListener("mouseenter", (e) => { /* ... */ })
document.addEventListener("keyup", (e) => { /* ... */ })
```
#### window/document prêt
```js
document.addEventListener("DOMContentLoaded",() = > { .....})
// le dom a été construit (on n'attend pas le chargement du css, images, etc.
windon.addEventListener('load',()=>{...})
// le dom est prêt et toutes les ressources ont été chargées.
```
#### dataset
```html
<div id="user" data-id="1234567890" data-user="carinaanand" data-date-of-birth>
Carina Anand
</div>
```
```javascript
const el = document.querySelector("#user");
// el.id === 'user'
// el.dataset.id === '1234567890'
// el.dataset.user === 'carinaanand'
// el.dataset.dateOfBirth === ''
```
#### Local storage
```js
localStorage.setItem('monChat', 'Tom')
let cat = localStorage.getItem('myCat')
localStorage.clear()
```
#### Limiter les appels successifs à une fonction
```js
function debounce(f,wait)
{
let timeout
return function(...args){
clearTimeout(timeout)
timeout=setTimeout(()=>f(...args),wait)
}
}
```
#### Gestion du css depuis le DOM
```js
// Select the first .box and change its text color to #000
document.querySelector(".box").style.color = "#000";
// Set color to #000 and background to red
var box = document.querySelector(".box")
box.style.color = "#000"
box.style.backgroundColor = "red"
// Set all styles at once (and override any existing styles)
box.style.cssText = "color: #000; background-color: red"
// Hide and show an element by changing "display" to block and none
document.querySelector(".box").style.display = "none"
document.querySelector(".box").style.display = "block"
// Add, remove, and the toggle the "focus" class
var box = document.querySelector(".box")
box.classList.add("focus")
box.classList.remove("focus")
box.classList.toggle("focus")
box.classList.add("focus", "highlighted")
box.classList.remove("focus", "highlighted")
box.classList.add("focus", "highlighted")
box.classList.remove("focus", "highlighted")
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,18 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<title>Favoris</title>
<script src="./js/favoris.js"></script>
</head>
<body>
<main>
<h1>Favoris</h1>
</main>
</body>
</html>

View File

@@ -1,24 +0,0 @@
let favoris = [
{
nom:"Google" ,
url:"www.google.fr",
img:"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/200px-Google_2015_logo.svg.png"
},
{
nom:"Le Monde",
url:"lemonde.fr",
img:"https://upload.wikimedia.org/wikipedia/commons/thumb/2/22/Lemonde_fr_2005_logo.svg/200px-Lemonde_fr_2005_logo.svg.png?uselang=fr"
},
{
nom:"L'Equipe",
url:"www.lequipe.fr",
img:"https://upload.wikimedia.org/wikipedia/commons/thumb/3/32/L%27%C3%89quipe_wordmark.svg/200px-L%27%C3%89quipe_wordmark.svg.png"
}
]
window.addEventListener("load",()=>{
// TODO
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,37 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Whack-a-Mole Game</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<div class="game">
<h1>Whack-a-Mole!</h1>
<div class="score-board">
<span>Score: </span><span id="score">0</span>
</div>
<div class="holes">
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole up"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
<div class="hole"><div class="mole"><img src="img/mole2.png"></div></div>
</div>
<button id="startButton">START</button>
</div>
</main>
<script src="script.js"></script>
</body>
</html>

View File

@@ -1,53 +0,0 @@
const holes = document.querySelectorAll('.hole');
const moles = document.querySelectorAll('.mole');
const scoreBoard = document.getElementById('score');
const startButton = document.getElementById('startButton');
let lastHole;
let timeUp = false;
let score = 0;
let duration = 30
function randomTime(min, max) {
return Math.round(Math.random() * (max - min) + min);
}
function randomHole(holes) {
const idx = Math.floor(Math.random() * holes.length);
const hole = holes[idx];
if (hole === lastHole) {
return randomHole(holes);
}
lastHole = hole;
return hole;
}
function peep() {
const time = randomTime(1000, 1500);
const hole = randomHole(holes);
// TODO
setTimeout(() => {
// TODO
//
}}, time);
}
function startGame() {
scoreBoard.textContent = 0;
score = 0;
timeUp = false;
// TODO
}
function bonk(e) {
// TODO
}
moles.forEach(mole => mole.addEventListener('click', bonk));
startButton.addEventListener('click', startGame);

View File

@@ -1,68 +0,0 @@
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
/* font-family: Arial, sans-serif;*/
}
.game {
text-align: center;
}
.holes {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
width: 400px;
margin: 20px auto;
}
.hole {
width: 100px;
height: 100px;
background : radial-gradient(rgb(150,250,150), #00ee00);
/* background-color: red;/*#8b4513;*/
/* background-image : url('img/mole2.png');*/
position: relative;
border-radius: 50%;
margin: 10px;
overflow: hidden;
}
.mole img{
width: 10px;
height: 10px;
/* background-color: #555;*/
position: absolute;
bottom: -100px;
left: 0px;
/*border-radius: 50%;*/
transition: bottom 0.3s;
}
.mole.up img{
/* background-image : url('img/mole2.png');
background-size:contain;
background-repeat: no-repeat;*/
width:90px;
height:90px;
bottom: 0px;
}
.mole.whacked img {
content: url('img/mole-whacked.png');
/* background-image : url('img/mole-whacked.png');
background-size:contain;
background-repeat: no-repeat;*/
width:90px;
height:90px;
bottom: -20px;
}
.score-board {
font-size: 1.5em;
margin: 20px;
}

View File

@@ -1,71 +0,0 @@
// variables de vue
const button = document.querySelector("input[type=submit]");
const select = document.querySelector("select");
const board = document.querySelector(".board");
const message = document.querySelector("#message");
let lights = null
// state <-> tableau de booléen pour
// stocker l'état des lumières
// neighbors <-> tableau des voisins de chaque lumière
let state = [];
let neighbors = [];
let newBoard = ( (size ) => {
let frag = document.createDocumentFragment()
// TODO
// la fonction crée dans le dom la grille des lumières
board.replaceChildren(frag)
});
let calcNeighbours = ( (size) =>{
let res = [];
for(let i = 0; i < size; i ++){
for(let j = 0; j < size; j++){
let v = [];
v.push(i*size + j);
if ( (j - 1) >= 0) v.push(i*size + j - 1);
if ( (j + 1) < size) v.push(i*size + j + 1);
if ( (i - 1) >= 0) v.push(size*(i-1) + j );
if ( (i + 1) < size) v.push(size*(i+1) + j);
res.push(v)
}
}
return res
});
function play(){
let size = select.value;
newBoard(size);
neighbors = calcNeighbours(size);
lights = document.querySelectorAll(".board span");
state = Array.from({length: size*size}, () => Math.random() < 0.5 ? 1:0);
state.forEach((el,i)=>{
if (el) lights[i].classList.toggle("off");
});
message.textContent = "";
}
// abonnements
document
.querySelector(".board")
.addEventListener("click", ev => {
// TODO
// permet de choisir d'éteindre/allumer une lumière et
// ses voisines
// Il faut en outre detecter la fin de partie
});
button.addEventListener("click",play);
play();

View File

@@ -1,52 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!-- Centered viewport -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" title="no title" charset="utf-8">
</head>
<body>
<main>
<h4>Lights</h4>
<p>Le but est d'éteindre l'ensemble des lumières.</p>
<p id="message"></p>
<article>
<div class="board">
<!--div class="row">
<span data-num="0"></span>
<span data-num="1"></span>
<span data-num="2"></span>
</div>
<div class="row">
<span data-num="3"></span>
<span data-num="4"></span>
<span data-num="5"></span>
</div>
<div class="row">
<span data-num="6"></span>
<span data-num="7"></span>
<span data-num="8"></span-->
</div>
</div>
</article>
<div role="group">
<select aria-label="Select size" required>
<option selected value="3">3x3</option>
<option value="2">2x2</option>
<option value="6">6x6</option>
<option value="7">7x7</option>
<option value="8">8x8</option>
<option value="10">10x10</option>
</select>
<input type="submit" value="New Game">
</div>
</main>
<script src="app.js"></script>
</body>
</html>

View File

@@ -1,50 +0,0 @@
/*.grid {
display:grid;
grid-template-columns : 100px 100px 100px;
grid-template-rows: auto;
grid-gap: 10px;
}*/
.board > div {
display : flex;
}
.board span {
display: inline-block;
vertical-align:baseline;
width: 100px;
height: 100px;
/*padding : 1em;*/
margin : 0.1em;
cursor: pointer;
border: 1px solid #444;
border-radius: 50px;
background: radial-gradient(rgb(150,250,150), #00ee00);
}
.board span.off {
background: #009900;
}
.board span.off:hover {
background: #3AB903;
}
.board span:hover {
background: #3AB903;
background: radial-gradient(rgb(66, 255, 66), #065006);
}
/*
.wrapper {
display : flex;
justify-content: space-around;
}
.wrapper .grid {
flex-basis : auto;
}
*/

View File

@@ -1,163 +0,0 @@
#### Ex3 : modele MVC
Le but est d'écrire une todolist en javascript, en respectant le pattern MVC. Il est important de mener à bout cet exercice, car il nous servira
de fil rouge notamment en ajoutant une api rest et ajax pour la communication avec le service.
<div align="center">
<img src="./img/todo.png">
</div>
Le contrôleur a accès à la vue et au modèle.
##### Le modèle
Cette "classe" (rien à compléter) utilise
l'objet [localStorage](https://developer.mozilla.org/fr/docs/Web/API/Window/localStorage)
pour sauvegarder la todolist.
Chaque todo est un objet json de la forme
```js
{ id : 1 , text : "apprendre le js", done : false }
```
La liste des méthodes publiques de cette classe
```js
/** @brief return the todolist
* @param filter "all" or "active" or "done"
* @return array of todos
*/
getTodos(filter)
/** @brief add (and save) a new todo with todoText
* @param todoText : text of the new todo
*/
add(todoText)
/** @brief delete a todo
* @param id id of the todo
*/
delete(id)
/** @brief update a todo
* @param id id of the todo
*/
edit(id,updatedText)
/** @brief toggle a todo (done<->active)
* @param id id of the todo
* @param updatedText text of the todo
*/
toggle(id)
```
##### La vue
Cette "classe" permet au contrôleur de gérer la vue.
Liste des méthodes publiques
```js
/** @brief change the active tab (all,active or done)
* @param filter the active tab (all, active or done)
*/
setFilterTabs(filter)
/** @brief update the todo list with todos
* @param todos array of todo
*/
renderTodoList(todos)
```
Le contrôleur peut s'abonner (notification de la vue au acontrôleur)
aux événements suivants :
add/delete/edit/toggle todo : avec `bind{Add|Delete|Edit|Toggle}Todo`
Ces méthodes d'abonnement prennent en paramètre une fonction du contrôleur qui est appelé par la vue pour lui notifier
une requête.
```js
/** @brief subscribe to add event
* @param handler function(text)
*/
bindAddTodo(handler)
/** @brief suscribe to delete event
* @param handler function(id)
*/
bindDeleteTodo(handler)
/** @brief suscribe to edit event
* @param handler function(id,text)
*/
bindEditTodo(handler)
/** @brief suscribe to toggle event
* @param handler function(id)
*/
bindToggleTodo(handler)
```
##### Le contrôleur
C'est lui qui gére le routage. Il y a trois urls possibles `index.html/#/{all|active|done}` (listener sur l'évenement
dom `hashchange`.
Liste des méthodes
```js
/** @brief get the todolist from the model
* and use the view to render
*/
filterTodoList()
/** @brief binding function called by the view
* to add a new todo
* @param text text of the new todo
*/
addTodo(text)
/** @brief binding function called by the view
* to delete a todo
* @param id id of the todo
*/
deleteTodo(id)
/** @brief binding function to toggle the state
* of a todo
* @param id id of the todo
*/
toggleTodo(id)
/** @brief binding function to change the text
* of a todo
* @param id id of the todo
* @param changedText new text for the todo
*/
editTodo(id,changedText)
```
Par exemple, lorsque l'utilisateur ajoute une todo :
1. la vue est sensible à l'événement de soumission du formulaire,
2. la fonction reflexe récupére le texte saisie,
3. elle appelle la fonction avec laquelle le contrôleur s'est abonné, en lui passant le texte,
4. la fonction du contrôleur `addTodo` récupére le texte,
5. le contrôleur demande au modèle la création d'une nouvelle todo,
6. le contrôleur demande un rafraichissement de la vue.
#### Travail à faire
- Commpléter la méthode privée dans la vue `#createNewTodoElement` qui permet de créer un
nouvel élément dom représentant une todo. Ce qui est attendu est de la forme
```html
<li class="todo" data-id="1">
<label>
<input type="checkbox">
<span>apprendre un peu de javascript</span>
</label>
<i class="fas fa-trash"></i>
</li>
```
- Compléter la méthode `bindDeleteTodo` de la vue.
- Compléter la méthode `bindToggleTodo` de la vue.
- Compléter la méthode `bindEditTodo` de la vue.

Some files were not shown because too many files have changed in this diff Show More