cocos 写 连连看 小游戏主要逻辑(Ts编写)算法总结

news2024/11/18 22:50:01

cocos官方文档:节点系统事件 | Cocos Creator

游戏界面展示

一、在cocos编译器随便画个页面 展示页面

二、连连看元素生成

2.1、准备单个方块元素,我这里就是直接使用一张图片,图片大小为100x100,锚点为(0,0),这图片命名animal,把这一张图片设置成Prefab(预制)

(作为后面用代码生成元素矩阵使用)

2.2、给命名animal的Prefab(预制)绑定一个ts文件,命名Animal.ts,这个类就是存放单个图片参数了

@property(cc.SpriteFrame)
  sp1 = [];

这里就是表示不同的图片资源,在上图的最右边就可以看的绑定了5张图片进去,为了id对应,[0]位置空了

Animal.ts文件代码如下:

//import { AnimalMgr } from "./AnimalMgr";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Animal extends cc.Component {
  // 存放不同图片,就是元素种类
  @property(cc.SpriteFrame)
  sp1 = [];

  // LIFE-CYCLE CALLBACKS:

  // onLoad () {}

//存放元素种类id,用于后面匹配消除同类元素
  private _aid: number = 0;
  public get aid(): number {
    return this._aid;
  }
  public set aid(value: number) {
    this._aid = value;
    if (this._aid > 0 && this._aid < this.sp1.length) {
      this.node.getComponent(cc.Sprite).spriteFrame = this.sp1[this._aid];
    }
  }
  // 该元素位于矩阵第几行(x)
  private _rowIndex: number = -1;
  public get rowIndex(): number {
    return this._rowIndex;
  }
  public set rowIndex(value: number) {
    this._rowIndex = value;
  }
  // 该元素位于矩阵第几列(y)
  private _colIndex: number = -1;
  public get colIndex(): number {
    return this._colIndex;
  }
  public set colIndex(value: number) {
    this._colIndex = value;
  }

  // 该元素矩阵横着总长度
  private _rowSum: number = -1;
  public get rowSum(): number {
    return this._rowSum;
  }
  public set rowSum(value: number) {
    this._rowSum = value;
  }

  // 该元素矩阵竖着总长度
  private _colSum: number = -1;
  public get colSum(): number {
    return this._colSum;
  }
  public set colSum(value: number) {
    this._colSum = value;
  }

  start() {
    // 点击该元素就会触发该方法,cocos固定点击事件写法
    this.node.on(cc.Node.EventType.TOUCH_END, (xxx) => {
      console.log(this.aid);
     // AnimalMgr.addAnimal(this);
    });
  }

  // update (dt) {}
}

2.3、给整个画布绑定一个ts文件,命名Mgr.ts,后面在这个Mgr.ts文件声明一个预制,引入上面的预置文件Animal

里面就是编写动态生成连连看矩阵元素的逻辑

Mgr.ts文件代码如下:

