TP01, TP02 & TP03EX01

This commit is contained in:
Alexis WAMSTER 2024-02-26 19:17:32 +01:00
commit 2cfb5211c3
28 changed files with 1147 additions and 0 deletions

73
TP01/EX1/app.js Normal file
View File

@ -0,0 +1,73 @@
import render from "./modules/langton-renderer-canvas2d";
import Ant from "./modules/Ant.js";
const options = {
antStateColors : ['red','yellow'],
tileStateColors : ['white','black'],
tileSize : 10
};
// For the view
const STEP_INTERVAL = 5;
const BTN_AUTOPLAY_ID = 'autoplay';
const BTN_NEXT_MOVE_ID = 'next-move';
const BTN_RESET_ID = 'reset';
const MOVE_VAL_ID = 'move-value';
const BTN_PLUS_100_ID = 'plus-100';
let autoplayInterval;
let auto=false;
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));
function boucle() {
ant.moveForward();
updateView(ant,canvas,options)
if (auto === true){
setTimeout(boucle, STEP_INTERVAL);
}
}
document.getElementById(BTN_AUTOPLAY_ID).addEventListener('click', () => {
auto = !auto;
boucle();
});
document.getElementById(BTN_PLUS_100_ID).addEventListener('click', () => {
for (let i=0; i<100; i++){
ant.moveForward();
}
updateView(ant,canvas,options)
});
document.getElementById(BTN_NEXT_MOVE_ID).addEventListener('click', () => {
ant.moveForward();
updateView(ant,canvas,options)
})
document.getElementById(BTN_RESET_ID).addEventListener('click', () => {
ant.reset();
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,1)

47
TP01/EX1/index.html Normal file
View File

@ -0,0 +1,47 @@
<!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/bulma@0.9.4/css/bulma.min.css">
<style>
canvas {
position : absolute ;
top : 0;
left : 0;
z-index : -1;
}
.control {
position : absolute ;
top : 0;
left : 0;
width : auto;
}
</style>
</head>
<body>
<div class="control m-6 has-text-centered">
<h4 class="has-text-primary-dark title is-4">
Fourmi de Langton
</h4>
<nav class="m-3">
<button class="button" id="next-move">Next</button>
<button class="button" id="autoplay">Auto</button>
<button class="button" id="plus-100">+100</button>
<button class="button" id="reset">reset</button>
</nav>
<p class="mb-6 is-size-7">
Nombre de mouvements : <span id="move-value"></span>
</p>
</div>
<canvas></canvas>
<script type="module" src="app.js"></script>
</body>
</html>

86
TP01/EX1/modules/Ant.js Normal file
View File

@ -0,0 +1,86 @@
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);
}
reset() {
this.direction = 0;
this.x = Math.floor(this.w/2);
this.y = Math.floor(this.h/2);
this.state = 0;
this.tiles.forEach(el=>el.fill(0));
}
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
this.direction = (this.direction+90)%360;
}
rotateLeft() {
// TODO
this.direction = (this.direction+270)%360;
}
computeNextState()
{
// TODO
if (this.tiles[this.x][this.y]===1){ //noir
if (this.state ===1){
this.state = 0;
this.tiles[this.x][this.y] = 0;
}
else{
this.rotateLeft();
this.tiles[this.x][this.y] = 0;
}
}
else{ // blanc
if (this.state ===1){
this.rotateRight();
this.tiles[this.x][this.y] = 1;
}
else{
this.state = 1;
this.tiles[this.x][this.y] = 1;
}
}
}
}
export default Ant;

View File

