SNT

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

lvl4.html (8350B)


      1 <head>
      2 
      3 <meta charset="utf-8"/>
      4 
      5 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"/>
      6 
      7 <style>
      8 h1,h2 {
      9     font-family: Sans;
     10 }
     11 
     12 .stderr {
     13     background-color: #fee;
     14     color: #900;
     15 }
     16 
     17 .stderr, .stdout {
     18     /* display: contents; */ /* uncomment to make print( end='') work */
     19     margin: 0px;
     20     padding: 0px 0.3em;
     21 }
     22 
     23 .console {
     24     max-height: 20em;
     25     overflow: auto;
     26     border: medium solid black;
     27 }
     28 
     29 .console:empty {
     30     display: none;
     31 }
     32 
     33 #feedback {
     34     border: solid #aaa;
     35     background-color: #eee;
     36 }
     37 
     38 #feedback:empty {
     39     display: none;
     40 }
     41 
     42 #edcontainer {
     43     display: flex;
     44 }
     45 .edcolumn {
     46     flex: 50%;
     47 }
     48 #breditor {
     49     width: 100%;
     50 }
     51 
     52 
     53 </style>
     54 
     55 <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.0/dist/phaser.min.js"></script>
     56 <script src="https://unpkg.com/brython@3.9.3/brython.js"></script>
     57 <script src="https://unpkg.com/brython@3.9.3/brython_stdlib.js"></script>
     58 <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.min.js"></script>
     59 <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/mode-python.min.js"></script>
     60 
     61 <script type="text/javascript">
     62 
     63 code = "# Écrivez votre code python ici :\nprint(\"Bonjour !\")";
     64 
     65 score = 0;
     66 
     67 API = window.API || window.parent.API;
     68 
     69 function loadSCO() {
     70     if (API) {
     71         API.LMSInitialize("");
     72 
     73         suspend_data = API.LMSGetValue("cmi.suspend_data");
     74 
     75         if (suspend_data) {
     76             code = suspend_data;
     77         }
     78     }
     79 }
     80 
     81 function sendSCO() {
     82     if (API) {
     83         API.LMSSetValue("cmi.core.score.raw", score);
     84         API.LMSSetValue("cmi.suspend_data", code);
     85         API.LMSSetValue("cmi.core.score.lesson_status", "completed");
     86 
     87         API.LMSCommit("");
     88     }
     89 }
     90 
     91 function nextSCO() {
     92     if (API) {
     93         API.LMSSetValue("nav.event","continue"); // Probably Moodle specific
     94         API.LMSFinish("");
     95     }
     96 }
     97 
     98 // Phaser stuff
     99 
    100 var tilesize = 32;
    101 var delay = 250;
    102 
    103 var movetime = 0;
    104 var delayed_moves = [];
    105 
    106 var config = {
    107     type: Phaser.AUTO,
    108     width: tilesize*10,
    109     height: tilesize*10,
    110     parent: "game",
    111     scene: {
    112         preload: preload,
    113         create: create
    114     }
    115 };
    116 
    117 function preload() {
    118     this.load.image("tilemap", "img/tilemap.png")
    119     this.load.image("bot", "img/bot.png")
    120     this.load.tilemapCSV('map', 'lvl/lvl4.csv');
    121 }
    122 
    123 function create() {
    124     map = this.make.tilemap({ key: 'map', tileWidth: 32, tileHeight: 32 });
    125     var tileset = map.addTilesetImage('tilemap');
    126     layer = map.createLayer(0, tileset, 0, 0);
    127     
    128     bot = this.add.image(tilesize * 1.5, tilesize * 1.5, "bot")
    129 }
    130 
    131 function get_tile_at(x,y) {
    132     return layer.getTileAtWorldXY(x*tilesize, y*tilesize, true).index;
    133 }
    134 
    135 function reset_board() {
    136     movetime = 0;
    137     bot.x = tilesize * 1.5;
    138     bot.y = tilesize * 1.5;
    139     bot.angle = 0;
    140 
    141     for (move of delayed_moves){
    142         clearTimeout(move)
    143     }
    144 
    145     delayed_moves = []
    146 }
    147 
    148 function move_left() {
    149     delayed_moves.push(
    150         setTimeout(
    151             function() {
    152                 bot.x -= tilesize;
    153                 bot.angle = 180;
    154             }, movetime)
    155         );
    156     movetime += delay;
    157 }
    158 
    159 function move_right() {
    160     delayed_moves.push(
    161         setTimeout(
    162             function() {
    163                 bot.x += tilesize;
    164                 bot.angle = 0;
    165             }, movetime)
    166         );
    167     movetime += delay;
    168 }
    169 
    170 function move_up() {
    171     delayed_moves.push(
    172         setTimeout(
    173             function() {
    174                 bot.y -= tilesize;
    175                 bot.angle = -90;
    176             }, movetime)
    177         );
    178     movetime += delay;
    179 }
    180 
    181 function move_down() {
    182     delayed_moves.push(
    183         setTimeout(
    184             function() {
    185                 bot.y += tilesize;
    186                 bot.angle = 90;
    187             }, movetime)
    188         );
    189     movetime += delay;
    190 }
    191 
    192 window.onload = function() {
    193     loadSCO();
    194     document.getElementById("code").textContent = code;
    195 
    196     game = new Phaser.Game(config);
    197     
    198     brython();
    199 }
    200 </script>
    201 
    202 <script type="text/python">
    203 # Requires Brython and Ace editor
    204 
    205 from browser import document, window, html
    206 from sys import stderr, stdout, settrace
    207 from traceback import print_exc, extract_stack, extract_tb
    208 
    209 def make_max_line_tracer(maxlines):
    210     lines = 0
    211     def tracer(frame, event, arg):
    212         nonlocal lines
    213         if event == 'line':
    214             lines += 1
    215             if lines >= maxlines:
    216                 raise TimeoutError
    217         return tracer
    218     return tracer
    219 
    220 def exec_code(editor, id):
    221     reset()
    222     feedback("Le drapeau n'est pas encore atteint")
    223 
    224     code_lines = editor.session.getLength()
    225     if code_lines > max_code_lines:
    226         feedback("Trop de lignes utilisées ( " + str(code_lines) + "/" + str(max_code_lines) + ")")
    227         return
    228     
    229     console = document[id + "_console"]
    230     console.clear()
    231     stderr.write = lambda data : console_target(data, console, True)
    232     stdout.write = lambda data : console_target(data, console)
    233 
    234     code = editor.getValue()
    235     try:
    236         compiled = compile(code, "<" + id + ">", "exec")
    237     except SyntaxError:
    238         print_exc(limit=0)
    239         return
    240 
    241     settrace(make_max_line_tracer(10000)) # increase to allow longer execution
    242     try:
    243         exec(code)
    244     except TimeoutError:
    245         settrace(None)
    246         print("L'exécution prend trop de temps, abandon.", file=stderr)
    247     except Exception as e:
    248         settrace(None)
    249         tb_len = len(extract_tb(e.__traceback__)) - len(extract_stack())
    250         print_exc(limit=-tb_len)
    251     finally:
    252         settrace(None)
    253 
    254     window.code = code
    255     #window.score = check()
    256     window.sendSCO()
    257 
    258 def console_target(data, elt, err=False):
    259     elt <= html.PRE(data, Class="stderr" if err else "stdout")
    260     elt.scrollTop = elt.scrollHeight
    261 
    262 breditors = document.select(".breditor")
    263 
    264 max_code_lines = 10
    265 
    266 for ed_elt in breditors:
    267     editor = window.ace.edit(ed_elt.id)
    268     editor.session.setMode("ace/mode/python")
    269     #editor.setOption('fontSize', '14px')
    270     editor.setOption('maxLines', max_code_lines)
    271     editor.setOption('minLines', max_code_lines)
    272 
    273     console = html.DIV(Class="console", id=ed_elt.id + "_console")
    274 
    275     ed_elt.insertAdjacentElement('afterend', console)
    276 
    277     exec_button = html.BUTTON("Exécuter →")
    278     exec_button.bind("click", lambda ev : exec_code(editor, ed_elt.id))
    279     ed_elt.insertAdjacentElement('afterend', exec_button)
    280 
    281 def feedback(msg):
    282     document["feedback"].clear()
    283     document["feedback"] <= msg
    284 
    285 coords = [1,1]
    286 
    287 def reset():
    288     global coords
    289     window.reset_board()
    290     coords = [1,1]
    291 
    292 def gauche():
    293     if coords[0] >= 0:
    294         tile = window.get_tile_at(coords[0]-1, coords[1])
    295         if tile in (0,1,3):
    296             window.move_left()
    297             coords[0] -= 1
    298             if tile == 1:
    299                 win()
    300             elif tile == 3:
    301                 fall()
    302 
    303 def droite():
    304     if coords[0] < 10:
    305         tile = window.get_tile_at(coords[0]+1, coords[1])
    306         if tile in (0,1,3):
    307             window.move_right()
    308             coords[0] += 1
    309             if tile == 1:
    310                 win()
    311             elif tile == 3:
    312                 fall()
    313 
    314 def haut():
    315     if coords[1] >= 0:
    316         tile = window.get_tile_at(coords[0], coords[1]-1)
    317         if tile in (0,1,3):
    318             window.move_up()
    319             coords[1] -= 1
    320             if tile == 1:
    321                 win()
    322             elif tile == 3:
    323                 fall()
    324 
    325 def bas():
    326     if coords[1] < 10:
    327         tile = window.get_tile_at(coords[0], coords[1]+1)
    328         if tile in (0,1,3):
    329             window.move_down()
    330             coords[1] += 1
    331             if tile == 1:
    332                 win()
    333             elif tile == 3:
    334                 fall()
    335 
    336 def fall():
    337     feedback("Le robot est tombé dans le vide !")
    338     raise Exception("Le robot est tombé dans le vide")
    339     
    340 
    341 def win():
    342     window.score = 100
    343     feedback("Bravo !")
    344     document["feedback"] <= html.BUTTON("Passer à la suite", onclick="nextSCO();")
    345     
    346 
    347 </script>
    348 
    349 </head>
    350 
    351 <body>
    352 
    353 <h1>Niveau 4</h1>
    354 
    355 Vous disposez des fonctions
    356 <code>droite()</code>,
    357 <code>gauche()</code>,
    358 <code>haut()</code>, et
    359 <code>bas()</code>
    360 pour faire avancer le robot.
    361 
    362 <div id="edcontainer">
    363     <div class="edcolumn">
    364         Code python :
    365         <pre id="code" class="breditor"></pre>
    366         <div id="feedback"></div>
    367     </div>
    368     <div class="edcolumn">
    369         Plateau :
    370         <div id="game"></div>
    371     </div>
    372 </div>
    373 
    374 
    375 
    376 
    377 
    378 
    379 </body>
    380 </html>