前端面试越来越离谱,竟然要求 40 分钟用原生 JS 实现黑白翻转棋~

32 阅读5分钟

不得不吐槽一下,现在的前端面试真的离谱,动辄扔几道力扣上的算法题,更有甚者,让 40 分钟实现黑白棋。 反正我当场是没做出来,刚写完个样式,加了个点击事件时间就到啦!上学的时候 40 分钟咋那么经用呢,现在的 40 分钟,咻咻~就没啦。离大谱。。。 面试没做出来不甘心嘛,终于努力了几个小时算是实现了,辣鸡前端写的辣鸡代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            height: 100%;
            display: flex;
            justify-content: center;
            padding-top: 200px;
        }
        .wrapper {
            width: 800px;
            height: 800px;
            display: flex;
            flex-direction: column;
            background-color: #dac5a4;
            border-top: 1px solid black;
            border-left: 1px solid black;
        }
        .row {
            width: 100%;
            height: 100px;
            display: flex;
        }
        .cell{
            position: relative;
            width: 100px;
            
        }
        .cell::before{
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            border-right: 1px solid black;
            border-bottom: 1px solid black;
        }
        .white{
            border-radius: 50%;
            background-image: radial-gradient(closest-side at 50% 50%,white 90%,transparent 10%);
        }
        .black{
            border-radius: 50%;
            background-image: radial-gradient(closest-side at 50% 50%,black 90%,transparent 10%);
        }
        .current{
            width: 50px;
            height: 50px;
            border: 2px solid black;
            border-radius: 50%;
            margin-right: 20px;
        }
        .blk{
            background-color: black;
        }
        .wht{
            background-color: white;
        }
    </style>
</head>
<body>
    <div class="current blk"></div>
    <div class="wrapper">
    </div>