import Animal from "./Animal";
//import { AnimalMgr } from "./AnimalMgr";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Mgr extends cc.Component {
  @property(cc.Prefab)
  T0 = null;

  onLoad() {}

  private _rows: number = 5; //矩阵的行数
  private _cols: number = 6; //矩阵的列数
  private _eleIdSum: number = 5; //可以展示图片的种类数量
  start() {
    // console.log("start");
    // let _tmp = [
    //   [1,1,1,1,1,1,],
    //   [1,1,1,1,1,1,],
    //   [1,1,1,1,1,1,],
    //   [1,1,1,1,1,1,],
    //   [1,1,1,1,1,1,],
    // ]
    let _startx: number = -(this._cols * 100) >> 1;
    let _starty: number = -(this._rows * 100) >> 1;

    for (let index1 = 0; index1 < this._rows; index1++) {
      for (let index2 = 0; index2 < this._cols; index2++) {
        let _xxx: cc.Node = cc.instantiate(this.T0);//创建一个元素
        this.node.addChild(_xxx); //把这元素添加到页面上
        _xxx.x = _startx;
        _xxx.y = _starty;
        _startx += 100;
        // 获取这个元素组件的元素
        let _script: Animal = _xxx.getComponent(Animal);  //获取这个元素的信息
        _script.aid = this.randomIdFn(index1, index2); //给这个元素渲染的图片id 该方法并生成对称id种类个数
        _script.rowIndex = index1; // 记录该图片在矩阵x轴位置
        _script.colIndex = index2; // 记录该图片在矩阵y轴位置
        _script.rowSum = this._rows; // 该元素矩阵横着总长度
        _script.colSum = this._cols; // 该元素矩阵横着总长度
        //AnimalMgr.set(index1, index2, 1); //记录矩阵元素是否消除或者存在,1表示存在,表示不存在
      }
      _startx = -(this._cols * 100) >> 1;
      _starty += 100;
    }

    /* 
     伪节点,就是在连连看矩阵四周加多一层节点数据,
     标识四周一圈的节点都消除成功了,为后面的链接算法做处理
    */
    // for (let index = 0; index < this._cols; index++) {
    //   AnimalMgr.set(-1, index, 0);
    // }

    // for (let index = 0; index < this._cols; index++) {
    //   AnimalMgr.set(this._rows, index, 0);
    // }

    // for (let index = 0; index < this._rows; index++) {
    //   AnimalMgr.set(index, -1, 0);
    // }
    // for (let index = 0; index < this._rows; index++) {
    //   AnimalMgr.set(index, this._cols, 0);
    // }
  }

  private idMap: Map<number, number> = new Map(); //收集每种元素id生成的个数,用于记录每种元素已经生成的个数

  public randomIdFn(rowIndex: number, colIndex: number) {
    // rowIndex: 记录元素生成到第几行, colIndex: 记录元素生成到第几列
    //这里是末尾补偶法,前面元素随机生成,末尾再把基数种类元素补为偶数 此方法用于保证生成的元素都为偶数对
    let randomId = 1 + Math.floor(Math.random() * this._eleIdSum); // 渲染的图片id--> 1~5

    const eleSum = rowIndex * this._cols + colIndex; //遍历到第几个元素了
    const replenish = this._cols * this._rows - this._eleIdSum; //需要开始补充奇数位的元素开始位置
    if (eleSum > replenish) {
      //开始补充基数位的元素-->这里有5类元素,我在格子最后的五位元素补充,确保每种元素都为偶数对
      // let newCreateIdSum = this.idMap.get(randomId);
      this.idMap.forEach((value, key) => {
        if (value % 2 != 0) {
          randomId = key; //不是偶数的元素种类,补充为偶数
        }
      });
    }

    //用于记录每种元素已经生成的个数
    if (this.idMap.get(randomId) && this.idMap.get(randomId) > 0) {
      let idSum = this.idMap.get(randomId) + 1;
      this.idMap.set(randomId, idSum);
    } else {
      this.idMap.set(randomId, 1); //初始化
    }
    return randomId;
  }

  // protected onDestroy(): void {

  // }

  update(dt) {}

  // protected lateUpdate(dt: number): void {

  // }
}

        这里总结一下做上面所有步骤都只是为了生成一个 连连看的矩阵画面,这里的元素生成主要逻辑是:

末尾补齐法,目的让每一种类元素都可成为偶数,避免消除完后,最后某种元素中有单个元素在页面上,玩家无法进行匹配,主要代码逻辑在 public randomIdFn(rowIndex: number, colIndex: number),方法不唯一,可以用自己想法编写

三、连连看算法逻辑编写

3.1、在项目新建ts文件,命名AnimalMgr.ts 连连看小游戏的主要逻辑都存放在该文件

在该文件下,AnimalMgr.ts初始化代码如下:

import Animal from "./Animal";

interface VC {
  rowIndex: number;
  colIndex: number;
}

class _AnimalMgr {
  private _animals: Array<Animal> = []; //点击到的元素存进了,这里最大值2个元素
  private _paths: Map<string, number> = new Map(); //用于记录矩阵那个元素的消除情况,1表示存在,0表示消除

