100行web代碼實(shí)現(xiàn)五子棋游戲

廢話不多說(shuō)代碼如下:

index.jsx 代碼:

import styles from './index.module.scss';
import { useEffect, useState } from 'react';

const Gobang = () => {
    const [chess, setChess] = useState([]); // 棋子
    const [isBlack, setIsBlack] = useState(true); // 是否是黑子
    // 橫線
    const hLine = new Array(21).fill(null).map((_, i) => `M 20 ${i * 40 + 20} L 820 ${i * 40 + 20} `).join('');
    // 豎線
    const vLine = new Array(21).fill(null).map((_, i) => `M ${i * 40 + 20} 20 L ${i * 40 + 20} 820 `).join('');
    const handleClick = (e) => { // 點(diǎn)擊事件
        const x = Math.floor(e.nativeEvent.offsetX / 40);
        const y = Math.floor(e.nativeEvent.offsetY / 40);
        if (chess.some(item => item.x === x && item.y === y)) { // 已經(jīng)有棋子
            return;
        }
        const newChess = [...chess, { x, y, isBlack }];
        setChess(newChess);
        setIsBlack(!isBlack);
        // 判斷輸贏
        const currentChess = newChess.filter(item => item.isBlack === isBlack);
        const isWin = (fn) => { // 判斷輸贏
            let count = 1;
            for (let i = 1; i < 5; i++) {
                if (currentChess.some(j => fn(j, i))) {
                    count++;
                } else {
                    break;
                }
            }
            return count >= 5;
        };
        if (currentChess.some(item => { // 該點(diǎn)為起點(diǎn),
            return isWin((cItem, i) => cItem.x === item.x + i && cItem.y === item.y) || // 橫向
                isWin((cItem, i) => cItem.x === item.x && cItem.y === item.y + i) || // 縱向
                isWin((cItem, i) => cItem.x === item.x + i && cItem.y === item.y + i) || // 左上到右下
                isWin((cItem, i) => cItem.x === item.x + i && cItem.y === item.y - i); // 左下到右上
        })) {
            setTimeout(() => {
                alert(`${isBlack ? '黑' : '白'}棋贏了`);
            });
        }
    };

    return (
        <div className={styles.box}>
            <svg className={styles.svg}>
                {/* 橫線*/}
                <path className={styles.line} d={hLine}/>
                {/* 豎線*/}
                <path className={styles.line} d={vLine}/>
                {/* 棋子*/}
                {
                    chess.map((item, index) => (
                        <circle
                            className={styles.chess}
                            cx={item.x * 40 + 20}
                            cy={item.y * 40 + 20}
                            fill={item.isBlack ? 'black' : 'white'}
                            key={index}
                            r={10}
                            stroke="black"
                            strokeWidth="1"
                        />
                    ))
                }
            </svg>
            {/* 點(diǎn)擊區(qū)域*/}
            <div className={styles.pointArea} onClick={handleClick}/>
        </div>
    );
};

export default Gobang;

index.module.scss代碼:

.box{
    width: 840px;
    height: 840px;
    display: block;
    margin: 10px auto;
    position: relative;
    cursor: pointer;
    .svg{
        width: 100%;
        height: 100%;
        pointer-events: none;
        .line{
            stroke-width: 1;
            stroke: #666;
        }
    }
    .pointArea{
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        z-index: 2;
    }
}

效果圖:

image.png

擼碼不易,送個(gè)贊吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容