俄罗斯方块游戏的算法实现

无工时代 / 2024-07-18 / 原文

已经实现的功能有:

地图功能

方块 向左向右向下移动

方块旋转90、180、270、360

向下移动到底了

未实现的:

向下移动到底,判断是否消除行
随机添加新的方块
游戏结束
 
function BinaryBlockGame(width=10,height=10){
    this.role=null
    this.roleMap=null
    this.data=new Array(height)
    for(let i=0;i<height;i++){
        this.data[i]=new Array(width).fill('_')
    }
}
BinaryBlockGame.prototype.sin=function(R){
   
    return Math.round(Math.sin((R)) * 1000000) / 1000000;
}
BinaryBlockGame.prototype.cos=function(R){
  
    return Math.round(Math.cos((R)) * 1000000) / 1000000;
}
//是否能添加方块
BinaryBlockGame.prototype.isCanAdd=function(role){
    const data=this.data
    let isOk=true
    for(let i=0;i<role.length;i++){
        if(data[role[i][1]][role[i][0]]!=="_"){
            isOk=false
            break
        }
    }
    return isOk
}
BinaryBlockGame.prototype.addRole=function(role){
    console.log('start:添加方块\n')
   const isOk=this.isCanAdd(role)
   if(!isOk){
    console.log('fail:不能添加方块,游戏结束')
    return
   }
    const data=this.data
    const temp={}
    role.forEach(function(pos){
        const key=pos.join(',')
        data[pos[1]][pos[0]]="#"
        temp[key]=1
    })
    this.roleMap=temp
    this.role=role

    console.log('ok:添加方块\n',this.toString())
}
//R是弧度
BinaryBlockGame.prototype.isCanRotate=function(R){
    const data=this.data
    const roleMap=this.roleMap
    const role=this.role
    let isOk=true
    const cx=role[0][0]
    const cy=role[0][1]
    for(let i=1;i<role.length;i++){
        const tx=role[i][0]-cx;
        const ty=role[i][1]-cy;

        const nx=tx*this.cos(R)-ty*this.sin(R)+cx
        const ny=tx*this.sin(R)+ty*this.cos(R)+cy
        const key=[nx,ny].join(',')
        if(!(roleMap[key]||data[ny][nx]==='_')){
            isOk=false
            break
        }
    }
    return isOk
}
BinaryBlockGame.prototype.rotate=function(A){
   
    if(!this.role){console.log('不存在可移动的方块')}
    const R=Math.PI*A/180
    const isOk=this.isCanRotate(R)
    console.log('rotate->',A,isOk)
    if(isOk){
        const roleMap=this.roleMap
        const role=this.role
        const data=this.data
        role.forEach(function(pos){
            const key=pos.join(',')
            data[pos[1]][pos[0]]="_"
            roleMap[key]--
        })
        const cx=role[0][0]
        const cy=role[0][1]
        this.role.forEach((pos)=>{
            const tx=pos[0]-cx;
            const ty=pos[1]-cy;

            const nx=tx*this.cos(R)-ty*this.sin(R)+cx
            const ny=tx*this.sin(R)+ty*this.cos(R)+cy
            pos[0]=nx
            pos[1]=ny
            const nkey=pos.join(',')
            data[pos[1]][pos[0]]="#"
            if(!roleMap[nkey]){
                roleMap[nkey]=1
            }else{
                roleMap[nkey]++
            }
        })
        console.log(this.toString())
    }
   
}
BinaryBlockGame.prototype.isCanMove=function(x,y){
    const data=this.data
    const roleMap=this.roleMap
    const role=this.role
    let isOk=true
    for(let i=0;i<role.length;i++){
        const nx=role[i][0]+x
        const ny=role[i][1]+y
        const key=[nx,ny].join(',')
        if(!(roleMap[key]||data[ny]&&data[ny][nx]==='_')){
            isOk=false
            break
        }
    }
    return isOk
}
BinaryBlockGame.prototype.move=function(x,y){
   
    if(!this.role){console.log('不存在可移动的方块')}
    const isOk=this.isCanMove(x,y)
    console.log('move->',x,y,isOk)
    if(isOk){
        const roleMap=this.roleMap
        const data=this.data
        this.role.forEach(function(pos){
            const key=pos.join(',')
            data[pos[1]][pos[0]]="_"
            roleMap[key]--
        })
        this.role.forEach(function(pos){
            pos[0]=pos[0]+x
            pos[1]=pos[1]+y
            const nkey=pos.join(',')
            data[pos[1]][pos[0]]="#"
            if(!roleMap[nkey]){
                roleMap[nkey]=1
            }else{
                roleMap[nkey]++
            }
        })
        console.log(this.toString())
    }else if(y===1){
        console.log('向下移动到底,判断是否消除行,以及添加新的方块')

    }
}


BinaryBlockGame.prototype.toString=function(){
    let str=''
    const data=this.data
    for(let i=0;i<data.length;i++){
        str=str+data[i].join(',')+'\n'
    }
    return str
    
}

const game=new BinaryBlockGame()
//添加方块
game.addRole([[1,2],[1,1],[2,1],[0,1]])
//向左移动
game.move(-1,0)

//向右移动
game.move(1,0)

//向左移动
game.move(-1,0)

//向下移动
game.move(0,1)
//向下移动
game.move(0,1)
//向下移动
game.move(0,1)
//向下移动
game.move(0,1)
//旋转90度
game.rotate(90)
//向下移动
game.move(0,1)
//向下移动
game.move(0,1)
//向下移动
game.move(0,1)

 

C:\Program Files\nodejs\node.exe .\BinaryBlock.js
start:添加方块
ok:添加方块
_,_,_,_,_,_,_,_,_,_
#,#,#,_,_,_,_,_,_,_
_,#,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
move-> -1 0 false
move-> 1 0 true
_,_,_,_,_,_,_,_,_,_
_,#,#,#,_,_,_,_,_,_
_,_,#,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
move-> -1 0 true
_,_,_,_,_,_,_,_,_,_
#,#,#,_,_,_,_,_,_,_
_,#,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
move-> 0 1 true
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
#,#,#,_,_,_,_,_,_,_
_,#,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
move-> 0 1 true
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
#,#,#,_,_,_,_,_,_,_
_,#,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
move-> 0 1 true
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
#,#,#,_,_,_,_,_,_,_
_,#,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
move-> 0 1 true
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
#,#,#,_,_,_,_,_,_,_
_,#,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
rotate-> 90 true
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,#,_,_,_,_,_,_,_
_,#,#,_,_,_,_,_,_,_
_,_,#,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
move-> 0 1 true
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,#,_,_,_,_,_,_,_
_,#,#,_,_,_,_,_,_,_
_,_,#,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
move-> 0 1 true
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,_,_,_,_,_,_,_,_
_,_,#,_,_,_,_,_,_,_
_,#,#,_,_,_,_,_,_,_
_,_,#,_,_,_,_,_,_,_
move-> 0 1 false
向下移动到底