-
Notifications
You must be signed in to change notification settings - Fork 0
/
tp2.html
404 lines (358 loc) · 24.6 KB
/
tp2.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
<html>
<head>
<meta charset="UTF-8"/>
<link rel="stylesheet" href="style.css">
<title>JavaScript survivor's guide: second training !</title>
<script type='text/javascript'>
// To show he solution to an exercise
function showSolution(solutionId) {
document.getElementById('solution'+solutionId).style.display = 'inline-block';
}
// To evaluate "simple" JS code extract and output the result in a simple div
function runProgram(pgmId) {
var UI=document.getElementById('program'+pgmId).value;
document.getElementById('result'+pgmId).innerHTML= eval(UI);
}
var chessSymbols = new Image();
chessSymbols.src = 'chess.png';
chessSymbols.onload = function() {
console.info("Chess symbols loaded !");
//drawGrid(0,0, canvas.width, canvas.height, 8, 8);
};
</script>
</head>
<body>
<h1>Les joies de la création d'objets et de la programmation fonctionnelle</h1>
<p>
La création d'objets en JS peut s'effectuer de multiples façons. L'élément le plus surprenant, pour des développeurs habitués à des langages objets basés sur la définition de classe, est très sûrement la construction d'objets par prototypage. Dans ce type de langage, la définition des objets n'est pas obtenue par instanciation d'une description générique (la classe), mais est le résultat de la description directe des propriétés (attributs et méthodes) de l'objet. Nous allons explorer dans un premier temps les mécanismes les plus courants pour définir des objets en JS avant d'explorer quelques traitement classiques en programmation fonctionnelle.
</p>
<h2>Création d'objets en JavaScript</h2>
<p>Un objet en JavaScript est un ensemble de propriétés. Une propriété se présente sous la forme d'un couple <tt>(clé, valeur)</tt>. Lorsque la valeur est une fonction, cela correspond à la définition d'une méthode de l'objet, lorsque cela n'est pas une fonction, cela correspond à la définition d'un attribut. Les propriétés d'un objet sont accessibles soit par la notation pointé (objet.propriété) soit via un sélecteur (objet['propriété']). Le sélecteur est pratique lorsque les propriétés contiennent des caractères particuliers comme l'espace.</p>
<p>
Comme vu en cours, on peut exploiter trois approches principales pour la création d'objets en JavaScript: le singleton, le constructeur et l'usine à objets. Nous allons explorer ces trois approches afin de bien comprendre leurs différences et les situations dans lesquelles une approche est plus appropriée que les autres.
</p>
<h3>Création d'un object "directement" (<i>object literal/singleton</i>)</h3>
<p>La première approche est utile lorsque vous n'avez pas besoin de manipuler plusieurs instances d'un objet. Dans ce cas, vous pouvez créer facilement un <i>singleton</i> en énumérant tout simplement les propriétés de votre objet. Dans l'exemple ci-dessous, on crée un objet possédant trois propriétés: un nom, une date et une taille.</p>
<div class="code">
<pre>
var totoro = {
name: 'となりのトトロ',
birthday: '16/04/1988',
height: 356,
};
</pre>
</div>
<p>
Copiez/collez la déclaration ci-dessus dans la console JavaScript de Chromium. Explorez maintenant ce nouvel objet à l'aide de <tt>console.dir(totoro)</tt>. Vous devriez visualiser la définition de cet objet et obtenir ceci:
</p>
<img src="totoro1.png" width='300px' style='align: center' />
<p>Comme vous le constatez, cet objet est de type <tt>Object</tt> et possède les trois propriétés définies lors de sa déclaration. Par contre, on observe une propriété au nom un peu surprenant <tt>__proto__</tt>, aussi de type <tt>Object</tt>. Explorez un peu cette propriété pour découvrir que c'est une référence au prototype de cet objet</p>
<img src="totoro2.png" width='600px' style='align: center' />
<p>
Cet objet correspond à l'objet dont nous avons hérité par défaut, le type <tt>Object</tt> ! On ne va pas entrer trop dans les détails de cet objet pour l'instant. Retenons simplement que le type de notre instance <tt>totoro</tt> est <tt>Object</tt> et que cette information est défini dans l'attribut "caché" <tt>__proto__</tt>.
</p>
<h3>Création d'un object à partir d'un constructeur</h3>
<p>
Un objet tel que <tt>totoro</tt> est ce que l'on appelle un singleton, c'est-à-dire une instance unique d'un type donné (ce que vous construisez avec un constructeur privé en Java). Cela peut servir, mais lorsque l'on souhaite créer plusieurs instances de même type, il est nécessaire de passer par un autre mécanisme de construction d'objet reposant sur la notion de constructeur. Pour cela, on définit dans un premier temps une fonction correspondant au constructeur de l'objet, puis dans un second temps, on utilise l'opérateur <tt>new</tt> afin d'instancier de nouveaux objets de ce type.
</p>
<p>Tapez les commandes ci-dessous dans votre console afin de produire un résultat similaire:</p>
<img src="titiri1.png" width='800px' style='align: center' />
<p>
Si vous observez attentivement la structure de cet objet, vous remarquerez qu'une chose intéressante s'est produite: cet objet n'est plus de type <tt>Object</tt> mais de type <tt>Manga</tt> ! Le fait d'instancier l'objet avec l'opérateur <tt>new</tt> et le constructeur <tt>Manga</tt> a induit sa création comme une instance du type <tt>Manga</tt>. Après tout, il est nécessaire en Java que le constructeur soit du même nom que la classe, on pourrait donc estimer que c'est le constructeur qui nomme la classe ;) Deuxième élément intéressant, vous remarquez qu'un attribut <tt>constructor</tt> est défini au niveau du protoype (<tt>__proto__</tt>) de notre objet <tt>titiri</tt> et que cet attribut référence la fonction <tt>Manga</tt>, c'est-à-dire notre constructeur. Dernier élément, moins surprenant cette fois, le type <tt>Manga</tt> hérite bien du type de base <tt>Object</tt>.
</p>
<p>Nous allons maintenant modifier notre objet afin de lui ajouter une méthode. Définissez la méthode hi() qui retourne <tt>I'm トトロ</tt> en ajoutant une propriété à <tt>titiri</tt>.
</p>
<img src="titiri2.png" width='800px' style='align: center' />
<!--
var Manga = function(name, birthday, height) { this.name = name; this.birthday = birthday; this.height = height; };
var titiri = new Manga('トトロ', '07/07/707', 128);
titiri.hi = function(){ return 'Hi '+this.name; };
-->
<p>
<ul>
<li>Que se passe-t-il lorsque vous invoquez la méthode <tt>hi()</tt> sur <tt>titiri</tt> ?</li>
<li>Créez une nouvelle instance de <tt>Manga</tt> appelée <tt>tuturu</tt> (avec les valeurs que vous voulez) puis appeler sa méthode <tt>hi</tt>. Que se passe-t-il ?</li>
<li>Essayez de comprendre à l'aide d'un <tt>console.dir(tuturu)</tt>.</li>
</ul>
En fait, nous avons ajouté la fonction <tt>hi</tt> directement à l'instance <tt>titiri</tt>, pas à son prototype ! Du coup, lorsque l'on crée une autre instance, cette dernière étant créée à partir du constructeur ne récupère que les attributs définis dans ce dernier. Par contre, si nous avions ajouté notre fonction au prototype <tt>__proto__</tt> la fonction aurait été accessible depuis toutes les instances de <tt>Manga</tt>. Pour vous en assurer, ajoutez une méthode <tt>ho</tt> faisant la même chose que <tt>hi</tt> mais en l'ajoutant cette fois au prototype de <tt>Manga</tt> à l'aide de la syntaxe suivante: <tt>Manga.prototype.ho = function(){return 'Hi '+this.name;}</tt>, puis invoquez là. Voilà qui est plus pratique ;)
</p>
<h3>Création d'un object via <tt>Object.create</tt></h3>
<p>
Une dernière manière possible pour créer un objet consiste à passer par une <it>usine</it> (<it>factory</it>) pour créer un nouvel objet. La principale différence avec l'approche par constructeur est justement qu'il est possible de créer un nouveau type à partir d'un objet existant mais sans avoir à exécuter le constructeur. Un autre aspect plus technique permet de définir des propriétés à la création en spécifiant des modificateurs tels que des accesseurs, des constantes, si la propriété est énumérable ...
</p>
<p>Reprenons notre type <tt>Manga</tt> et créons une instance via une <it>usine</it> plutôt qu'à partir de l'opérateur <tt>new</tt>. Pour cela, on utiliser <tt>Object.create</tt> avec comme paramètre le prototype que l'on souhaite utiliser comme prototype pour le nouvel object créé.
</p>
<div class="code">
<pre>
var Manga = function(name, birthday, height) {
this.name = name; this.birthday = birthday; this.height = height; };
var titiri = new Manga('トトロ', '07/07/707', 128);
Manga.prototype.hi = function(){ return 'Hi '+this.name; };
var titiri2 = Object.create(Manga.prototype);
titiri.hi();
titiri2.hi();
</pre>
</div>
<p>Exécutez les lignes de code données ci-dessus dans la console JavaScript. Comme l'illustre les résultats des appels à la fonction <tt>hi</tt> sur les deux objets, on vérifie bien que le constructeur n'ayant pas été invoqué lors de la création de <tt>titiri2</tt>, ses attributs n'ont ainsi pas été initialisés (et donc pas créés comme l'illustre la figure ci-dessous !). En effet, lorsque l'opérateur <tt>new</tt> est utilisé, un certain nombre d'opérations spécifiques sont effectuées:
<ul>
<li>une instance est créée et son prototype est réglé avec la propriété <tt>prototype</tt> du constructeur,</li>
<li>le constructeur est ensuite invoquée avec le <tt>this</tt> défini comme étant l'instance en cours de création,</li>
<li>si la constructeur ne retourne pas de valeur, <tt>this</tt> est retourné par défaut.</li>
</ul>
Si l'on souhaite obtenir un résultat similaire avec <tt>Create.object</tt>, il est nécessaire d'appeler explicitement le constructeur défini dans le prototype <tt>Manga</tt>, ce qui déclenchera la création des attributs:
</p>
<img src="titiri3.png" width='800px' style='align: center' />
<p>En guise de conclusion, il faut être très attentif à ce que l'on fait lorsque l'on créé des objets en JavaScript car selon la méthode employée, on obtient des résultats assez différents !
</p>
<h3>Un peu d'héritage dans un langage à prototype</h3>
<p>Maintenant que nous connaissons différents procédés pour construire nos objets, nous allons étudier la création de lien d'héritage entre objets. En fait, en utilisant l'opérateur <tt>new</tt>, nous avons vu que le lien d'héritage est créé au moment de l'instanciation avec cet opérateur. Lorsqu'un attribut ou une méthode est invoquée sur un objet, elle est d'abord recherchée sur cet objet et si elle n'est pas trouvée, la recherche se poursuit au niveau de son prototype, et ce récursivement jusqu'à atteindre <tt>Object</tt>.
</p>
<p>Explorons cela concrètement en définissant un type <tt>Animal</tt> que nous spécialiserons ensuite en type <tt>Dog</tt>.
<div class="code">
<pre>
var Animal = function () {
this.name = 'unknown';
this.getName = function () {
return this.name;
}
this.talk = function () {
return '...';
}
};
</pre>
</div>
Le type <tt>Dog</tt> va surcharger la méthode <tt>talk</tt> et définir un attribut supplémentaire privé (en ne l'associant pas à <tt>this</tt> !):
<div class="code">
<pre>
var Dog = function () {
var private = 42;
this.name = "Bello";
this.talk = function () {
return 'WOUF WOUF !';
}
};
</pre>
</div>
Il est maintenant possible de définir le lien d'héritage en réglant le prototype de <tt>Dog</tt> à <tt>Animal</tt>.
<div class="code">
<pre>
// Dog spécialise Animal
Dog.prototype = new Animal();
var dog = new Dog();
console.log(
"Is dog an instance of Dog? ", dog instanceof Dog, "\n",
"Is dog an instance of Animal? ", dog instanceof Animal, "\n",
dog.talk() +"\n", // Should be: "WOUF WOUF !"
dog.getName() +"\n", // Should be: "Bello"
dog.private +"\n" // Should be: 'undefined'
);
</pre>
</div>
</p>
<h2>Mise en pratique avec la réalisation (partielle) d'un jeu d'échecs</h2>
<p>Nous allons maintenant nous intéresser à la modélisation d'une partie de jeu d'échecs. Cela nous permettra de nous approprier les notions d'héritage sur un exemple concret et de découvrir au passage la possibilité de faire des IHM "jolies" à l'aide des <tt>canvas</tt>. Le but à atteindre est de calculer les déplacements de quelques pièces (toutes si vous êtes motivés !) du jeu d'échec.
</p>
<p>Afin de réaliser les premières étapes du jeu d'échec, un peu de code vous est donné afin de vous concentrer sur la partie concernant les déplacements des pièces. En effet, toutes les pièces se déplacent, mais pas de la même manière. L'héritage et le polymorphisme sont donc pratiques afin de calculer les différents types de déplacements des différentes pièces du jeu.
</p>
<center><img src='result.png' width='300'/><br/><br/><i>L'interface a réaliser aujourd'hui !</i></center>
<h3>Les bases de l'utilisation d'un <tt>canvas</tt></h3>
<p>
Afin de ne pas perdre trop de temps sur les aspects graphiques, nous allons nous exercer sur quelques primitives graphiques disponibles au travers la balise <tt>canvas</tt> afin de pouvoir se concentrer sur l'héritage ensuite. La balise <tt>canvas</tt> permet de définir une zone graphique rectangulaire dans laquelle il est possible de récupérer un contexte graphique (un peu comme le paramètre <tt>Graphics</tt> de la méthode <tt>paintComponents</tt> des <tt>JPanel</tt>). A l'aide de ce contexte graphique, il est ensuite possible d'appliquer différentes opérations pour dessiner des figures (creuses ou remplies) ou afficher des images. Nous n'explorerons pas ici toutes les possibilités des <tt>canvas</tt>, juste celles nécessaires à la réalisation de l'interface graphique de notre jeu.
</p>
<p>Pour ce premier exercice, nous aurons besoin des objets et méthodes suivantes:
<ul>
<li>l'objet <a href='https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D'><tt>CanvasRenderingContexte2D</tt></a> qui fournit le contexte graphique sur lequel invoquer les méthodes de manipulation de la zone graphique,</li>
<li>les attributs <tt>canvas.width</tt> et <tt>canvas.height</tt> retournant les dimensions en pixel de la zone graphique (attention au repère: axe des <tt>x</tt> horizontal et des <tt>y</tt> vertical en JS!),</li>
<li>les méthodes <tt>strokeStyle</tt> et <tt>fillStyle</tt> pour définir la couleur du crayon et du remplissage respectivement, ainsi que <tt>fillRect</tt> et <tt>strokeRect</tt> pour dessiner des rectangles plein ou creux.</li>
<li>la notation <tt>'rgb(r,g,b)'</tt> pour définir une couleur (des constantes existent aussi comme <tt>'white', 'black', 'lightgrey', 'darkgrey'</tt>) ATTENTION: il faut bien représenter une couleur sous la forme d'une chaîne de caractères !,</li>
<li>l'objet <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math'><tt>Math</tt></a> et particulièrement ses méthodes <tt>random()</tt> et <tt>ceil(nb)</tt>.</li>
</ul>
L'objectif de ce premier exercice est d'afficher une centaine de rectangles mulicolores placées aléatoirement dans la zone graphique. Vous veillerez au préalable à "effacer" l'ensemble de l'écran en noir !
</p>
<!-- Program 5 -->
<div>
<textarea id="program5" class="programInput" rows="8" cols="50">
// récupération de l'élément canvas sur lequel faire les dessins
var canvas = document.getElementById("essai1");
// récupération du contexte graphique
var gfx = canvas.getContext("2d");
// changement de la couleur utilisé pour les dessins de figures pleines
// affichage d'un rectangle plein sur l'ensemble du canvas
for (var i=0; i<100; i++) {
// tirage aléatoire de la couleur
// dessin d'un rectable placé aléatoirement sur le canvas
}
undefined;
</textarea>
<div id='solution5' class='solution'>
<textarea class="programInput" readonly rows="4" cols="50">
:)
</textarea>
</div>
</div><br/>
<button onClick='runProgram(5)'>Run</button>
<button id='soluce' onClick='showSolution(5)'>Surrender</button><br/>
<div id='result5' class='programOutput'></div><br/><br/>
<center><canvas id='essai1' width='600' height='200' style='border-style: double'></canvas></center>
<br/><br/>
<!-- Program 5 -->
<p>Ces premières primitives vont nous permettre de créer le damier du plateau de jeu. Par contre, pour ce qui est des pièces, il est préférable de passer directement par des images :) L'exercice suivant a pour but de vous familiariser avec les primitives permettant d'afficher une image complète ou partielle dans un canvas.</p>
<p>Avant de pouvoir manipuler une image, encore faut-il la charger ... une fois cette dernière accessible, il devient possible grace à la méthode <tt>drawImage</tt> de recopier directement tout ou partie de l'image en la redimensionnant directement dans le canvas:
<ul>
<li>pour charger l'image, on utilise le type <tt><a href='https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement'>Image</a></tt> et la méthode <tt>onload</tt> qui invoquera la fonction passée en paramètre, une fois l'image chargée:
<div class="code">
<pre>
var chessSymbols = new Image();
chessSymbols.src = 'chess.png';
chessSymbols.onload = function() {
console.info("Chess symbols loaded !");
gfx.drawImage(chessSymbols, 0, 0, canvas.width, canvas.height);
};
</pre>
</div>
</li>
<li>pour extraire tout ou partie de l'image: <tt><a href='https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage'>gfx.drawImage(image,xSource,ySource,widthSource,heightSource,xTarget,yTarget,widthTarget,heightTarget);</a></tt></li>
</ul>
</p>
<p>La première étape de l'exercice suivant consiste à afficher d'abord l'ensemble de l'image <tt>chess.png</tt> et d'essayer d'en extraire ensuite le pion blanc. L'objectif est de reproduire l'affichage ci-dessous (sachant que le pien est positionné à la moitié du canvas (en largeur et en hauteur) et qu'une pièce rentre dans un carré d'environ 75 pixels).
</p>
<center><img src='drawImage.png' width='1000'/></center>
<p> Complétez le squelette donné ci-dessous afin de reproduire l'image présentée ci-dessus :)
</p>
<!-- Program 6 -->
<div>
<textarea id="program6" class="programInput" rows="8" cols="50">
// récupération du contexte graphique
var canvas = document.getElementById("essai2");
var gfx = canvas.getContext("2d");
var chessSymbols = new Image();
chessSymbols.src = 'chess.png';
chessSymbols.onload = function() {
// à compléter ...
};
undefined;
</textarea>
<div id='solution6' class='solution'>
<textarea class="programInput" readonly rows="4" cols="50">
:)
</textarea>
</div>
</div><br/>
<button onClick='runProgram(6)'>Run</button>
<button id='soluce' onClick='showSolution(6)'>Surrender</button><br/>
<div id='result6' class='programOutput'></div><br/><br/>
<center><canvas id='essai2' width='1000' height='175' style='border-style: double'></canvas></center>
<br/><br/>
<!-- Program 6 -->
<p>Nous disposons maintenant de suffisamment d'éléments sur les aspects graphiques pour pouvoir produire une jolie interface pour notre jeu d'échec. Nous allons donc basculer sur l'élément important de conception qui va mettre en oeuvre la création de différents types liés par des relations d'héritage.
</p>
<h3>Modélisation des différentes pièces du jeu d'échec</h3>
<p>Le jeu d'échec comporte 6 types de pièces pouvant prendre chacune la couleur noire ou blanche: le roi (<i>King</i>), la reine (<i>Queen</i>), la tour (<i>Rook</i>), le fou (<i>Bishop</i>), le cavalier (<i>Knight</i>) et le pion (<i>Pawn</i>). Chacune de ces pièces possède un nom (<i>name</i>), une couleur (<i>color</i>), une position (<i>line</i> et <i>column</i>) sur l'échiquier et une représentation graphique (nous verrons cela plus tard !). Chacune de ces pièces doit être capable de s'afficher (<i>draw</i>) sur le plateau et de calculer ses déplacements valides (<i>getMoves</i>). Il peut être pratique aussi d'introduire une pièce "vide" pour les cases ne contenant pas de pièce du jeu.
</p>
<p>La décomposition proposée consiste à créer:
<ul>
<li>un objet <tt>Piece</tt> définissant les attributs cités ci-dessus ainsi que la méthode <tt>draw</tt>,</li>
<li>un objet par type de pièce héritant de <tt>Piece</tt>, c'est-à-dire un <tt>Pawn</tt> spécialisant <tt>Piece</tt>, puis un <tt>Knight</tt> spécialisant aussi <tt>Piece</tt> ... qui définirait juste la méthode <tt>getMove</tt>,</li>
<li>si nous allions jusqu'au bout de l'implémentation de l'ensemble des pièces, nous pourrions aussi sûrement factoriser le calcul des déplacements de la reine à partir de ceux de la tour et du fou ;)</li>
</ul>
</p>
<p>Afin de vous permettre de démarrer plus rapidement, vous trouverez ci-dessous le squelette de la page <tt>chess.html</tt> contenant notamment la déclaration du type <tt>Piece</tt> et illustrant la définition de type via la méthode du constructeur. Soyez attentif aussi à la manière dont il est possible d'invoquer le constructeur d'un autre objet (cf. constructeur de <tt>Pawn</tt>).
<div class="code">
<pre>
<html>
<head>
<script type='text/javascript'>
// On tente de charger l'image au plus tôt !
var chessSymbols = new Image();
chessSymbols.src = 'chess.png';
chessSymbols.onload = function() {
console.info("Chess symbols loaded !");
// dessine la grille, une fois l'image chargée
//drawGrid(0,0, canvas.width, canvas.height, 8, 8);
};
</script>
</head>
<body>
<h1>Deep blue version JS</h1>
<center><canvas id='screen' width='400' height='400' >JavaScript est nécessaire ...</canvas></center>
<script type='text/javascript'>
var canvas = document.getElementById("screen");
var gfx = canvas.getContext("2d");
// définition du constructeur du type Piece
var Piece = function(name, color, line, column){
this.name = name || 'empty'; // si il n'y a pas de paramètre 'name', utiliser 'empty'
this.line = line || 0;
this.column = column || 0;
this.color = color || 'grey';
this.pieceId = undefined;
};
// définition d'une méthode du type Piece: il est crucial de la créer
// au niveau du prototype et non pas de l'objet !
// Cette fonction sera pratique pour calculer le déplacement des pièces
// quelle que soit leur orientation
Piece.prototype.orientation = function() {
return (this.color === 'white') ? +1 : -1;
}
// Constructeur du type Pawn, observez attentivement l'appel au constructeur de Piece !
// pieceId correspond aux coordonnées d'extraction des images du pion en blanc puis noir
var Pawn = function(color, line, column) {
Piece.prototype.constructor.call(this, 'Pawn', color, line, column);
this.pieceId = [[0, 5], [480, 5]];
}
Pawn.prototype = new Piece();
//var createBoard = function(nbLine, nbColumn) // avec des pieces vide
//var isEmpty = function(lig, col)
//var put = function(lig, col, piece)
//var board = createBoard(8, 8);
//var initBoard = function() // avec les pièces du jeu
var convertCoordinates = function(ligPixel, colPixel) {
var lig = Math.ceil(ligPixel / (canvas.height/8)) - 1;
var col = Math.ceil(colPixel / (canvas.width /8)) - 1;
return [lig, col];
}
// liste des coordonnées des cellules libres accessibles par la pièce actuellement
// sélectionnée par l'utilisateur
var highlightedCells = [];
// on prend la coordonnée de la cellule à dessiner et une couleur correspondant
// au carré dessiné dans la case si elle ne contient pas de pièce (gris si la
// case n'est pas sélectionnée pour représenter un déplacement valide et jaune sinon)
// var drawCell = function(coord, color)
//var highlight = function(on)
canvas.addEventListener("mousedown", mouseClicked, false);
//var mouseClicked = function(event) { // Pourquoi cela ne fonctionne pas avec var ?!
function mouseClicked(event) {
/* var ligCoord = event.pageY - canvas.offsetTop;
var colCoord = event.pageX - canvas.offsetLeft;
var coord = convertCoordinates(ligCoord, colCoord);
console.info(coord);
if (highlightedCells.length > 0) {
highlight(false);
highlightedCells = [];
}
var piece = board[coord[0]][coord[1]];
if (piece.name !== '.') {
var moves = piece.getMoves();
highlightedCells.push(moves);
highlight(true);
} else {
// TODO: if empty and highlighted, move the piece !
// doMove();
}*/
}
// initialise le plateau en déposant les pièces de deux joueurs au début de la partie
//initBoard();
// Pour dessiner le plateau, on spécifie le coin supérieur gauche, la
// largeur et la hauteur. Dans cette fonction, on appelle drawCell
// pour dessiner une cellule à une coordonnée donnée.
//var drawGrid = function(x, y, width, height, nbLig, nbCol) {
</script>
</body>
</html>
</pre>
</div>
<br/>
<center><i>Squelette de la page</i> <tt>chess.html</tt></center>
</p>
<!-- SOLUTION COMPLETE DU JEU D'ECHECS -->
</body>
</html>