Compare commits

...

3 Commits

Author SHA1 Message Date
EmmanuelTiamzon 2b977bda34 update 2026-05-12 12:30:20 +02:00
EmmanuelTiamzon d66467a7f6 update 2026-04-14 17:29:49 +02:00
EmmanuelTiamzon dbc0fbd946 ajout tp2mvc, tp3 et update des tp 1 et 2 2026-04-14 12:28:43 +02:00
20 changed files with 2274 additions and 85 deletions
+22
View File
@@ -0,0 +1,22 @@
# TP1
## Ex1
1. Avec convert ou magick ou magick convert on fait :
```shell
magick Tux.xvg Tux.ppm
```
2. avec la commande head je prends les 3 premières lignes de Tux.ppm et les redirige vers header.txt
```shell
head -n 3 Tux.ppm >> header.txt
```
3. Mettre tout le fichier ppm sauf les 3 premières lignes dans un fichier body.bin
```shell
tail +3 Tux.ppm >> body.bin
```
4. Chiffrer avec openssl en AES-ECB le fichier .bin
```shell
```
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 49 KiB

File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
P6
216 256
65535
@@ -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>
-23
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;
}
+6 -7
View File
@@ -48,15 +48,14 @@ class Ant {
}
computeNextState() {
if(this.tiles[this.x][this.y] === 1) { //On vérifie si la prochaine case est noire
//On fait en sorte à ce qu'elle soit repeinte en blanc et tourne de 90° à gauche.
if(this.tiles[this.x][this.y] === 1) {
this.tiles[this.x][this.y] = 0;
this.rotateLeft();
} else { //Dans ce cas si la prochaine case est blanche
// On fait en sorte à ce qu'elle soit repeinte en noir et tourne de 90° à droite.
this.tiles[this.x][this.y] = 1;
this.rotateRight();
}
} else {
this.tiles[this.x][this.y] = 1;
this.rotateRight();
}
}
}
export default Ant;
+91
View File
@@ -0,0 +1,91 @@
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']
}
];
// Question 1 :
function filterOldPeople(customers) {
customers.filter(returnOldPeople);
}
function returnOldPeople(customer) {
return customer.age > 60;
}
let oldCustomers = filterOldPeople(customers);
//console.log(oldCustomers);
// Question 2 :
function fullName(customer) {
customer.full_name = customer.f_name +" "+ customer.l_name;
}
customers.forEach(fullName);
//console.log(customers);
//Question 3 :
function isUnderTen(customer) {
return customer.age < 10;
}
customers.some(isUnderTen);
+28 -7
View File
@@ -26,13 +26,16 @@ function peep() {
const time = randomTime(1000, 1500);
const hole = randomHole(holes);
// TODO
const mole = hole.querySelector('.mole');
mole.classList.add('up');
mole.classList.remove('whacked');
setTimeout(() => {
// TODO
//
}}, time);
mole.classList.remove('up');
if(!timeUp) {
peep();
}
}, time);
}
function startGame() {
@@ -40,13 +43,31 @@ function startGame() {
score = 0;
timeUp = false;
// TODO
moles.forEach(mole => {
mole.classList.remove('up');
mole.classList.remove('whacked');
});
peep();
setTimeout(()=>{
timeUp = true;
}, duration * 1000)
}
function bonk(e) {
if(!this.classList.contains('up')) {
return;
}
// TODO
score ++;
scoreBoard.textContent = score;
this.classList.remove('up');
this.classList.add('whacked');
setTimeout(()=>{
this.classList.remove('whacked');
}, 800);
}
moles.forEach(mole => mole.addEventListener('click', bonk));
+6 -6
View File
@@ -4,7 +4,7 @@ body {
align-items: center;
height: 100vh;
background-color: #f0f0f0;
/* font-family: Arial, sans-serif;*/
font-family: Arial, sans-serif;
}
.game {
@@ -24,7 +24,7 @@ body {
background : radial-gradient(rgb(150,250,150), #00ee00);
/* background-color: red;/*#8b4513;*/
/* background-image : url('img/mole2.png');*/
/*background-image : url('img/mole2.png');*/
position: relative;
border-radius: 50%;
margin: 10px;
@@ -43,9 +43,9 @@ body {
}
.mole.up img{
/* background-image : url('img/mole2.png');
background-image : url('img/mole2.png');
background-size:contain;
background-repeat: no-repeat;*/
background-repeat: no-repeat;
width:90px;
height:90px;
@@ -54,9 +54,9 @@ body {
.mole.whacked img {
content: url('img/mole-whacked.png');
/* background-image : url('img/mole-whacked.png');
background-image : url('img/mole-whacked.png');
background-size:contain;
background-repeat: no-repeat;*/
background-repeat: no-repeat;
width:90px;
height:90px;
+84
View File
@@ -0,0 +1,84 @@
#### Ex1 : modele MVC et pattern strategy
> Stratégie est un patron de conception comportemental qui permet de définir une
> famille dalgorithmes, de les mettre dans des classes séparées et de rendre
> leurs objets interchangeables. (source wikipédia)
Le but est de réaliser ce pattern de conception dans le jeu très simple du chifoumi.
<div align="center">
<img src="./img/chifoumi.png">
</div>
Pour l'instant, le jeu utilise le pattern MVC. Le modèle, qui calcule le coup de l'ordinateur utilise
un tirage aléatoire. On veut pouvoir utilisé d'autres méthodes, qui utilisent l'historique des coups
joués par le joueur.
1. Modifiez le modèle et la vue pour que le jeu affiche le pourcentage de victoires, matchs nuls et défaites du joueur depuis le début
de la partie.
On veut maintenant séparer la façon dont l'ordinateur choisit son coup de la logique du jeu. Le modèle utilisera
une stratégie donnée.
2. Créez un sous-répétoires `stratégies` dans lequel on stokera les différentes stratégies disponibles.
Les différentes stratégies réaliseront l'interface
```js
getChoice(playerHistory)
```
qui calcule le coup de l'ordinateur, en fonction de l'historique des différents coups du joueur.
3. Ecrivez 3 stratégies simples `RandomStrategy.js` (stratégie initiale), `CopyPlayerStrategy.js`
(joue le même coup que le joueur) `CounterMostUsedStrategy.js` (joue le coup le plus joué par le joueur) :
Chaque fichier implémente la stratégie correspondante sous la forme :
```js
export default class RandomStrategy {
getChoice(playerHistory) {
....
}
}
```
4. Mettez à jour le modèle pour qu'il puisse utiliser une stratégie donnée.
5. testez dans le main.
#### Ajout d'une stratégie
On va ajouter une stratégie markovienne d'ordre 1. On fait
l'hyptohése que le coup du joueur dépend de son coup précedent (ordre 1).
On met à jour au fur et à mesure la matrice de transitions entre
les coups joué par le joueur. Par exemple,
```js
{
rock: { rock: 2, paper: 5, scissors: 1 },
paper: { rock: 1, paper: 3, scissors: 4 },
scissors: { rock: 6, paper: 1, scissors: 2 }
}
```
signifie qu'après paper, le joueur a joué 1 fois rock, 3 fois paper, et 4 fois scissors.
On se sert de la matrice pour contrer la prédiction.
5. Écrivezz cette stratégie, et testez la.
#### Stratégie mixte
Le but est d'implanter une stratégie mixte. On se donne une probabilité `p`.
- la stratégie markovienne est jouée avec la probabilité `p`.
- la stratégie aléatoire est jouée avec la probabilité `1-p`
Écrivez la stratégie mixte, et testez.
#### Stratégie adaptative
La probabilité `p` dépend du score. On l'adapte au fur et à mesure. Si on gagne beaucoup (trop),
on joue au hasard, sinon avec Markov.
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

+41
View File
@@ -0,0 +1,41 @@
.game {
}
.choices{
display : flex;
align-items:stretch;
height:8em;
}
.choices > span:nth-child(2) {
margin-left:3em;
}
.choices span i{
font-size: 2em;
cursor: pointer;
border: none;
margin-right:0.25em;
transition: transform 0.2s, color 0.2s;
}
#player,#computer{
font-size: 3em;
border: none;
margin-right:0.25em;
}
.choices span i:hover {
color:#398712
}
#player {
color:#398712
}
#computer {
color:#D93526;
}
+40
View File
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Pierre Feuille Ciseaux</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<main>
<h1>
Pierre - Feuille - Ciseaux
</h1>
<div class="choices">
<span>
<i data-choice="rock" class="far fa-hand-rock"></i>
<i data-choice="paper" class="far fa-hand-paper"></i>
<i data-choice="scissors" class="far fa-hand-scissors"></i>
</span>
<span>
<span id="player"></span>
<span id="computer"></span>
</span>
</div>
<div class="game">
<p id="score"></p>
<p id="result"></p>
</div>
</main>
<script type="module" src="js/main.js"></script>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
export default class GameController {
constructor(model, view) {
this.model = model;
this.view = view;
this.view.bindPlay(this.handlePlay);
this.view.displayScore(this.model.getScore());
}
handlePlay = (playerChoice) => {
const computerChoice = this.model.getComputerChoice();
const result = this.model.getResult(playerChoice, computerChoice);
this.view.displayResult(playerChoice, computerChoice, result);
this.view.displayScore(this.model.getScore());
}
}
+9
View File
@@ -0,0 +1,9 @@
import GameModel from "./model.js";
import GameView from "./view.js";
import GameController from "./controller.js";
const app = new GameController(
new GameModel(),
new GameView()
);
+29
View File
@@ -0,0 +1,29 @@
export default class GameModel {
constructor() {
this.choices = ["rock", "paper", "scissors"];
this.score = { player: 0, computer: 0};
}
getComputerChoice() {
const index = Math.floor(Math.random() * this.choices.length);
return this.choices[index];
}
getResult(player, computer) {
if (player === computer) return "égalité";
if (
(player === "rock" && computer === "scissors") ||
(player === "paper" && computer === "rock") ||
(player === "scissors" && computer === "paper")
) {
this.score.player++;
return "gagné";
}
this.score.computer++;
return "perdu";
}
getScore() {
return this.score;
}
}
+50
View File
@@ -0,0 +1,50 @@
export default class GameView {
#icons = {
"rock" : "far fa-hand-rock",
"paper" : "far fa-hand-paper",
"scissors" : "far fa-hand-scissors"
}
constructor() {
this.resultEl = document.getElementById("result");
this.scoreEl = document.getElementById("score");
this.buttons = document.querySelectorAll(".choices span i");
this.player = document.getElementById("player");
this.computer = document.getElementById("computer");
}
bindPlay(handler) {
this.buttons.forEach(button => {
button.addEventListener("click", () => {
handler(button.dataset.choice);
});
});
}
displayResult(player, computer, result) {
let i = document.createElement("i");
i.classList.add(...this.#icons[player].split(' '))
this.player.replaceChildren(i)
i = document.createElement("i");
i.classList.add(...this.#icons[computer].split(' '))
this.computer.replaceChildren(i)
this.resultEl.innerHTML =
`Joueur <i class="${this.#icons[player]}"></i>, ordinateur <i class="${this.#icons[computer]}"></i> → ${result}`;
}
displayScore(score) {
let winRate = ((score.player * 100 / score.count) || 0).toFixed(2)
let lossRate = ((score.computer * 100 / score.count) ||0).toFixed(2)
let drawRate = (100 - winRate - lossRate).toFixed(2)
this.scoreEl.textContent =
`Score — Joueur: ${score.player} | Ordinateur: ${score.computer}`;
}
}
Submodule
+1
Submodule DEV.4.2 added at 5573c92520