@ -0,0 +1,99 @@
/**
* 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;

50
TP01/EX3/array.html Normal file
View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,witdh=device-width">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<script src="graph.js" type="text/javascript"></script>
<script>
window.onload = (()=>{
let array = Array.from({length: 15}, () => -10 + Math.floor(Math.random() * 21));
graph('graph1', array)
graph('graph2', array.map(function(nombre){return nombre+3}))
graph('graph3', array.slice().sort((a,b) => (a-b)))
graph('graph4', array.filter(function(nombre){return (nombre >= 0)}))
})
</script>
</head>
<body class="m-6">
<main class="container">
<section class="columns is-multiline">
<div class="column is-6">
<h2 class="title is-2">Simple Array</h2>
<canvas id="graph1" width="500" height="400"></canvas>
</div>
<div class="column is-6">
<h2 class="title is-2">Add 3 (using map)</h2>
<canvas id="graph2" width="500" height="400"></canvas>
</div>
<div class="column is-6">
<h2 class="title is-2">Sorted</h2>
<canvas id="graph3" width="500" height="400"></canvas>
</div>
<div class="column is-6">
<h2 class="title is-2">Filtered (positives values)</h2>
<canvas id="graph4" width="500" height="400"></canvas>
</div>
</section>
</main>
</body>
</html>

34
TP01/EX3/graph.js Normal file
View File

@ -0,0 +1,34 @@
"use strict";
const colors = [
'#00429d', '#204fa3', '#325da9', '#406aaf', '#4e78b5', '#5a86bb',
'#6694c1', '#73a2c6', '#80b1cc', '#8ebfd1', '#9dced6', '#addcda',
'#c0eade', '#d8f6e1', '#ffffe0'
]
function graph(canvasId, array) {
if (array.length == 0) {
throw "array.length == 0"
}
var min = array.reduce(function(a, b) { return (a < b)? a: b; })
var max = array.reduce(function(a, b) { return (a < b)? b: a; })
var canvas = document.getElementById(canvasId)
var context = canvas.getContext("2d")
context.clearRect(0, 0, canvas.width, canvas.height)
context.beginPath()
context.strokeStyle = "black"
context.moveTo(0, canvas.height / 2)
context.lineTo(canvas.width, canvas.height / 2)
context.stroke()
array.forEach(function(v, i) {
context.fillStyle = colors[(i) % colors.length]
context.fillRect((i + 0.1) * canvas.width / array.length, canvas.height / 2, 0.8 * canvas.width / array.length, v * canvas.height / (min - max) / 2)
context.strokeText(v, (i + 0.4)* canvas.width / array.length, canvas.height /10)
})
}

59
TP01/EX3/minmax.html Normal file
View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://www.iut-fbleau.fr/css/tacit.css">
</head>
<body class="m-6">
<main class="container">
<h2 class="title is-2">Random Array</h2>
<div id="line"></div>
<h2 class="title is-2">Min/Max</h2>
<p>
Min : <span id="min"></span>
</p>
<p>
Max : <span id="max"></span>
</p>
</main>
<script>
function getRandomArray(size,inf,max)
{
// TODO
let i;
let array = [];
for (i=0; i<size; i++){
let x = Math.floor(Math.random() * (max - inf + 1) + inf);
array[i] = x;
}
return array;
}
function minmax(array)
{
// TODO
if (array.length >= 0){
return array.reduce(function(resultat, nombre) {
return{
'min': Math.min(resultat.min, nombre),
'max': Math.max(resultat.max, nombre)
};
},
{
'min': Number.MAX_SAFE_INTEGER,
'max': Number.MIN_SAFE_INTEGER
});
}
}
let array = getRandomArray(50,-100,100)
let minAndMax = minmax(array)
document.getElementById("line").textContent = array
document.getElementById('min').textContent = minAndMax.min
document.getElementById('max').textContent = minAndMax.max
</script>
</body>
</html>

22
TP02/EX01/data.js Normal file
View File

@ -0,0 +1,22 @@
let data = [
{"idStanding":"2282066","intRank":"1","idTeam":"133714","strTeam":"Paris SG","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/rwqrrq1473504808.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WLWWW","strDescription":"Promotion - Champions League (Group Stage)","intPlayed":"18","intWin":"15","intLoss":"1","intDraw":"2","intGoalsFor":"48","intGoalsAgainst":"13","intGoalDifference":"35","intPoints":"47","dateUpdated":"2023-01-12 23:01:12"},
{"idStanding":"2282067","intRank":"2","idTeam":"133822","strTeam":"Lens","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/3pxoum1598797195.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DWDWW","strDescription":"Promotion - Champions League (Group Stage)","intPlayed":"18","intWin":"12","intLoss":"1","intDraw":"5","intGoalsFor":"31","intGoalsAgainst":"13","intGoalDifference":"18","intPoints":"41","dateUpdated":"2023-01-12 23:01:12"},
{"idStanding":"2282068","intRank":"3","idTeam":"133707","strTeam":"Marseille","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/uutsyt1473504764.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WWWWW","strDescription":"Promotion - Champions League (Qualification)","intPlayed":"18","intWin":"12","intLoss":"3","intDraw":"3","intGoalsFor":"36","intGoalsAgainst":"15","intGoalDifference":"21","intPoints":"39","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282069","intRank":"4","idTeam":"133719","strTeam":"Rennes","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/ypturx1473504818.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LWLWD","strDescription":"Promotion - Europa League (Group Stage)","intPlayed":"18","intWin":"10","intLoss":"4","intDraw":"4","intGoalsFor":"35","intGoalsAgainst":"20","intGoalDifference":"15","intPoints":"34","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282070","intRank":"5","idTeam":"133823","strTeam":"Monaco","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/819x3z1655593495.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DWWLW","strDescription":"Promotion - Europa Conference League (Qualification)","intPlayed":"18","intWin":"10","intLoss":"4","intDraw":"4","intGoalsFor":"35","intGoalsAgainst":"25","intGoalDifference":"10","intPoints":"34","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282071","intRank":"6","idTeam":"133715","strTeam":"Lorient","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/sxsttw1473504748.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DWLDL","strDescription":"","intPlayed":"18","intWin":"9","intLoss":"4","intDraw":"5","intGoalsFor":"30","intGoalsAgainst":"26","intGoalDifference":"4","intPoints":"32","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282072","intRank":"7","idTeam":"133711","strTeam":"Lille","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/2giize1534005340.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DDWWD","strDescription":"","intPlayed":"18","intWin":"9","intLoss":"5","intDraw":"4","intGoalsFor":"30","intGoalsAgainst":"24","intGoalDifference":"6","intPoints":"31","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282073","intRank":"8","idTeam":"133713","strTeam":"Lyon","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/blk9771656932845.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DLWDL","strDescription":"","intPlayed":"18","intWin":"7","intLoss":"7","intDraw":"4","intGoalsFor":"27","intGoalsAgainst":"21","intGoalDifference":"6","intPoints":"25","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282074","intRank":"9","idTeam":"134713","strTeam":"Clermont Foot","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/wrytst1426871249.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WWLLD","strDescription":"","intPlayed":"18","intWin":"7","intLoss":"7","intDraw":"4","intGoalsFor":"22","intGoalsAgainst":"26","intGoalDifference":"-4","intPoints":"25","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282075","intRank":"10","idTeam":"133712","strTeam":"Nice","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/msy7ly1621593859.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WLDDW","strDescription":"","intPlayed":"18","intWin":"6","intLoss":"6","intDraw":"6","intGoalsFor":"22","intGoalsAgainst":"20","intGoalDifference":"2","intPoints":"24","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282076","intRank":"11","idTeam":"133934","strTeam":"Stade de Reims","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/xcrw1b1592925946.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WDWDW","strDescription":"","intPlayed":"18","intWin":"5","intLoss":"4","intDraw":"9","intGoalsFor":"21","intGoalsAgainst":"23","intGoalDifference":"-2","intPoints":"24","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282077","intRank":"12","idTeam":"133703","strTeam":"Toulouse","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/3kqxs61547893229.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WWLLL","strDescription":"","intPlayed":"18","intWin":"6","intLoss":"8","intDraw":"4","intGoalsFor":"28","intGoalsAgainst":"33","intGoalDifference":"-5","intPoints":"22","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282078","intRank":"13","idTeam":"134789","strTeam":"Troyes","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/swuwpq1426544753.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LWDLD","strDescription":"","intPlayed":"18","intWin":"4","intLoss":"8","intDraw":"6","intGoalsFor":"29","intGoalsAgainst":"35","intGoalDifference":"-6","intPoints":"18","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282079","intRank":"14","idTeam":"133861","strTeam":"Nantes","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/8r0dab1598797469.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DWDDL","strDescription":"","intPlayed":"18","intWin":"3","intLoss":"6","intDraw":"9","intGoalsFor":"18","intGoalsAgainst":"24","intGoalDifference":"-6","intPoints":"18","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282080","intRank":"15","idTeam":"133709","strTeam":"Montpellier","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/spxtvu1473504783.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LLWDD","strDescription":"","intPlayed":"18","intWin":"5","intLoss":"11","intDraw":"2","intGoalsFor":"28","intGoalsAgainst":"37","intGoalDifference":"-9","intPoints":"17","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282081","intRank":"16","idTeam":"133702","strTeam":"Ajaccio","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/qpxvwy1473505505.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LLWDW","strDescription":"","intPlayed":"18","intWin":"4","intLoss":"11","intDraw":"3","intGoalsFor":"15","intGoalsAgainst":"27","intGoalDifference":"-12","intPoints":"15","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282082","intRank":"17","idTeam":"133704","strTeam":"Brest","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/z69be41598797026.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DLLWL","strDescription":"Relegation - Ligue 2","intPlayed":"18","intWin":"3","intLoss":"10","intDraw":"5","intGoalsFor":"18","intGoalsAgainst":"33","intGoalDifference":"-15","intPoints":"14","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282083","intRank":"18","idTeam":"134788","strTeam":"Auxerre","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/lzdtbf1658753355.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LLLLD","strDescription":"Relegation - Ligue 2","intPlayed":"18","intWin":"3","intLoss":"11","intDraw":"4","intGoalsFor":"16","intGoalsAgainst":"40","intGoalDifference":"-24","intPoints":"13","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282084","intRank":"19","idTeam":"133882","strTeam":"Strasbourg","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/yuxtyy1464540071.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DLLDL","strDescription":"Relegation - Ligue 2","intPlayed":"18","intWin":"1","intLoss":"8","intDraw":"9","intGoalsFor":"22","intGoalsAgainst":"33","intGoalDifference":"-11","intPoints":"12","dateUpdated":"2023-01-12 23:01:13"},
{"idStanding":"2282085","intRank":"20","idTeam":"134709","strTeam":"Angers","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/445gc21622560255.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LLLLL","strDescription":"Relegation - Ligue 2","intPlayed":"18","intWin":"2","intLoss":"14","intDraw":"2","intGoalsFor":"16","intGoalsAgainst":"39","intGoalDifference":"-23","intPoints":"8","dateUpdated":"2023-01-12 23:01:13"}
];

67
TP02/EX01/index.html Normal file
View File

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1,witdh=device-width">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" integrity="sha512-q3eWabyZPc1XTCmF+8/LuE1ozpg5xxn7iO89yfSOd5/oKvyqLngoNGsx8jq92Y8eXJ/IRxQbEC+FGSYxtk2oiw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<!--link rel="stylesheet" href="./style.css"-->
<title>Classement Ligue 1</title>
</head>
<body class="m-6">
<main class="container">
<h3 class="title is-3 has-text-primary-dark">
Classement Ligue 1 de football<span class="tag" id="date"></span>
<div class="block control has-icons-left is-inline-block is-pulled-right">
<input class="input" type="search" placeholder="Equipe" id="myInput">
<span class="icon is-small is-left">
<i class="fas fa-search"></i>
</span>
</div>
</h3>
<table class="table is-fullwidth is-hoverable">
<thead>
<tr>
<th><abbr title="Position">Pos</abbr><a id="sort" onclick="trier()" href="#"><span class="icon"><i class="fas fa-sort"></i></span></a></th>
<th></th>
<th>Team</th>
<th><abbr title="Played">Pld</abbr></th>
<th><abbr title="Won">W</abbr></th>
<th><abbr title="Drawn">D</abbr></th>
<th><abbr title="Lost">L</abbr></th>
<th><abbr title="Goals for">GF</abbr></th>
<th><abbr title="Goals against">GA</abbr></th>
<th><abbr title="Goal difference">GD</abbr></th>
<th><abbr title="Points">Pts</abbr></th>
</tr>
</thead>
<tfoot>
<tr>
<th><abbr title="Position">Pos</abbr></th>
<th></th>
<th>Team</th>
<th><abbr title="Played">Pld</abbr></th>
<th><abbr title="Won">W</abbr></th>
<th><abbr title="Drawn">D</abbr></th>
<th><abbr title="Lost">L</abbr></th>
<th><abbr title="Goals for">GF</abbr></th>
<th><abbr title="Goals against">GA</abbr></th>
<th><abbr title="Goal difference">GD</abbr></th>
<th><abbr title="Points">Pts</abbr></th>
</tr>
</tfoot>
<tbody></tbody>
</table>
</main>
<script src="data.js"></script>
<script src="script.js"></script>
</body>
</html>

71
TP02/EX01/script.js Normal file
View File

@ -0,0 +1,71 @@
let table = document.getElementsByClassName("table")[0];
let trieCroissant = false;
let dat = ["intRank","strTeamBadge","strTeam","intPlayed","intWin","intDraw","intLoss","intGoalsFor","intGoalsAgainst","intGoalDifference","intPoints"];
let recherche = document.getElementById("myInput");
recherche.addEventListener('input', function(){
filtrer(recherche.value.toLowerCase());
});
trier();
function viderTable(){
let listeLigne = table.children;
let i=0;
while (listeLigne.length>i){
if (listeLigne[i].tagName === 'tr'){
table.removeChild(listeLigne[i]);
}
else{
i++;
}
}
}
function remplirTable(donnee=data){
for (let i=0; i<donnee.length; i++){
let ligne = createLine(donnee[i]);
table.appendChild(ligne);
};
}
function createLine(ligne){
let resultat = document.createElement("tr");
for(let i=0; i<dat.length; i++){
let colonne = document.createElement("th");
let contenu;
if (dat[i]==="strTeamBadge"){
contenu = document.createElement("img");
contenu.src = ligne[dat[i]];
}
else{
contenu = document.createTextNode(ligne[dat[i]]);
}
colonne.appendChild(contenu);
resultat.appendChild(colonne);
}
return resultat;
}
function trier(){
trieCroissant = !trieCroissant;
if (trieCroissant === true){
data.sort((a,b)=>a.intRank - b.intRank);
}
else{
data.sort((a,b)=>b.intRank - a.intRank);
}
viderTable();
remplirTable();
}
function filtrer(filtre){
viderTable();
let dataFiltrer = data.filter(function(equipe){
if (equipe.strTeam.toLowerCase().startsWith(filtre)){
return equipe;
}
});
remplirTable(dataFiltrer);
}

32
TP02/EX02/css/style.css Normal file
View File

@ -0,0 +1,32 @@
:focus-visible {outline:none;}
.strike {
text-decoration-line : line-through;
}
#loader.is-loading {
position: fixed;
z-index: 999;
overflow: show;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
#loader.is-loading:after {
animation: spinAround 500ms infinite linear;
border: 2px solid hsl(0deg, 0%, 86%);
border-radius: 9999px;
border-right-color: transparent;
border-top-color: transparent;
content: "";
display: block;
position: relative;
top: calc(50% - 5em);
left: calc(50% - 5em);
width: 10em;
height: 10em;
border-width: 0.25em;
}

48
TP02/EX02/index.html Normal file
View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Todo</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" integrity="sha512-q3eWabyZPc1XTCmF+8/LuE1ozpg5xxn7iO89yfSOd5/oKvyqLngoNGsx8jq92Y8eXJ/IRxQbEC+FGSYxtk2oiw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="container content is-max-desktop p-4">
<div id="loader"></div>
<div class="has-text-centered">
</div>
<!-- formulaire pour la saisie -->
<form id="add_form" class="block">
<p class="control has-icons-left is-expanded">
<input autocomplete="off" id="input_todo" class="input is-large is-expanded" type="text" placeholder="Enter Todo">
<span class="icon is-left">
<i class="fas fa-plus" aria-hidden="true"></i>
</span>
</p>
</form>
<!-- filtrage de l'affichage -->
<div id="todos_filter" class="tabs is-small is-centered">
<ul>
<li class="is-active"><a href="#/" id="all">All</a></li>
<li><a href="#/active" id="active">Active</a></li>
<li><a href="#/done" id="done">Done</a></li>
</ul>
</div>
<!-- Affichage des todos -->
<section id="todos_list">
</section>
</body>
<script type="module" src="./js/app.js"></script>
</html>

6
TP02/EX02/js/app.js Normal file
View File

@ -0,0 +1,6 @@
import Controller from './controller.js'
import Model from './model.js'
import View from './view.js'
const app = new Controller(new Model(),new View())

View File

@ -0,0 +1,54 @@
export default class Controller {
constructor(model, view) {
this.model = model
this.view = view
this.filter = "all"
this.view.bindAddTodo(this.addTodo.bind(this))
this.view.bindDeleteTodo(this.deleteTodo.bind(this))
this.view.bindToggleTodo(this.toggleTodo.bind(this))
this.view.bindEditTodo(this.editTodo.bind(this))
/** Routage **/
this.routes = ['all','active','done'];
/** Routage **/
window.addEventListener("load",this.routeChanged.bind(this));
window.addEventListener("hashchange",this.routeChanged.bind(this));
}
routeChanged(){
let route = window.location.hash.replace(/^#\//,'');
this.filter = this.routes.find( r => r === route) || 'all';
this.filterTodoList();
}
filterTodoList () {
let todos = this.model.getTodos(this.filter)
this.view.renderTodoList(todos)
this.view.setFilterTabs(this.filter)
}
addTodo(text) {
let todo = this.model.add(text)
this.filterTodoList()
}
deleteTodo(id) {
this.model.delete(parseInt(id))
this.filterTodoList()
}
toggleTodo(id) {
this.model.toggle(parseInt(id))
this.filterTodoList()
}
editTodo(id, text) {
this.model.edit(parseInt(id),text)
this.filterTodoList()
}
}

