20-30 五子棋游戏

news2025/2/1 13:49:59

20-分析五子棋的实现思路_哔哩哔哩_bilibili20-分析五子棋的实现思路是一次性学会 Canvas 动画绘图(核心精讲+50个案例)2023最新教程的第21集视频,该合集共计53集,视频收藏或关注UP主,及时了解更多相关视频内容。https://www.bilibili.com/video/BV16T411B7kP?spm_id_from=333.788.player.switch&vd_source=9218320e7bcc2e793fa8493559f4acd7&p=21https://www.bilibili.com/video/BV16T411B7kP?spm_id_from=333.788.player.switch&vd_source=9218320e7bcc2e793fa8493559f4acd7&p=21https://www.bilibili.com/video/BV16T411B7kP?spm_id_from=333.788.player.switch&vd_source=9218320e7bcc2e793fa8493559f4acd7&p=21https://www.bilibili.com/video/BV16T411B7kP?spm_id_from=333.788.player.switch&vd_source=9218320e7bcc2e793fa8493559f4acd7&p=21

20-分析五子棋的实现思路

逻辑处理用原生JavaScript写,画布与棋子用canvas画

21-绘制网格棋盘

视频里用的绿色太晃眼了,换了一个更像木质棋盘的颜色 #ebc78f 。

页面底色与棋盘颜色,代码如下:

html,
body {
    background: #eee;
}

canvas {
    display: block;
    margin: 0 auto;
    background-color: #ebc78f;
}

棋盘是由多条横线和纵线组合而成,一格是50px,左右余宽 50px, (800-50-50) / 50 = 14,如果i从0开始算,0到14一共是15条线,为了方便计算,设 i 从1开始,for循环至 i < 16结束。

    // 1.创建canvas
    let canvas = document.createElement('canvas')
    canvas.width = 800
    canvas.height = 800
    document.body.append(canvas)

    // 2.获取 context
    let context = canvas.getContext('2d')

    // 3.画棋盘
    // 3.1 棋盘是由多条横线和纵线组合而成,一格按50px算,左右余宽 50px, (800-50-50) / 50 = 14,所以我们需要15条线
    for (let i = 1; i < 16; i++) {
        // 把线段的开头表示出来(横线)
        context.moveTo(50, 50 * i)  // 起点
        context.lineTo(750, 50 * i)  // 终点
        context.stroke()
    }
    for (let i = 1; i < 16; i++) {
        // 把线段的开头表示出来(竖线)
        context.moveTo(50 * i, 50)  // 起点
        context.lineTo(50 * i, 750)  // 终点
        context.stroke()
    }

22-点击棋盘绘制棋子

通过 context.beginPath(),可以避免上图这种情况,要注意 .beginPath() 要写在画圆 .arc() 之前

canvas.addEventListener('click', e => {
    let { offsetX: x, offsetY: y } = e
    context.beginPath()  // 避免起点终点被fill()填充颜色
    context.arc(x, y, 20, 0, 2 * Math.PI)
    context.fill()
    context.closePath()  // 配合 .beginPath()  使用
})

因为一个格子是50px,我们设置 (offsetX+25)/2 ,这样计算后可以让偏左的对齐左边的线偏右的对齐右边的线(offsetY也是同理),在 canvas.addEventListener 中设置如下:

let { offsetX, offsetY } = e
let x = Math.floor((offsetX + 25) / 50) * 50  // 让棋子在网格线正确的位置
let y = Math.floor((offsetY + 25) / 50) * 50

23-棋盘的边界判断

判断点击的位置边界,如果超出棋盘范围则不落棋子。如果offsetX < 25,则不落棋子(因为如果 offsetX >= 25,则可知落棋子在第一列上),offsetY与上下左右四边同理。

// 判断点击的位置边界,如果超出棋盘范围则不落棋子
if (offsetX < 25 || offsetY < 25 || offsetX > 775 || offsetY > 775) {
    return;
}

24-绘制不不同的棋子

context.beginPath()
context.arc(x, y, 20, 0, 2 * Math.PI)