  public addAnimal(_Animal: Animal) {
    if (_Animal) {
      //
      console.log(this._animals);
      if (this._animals.length > 0) {
        let _start: Animal = this._animals[0];
        //是否是相同元素,是就不记录进去
        if (
          _start.colIndex == _Animal.colIndex &&
          _start.rowIndex == _Animal.rowIndex
        ) {
          return;
        }
      }
      this._animals.push(_Animal);
      //------------
      if (this._animals.length == 2) {
        //TODO:0拐点
        let _isConnect: boolean = false;
        let _start: Animal = this._animals[0];
        let _stop: Animal = this._animals[1];
        if (_start.aid != _stop.aid) {
          //是否是相同元素
          this._animals = [];
          return;
        }

        if (_isConnect) {
          // 符合连接条件的,在视图上销毁这俩连接上的节点,并记录下来这两节点已经消除
          this.set(_start.rowIndex, _start.colIndex, 0);
          this.set(_stop.rowIndex, _stop.colIndex, 0);
          _start.node.destroy();
          _stop.node.destroy();
        }
        // console.log("_isConnect",_isConnect);
        this._animals = [];
      }
    }
  }
 //判断这个节点是否存在矩阵图形上
  public isPass(_r: number, _c: number) {
    let _key = `${_r}_${_c}`;
    if (this._paths.has(_key)) {
      return this._paths.get(_key) == 0;
    } else {
      return false;
    }
  }
  /* 
  标识矩阵每个元素的位置,并且值为1 代表存在,0代表销毁
  _r: number,  //横坐标
  _c: number, // 纵坐标
  _v: number //值为1 代表存在,0代表销毁
   */
  public set(_r: number, _c: number, _v: number) {
    let _key = `${_r}_${_c}`;
    this._paths.set(_key, _v);
    console.log(this._paths);
  }
}

export const AnimalMgr = new _AnimalMgr();

上面AnimalMgr.ts初始化代码主要一个目的,记录元素在矩阵中是否存在,存在的,就在矩阵的对应位置标识为1 不存在就标识为0

3.2、然后把上面Animal.ts和Mgr.ts文件,关于引用到AnimalMgr.ts的代码,注释回来,就可正常随意点击任意两个元素,这两个元素就会消失在页面上,如下图所示:

3.3、点击矩阵的两个节点,是否能连接成功,符合条件就把连接成功的节点消除

下面是主要逻辑,分三步走,

(第一步)0拐点:

意思是两个节点都是在同一条直线上,都在同一条x轴或者y轴上面,

比如A到B点,中间只是一条直线连接在同y轴上,或者C到D点也只一条直线连接,在同x轴上,

中间连接线不需要任何直角拐弯就可联通,就表示这两个节点0个拐点

在0拐点的两个节点,只要中间没有任何东西,就表示可连接成功

0拐点代码逻辑如下,思路才是重点,代码可以自己写,下面代码只做参考:

// 两点距离0个拐角(直角)
  public _0c(start_: VC, stop_: VC): boolean {
    // 同一条横直线上
    if (start_.rowIndex == stop_.rowIndex) {
      if (start_.colIndex < stop_.colIndex) {
        //向右移动
        let _startCol: number = start_.colIndex + 1;
        //判断到下一个节点空就为true,有值就false
        while (this.isPass(start_.rowIndex, _startCol)) {
          _startCol++;
        }
        return _startCol == stop_.colIndex;
      } else {
        // 向左移动
        let _startCol: number = start_.colIndex - 1;
        while (this.isPass(start_.rowIndex, _startCol)) {
          _startCol--;
        }
        return _startCol == stop_.colIndex;
      }
    } else if (start_.colIndex == stop_.colIndex) {
      // 同一条竖直线上
      if (start_.rowIndex < stop_.rowIndex) {
        //向上移动
        let _startRow: number = start_.rowIndex + 1;
        while (this.isPass(_startRow, start_.colIndex)) {
          _startRow++;
        }
        return _startRow == stop_.rowIndex;
      } else {
        //向下移动
        let _startRow: number = start_.rowIndex - 1;
        while (this.isPass(_startRow, start_.colIndex)) {
          _startRow--;
        }
        return _startRow == stop_.rowIndex;
      }
    }
    return;
  }

(第二步:假设0个拐点条件不满足)1拐点:

意思是两个节点坐标x和y都不相同,但是,两个节点的连接线,只有一个直角

如下图:

下面需要点击A和B节点,A和B的直线距离都不能直接连接,现在需要连接只能两条路线,每条路线只能一个直角,就只有两条路线可走,每条路线都会有一个拐点,分别是 C和D拐点

A和B要想连接成功,路线一或者路线二,只要有一条能连接上:拐点的位置到起点和终点的直线连接都没有阻碍物,表示A和B就可以相连

1拐点代码逻辑如下,思路才是重点,代码可以自己写,下面代码只做参考:

// 两点距离1个拐角(直角)
  public _1c(start_: VC, stop_: VC): boolean {
    //找到两个节点的两个直角拐点
    let _p1: VC = { rowIndex: start_.rowIndex, colIndex: stop_.colIndex }; //拐角点1
    let _p2: VC = { rowIndex: stop_.rowIndex, colIndex: start_.colIndex }; //拐角点2
    let _tmp: Array<VC> = [_p1, _p2];
    // 判断每个拐角点到初始点和终点之间是否有阻碍节点,有就表示行不通
    for (let index = 0; index < _tmp.length; index++) {
      const pt = _tmp[index];
      if (this.isPass(pt.rowIndex, pt.colIndex)) {
        let _isOK = true;
        _isOK = _isOK && this._0c(pt, start_);
        _isOK = _isOK && this._0c(pt, stop_);
        if (_isOK) {
          return true;
        }
      }
    }
    return false;
  }

(第三步:假设0个1拐点条件都不满足)2拐点:

意思是:A到B点的连通需要满足连接路线会出现两个直角的

如下图:

A点到B点要想连接成功,连接路线需要两个拐角,

C点到D点要想连接成功,连接路线也需要两个拐角,

两个节点出现两个拐角点要是想连接成功,代码的核心思路是,在起始点,通过上下左右移动的尝试,起始点移动到的位置,可以实现与终点连接出现一个拐点路线,就能连接成功了,就表示这两个节点可以连接成功

2拐点代码逻辑如下,思路才是重点,代码可以自己写,下面代码只做参考:

// 两点距离2个拐角(直角)
  public _2c(start_: VC, stop_: VC): boolean {
    // 向初始节点四面移动,判断受否可能找到 连接到终节点的一个拐角的路线
    //TODO:左
    let _startCol: number = start_.colIndex - 1;
    //在初始起点向左移动,直到找到可连接到终节点的一个拐角的路线,遇到符合就终止,
    // 如果都不满足,就退出向左移动的尝试,走下面的右移动逻辑
    while (this.isPass(start_.rowIndex, _startCol)) {
      // 判断这个节点是否存在矩阵图形上--this.isPass(start_.rowIndex, _startCol)
      this.set(start_.rowIndex, _startCol, 100);//起始点左移动,标记该位置存在元素
      let _isOk = this._1c(
        { rowIndex: start_.rowIndex, colIndex: _startCol },
        { rowIndex: stop_.rowIndex, colIndex: stop_.colIndex }
      );
      this.set(start_.rowIndex, _startCol, 0);
      _startCol -= 1;
      if (_isOk) {
        return true;
      }
    }
    //TODO:右
    _startCol = start_.colIndex + 1;
    while (this.isPass(start_.rowIndex, _startCol)) {
      this.set(start_.rowIndex, _startCol, 100);
      let _isOk = this._1c(
        { rowIndex: start_.rowIndex, colIndex: _startCol },
        { rowIndex: stop_.rowIndex, colIndex: stop_.colIndex }
      );
      this.set(start_.rowIndex, _startCol, 0);
      _startCol += 1;
      if (_isOk) {
        return true;
      }
    }
    //TODO:上
    let _startRow = start_.rowIndex + 1;
    while (this.isPass(_startRow, start_.colIndex)) {
      this.set(_startRow, start_.colIndex, 100);
      let _isOk = this._1c(
        { rowIndex: _startRow, colIndex: start_.colIndex },
        { rowIndex: stop_.rowIndex, colIndex: stop_.colIndex }
      );

      this.set(_startRow, start_.colIndex, 0);
      _startRow += 1;
      if (_isOk) {
        return true;
      }
    }
    //TODO:下
    _startRow = start_.rowIndex - 1;
    while (this.isPass(_startRow, start_.colIndex)) {
      this.set(_startRow, start_.colIndex, 100);
      let _isOk = this._1c(
        { rowIndex: _startRow, colIndex: start_.colIndex },
        { rowIndex: stop_.rowIndex, colIndex: stop_.colIndex }
      );
      this.set(_startRow, start_.colIndex, 0);
      _startRow -= 1;
      if (_isOk) {
        return true;
      }
    }
    return false;
  }