71
TP02/EX02/js/model.js Normal file
View File

@ -0,0 +1,71 @@
const todos = [
{
id : 1,
text : "apprendre le javascript",
done : false
},
{
id : 2,
text : "Faire des maths",
done : false
}]
export default class Model {
constructor() {
//this.todos = JSON.parse(localStorage.getItem('todos')) || []
this.todos = JSON.parse(localStorage.getItem('todos')) || todos
}
_commit(todos) {
localStorage.setItem('todos', JSON.stringify(todos))
}
getTodos(filter){
if (filter == "active")
return this.todos.filter(todo => !todo.done)
if (filter == "done")
return this.todos.filter(todo => todo.done)
return this.todos
}
add(todoText) {
const todo = {
id: this.todos.length > 0 ? this.todos[this.todos.length - 1].id + 1 : 1,
text: todoText,
done : false,
}
this.todos.push(todo)
this._commit(this.todos)
return todo
}
edit(id, updatedText) {
let todo = this.todos.find(t => t.id === id)
todo.text = updatedText
// this.todos = this.todos.map(todo =>
// todo.id === id ? { id: todo.id, text: updatedText, done: todo.done} : todo
// )
this._commit(this.todos)
}
delete(id) {
this.todos = this.todos.filter(todo => todo.id !== id)
this._commit(this.todos)
}
toggle(id) {
let todo = this.todos.find(t => t.id === id)
todo.done = !todo.done
//this.todos = this.todos.map(todo =>
// todo.id === id ? { id: todo.id, text: todo.text, done: !todo.done } : todo
//)
this._commit(this.todos)
}
}