// 设置黑白棋子的渐变色
let gBlack = context.createRadialGradient(x - 8, y - 8, 0, x, y, 20)
gBlack.addColorStop(0, '#999')
gBlack.addColorStop(1, '#000')

let gWhite = context.createRadialGradient(x - 5, y - 10, 18, x, y, 40)
gWhite.addColorStop(0, '#fff')
gWhite.addColorStop(1, '#666')

// 判断当前棋子颜色变量,给棋子黑白不同颜色
context.fillStyle = isBlack ? gBlack : gWhite

// 视频里老师的代码
// let tx = isBlack ? x - 10 : x + 10;
// let ty = isBlack ? y - 10 : y + 10;
// let g = context.createRadialGradient(tx, ty, 0, tx, ty, 30);
// g.addColorStop(0, isBlack ? '#ccc' : '#666');
// g.addColorStop(1, isBlack ? '#000' : '#fff');
// context.fillStyle = g
// 视频里老师的代码 END

context.fill()
context.closePath()

25-处理重复落子的问题

第1个数组代表第一列的棋子内容(原点 (0,0) 在左上角,row 相当于 X轴,向右方向为正方向, col 是 Y轴,向下方向为正方向)。

使用一个二维数组,把所有的棋子位置存储起来。棋盘有15横列,每个 i 代表一列,循环15次,设置 circles[i] 为一个空数组。

// 6. 使用一个二维数组把所有的棋子位置存储起来
let circles = [];
// 棋盘有15列,每个i指代每一列
for (let i = 1; i < 16; i++) {
    // circles[i]里的每一项都是一个空数组
    circles[i] = []
}
console.log(circles);

设置 x = i * 50, y = j * 50 ,可以让棋子在网格线十字中心的位置上,添加一个布尔变量 isBlack,用来控制棋子黑白颜色的切换。

let x = i * 50  // 让棋子在网格线十字中心的位置
let y = j * 50
context.beginPath()
context.arc(x, y, 20, 0, 2 * Math.PI)

// 6.1 把棋子的坐标存到二维数组里
circles[i][j] = isBlack ? 'black' : 'white'
// console.log(circles);   

如果 circles[i][j] 不为空,说明里面已经有内容,那么不允许重复落子。

// 6.2 判断当前位置是否已经存在棋子
if (circles[i][j]) {
    // 提醒用户, 这里已有棋子
    tip.innerText = `不能重复落子!当前是${isBlack ? '黑' : '白'}棋的回合`
    return;
}

设置顶部的文字提示。

 <div class="tip">请黑棋落子</div>

// ...
// 提醒用户换人
let text = isBlack ? '请黑棋落子' : '请白棋落子'
tip.innerText = text
// ...

26-纵向判断棋子连续

连成线的4种情况:

将坐标(row,col)视作(x,y)更加直观,在纵轴(竖轴)方向上检索是否有5个连续的棋子可以想象为:在X轴位置不变,Y轴加减坐标上下移动,在此期间判断各个棋子是否为同一种颜色

代码逻辑草稿:

// 以 row, col 为起点,在二维数组里向上和向下查找
circles[row][col-1]
circles[row][col-2]
circles[row][col-3]
circles[row][col-4]

circles[row][col+1]
circles[row][col+2]
circles[row][col+3]
// ...

设置一个 checkVertical 函数,来判断在竖轴方向上是否有五子相连,它的返回值是 return count >=5 ,如果 count 是 5,那么函数结果返回 true,会在下面的步骤中将结果传递给一个 endGame变量作为判断结束游戏的依据(其他三个方向的设计逻辑也是这样)。

【b站视频内提供的代码(有bug)】

// 纵向查找是否有5个连续相同的棋子
function checkVertical(row, col) {
    // 记录向上的次数
    let up = 0;
    // 记录向下的次数
    let down = 0;

    let times = 0;

    // 定义当前总共有几个已经连在一起
    let count = 1; // 初始值,自己本身算1个

    // 为避免出现死循环,设置一个循环上限 10000

    while (times < 17) {

        times++;

        // 如果棋子已经大于一个指定的次数,就不找了
        if (count >= 5) {
            break;
        }

        let target = isBlack ? 'black' : 'white';

        // 以 row, col 为起点,在二维数组里向上查找
        up++;

        if (circles[row][col - up] && circles[row][col - up] == target) {
            count++;
        };

        // 以 row, col 为起点,在二维数组里向下查找
        down++;

        if (circles[row][col + down] && circles[row][col + down] == target) {
            count++;
        };
    }
    return count >= 5;
}

