{"id":1453,"date":"2025-02-21T14:44:00","date_gmt":"2025-02-21T14:44:00","guid":{"rendered":"https:\/\/mariogr.com\/?p=1453"},"modified":"2026-11-04T15:19:05","modified_gmt":"2026-11-04T15:19:05","slug":"inteligencia-artificial-en-un-laberinto-creepy","status":"publish","type":"portfolio","link":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/","title":{"rendered":"Inteligencia Artificial en un Laberinto Creepy"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"1453\" class=\"elementor elementor-1453\">\n\t\t\t\t<div class=\"elementor-element elementor-element-88f160b e-flex e-con-boxed e-con e-parent\" data-id=\"88f160b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3fc0ad4 elementor-widget elementor-widget-html\" data-id=\"3fc0ad4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- Laberinto Creepy \u00b7 Pega este bloque completo en un widget HTML de Elementor. -->\r\n<style>\r\n  .crp-case,.crp-case *{box-sizing:border-box}\r\n  .crp-case{--crp-bg:#090b0c;--crp-panel:#15191a;--crp-text:#f2eee4;--crp-muted:#b5bbb8;--crp-acid:#c1ed79;--crp-red:#f17a79;width:100%;max-width:100%;color:var(--crp-text);container:crpCase \/ inline-size;font-family:Inter,ui-sans-serif,system-ui,-apple-system,\"Segoe UI\",sans-serif;line-height:1.6}\r\n  .crp-case :is(h2,h3,h4,p,figure){margin:0}.crp-case a{text-decoration:none}.crp-case a:focus-visible,.crp-case button:focus-visible{outline:2px solid var(--crp-acid);outline-offset:4px}\r\n  .crp-shell{position:relative;overflow:hidden;border:1px solid #3a4740;border-radius:18px;background:var(--crp-bg);box-shadow:0 26px 70px rgba(0,0,0,.35)}\r\n  .crp-shell::before{content:\"\";position:absolute;inset:0;pointer-events:none;z-index:4;opacity:.055;background:repeating-linear-gradient(0deg,transparent 0 3px,#d9e8e0 4px)}\r\n  .crp-top{display:flex;align-items:center;justify-content:space-between;gap:15px;padding:13px clamp(21px,4vw,46px);border-bottom:1px solid #41483d;background:#111914;color:#cce3b4;font:800 10px\/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;letter-spacing:.16em;text-transform:uppercase}\r\n  .crp-top__right{color:#e79c91}.crp-pulse{display:inline-block;width:7px;height:7px;margin-right:9px;border-radius:50%;background:#ef7779;box-shadow:0 0 13px #ef7779;animation:crp-blink 2.4s step-end infinite}@keyframes crp-blink{50%{opacity:.25}}\r\n  .crp-hero{position:relative;display:grid;grid-template-columns:1.06fr .94fr;min-height:490px;background:radial-gradient(circle at 20% 40%,rgba(154,35,56,.29),transparent 46%),radial-gradient(circle at 88% 87%,rgba(93,126,60,.18),transparent 40%),linear-gradient(135deg,#1b1b1f,#0b1010 76%)}\r\n  .crp-hero::before{content:\"\";position:absolute;inset:0;pointer-events:none;opacity:.12;background-image:linear-gradient(90deg,#60745d 1px,transparent 1px),linear-gradient(#60745d 1px,transparent 1px);background-size:42px 42px;mask-image:linear-gradient(90deg,#000,transparent 70%)}\r\n  .crp-hero__copy{position:relative;z-index:1;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;padding:clamp(28px,5vw,56px)}\r\n  .crp-eyebrow,.crp-label{display:inline-flex;align-items:center;gap:10px;color:var(--crp-acid);font:800 10px\/1.5 ui-monospace,SFMono-Regular,Consolas,monospace;letter-spacing:.19em;text-transform:uppercase}.crp-eyebrow::before{content:\"\";width:24px;height:1px;background:#d57877}\r\n  .crp-hero h2{max-width:700px;margin-top:23px;color:#faf5e9!important;font-family:Georgia,\"Times New Roman\",serif;font-size:clamp(41px,5.2vw,67px)!important;font-weight:700!important;line-height:1.04!important;letter-spacing:-.045em;text-wrap:balance}\r\n  .crp-hero h2 em{display:block;color:#caed9a;font-style:normal;text-shadow:0 0 24px rgba(172,235,111,.16)}\r\n  .crp-lead{max-width:580px;margin-top:22px!important;color:#cbd0c8;font-size:15px;line-height:1.8}.crp-lead strong{color:#f5ddcc}\r\n  .crp-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:27px}.crp-button{display:inline-flex;align-items:center;justify-content:center;min-height:45px;padding:10px 17px;border:1px solid #73826a;border-radius:5px;background:#1a2420;color:#f1f2e7!important;font-size:12px;font-weight:800;transition:transform .18s ease,background .18s ease,border-color .18s ease}.crp-button:hover{transform:translateY(-2px);border-color:#c4ec8c;background:#263b2a}.crp-button--primary{border-color:#dd9290;background:#9a383b;color:#fff!important;box-shadow:0 5px 0 #4a2024}.crp-button--primary:hover{background:#b84749}\r\n  .crp-hero__visual{position:relative;min-height:490px;overflow:hidden;border-left:1px solid #455041;background:#120d1d}.crp-hero__visual img{display:block;width:100%;height:100%;min-height:490px;object-fit:cover;object-position:center;filter:contrast(1.16) saturate(.87)}\r\n  .crp-hero__visual::after{content:\"\";position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,rgba(15,17,16,.5),transparent 40%),linear-gradient(0deg,rgba(4,8,8,.83),transparent 47%)}\r\n  .crp-hero__stamp{position:absolute;z-index:1;top:20px;right:19px;padding:7px 9px;border:1px solid #cde4ad;background:rgba(8,13,12,.83);color:#d4efb7;font:800 10px ui-monospace,monospace;letter-spacing:.12em}.crp-hero__caption{position:absolute;z-index:1;right:24px;bottom:26px;left:24px;color:#f3e8e1;font:700 clamp(19px,2.5vw,28px)\/1.2 Georgia,serif}.crp-hero__caption small{display:block;margin-bottom:9px;color:#d69a97;font:800 10px ui-monospace,monospace;letter-spacing:.15em;text-transform:uppercase}\r\n  .crp-facts{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border-block:1px solid #354038;background:#18201c}.crp-facts div{min-width:0;padding:18px 19px;border-right:1px solid #354038}.crp-facts div:last-child{border-right:0}.crp-facts small{display:block;margin-bottom:6px;color:#badc8b;font:800 10px ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase}.crp-facts strong{display:block;color:#eeeae0;font-size:12px;line-height:1.5}\r\n  .crp-play{position:relative;overflow:hidden;padding:44px clamp(18px,4vw,44px);border-bottom:1px solid #435043;background:radial-gradient(circle at 45% 12%,rgba(120,38,43,.25),transparent 42%),repeating-linear-gradient(90deg,transparent 0 75px,rgba(163,193,129,.025) 76px),#101614}.crp-play::before{content:\"\";position:absolute;right:-70px;top:-100px;width:300px;height:300px;border:1px solid rgba(174,204,122,.12);border-radius:50%;box-shadow:0 0 0 42px rgba(174,204,122,.035),0 0 0 105px rgba(174,204,122,.025);pointer-events:none}.crp-play>*{position:relative}.crp-play h3{margin-top:13px;color:#f9eee3!important;font-family:Georgia,serif;font-size:clamp(29px,3.8vw,43px)!important;line-height:1.14}.crp-play>p{max-width:780px;margin-top:14px;color:#bdc7ba;font-size:14px;line-height:1.75}.crp-play__notice{max-width:790px;margin-top:15px!important;color:#b7e8a2!important;font-size:11px!important}\r\n  .crp-game{max-width:860px;margin:27px auto 0;border:2px solid #667a56;border-radius:10px;background:#0b100e;box-shadow:0 0 0 5px rgba(116,154,83,.08),0 28px 50px rgba(0,0,0,.42)}.crp-game__head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 15px;border-bottom:1px solid #475748;background:#1b2820}.crp-game__head b{color:#e8edda;font:900 11px ui-monospace,monospace;letter-spacing:.13em}.crp-game__head span{color:#e99b91;font:800 10px ui-monospace,monospace;letter-spacing:.1em}.crp-game__hud{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;border-bottom:1px solid #3a4b3e;background:#3a4b3e}.crp-game__hud div{min-width:0;padding:10px 13px;background:#101a14}.crp-game__hud small{display:block;color:#9bb398;font:800 9px ui-monospace,monospace;letter-spacing:.1em;text-transform:uppercase}.crp-game__hud strong{display:block;margin-top:4px;color:#eee9d9;font:800 12px ui-monospace,monospace;line-height:1.4}.crp-game__hud [data-crp-health]{color:#f19c94}.crp-game__screen{position:relative;padding:12px;background:radial-gradient(circle at 50% 50%,#15251b,#070d0b 75%)}.crp-game canvas{display:block;width:100%;height:auto;max-width:100%;border:1px solid #526452;border-radius:3px;background:#080d0a;image-rendering:pixelated;touch-action:none}.crp-game__screen::after{content:\"\";position:absolute;inset:12px;pointer-events:none;opacity:.16;background:repeating-linear-gradient(0deg,transparent 0 3px,#141b16 4px)}.crp-game__status{min-height:44px;padding:12px 15px;border-top:1px solid #334438;border-bottom:1px solid #334438;background:#171e19;color:#d6e2cc;font:700 11px\/1.6 ui-monospace,monospace}.crp-game__status::before{content:\"\u25b8\";margin-right:9px;color:#e77d78}.crp-game__controls{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:16px;align-items:center;padding:14px;background:#121a15}.crp-game__actions,.crp-game__pad{display:flex;flex-wrap:wrap;gap:8px}.crp-game__pad{display:grid;grid-template-columns:repeat(3,46px);grid-template-rows:repeat(2,42px);place-items:stretch}.crp-game__pad [data-crp-move=\"up\"]{grid-column:2;grid-row:1}.crp-game__pad [data-crp-move=\"left\"]{grid-column:1;grid-row:2}.crp-game__pad [data-crp-move=\"down\"]{grid-column:2;grid-row:2}.crp-game__pad [data-crp-move=\"right\"]{grid-column:3;grid-row:2}.crp-game button{min-height:42px;padding:9px 13px;border:1px solid #6d8665;border-radius:5px;background:#24372a;color:#edf5dc;font:800 11px ui-monospace,monospace;cursor:pointer;touch-action:none;user-select:none}.crp-game button:hover{background:#344d36;border-color:#c8ee9c}.crp-game button:disabled{opacity:.45;cursor:not-allowed}.crp-game [data-crp-action=\"start\"]{border-color:#e29a90;background:#8d3439}.crp-game [data-crp-action=\"fire\"]{border-color:#df8f87;background:#863a3a}.crp-game [data-crp-action=\"repair\"]{border-color:#a7e0b9;background:#286f52}.crp-game__help{padding:0 15px 15px;color:#a5b4a5;font:11px\/1.65 ui-monospace,monospace}.crp-game__legend{display:flex;flex-wrap:wrap;gap:8px 15px;margin:14px 0 0;padding:0;list-style:none;color:#a9c0aa;font:10px ui-monospace,monospace}.crp-game__legend li{display:flex;align-items:center;gap:7px}.crp-game__legend i{display:inline-block;width:10px;height:10px;border-radius:2px}.crp-game__legend li:nth-child(1) i{background:#edc37e}.crp-game__legend li:nth-child(2) i{background:#86daaf}.crp-game__legend li:nth-child(3) i{background:#c3ec82}.crp-game__legend li:nth-child(4) i{background:#e66d6b}\r\n  .crp-section{padding:42px clamp(22px,5vw,48px);border-bottom:1px solid #303b34}.crp-section--shade{background:#111816}.crp-section h3,.crp-closing h3{margin-top:13px;color:#f4eee3!important;font-family:Georgia,\"Times New Roman\",serif;font-size:clamp(27px,3.5vw,39px)!important;font-weight:700!important;line-height:1.17;letter-spacing:-.025em;text-wrap:balance}.crp-section>p{max-width:820px;margin-top:15px;color:var(--crp-muted);font-size:14px;line-height:1.8}\r\n  .crp-intro{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-top:25px}.crp-card{padding:22px;border:1px solid #475147;border-radius:7px;background:#1b2420}.crp-card small{display:block;margin-bottom:11px;color:#c6e89a;font:800 10px ui-monospace,monospace;letter-spacing:.13em;text-transform:uppercase}.crp-card h4{color:#f5eee2;font-family:Georgia,serif;font-size:20px}.crp-card p{margin-top:10px;color:#bfc7bd;font-size:12px;line-height:1.72}\r\n  .crp-mission{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-top:25px}.crp-mission article{position:relative;min-width:0;padding:19px 15px;border-top:2px solid #8aaf67;background:#1c2820}.crp-mission article:nth-child(even){border-color:#b85b5e}.crp-mission small{color:#dd9b90;font:800 10px ui-monospace,monospace;letter-spacing:.13em}.crp-mission strong{display:block;margin-top:12px;color:#f1f0e4;font-size:14px}.crp-mission p{margin-top:7px;color:#aebdb0;font-size:11px;line-height:1.65}\r\n  .crp-interactive{margin-top:24px;padding:23px;border:1px solid #65714e;border-radius:8px;background:radial-gradient(circle at 90% 10%,rgba(162,50,55,.11),transparent 35%),#1b231e}.crp-interactive h4{color:#f4eadd;font-family:Georgia,serif;font-size:22px}.crp-interactive>p{margin-top:8px;color:#b9c5b5;font-size:12px;line-height:1.7}.crp-switch{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px}.crp-switch button{min-height:43px;padding:9px 12px;border:1px solid #60735a;border-radius:4px;background:#18251c;color:#d8e8cc;font:800 11px ui-monospace,monospace;cursor:pointer}.crp-switch button:hover,.crp-switch button[aria-pressed=\"true\"]{border-color:#e7a7a1;background:#8d3e42;color:#fff}.crp-response{display:grid;grid-template-columns:150px minmax(0,1fr);gap:20px;align-items:start;margin-top:20px;padding:19px;border-left:3px solid #d27b73;background:#111915}.crp-response__signal{display:flex;align-items:center;gap:9px;color:#e8aaa1;font:800 10px ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase}.crp-response__signal::before{content:\"\";width:10px;height:10px;border-radius:50%;background:#e67670;box-shadow:0 0 15px #e67670}.crp-response h5{margin:0;color:#f4eddf;font-family:Georgia,serif;font-size:20px}.crp-response p{margin-top:7px;color:#c0c8bd;font-size:12px;line-height:1.7}.crp-interactive__note{margin-top:12px!important;color:#8fa497!important;font-size:10px!important}\r\n  .crp-flow{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-top:25px}.crp-flow article{min-width:0;padding:17px 14px;border:1px solid #455045;background:#1c2521}.crp-flow small{color:#d8847f;font:800 10px ui-monospace,monospace;letter-spacing:.1em}.crp-flow b{display:block;margin-top:9px;color:#e9eddf;font-size:13px}.crp-flow p{margin-top:7px;color:#aebbb0;font-size:11px;line-height:1.65}\r\n  .crp-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px;align-items:center;margin-top:26px}.crp-split h4{color:#f4e9dc;font-family:Georgia,serif;font-size:24px;line-height:1.2}.crp-split p{margin-top:12px;color:#bdc6bb;font-size:13px;line-height:1.75}.crp-split ul{margin:16px 0 0;padding:0;list-style:none}.crp-split li{position:relative;padding:6px 0 6px 19px;color:#d4dacb;font-size:12px;line-height:1.6}.crp-split li::before{content:\"\u2726\";position:absolute;left:0;color:#c6e78c}.crp-figure{overflow:hidden;border:1px solid #536351;border-radius:7px;background:#090d0d}.crp-figure img{display:block;width:100%;height:auto}.crp-figure figcaption{padding:10px 13px;border-top:1px solid #3a493d;color:#a5b4a6;font-size:10px;line-height:1.55}.crp-figure--mobile img{aspect-ratio:780\/351;object-fit:contain}\r\n  .crp-visual-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:23px}.crp-visual-grid article{padding:19px;border:1px solid #465144;border-radius:6px;background:#1a2420}.crp-visual-grid span{color:#d98379;font:800 10px ui-monospace,monospace;letter-spacing:.11em}.crp-visual-grid h4{margin-top:12px;color:#f4eedf;font-family:Georgia,serif;font-size:18px}.crp-visual-grid p{margin-top:9px;color:#b3c1b3;font-size:12px;line-height:1.7}.crp-visual-note{margin-top:15px!important;color:#93a398!important;font-size:11px!important}\r\n  .crp-result{display:grid;grid-template-columns:1fr 1fr;gap:22px;margin-top:23px;padding:23px;border-left:3px solid #b85b5e;background:linear-gradient(110deg,rgba(143,49,58,.17),rgba(145,188,98,.06))}.crp-result strong{color:#f6eadc;font-family:Georgia,serif;font-size:20px}.crp-result p{margin-top:9px;color:#bec8bc;font-size:12px;line-height:1.7}.crp-result ul{margin:0;padding:0;list-style:none}.crp-result li{position:relative;padding:6px 0 6px 19px;color:#dae3d4;font-size:12px;line-height:1.55}.crp-result li::before{content:\"+\";position:absolute;left:0;color:#c3e990;font-weight:900}\r\n  .crp-closing{padding:39px clamp(22px,5vw,48px);background:radial-gradient(circle at 92% 30%,rgba(163,48,58,.22),transparent 35%),#17221b}.crp-closing p{max-width:650px;margin-top:12px;color:#bfccbc;font-size:13px;line-height:1.75}\r\n  @media(max-width:760px){.crp-hero,.crp-split,.crp-intro,.crp-result{grid-template-columns:1fr}.crp-hero__visual{min-height:300px;border-left:0;border-top:1px solid #455041}.crp-hero__visual img{min-height:300px;max-height:420px}.crp-facts,.crp-mission,.crp-flow{grid-template-columns:repeat(2,minmax(0,1fr))}.crp-visual-grid{grid-template-columns:1fr}}\r\n  @container crpCase (max-width:760px){.crp-hero,.crp-split,.crp-intro,.crp-result{grid-template-columns:1fr}.crp-hero__visual{min-height:300px;border-left:0;border-top:1px solid #455041}.crp-hero__visual img{min-height:300px;max-height:420px}.crp-facts,.crp-mission,.crp-flow{grid-template-columns:repeat(2,minmax(0,1fr))}.crp-visual-grid{grid-template-columns:1fr}}\r\n  @container crpCase (max-width:470px){.crp-top__right{display:none}.crp-hero h2{font-size:43px!important}.crp-facts div{padding:14px 11px}.crp-response{grid-template-columns:1fr;gap:9px}.crp-mission,.crp-flow{grid-template-columns:1fr}.crp-interactive{padding:18px}.crp-game__controls{grid-template-columns:1fr}.crp-game__actions{justify-content:center}.crp-game__pad{justify-content:center}.crp-game__hud div{padding:8px}.crp-game__hud strong{font-size:10px}.crp-game__screen{padding:5px}.crp-game__screen::after{inset:5px}}\r\n  @media(prefers-reduced-motion:reduce){.crp-pulse{animation:none}.crp-button{transition:none}}\r\n  \/* RyanCV + Elementor: impide el gran espacio vac\u00edo causado por container queries en un flex. *\/\r\n  body.single-portfolio .e-con-inner:has(> .elementor-widget-html .crp-case){display:block!important}\r\n  @supports not selector(:has(*)){.crp-case{container:none!important}}\r\n  @media(max-width:680px){body.single-portfolio .card-inner .card-wrap{padding-left:10px!important;padding-right:10px!important}}\r\n  \/* RyanCV theme switch: the site starts dark and removes body-style-dark for light mode. *\/\r\n  body:not(.body-style-dark) .crp-case {color-scheme:light;color:#203340}\r\n  body:not(.body-style-dark) .crp-shell {background:#f9fbfc;border-color:#d9cdca;box-shadow:0 20px 45px rgba(32,57,72,.12)}\r\n  body:not(.body-style-dark) .crp-hero {background:linear-gradient(130deg,#f2e9e7,#f9fbfc 82%)}\r\n  body:not(.body-style-dark) .crp-hero h2 {color:#172f3c!important}\r\n  body:not(.body-style-dark) .crp-hero h2 em {color:#7b383d!important;text-shadow:none}\r\n  body:not(.body-style-dark) .crp-section {background:#f9fbfc;border-color:#d5e1e7}\r\n  body:not(.body-style-dark) .crp-section--shade {background:#f5f1ef}\r\n  body:not(.body-style-dark) .crp-section h3,\r\n  body:not(.body-style-dark) .crp-closing h3 {color:#203744!important}\r\n  body:not(.body-style-dark) .crp-section>p,\r\n  body:not(.body-style-dark) .crp-closing p {color:#4c6471}\r\n  body:not(.body-style-dark) .crp-section strong {color:#213846}\r\n  body:not(.body-style-dark) .crp-closing {background:linear-gradient(120deg,#f5f1ef,#f9fbfc)}\r\n  body:not(.body-style-dark) .crp-card,\r\n  body:not(.body-style-dark) .crp-mission article,\r\n  body:not(.body-style-dark) .crp-flow article,\r\n  body:not(.body-style-dark) .crp-visual-grid article,\r\n  body:not(.body-style-dark) .crp-result {background:#fff;border-color:#d9cdca}\r\n  body:not(.body-style-dark) .crp-card h4,\r\n  body:not(.body-style-dark) .crp-mission strong,\r\n  body:not(.body-style-dark) .crp-flow b,\r\n  body:not(.body-style-dark) .crp-visual-grid h4,\r\n  body:not(.body-style-dark) .crp-result strong {color:#203946}\r\n  body:not(.body-style-dark) .crp-card p,\r\n  body:not(.body-style-dark) .crp-mission p,\r\n  body:not(.body-style-dark) .crp-flow p,\r\n  body:not(.body-style-dark) .crp-visual-grid p,\r\n  body:not(.body-style-dark) .crp-result p,\r\n  body:not(.body-style-dark) .crp-result li {color:#4c6471}\r\n  body:not(.body-style-dark) .crp-eyebrow,\r\n  body:not(.body-style-dark) .crp-label,\r\n  body:not(.body-style-dark) .crp-card small,\r\n  body:not(.body-style-dark) .crp-mission small,\r\n  body:not(.body-style-dark) .crp-flow small,\r\n  body:not(.body-style-dark) .crp-visual-grid span {color:#7b383d}\r\n  body:not(.body-style-dark) .crp-visual-note,\r\n  body:not(.body-style-dark) .crp-interactive__note {color:#526977!important}\r\n  body:not(.body-style-dark) .crp-case {--crp-bg:#f8f7f4;--crp-text:#322e2e;--crp-muted:#625b59;--crp-acid:#516c35;--crp-red:#9d4145}\r\n  body:not(.body-style-dark) .crp-top,\r\n  body:not(.body-style-dark) .crp-facts {background:#ebece5;border-color:#d1d7ca;color:#42523c}\r\n  body:not(.body-style-dark) .crp-top__right,\r\n  body:not(.body-style-dark) .crp-facts small,\r\n  body:not(.body-style-dark) .crp-facts strong {color:#475841}\r\n  body:not(.body-style-dark) .crp-lead,\r\n  body:not(.body-style-dark) .crp-lead strong {color:#584b4a}\r\n  body:not(.body-style-dark) .crp-button:not(.crp-button--primary) {background:#fff;color:#4e693d!important;border-color:#b9cbb1}\r\n  body:not(.body-style-dark) .crp-button--primary {background:#943b42;color:#fff!important}\r\n  body:not(.body-style-dark) .crp-interactive,\r\n  body:not(.body-style-dark) .crp-response {background:#eceee9;border-color:#bdc9ba}\r\n  body:not(.body-style-dark) .crp-interactive h4,\r\n  body:not(.body-style-dark) .crp-response h5,\r\n  body:not(.body-style-dark) .crp-response p,\r\n  body:not(.body-style-dark) .crp-interactive>p {color:#364238}\r\n  body:not(.body-style-dark) .crp-switch button {background:#fff;color:#455b3c;border-color:#bccbb6}\r\n  body:not(.body-style-dark) .crp-switch button[aria-pressed=true] {background:#934149;color:#fff}\r\n  body:not(.body-style-dark) .crp-closing {background:#e9eee4}\r\n  body:not(.body-style-dark) .crp-figure figcaption,\r\n  body:not(.body-style-dark) .crp-figure--mobile figcaption {color:#48574b}\r\n  body:not(.body-style-dark) .crp-play {background:radial-gradient(circle at 50% 10%,rgba(127,53,58,.15),transparent 40%),#f2edea}\r\n  body:not(.body-style-dark) .crp-play h3 {color:#342c2b!important}\r\n  body:not(.body-style-dark) .crp-play>p {color:#5e5351}\r\n  body:not(.body-style-dark) .crp-play__notice {color:#506d3a!important}\r\n  body:not(.body-style-dark) .crp-game {background:#0b100e;color:#eaf3e0}\r\n  body:not(.body-style-dark) .crp-game__legend {color:#4a5c47}\r\n  body:not(.body-style-dark) .crp-split h4 {color:#352f2e}\r\n  body:not(.body-style-dark) .crp-split p,\r\n  body:not(.body-style-dark) .crp-split li {color:#554e4a}\r\n  body:not(.body-style-dark) .crp-response__signal {color:#8b3e43}\r\n  body:not(.body-style-dark) .crp-figure figcaption {color:#b8cbb8}\r\n<\/style>\r\n\r\n<article class=\"crp-case\" aria-label=\"Caso de estudio del videojuego Inteligencia Artificial en un Laberinto Creepy\">\r\n  <div class=\"crp-shell\">\r\n    <div class=\"crp-top\"><span><span class=\"crp-pulse\" aria-hidden=\"true\"><\/span>Expediente 01 \/ Se\u00f1al detectada<\/span><span class=\"crp-top__right\">Unity \u00b7 IA \u00b7 Terror<\/span><\/div>\r\n    <header class=\"crp-hero\">\r\n      <div class=\"crp-hero__copy\">\r\n        <span class=\"crp-eyebrow\">Laberinto Creepy \u00b7 Videojuego multiplataforma<\/span>\r\n        <h2>El laberinto <em>te est\u00e1 buscando.<\/em><\/h2>\r\n        <p class=\"crp-lead\">En este videojuego de terror, escapar exige algo m\u00e1s que encontrar la salida. Hay que explorar sin armas, <strong>recuperar el equipo<\/strong> y sobrevivir a enemigos que adaptan sus decisiones al estado del mundo.<\/p>\r\n        <div class=\"crp-actions\"><a class=\"crp-button crp-button--primary\" href=\"#crp-jugar\">Entrar en el laberinto \u2193<\/a><a class=\"crp-button\" href=\"#crp-ia\">Descubrir la IA \u2193<\/a><\/div>\r\n      <\/div>\r\n      <div class=\"crp-hero__visual\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/mariogr.com\/wp-content\/uploads\/2025\/02\/Imagen3.png\" alt=\"Imagen original del proyecto: vista violeta y distorsionada del laberinto\" width=\"431\" height=\"430\"><span class=\"crp-hero__stamp\">No mires atr\u00e1s<\/span><div class=\"crp-hero__caption\"><small>Imagen del proyecto<\/small>La salida cambia.<br>La amenaza tambi\u00e9n.<\/div><\/div>\r\n    <\/header>\r\n\r\n    <div class=\"crp-facts\" aria-label=\"Ficha t\u00e9cnica\"><div><small>Formato<\/small><strong>Videojuego de terror<\/strong><\/div><div><small>Motor<\/small><strong>Unity<\/strong><\/div><div><small>IA<\/small><strong>Costes + estados del mundo<\/strong><\/div><div><small>Navegaci\u00f3n<\/small><strong>B\u00fasqueda de rutas A*<\/strong><\/div><\/div>\r\n\r\n    <section class=\"crp-play\" id=\"crp-jugar\"><span class=\"crp-label\">Acceso al experimento \/ Juego integrado<\/span><h3>Encuentra el arma. Rep\u00e1rala. Sobrevive.<\/h3><p>Entra en el laberinto, recoge el arma averiada, busca la mesa de reparaci\u00f3n y elimina a las dos criaturas. Solo entonces podr\u00e1s abrir la salida. Hay tres vidas; si te atrapan, reapareces en el \u00faltimo punto alcanzado.<\/p>\r\n      <div class=\"crp-game\" data-crp-game>\r\n        <div class=\"crp-game__head\"><b>LABERINTO \/ SECTOR 01<\/b><span>\u25cf SE\u00d1AL INESTABLE<\/span><\/div>\r\n        <div class=\"crp-game__hud\"><div><small>Resistencia<\/small><strong data-crp-health>\u2665 \u2665 \u2665<\/strong><\/div><div><small>Objetivo<\/small><strong data-crp-objective>Encuentra el arma<\/strong><\/div><div><small>Criaturas<\/small><strong data-crp-kills>0 \/ 2<\/strong><\/div><\/div>\r\n        <div class=\"crp-game__screen\"><canvas width=\"540\" height=\"396\" tabindex=\"0\" aria-label=\"Minijuego del laberinto: usa las flechas o WASD para moverte y espacio para disparar\"><\/canvas><\/div>\r\n        <p class=\"crp-game__status\" role=\"status\" aria-live=\"polite\" data-crp-status>Pulsa \u00abEntrar\u00bb para comenzar. Escucha los pasillos.<\/p>\r\n        <div class=\"crp-game__controls\"><div class=\"crp-game__actions\"><button type=\"button\" data-crp-action=\"start\">Entrar<\/button><button type=\"button\" data-crp-action=\"pause\" disabled>Pausa<\/button><button type=\"button\" data-crp-action=\"repair\" disabled>Reparar<\/button><button type=\"button\" data-crp-action=\"fire\" disabled>Disparar<\/button><button type=\"button\" data-crp-action=\"map\" disabled>Mapa<\/button><\/div><div class=\"crp-game__pad\" aria-label=\"Controles t\u00e1ctiles\"><button type=\"button\" data-crp-move=\"up\" aria-label=\"Mover arriba\">\u25b2<\/button><button type=\"button\" data-crp-move=\"left\" aria-label=\"Mover a la izquierda\">\u25c0<\/button><button type=\"button\" data-crp-move=\"down\" aria-label=\"Mover abajo\">\u25bc<\/button><button type=\"button\" data-crp-move=\"right\" aria-label=\"Mover a la derecha\">\u25b6<\/button><\/div><\/div>\r\n        <p class=\"crp-game__help\">Teclado: flechas o WASD para moverte \u00b7 E para reparar en la mesa \u00b7 Espacio para disparar \u00b7 M para ver el mapa \u00b7 P para pausar. En m\u00f3vil usa los botones. Disparas en la \u00faltima direcci\u00f3n de movimiento.<\/p>\r\n      <\/div>\r\n      <ul class=\"crp-game__legend\" aria-label=\"Leyenda del juego\"><li><i><\/i>Arma averiada<\/li><li><i><\/i>Mesa de reparaci\u00f3n<\/li><li><i><\/i>Salida<\/li><li><i><\/i>Criatura<\/li><\/ul>\r\n      <p class=\"crp-play__notice\">Esta es una adaptaci\u00f3n jugable creada para el portfolio en JavaScript y Canvas. El proyecto original descrito m\u00e1s abajo se desarroll\u00f3 en Unity.<\/p>\r\n    <\/section>\r\n\r\n    <section class=\"crp-section crp-section--shade\"><span class=\"crp-label\">01 \/ La premisa<\/span><h3>Sin armas. Sin mapa seguro. Con algo detr\u00e1s.<\/h3><p>El jugador despierta atrapado en un laberinto oscuro. Su primer objetivo es sobrevivir mientras explora; despu\u00e9s debe encontrar y reparar sus armas, enfrentarse a los enemigos y llegar a la salida. La tensi\u00f3n nace de esa progresi\u00f3n: cada avance cambia tambi\u00e9n el comportamiento de quienes lo persiguen.<\/p><div class=\"crp-intro\"><article class=\"crp-card\"><small>El conflicto<\/small><h4>Sobrevivir antes de combatir<\/h4><p>La ausencia inicial de armamento obliga a moverse, observar y tomar decisiones bajo presi\u00f3n.<\/p><\/article><article class=\"crp-card\"><small>La mec\u00e1nica<\/small><h4>Enemigos que reaccionan<\/h4><p>La IA considera el contexto de la partida para elegir acciones y recorrer los pasillos del laberinto.<\/p><\/article><\/div><div class=\"crp-mission\"><article><small>01 \/ EXPLORA<\/small><strong>Lee el entorno<\/strong><p>Busca un camino entre pasillos y amenazas.<\/p><\/article><article><small>02 \/ RECUPERA<\/small><strong>Repara tus armas<\/strong><p>Encuentra el equipo necesario para defenderte.<\/p><\/article><article><small>03 \/ RESISTE<\/small><strong>Enfrenta a la IA<\/strong><p>Los enemigos modifican sus t\u00e1cticas seg\u00fan tu situaci\u00f3n.<\/p><\/article><article><small>04 \/ ESCAPA<\/small><strong>Alcanza la salida<\/strong><p>La presi\u00f3n aumenta cuando est\u00e1s cerca de huir.<\/p><\/article><\/div><\/section>\r\n\r\n    <section class=\"crp-section\" id=\"crp-ia\"><span class=\"crp-label\">02 \/ Inteligencia artificial<\/span><h3>La amenaza toma decisiones<\/h3><p>La l\u00f3gica de los enemigos combina una evaluaci\u00f3n basada en costes con estados del mundo. Antes de actuar, cada enemigo tiene en cuenta factores como la posici\u00f3n del jugador, la presencia de otros enemigos, su agresividad y su propio estado. As\u00ed, la reacci\u00f3n no depende de una \u00fanica orden fija.<\/p><div class=\"crp-interactive\" data-crp-simulator><h4>Interroga al sistema<\/h4><p>Selecciona una situaci\u00f3n para ver c\u00f3mo cambia la conducta descrita en el proyecto.<\/p><div class=\"crp-switch\" role=\"group\" aria-label=\"Situaci\u00f3n del jugador\"><button type=\"button\" data-crp-state=\"unarmed\" aria-pressed=\"true\">Sin armas<\/button><button type=\"button\" data-crp-state=\"armed\" aria-pressed=\"false\">Con arma<\/button><button type=\"button\" data-crp-state=\"exit\" aria-pressed=\"false\">Cerca de la salida<\/button><\/div><div class=\"crp-response\" role=\"status\" aria-live=\"polite\"><span class=\"crp-response__signal\">Estado detectado<\/span><div><h5 data-crp-title>Patrulla agresiva<\/h5><p data-crp-description>Al detectar al jugador desarmado, los enemigos se muestran m\u00e1s agresivos y patrullan activamente.<\/p><\/div><\/div><p class=\"crp-interactive__note\">Esta visualizaci\u00f3n resume las reglas publicadas; no ejecuta el c\u00f3digo de IA del juego.<\/p><\/div><div class=\"crp-flow\" aria-label=\"Resumen de la l\u00f3gica enemiga\"><article><small>ENTRADA<\/small><b>Leer el mundo<\/b><p>Posici\u00f3n del jugador, situaci\u00f3n de los enemigos y estado de la partida.<\/p><\/article><article><small>EVALUACI\u00d3N<\/small><b>Comparar costes<\/b><p>Las alternativas se valoran seg\u00fan el contexto y el estado de cada enemigo.<\/p><\/article><article><small>DECISI\u00d3N<\/small><b>Elegir conducta<\/b><p>Patrullar, perseguir, defender o intentar una emboscada.<\/p><\/article><article><small>MOVIMIENTO<\/small><b>Buscar ruta<\/b><p>A* permite desplazarse por los pasillos hacia el objetivo elegido.<\/p><\/article><\/div><\/section>\r\n\r\n    <section class=\"crp-section crp-section--shade\"><span class=\"crp-label\">03 \/ Pathfinding<\/span><h3>El camino m\u00e1s inquietante es el que s\u00ed encuentran<\/h3><p>Un enemigo que atraviesa paredes o se mueve en l\u00ednea recta rompe la credibilidad del laberinto. En el proyecto original, la b\u00fasqueda A* permite recorrer pasillos para perseguir al jugador, bloquear caminos y coordinar enemigos. En el minijuego integrado puedes comprobarlo: si una criatura te detecta, evita los muros y recalcula su ruta cuando cambias de posici\u00f3n.<\/p><div class=\"crp-split\"><div><h4>Persecuci\u00f3n dentro del espacio real<\/h4><p>La navegaci\u00f3n convierte una decisi\u00f3n t\u00e1ctica en un trayecto posible dentro del nivel. El jugador puede ganar tiempo cambiando de pasillo, pero debe buscar una l\u00ednea de tiro antes de disparar.<\/p><ul><li>La decisi\u00f3n de perseguir depende del estado de la partida.<\/li><li>A* compara rutas transitables entre enemigo y jugador.<\/li><li>Los muros tambi\u00e9n bloquean los disparos en la adaptaci\u00f3n.<\/li><\/ul><\/div><figure class=\"crp-figure crp-figure--mobile\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mariogr.com\/wp-content\/uploads\/2025\/02\/Imagen5.jpg\" alt=\"Captura real de la versi\u00f3n m\u00f3vil: pasillo de paredes verdes, antorcha encendida y controles t\u00e1ctiles\" width=\"780\" height=\"351\" loading=\"lazy\"><figcaption>Captura original desde m\u00f3vil: pasillos, antorcha y controles t\u00e1ctiles.<\/figcaption><\/figure><\/div><\/section>\r\n\r\n    <section class=\"crp-section\" id=\"crp-visual\"><span class=\"crp-label\">04 \/ Shading y atm\u00f3sfera<\/span><h3>El miedo tambi\u00e9n se construye con luz<\/h3><p>Las im\u00e1genes del proyecto muestran un espacio de color irreal: superficies verdes y violetas, fuego c\u00e1lido y zonas de poca lectura. En Unity, el shading determina c\u00f3mo se ven los materiales al recibir luz; aqu\u00ed la combinaci\u00f3n visible de textura, color y contraste hace que el laberinto resulte extra\u00f1o y que la antorcha destaque en medio del recorrido.<\/p><div class=\"crp-visual-grid\"><article><span>01 \/ PALETA<\/span><h4>Color que inquieta<\/h4><p>Los verdes y violetas intensos alejan la escena de un entorno cotidiano y dan identidad al terror del juego.<\/p><\/article><article><span>02 \/ SUPERFICIES<\/span><h4>Texturas y materiales<\/h4><p>Las paredes y el suelo muestran un patr\u00f3n marcado. El material define c\u00f3mo ese patr\u00f3n y su color se presentan en la escena.<\/p><\/article><article><span>03 \/ LUZ<\/span><h4>Contraste y orientaci\u00f3n<\/h4><p>La antorcha crea un foco c\u00e1lido frente a las superficies fr\u00edas, \u00fatil para dirigir la mirada del jugador.<\/p><\/article><\/div><p class=\"crp-visual-note\">La ficha p\u00fablica no identifica shaders personalizados, pipeline ni par\u00e1metros concretos. Esta lectura se basa en las capturas disponibles, sin atribuir t\u00e9cnicas de implementaci\u00f3n que no est\u00e1n documentadas.<\/p><\/section>\r\n\r\n    <section class=\"crp-section crp-section--shade\"><span class=\"crp-label\">05 \/ Construcci\u00f3n del proyecto<\/span><h3>De la escena al comportamiento<\/h3><p>El trabajo une dise\u00f1o de nivel, l\u00f3gica de enemigos y presentaci\u00f3n visual en Unity. La dificultad del proyecto est\u00e1 en que cada parte apoye a las dem\u00e1s: un laberinto recorrible, una amenaza que responda al jugador y una atm\u00f3sfera que mantenga la tensi\u00f3n.<\/p><div class=\"crp-intro\"><article class=\"crp-card\"><small>Dise\u00f1o de juego<\/small><h4>Una progresi\u00f3n clara<\/h4><p>Explorar, equiparse, combatir y escapar crea objetivos sucesivos y eleva la presi\u00f3n de forma natural.<\/p><\/article><article class=\"crp-card\"><small>IA de enemigos<\/small><h4>Contexto antes que rutina<\/h4><p>Los estados del mundo y la evaluaci\u00f3n de costes permiten adaptar las acciones a cada situaci\u00f3n.<\/p><\/article><article class=\"crp-card\"><small>Navegaci\u00f3n<\/small><h4>Rutas entre pasillos<\/h4><p>A* conecta la decisi\u00f3n del enemigo con un recorrido viable por el nivel.<\/p><\/article><article class=\"crp-card\"><small>Experiencia visual<\/small><h4>El laberinto como amenaza<\/h4><p>La paleta, las texturas y las fuentes de luz refuerzan el tono extra\u00f1o del juego.<\/p><\/article><\/div><\/section>\r\n\r\n    <section class=\"crp-section\"><span class=\"crp-label\">06 \/ Detr\u00e1s de esta p\u00e1gina<\/span><h3>C\u00f3mo se construy\u00f3 la versi\u00f3n jugable<\/h3><p>El juego integrado traduce la premisa del proyecto original a una experiencia breve de navegador. Est\u00e1 hecho expresamente para este portfolio: usa HTML Canvas para dibujar, JavaScript para las reglas y controles de teclado y pantalla t\u00e1ctil. Su c\u00f3digo y su arte son independientes de la versi\u00f3n de Unity.<\/p><div class=\"crp-intro\"><article class=\"crp-card\"><small>Generaci\u00f3n del nivel<\/small><h4>Un laberinto nuevo en cada partida<\/h4><p>Un recorrido en profundidad abre pasillos; una b\u00fasqueda en anchura localiza un camino largo donde situar arma, mesa, criaturas y salida en orden.<\/p><\/article><article class=\"crp-card\"><small>M\u00e1quina de estados<\/small><h4>Objetivos que se desbloquean<\/h4><p>Primero hay que recoger el arma y usar la mesa para repararla. Solo entonces se puede disparar, derrotar a las dos criaturas y salir.<\/p><\/article><article class=\"crp-card\"><small>Enemigos<\/small><h4>A* y persecuci\u00f3n<\/h4><p>Las criaturas patrullan y, al detectar al jugador, calculan una ruta por las casillas libres. Su ritmo cambia con la situaci\u00f3n de la partida.<\/p><\/article><article class=\"crp-card\"><small>Renderizado<\/small><h4>Oscuridad como regla<\/h4><p>El canvas dibuja materiales, grietas, personajes y una m\u00e1scara radial alrededor del jugador. El bot\u00f3n Mapa permite ver todo el recorrido cuando se necesita orientaci\u00f3n.<\/p><\/article><\/div><\/section>\r\n\r\n    <section class=\"crp-section crp-section--shade\"><span class=\"crp-label\">07 \/ Resultado<\/span><h3>Una persecuci\u00f3n que cambia contigo<\/h3><p>El proyecto de Unity muestra c\u00f3mo la inteligencia artificial puede dar tensi\u00f3n a un juego de terror: el enemigo eval\u00faa el contexto, decide c\u00f3mo actuar y encuentra un camino para ejecutar esa decisi\u00f3n. La versi\u00f3n m\u00f3vil publicada demuestra adem\u00e1s la adaptaci\u00f3n a controles t\u00e1ctiles. El minijuego de esta p\u00e1gina permite experimentar esa idea en una partida corta.<\/p><div class=\"crp-result\"><div><strong>Lo que demuestra el proyecto<\/strong><p>La atm\u00f3sfera inquieta, pero la reacci\u00f3n de los enemigos hace que el laberinto resulte imprevisible durante la partida.<\/p><\/div><ul><li>Enemigos con decisiones basadas en costes y estados.<\/li><li>Navegaci\u00f3n A* dentro del laberinto.<\/li><li>Progresi\u00f3n desde la vulnerabilidad hasta la huida.<\/li><li>Una adaptaci\u00f3n jugable para este portfolio.<\/li><\/ul><\/div><\/section>\r\n\r\n    <footer class=\"crp-closing\"><span class=\"crp-label\">Fin del expediente<\/span><h3>\u00bfTu juego tambi\u00e9n necesita una amenaza memorable?<\/h3><p>Si est\u00e1s creando una experiencia interactiva y necesitas trabajar la IA, el dise\u00f1o de niveles o su atm\u00f3sfera visual, hablemos.<\/p><div class=\"crp-actions\"><a class=\"crp-button crp-button--primary\" href=\"https:\/\/mariogr.com\/#contact\" target=\"_blank\" rel=\"noopener noreferrer\">Hablar con Mario \u2197<\/a><a class=\"crp-button\" href=\"#crp-ia\">Volver a la IA \u2191<\/a><\/div><\/footer>\r\n  <\/div>\r\n<\/article>\r\n<script>\r\n(() => {\r\n  document.querySelectorAll('[data-crp-simulator]').forEach(root => {\r\n    if (root.dataset.crpReady) return;\r\n    root.dataset.crpReady = '1';\r\n    const states = {\r\n      unarmed: ['Patrulla agresiva', 'Al detectar al jugador desarmado, los enemigos se muestran m\u00e1s agresivos y patrullan activamente.'],\r\n      armed: ['Defensa o emboscada', 'Si el jugador ya tiene un arma, los enemigos pueden adoptar t\u00e1cticas defensivas o preparar una emboscada.'],\r\n      exit: ['Intercepci\u00f3n de la huida', 'Al acercarse el jugador a la salida, los enemigos aumentan su velocidad y agresividad para impedir la fuga.']\r\n    };\r\n    root.querySelectorAll('[data-crp-state]').forEach(button => button.addEventListener('click', () => {\r\n      const [title, description] = states[button.dataset.crpState];\r\n      root.querySelectorAll('[data-crp-state]').forEach(item => item.setAttribute('aria-pressed', String(item === button)));\r\n      root.querySelector('[data-crp-title]').textContent = title;\r\n      root.querySelector('[data-crp-description]').textContent = description;\r\n    }));\r\n  });\r\n})();\r\n<\/script>\r\n<script>\r\n(() => {\r\n  document.querySelectorAll('[data-crp-game]').forEach(root => {\r\n    if (root.dataset.crpGameReady) return;\r\n    root.dataset.crpGameReady = '1';\r\n    const canvas = root.querySelector('canvas');\r\n    const ctx = canvas && canvas.getContext('2d');\r\n    const status = root.querySelector('[data-crp-status]');\r\n    if (!ctx) { status.textContent = 'Este navegador no admite Canvas 2D.'; return; }\r\n\r\n    const W = 15, H = 11, T = 36;\r\n    const buttons = {\r\n      start: root.querySelector('[data-crp-action=\"start\"]'),\r\n      pause: root.querySelector('[data-crp-action=\"pause\"]'),\r\n      repair: root.querySelector('[data-crp-action=\"repair\"]'),\r\n      fire: root.querySelector('[data-crp-action=\"fire\"]'),\r\n      map: root.querySelector('[data-crp-action=\"map\"]')\r\n    };\r\n    const dirs = [{ x: 0, y: -1 }, { x: 1, y: 0 }, { x: 0, y: 1 }, { x: -1, y: 0 }];\r\n    const key = (x, y) => `${x},${y}`;\r\n    const same = (a, b) => a.x === b.x && a.y === b.y;\r\n    const distance = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);\r\n    let grid, route, weapon, bench, exit, enemies, player, facing, checkpoint;\r\n    let mode = 'idle', phase = 0, health = 3, kills = 0, runs = 0, showMap = false;\r\n    let enemyClock = 0, lastFrame = performance.now(), lastDraw = 0, lastMove = 0, lastShot = 0;\r\n    let flash = null, invulnerableUntil = 0, dirty = true;\r\n\r\n    function randomFactory(seed) {\r\n      let value = seed >>> 0;\r\n      return () => ((value = (Math.imul(value, 1664525) + 1013904223) >>> 0) \/ 4294967296);\r\n    }\r\n    function open(x, y) { return x >= 0 && y >= 0 && x < W && y < H && grid[y][x] === 0; }\r\n    function neighbors(point) { return dirs.map(dir => ({ x: point.x + dir.x, y: point.y + dir.y })).filter(pos => open(pos.x, pos.y)); }\r\n\r\n    function farthestPath(start) {\r\n      const queue = [start], parents = new Map([[key(start.x, start.y), null]]);\r\n      let last = start;\r\n      for (let i = 0; i < queue.length; i++) {\r\n        const point = queue[i];\r\n        last = point; \/\/ En una BFS, el \u00faltimo nodo visitado tiene la mayor distancia por pasillos.\r\n        for (const next of neighbors(point)) {\r\n          const id = key(next.x, next.y);\r\n          if (parents.has(id)) continue;\r\n          parents.set(id, point);\r\n          queue.push(next);\r\n        }\r\n      }\r\n      const path = [];\r\n      for (let point = last; point; point = parents.get(key(point.x, point.y))) path.unshift(point);\r\n      return path;\r\n    }\r\n\r\n    function createMaze() {\r\n      for (let attempt = 0; attempt < 18; attempt++) {\r\n        const random = randomFactory(543217 + runs * 8831 + attempt * 379);\r\n        grid = Array.from({ length: H }, () => Array(W).fill(1));\r\n        grid[1][1] = 0;\r\n        const stack = [{ x: 1, y: 1 }];\r\n        while (stack.length) {\r\n          const current = stack[stack.length - 1];\r\n          const options = dirs.map(dir => ({ x: current.x + dir.x * 2, y: current.y + dir.y * 2, wx: current.x + dir.x, wy: current.y + dir.y }))\r\n            .filter(next => next.x > 0 && next.y > 0 && next.x < W - 1 && next.y < H - 1 && grid[next.y][next.x] === 1);\r\n          if (!options.length) { stack.pop(); continue; }\r\n          const next = options[Math.floor(random() * options.length)];\r\n          grid[next.wy][next.wx] = 0;\r\n          grid[next.y][next.x] = 0;\r\n          stack.push(next);\r\n        }\r\n        for (let y = 1; y < H - 1; y++) for (let x = 1; x < W - 1; x++) {\r\n          if (!grid[y][x] || random() > .075) continue;\r\n          if (x % 2 === 0 && y % 2 === 1 && !grid[y][x - 1] && !grid[y][x + 1]) grid[y][x] = 0;\r\n          if (x % 2 === 1 && y % 2 === 0 && !grid[y - 1][x] && !grid[y + 1][x]) grid[y][x] = 0;\r\n        }\r\n        route = farthestPath({ x: 1, y: 1 });\r\n        if (route.length >= 28 || attempt === 17) break;\r\n      }\r\n      const at = ratio => route[Math.floor((route.length - 1) * ratio)];\r\n      player = { x: 1, y: 1 };\r\n      checkpoint = { ...player };\r\n      facing = { x: 1, y: 0 };\r\n      weapon = { ...at(.27) };\r\n      bench = { ...at(.57) };\r\n      exit = { ...route[route.length - 1] };\r\n      enemies = [.76, .9].map((ratio, id) => ({ ...at(ratio), spawn: { ...at(ratio) }, id, alive: true, previous: null }));\r\n    }\r\n\r\n    \/\/ A* real para el movimiento de las criaturas de esta adaptaci\u00f3n.\r\n    function aStar(start, goal) {\r\n      const openSet = [{ ...start, g: 0, f: distance(start, goal) }];\r\n      const best = new Map([[key(start.x, start.y), 0]]);\r\n      const parents = new Map();\r\n      while (openSet.length) {\r\n        openSet.sort((a, b) => a.f - b.f);\r\n        const current = openSet.shift();\r\n        const id = key(current.x, current.y);\r\n        if (current.g !== best.get(id)) continue;\r\n        if (same(current, goal)) {\r\n          const path = [{ x: current.x, y: current.y }];\r\n          for (let point = parents.get(id); point; point = parents.get(key(point.x, point.y))) path.unshift(point);\r\n          return path;\r\n        }\r\n        for (const next of neighbors(current)) {\r\n          const nextId = key(next.x, next.y), cost = current.g + 1;\r\n          if (cost >= (best.get(nextId) ?? Infinity)) continue;\r\n          best.set(nextId, cost);\r\n          parents.set(nextId, { x: current.x, y: current.y });\r\n          openSet.push({ ...next, g: cost, f: cost + distance(next, goal) });\r\n        }\r\n      }\r\n      return [];\r\n    }\r\n\r\n    function setStatus(message) { status.textContent = message; dirty = true; }\r\n    function updateHud() {\r\n      root.querySelector('[data-crp-health]').textContent = '\u2665 '.repeat(health).trim() || 'SIN VIDAS';\r\n      root.querySelector('[data-crp-objective]').textContent = phase === 0 ? 'Busca el arma' : phase === 1 ? 'Repara el arma' : kills < 2 ? 'Elimina las criaturas' : 'Ve a la salida';\r\n      root.querySelector('[data-crp-kills]').textContent = `${kills} \/ 2`;\r\n      buttons.repair.disabled = mode !== 'playing' || phase !== 1 || !same(player, bench);\r\n      buttons.fire.disabled = mode !== 'playing' || phase < 2;\r\n      buttons.pause.disabled = mode !== 'playing' && mode !== 'paused';\r\n      buttons.map.disabled = mode !== 'playing' && mode !== 'paused';\r\n      buttons.pause.textContent = mode === 'paused' ? 'Continuar' : 'Pausa';\r\n      buttons.map.textContent = showMap ? 'Ocultar mapa' : 'Mapa';\r\n    }\r\n    function start() {\r\n      runs++;\r\n      createMaze();\r\n      phase = 0; health = 3; kills = 0; showMap = false; enemyClock = 0;\r\n      invulnerableUntil = 0; lastMove = 0; lastShot = 0; flash = null;\r\n      mode = 'playing';\r\n      buttons.start.textContent = 'Reiniciar';\r\n      updateHud();\r\n      setStatus('La puerta se cierra detr\u00e1s de ti. Busca el arma averiada.');\r\n      canvas.focus();\r\n    }\r\n    function pause() {\r\n      if (mode === 'playing') { mode = 'paused'; setStatus('El laberinto aguarda. Pulsa Continuar.'); }\r\n      else if (mode === 'paused') { mode = 'playing'; setStatus('Has vuelto. Algo se mueve en los pasillos.'); canvas.focus(); }\r\n      updateHud();\r\n    }\r\n    function end(won) {\r\n      mode = won ? 'won' : 'lost';\r\n      buttons.start.textContent = 'Jugar otra vez';\r\n      setStatus(won ? 'Escapaste. El laberinto tendr\u00e1 que esperar a otra v\u00edctima.' : 'Las criaturas te encontraron. Pulsa \u00abJugar otra vez\u00bb.');\r\n      updateHud();\r\n    }\r\n    function hurt() {\r\n      if (mode !== 'playing' || performance.now() < invulnerableUntil) return;\r\n      health--;\r\n      if (health <= 0) { end(false); return; }\r\n      player = { ...checkpoint };\r\n      enemies.forEach(enemy => { if (enemy.alive) { enemy.x = enemy.spawn.x; enemy.y = enemy.spawn.y; enemy.previous = null; } });\r\n      invulnerableUntil = performance.now() + 1800;\r\n      enemyClock = 0;\r\n      setStatus(`Una criatura te alcanz\u00f3. Quedan ${health} vidas; vuelves al \u00faltimo punto seguro.`);\r\n      updateHud();\r\n    }\r\n    function move(dir) {\r\n      if (mode !== 'playing') return;\r\n      const now = performance.now();\r\n      if (now - lastMove < 115) return;\r\n      lastMove = now;\r\n      facing = dir;\r\n      const next = { x: player.x + dir.x, y: player.y + dir.y };\r\n      if (!open(next.x, next.y)) { dirty = true; return; }\r\n      if (enemies.some(enemy => enemy.alive && same(enemy, next))) { hurt(); return; }\r\n      player = next;\r\n      if (phase === 0 && same(player, weapon)) {\r\n        phase = 1; checkpoint = { ...weapon };\r\n        setStatus('Has encontrado el arma. Est\u00e1 rota. Busca la mesa de reparaci\u00f3n verde.');\r\n      } else if (phase === 1 && same(player, bench)) {\r\n        setStatus('Mesa de reparaci\u00f3n encontrada. Pulsa E o el bot\u00f3n Reparar.');\r\n      } else if (same(player, bench) && phase === 0) {\r\n        setStatus('Hay herramientas en la mesa, pero todav\u00eda no tienes el arma.');\r\n      } else if (same(player, exit)) {\r\n        if (phase === 2 && kills === 2) { end(true); return; }\r\n        setStatus('La salida est\u00e1 sellada: repara el arma y elimina a las dos criaturas.');\r\n      }\r\n      updateHud();\r\n      dirty = true;\r\n    }\r\n    function repair() {\r\n      if (mode !== 'playing' || phase !== 1) return;\r\n      if (!same(player, bench)) { setStatus('Debes estar sobre la mesa verde para reparar el arma.'); return; }\r\n      phase = 2;\r\n      checkpoint = { ...bench };\r\n      setStatus('El arma funciona. Apunta al avanzar y pulsa Espacio o Disparar.');\r\n      updateHud();\r\n      dirty = true;\r\n    }\r\n    function fire() {\r\n      if (mode !== 'playing') return;\r\n      if (phase < 2) { setStatus(phase === 0 ? 'Todav\u00eda no tienes un arma.' : 'El arma est\u00e1 averiada. Busca la mesa de reparaci\u00f3n.'); return; }\r\n      const now = performance.now();\r\n      if (now - lastShot < 340) return;\r\n      lastShot = now;\r\n      let target = null, endPoint = { ...player };\r\n      for (let step = 1; step <= 6; step++) {\r\n        const x = player.x + facing.x * step, y = player.y + facing.y * step;\r\n        if (!open(x, y)) break;\r\n        endPoint = { x, y };\r\n        target = enemies.find(enemy => enemy.alive && enemy.x === x && enemy.y === y);\r\n        if (target) break;\r\n      }\r\n      flash = { end: endPoint, until: now + 150 };\r\n      if (target) {\r\n        target.alive = false;\r\n        kills++;\r\n        setStatus(kills === 2 ? 'Las criaturas han ca\u00eddo. Corre hacia la salida verde.' : 'Una criatura menos. La otra sigue en el laberinto.');\r\n      } else setStatus('El disparo se pierde entre los muros. Ac\u00e9rcate y apunta al pasillo.');\r\n      updateHud();\r\n      dirty = true;\r\n    }\r\n    function enemyStep() {\r\n      const nearbyExit = distance(player, exit) <= 4;\r\n      for (const enemy of enemies) {\r\n        if (!enemy.alive) continue;\r\n        const range = phase === 1 ? 5 : 7;\r\n        let next;\r\n        if (distance(enemy, player) <= range || nearbyExit) {\r\n          const path = aStar(enemy, player);\r\n          next = path[1];\r\n        } else {\r\n          const options = neighbors(enemy).filter(point => !enemy.previous || !same(point, enemy.previous));\r\n          const choices = options.length ? options : neighbors(enemy);\r\n          next = choices[Math.floor(Math.random() * choices.length)];\r\n        }\r\n        if (!next || enemies.some(other => other !== enemy && other.alive && same(other, next))) continue;\r\n        enemy.previous = { x: enemy.x, y: enemy.y };\r\n        enemy.x = next.x; enemy.y = next.y;\r\n        if (same(enemy, player)) { hurt(); break; }\r\n      }\r\n      dirty = true;\r\n    }\r\n\r\n    function paint(now) {\r\n      ctx.fillStyle = '#080e0a'; ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n      for (let y = 0; y < H; y++) for (let x = 0; x < W; x++) {\r\n        const px = x * T, py = y * T;\r\n        if (grid[y][x]) {\r\n          ctx.fillStyle = (x * 7 + y * 11) % 5 === 0 ? '#28382c' : '#203026';\r\n          ctx.fillRect(px, py, T, T);\r\n          ctx.fillStyle = '#324738'; ctx.fillRect(px + 2, py + 2, T - 4, 2);\r\n          ctx.fillStyle = '#121c16'; ctx.fillRect(px + 2, py + T - 5, T - 4, 3);\r\n          if ((x * 13 + y * 17) % 7 === 0) { ctx.strokeStyle = '#496044'; ctx.beginPath(); ctx.moveTo(px + 17, py + 8); ctx.lineTo(px + 12, py + 19); ctx.lineTo(px + 22, py + 26); ctx.stroke(); }\r\n        } else {\r\n          ctx.fillStyle = (x + y) % 2 ? '#172119' : '#1a261d'; ctx.fillRect(px, py, T, T);\r\n          ctx.strokeStyle = 'rgba(140,170,125,.08)'; ctx.strokeRect(px + .5, py + .5, T - 1, T - 1);\r\n          if ((x * 19 + y * 23) % 9 === 0) { ctx.fillStyle = '#394536'; ctx.fillRect(px + 23, py + 9, 2, 2); }\r\n        }\r\n      }\r\n      const tile = point => ({ x: point.x * T + T \/ 2, y: point.y * T + T \/ 2 });\r\n      const mark = (point, color, label) => {\r\n        const center = tile(point);\r\n        ctx.fillStyle = color; ctx.fillRect(center.x - 10, center.y - 10, 20, 20);\r\n        ctx.strokeStyle = '#f5ebd5'; ctx.lineWidth = 1.5; ctx.strokeRect(center.x - 10, center.y - 10, 20, 20);\r\n        ctx.fillStyle = '#09120d'; ctx.textAlign = 'center'; ctx.font = 'bold 12px monospace'; ctx.fillText(label, center.x, center.y + 4);\r\n      };\r\n      if (phase === 0) mark(weapon, '#e8ba72', '!');\r\n      mark(bench, '#84d8ae', 'R');\r\n      mark(exit, phase === 2 && kills === 2 ? '#c8ed82' : '#9b474a', 'E');\r\n      for (const enemy of enemies) if (enemy.alive) {\r\n        const center = tile(enemy);\r\n        ctx.fillStyle = 'rgba(181,38,42,.22)'; ctx.beginPath(); ctx.arc(center.x, center.y, 18, 0, Math.PI * 2); ctx.fill();\r\n        ctx.fillStyle = '#170e0f'; ctx.beginPath(); ctx.ellipse(center.x, center.y + 3, 12, 14, 0, 0, Math.PI * 2); ctx.fill();\r\n        ctx.fillStyle = '#f26e68'; ctx.fillRect(center.x - 8, center.y - 2, 5, 3); ctx.fillRect(center.x + 3, center.y - 2, 5, 3);\r\n        ctx.strokeStyle = '#a83c3d'; ctx.beginPath(); ctx.moveTo(center.x - 11, center.y - 7); ctx.lineTo(center.x - 15, center.y - 13); ctx.moveTo(center.x + 11, center.y - 7); ctx.lineTo(center.x + 15, center.y - 13); ctx.stroke();\r\n      }\r\n      if (!showMap) {\r\n        const center = tile(player), radius = 160 + (window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 0 : Math.sin(now \/ 140) * 5);\r\n        const fog = ctx.createRadialGradient(center.x, center.y, 31, center.x, center.y, radius);\r\n        fog.addColorStop(0, 'rgba(1,5,3,0)'); fog.addColorStop(.62, 'rgba(1,5,3,.14)'); fog.addColorStop(1, 'rgba(1,5,3,.82)');\r\n        ctx.fillStyle = fog; ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n      }\r\n      if (flash && now < flash.until) {\r\n        const from = tile(player), to = tile(flash.end);\r\n        ctx.strokeStyle = '#ffe7a7'; ctx.lineWidth = 4; ctx.shadowColor = '#ffbd6e'; ctx.shadowBlur = 15;\r\n        ctx.beginPath(); ctx.moveTo(from.x, from.y); ctx.lineTo(to.x, to.y); ctx.stroke(); ctx.shadowBlur = 0;\r\n      }\r\n      const center = tile(player);\r\n      if (now >= invulnerableUntil || Math.floor(now \/ 100) % 2 === 0) {\r\n        ctx.fillStyle = '#e6e1c8'; ctx.beginPath(); ctx.arc(center.x, center.y, 9, 0, Math.PI * 2); ctx.fill();\r\n        ctx.fillStyle = '#daaa70'; ctx.beginPath(); ctx.arc(center.x, center.y, 4, 0, Math.PI * 2); ctx.fill();\r\n        ctx.strokeStyle = '#f6e5a5'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(center.x, center.y); ctx.lineTo(center.x + facing.x * 14, center.y + facing.y * 14); ctx.stroke();\r\n      }\r\n      if (mode !== 'playing') {\r\n        ctx.fillStyle = 'rgba(4,10,6,.76)'; ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n        ctx.textAlign = 'center'; ctx.fillStyle = mode === 'won' ? '#c8ed82' : '#f0b5a9';\r\n        ctx.font = 'bold 32px Georgia';\r\n        ctx.fillText(mode === 'idle' ? 'NO EST\u00c1S SOLO' : mode === 'paused' ? 'EL TIEMPO SE DETIENE' : mode === 'won' ? 'HAS ESCAPADO' : 'TE HAN ENCONTRADO', canvas.width \/ 2, 181);\r\n        ctx.fillStyle = '#d2dfcc'; ctx.font = '14px monospace';\r\n        ctx.fillText(mode === 'paused' ? 'PULSA CONTINUAR' : mode === 'idle' ? 'PULSA ENTRAR' : 'PULSA JUGAR OTRA VEZ', canvas.width \/ 2, 218);\r\n      }\r\n    }\r\n\r\n    function frame(now) {\r\n      if (!root.isConnected) return;\r\n      const dt = Math.min((now - lastFrame) \/ 1000, .1); lastFrame = now;\r\n      if (mode === 'playing' && !document.hidden) {\r\n        enemyClock += dt;\r\n        const speed = distance(player, exit) <= 4 ? .52 : phase === 1 ? .85 : phase === 0 ? .72 : .68;\r\n        if (enemyClock >= speed) { enemyClock = 0; enemyStep(); }\r\n      }\r\n      if (dirty || mode === 'playing' && now - lastDraw > 100) { paint(now); dirty = false; lastDraw = now; }\r\n      requestAnimationFrame(frame);\r\n    }\r\n\r\n    buttons.start.addEventListener('click', start);\r\n    buttons.pause.addEventListener('click', pause);\r\n    buttons.repair.addEventListener('click', repair);\r\n    buttons.fire.addEventListener('click', fire);\r\n    buttons.map.addEventListener('click', () => { showMap = !showMap; updateHud(); dirty = true; canvas.focus(); });\r\n    const keyDirections = { ArrowUp: dirs[0], KeyW: dirs[0], ArrowRight: dirs[1], KeyD: dirs[1], ArrowDown: dirs[2], KeyS: dirs[2], ArrowLeft: dirs[3], KeyA: dirs[3] };\r\n    document.addEventListener('keydown', event => {\r\n      if (!root.contains(document.activeElement)) return;\r\n      if (keyDirections[event.code]) { event.preventDefault(); move(keyDirections[event.code]); }\r\n      else if (event.code === 'KeyE') { event.preventDefault(); repair(); }\r\n      else if (event.code === 'Space') { event.preventDefault(); fire(); }\r\n      else if (event.code === 'KeyP') { event.preventDefault(); pause(); }\r\n      else if (event.code === 'KeyM' && (mode === 'playing' || mode === 'paused')) { event.preventDefault(); showMap = !showMap; updateHud(); dirty = true; }\r\n    });\r\n    root.querySelectorAll('[data-crp-move]').forEach(button => {\r\n      const direction = { up: dirs[0], right: dirs[1], down: dirs[2], left: dirs[3] }[button.dataset.crpMove];\r\n      let timer;\r\n      const stop = () => { if (timer) clearInterval(timer); timer = null; };\r\n      button.addEventListener('pointerdown', event => { event.preventDefault(); stop(); button.setPointerCapture(event.pointerId); move(direction); timer = setInterval(() => move(direction), 145); });\r\n      ['pointerup', 'pointercancel', 'lostpointercapture'].forEach(type => button.addEventListener(type, stop));\r\n      button.addEventListener('click', event => { if (event.detail === 0) move(direction); });\r\n    });\r\n    window.addEventListener('blur', () => { if (mode === 'playing') pause(); });\r\n    document.addEventListener('visibilitychange', () => { if (document.hidden && mode === 'playing') pause(); });\r\n    createMaze(); updateHud(); paint(performance.now()); requestAnimationFrame(frame);\r\n  });\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"featured_media":1454,"menu_order":0,"template":"","portfolio_categories":[50,46],"portfolio_tags":[33,36,55],"class_list":["post-1453","portfolio","type-portfolio","status-publish","has-post-thumbnail","hentry","portfolio_categories-ai","portfolio_categories-videojuegos","portfolio_tags-mobile","portfolio_tags-software","portfolio_tags-videojuegos"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Inteligencia Artificial en un Laberinto Creepy - Mario Gonz\u00e1lez<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Inteligencia Artificial en un Laberinto Creepy - Mario Gonz\u00e1lez\" \/>\n<meta property=\"og:description\" content=\"Expediente 01 \/ Se\u00f1al detectadaUnity \u00b7 IA \u00b7 Terror Laberinto Creepy \u00b7 Videojuego multiplataforma El laberinto te est\u00e1 buscando. En...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/\" \/>\n<meta property=\"og:site_name\" content=\"Mario Gonz\u00e1lez\" \/>\n<meta property=\"article:modified_time\" content=\"2026-11-04T15:19:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/mariogr.com\/wp-content\/uploads\/2025\/02\/Imagen3.png\" \/>\n\t<meta property=\"og:image:width\" content=\"431\" \/>\n\t<meta property=\"og:image:height\" content=\"430\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data1\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/inteligencia-artificial-en-un-laberinto-creepy\\\/\",\"url\":\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/inteligencia-artificial-en-un-laberinto-creepy\\\/\",\"name\":\"Inteligencia Artificial en un Laberinto Creepy - Mario Gonz\u00e1lez\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariogr.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/inteligencia-artificial-en-un-laberinto-creepy\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/inteligencia-artificial-en-un-laberinto-creepy\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/mariogr.com\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/Imagen3.png\",\"datePublished\":\"2025-02-21T14:44:00+00:00\",\"dateModified\":\"2026-11-04T15:19:05+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/inteligencia-artificial-en-un-laberinto-creepy\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/inteligencia-artificial-en-un-laberinto-creepy\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/inteligencia-artificial-en-un-laberinto-creepy\\\/#primaryimage\",\"url\":\"https:\\\/\\\/mariogr.com\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/Imagen3.png\",\"contentUrl\":\"https:\\\/\\\/mariogr.com\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/Imagen3.png\",\"width\":431,\"height\":430},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/inteligencia-artificial-en-un-laberinto-creepy\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/mariogr.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Portfolio\",\"item\":\"https:\\\/\\\/mariogr.com\\\/index.php\\\/portfolio-archive\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Inteligencia Artificial en un Laberinto Creepy\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariogr.com\\\/#website\",\"url\":\"https:\\\/\\\/mariogr.com\\\/\",\"name\":\"Mario Gonz\u00e1lez\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariogr.com\\\/#\\\/schema\\\/person\\\/eb8233b36ab81d794487c9dabf5099ec\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/mariogr.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/mariogr.com\\\/#\\\/schema\\\/person\\\/eb8233b36ab81d794487c9dabf5099ec\",\"name\":\"Mario Gonz\u00e1lez\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd530be9d9f1f94c4f61cde6df1335bd8ac6fcc3f83a362eb0911f10b6f91d25?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd530be9d9f1f94c4f61cde6df1335bd8ac6fcc3f83a362eb0911f10b6f91d25?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd530be9d9f1f94c4f61cde6df1335bd8ac6fcc3f83a362eb0911f10b6f91d25?s=96&d=mm&r=g\",\"caption\":\"Mario Gonz\u00e1lez\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd530be9d9f1f94c4f61cde6df1335bd8ac6fcc3f83a362eb0911f10b6f91d25?s=96&d=mm&r=g\"},\"sameAs\":[\"https:\\\/\\\/mariogr.com\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/mariogr99\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Inteligencia Artificial en un Laberinto Creepy - Mario Gonz\u00e1lez","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/","og_locale":"es_ES","og_type":"article","og_title":"Inteligencia Artificial en un Laberinto Creepy - Mario Gonz\u00e1lez","og_description":"Expediente 01 \/ Se\u00f1al detectadaUnity \u00b7 IA \u00b7 Terror Laberinto Creepy \u00b7 Videojuego multiplataforma El laberinto te est\u00e1 buscando. En...","og_url":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/","og_site_name":"Mario Gonz\u00e1lez","article_modified_time":"2026-11-04T15:19:05+00:00","og_image":[{"width":431,"height":430,"url":"https:\/\/mariogr.com\/wp-content\/uploads\/2025\/02\/Imagen3.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Tiempo de lectura":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/","url":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/","name":"Inteligencia Artificial en un Laberinto Creepy - Mario Gonz\u00e1lez","isPartOf":{"@id":"https:\/\/mariogr.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/#primaryimage"},"image":{"@id":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/#primaryimage"},"thumbnailUrl":"https:\/\/mariogr.com\/wp-content\/uploads\/2025\/02\/Imagen3.png","datePublished":"2025-02-21T14:44:00+00:00","dateModified":"2026-11-04T15:19:05+00:00","breadcrumb":{"@id":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/#primaryimage","url":"https:\/\/mariogr.com\/wp-content\/uploads\/2025\/02\/Imagen3.png","contentUrl":"https:\/\/mariogr.com\/wp-content\/uploads\/2025\/02\/Imagen3.png","width":431,"height":430},{"@type":"BreadcrumbList","@id":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/inteligencia-artificial-en-un-laberinto-creepy\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/mariogr.com\/"},{"@type":"ListItem","position":2,"name":"Portfolio","item":"https:\/\/mariogr.com\/index.php\/portfolio-archive\/"},{"@type":"ListItem","position":3,"name":"Inteligencia Artificial en un Laberinto Creepy"}]},{"@type":"WebSite","@id":"https:\/\/mariogr.com\/#website","url":"https:\/\/mariogr.com\/","name":"Mario Gonz\u00e1lez","description":"","publisher":{"@id":"https:\/\/mariogr.com\/#\/schema\/person\/eb8233b36ab81d794487c9dabf5099ec"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/mariogr.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":["Person","Organization"],"@id":"https:\/\/mariogr.com\/#\/schema\/person\/eb8233b36ab81d794487c9dabf5099ec","name":"Mario Gonz\u00e1lez","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/fd530be9d9f1f94c4f61cde6df1335bd8ac6fcc3f83a362eb0911f10b6f91d25?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/fd530be9d9f1f94c4f61cde6df1335bd8ac6fcc3f83a362eb0911f10b6f91d25?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/fd530be9d9f1f94c4f61cde6df1335bd8ac6fcc3f83a362eb0911f10b6f91d25?s=96&d=mm&r=g","caption":"Mario Gonz\u00e1lez"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/fd530be9d9f1f94c4f61cde6df1335bd8ac6fcc3f83a362eb0911f10b6f91d25?s=96&d=mm&r=g"},"sameAs":["https:\/\/mariogr.com","https:\/\/www.linkedin.com\/in\/mariogr99\/"]}]}},"_links":{"self":[{"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/portfolio\/1453","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/portfolio"}],"about":[{"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/types\/portfolio"}],"version-history":[{"count":6,"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/portfolio\/1453\/revisions"}],"predecessor-version":[{"id":1724,"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/portfolio\/1453\/revisions\/1724"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/media\/1454"}],"wp:attachment":[{"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/media?parent=1453"}],"wp:term":[{"taxonomy":"portfolio_categories","embeddable":true,"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/portfolio_categories?post=1453"},{"taxonomy":"portfolio_tags","embeddable":true,"href":"https:\/\/mariogr.com\/index.php\/wp-json\/wp\/v2\/portfolio_tags?post=1453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}