115
TP02/EX02/js/view.js Normal file
View File

@ -0,0 +1,115 @@
export default class View {
constructor() {
this.form = document.querySelector("#add_form")
this.input = document.querySelector("#input_todo")
this.list = document.querySelector("#todos_list")
this.tabs = document.querySelector("#todos_filter")
this.loader = document.querySelector("#loader")
}
_getTodo() {
return this.input.value
}
_resetInput() {
this.input.value = ''
}
_getNewTodoElement(todo){
let div = document.createElement("div")
div.classList.add("box","is-flex","is-align-items-center","m-2")
div.dataset.id = todo.id
let input = document.createElement("input")
input.type = "checkbox"
input.classList.add("mr-3")
let span = document.createElement("p")
span.classList.add("mb-0","is-size-3","mr-auto")
span.textContent = todo.text
span.setAttribute("contenteditable",true)
let button = document.createElement("button")
button.classList.add("delete","is-large")
if (todo.done){
span.classList.add("strike")
input.checked = true
}
div.append(input,span,button)
return div
}
setLoader(){
this.loader.classList.add("is-loading")
}
unsetLoader(){
this.loader.classList.remove("is-loading")
}
setFilterTabs(filter){
let li = this.tabs.querySelectorAll("li")
li.forEach( tab => {
tab.classList.remove("is-active")
})
let active = this.tabs.querySelector(`#${filter}`)
active.parentNode.classList.add("is-active")
}
renderTodoList(todos) {
let list = new DocumentFragment()
for (let todo of todos){
list.appendChild(this._getNewTodoElement(todo))
}
this.list.replaceChildren(list)
}
/** Abonnements événements **/
bindAddTodo(handler) {
this.form.addEventListener("submit", (e=>{
e.preventDefault()
let text = this._getTodo()
handler(text)
this._resetInput()
}))
}
bindDeleteTodo(handler) {
// TODO
this.list.addEventListener("click", (e) => {
let selection = e.target;
if (selection.tagName === "BUTTON"){
let id = selection.parentNode.dataset.id;
handler(id);
}
});
}
bindEditTodo(handler) {
this.list.addEventListener("keydown", (e) => {
let selection = e.target;
if (selection.tagName === "P" && e.key === "Enter"){
let id = selection.parentNode.dataset.id;
let texte = selection.textContent;
handler(id, texte);
}
});
}
bindToggleTodo(handler) {
this.list.addEventListener("change", (e) => {
let selection = e.target;
if (selection.tagName === "INPUT"){
let id = selection.parentNode.dataset.id;
handler(id);
}
});
}
}