27-处理获胜的逻辑

添加一个 endGame 布尔值变量,初始值为 false, 通过将当前棋子的(i, j) 值传递给四个方向的五子相连函数来判断是否有 true 值存在,如果有,那么游戏结束,棋盘无法再被点击。

// 8.1 定义一个变量标识,是否结束游戏
let endGame = false

// ...
// 8. 判断是否有人已经获胜,endGame为true,则无法点击
if (endGame) {
    // 游戏结束
    return
}

// ...
// 7.判断当前是否已有对应的棋子连成5颗,endGame为true则出现获胜提示字
endGame = checkVertical(i, j)
if(endGame) {
    tip.innerText = `${isBlack?'黑': '白'}方获胜!`
    return
}

28-处理棋子非连续的情况

如果相邻的棋子都不是同色的,直接 break 这次的判断循环。

// 如果棋子已经大于一个指定的次数,或者相邻棋子不是同色的(同色棋子不连续),就不找了
if (count >= 5 || (circles[row][col - up] != target && circles[row][col + down] != target)) {
    break;
}

29-横向判断是否获胜

【b站视频内提供的代码(有bug)】

// 横向查找是否有5个连续相同的棋子
function checkHorizontal(row, col) {
    // 记录向左的次数
    let left = 0;
    // 记录向右的次数
    let right = 0;

    let times = 0;

    // 定义当前总共有几个已经连在一起
    let count = 1; // 初始值,自己本身算1个

    // 为避免出现死循环,设置一个循环上限 10000

    while (times < 17) {

        times++;

        let target = isBlack ? 'black' : 'white';

        // 以 row, col 为起点,在二维数组里向左查找
        left++;

        if (circles[row-left][col] && circles[row-left][col] == target) {
            count++;
        };

        // 以 row, col 为起点,在二维数组里向右查找
        right++;

        if (circles[row+right][col] && circles[row+right][col] == target) {
            count++;
        };

        // 如果棋子已经大于一个指定的次数,或者相邻棋子不是同色的(同色棋子不连续),就不找了
        if (count >= 5 || (circles[row-left][col] != target && circles[row+right][col] != target)) {
            break;
        }
    }
    return count >= 5;
}

 最终我们需要4个方向的判断,所以这里会有4个判断函数,上下、左右、左上右下、右上左下。

// 7.判断当前是否已有对应的棋子连成5颗,endGame为true则出现获胜提示字
endGame = checkVertical(i, j) || checkHorizontal(i, j)

30-斜向判断是否获胜

判断方向在左上右下时,方向往左上延伸,那么X-, Y-,方向往右下延伸,那么X+, Y+。

判断方向在右上左下时,方向往右上延伸,那么X+, Y-,方向往左下延伸,那么X-, Y+。

【完整代码-bug修复版本】

落子靠近棋盘四周一圈时,如果要判断(不存在的)超出棋盘范围的棋子代码会报错,所以进行了 if 判断。

* 如果还有其他bug,建议自己修正一下。

<!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>
        html,
        body {
            background: #eee;
        }

        canvas {
            display: block;
            margin: 0 auto;
            background-color: #ebc78f;
        }

        .tip {
            text-align: center;
            padding: 16px;
            color: #666;
        }
    </style>
</head>

