{"id":9985,"date":"2025-12-16T10:59:40","date_gmt":"2025-12-16T10:59:40","guid":{"rendered":"https:\/\/www.animcloud.fr\/?page_id=9985"},"modified":"2025-12-16T10:59:42","modified_gmt":"2025-12-16T10:59:42","slug":"machine-a-sous","status":"publish","type":"page","link":"https:\/\/www.animcloud.fr\/en\/machine-a-sous\/","title":{"rendered":"MACHINE A SOUS"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"fr\">\n<head>\n<meta charset=\"UTF-8\">\n<title>Casino Royal &#8211; Dual Screen Admin<\/title>\n\n<style>\n\/* ===== DESIGN G\u00c9N\u00c9RAL ===== *\/\nbody{\n  background:radial-gradient(circle at top,#222,#000);\n  height:100vh;\n  margin:0;\n  display:flex;\n  justify-content:center;\n  align-items:center;\n  font-family:'Segoe UI',sans-serif;\n  color:white;\n  overflow: hidden;\n}\n\n\/* ===== MACHINE ===== *\/\n.machine{\n  width:900px;\n  background:linear-gradient(180deg,#4a2f00,#f5c400,#4a2f00);\n  padding:20px;\n  border-radius:25px;\n  box-shadow:0 0 50px #000;\n  position: relative;\n}\n\n\/* ===== JACKPOT ===== *\/\n.jackpot{\n  background:black;\n  color:red;\n  font-size:30px;\n  padding:10px;\n  border-radius:10px;\n  text-align:center;\n  margin-bottom:15px;\n  text-shadow:0 0 15px red;\n}\n\n\/* ===== GRILLE ===== *\/\n.screen{\n  background:#111;\n  padding:12px;\n  border-radius:15px;\n  display:grid;\n  grid-template-columns:repeat(5,1fr);\n  gap:6px;\n  height:270px;\n  box-shadow:inset 0 0 20px black;\n}\n\n.reel{\n  background:white;\n  border-radius:8px;\n  display:flex;\n  flex-direction:column;\n  justify-content:center;\n  overflow:hidden;\n}\n\n.symbol{\n  height:85px;\n  font-size:52px;\n  display:flex;\n  justify-content:center;\n  align-items:center;\n}\n\n\/* Animation Gain *\/\n.win{\n  background:radial-gradient(circle,#fff,#ffe600);\n  animation:winFlash .6s infinite alternate;\n  filter:drop-shadow(0 0 10px gold);\n  z-index: 10;\n}\n@keyframes winFlash{\n  from{transform:scale(1)}\n  to{transform:scale(1.15)}\n}\n\n\/* ===== DASHBOARD ===== *\/\n.dashboard{\n  margin-top:15px;\n  background:#222;\n  padding:15px;\n  border-radius:12px;\n  display:flex;\n  justify-content:space-between;\n  align-items:center;\n}\n\n.lcd{\n  background:black;\n  color:#0f0;\n  padding:10px;\n  border-radius:5px;\n  font-family:monospace;\n  min-width:130px;\n  text-align:center;\n}\n\nbutton{\n  cursor:pointer;\n  border:none;\n  border-radius:8px;\n  padding:10px 20px;\n  font-size:18px;\n  font-weight:bold;\n}\n\n.spin{\n  background:red;\n  color:white;\n  box-shadow:0 0 20px red;\n  animation:pulse 1.2s infinite;\n}\n\n.spin:disabled{background:#555;box-shadow:none;animation:none;}\n\n@keyframes pulse{\n  0%{transform:scale(1)}\n  50%{transform:scale(1.05)}\n  100%{transform:scale(1)}\n}\n\n.betbtn{background:#ddd;}\n\n#status{\n  text-align:center;\n  height:26px;\n  margin-top:5px;\n  font-weight:bold;\n  color: #f5c400;\n}\n\n.legend{\n  margin-top:15px;\n  background:#111;\n  padding:15px;\n  border-radius:12px;\n  font-size:14px;\n  box-shadow:inset 0 0 15px black;\n  display: flex;\n  justify-content: space-around;\n}\n.legend p { margin: 0; text-align: center; }\n\n\/* BOUTON ADMIN DISCRET *\/\n.admin-btn {\n  position: absolute;\n  bottom: 10px;\n  right: 10px;\n  background: #333;\n  color: #888;\n  font-size: 12px;\n  padding: 5px 10px;\n  border: 1px solid #555;\n  opacity: 0.5;\n}\n.admin-btn:hover { opacity: 1; background: #000; color: white; }\n\n<\/style>\n<\/head>\n\n<body>\n\n<div class=\"machine\">\n  <div class=\"jackpot\">JACKPOT : <span id=\"jackpot\">12500.00<\/span> \u20ac<\/div>\n  <div class=\"screen\" id=\"grid\"><\/div>\n  <div id=\"status\">\ud83c\udfb0 Pr\u00eat \u00e0 jouer<\/div>\n\n  <div class=\"dashboard\">\n    <div class=\"lcd\">SOLDE<br><span id=\"balance\">1000<\/span><\/div>\n    <div>\n      <button class=\"betbtn\" onclick=\"changeBet(-1)\">&#8211;<\/button>\n      <span style=\"margin:0 10px;font-size:20px\" id=\"bet\">2<\/span>\n      <button class=\"betbtn\" onclick=\"changeBet(1)\">+<\/button>\n    <\/div>\n    <button class=\"spin\" onclick=\"spin()\" id=\"spinBtn\">SPIN<\/button>\n    <div class=\"lcd\">GAIN<br><span id=\"win\">0<\/span><\/div>\n  <\/div>\n\n  <div class=\"legend\">\n    <p>\ud83c\udf52\ud83c\udf4b\ud83c\udf47 x2 | \ud83d\udd14 x5<\/p>\n    <p>\ud83d\udc8e x10 | 7\ufe0f\u20e3 x25<\/p>\n    <p>\ud83c\udccf WILD | \u2b50 BONUS<\/p>\n  <\/div>\n  \n  <button class=\"admin-btn\" onclick=\"openAdminWindow()\">\u2699\ufe0f Ouvrir Admin<\/button>\n<\/div>\n\n<script>\n\/* ===== CONFIG DATA ===== *\/\nconst symbols = ['\ud83c\udf52','\ud83c\udf4b','\ud83c\udf47','\ud83d\udd14','\ud83d\udc8e','7\ufe0f\u20e3','\u2b50','\ud83c\udccf'];\nconst payouts = {'\ud83c\udf52':2,'\ud83c\udf4b':2,'\ud83c\udf47':2,'\ud83d\udd14':5,'\ud83d\udc8e':10,'7\ufe0f\u20e3':25};\nconst paylinesDef = [\n  [{r:0,c:0},{r:0,c:1},{r:0,c:2},{r:0,c:3},{r:0,c:4}],\n  [{r:1,c:0},{r:1,c:1},{r:1,c:2},{r:1,c:3},{r:1,c:4}],\n  [{r:2,c:0},{r:2,c:1},{r:2,c:2},{r:2,c:3},{r:2,c:4}],\n  [{r:0,c:0},{r:1,c:1},{r:2,c:2},{r:1,c:3},{r:0,c:4}],\n  [{r:2,c:0},{r:1,c:1},{r:0,c:2},{r:1,c:3},{r:2,c:4}]\n];\n\n\/* ===== \u00c9TATS DU JEU ===== *\/\nlet balance = 1000, bet = 2, jackpot = 12500;\nlet freeSpins = 0, spinning = false;\n\n\/\/ VARIABLES ADMIN (Accessibles depuis la fen\u00eatre popup)\nwindow.winRate = 30;    \/\/ % de chance de gagner (lignes normales)\nwindow.bonusRate = 10;  \/\/ % de chance de d\u00e9clencher le BONUS (ind\u00e9pendant)\n\nlet targetGrid = []; \nconst grid = document.getElementById(\"grid\");\nconst status = document.getElementById(\"status\");\nconst spinBtn = document.getElementById(\"spinBtn\");\nlet reelsDOM = []; \n\n\/* ===== INIT ===== *\/\nfunction init(){\n  grid.innerHTML = \"\";\n  reelsDOM = [];\n  for(let c=0; c<5; c++){\n    let col = document.createElement(\"div\");\n    col.className = \"reel\";\n    let arr = [];\n    for(let r=0; r<3; r++){\n      let s = document.createElement(\"div\");\n      s.className = \"symbol\";\n      s.textContent = \"7\ufe0f\u20e3\";\n      col.appendChild(s);\n      arr.push(s);\n    }\n    grid.appendChild(col);\n    reelsDOM.push(arr);\n  }\n}\ninit();\n\n\/* ===== GESTION FEN\u00caTRE ADMIN ===== *\/\nlet adminWindow = null;\n\nfunction openAdminWindow(){\n  \/\/ Configuration de la popup\n  const width = 350;\n  const height = 450;\n  const left = (screen.width - width) \/ 2;\n  const top = (screen.height - height) \/ 2;\n  \n  adminWindow = window.open(\"\", \"AdminPanel\", `width=${width},height=${height},top=${top},left=${left}`);\n  \n  if(!adminWindow){\n    alert(\"\u26a0\ufe0f Pop-up bloqu\u00e9e ! Autorisez les pop-ups pour voir l'admin.\");\n    return;\n  }\n\n  \/\/ Contenu HTML de la fen\u00eatre Admin\n  const htmlContent = `\n    <!DOCTYPE html>\n    <html lang=\"fr\">\n    <head>\n      <style>\n        body { background: #111; color: white; font-family: sans-serif; padding: 20px; text-align: center; border: 4px solid red; }\n        h2 { color: red; margin-top: 0; }\n        .control { margin: 25px 0; background: #222; padding: 15px; border-radius: 10px; }\n        input[type=range] { width: 100%; cursor: pointer; }\n        .val { color: #f5c400; font-weight: bold; font-size: 24px; display: block; margin-top: 5px; }\n        button { background: red; color: white; border: none; padding: 10px 20px; font-weight: bold; cursor: pointer; border-radius: 5px; }\n        p { font-size: 12px; color: #aaa; }\n      <\/style>\n    <\/head>\n    <body>\n      <h2>\ud83d\udc6e\u200d\u2642\ufe0f ADMIN CONTROL<\/h2>\n      \n      <div class=\"control\">\n        <label>\ud83c\udfaf Taux de Victoire (Lignes)<\/label>\n        <input type=\"range\" min=\"0\" max=\"100\" value=\"${window.winRate}\" oninput=\"updateWin(this.value)\">\n        <span id=\"winVal\" class=\"val\">${window.winRate}%<\/span>\n      <\/div>\n\n      <div class=\"control\">\n        <label>\u2b50 Taux de BONUS (Free Spins)<\/label>\n        <input type=\"range\" min=\"0\" max=\"100\" value=\"${window.bonusRate}\" oninput=\"updateBonus(this.value)\">\n        <span id=\"bonusVal\" class=\"val\">${window.bonusRate}%<\/span>\n      <\/div>\n\n      <p>Les modifications sont imm\u00e9diates pour le prochain tour.<\/p>\n      <button onclick=\"window.close()\">Fermer<\/button>\n\n      <script>\n        \/\/ Fonctions ex\u00e9cut\u00e9es DANS la popup pour parler \u00e0 la fen\u00eatre principale (opener)\n        function updateWin(v) {\n          document.getElementById('winVal').innerText = v + '%';\n          if(window.opener) window.opener.winRate = parseInt(v);\n        }\n        function updateBonus(v) {\n          document.getElementById('bonusVal').innerText = v + '%';\n          if(window.opener) window.opener.bonusRate = parseInt(v);\n        }\n      <\\\/script>\n    <\/body>\n    <\/html>\n  `;\n  \n  adminWindow.document.write(htmlContent);\n  adminWindow.document.close();\n}\n\n\n\/* ===== LOGIQUE DE JEU ===== *\/\nfunction changeBet(v){\n  if(spinning || freeSpins > 0) return;\n  bet = Math.max(1, Math.min(100, bet + v));\n  document.getElementById(\"bet\").textContent = bet;\n}\n\nfunction spin(){\n  if(spinning) return;\n\n  if(freeSpins === 0){\n    if(balance < bet){ status.textContent = \"\u274c Solde insuffisant\"; return; }\n    balance -= bet;\n    jackpot += bet * 0.05;\n  } else {\n    freeSpins--;\n    status.textContent = \"\ud83c\udf81 FREE SPIN (\" + freeSpins + \")\";\n  }\n\n  spinning = true;\n  spinBtn.disabled = true;\n  document.getElementById(\"balance\").textContent = balance.toFixed(0);\n  document.getElementById(\"win\").textContent = 0;\n  clearWins();\n\n  \/\/ 1. CALCUL DU R\u00c9SULTAT (TRUQU\u00c9)\n  targetGrid = calculateRiggedResult();\n\n  \/\/ 2. LANCEMENT ANIMATION\n  startReelAnimation(0);\n}\n\nfunction startReelAnimation(c){\n  if(c >= 5){ finishSpinProcessing(); return; }\n\n  let speed = 60;\n  let loops = 0;\n  let minLoops = 10 + (c * 3);\n\n  let anim = setInterval(() => {\n    for(let r=0; r<3; r++) reelsDOM[c][r].textContent = symbols[Math.floor(Math.random() * symbols.length)];\n    loops++;\n    if(loops > minLoops){\n      clearInterval(anim);\n      for(let r=0; r<3; r++) reelsDOM[c][r].textContent = targetGrid[c][r];\n      startReelAnimation(c + 1);\n    }\n  }, speed);\n}\n\n\/* ===== COEUR DE L'ALGO TRUQU\u00c9 ===== *\/\nfunction calculateRiggedResult(){\n  \n  \/\/ Lecture des valeurs d\u00e9finies par l'admin\n  let wantBonus = Math.random() * 100 < window.bonusRate;\n  let wantWin = Math.random() * 100 < window.winRate;\n\n  let tempGrid = [];\n  let attempts = 0;\n\n  do {\n    attempts++;\n    tempGrid = generateRandomGrid();\n    \n    \/\/ Analyse de la grille g\u00e9n\u00e9r\u00e9e\n    let analysis = analyzeGrid(tempGrid);\n    let hasBonus = analysis.scatters >= 3;\n    let hasWin = analysis.totalWin > 0;\n\n    \/\/ S\u00c9CURIT\u00c9 (\u00e9viter boucle infinie)\n    if(attempts > 1000) break;\n\n    \/\/ CAS 1 : On VEUT un BONUS (Priorit\u00e9 absolue)\n    if(wantBonus) {\n      if(hasBonus) break; \/\/ On a trouv\u00e9 un bonus, on garde !\n      continue; \/\/ Sinon on recommence\n    }\n\n    \/\/ CAS 2 : On ne veut PAS de Bonus (pour \u00e9viter d'en donner par erreur quand on veut juste perdre)\n    if(hasBonus) continue; \/\/ Rejet des bonus accidentels\n\n    \/\/ CAS 3 : On VEUT gagner (Lignes normales)\n    if(wantWin) {\n      if(hasWin) break;\n      continue;\n    }\n\n    \/\/ CAS 4 : On VEUT perdre\n    if(!wantWin) {\n      if(!hasWin) break;\n      continue;\n    }\n\n  } while(true);\n\n  return tempGrid;\n}\n\n\/* ===== OUTILS ===== *\/\nfunction generateRandomGrid(){\n  let g = [];\n  for(let c=0; c<5; c++){\n    let col = [];\n    for(let r=0; r<3; r++){\n      let rdm = Math.random();\n      let s;\n      if(rdm < 0.35) s = '\ud83c\udf52';\n      else if(rdm < 0.55) s = '\ud83c\udf4b';\n      else if(rdm < 0.70) s = '\ud83c\udf47';\n      else if(rdm < 0.85) s = '\ud83d\udd14';\n      else if(rdm < 0.92) s = '\ud83d\udc8e';\n      else if(rdm < 0.96) s = '7\ufe0f\u20e3';\n      else if(rdm < 0.98) s = '\ud83c\udccf';\n      else s = '\u2b50';\n      col.push(s);\n    }\n    g.push(col);\n  }\n  return g;\n}\n\n\/\/ Analyse sans toucher au DOM\nfunction analyzeGrid(gridData){\n  let win = 0;\n  let scatters = gridData.flat().filter(s => s === '\u2b50').length;\n\n  paylinesDef.forEach(line => {\n    let lineSym = line.map(pos => gridData[pos.c][pos.r]);\n    let base = lineSym[0];\n    let effBase = (base === '\ud83c\udccf' || base === '\u2b50') ? lineSym[1] : base;\n    if(effBase === '\ud83c\udccf') effBase = '7\ufe0f\u20e3';\n\n    let match = 1;\n    for(let i=1; i<5; i++){\n      if(lineSym[i] === effBase || lineSym[i] === '\ud83c\udccf') match++;\n      else break;\n    }\n    if(match >= 3 && payouts[effBase]) {\n      win += bet * payouts[effBase] * (match - 2);\n    }\n  });\n  return { totalWin: win, scatters: scatters };\n}\n\nfunction finishSpinProcessing(){\n  checkAllLinesAndDisplay(targetGrid);\n  document.getElementById(\"jackpot\").textContent = jackpot.toFixed(2);\n  spinning = false;\n  spinBtn.disabled = false;\n}\n\nfunction checkAllLinesAndDisplay(finalGrid){\n  let res = analyzeGrid(finalGrid);\n  \n  \/\/ Scatters\n  if(res.scatters >= 3){\n    freeSpins += 10;\n    status.textContent = \"\ud83c\udf89 BONUS ! 10 FREE SPINS\";\n  }\n\n  \/\/ Affichage des gains\n  if(res.totalWin > 0){\n    balance += res.totalWin * (freeSpins > 0 ? 2 : 1); \/\/ x2 si free spins\n    document.getElementById(\"balance\").textContent = balance.toFixed(0);\n    document.getElementById(\"win\").textContent = res.totalWin * (freeSpins > 0 ? 2 : 1);\n    \n    \/\/ Colorier\n    paylinesDef.forEach(line => {\n      let lineSym = line.map(pos => finalGrid[pos.c][pos.r]);\n      let base = lineSym[0];\n      let effBase = (base === '\ud83c\udccf' || base === '\u2b50') ? lineSym[1] : base;\n      if(effBase === '\ud83c\udccf') effBase = '7\ufe0f\u20e3';\n      let match = 1;\n      for(let i=1; i<5; i++){ if(lineSym[i] === effBase || lineSym[i] === '\ud83c\udccf') match++; else break; }\n      \n      if(match >= 3 && payouts[effBase]){\n         for(let i=0; i<match; i++) reelsDOM[line[i].c][line[i].r].classList.add(\"win\");\n      }\n    });\n\n    if(res.scatters < 3) status.textContent = `\ud83d\udca5 GAGN\u00c9 ${res.totalWin} \u20ac`;\n  } else if(res.scatters < 3) {\n    status.textContent = \"Perdu...\";\n  }\n}\n\nfunction clearWins(){\n  reelsDOM.flat().forEach(e => e.classList.remove(\"win\"));\n}\n<\/script>\n\n<\/body>\n<\/html>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Casino Royal &#8211; Dual Screen Admin JACKPOT : 12500.00 \u20ac \ud83c\udfb0 Pr\u00eat \u00e0 jouer SOLDE1000 &#8211; 2 + SPIN GAIN0 \ud83c\udf52\ud83c\udf4b\ud83c\udf47 x2 | \ud83d\udd14 x5 \ud83d\udc8e x10 | 7\ufe0f\u20e3 x25 \ud83c\udccf WILD | \u2b50 BONUS \u2699\ufe0f Ouvrir Admin<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-9985","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.animcloud.fr\/en\/wp-json\/wp\/v2\/pages\/9985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.animcloud.fr\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.animcloud.fr\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.animcloud.fr\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.animcloud.fr\/en\/wp-json\/wp\/v2\/comments?post=9985"}],"version-history":[{"count":25,"href":"https:\/\/www.animcloud.fr\/en\/wp-json\/wp\/v2\/pages\/9985\/revisions"}],"predecessor-version":[{"id":10012,"href":"https:\/\/www.animcloud.fr\/en\/wp-json\/wp\/v2\/pages\/9985\/revisions\/10012"}],"wp:attachment":[{"href":"https:\/\/www.animcloud.fr\/en\/wp-json\/wp\/v2\/media?parent=9985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}