26
TP03/EX01/cookie.html Normal file
View File

@ -0,0 +1,26 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Cookie clicker</title>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="container">
<h1>Cookie clicker</h1>
<figure>
<img id="cookie"src="img/cookie.png" alt="cookie">
<span id="score">0</span>
</figure>
<button id="btnStart">start</button>
<p id="meme" class="hidden">
<img src="img/memee.png" alt="memee" width="64" height="64">
<span id="temps"></span>
</p>
</div>
<script type="text/javascript" src="./js/game.js"></script>
</body>
</html>

BIN
TP03/EX01/css/img/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

63
TP03/EX01/css/style.css Normal file
View File

@ -0,0 +1,63 @@
@import url(https://fonts.googleapis.com/css?family=Kavoon);
body {
background-image: url("img/bg.jpg");
background-repeat: repeat;
font-family: Kavoon;
font-size: 24px;
text-align: center;
color: white;
}
.container {
max-width: 320px;
margin: auto;
}
h1 {
font-size: 28px;
background-color: rgba(0, 0, 0, 0.25);
padding: 10px 40px 10px 40px;
border-radius: 10px;
}
figure {
position: relative;
margin: 0;
}
figure > span {
position: absolute;
top: 25px;
right: 50px;
border-radius: 21px;
height: 42px;
width: 56px;
background-color: #f4d03f;
box-shadow: 4px 4px 4px black;
padding-top: 9px;
}
button {
display: block;
width: 100%;
font-family: Kavoon;
font-size: 24px;
background-color: white;
padding: 9px;
border-radius: 10px;
border-width: 0;
}
p {
text-align: left;
}
img[alt="GrandMa"] {
float: left;
}
.hidden {
display: none;
}

BIN
TP03/EX01/img/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
TP03/EX01/img/cookie.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
TP03/EX01/img/memee.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

48
TP03/EX01/js/game.js Normal file
View File

@ -0,0 +1,48 @@
var btnStart = document.getElementById("btnStart");
var scoreView = document.getElementById("score");
var tempsView = document.getElementById("temps");
var meme = document.getElementById("meme");
var cookie = document.getElementById("cookie");
var score;
var temps;
var isPlayed=false;
var texte = " seconds left!";
var tailleCookieInitiale = cookie.naturalWidth;
btnStart.addEventListener('click', start);
cookie.addEventListener('click', clicCookie);
tempsView.style.color = "red";
function start(event){
if (!isPlayed){
meme.style.display="block";
cookie.style.width = tailleCookieInitiale+"px";
temps = 15;
score = 0;
scoreView.textContent = score;
isPlayed = true;
tempsView.textContent = temps+texte;
setTimeout(second,1000);
}
}
function clicCookie(event){
if (isPlayed){
score ++;
cookie.style.width = (tailleCookieInitiale+score)+"px";
scoreView.textContent = score;
}
}
function second(){
temps --;
tempsView.textContent = temps+texte;
if (temps <= 0){
isPlayed = false;
meme.style.display="none";
}
else{
setTimeout(second,1000);
}
}

11
TP03/EX02/css/style.css Normal file
View File

@ -0,0 +1,11 @@
img{
cursor:pointer;
}
#gagne,#perdu,.hidden{
display : none;
}
.progress::-webkit-progress-value {
transition: width 0.5s ease;
}