AnimalMgr.ts完整代码如下代码如下:

import Animal from "./Animal";

interface VC {
  rowIndex: number;
  colIndex: number;
}

class _AnimalMgr {
  private _animals: Array<Animal> = []; //点击到的元素存进了,这里最大值2个元素
  private _paths: Map<string, number> = new Map(); //用于记录矩阵那个元素的消除情况,1表示存在,0表示消除

  // AnimalMgr.set(index1,index2,0);

  public addAnimal(_Animal: Animal) {
    if (_Animal) {
      //
      console.log(this._animals);
      if (this._animals.length > 0) {
        let _start: Animal = this._animals[0];
        //是否是相同元素,是就不记录进去
        if (
          _start.colIndex == _Animal.colIndex &&
          _start.rowIndex == _Animal.rowIndex
        ) {
          return;
        }
      }
      this._animals.push(_Animal);
      //------------
      if (this._animals.length == 2) {
        //TODO:0拐点
        let _isConnect: boolean = false;
        let _start: Animal = this._animals[0];
        let _stop: Animal = this._animals[1];
        if (_start.aid != _stop.aid) {
          //是否是相同元素
          this._animals = [];
          return;
        }
        _isConnect = this._0c(
          { rowIndex: _start.rowIndex, colIndex: _start.colIndex },
          { rowIndex: _stop.rowIndex, colIndex: _stop.colIndex }
        );
        //TODO:1拐点
        if (!_isConnect) {
          _isConnect = this._1c(
            { rowIndex: _start.rowIndex, colIndex: _start.colIndex },
            { rowIndex: _stop.rowIndex, colIndex: _stop.colIndex }
          );
        }
        //TODO:2拐点
        if (!_isConnect) {
          _isConnect = this._2c(
            { rowIndex: _start.rowIndex, colIndex: _start.colIndex },
            { rowIndex: _stop.rowIndex, colIndex: _stop.colIndex }
          );
        }

        if (_isConnect) {
          // 符合连接条件的,在视图上销毁这俩连接上的节点,并记录下来这两节点已经消除
          this.set(_start.rowIndex, _start.colIndex, 0);
          this.set(_stop.rowIndex, _stop.colIndex, 0);
          _start.node.destroy();
          _stop.node.destroy();
        }
        // console.log("_isConnect",_isConnect);
        this._animals = [];
      }
    }
  }
  //判断这个节点是否存在矩阵图形上
  public isPass(_r: number, _c: number) {
    let _key = `${_r}_${_c}`;
    if (this._paths.has(_key)) {
      return this._paths.get(_key) == 0;
    } else {
      return false;
    }
  }
  /* 
  标识矩阵每个元素的位置,并且值为1 代表存在,0代表销毁
  _r: number,  //横坐标
  _c: number, // 纵坐标
  _v: number //值为1 代表存在,0代表销毁
   */
  public set(_r: number, _c: number, _v: number) {
    let _key = `${_r}_${_c}`;
    this._paths.set(_key, _v);
    console.log(this._paths);
  }

