SNT

Cours de SNT
git clone git://git.vgx.fr/SNT
Log | Files | Refs

lvl11.html (10307B)


      1 <head>
      2 
      3 <meta charset="utf-8"/>
      4 
      5 <style>
      6 h1,h2 {
      7     font-family: Sans;
      8 }
      9 
     10 .stderr {
     11     background-color: #fee;
     12     color: #900;
     13 }
     14 
     15 .stderr, .stdout {
     16     /* display: contents; */ /* uncomment to make print( end='') work */
     17     margin: 0px;
     18     padding: 0px 0.3em;
     19 }
     20 
     21 .console {
     22     max-height: 20em;
     23     overflow: auto;
     24     border: medium solid black;
     25 }
     26 
     27 .console:empty {
     28     display: none;
     29 }
     30 
     31 #feedback {
     32     border: solid #aaa;
     33     background-color: #eee;
     34 }
     35 
     36 #feedback:empty {
     37     display: none;
     38 }
     39 
     40 #edcontainer {
     41     display: flex;
     42 }
     43 .edcolumn {
     44     flex: 50%;
     45 }
     46 #breditor {
     47     width: 100%;
     48 }
     49 
     50 
     51 </style>
     52 
     53 <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.0/dist/phaser.min.js"></script>
     54 <script src="https://unpkg.com/brython@3.9.3/brython.js"></script>
     55 <script src="https://unpkg.com/brython@3.9.3/brython_stdlib.js"></script>
     56 <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.min.js"></script>
     57 <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/mode-python.min.js"></script>
     58 <!--
     59 <script src="lib/phaser/phaser.min.js"></script>
     60 <script src="lib/brython/brython.js"></script>
     61 <script src="lib/brython/brython_stdlib.js"></script>
     62 <script src="lib/ace/ace.js"></script>
     63 <script src="lib/ace/mode-python.js"></script>
     64 -->
     65 
     66 <script type="text/javascript">
     67 
     68 code = "# il faut définir la fonction u(n)\n" +
     69        "# et utiliser une variable pour se souvenir de combien descendre";
     70 
     71 score = 0;
     72 
     73 API = window.API || window.parent.API;
     74 
     75 function loadSCO() {
     76     if (API) {
     77         API.LMSInitialize("");
     78 
     79         suspend_data = API.LMSGetValue("cmi.suspend_data");
     80 
     81         if (suspend_data) {
     82             code = suspend_data;
     83         }
     84     }
     85 }
     86 
     87 function sendSCO() {
     88     if (API) {
     89         API.LMSSetValue("cmi.core.score.raw", score);
     90         API.LMSSetValue("cmi.suspend_data", code);
     91         API.LMSSetValue("cmi.core.score.lesson_status", "completed");
     92 
     93         API.LMSCommit("");
     94     }
     95 }
     96 
     97 function nextSCO() {
     98     if (API) {
     99         API.LMSSetValue("nav.event","continue"); // Probably Moodle specific
    100         API.LMSFinish("");
    101     }
    102 }
    103 
    104 // Phaser stuff
    105 
    106 var tilesize = 32;
    107 var delay = 250;
    108 
    109 var tiles = [];
    110 
    111 var movetime = 0;
    112 var delayed_moves = [];
    113 
    114 var config = {
    115     type: Phaser.AUTO,
    116     width: tilesize*10,
    117     height: tilesize*10,
    118     parent: "game",
    119     scene: {
    120         preload: preload,
    121         create: create
    122     }
    123 };
    124 
    125 function preload() {
    126     this.load.image("tilemap", "img/tilemap.png")
    127     this.load.image("bot", "img/bot.png")
    128     this.load.tilemapCSV('map', 'lvl/lvl11.csv');
    129 }
    130 
    131 function create() {
    132     map = this.make.tilemap({ key: 'map', tileWidth: 32, tileHeight: 32 });
    133     var tileset = map.addTilesetImage('tilemap');
    134     layer = map.createLayer(0, tileset, 0, 0);
    135     
    136     bot = this.add.image(tilesize * 1.5, tilesize * 1.5, "bot");
    137 }
    138 
    139 function gen_tiles() {
    140     for (var i = 0 ; i < 10 ; i++) {
    141         tiles[i] = [];
    142         for (var j = 0 ; j < 10 ; j++) {
    143             var id = map.getTileAt(i,j).index;
    144             if (id == 4)
    145                 id = 3;
    146             tiles[i][j] = id;
    147         }
    148     }
    149     var dy = 0;
    150     for (var x = 1 ; x < 9 ; x+=2) {
    151         var ddy = Math.floor(Math.random()*3);
    152         if(x==1)
    153             ddy++;
    154         tiles[x][0] = ddy;
    155         dy += ddy;
    156         tiles[x+1][1+dy] = 0;
    157     }
    158 }
    159 
    160 function get_tile_at(x,y) {
    161     return tiles[x][y];
    162 }
    163 
    164 function reset_board() {
    165     movetime = 0;
    166     bot.x = tilesize * 1.5;
    167     bot.y = tilesize * 1.5;
    168     bot.angle = 0;
    169 
    170     for (move of delayed_moves){
    171         clearTimeout(move)
    172     }
    173 
    174     delayed_moves = []
    175 
    176     gen_tiles()
    177 }
    178 
    179 function move_left() {
    180     delayed_moves.push(
    181         setTimeout(
    182             function() {
    183                 bot.x -= tilesize;
    184                 bot.angle = 180;
    185             }, movetime)
    186         );
    187     movetime += delay;
    188 }
    189 
    190 function move_right() {
    191     delayed_moves.push(
    192         setTimeout(
    193             function() {
    194                 bot.x += tilesize;
    195                 bot.angle = 0;
    196             }, movetime)
    197         );
    198     movetime += delay;
    199 }
    200 
    201 function move_up() {
    202     delayed_moves.push(
    203         setTimeout(
    204             function() {
    205                 bot.y -= tilesize;
    206                 bot.angle = -90;
    207             }, movetime)
    208         );
    209     movetime += delay;
    210 }
    211 
    212 function move_down() {
    213     delayed_moves.push(
    214         setTimeout(
    215             function() {
    216                 bot.y += tilesize;
    217                 bot.angle = 90;
    218             }, movetime)
    219         );
    220     movetime += delay;
    221 }
    222 
    223 window.onload = function() {
    224     loadSCO();
    225     document.getElementById("code").textContent = code;
    226 
    227     game = new Phaser.Game(config);
    228     
    229     brython();
    230 }
    231 </script>
    232 
    233 <script type="text/python">
    234 # Requires Brython and Ace editor
    235 
    236 from browser import document, window, html
    237 from sys import stderr, stdout, settrace
    238 from traceback import print_exc, extract_stack, extract_tb
    239 
    240 def make_max_line_tracer(maxlines):
    241     lines = 0
    242     def tracer(frame, event, arg):
    243         nonlocal lines
    244         if event == 'line':
    245             lines += 1
    246             if lines >= maxlines:
    247                 raise TimeoutError
    248         return tracer
    249     return tracer
    250 
    251 def exec_code(editor, id):
    252     reset()
    253     
    254     feedback("Le drapeau n'est pas encore atteint")
    255 
    256     code_lines = editor.session.getLength()
    257     if code_lines > max_code_lines:
    258         feedback("Trop de lignes utilisées ( " + str(code_lines) + "/" + str(max_code_lines) + ")")
    259         return
    260     
    261     console = document[id + "_console"]
    262     console.clear()
    263     stderr.write = lambda data : console_target(data, console, True)
    264     stdout.write = lambda data : console_target(data, console)
    265 
    266     code = editor.getValue()
    267     try:
    268         compiled = compile(code, "<" + id + ">", "exec")
    269     except SyntaxError:
    270         print_exc(limit=0)
    271         return
    272 
    273     settrace(make_max_line_tracer(10000)) # increase to allow longer execution
    274     try:
    275         exec(code)
    276     except TimeoutError:
    277         settrace(None)
    278         print("L'exécution prend trop de temps, abandon.", file=stderr)
    279     except Exception as e:
    280         settrace(None)
    281         tb_len = len(extract_tb(e.__traceback__)) - len(extract_stack())
    282         print_exc(limit=-tb_len)
    283     finally:
    284         settrace(None)
    285 
    286     window.code = code
    287     #window.score = check()
    288     window.sendSCO()
    289 
    290 def console_target(data, elt, err=False):
    291     elt <= html.PRE(data, Class="stderr" if err else "stdout")
    292     elt.scrollTop = elt.scrollHeight
    293 
    294 breditors = document.select(".breditor")
    295 
    296 max_code_lines = 15
    297 
    298 for ed_elt in breditors:
    299     editor = window.ace.edit(ed_elt.id)
    300     editor.session.setMode("ace/mode/python")
    301     #editor.setOption('fontSize', '14px')
    302     editor.setOption('maxLines', max_code_lines)
    303     editor.setOption('minLines', max_code_lines)
    304 
    305     console = html.DIV(Class="console", id=ed_elt.id + "_console")
    306 
    307     ed_elt.insertAdjacentElement('afterend', console)
    308 
    309     exec_button = html.BUTTON("Exécuter →")
    310     exec_button.bind("click", lambda ev : exec_code(editor, ed_elt.id))
    311     ed_elt.insertAdjacentElement('afterend', exec_button)
    312 
    313 def feedback(msg):
    314     document["feedback"].clear()
    315     document["feedback"] <= msg
    316 
    317 coords = [1,1]
    318 
    319 def reset():
    320     global coords
    321     window.reset_board()
    322     coords = [1,1]
    323 
    324 def gauche():
    325     if coords[0] >= 0:
    326         move_to(coords[0]-1, coords[1], -1, 0, window.move_left)
    327 
    328 def droite():
    329     if coords[0] < 10:
    330         move_to(coords[0]+1, coords[1], 1, 0, window.move_right)
    331 
    332 def haut():
    333     if coords[1] >= 0:
    334         move_to(coords[0], coords[1]-1, 0, -1, window.move_up)
    335 
    336 def bas():
    337     if coords[1] < 10:
    338         move_to(coords[0], coords[1]+1, 0 , 1, window.move_down)
    339 
    340 def move_to(x, y, dx, dy, move):
    341     tile = window.get_tile_at(x, y)
    342     if tile in (0,1,3):
    343         move()
    344         coords[0] += dx
    345         coords[1] += dy
    346         if tile == 1:
    347             win()
    348         elif tile == 3:
    349             fall()
    350         else:
    351             feedback("Le robot n'est pas sur un drapeau")
    352             window.score = 0
    353     
    354 
    355 def voir_gauche():
    356     if coords[0] == 0:
    357         return 3
    358     else:
    359         return voir(coords[0]-1, coords[1])
    360 
    361 def voir_droite():
    362     if coords[0] == 10:
    363         return 3
    364     else:
    365         return voir(coords[0]+1, coords[1])
    366 
    367 def voir_haut():
    368     if coords[1] == 0:
    369         return 3
    370     else:
    371         return voir(coords[0], coords[1]-1)
    372 
    373 def voir_bas():
    374     if coords[1] == 10:
    375         return 3
    376     else:
    377         return voir(coords[0], coords[1]+1)
    378 
    379 def voir(x,y):
    380     return window.get_tile_at(x,y)
    381 
    382 def u(n):
    383     for i in range(n):
    384         bas()
    385     droite()
    386     droite()
    387     for i in range(n):
    388         haut()
    389 
    390 def fall():
    391     feedback("Le robot est tombé dans le vide !")
    392     raise Exception("Le robot est tombé dans le vide")
    393     
    394 
    395 def win():
    396     window.score = 100
    397     feedback("Bravo ! (exécutez plusieurs fois avant de continuer)")
    398     #feedback("Bravo ! ")
    399     document["feedback"] <= html.BUTTON("Passer à la suite", onclick="nextSCO();")
    400     
    401 
    402 </script>
    403 
    404 </head>
    405 
    406 <body>
    407 
    408 <h1>Niveau 11</h1>
    409 
    410 <p>
    411 Vous disposez des fonctions
    412 <code>droite()</code>,
    413 <code>gauche()</code>,
    414 <code>haut()</code>, et
    415 <code>bas()</code>
    416 pour faire avancer le robot.
    417 </p>
    418 
    419 <p>
    420 Il faut maintenant écrire vous-même la fonction
    421 <code>u(<i>n</i>)</code>
    422 qui va faire faire un virage vers le bas
    423 de longueur <i>n</i> au robot.
    424 </p>
    425 
    426 <p>
    427 Chaque barrière de <i>?</i> possède un point de passage.
    428 </p>
    429 <p>
    430 Cette fois-ci, sa position est la
    431 <b>somme des cases <i>i</i> précédentes</b>.
    432 Par exemple, si la case <i>i</i> au dessus du début vaut 2
    433 et la case <i>i</i> suivante vaut 1,
    434 alors pour le 2ème virage
    435 il faudra faire un U de 3 cases de profond pour passer.
    436 </p>
    437 
    438 <p>
    439 Utilisez votre fonction <code>u(n)</code> et <code>voir_haut()</code>
    440 pour passer chaque barrière.
    441 </p>
    442 
    443 <p>
    444 Exemples de fonction avec paramètre :
    445 <pre><code># on définis une fonction f qui prend 1 paramètre n
    446 
    447 def f(n):
    448     # à l'intérieur de la fonction, on utilise n comme une variable :
    449     print(n)
    450     for i in range(n):
    451         print("lol")
    452 
    453 # on appelle f :
    454 
    455 f(42) # n vaudra 42 dans la fonction
    456 </code></pre>
    457 </p>
    458 
    459 <div id="edcontainer">
    460     <div class="edcolumn">
    461         Code python :
    462         <pre id="code" class="breditor"></pre>
    463         <div id="feedback"></div>
    464     </div>
    465     <div class="edcolumn">
    466         Plateau :
    467         <div id="game"></div>
    468     </div>
    469 </div>
    470 
    471 </body>
    472 </html>