</body>
<script>
    const arr = [
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,1,2,0,0,0],
        [0,0,0,2,1,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
    ]
    let isJudgeOver = false;
    let isBlack = true;
    const currentChange = ()=>{
        const current = document.querySelector('.current');
        if(isBlack){
            current.classList.remove('wht');
            current.classList.add('blk');
        }else{
            current.classList.remove('blk')
            current.classList.add('wht');
        }
    }
    const generatePannel = ()=>{
        const pannel = document.querySelector('.wrapper');
        pannel.innerHTML = '';
        for(let i = 0;i < arr.length;i++){
            const row = document.createElement('div');
            row.classList.add('row');
            pannel.appendChild(row)
            for(let j = 0;j < arr[i].length;j++){
                const cell = document.createElement('div');
                cell.classList.add('cell');
                cell.classList.add(`${i}-${j}`)
                if(arr[i][j] === 1){
                    cell.classList.add('black');
                }else if(arr[i][j] === 2){
                    cell.classList.add('white');
                }
                row.appendChild(cell);
            }
        }
    }
    generatePannel();
    const getPointAround = (position)=>{
        const [i,j] = position;
        const left = j-1>=0 ? arr[i][j-1] : 0;
        const right = j+1<arr[i].length ? arr[i][j+1] : 0;
        const top = i-1>=0 ? arr[i-1][j] : 0;
        const bottom = i+1<arr[i].length ? arr[i+1][j] : 0;
        const leftTop = i-1>=0 && j-1>=0 ? arr[i-1][j-1] : 0;
        const leftBottom = i+1<arr[i].length && j-1>=0 ? arr[i+1][j-1] : 0;
        const rightTop = i-1>=0 && j+1<arr[i].length ? arr[i-1][j+1] : 0;
        const rightBottom = i+1<arr[i].length && j+1<arr[i].length ? arr[i+1][j+1] : 0;
        return {
            left,
            right,
            top,
            bottom,
            leftTop,
            leftBottom,
            rightTop,
            rightBottom
        }
    }
    const leftFind = (position,value)=>{
        const [i,j] = position;
        let start = []
        for(let x = j-1;x >= 0;x--){
            if(arr[i][x] === value){
                start = [i,x]
                break;
            }
        }
        if(start.length === 0)return false;
        if(!isJudgeOver){
            let line = []
            let flag = true;
            arr[i].forEach((item,index)=>{
                if(index > start[1] && index <= j){
                    line.push([i,index])
                    if(arr[i][index] === 0 && index !==j){
                        flag = false;
                    }
                }
            })
            if(flag){
                line.forEach((item)=>{
                    arr[item[0]][item[1]] = value;
                })
            }
        }
        return true;
    }
    const rightFind = (position,value)=>{
        const [i,j] = position;
        let start = []
        for(let x = j+1;x < arr[i].length;x++){
            if(arr[i][x] === value){
                start = [i,x]
                break;
            }
        }
        if(start.length === 0)return false;
        if(!isJudgeOver){
            let line = [];
            let flag = true;
            arr[i].forEach((item,index)=>{
                if(index < start[1] && index >= j){
                    line.push([i,index])
                    // arr[i][index] = value;
                    if(arr[i][index] === 0 && index !==j){
                        flag = false;
                    }
                }
            })
            if(flag){
                line.forEach((item)=>{
                    arr[item[0]][item[1]] = value;
                })
            }
        } 
        return true;
    }
    const topFind = (position,value)=>{
        const [i,j] = position;
        let start = []
        for(let x=i-1;x>=0;x--){
            if(arr[x][j] === value){
                start = [x,j]
                break;
            }
        }
        if(start.length === 0) return false;
        if(!isJudgeOver){
            let line = []
            let flag = true;
            arr.forEach((item,index)=>{
                if(index > start[0] && index <= i){
                    line.push([index,j])
                    if(arr[index][j] === 0 && index !==i){
                        flag = false;
                    }
                    // arr[index][j] = value;
                }
            })
            if(flag){
                line.forEach((item)=>{
                    arr[item[0]][item[1]] = value;
                })
            }
        }
        return true;
    }
    const bottomFind = (position,value)=>{
        const [i,j] = position;
        let start = []
        for(let x=i+1;x<arr.length;x++){
            if(arr[x][j] === value){
                start = [x,j]
                break;
            }
        }
        if(start.length === 0)return false;
        if(!isJudgeOver) {
            let line = [];
            let flag = true;
            arr.forEach((item,index)=>{
                if(index < start[0] && index >= i){
                    line.push([index,j])
                    if(arr[index][j] === 0 && index !==i){
                        flag = false;
                    }
                    // arr[index][j] = value; 
                }
            })
            if(flag){
                line.forEach((item)=>{
                    arr[item[0]][item[1]] = value;
                })
            }   
        }
        return true;
    }
    const leftTopFind = (position,value)=>{
        const [i,j] = position;
        let start = []
        let x = i - 1;
        let y = j - 1;
        while(x >= 0 && y >= 0){
            if(arr[x][y] === value){
                start = [x,y]
                break;
            }
            x--;
            y--;
        }
        if(start.length === 0)return false;
        if(!isJudgeOver){
            let line = [];
            let flag = true;
            while(x <= i && y <= j){
                line.push([x,y])
                if(arr[x][y] === 0 && x !==i && y!== j){
                    flag = false;
                }
                // arr[x][y] = value;
                x++;
                y++;
            }
            if(flag){
                line.forEach((item)=>{
                    arr[item[0]][item[1]] = value;
                })
            }
        }
        return true;
    }
    const leftBottomFind = (position,value)=>{
        const [i,j] = position;
        let start = []
        let x = i + 1;
        let y = j - 1;
        while(x < arr.length && y >= 0){
            if(arr[x][y] === value){
                start = [x,y]
                break;
            }
            x++;
            y--;
        }
        if(start.length === 0)return false;
        if(!isJudgeOver){
            let line = [];
            let flag = true;
            while(x >= i && y <= j){
                // arr[x][y] = value;
                line.push([x,y])
                if(arr[x][y] === 0 && x !==i && y!== j){
                    flag = false;
                }
                x--;
                y++;
            }
            if(flag){
                line.forEach((item)=>{
                    arr[item[0]][item[1]] = value;
                })
            }
        }
        return true;
    }
    const rightTopFind = (position,value)=>{
        const [i,j] = position;
        let start = []
        let x = i - 1;
        let y = j + 1;
        while(x >= 0 && y < arr[i].length){
            if(arr[x][y] === value){
                start = [x,y]
                break;
            }
            x--;
            y++;
        }
        if(start.length === 0)return false;
        if(!isJudgeOver){
            let line = [];
            let flag = true;
            while(x <= i && y >= j){
                // arr[x][y] = value;
                line.push([x,y])
                if(arr[x][y] === 0 && x !==i && y!== j){
                    flag = false;
                }
                x++;
                y--;
            }
            if(flag){
                line.forEach((item)=>{
                    arr[item[0]][item[1]] = value;
            })
        }
        return true;
    }
}
    const rightBottomFind = (position,value)=>{
        const [i,j] = position;
        let start = []
        let x = i + 1;
        let y = j + 1;
        while(x < arr.length && y < arr[i].length){
            if(arr[x][y] === value){
                start = [x,y]
                break;  
            }
            x++;
            y++;
        }
        if(start.length === 0)return false;
        if(!isJudgeOver){
            let line = [];
            let flag = true;
            while(x >= i && y >= j){
                // arr[x][y] = value;
                line.push([x,y])
                if(arr[x][y] === 0 && x !==i && y!== j){
                    flag = false;
                }
                x--;
                y--;    
            }
            if(flag){
                line.forEach((item)=>{
                    arr[item[0]][item[1]] = value;
                })
            }
        }
        return true;
    }
    const run = (position,isRunBlack)=>{
        const value = isRunBlack ? 1 : 2;
        const [i,j] = position;
        // 获取点击位置四周 8 个位置的坐标
        const {left,right,top,bottom,leftBottom,leftTop,rightBottom,rightTop} = getPointAround(position);
        let leftChange = false;
        let rightChange = false;
        let topChange = false;
        let bottomChange = false;
        let leftTopChange = false;
        let leftBottomChange = false;
        let rightTopChange = false;
        let rightBottomChange = false;
        if(left && left !== value){
            leftChange = leftFind(position,value)
        }
        if(right && right !== value){
            rightChange = rightFind(position,value)
        }
        if(top && top !== value){
            topChange = topFind(position,value)
        }
        if(bottom && bottom !== value){
            bottomChange = bottomFind(position,value)
        }
        if(leftTop && leftTop !== value){
            leftTopChange = leftTopFind(position,value)
        }
        if(leftBottom && leftBottom !== value){
            leftBottomChange = leftBottomFind(position,value)
        }
        if(rightTop && rightTop !== value){
            rightTopChange = rightTopFind(position,value)
        }
        if(rightBottom && rightBottom !== value){
            rightBottomChange = rightBottomFind(position,value)
        }
        const bool = leftChange || rightChange || topChange || bottomChange || leftTopChange || leftBottomChange || rightTopChange || rightBottomChange;
        if(!isJudgeOver && bool){
            isBlack = !isBlack;
            currentChange()
        }
        return bool
    }
    const isOver = (isBlack)=>{
        isJudgeOver = true;
        const edgePointPosition = []
         arr.forEach((row,i)=>{
             row.forEach((item,j)=>{
                if(item === 0){
                    const {left,right,top,bottom,leftBottom,leftTop,rightBottom,rightTop} = getPointAround([i,j]);
                    if(left || right || top || bottom || leftTop || leftBottom || rightTop || rightBottom){
                        edgePointPosition.push([i,j])
                    }
                }
            })
        })
        let canRun = false;
        let blackNum = 0;
        let whiteNum = 0;
        arr.forEach((row,i)=>{
            row.forEach((item,j)=>{
                if(item === 1){
                    blackNum++;
                }
                if(item === 2){
                    whiteNum++; 
                }
            })
        })
        if(blackNum === 0){
            window.alert('白棋胜利')
        }
        if(whiteNum === 0){
            window.alert('黑棋胜利')
        }
        if(edgePointPosition && edgePointPosition.length > 0){
            for(let a = 0;a < edgePointPosition.length;a++){
               const [i,j] = edgePointPosition[a];
               if(run([i,j],isBlack)){
                    canRun = true;
                    break;
               }
            }
            if(!canRun){
                window.alert(blackNum > whiteNum ? '黑棋胜利' : '白棋胜利')
            }
        }else{
            window.alert(blackNum > whiteNum ? '黑棋胜利' : '白棋胜利')
        }
        isJudgeOver = false;
    }
    const pannel = document.querySelector('.wrapper');
    pannel.addEventListener('click',(e)=>{
            const target = e.target;
            const isCell = target.classList.contains('cell');
            isOver(isBlack)
            if(isCell){
                const [i,j] = target.classList[1].split('-').map(item=>parseInt(item));
                if(arr[i][j] === 0){
                    run([i,j],isBlack);
                };
            }
            generatePannel()
    })
</script>
</html>

简易版效果:

6161719559862_.pic.jpg 反正就这么个简易版我 40 分钟也写不出来。可能人家压根没想招人,或者单纯的没想招我。。。