  // 两点距离0个拐角(直角)
  public _0c(start_: VC, stop_: VC): boolean {
    // 同一条横直线上
    if (start_.rowIndex == stop_.rowIndex) {
      if (start_.colIndex < stop_.colIndex) {
        //向右移动
        let _startCol: number = start_.colIndex + 1;
        //判断到下一个节点空就为true,有值就false
        while (this.isPass(start_.rowIndex, _startCol)) {
          _startCol++;
        }
        return _startCol == stop_.colIndex;
      } else {
        // 向左移动
        let _startCol: number = start_.colIndex - 1;
        while (this.isPass(start_.rowIndex, _startCol)) {
          _startCol--;
        }
        return _startCol == stop_.colIndex;
      }
    } else if (start_.colIndex == stop_.colIndex) {
      // 同一条竖直线上
      if (start_.rowIndex < stop_.rowIndex) {
        //向上移动
        let _startRow: number = start_.rowIndex + 1;
        while (this.isPass(_startRow, start_.colIndex)) {
          _startRow++;
        }
        return _startRow == stop_.rowIndex;
      } else {
        //向下移动
        let _startRow: number = start_.rowIndex - 1;
        while (this.isPass(_startRow, start_.colIndex)) {
          _startRow--;
        }
        return _startRow == stop_.rowIndex;
      }
    }
    return;
  }
  // 两点距离1个拐角(直角)
  public _1c(start_: VC, stop_: VC): boolean {
    //找到两个节点的两个直角拐点
    let _p1: VC = { rowIndex: start_.rowIndex, colIndex: stop_.colIndex }; //拐角点1
    let _p2: VC = { rowIndex: stop_.rowIndex, colIndex: start_.colIndex }; //拐角点2
    let _tmp: Array<VC> = [_p1, _p2];
    // 判断每个拐角点到初始点和终点之间是否有阻碍节点,有就表示行不通
    for (let index = 0; index < _tmp.length; index++) {
      const pt = _tmp[index];
      if (this.isPass(pt.rowIndex, pt.colIndex)) {
        let _isOK = true;
        _isOK = _isOK && this._0c(pt, start_);
        _isOK = _isOK && this._0c(pt, stop_);
        if (_isOK) {
          return true;
        }
      }
    }
    return false;
  }
  // 两点距离2个拐角(直角)
  public _2c(start_: VC, stop_: VC): boolean {
    // 向初始节点四面移动,判断受否可能找到 连接到终节点的一个拐角的路线
    //TODO:左
    let _startCol: number = start_.colIndex - 1;
    //在初始起点向左移动,直到找到可连接到终节点的一个拐角的路线,遇到符合就终止,
    // 如果都不满足,就退出向左移动的尝试,走下面的右移动逻辑
    while (this.isPass(start_.rowIndex, _startCol)) {
      // 判断这个节点是否存在矩阵图形上--this.isPass(start_.rowIndex, _startCol)
      this.set(start_.rowIndex, _startCol, 100); //起始点左移动,标记该位置存在元素
      let _isOk = this._1c(
        { rowIndex: start_.rowIndex, colIndex: _startCol },
        { rowIndex: stop_.rowIndex, colIndex: stop_.colIndex }
      );
      this.set(start_.rowIndex, _startCol, 0);
      _startCol -= 1;
      if (_isOk) {
        return true;
      }
    }
    //TODO:右
    _startCol = start_.colIndex + 1;
    while (this.isPass(start_.rowIndex, _startCol)) {
      this.set(start_.rowIndex, _startCol, 100);
      let _isOk = this._1c(
        { rowIndex: start_.rowIndex, colIndex: _startCol },
        { rowIndex: stop_.rowIndex, colIndex: stop_.colIndex }
      );
      this.set(start_.rowIndex, _startCol, 0);
      _startCol += 1;
      if (_isOk) {
        return true;
      }
    }
    //TODO:上
    let _startRow = start_.rowIndex + 1;
    while (this.isPass(_startRow, start_.colIndex)) {
      this.set(_startRow, start_.colIndex, 100);
      let _isOk = this._1c(
        { rowIndex: _startRow, colIndex: start_.colIndex },
        { rowIndex: stop_.rowIndex, colIndex: stop_.colIndex }
      );

      this.set(_startRow, start_.colIndex, 0);
      _startRow += 1;
      if (_isOk) {
        return true;
      }
    }
    //TODO:下
    _startRow = start_.rowIndex - 1;
    while (this.isPass(_startRow, start_.colIndex)) {
      this.set(_startRow, start_.colIndex, 100);
      let _isOk = this._1c(
        { rowIndex: _startRow, colIndex: start_.colIndex },
        { rowIndex: stop_.rowIndex, colIndex: stop_.colIndex }
      );
      this.set(_startRow, start_.colIndex, 0);
      _startRow -= 1;
      if (_isOk) {
        return true;
      }
    }
    return false;
  }
}