BIN
TP03/EX02/images/off.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
TP03/EX02/images/on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

1
TP03/EX02/js/memory.js Normal file
View File

@ -0,0 +1 @@
// TODO

64
TP03/EX02/memory.html Normal file
View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="initial-scale=1,witdh=device-width">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<link rel="stylesheet" href="./css/style.css">
<script src="./js/memory.js"></script>
<title>Memory</title>
</head>
<body class="m-4">
<main class="container">
<h1 class="title is-1 has-text-primary">Memory</h1>
<div class="columns">
<div class="column is-6">
<div class="columns">
<div class="column">
<img src="./images/off.png" alt="" />
<img src="./images/off.png" alt="" />
<img src="./images/off.png" alt="" />
</div>
<div class="column">
<img src="./images/off.png" alt="" />
<img src="./images/off.png" alt="" />
<img src="./images/off.png" alt="" />
</div>
<div class="column">
<img src="./images/off.png" alt="" />
<img src="./images/off.png" alt="" />
<img src="./images/off.png" alt="" />
</div>
</div>
</div>
<div class="column is-6">
<h3 class="title is-3 has-text-primary">Règles</h3>
<p class="block is-size-4">
Pendant une seconde, vous verrez l'état de l'ensemble
des ampoules, puis elles seront éteintes. Vous devrez
alors cliquer sur celles qui étaient allumées.
</p>
<button class="block button is-info">COMMENCER</button>
<progress id="temps" class="progress is-primary" value="100" max="100"></progress>
<!--div id="temps">10</div-->
<div class="notification is-danger is-size-4 p-4" id="perdu">
<p>Perdu ! </p>
</div>
<div class="notification is-success is-size-4 p-4" id="gagne">
<p>Gagné ! </p>
</div>
</div>
</div>
</main>
</body>
</html>