{"id":11085,"date":"2025-11-02T11:09:49","date_gmt":"2025-11-02T10:09:49","guid":{"rendered":"https:\/\/spgoo.org\/?page_id=11085"},"modified":"2025-11-02T11:10:06","modified_gmt":"2025-11-02T10:10:06","slug":"simulateur-axelrod-v2","status":"publish","type":"page","link":"https:\/\/spgoo.org\/?page_id=11085","title":{"rendered":"Simulateur Axelrod &#8211; V2"},"content":{"rendered":"\n<link rel='stylesheet' id='11080-css'  href='https:\/\/spgoo.org\/wp-content\/uploads\/winp-css-js\/11080.css?ver=1762096852' type='text\/css' media='all' \/>\n\n\n<script type='text\/javascript'>\nvar id = \"11082\";<\/script>\n<script type='text\/javascript' src='https:\/\/spgoo.org\/wp-content\/uploads\/winp-css-js\/11082.js?ver=1762096355'><\/script>\n\n\n<script type='text\/javascript'>\nvar id = \"10667\";<\/script>\n<script type='text\/javascript' src='https:\/\/spgoo.org\/wp-content\/uploads\/winp-css-js\/10667.js?ver=1762078084'><\/script>\n\n\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/katex\/dist\/katex.min.js\"><\/script>\r\n    <link href=\"https:\/\/cdn.jsdelivr.net\/npm\/katex\/dist\/katex.min.css\" rel=\"stylesheet\"> \r\n    <!-- <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/jsxgraph\/distrib\/jsxgraphcore.min.js\"><\/script>    -->\r\n\r\n    <script charset=\"UTF-8\"  src=\"https:\/\/cdn.jsdelivr.net\/npm\/jsxgraph\/distrib\/jsxgraphcore.js\"><\/script>\r\n    <link rel=\"stylesheet\"  type=\"text\/css\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/jsxgraph\/distrib\/jsxgraph.css\">\r\n\r\n    <!-- <link rel=\"stylesheet\" type=\"text\/css\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jsxgraph\/1.4.6\/jsxgraph.css\" \/>\r\n    <script type=\"text\/javascript\" src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jsxgraph\/1.4.6\/jsxgraphcore.js\"><\/script>-->\r\n\r\n    <script>\r\n        window.MathJax = {\r\n          tex: {\r\n            inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\r\n            displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ],\r\n            packages: ['base', 'ams']\r\n          },\r\n          options: {\r\n            ignoreHtmlClass: 'tex2jax_ignore',\r\n            processHtmlClass: 'tex2jax_process'\r\n          }\r\n        };\r\n    <\/script>  \r\n    <script type=\"text\/javascript\" id=\"MathJax-script\"   src=\"https:\/\/cdn.jsdelivr.net\/npm\/mathjax@3\/es5\/tex-mml-chtml.js\"> <\/script>\r\n    <!-- <link rel=\"stylesheet\"  type=\"text\/css\" href=\"machinesetats.css\">\r\n    <script charset=\"UTF-8\"  src=\"config_strateg.js\"><\/script>\r\n    <script src=\".\/strategies_code.js\"><\/script>\r\n    <script src=\".\/strategies_comments.js\"><\/script> -->\r\n\r\n\r\n    <h1>\\(\\textrm{Tournoi d&#8217;Axelrod  &#8211; Simulateur }\\)<\/h1>\r\n    \r\n    <div id=\"container\">\r\n        <div id=\"sidebarGauche\">\r\n            <div class=\"panel\">\r\n                <h2>\ud83d\udccd \\(\\textrm{Strat\u00e9gie Candidat 1}\\)<\/h2>\r\n                <div class=\"droplist\" id=\"myDroplist-User1\">\r\n                    <div class=\"droplist-header\">\r\n                        <div class=\"droplist-header-content\" id=\"selectedValue-User1\">\\(\\textrm{S\u00e9lectionnez une strat\u00e9gie}\\)<\/div>\r\n                        <div class=\"droplist-arrow\"><\/div>\r\n                    <\/div>\r\n                    <div class=\"droplist-list\" id=\"droplist-User1\"><\/div>\r\n                <\/div>\r\n                <div id=\"current-state-1\" style=\"cursor:pointer;\" onclick=\"change_depart('1');\">Strat\u00e9gie<\/div>\r\n                <div class=\"state-description\" id=\"state-description-1\">Choix de la strat\u00e9gie du candidat 1 <\/div>\r\n            <\/div>\r\n            <div class=\"panel\">\r\n                <div class=\"control-group\">\r\n                    <label z-index=\"10\" >NB It\u00e9.<span id=\"resValue\">50<\/span><\/label>\r\n                    <input type=\"range\" id=\"resolution\" min=\"10\" max=\"100\" value=\"50\">\r\n                <\/div>\r\n                <div class=\"control-group\">\r\n                    <label>Vitesse :<span id=\"resVitesse\">1<\/span><\/label>\r\n                    <input type=\"range\" id=\"vitesse\" min=\"1\" max=\"10\" value=\"1\">\r\n                <\/div>\r\n        \r\n                <!-- <button onclick=\"avance();\" class=\"event-btn\" >\\(Step\\)<\/button> -->\r\n                <button onclick=\"game_start();\" class=\"event-btn\" >\\(Run\\)<\/button>\r\n                <button onclick=\"resetSystem();\" class=\"event-btn\" >\\(Reset\\)<\/button>\r\n            <\/div>\r\n\r\n        <\/div>\r\n        \r\n        <div id=\"jxgbox_candidat1\" class=\"jxgbox\"><\/div>\r\n        <div id=\"jxgbox_candidat2\" class=\"jxgbox\"><\/div>\r\n\r\n        <div id=\"sidebarDroit\">\r\n            <div class=\"panel\">\r\n                <h2>\ud83d\udccd  \\(\\textrm{Strat\u00e9gie Candidat 2}\\)<\/h2>\r\n                <div class=\"droplist\" id=\"myDroplist-User2\">\r\n                    <div class=\"droplist-header\">\r\n                        <div class=\"droplist-header-content\" id=\"selectedValue-User2\">\\(\\textrm{S\u00e9lectionnez une strat\u00e9gie}\\)<\/div>\r\n                        <div class=\"droplist-arrow\"><\/div>\r\n                    <\/div>\r\n                    <div class=\"droplist-list\" style=\"cursor:pointer;\" id=\"droplist-User2\"><\/div>\r\n                <\/div>\r\n                <div id=\"current-state-2\" onclick=\"change_depart('2');\"  style=\"cursor:pointer;\">Strat\u00e9gie<\/div>\r\n                <div class=\"state-description\" id=\"state-description-2\">Choix de la strat\u00e9gie du candidat 2<\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n    <\/div>\r\n    <br\/>\r\n    <div class=\"panelHisto\">\r\n        <h2>\ud83d\udcdc Historique<\/h2>\r\n        <div id=\"history\"><\/div>\r\n    <\/div>\r\n\r\n    <script>\r\n\r\n        document.getElementById('resolution').addEventListener('input', (e) => {\r\n            document.getElementById('resValue').textContent = e.target.value;\r\n        });\r\n        document.getElementById('vitesse').addEventListener('input', (e) => {\r\n            document.getElementById('resVitesse').textContent = e.target.value;\r\n        });\r\n\r\n        \/\/ changement de la valeur de d\u00e9part du candidat \r\n        const change_depart=function(indice) {\r\n            let val1=\"\", val2=\"\";\r\n            console.log(graph1.StateMachine.currentState,graph2.StateMachine.currentState);\r\n            if (graph1.StateMachine.currentState==\"COLLABORE\") {val1=\"C\";}  else {val1=\"T\";}\r\n            if (graph2.StateMachine.currentState==\"COLLABORE\")  {val2=\"C\" } else {val2=\"T\";}\r\n            console.log(val1,val2, indice);\r\n            switch(indice) {\r\n                case '1': \r\n                    if (graph1.StateMachine.currentState==\"TRAHIE\") {\r\n                        graph1.current_state.innerHTML=\"COLLABORE\";\r\n                        graph1.StateMachine.currentState=\"COLLABORE\";\r\n                        val1=\"C\";\r\n                    } else {\r\n                        graph1.current_state.innerHTML=\"TRAHIE\";\r\n                        graph1.StateMachine.currentState=\"TRAHIE\";\r\n                        val1=\"T\";\r\n                    }\r\n                    graph1.updateUI();\r\n                    graph1.updateVisuals();\r\n                    break;\r\n                case '2':\r\n                    if (graph2.StateMachine.currentState==\"TRAHIE\") {\r\n                        graph2.current_state.innerHTML=\"COLLABORE\";\r\n                        graph2.StateMachine.currentState=\"COLLABORE\";\r\n                        val2=\"C\";\r\n                    } else {\r\n                        graph2.current_state.innerHTML=\"TRAHIE\";\r\n                        graph2.StateMachine.currentState=\"TRAHIE\";\r\n                        val2=\"T\";                    \r\n                    }\r\n                    graph2.updateUI();\r\n                    graph2.updateVisuals();\r\n                break;\r\n            }\r\n            \/\/ mettre a jour l'historique \r\n            document.getElementById('history').innerHTML = '';\r\n            console.log(val1,val2);\r\n            choix1=val1, choix2=val2;\r\n            ajoute_histo(val1,val2);    \r\n\r\n        }\r\n\r\n\r\n        \/\/ Configuration de JSXGraph\r\n        const board = JXG.JSXGraph.initBoard('jxgbox_candidat1', {\r\n            boundingbox: [-2, 8, 4, -2],\r\n            axis: false,\r\n            showNavigation: false,\r\n            keepAspectRatio:false,\r\n            showCopyright: false,\r\n            pan: {enabled: true, needTwoFingers: false},\r\n            zoom: {wheel: true}\r\n        });\r\n        board.renderer.container.style.backgroundColor = 'gainsboro';\r\n\r\n        const board2 = JXG.JSXGraph.initBoard('jxgbox_candidat2', {\r\n            boundingbox: [-2, 8, 4, -2],\r\n            axis: false,\r\n            keepAspectRatio:false,\r\n            showNavigation: false,\r\n            showCopyright: false,\r\n            pan: {enabled: true, needTwoFingers: false},\r\n            zoom: {wheel: true}\r\n        });\r\n        board2.renderer.container.style.backgroundColor = 'gainsboro';\r\n\r\n        \/\/ objet graphe pour la creation des reprsentations graphiques et l'animation \r\n        class graph {\r\n            StateMachine=null; \r\n            history = [];\r\n            stateCircles = {};\r\n            stateTexts = {};\r\n            transitionArrows = {};\r\n            \r\n            constructor(State, brd, indice, entite, Strategie) {\r\n                this.strategie=Strategie;\r\n                this.entiteHTML=entite;\r\n                this.animationPoint = null;\r\n                this.Brd=brd;\r\n                this.StateMachine=JSON.parse(JSON.stringify(State));\r\n                this.history = [];\r\n                this.stateCircles = {};\r\n                this.stateTexts = {};\r\n                this.transitionArrows = {};\r\n                this.current_state=document.getElementById('current-state-'+indice);\r\n                this.state_description= document.getElementById('state-description-'+indice);\r\n                \/\/ ajoute le titre de la strategie \r\n                this.strateg = this.Brd.create(\"text\",[-0.5,7.5,\"\\\\(\\\\textrm{\"+Strategie[\"key\"]+\"}\\\\)\"],{fontSize:16,fixed:true,highlight:false,opacity:1,anchorX:'middle',anchorY:'middle',color:'red'});\r\n\r\n            }\r\n            update_title(strategie) {\r\n                this.strateg.setText(\"\\\\(\\\\textrm{\"+ strategie +\"}\\\\)\");\r\n            }\r\n            update_model(model ) {\r\n                let Model_variable=null;\r\n                eval(\"Model_variable=Archi_\"+model);\r\n                if (this.Brd!=null) {\r\n                    JXG.JSXGraph.freeBoard(this.Brd);\r\n                }\r\n                this.Brd= JXG.JSXGraph.initBoard(this.entiteHTML, {\r\n                    boundingbox: [-2, 8, 4, -2],\r\n                    axis: false,\r\n                    showNavigation: false,\r\n                    keepAspectRatio:false,\r\n                    showCopyright: false,\r\n                    pan: {enabled: true, needTwoFingers: false},\r\n                    zoom: {wheel: true}\r\n                });\r\n                this.Brd.renderer.container.style.backgroundColor = 'gainsboro';\r\n                this.strateg = this.Brd.create(\"text\",[-0.5,7.5,\"\\\\(\\\\textrm{\"+model+\"}\\\\)\"],{fontSize:16,fixed:true,highlight:false,opacity:1,anchorX:'middle',anchorY:'middle',color:'red'});                \r\n                \r\n                this.StateMachine=JSON.parse(JSON.stringify(Model_variable));\r\n                this.history = [];\r\n                this.stateCircles = {};\r\n                this.stateTexts = {};\r\n                this.transitionArrows = {};\r\n                \/\/ generation des objets graphiques pour le visuel \r\n                this.createStates();\r\n                this.createTransitions();\r\n                this.createComplementsVisuels();\r\n                this.updateVisuals();\r\n                this.updateUI();\r\n\r\n            }\r\n            \/\/ Cr\u00e9er les \u00e9tats visuels\r\n            createStates() {\r\n                Object.keys(this.StateMachine.states).forEach(stateName => {\r\n                    const state = this.StateMachine.states[stateName];\r\n                    const type = this.StateMachine.states[stateName].type;\r\n                    const [x, y] = state.position;\r\n                    if (type==\"etat\") {\r\n                        \/\/ Cercle pour l'\u00e9tat\r\n                        const circle = this.Brd.create('circle', [[x, y], 0.5],\r\n                        {strokeColor:  state.color,strokeWidth: 2,fillColor: state.color,fillOpacity: 1,fixed: true,highlight: false});\r\n                        let image=null;\r\n                        if (stateName.indexOf(\"COLLABORE\")!=-1)\r\n                            image = this.Brd.create('image', [\"\/personnalisation\/images\/poignee.png\",[x-0.3,y-0.2],[0.5,0.5]],\r\n                        {layer:50,strokeColor: state.color,strokeWidth: 2,fillColor: state.color,fillOpacity: 1,fixed: true,highlight: false});\r\n                        else \r\n                        image = this.Brd.create('image', [\"\/personnalisation\/images\/couteau.png\",[x-0.2,y-0.2],[0.3,0.5]],\r\n                        {layer:50,strokeColor: state.color,strokeWidth: 2,fillColor: state.color,fillOpacity: 1,fixed: true,highlight: false});\r\n\r\n                      \r\n                        \/\/ il faut rajouter un compteur si existe \r\n                        if (state.compteur) {\r\n                            const compteur = this.Brd.create('text', [x+0.2, y+0.2 ,\r\n                            `<span style=\"font-size:16px\">${state.compteur}<\/span>`\r\n                        ], {color:\"red\",visible:true,fontSize: 24,fixed: true,highlight: false,anchorX: 'middle',anchorY: 'middle'});    \r\n                        }\r\n                      \r\n                        \/\/ Texte avec emoji et label\r\n                        const text = this.Brd.create('text', [x+1, y+0.3 ,\r\n                            `${state.emoji}<br\/><span style=\"font-size:12px\">${state.label}<\/span>`\r\n                        ], {visible:false,fontSize: 24,fixed: true,highlight: false,anchorX: 'middle',anchorY: 'middle'});\r\n                        this.stateCircles[stateName] = circle;\r\n                        this.stateTexts[stateName] = text;\r\n                    }\r\n                });\r\n            }\r\n            \/\/ Cr\u00e9er les transitions\r\n            createTransitions() {\r\n                this.StateMachine.transitions.forEach((transition, index) => {\r\n                    const fromState = this.StateMachine.states[transition.from];\r\n                    const toState = this.StateMachine.states[transition.to];\r\n                    let [x1, y1] = fromState.position;\r\n                    let [x2, y2] = toState.position;\r\n                    let couleur=\"red\";\r\n                    let depart=0.35, end=1.13;\r\n                    if (transition.label==\"collabore\") {\r\n                        couleur=\"blue\";depart=-0.15; end=0.65;\r\n                    }\r\n                    \/\/ Auto-transition (boucle)\r\n                    if (transition.from === transition.to) {\r\n                        let signe=1;\r\n                        if (transition.label==\"trahison\")\r\n                            signe=-1\r\n                        const curve = this.Brd.create('curve', [\r\n                            function(t) { \r\n                                const angle = t * Math.PI * 2;\r\n                                return x1 + 0.8 * Math.cos(angle);\r\n                            },\r\n                            function(t) { \r\n                                const angle = t * Math.PI * 2;\r\n                                return y1 + signe * 0.5 + 0.8 * Math.sin(angle);\r\n                            },\r\n                            depart, end\r\n                        ], {StrokeColor: couleur,opacity:0.5,strokeWidth: 2,dash: 0,fixed: true,highlight: false,lastArrow: {type: 2, size: 6}});\r\n\r\n                        const labelText = this.Brd.create('text', [\r\n                            x1 + 0.8, y1 +signe*1.2, \"\\\\(\\\\textrm{\"+transition.label+\"}\\\\)\"\r\n                        ], {fontSize: 11,color: couleur,fixed: true,highlight: false});\r\n\r\n                        this.transitionArrows[`${transition.from}-${transition.to}-${index}`] = {\r\n                            curve,label: labelText,from: transition.from,to: transition.to,event: transition.event};\r\n                    } else {\r\n                        if (y1<y2) {  \/\/ on remonte\r\n                            y1+=0.5;x1-=0.2;y2-=0.5;x2-=0.2;  \/\/ pour \u00e9viter qu'il commence par la centre\r\n                        }\r\n                        else {  \/\/ on descend \r\n                            y1-=0.5;x1+=0.2;y2+=0.5;x2+=0.2;  \/\/ pour \u00e9viter qu'il commence par la centre\r\n                        }\r\n                        \/\/ Transition normale avec courbe\r\n                        const dx = x2 - x1;\r\n                        const dy = y2 - y1;\r\n                        const dist = Math.sqrt(dx * dx + dy * dy);                        \r\n                        \/\/ Point de contr\u00f4le pour la courbe\r\n                        const midX = (x1 + x2) \/ 2;\r\n                        const midY = (y1 + y2) \/ 2;\r\n                        const offsetX = -dy \/ dist * 0.9;\r\n                        const offsetY = dx \/ dist * 0.8;\r\n                        let curve= this.Brd.create('curve', [\r\n                            function(t) {\r\n                                return (1-t)*(1-t)*x1 + 2*(1-t)*t*(midX + 0.10*(dy*dy)*offsetX) + t*t*x2;\r\n                            },\r\n                            function(t) {\r\n                                return (1-t)*(1-t)*y1 + 2*(1-t)*t*(midY + offsetY) + t*t*y2;\r\n                            },\r\n                            0, 1\r\n                        ], {opacity:0.5,strokeColor: couleur,strokeWidth: 3,dash: 0,fixed: true,highlight: false,lastArrow: {type: 2, size: 6}});\r\n\r\n                        const labelText = this.Brd.create('text', [\r\n                            midX + + 0.10*(dy*dy)*offsetX\/2, midY + offsetY, \"\\\\(\\\\textrm{\"+transition.label+\"}\\\\)\"\r\n                        ], {fontSize: 11,color: couleur,fixed: true,highlight: false,anchorX: 'middle',anchorY: 'middle'});\r\n\r\n                        this.transitionArrows[`${transition.from}-${transition.to}-${index}`] = {\r\n                            curve,label: labelText,from: transition.from,to: transition.to,event: transition.event,controlPoint: [midX +  0.10*(dy*dy)*offsetX, midY + offsetY]\r\n                        };\r\n                    }\r\n                });\r\n            }\r\n            \/\/ fonction de generation des complements visuels pour les strategies qui ont en besoin \r\n            \/\/ Nydegger et autres \r\n            createComplementsVisuels() {\r\n                if (this.strategie.complements!=undefined) {\r\n                    if (this.strategie.complements[\"visuelHistoAdv\"]) {\r\n                        this.zone_histoADV=[];\r\n                        const nb=this.strategie.complements[\"visuelHistoAdv\"];\r\n                        const hauteur=nb*0.5;\r\n                        \/\/ creation des complements visuels \r\n                        this.Brd.create(\"polygon\",[[-1.5,6],[-1,6],[-1,6-hauteur],[-1.5,6-hauteur]],{highlight:false,vertices:{visible:false},fillColor:\"red\"});\r\n                        \r\n                        this.Brd.create(\"text\",[-1.8,6.5,\"\\\\(\\\\textrm{M\u00e9moires ADV}\\\\)\"]);\r\n                        for (let i=0;i<nb; i++) {\r\n                            const Z=this.Brd.create(\"text\",[-1.5+0.2,5.8-(i*0.5),\" \"]);\r\n                            this.zone_histoADV.push(Z);\r\n                        }\r\n                    }\r\n                    if (this.strategie.complements[\"visuelHistoMe\"]) {\r\n                        this.zone_histoME=[];\r\n                        const nb=this.strategie.complements[\"visuelHistoMe\"];\r\n                        const hauteur=nb*0.5;\r\n                        this.Brd.create(\"polygon\",[[3,6],[3.5,6],[3.5,6-hauteur],[3,6-hauteur]],{highlight:false,vertices:{visible:false},fillColor:\"lightblue\"});\r\n                        this.Brd.create(\"text\",[2.5,6.5,\"\\\\(\\\\textrm{M\u00e9moires ME}\\\\)\"]);\r\n                        \/\/ zones de textes pour l'info des strategies pass\u00e9es \r\n                        for (let i=0;i<nb; i++) {\r\n                            const Z=this.Brd.create(\"text\",[3+0.2,5.8-(i*0.5),\" \"]);\r\n                            this.zone_histoME.push(Z);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            complete_memories(histoAdv, histoMe) {\r\n                if (this.strategie.complements!=undefined) {\r\n                    if (this.strategie.complements[\"visuelHistoAdv\"]) {\r\n                        for (let i=0;i<3; i++) {\r\n                            this.zone_histoADV[i].setText(\" \");\r\n                        }\r\n                        for (let i=0;i<3; i++) {\r\n                            if (histoAdv[histoAdv.length-1-i]!=undefined)\r\n                                this.zone_histoADV[i].setText(histoAdv[histoAdv.length-1-i]);\r\n                        }\r\n                    }\r\n                    if (this.strategie.complements[\"visuelHistoMe\"]) {\r\n                        for (let i=0;i<3; i++) {\r\n                            this.zone_histoME[i].setText(\" \");\r\n                        }\r\n                        for (let i=0;i<3; i++) {\r\n                            if (histoMe[histoMe.length-1-i]!=undefined)\r\n                                this.zone_histoME[i].setText(histoMe[histoMe.length-1-i]);\r\n                        }\r\n                    }\r\n                }\r\n\r\n            }\r\n            \/\/ Mettre \u00e0 jour l'apparence selon l'\u00e9tat actuel\r\n            updateVisuals() {\r\n                Object.keys(this.stateCircles).forEach(stateName => {\r\n                    const isActive = stateName === this.StateMachine.currentState;\r\n                    const state = this.StateMachine.states[stateName];\r\n                    \r\n                    this.stateCircles[stateName].setAttribute({\r\n                        \/\/fillColor: isActive ? '#4ECDC4' : state.color,\r\n                        fillOpacity: isActive ? 0.9 : 0.9,\r\n                        strokeWidth: isActive ? 5 : 3\r\n                    });\r\n                });\r\n\r\n                \/\/ Mettre \u00e0 jour les transitions disponibles\r\n                Object.keys(this.transitionArrows).forEach(key => {\r\n                    const transition = this.transitionArrows[key];\r\n                    const isAvailable = transition.from === this.createStates.currentState;\r\n                    \r\n                    \/*transition.curve.setAttribute({\r\n                        strokeColor: isAvailable ? '#4ECDC4' : '#999',\r\n                        strokeWidth: isAvailable ? 3 : 2,\r\n                        \/\/dash: isAvailable ? 0 : 2\r\n                    });*\/\r\n                    \r\n                    \/*transition.label.setAttribute({\r\n                        color: isAvailable ? '#4ECDC4' : '#666'\r\n                    });*\/\r\n                });\r\n\r\n                this.Brd.update();\r\n            }\r\n            \/\/ Mettre \u00e0 jour l'interface\r\n            updateUI() {\r\n                const currentState = this.StateMachine.states[this.StateMachine.currentState];\r\n                this.current_state.textContent = currentState.label;\r\n                this.state_description.textContent = currentState.description;\r\n\r\n                \/\/ Activer\/d\u00e9sactiver les boutons d'\u00e9v\u00e9nements\r\n                \/*document.querySelectorAll('.event-btn').forEach(btn => {\r\n                    const event = btn.getAttribute('data-event');\r\n                    const isAvailable = stateMachine.transitions.some(\r\n                        t => t.from === stateMachine.currentState && t.event === event\r\n                    );\r\n                    btn.disabled = !isAvailable;\r\n                });*\/\r\n            }\r\n        } \/\/ fin de la defintion de la classe \r\n\r\n\r\n       \r\n        \/\/ Ajouter \u00e0 l'historique\r\n        function addToHistory(event, fromState, toState) {\r\n            const time = new Date().toLocaleTimeString();\r\n            const from = stateMachine.states[fromState];\r\n            const to = stateMachine.states[toState];\r\n            \r\n            history.unshift({ time, event, from: from.label, to: to.label });\r\n            if (history.length > 20) history.pop();\r\n\r\n            const historyDiv = document.getElementById('history');\r\n            historyDiv.innerHTML = history.map(item => `\r\n                <div class=\"history-item\">\r\n                    <div><strong>${item.from}<\/strong> \u2192 <strong>${item.to}<\/strong><\/div>\r\n                    <div>\u00c9v\u00e9nement: ${item.event}<\/div>\r\n                    <div class=\"time\">${item.time}<\/div>\r\n                <\/div>\r\n            `).join('');\r\n        }\r\n\r\n        \/\/ ajoute deux choix dans l'historique \r\n        const ajoute_histo=function(choix1, choix2) {\r\n            let IMG1=null, IMG2=null,color1=\"red\",color2=\"lightblue\";\r\n            choix1==\"T\"?IMG1=\"\/personnalisation\/images\/couteau.png\":IMG1=\"\/personnalisation\/images\/poignee.png\";\r\n            choix2==\"T\"?IMG2=\"\/personnalisation\/images\/couteau.png\":IMG2=\"\/personnalisation\/images\/poignee.png\";\r\n            choix1==\"T\"?color1=\"#F87C63\":color1=\"lightblue\";\r\n            choix2==\"T\"?color2=\"#F87C63\":color2=\"lightblue\";\r\n\r\n            const historyDiv = document.getElementById('history');\r\n            \r\n            \r\n            const nouv1=document.createElement(\"div\");\r\n            nouv1.className = 'fighter';\r\n            const img=document.createElement('img');\r\n            img.src=IMG1;\r\n            img.setAttribute(\"width\",\"30px\")\r\n            img.setAttribute(\"height\",\"30px\")\r\n            nouv1.appendChild(img);\r\n            nouv1.style.backgroundColor = color1;\r\n            \r\n            const nouv2=document.createElement(\"div\");\r\n            nouv2.className = 'fighter';\r\n            const img2=document.createElement('img');\r\n            img2.src=IMG2;\r\n            img2.setAttribute(\"width\",\"30px\")\r\n            img2.setAttribute(\"height\",\"30px\")\r\n            nouv2.appendChild(img2);\r\n            nouv2.style.backgroundColor = color2;\r\n            \r\n            const box=document.createElement(\"div\");\r\n            box.setAttribute(\"class\",\"box\");\r\n            box.appendChild(nouv1);\r\n            box.appendChild(nouv2);\r\n\r\n            historyDiv.appendChild(box);\r\n\r\n        }\r\n        function avance21() {\r\n            animateTransition(graph1, \"COLLABORE\",\"TRAHIE\",\"COLLABORE-TRAHIE-0\");\r\n            animateTransition(graph2, \"TRAHIE\",\"COLLABORE\",\"TRAHIE-COLLABORE-4\");\r\n            ajoute_histo(\"T\",\"C\");   \r\n            graph1.StateMachine.currentState = \"TRAHIE\";\r\n            \/\/addToHistory(event, currentState, transition.to);\r\n            graph1.updateVisuals();\r\n            graph1.updateUI();\r\n            graph2.StateMachine.currentState = \"COLLABORE\";\r\n            \/\/addToHistory(event, currentState, transition.to);\r\n            graph2.updateVisuals();\r\n            graph2.updateUI();\r\n\r\n \r\n        }\r\n        function avance(graphe, choix_prec, choix ) {\r\n            let etat1=\"\",etat2=\"\";\r\n            choix_prec==\"C\"?etat1=\"COLLABORE\":etat1=\"TRAHIE\";\r\n            choix==\"C\"?etat2=\"COLLABORE\":etat2=\"TRAHIE\";\r\n            \/\/ il faut recherche la trasition qui correspond \u00e0 ce changement \r\n            let transition = Object.keys(graphe.transitionArrows).find(e=>(e.indexOf(etat1+\"-\"+etat2)!=-1))\r\n            \/\/ console.log(choix_prec,choix,transition);\r\n            animateTransition(graphe, etat1,etat2,transition);\r\n            \r\n            graphe.StateMachine.currentState = etat2;\r\n            \/\/addToHistory(event, currentState, transition.to);\r\n            graphe.updateVisuals();\r\n            graphe.updateUI(); \r\n        }\r\n\r\n        \/\/ Animer la transition pour un graphe \r\n        async function animateTransition(grp, fromState, toState, transitionKey) {\r\n            const transition = grp.transitionArrows[transitionKey];\r\n            if (!transition) return;\r\n\r\n            const fromPos = grp.StateMachine.states[fromState].position;\r\n            const toPos = grp.StateMachine.states[toState].position;\r\n\r\n            \/\/ Cr\u00e9er un point d'animation\r\n            if (grp.animationPoint) {\r\n                grp.Brd.removeObject(grp.animationPoint);\r\n            }\r\n\r\n            grp.animationPoint = grp.Brd.create('point', fromPos, {\r\n                name: '',\r\n                size: 8,\r\n                fillColor: '#e74c3c',\r\n                strokeColor: 'white',\r\n                strokeWidth: 2,\r\n                fixed: true\r\n            });\r\n\r\n            \/\/ Animer le point le long de la courbe\r\n            return new Promise(resolve => {\r\n                let progress = 0;\r\n                const animate = () => {\r\n                    progress += 0.08;\r\n                    \r\n                    if (transition.controlPoint) {\r\n                        const [cx, cy] = transition.controlPoint;\r\n                        const t = progress;\r\n                        const x = (1-t)*(1-t)*fromPos[0] + 2*(1-t)*t*cx + t*t*toPos[0];\r\n                        const y = (1-t)*(1-t)*fromPos[1] + 2*(1-t)*t*cy + t*t*toPos[1];\r\n                        grp.animationPoint.moveTo([x, y], 0);\r\n                    } else {\r\n                        \/\/ Pour les auto-transitions\r\n                        const angle = progress * Math.PI * 2;\r\n                        const x = fromPos[0] + 0.8 * Math.cos(angle);\r\n                        const y = fromPos[1] + 0.5 + 0.8 * Math.sin(angle);\r\n                        grp.animationPoint.moveTo([x, y], 0);\r\n                    }\r\n\r\n                    grp.Brd.update();\r\n\r\n                    if (progress < 1) {\r\n                        requestAnimationFrame(animate);\r\n                    } else {\r\n                        grp.Brd.removeObject(grp.animationPoint);\r\n                        grp.animationPoint = null;\r\n                        resolve();\r\n                    }\r\n                };\r\n                animate();\r\n            });\r\n        }\r\n\r\n        \/\/ D\u00e9clencher un \u00e9v\u00e9nement\r\n        async function triggerEvent(event) {\r\n            const currentState = stateMachine.currentState;\r\n            const transitions = stateMachine.transitions.filter(\r\n                t => t.from === currentState && t.event === event\r\n            );\r\n\r\n            if (transitions.length > 0) {\r\n                const transition = transitions[0];\r\n                const transitionKey = Object.keys(transitionArrows).find(key => {\r\n                    const t = transitionArrows[key];\r\n                    return t.from === currentState && t.to === transition.to && t.event === event;\r\n                });\r\n\r\n                if (transitionKey) {\r\n                    await animateTransition(currentState, transition.to, transitionKey);\r\n                }\r\n\r\n                stateMachine.currentState = transition.to;\r\n                addToHistory(event, currentState, transition.to);\r\n                updateVisuals();\r\n                updateUI();\r\n            }\r\n        }\r\n\r\n        \/\/ R\u00e9initialiser le syst\u00e8me\r\n        function resetSystem() {\r\n            \r\n            graph1.StateMachine.currentState = 'COLLABORE';\r\n            graph2.StateMachine.currentState = 'TRAHIE';\r\n            history = [];\r\n            document.getElementById('history').innerHTML = '';\r\n            graph1.updateVisuals();\r\n            graph1.updateUI();\r\n            graph2.updateVisuals();\r\n            graph2.updateUI();\r\n            ajoute_histo(\"C\",\"T\");\r\n            \/\/ pour arreter le chrono si il tourne\r\n            if (declenche!=null) \r\n                clearInterval(declenche);\r\n\r\n        }\r\n\r\n        \/\/ Event listeners\r\n        document.querySelectorAll('.event-btn').forEach(btn => {\r\n            btn.addEventListener('click', () => {\r\n               \/\/ const event = btn.getAttribute('data-event');\r\n               \/\/ triggerEvent(event);\r\n            });\r\n        });\r\n\r\n\r\n\r\n\/\/ chargement des droplists \r\nconst charge_structure=function(user, strateg) {\r\n      const zone=document.getElementById(\"droplist-\"+user);\r\n      \/\/ on ajoute les items dans la liste correspondante\r\n      Object.keys(tableau_strategies).forEach(groupe=> {\r\n        \/\/ on affiche le nom du groupe des strat\u00e9gies \r\n        const div_groupe=document.createElement(\"div\"); \r\n        div_groupe.setAttribute(\"class\",\"droplist-groupe\");\r\n        div_groupe.setAttribute(\"data-value\",groupe);\r\n        div_groupe.innerHTML=\"\\\\(\\\\textrm{\"+ groupe+ \"}\\\\)\";\r\n        zone.appendChild(div_groupe);\r\n        tableau_strategies[groupe].forEach(item=> {\r\n          const div_item=document.createElement(\"div\"); \r\n          div_item.setAttribute(\"z-index\",\"2000\");\r\n          div_item.setAttribute(\"class\",\"droplist-item\");\r\n          div_item.setAttribute(\"data-value\",item.key);\r\n          div_item.setAttribute(\"data-text\",item.text);\r\n          div_item.item=item;\r\n          div_item.innerText=\"\\\\(\\\\textrm{\"+item.text+ \"}\\\\)\";\r\n          zone.appendChild(div_item);\r\n          div_item.addEventListener(\"mouseover\", function(event) {\r\n              const value= this.getAttribute(\"data-value\");\r\n              \/\/ showCommentOverlay(value);\r\n          })\r\n          div_item.addEventListener(\"mouseleave\", function(event) {\r\n              const value= this.getAttribute(\"data-value\");\r\n              \/\/ document.getElementById(\"commentBoard\").style.display=\"none\";\r\n          })\r\n          div_item.addEventListener(\"click\", function(event) {\r\n              const value= this.getAttribute(\"data-text\");\r\n              \/\/ on compl\u00e8te l'affichage \r\n              \/\/strateg.setText(value);\r\n              \/\/document.getElementById(\"commentBoard\").style.display=\"none\";\r\n          })\r\n\r\n        });\r\n      })\r\n      MathJax.typesetPromise(); \r\n  }\r\n  const charge_comportement_structure=function(lbl, graphe) {\r\n      const droplist = document.getElementById('myDroplist-'+lbl);\r\n      const selectedValue = document.getElementById('selectedValue-'+lbl);\r\n      \r\n      const header = droplist.querySelector('.droplist-header');\r\n      const arrow = droplist.querySelector('.droplist-arrow');\r\n      const list = droplist.querySelector('.droplist-list');\r\n      const items = droplist.querySelectorAll('.droplist-item');\r\n      \/\/ Ouvrir\/fermer la liste\r\n      header.addEventListener('click', () => {\r\n          list.classList.toggle('open');\r\n          arrow.classList.toggle('rotate');\r\n          header.classList.toggle('active');\r\n      });\r\n      \/\/ S\u00e9lectionner un \u00e9l\u00e9ment\r\n      items.forEach(item => {\r\n          item.addEventListener('click', (e) => {\r\n              e.stopPropagation();              \r\n              items.forEach(i => i.classList.remove('selected'));\r\n              item.classList.add('selected');\r\n              const mathContent = item.innerHTML;\r\n              const value = item.getAttribute('data-value');\r\n              selectedValue.innerHTML = mathContent;\r\n              selectedValue.setAttribute(\"data-value\",value);   \r\n              selectedValue.item=item.item; \/\/ pour recup\u00e8rer les infos complets sur la strategie\r\n              graphe.strategie=item.item;\r\n              \/\/ graphe.update_title(value);\r\n              graphe.update_model(value);\r\n              \r\n              list.classList.remove('open');\r\n              arrow.classList.remove('rotate');\r\n              header.classList.remove('active');\r\n              MathJax.typesetPromise(); \r\n          });\r\n      });\r\n  }\r\n\r\n        \/\/document.getElementById('reset-btn').addEventListener('click', resetSystem);\r\n\r\n        \/\/ Initialisation\r\n        const graph1=new graph(Archi_TidemanAndChieruzzi, board,1,\"jxgbox_candidat1\",tableau_strategies[\"Premier Tournois (1980)\"][1]);\r\n        graph1.createStates();\r\n        graph1.createTransitions();\r\n        \/\/graph1.StateMachine.currentState = 'COLLABORE';\r\n        graph1.updateVisuals();\r\n        graph1.updateUI();\r\n        \r\n        const graph2=new graph(Archi_TidemanAndChieruzzi, board2,2,\"jxgbox_candidat2\",tableau_strategies[\"Premier Tournois (1980)\"][1]);\r\n        graph2.createStates();\r\n        graph2.createTransitions();\r\n        \/\/graph2.StateMachine.currentState = 'TRAHIE';\r\n        graph2.updateVisuals();\r\n        graph2.updateUI();\r\n        choix1=\"T\";choix2=\"T\";\r\n        \/\/  ajoute_histo(\"C\",\"T\");    \r\n        \/\/ updateVisuals();\r\n        \/\/ updateUI();\r\n\r\n        charge_structure(\"User1\", graph1.strateg); \r\n        charge_structure(\"User2\", graph1.strateg);\r\n        charge_comportement_structure(\"User1\", graph1);\r\n        charge_comportement_structure(\"User2\", graph2);\r\n\r\n\r\n\r\n\r\n    <\/script>\r\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-11085","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/spgoo.org\/index.php?rest_route=\/wp\/v2\/pages\/11085","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spgoo.org\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/spgoo.org\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/spgoo.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spgoo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11085"}],"version-history":[{"count":1,"href":"https:\/\/spgoo.org\/index.php?rest_route=\/wp\/v2\/pages\/11085\/revisions"}],"predecessor-version":[{"id":11086,"href":"https:\/\/spgoo.org\/index.php?rest_route=\/wp\/v2\/pages\/11085\/revisions\/11086"}],"wp:attachment":[{"href":"https:\/\/spgoo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11085"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}