export const AnimalMgr = new _AnimalMgr();

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

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

相关文章

使用python对指定文件夹下的pdf文件进行合并

使用python对指定文件夹下的pdf文件进行合并 介绍效果代码 介绍 对指定文件夹下的所有pdf文件进行合并成一个pdf文件。 效果 要合并的pdf文件&#xff0c;共计16个1页的pdf文件。 合并成功的pdf文件&#xff1a;一个16页的pdf文件。 代码 import os from PyPDF2 import …

吴恩达深度学习笔记:超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架(Hyperparameter tuning)3.4-3.5

目录 第二门课: 改善深层神经网络&#xff1a;超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第三周&#xff1a; 超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架&#xff08;Hyperparameter …

Gin框架学习笔记(六)——gin中的日志使用

gin内置日志组件的使用 前言 在之前我们要使用Gin框架定义路由的时候我们一般会使用Default方法来实现&#xff0c;我们来看一下他的实现&#xff1a; func Default(opts ...OptionFunc) *Engine {debugPrintWARNINGDefault()engine : New()engine.Use(Logger(), Recovery())…

datasheet芯片数据手册—新手入门学习(二)【8-18】

参考芯片手册已经上传&#xff0c;可自行下载 因为芯片参考手册内容比较多&#xff0c;故再一次介绍本文内容主要讲解章节。 目录 8、内容介绍 命令真值表 9、Command Definitions 10、READ Operations &#xff08;1&#xff09;页面读取操作 &#xff08;2&#xff…

Orangepi Zero2 linux系统摄像头设备文件名固定

文章目录 1. 寻找设备规则2. 使用udev规则修改挂载设备文件名称 问题&#xff1a; 在多次插拔usb摄像头或者在使用中不小心碰到或松了会导致设备文件名称变化&#xff0c;如从/dev/video1和/dev/video2变为/dev/video2和/dev/video3, 所以每次发生变化后都要充型修改代码或者重…

2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(下):多智能体开发

传送门&#xff1a; 《2024.5组队学习——MetaGPT&#xff08;0.8.1&#xff09;智能体理论与实战&#xff08;上&#xff09;&#xff1a;MetaGPT安装、单智能体开发》《2024.5组队学习——MetaGPT&#xff08;0.8.1&#xff09;智能体理论与实战&#xff08;中&#xff09;&…

高校网站群及融媒体中心建设方案

一、项目背景 随着信息技术的飞速发展&#xff0c;互联网已成为高校展示形象、传播信息、服务师生、沟通社会的重要渠道。然而&#xff0c;目前许多高校在网站建设和媒体传播方面存在以下问题&#xff1a; 网站分散、缺乏统一规划&#xff1a;各高校内部往往存在多个部门或学院…

移动云——让每个人都能享受云技术的魅力

一、引言 云技术的起源可以追溯到20世纪60年代和70年代&#xff0c;随着科技的发展&#xff0c;现在早就和所有人息息相关。在云技术的浪潮中&#xff0c;有这么一家厂商通过自己的努力&#xff0c;深耕云计算市场&#xff0c;不仅有各种各样的产品为开发者提供服务&#xff0…

E1载波:一种2.048Mbps速率的PCM载波

E1载波的基本帧由32个子信道组成 帧长为256个bit,分为32个相等时隙&#xff0c;一个时隙为8个bit。256/328 时隙的编号为CH0~CH31 全帧包含256位,且每一帧用 125us时间传送 E1载波支持的数据传输效率为2.048Mbps&#xff0c;用PCM编码&#xff08;即 256bit/125us2.048Mbps…

融媒宝:群发自媒体平台的神器,注册送7天中级会员