<body>
    <div class="tip">请黑棋落子</div>

    <script>
        // 1.创建canvas
        let canvas = document.createElement('canvas')
        canvas.width = 800
        canvas.height = 800
        document.body.append(canvas)

        // 获取文字提示 tip 元素
        let tip = document.querySelector('.tip')

        // 2.获取 context
        let context = canvas.getContext('2d')

        // 3.画棋盘
        // 3.1 棋盘是由多条横线和纵线组合而成,一格按50px算,左右余宽 50px, (800-50-50) / 50 = 14,所以我们需要14条线
        for (let i = 1; i < 16; i++) {
            // 把线段的开头表示出来(横线)
            context.moveTo(50, 50 * i)  // 起点
            context.lineTo(750, 50 * i)  // 终点
            context.stroke()
        }
        for (let i = 1; i < 16; i++) {
            // 把线段的开头表示出来(竖线)
            context.moveTo(50 * i, 50)  // 起点
            context.lineTo(50 * i, 750)  // 终点
            context.stroke()
        }

        // 6. 使用一个二维数组把所有的棋子位置存储起来
        let circles = [];
        // 棋盘有15列,每个i指代每一列
        for (let i = 1; i < 16; i++) {
            // circles[i]里的每一项都是一个空数组
            circles[i] = []
        }
        // console.log(circles);

        // 5.使用一个变量保存当前的棋子颜色
        let isBlack = true

        // 8.1 定义一个变量标识,是否结束游戏
        let endGame = false

        // 4. 当点击在棋盘里的时候,绘制一个棋子
        canvas.addEventListener('click', e => {

            let { offsetX, offsetY } = e

            // 判断点击的位置边界,如果超出棋盘范围则不落棋子
            if (offsetX < 25 || offsetY < 25 || offsetX > 775 || offsetY > 775) {
                return;
            }

            // 格子所在的位置
            let i = Math.floor((offsetX + 25) / 50)
            let j = Math.floor((offsetY + 25) / 50)

            // 8. 判断是否有人已经获胜,endGame为true,则无法点击
            if (endGame) {
                // 游戏结束
                return
            }

            // 6.2 判断当前位置是否已经存在棋子
            if (circles[i][j]) {
                // 提醒用户, 这里已有棋子
                tip.innerText = `不能重复落子!当前是${isBlack ? '黑' : '白'}棋的回合`
                return;
            }

            let x = i * 50  // 让棋子在网格线正确的位置
            let y = j * 50
            context.beginPath()
            context.arc(x, y, 20, 0, 2 * Math.PI)

            // 6.1 把棋子的坐标存到二维数组里
            circles[i][j] = isBlack ? 'black' : 'white'
            // console.log(circles);        

            // 设置黑白棋子的渐变色
            let gBlack = context.createRadialGradient(x - 8, y - 8, 0, x, y, 20)
            gBlack.addColorStop(0, '#999')
            gBlack.addColorStop(1, '#000')

            let gWhite = context.createRadialGradient(x - 5, y - 10, 18, x, y, 40)
            gWhite.addColorStop(0, '#fff')
            gWhite.addColorStop(1, '#666')

            // 判断当前棋子颜色变量,给棋子黑白不同颜色
            context.fillStyle = isBlack ? gBlack : gWhite

            // 视频里老师的代码
            // let tx = isBlack ? x - 10 : x + 10;
            // let ty = isBlack ? y - 10 : y + 10;
            // let g = context.createRadialGradient(tx, ty, 0, tx, ty, 30);
            // g.addColorStop(0, isBlack ? '#ccc' : '#666');
            // g.addColorStop(1, isBlack ? '#000' : '#fff');
            // context.fillStyle = g
            // 视频里老师的代码 END

            context.fill()
            context.closePath()

            // 7.判断当前是否已有对应的棋子连成5颗,endGame为true则出现获胜提示字
            endGame = checkVertical(i, j) || checkHorizontal(i, j) || checkNWtoSE(i, j) || checkNEtoSW(i, j)

            if (endGame) {
                tip.innerText = `${isBlack ? '黑' : '白'}方获胜!`
                return
            }

            // 提醒用户换人
            let text = isBlack ? '请白棋落子' : '请黑棋落子'
            tip.innerText = text

            isBlack = !isBlack
        })

        // 
        // 开始判断4个方向的棋子相连情况
        //

        // 纵向查找是否有5个连续相同的棋子
        function checkVertical(row, col) {
            // 记录向上的次数
            let up = 0;
            // 记录向下的次数
            let down = 0;
            let target = isBlack ? 'black' : 'white';
            let times = 0;

            // 定义当前总共有几个已经连在一起
            let count = 1; // 初始值,自己本身算1个

            // 5个棋子连成线即可结束 times < 6

            while (times < 6) {
                times++;

                // 探寻上边
                up++;
                // 当col - up > 0,说明棋子的上侧还在棋盘内,开始进行判断
                if (col - up > 0) {
                    if (circles[row][col - up] == target) {
                        count++;
                    }
                }

                // 探寻下边
                down++;
                // 当col+down < 16,说明棋子的下侧还在棋盘内,开始进行判断
                if (col + down < 16) {
                    if (circles[row][col + down] == target) {
                        count++;
                    }
                }

                // 在col - up与col + down都在棋盘里的情况在,如果相邻棋子不是target,则break,或如果count已满足5颗相连,则break
                if (col - up > 0 && col + down < 16) {
                    if (count >= 5 || (circles[row][col - up] != target && circles[row][col + down] != target)) {
                        break;
                    }
                }

            }

            return count >= 5;
        }

        // 横向查找是否有5个连续相同的棋子
        function checkHorizontal(row, col) {
            // 记录向左的次数
            let left = 0;
            // 记录向右的次数
            let right = 0;
            let target = isBlack ? 'black' : 'white';
            let times = 0;
            // 定义当前总共有几个已经连在一起
            let count = 1; // 初始值,自己本身算1个
            // 为避免出现死循环,设置一个循环上限 5
            while (times < 6) {
                times++;
                // 探寻左边
                left++;
                // 当row-left>0,说明棋子的左侧还在棋盘内,开始进行判断
                if (row - left > 0) {
                    if (circles[row - left][col] == target) {
                        count++;
                    }
                }
                right++;
                // 当row+right<16,说明棋子的右侧还在棋盘内,开始进行判断
                if (row + right < 16) {
                    if (circles[row + right][col] == target) {
                        count++;
                    }
                }
                if (row + right < 16 && row - left > 0) {
                    if (count >= 5 || (circles[row + right][col] != target && circles[row - left][col] != target)) {
                        break;
                    }
                }
            }
            return count >= 5;
        }

        // 判断 \ 左上到右下的方向
        function checkNWtoSE(row, col) {
            let lt = 0; // 左上
            let rb = 0; // 右下
            let target = isBlack ? 'black' : 'white';
            let times = 0;
            let count = 1; // 初始值,自己本身算1个
            while (times < 5) {
                times++;
                // 探寻左上方向
                lt++;
                if (col - lt > 0 && row - lt > 0) {
                    if (circles[row - lt][col - lt] == target) {
                        count++;
                    }
                }
                // 探寻右下方向
                rb++;
                if (row + rb < 16 && col + rb < 16) {
                    if (circles[row + rb][col + rb] == target) {
                        count++;
                    }
                }
                if (row - lt > 0 && col - lt && row + rb < 16 && col + rb < 16) {
                    if (count >= 5 || (circles[row - lt][col - lt] != target && circles[row + rb][col + rb] != target)) {
                        break;
                    }
                }
            }
            return count >= 5;
        }
        // 判断 / 右上到左下的方向
        function checkNEtoSW(row, col) {
            let rt = 0; // 右上
            let lb = 0; // 左下
            let target = isBlack ? 'black' : 'white';
            let times = 0;
            let count = 1; // 初始值,自己本身算1个
            while (times < 5) {
                times++;
                // 探寻右上
                rt++;
                if (col - rt > 0 && row + rt < 16) {
                    if (circles[row + rt][col - rt] && circles[row + rt][col - rt] == target) {
                        count++;
                    };
                }
                // 探寻左下
                lb++;
                if (row - lb > 0 && col + lb < 16) {
                    if (circles[row - lb][col + lb] && circles[row - lb][col + lb] == target) {
                        count++;
                    };
                }
                if (row - lb > 0 && col + lb < 16) {
                    if (count >= 5 || (circles[row + rt][col - rt] != target && circles[row - lb][col + lb] != target)) {
                        break;
                    }
                }
            }
            return count >= 5;
        }


    </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2289322.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

