1var Y=Object.defineProperty;var B=(h,t,s)=>t in h?Y(h,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):h[t]=s;var d=(h,t,s)=>B(h,typeof t!="symbol"?t+"":t,s);import{_ as V,c as x,o as y,a as u,p as M,C as k,h as T,H as O,z as b}from"./router-B_NRvU0r.js";import{c as p,p as _,r as w,P as D,F as g,G as v,L,K as m,T as R}from"./TetrisRenderer-COyD4Mj2.js";import"./three.module-B96IhAFS.js";class P{constructor(){d(this,"blocks");this.blocks=new Map}clear(){this.blocks.clear()}get(t,s,e){return this.blocks.get(p(t,s,e))??null}set(t,s,e,i){const o=p(t,s,e);i===null?this.blocks.delete(o):this.blocks.set(o,i)}has(t,s,e){return this.blocks.has(p(t,s,e))}getBounds(){let t=0,s=0,e=0,i=0,o=0,r=0,a=!0;for(const n of this.blocks.keys()){const{x:c,y:l,z:f}=_(n);a?(t=s=c,e=i=l,o=r=f,a=!1):(t=Math.min(t,c),s=Math.max(s,c),e=Math.min(e,l),i=Math.max(i,l),o=Math.min(o,f),r=Math.max(r,f))}return{minX:t,maxX:s,minY:e,maxY:i,minZ:o,maxZ:r}}toPointList(){const t=[];for(const[s,e]of this.blocks)t.push({point:_(s),data:e});return t}entries(){return this.blocks.entries()}get size(){return this.blocks.size}rotate(t,s=1){const e=new P;if(s=(s%4+4)%4,s===0){for(const[i,o]of this.blocks){const r=_(i);e.set(r.x,r.y,r.z,{...o})}return e}for(const[i,o]of this.blocks){let{x:r,y:a,z:n}=_(i);for(let c=0;c<s;c++){let l=r,f=a,S=n;switch(t){case"x":f=-n,S=a;break;case"y":l=n,S=-r;break;case"z":l=-a,f=r;break}r=w(l),a=w(f),n=w(S)}e.set(r,a,n,{...o,position:{x:r,y:a,z:n}})}return e}clone(){const t=new P;for(const[s,e]of this.blocks)t.blocks.set(s,{...e});return t}countAtY(t){let s=0;for(const e of this.blocks.keys())_(e).y===t&&s++;return s}getOccupiedYLevels(){const t=new Set;for(const s of this.blocks.keys()){const{y:e}=_(s);t.add(e)}return Array.from(t).sort((s,e)=>s-e)}removeLayerAndShift(t){const s=[],e=[];for(const[i,o]of this.blocks){const r=_(i);r.y===t?s.push(i):r.y>t&&e.push({key:i,data:o,point:r})}for(const i of s)this.blocks.delete(i);e.sort((i,o)=>i.point.y-o.point.y);for(const{key:i,data:o,point:r}of e){this.blocks.delete(i);const a=r.y-1;this.set(r.x,a,r.z,{...o,position:{x:r.x,y:a,z:r.z}})}}removeLayersAndShift(t){if(t.length===0)return;const s=[...t].sort((r,a)=>r-a),e=new Set(s),i=[],o=[];for(const[r,a]of this.blocks){const n=_(r);if(e.has(n.y))i.push(r);else{let c=0;for(const l of s)if(l<n.y)c++;else break;c>0&&o.push({key:r,data:a,point:n,dropDistance:c})}}for(const r of i)this.blocks.delete(r);o.sort((r,a)=>r.point.y-a.point.y);for(const{key:r,data:a,point:n,dropDistance:c}of o){this.blocks.delete(r);const l=n.y-c;this.set(n.x,l,n.z,{...a,position:{x:n.x,y:l,z:n.z}})}}}class z{constructor(t,s){d(this,"grid");d(this,"_position");d(this,"_rotationState");d(this,"definition");this.definition=t,this.grid=new P,this._position=s??{x:0,y:0,z:0},this._rotationState={x:0,y:0,z:0},this.initializeBlocks()}initializeBlocks(){this.grid.clear();for(const t of this.definition.blocks)this.grid.set(t.x,t.y,t.z,{color:this.definition.color,position:{...t}})}get position(){return{...this._position}}set position(t){this._position={...t}}get color(){return this.definition.color}getWorldBlocks(){const t=[],s=this.grid.toPointList(),e=new Set;for(const{point:i}of s)e.add(p(i.x,i.y,i.z));for(const{point:i,data:o}of s){let r=0;e.has(p(i.x+1,i.y,i.z))||(r|=g.POS_X),e.has(p(i.x-1,i.y,i.z))||(r|=g.NEG_X),e.has(p(i.x,i.y+1,i.z))||(r|=g.POS_Y),e.has(p(i.x,i.y-1,i.z))||(r|=g.NEG_Y),e.has(p(i.x,i.y,i.z+1))||(r|=g.POS_Z),e.has(p(i.x,i.y,i.z-1))||(r|=g.NEG_Z),t.push({point:{x:i.x+this._position.x,y:i.y+this._position.y,z:i.z+this._position.z},data:{...o,faceMask:r}})}return t}getLocalBlocks(){return this.grid.toPointList().map(({point:t})=>({...t}))}getBaseBlocks(){return this.definition.blocks.map(t=>({...t}))}getRotationAngles(){const t=Math.PI/2;return{x:this._rotationState.x*t,y:this._rotationState.y*t,z:this._rotationState.z*t}}move(t,s,e){this._position.x+=t,this._position.y+=s,this._position.z+=e}moveLeft(){this.move(-1,0,0)}moveRight(){this.move(1,0,0)}moveForward(){this.move(0,0,-1)}moveBackward(){this.move(0,0,1)}moveDown(){this.move(0,-1,0)}rotate(t,s=1){this.grid=this.grid.rotate(t,s),this._rotationState[t]=(this._rotationState[t]+s)%4,this._rotationState[t]<0&&(this._rotationState[t]+=4)}rotateX(t=1){this.rotate("x",t)}rotateY(t=1){this.rotate("y",t)}rotateZ(t=1){this.rotate("z",t)}getWorldBounds(){const t=this.grid.getBounds();return{min:{x:t.minX+this._position.x,y:t.minY+this._position.y,z:t.minZ+this._position.z},max:{x:t.maxX+this._position.x,y:t.maxY+this._position.y,z:t.maxZ+this._position.z}}}clone(){const t=new z(this.definition,{...this._position});return t.grid=this.grid.clone(),t._rotationState={...this._rotationState},t}static createRandom(t){const s=Math.floor(Math.random()*D.length);return new z(D[s],t)}static createByName(t,s){const e=D.find(i=>i.name===t);return e?new z(e,s):null}}const A="cubeTetris.highScore";class I{constructor(t){d(this,"config");d(this,"board");d(this,"_currentPiece",null);d(this,"_nextPiece",null);d(this,"_state");d(this,"_highScore",0);d(this,"_lastDropTime",0);d(this,"_eventListeners",new Map);d(this,"_clearingLayers",[]);d(this,"_isClearingAnimation",!1);d(this,"_isDropping",!1);d(this,"_dropTargetY",0);d(this,"_dropVisualY",0);d(this,"_lastDropAnimTime",0);this.config={...v,...t},this.board=new P,this._state={score:0,level:1,linesCleared:0,piecesDropped:0,gameOver:!1,paused:!1},this._highScore=this.loadHighScore()}get currentPiece(){return this._currentPiece}get nextPiece(){return this._nextPiece}get state(){return{...this._state}}get highScore(){return this._highScore}get isDropping(){return this._isDropping}get dropVisualY(){var t;return this._isDropping?this._dropVisualY:((t=this._currentPiece)==null?void 0:t.position.y)??0}on(t,s){this._eventListeners.has(t)||this._eventListeners.set(t,new Set),this._eventListeners.get(t).add(s)}off(t,s){var e;(e=this._eventListeners.get(t))==null||e.delete(s)}emit(t,s){var i;const e={type:t,data:s};
1(i=this._eventListeners.get(t))==null||i.forEach(o=>o(e))}start(){this.board.clear(),this._state={score:0,level:1,linesCleared:0,piecesDropped:0,gameOver:!1,paused:!1},this._lastDropTime=0,this._nextPiece=this.createPiece(),this.spawnNextPiece()}togglePause(){this._state.gameOver||(this._state.paused=!this._state.paused,this._state.paused||(this._lastDropTime=0))}createPiece(){const t={x:Math.floor(this.config.boardWidth/2),y:this.config.boardHeight-1,z:Math.floor(this.config.boardDepth/2)};return z.createRandom(t)}spawnNextPiece(){this._currentPiece=this._nextPiece,this._nextPiece=this.createPiece(),this._currentPiece&&this.centerPiece(this._currentPiece),this._currentPiece&&!this.isValidPosition(this._currentPiece)?(this._state.gameOver=!0,this.emit("gameOver")):this.emit("pieceSpawned",{piece:this._currentPiece})}centerPiece(t){const s=t.getWorldBounds(),e=s.max.x-s.min.x+1,i=s.max.z-s.min.z+1,o=Math.floor((this.config.boardWidth-e)/2),r=Math.floor((this.config.boardDepth-i)/2);t.position={x:o-s.min.x+t.position.x,y:t.position.y,z:r-s.min.z+t.position.z}}isValidPosition(t){const s=t.getWorldBlocks();for(const{point:e}of s)if(e.y<0||e.x<0||e.x>=this.config.boardWidth||e.z<0||e.z>=this.config.boardDepth||this.board.has(e.x,e.y,e.z))return!1;return!0}movePiece(t,s,e){if(!this._currentPiece||this._state.gameOver||this._state.paused)return!1;const i=this._currentPiece.clone();return i.move(t,s,e),this.isValidPosition(i)?(this._currentPiece.move(t,s,e),this.emit("pieceMoved",{direction:{dx:t,dy:s,dz:e}}),!0):!1}moveLeft(){return this.movePiece(-1,0,0)}moveRight(){return this.movePiece(1,0,0)}moveForward(){return this.movePiece(0,0,-1)}moveBackward(){return this.movePiece(0,0,1)}rotatePiece(t,s=1){if(!this._currentPiece||this._state.gameOver||this._state.paused)return!1;const e=this._currentPiece.clone();if(e.rotate(t,s),this.isValidPosition(e))return this._currentPiece.rotate(t,s),this.emit("pieceRotated",{axis:t,times:s}),!0;const i=[];for(let o=1;o<=3;o++)i.push({x:-o,z:0},{x:o,z:0},{x:0,z:-o},{x:0,z:o}),i.push({x:-o,z:-o},{x:o,z:-o},{x:-o,z:o},{x:o,z:o});for(const o of i){const r=this._currentPiece.clone();if(r.rotate(t,s),r.move(o.x,0,o.z),this.isValidPosition(r))return this._currentPiece.rotate(t,s),this._currentPiece.move(o.x,0,o.z),this.emit("pieceRotated",{axis:t,times:s,kick:o}),!0}return!1}dropOne(){return!this._currentPiece||this._state.gameOver||this._state.paused?!1:this.movePiece(0,-1,0)?!0:(this.lockPiece(),!1)}hardDrop(){if(!this._currentPiece||this._state.gameOver||this._state.paused||this._isDropping)return;const t=this.getGhostPosition();if(!t)return;const s=this._currentPiece.position.y,e=t.y;if(s<=e){this.lockPiece();return}this._isDropping=!0,this._dropTargetY=e,this._dropVisualY=s,this._currentPiece.position={...this._currentPiece.position,y:e},this.emit("pieceDropping",{startY:s,targetY:e})}lockPiece(){if(!this._currentPiece)return;const t=this._currentPiece.getWorldBlocks();for(const{point:e,data:i}of t)this.board.set(e.x,e.y,e.z,i);this._state.piecesDropped++,this.emit("pieceLocked",{piece:this._currentPiece});const s=this.detectFullLayers();if(s.length>0){const e=[];for(const i of s)for(let o=0;o<this.config.boardWidth;o++)for(let r=0;r<this.config.boardDepth;r++){const a=this.board.get(o,i,r);a&&e.push({point:{x:o,y:i,z:r},color:a.color,faceMask:a.faceMask})}this._clearingLayers=s,this._isClearingAnimation=!0,this.emit("layersClearStart",{layers:s,blocks:e})}else this.spawnNextPiece()}detectFullLayers(){const t=[],s=this.config.boardWidth*this.config.boardDepth;for(let e=0;e<this.config.boardHeight;e++)this.board.countAtY(e)===s&&t.push(e);return t}completeClearingAnimation(){if(!this._isClearingAnimation||this._clearingLayers.length===0)return;this.board.removeLayersAndShift(this._clearingLayers),this.updateFaceMasksAfterClearing();const t=this._clearingLayers.length,e=L[Math.min(t,L.length-1)]*(this._state.level+1);this._state.score+=e,this._state.linesCleared+=t,this._state.level=Math.floor(Math.log2(this._state.linesCleared+1)),this.emit("layersCleared",{layers:this._clearingLayers,score:e}
1),this.emit("scoreChanged",{score:this._state.score,level:this._state.level}),this.checkHighScore(),this._clearingLayers=[],this._isClearingAnimation=!1,this.spawnNextPiece()}updateFaceMasksAfterClearing(){const t=[{mask:g.POS_X,dx:1,dy:0,dz:0},{mask:g.NEG_X,dx:-1,dy:0,dz:0},{mask:g.POS_Y,dx:0,dy:1,dz:0},{mask:g.NEG_Y,dx:0,dy:-1,dz:0},{mask:g.POS_Z,dx:0,dy:0,dz:1},{mask:g.NEG_Z,dx:0,dy:0,dz:-1}];for(const{point:s,data:e}of this.board.toPointList()){let i=e.faceMask??g.ALL;for(const o of t)i&o.mask||this.board.get(s.x+o.dx,s.y+o.dy,s.z+o.dz)||(i|=o.mask);e.faceMask=i}}get isClearingAnimation(){return this._isClearingAnimation}getGhostPosition(){if(!this._currentPiece)return null;const t=this._currentPiece.clone();for(;;)if(t.move(0,-1,0),!this.isValidPosition(t)){t.move(0,1,0);break}return t.position}update(t){if(this._state.gameOver||this._state.paused||this._isClearingAnimation||!this._currentPiece)return;if(this._isDropping){this.updateDropAnimation(t);return}if(this._lastDropTime===0){this._lastDropTime=t;return}const s=1e3/Math.sqrt(this._state.level+1);t-this._lastDropTime>=s&&(this.dropOne(),this._lastDropTime=t)}updateDropAnimation(t){if(!this._isDropping)return;if(this._lastDropAnimTime===0){this._lastDropAnimTime=t;return}const s=(t-this._lastDropAnimTime)/1e3;this._lastDropAnimTime=t;const e=this.config.hardDropSpeed;this._dropVisualY-=e*s,this._dropVisualY<=this._dropTargetY&&(this._dropVisualY=this._dropTargetY,this._isDropping=!1,this._lastDropAnimTime=0,this.lockPiece()),this.emit("pieceMoved",{visualY:this._dropVisualY})}get dropInterval(){return 1e3/Math.sqrt(this._state.level+1)}loadHighScore(){try{const t=localStorage.getItem(A);return t&&parseInt(t,10)||0}catch{return 0}}saveHighScore(){try{localStorage.setItem(A,String(this._highScore))}catch{}}checkHighScore(){this._state.score>this._highScore&&(this._highScore=this._state.score,this.saveHighScore(),this.emit("newHighScore",{highScore:this._highScore}))}}const N=[[],[{axis:"y",times:1}],[{axis:"y",times:2}],[{axis:"y",times:-1}],[{axis:"x",times:1}],[{axis:"x",times:1},{axis:"y",times:1}],[{axis:"x",times:1},{axis:"y",times:2}],[{axis:"x",times:1},{axis:"y",times:-1}],[{axis:"x",times:-1}],[{axis:"x",times:-1},{axis:"y",times:1}],[{axis:"x",times:-1},{axis:"y",times:2}],[{axis:"x",times:-1},{axis:"y",times:-1}],[{axis:"z",times:1}],[{axis:"z",times:1},{axis:"y",times:1}],[{axis:"z",times:1},{axis:"y",times:2}],[{axis:"z",times:1},{axis:"y",times:-1}],[{axis:"z",times:-1}],[{axis:"z",times:-1},{axis:"y",times:1}],[{axis:"z",times:-1},{axis:"y",times:2}],[{axis:"z",times:-1},{axis:"y",times:-1}],[{axis:"x",times:2}],[{axis:"x",times:2},{axis:"y",times:1}],[{axis:"x",times:2},{axis:"y",times:2}],[{axis:"x",times:2},{axis:"y",times:-1}]];class E{constructor(t){d(this,"game");d(this,"targetState",null);d(this,"moveDelay",100);d(this,"lastMoveTime",0);d(this,"rotationSteps",[]);d(this,"rotationIndex",0);d(this,"enabled",!1);this.game=t}setEnabled(t){this.enabled=t,t?this.computeTarget():this.targetState=null}isEnabled(){return this.enabled}setMoveDelay(t){this.moveDelay=t}onPieceSpawned(){this.enabled&&(this.computeTarget(),this.rotationIndex=0)}update(t){if(!this.enabled||!this.targetState||!this.game.currentPiece||this.game.state.paused||this.game.state.gameOver||this.game.isClearingAnimation||this.game.isDropping||t-this.lastMoveTime<this.moveDelay)return;const s=this.game.currentPiece,e=this.targetState;if(this.rotationIndex<this.rotationSteps.length){const a=this.rotationSteps[this.rotationIndex];this.game.rotatePiece(a.axis,a.times)?this.rotationIndex++:this.computeTarget(),this.lastMoveTime=t;return}const i=s.getWorldBounds(),o=i.min.x,r=i.min.z;if(o<e.x){this.game.moveRight()||this.computeTarget(),this.lastMoveTime=t;return}else if(o>e.x){this.game.moveLeft()||this.computeTarget(),this.lastMoveTime=t;return}if(r<e.z){this.game.moveBackward()||this.computeTarget(),this.lastMoveTime=t;return}else if(r>e.z){this.game.moveForward()||this.computeTarget(),this.lastMoveTime=t;return}this.game.hardDrop(),this.lastMoveTime=t}computeTarget(){const t=this.game.currentPiece;if(!t){this.targetState=null,this.rotationSteps=[],this.rotationIndex=0;return}const s=[];for(const e of N){const i=t.clone();for(const n of e)i.rotate(n.axis,n.times);const o=i.getWorldBounds(),r=o.max.x-o.min.x+1,a=o.max.z-o.min.z+1;for(let n=0;n<=v.boardWidth-r;n++)for(let c=0;c<=v.boardDepth-a;c++){const l={x:n,z:c,rotations:[...e],worth:0};l.worth=this.evaluatePosition(i,n-o.min.x,c-o.min.z),s.push(l)}}if(s.sort((e,i)=>e.worth-i.worth),s.length>0){const e=Math.min(3,s.length),i=Math.floor(Math.random()*e);this.targetState=s[i],this.rotationSteps=this.expandRotations(this.targetState.rotations),this.rotationIndex=0}else this.targetState=null,this.rotationSteps=[],this.rotationIndex=0}expandRotations(t){const s=[];for(const e of t){const i=Math.abs(e.times),o=e.times>0?1:-1;for(let r=0;r<i;r++)s.push({axis:e.axis,times:o})}return s}evaluatePosition(t,s,e){const i=t.clone();i.position={x:i.position.x+s,y:i.position.y,z:i.position.z+e};let o=i.position.y;for(;o>0;){if(i.position={...i.position,y:o-1},!this.isValidPosition(i)){i.position={...i.position,y:o};break}o--}const r=i.getWorldBlocks();let a=0,n=0;for(const{point:f}of r)n+=f.y;a+=n*n/36;const c=this.countSideFaces(i);a+=c;const l=this.countHoleSpace(i);return a+=l*8,a}isValidPosition(t){const s=t.getWorldBlocks();for(const{point:e}of s)if(e.y<0||e.x<0||e.x>=v.boardWidth||e.z<0||e.z>=v.boardDepth||this.game.board.has(e.x,e.y,e.z))return!1;return!0}countSideFaces(t){const s=t.getWorldBlocks(),e=new Set;for(const{point:r}of s)e.add(`${r.x},${r.y},${r.z}`);let i=0;const o=[{dx:1,dz:0},{dx:-1,dz:0},{dx:0,dz:1},{dx:0,dz:-1}];for(const{point:r}of s)for(const{dx:a,dz:n}of o){const c=r.x+a,l=r.z+n,f=`${c},${r.y},${l}`;if(!e.has(f)){if(c<0||c>=v.boardWidth||l<0||l>=v.boardDepth){i+=.3;continue}this.game.board.has(c,r.y,l)||(r.y>0&&!this.game.board.has(c,r.y-1,l)?i+=1.6:i+=1)}}return i}countHoleSpace(t){const s=t.getWorldBlocks(),e=new Set;for(const{point:o}of s)e.add(`${o.x},${o.y},${o.z}`);let i=0;for(const{point:o}of s){const r=`${o.x},${o.y-1},${o.z}`;if(e.has(r))continue;let a=o.y-1;for(;a>=0;){const n=`${o.x},${a},${o.z}`;if(e.has(n)){a--;continue}if(this.game.board.has(o.x,a,o.z))break;i++,a--}if(a>0){let n=a-1;for(;n>=0&&!this.game.board.has(o.x,n,o.z);)i+=.2,n--}}return i}}const F="/klstudio/assets/brick-freeze-Df-glg-H.wav",G="/klstudio/assets/game-over-D5JTEiWO.wav",W="/klstudio/assets/layer-clear-BVe
1LlL6s.wav",C={brickFreeze:{url:F,volume:.5},gameOver:{url:G,volume:.6},layerClear:{url:W,volume:.5}};class H{constructor(){d(this,"sounds",new Map);d(this,"_muted",!1);d(this,"_masterVolume",1);d(this,"_initialized",!1);this.preloadSounds()}preloadSounds(){for(const[t,s]of Object.entries(C)){const e=new Audio(s.url);e.preload="auto",e.volume=s.volume*this._masterVolume,this.sounds.set(t,e)}this._initialized=!0}play(t){if(this._muted||!this._initialized)return;const s=this.sounds.get(t);if(!s)return;const e=s.cloneNode();e.volume=C[t].volume*this._masterVolume,e.play().catch(()=>{})}get muted(){return this._muted}set muted(t){this._muted=t}toggleMute(){return this._muted=!this._muted,this._muted}get masterVolume(){return this._masterVolume}set masterVolume(t){this._masterVolume=Math.max(0,Math.min(1,t));for(const[s,e]of this.sounds)e.volume=C[s].volume*this._masterVolume}dispose(){for(const t of this.sounds.values())t.pause(),t.src="";this.sounds.clear(),this._initialized=!1}}const X={name:"cube-tetris",data(){return{game:null,renderer:null,aiController:null,audioManager:null,aiMode:!0,muted:!1,highScore:0,state:{score:0,level:1,linesCleared:0,piecesDropped:0,gameOver:!1,paused:!1}}},mounted(){this.initGame(),this.$refs.container.focus(),window.addEventListener("resize",this.onResize),this.onResize()},beforeUnmount(){window.removeEventListener("resize",this.onResize),this.cleanup()},methods:{initGame(){this.game=b(new I),this.renderer=b(new R(this.$refs.canvas)),this.aiController=b(new E(this.game)),this.audioManager=b(new H),this.game.on("scoreChanged",()=>this.updateState()),this.game.on("newHighScore",h=>{this.highScore=h.data.highScore}),this.game.on("pieceSpawned",()=>{this.updateVisuals(),this.aiController.onPieceSpawned(),this.renderer.onPieceSpawned()}),this.game.on("pieceMoved",()=>this.updateVisuals()),this.game.on("pieceRotated",()=>this.updateVisuals()),this.game.on("pieceLocked",()=>{this.updateVisuals(),this.updateState(),this.audioManager.play("brickFreeze")}),this.game.on("layersClearStart",h=>{const{blocks:t}=h.data;this.renderer.startClearingAnimation(t),this.audioManager.play("layerClear")}),this.game.on("layersCleared",()=>this.updateVisuals()),this.game.on("gameOver",()=>{this.updateState(),this.audioManager.play("gameOver"),this.aiMode&&setTimeout(()=>{this.aiMode&&this.game&&this.restart()},2e3)}),this.game.start(),this.highScore=this.game.highScore,this.updateState(),this.updateVisuals(),this.setAiMode(!0),this.renderer.startAnimationLoop(h=>{this.game.update(h),this.aiController.update(h),this.game.isDropping&&this.updateVisuals(),this.game.isClearingAnimation&&!this.renderer.isClearingAnimation()&&(this.game.completeClearingAnimation(),this.updateVisuals(),this.updateState())})},updateState(){this.game&&(this.state={...this.game.state})},updateVisuals(){var o;if(!this.game||!this.renderer)return;if(this.game.isClearingAnimation||this.renderer.updateBoard(this.game.board),this.game.isClearingAnimation)this.renderer.updatePiece(null);else{const r=this.game.isDropping?this.game.dropVisualY:void 0;this.renderer.updatePiece(this.game.currentPiece,r)}const h=this.game.getGhostPosition(),t=(o=this.game.currentPiece)==null?void 0:o.position,s=this.game.isDropping?this.game.dropVisualY:t==null?void 0:t.y,e=s!==void 0&&h?s-h.y:1/0;this.game.isClearingAnimation||e<4?this.renderer.updateGhost(null,null):this.game.isDropping?this.renderer.updateGhost(this.game.currentPiece,h,.15):this.renderer.updateGhost(this.game.currentPiece,h);const i=this.game.board.getBounds();if(this.renderer.setHeapMaxY(i.maxY),this.aiMode&&this.game.currentPiece){const r=this.game.currentPiece.getWorldBlocks(),a={x:r.reduce((n,c)=>n+c.point.x,0)/r.length,z:r.reduce((n,c)=>n+c.point.z,0)/r.length};if(this.renderer.setPieceCentroid(a),h){const n=this.game.currentPiece.getLocalBlocks(),c=Math.min(...n.map(l=>l.y+h.y));this.renderer.setGhostMinY(c)}}else this.renderer.setPieceCentroid(null),this.renderer.setGhostMinY(1/0)},toggleAiMode(){this.setAiMode(!this.aiMode)},toggleMute(){this.audioManager&&(this.muted=this.audioManager.toggleMute())},setAiMode(h){this.aiMode=h,this.aiController&&(this.aiController.setEnabled(h),this.aiController.setMoveDelay(h?200:100)),this.renderer&&this.renderer.setAutoRotate(h,.2),h||this.$refs.container.focus()},onKeyDown(h){if(!this.game)return;
1const t=h.code;if(m.pause.includes(t)){h.preventDefault(),this.game.togglePause(),this.updateState();return}this.aiMode||(m.moveLeft.includes(t)?(h.preventDefault(),this.moveCameraRelative("left")):m.moveRight.includes(t)?(h.preventDefault(),this.moveCameraRelative("right")):m.moveForward.includes(t)?(h.preventDefault(),this.moveCameraRelative("forward")):m.moveBackward.includes(t)?(h.preventDefault(),this.moveCameraRelative("backward")):m.drop.includes(t)?(h.preventDefault(),this.game.hardDrop()):m.rotateYPos.includes(t)?(h.preventDefault(),this.game.rotatePiece("y",1)):m.rotateYNeg.includes(t)?(h.preventDefault(),this.game.rotatePiece("y",-1)):m.rotateXPos.includes(t)?(h.preventDefault(),this.game.rotatePiece("x",1)):m.rotateXNeg.includes(t)?(h.preventDefault(),this.game.rotatePiece("x",-1)):m.rotateZPos.includes(t)?(h.preventDefault(),this.game.rotatePiece("z",1)):m.rotateZNeg.includes(t)?(h.preventDefault(),this.game.rotatePiece("z",-1)):m.restart.includes(t)&&(h.preventDefault(),this.restart()),this.updateVisuals())},moveCameraRelative(h){if(!this.renderer||!this.game)return;const t=this.renderer.getCamera(),s=this.renderer.getBoardCenter(),e=s.x-t.position.x,i=s.z-t.position.z,r=(Math.atan2(i,e)*180/Math.PI+360)%360;let a,n,c,l;switch(r>=315||r<45?(a=()=>this.game.moveRight(),n=()=>this.game.moveLeft(),c=()=>this.game.moveForward(),l=()=>this.game.moveBackward()):r>=45&&r<135?(a=()=>this.game.moveBackward(),n=()=>this.game.moveForward(),c=()=>this.game.moveRight(),l=()=>this.game.moveLeft()):r>=135&&r<225?(a=()=>this.game.moveLeft(),n=()=>this.game.moveRight(),c=()=>this.game.moveBackward(),l=()=>this.game.moveForward()):(a=()=>this.game.moveForward(),n=()=>this.game.moveBackward(),c=()=>this.game.moveLeft(),l=()=>this.game.moveRight()),h){case"forward":a();break;case"backward":n();break;case"left":c();break;case"right":l();break}},onResize(){if(!this.renderer||!this.$refs.container)return;const h=this.$refs.container.getBoundingClientRect();this.renderer.resize(h.width,h.height)},restart(){this.game&&(this.game.start(),this.updateState(),this.updateVisuals(),this.aiMode||this.$refs.container.focus())},cleanup(){this.renderer&&(this.renderer.dispose(),this.renderer=null),this.audioManager&&(this.audioManager.dispose(),this.audioManager=null),this.game=null,this.aiController=null}}},Z={ref:"canvas"},K={class:"ui-overlay"},U={class:"score-panel"},$={class:"stat"},q={class:"value hi-score"},j={class:"stat"},J={class:"value"},Q={class:"stat"},tt={class:"value"},et={class:"stat"},st={class:"value"},it={class:"mode-panel"},ot=["title"],rt={key:0,viewBox:"0 0 24 24",fill:"currentColor"},at={key:1,viewBox:"0 0 24 24",fill:"currentColor"},nt={key:0,class:"controls-hint"},ht={key:0,class:"overlay"},ct={key:1,class:"overlay"},lt={class:"message game-over"};function dt(h,t,s,e,i,o){return y(),x("div",{class:"cube-tetris",onKeydown:t[3]||(t[3]=(...r)=>o.onKeyDown&&o.onKeyDown(...r)),tabindex:"0",ref:"container"},[u("canvas",Z,null,512),u("div",K,[u("div",U,[u("div",$,[t[4]||(t[4]=u("span",{class:"label"},"Hi-Score",-1)),u("span",q,k(i.highScore),1)]),u("div",j,[t[5]||(t[5]=u("span",{class:"label"},"Score",-1)),u("span",J,k(i.state.score),1)]),u("div",Q,[t[6]||(t[6]=u("span",{class:"label"},"Layers",-1)),u("span",tt,k(i.state.linesCleared),1)]),u("div",et,[t[7]||(t[7]=u("span",{class:"label"},"Level",-1)),u("span",st,k(i.state.level),1)])]),u("div",it,[u("button",{class:T(["mode-btn",{active:i.aiMode}]),onClick:t[0]||(t[0]=(...r)=>o.toggleAiMode&&o.toggleAiMode(...r))},k(i.aiMode?"AI Playing":"AI Demo"),3),u("button",{class:"icon-btn",onClick:t[1]||(t[1]=(...r)=>o.toggleMute&&o.toggleMute(...r)),title:i.muted?"Unmute":"Mute"},[i.muted?(y(),x("svg",at,[...t[9]||(t[9]=[u("path",{d:"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"},null,-1)])])):(y(),x("svg",rt,[...t[8]||(t[8]=[u("path",{d:"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"},null,-1)])]))],8,ot)]),i.aiMode?M("",!0):(y(),x("div",nt,[...t[10]||(t[10]=[O('<div class="hint-section" data-v-2f172269><strong data-v-2f172269>Move</strong><span data-v-2f172269>W/A/S/D or Arrows</span></div><div class="hint-section" data-v-2f172269><strong data-v-2f172269>Drop</strong><span data-v-2f172269>Space or X</span></div><div class="hint-section" data-v-2f172269><strong data-v-2f172269>Rotate</strong><span data-v-2f172269>Q/E (Y) R/F (X) Z/C (Z)</span></div><div class="hint-section" data-v-2f172269><strong data-v-2f172269>Pause</strong><span data-v-2f172269>P</span></div>
1',4)])]))]),i.state.paused&&!i.state.gameOver?(y(),x("div",ht,[...t[11]||(t[11]=[u("div",{class:"message"},[u("h2",null,"Paused"),u("p",null,"Press P to continue")],-1)])])):M("",!0),i.state.gameOver?(y(),x("div",ct,[u("div",lt,[t[12]||(t[12]=u("h2",null,"Game Over",-1)),u("p",null,"Score: "+k(i.state.score),1),u("button",{onClick:t[2]||(t[2]=(...r)=>o.restart&&o.restart(...r))},"Play Again")])])):M("",!0)],544)}const pt=V(X,[["render",dt],["__scopeId","data-v-2f172269"]]);export{pt as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.