近几年自媒体比较火&#xff0c;做自媒体往往需要发布文章或视频到多个平台&#xff0c;如手工复制粘贴逐一发布&#xff0c;委实费时费力、效率不高。今天就给大家分享一款提高自媒体运营效率的神器--融媒宝&#xff1a; 融媒宝简介 融媒宝是一款可免费使用的高效自媒体工具…

axios如何传递数组作为参数,后端又如何接收呢????

前端的参数是一个数组。 前端编写&#xff1a; 后端接收&#xff1a;

“大数据建模、分析、挖掘技术应用研修班”的通知!

随着2015年9月国务院发布了《关于印发促进大数据发展行动纲要的通知》&#xff0c;各类型数据呈现出了指数级增长&#xff0c;数据成了每个组织的命脉。今天所产生的数据比过去几年所产生的数据大好几个数量级&#xff0c;企业有了能够轻松访问和分析数据以提高性能的新机会&am…

力扣刷题---3146. 两个字符串的排列差

题目描述 给你两个字符串 s 和 t&#xff0c;每个字符串中的字符都不重复&#xff0c;且 t 是 s 的一个排列。 排列差 定义为 s 和 t 中每个字符在两个字符串中位置的绝对差值之和。 返回 s 和 t 之间的 排列差 。 示例 1&#xff1a; 输入&#xff1a;s “abc”, t “b…

新手做视频号小店,常见问题解答,看懂就明白做店逻辑了!

大家好&#xff0c;我是电商糖果 商家做视频号小店前期一定会反复咨询一些问题。 因为他们要提前做好调查&#xff0c;以防店铺运营的过程中出现问题。 糖果因为经常在网上分享自己做店的经验&#xff0c;所以就有很多朋友前来咨询过。 其实大家咨询的问题&#xff0c;反反…

利用AI技术做电商网赚,这些百万级赛道流量,你还不知道?!

大家好&#xff0c;我是向阳 AI技术的飞速扩展已经势不可挡&#xff0c;不管你承不承认&#xff0c;AI 已经毫无争议的在互联网中占有一席之地了 无论你是做内容产业的&#xff0c;还是做电商的&#xff0c;你现在都躲不开 AI。 现在互联网行业的竞争就是这么残酷 互联网行业…

YOLOv10最全使用教程(含ONNX和TensorRT推理)

论文题目&#xff1a;YOLOv10: Real-Time End-to-End Object Detection 研究单位&#xff1a;清华大学 论文链接&#xff1a;http://arxiv.org/abs/2405.14458 代码链接&#xff1a;https://github.com/THU-MIG/yolov10 作者提供的模型性能评价图&#xff0c;如下&#xff1a;…

【数据结构】神奇的二叉树

文章目录 前言1. 树形结构1.1 什么是树1.2 名词概念1.3 树的表现形式 2. 二叉树2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质 3. 二叉树的存储结构3.1 顺序存储3.2 链式存储 4. 二叉树的遍历4.1 前序遍历4.2 中序遍历4.3 后序遍历4.4 层序遍历 5. 遍历的代码实现5.1 递归实现…

机器学习模型可视化分析和诊断神器Yellowbrick

大家好&#xff0c;机器学习(ML)作为人工智能的核心&#xff0c;近来得到巨大应用&#xff0c;ML是使计算机能够在无需显式编程的情况下进行学习和预测或决策。ML算法通过学习历史数据模式&#xff0c;来对新的未见数据做出明智的预测或决策。然而&#xff0c;构建和训练ML模型…

ROS2学习——节点话题通信(2)

目录 一、ROS2节点 1.概念 2.实例 &#xff08;1&#xff09;ros2 run &#xff08;2&#xff09;ros2 node list &#xff08;3&#xff09;remapping重映射 &#xff08;4&#xff09;ros2 node info 二、话题 &#xff08;1&#xff09; ros2 topic list &#xf…

C语言内存函数(与上篇字符函数及字符串函数一起食用效果更佳哦~)

顾名思义&#xff0c;内存函数就是针对内存块&#xff08;即一块内存&#xff09;来处理的。 因此本篇所讲的四种内存函数&#xff1a; memcpy&#xff08;内存拷贝&#xff09;memmove&#xff08;内存移动&#xff09;memset&#xff08;内存设置&#xff09;memcmp&#x…