受击反馈HitReact、死亡效果Death Dissolve、Floating伤害值Text(末尾附 客户端RPC )

受击反馈HitReact 设置角色受击标签 (GameplayTag基本了解待补充) 角色监听标签并设置移动速度 创建一个受击技能&#xff0c;并应用GE 实现设置角色的受击蒙太奇动画 实现角色受击时播放蒙太奇动画&#xff0c;为了保证通用性&#xff0c;将其设置为一个函数&#xff0c;并…

STM32 LED呼吸灯

接线图&#xff1a; 这里将正极接到PA0引脚上&#xff0c;负极接到GND&#xff0c;这样就高电平点亮LED&#xff0c;低电平熄灭。 占空比越大&#xff0c;LED越亮&#xff0c;占空比越小&#xff0c;LED越暗 PWM初始化配置 输出比较函数介绍&#xff1a; 用这四个函数配置输…

栈和队列特别篇:栈和队列的经典算法问题

图均为手绘,代码基于vs2022实现 系列文章目录 数据结构初探: 顺序表 数据结构初探:链表之单链表篇 数据结构初探:链表之双向链表篇 链表特别篇:链表经典算法问题 数据结构:栈篇 数据结构:队列篇 文章目录 系列文章目录前言一.有效的括号(leetcode 20)二.用队列实现栈(leetcode…

2024年数据记录

笔者注册时间超过98.06%的用户 CSDN 原力是衡量一个用户在 CSDN 的贡献和影响力的系统&#xff0c;笔者原力值超过99.99%的用户 其他年度数据

DBO优化最近邻分类预测matlab

蜣螂优化算法&#xff08;Dung Beetle Optimizer&#xff0c;简称 DBO&#xff09;作为一种新兴的群智能优化算法&#xff0c;于 2022 年末被提出&#xff0c;其灵感主要来源于蜣螂的滚球、跳舞、觅食、偷窃以及繁殖等行为。 本次使用的数据为 Excel 格式的分类数据集。该数据…

PSpice for TI体验

前言 基于 从零开始学 PSpice for TI 仿真工具 - 手把手操作实训课程_哔哩哔哩_bilibili 体验PSpice for TI的功能&#xff0c;并记录下来。文章内容大部分都参考自视频&#xff0c;可以理解成图文版。目前发现是没有支持中文语言&#xff0c;而且部分仿真&#xff0c;时间消耗…

苯乙醇苷类化合物的从头生物合成-文献精读108

Complete pathway elucidation of echinacoside in Cistanche tubulosa and de novo biosynthesis of phenylethanoid glycosides 管花肉苁蓉中松果菊苷全生物合成途径解析及苯乙醇苷类化合物的从头生物合成 摘要 松果菊苷&#xff08;ECH&#xff09;是最具代表性的苯乙醇苷…

【C++】设计模式详解:单例模式

文章目录 Ⅰ. 设计一个类&#xff0c;不允许被拷贝Ⅱ. 请设计一个类&#xff0c;只能在堆上创建对象Ⅲ. 请设计一个类&#xff0c;只能在栈上创建对象Ⅳ. 请设计一个类&#xff0c;不能被继承Ⅴ. 请设计一个类&#xff0c;只能创建一个对象&#xff08;单例模式&#xff09;&am…

解决vsocde ssh远程连接同一ip,不同端口情况下,无法区分的问题

一般服务器会通过镜像分身或者容器的方式&#xff0c;一个ip分出多个端口给多人使用&#xff0c;但如果碰到需要连接同一user&#xff0c;同一个ip,不同端口的情况&#xff0c;vscode就无法识别&#xff0c;如下图所示&#xff0c;vscode无法区分该ip下不同端口的连接&#xff…

AJAX案例——图片上传个人信息操作

黑马程序员视频地址&#xff1a; AJAX-Day02-11.图片上传https://www.bilibili.com/video/BV1MN411y7pw?vd_source0a2d366696f87e241adc64419bf12cab&spm_id_from333.788.videopod.episodes&p26 图片上传 <!-- 文件选择元素 --><input type"file"…

LabVIEW温度修正部件测试系统

LabVIEW温度修正部件测试系统 这个基于LabVIEW的温度修正部件测试系统旨在解决飞行器温度测量及修正电路的测试需求。该系统的意义在于提供一个可靠的测试平台&#xff0c;用于评估温度修正部件在实际飞行器环境中的性能表现&#xff0c;从而确保飞行器的安全性和可靠性。 系统…

细说机器学习算法之ROC曲线用于模型评估

系列文章目录 第一章&#xff1a;Pyhton机器学习算法之KNN 第二章&#xff1a;Pyhton机器学习算法之K—Means 第三章&#xff1a;Pyhton机器学习算法之随机森林 第四章&#xff1a;Pyhton机器学习算法之线性回归 第五章&#xff1a;Pyhton机器学习算法之有监督学习与无监督…

DeepSeek本地部署(windows)

一、下载并安装Ollama 1.下载Ollama Ollama官网:Ollama 点击"Download",会跳转至下载页面。 点击"Download for Windows"。会跳转Github进行下载,如下载速度过慢,可在浏览器安装GitHub加速插件。 2.安装Ollama 双击下载的安装文件,点击"Inst…

简要介绍C语言/C++的三目运算符

三元运算符是C语言和C中的一种简洁的条件运算符&#xff0c;它的形式为&#xff1a; 条件表达式 ? 表达式1 : 表达式2; 三元运算符的含义 条件表达式&#xff1a;这是一个布尔表达式&#xff0c;通常是一个比较操作&#xff08;如 >、<、 等&#xff09;。 表达式1&am…

SpringCloud系列教程:微服务的未来(十九)请求限流、线程隔离、Fallback、服务熔断

前言 前言 在现代微服务架构中&#xff0c;系统的高可用性和稳定性至关重要。为了解决系统在高并发请求或服务不可用时出现的性能瓶颈或故障&#xff0c;常常需要使用一些技术手段来保证服务的平稳运行。请求限流、线程隔离、Fallback 和服务熔断是微服务中常用的四种策略&…

STM32 对射式红外传感器配置

这次用的是STM32F103的开发板&#xff08;这里面的exti.c文件没有how to use this driver 配置说明&#xff09; 对射式红外传感器 由一个红外发光二极管和NPN光电三极管组成&#xff0c;M3固定安装孔&#xff0c;有输出状态指示灯&#xff0c;输出高电平灯灭&#xff0c;输出…

(动态规划路径基础 最小路径和)leetcode 64

视频教程 1.初始化dp数组&#xff0c;初始化边界 2、从[1行到n-1行][1列到m-1列]依次赋值 #include<vector> #include<algorithm> #include <iostream>using namespace std; int main() {vector<vector<int>> grid { {1,3,1},{1,5,1},{4,2,1}…

嵌入式C语言:什么是共用体?

在嵌入式C语言编程中&#xff0c;共用体&#xff08;Union&#xff09;是一种特殊的数据结构&#xff0c;它允许在相同的内存位置存储不同类型的数据。意味着共用体中的所有成员共享同一块内存区域&#xff0c;因此&#xff0c;在任何给定时间&#xff0c;共用体只能有效地存储…

QT简单实现验证码(字符)

0&#xff09; 运行结果 1&#xff09; 生成随机字符串 Qt主要通过QRandomGenerator类来生成随机数。在此之前的版本中&#xff0c;qrand()函数也常被使用&#xff0c;但从Qt 5.10起&#xff0c;推荐使用更现代化的QRandomGenerator类。 在头文件添加void generateRandomNumb…

【4Day创客实践入门教程】Day2 探秘微控制器——单片机与MicroPython初步

Day2 探秘微控制器——单片机与MicroPython初步 目录 Day2 探秘微控制器——单片机与MicroPython初步MicroPython语言基础开始基础语法注释与输出变量模块与函数 单片机基础后记 Day0 创想启程——课程与项目预览Day1 工具箱构建——开发环境的构建Day2 探秘微控制器——单片机…