| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- import { Vec2 } from "cc";
- export class BlockUtil {
- static isLineConnectedByIndex(startI: number, startJ: number, endI: number, endJ: number,
- canPass: (i: number, j: number) => boolean): boolean {
- // 同一行
- if (startI === endI) {
- const minJ = Math.min(startJ, endJ);
- const maxJ = Math.max(startJ, endJ);
- for (let j = minJ + 1; j < maxJ; j++) {
- if (!canPass(startI, j)) {
- return false;
- }
- }
- return true;
- }
- // 同一列
- if (startJ === endJ) {
- const minI = Math.min(startI, endI);
- const maxI = Math.max(startI, endI);
- for (let i = minI + 1; i < maxI; i++) {
- if (!canPass(i, startJ)) {
- return false;
- }
- }
- return true;
- }
- return false;
- }
- static isOneLink(
- startI: number,
- startJ: number,
- endI: number,
- endJ: number,
- canPass: (i: number, j: number) => boolean
- ): boolean {
- // 检查C点路径
- const cI = startI;
- const cJ = endJ;
- // 确保C点本身可通行
- if (canPass(cI, cJ)) {
- // 检查从起点到C点的路径(不包含起点,但包含C点)
- const path1 = BlockUtil.checkPath(startI, startJ, cI, cJ, canPass, true, true);
- // 检查从C点到终点的路径(包含C点和终点)
- const path2 = BlockUtil.checkPath(cI, cJ, endI, endJ, canPass, true, true);
- if (path1 && path2) return true;
- }
- // 检查D点路径
- const dI = endI;
- const dJ = startJ;
- //
- // 确保D点本身可通行
- if (canPass(dI, dJ)) {
- // 检查从起点到D点的垂直路径是否畅通
- // 检查从起点到D点的路径(不包含起点,但包含D点)
- const path1 = BlockUtil.checkPath(startI, startJ, dI, dJ, canPass, true, true);
- // 检查从D点到终点的路径(包含D点和终点)
- const path2 = BlockUtil.checkPath(dI, dJ, endI, endJ, canPass, true, true);
- if (path1 && path2) return true;
- }
- return false;
- }
- static getOneLinkCorner(
- startI: number,
- startJ: number,
- endI: number,
- endJ: number,
- canPass: (i: number, j: number) => boolean
- ): { i: number; j: number } | null {
- // 检查C点路径 (水平→垂直)
- const cI = startI;
- const cJ = endJ;
- if (canPass(cI, cJ)) {
- const path1 = BlockUtil.checkPath(startI, startJ, cI, cJ, canPass, true, true);
- const path2 = BlockUtil.checkPath(cI, cJ, endI, endJ, canPass, true, true);
- if (path1 && path2) {
- return { i: cI, j: cJ }; // 返回C点坐标
- }
- }
- // 检查D点路径 (垂直→水平)
- const dI = endI;
- const dJ = startJ;
- if (canPass(dI, dJ)) {
- const path1 = BlockUtil.checkPath(startI, startJ, dI, dJ, canPass, true, true);
- const path2 = BlockUtil.checkPath(dI, dJ, endI, endJ, canPass, true, true);
- if (path1 && path2) {
- return { i: dI, j: dJ }; // 返回D点坐标
- }
- }
- return null; // 无可达路径时返回null
- }
- static isTwoLink(
- startI: number,
- startJ: number,
- endI: number,
- endJ: number,
- rows: number,
- cols: number,
- canPass: (i: number, j: number) => boolean
- ): boolean {
- // 向上扫描
- for (let i = startI - 1; i >= -1; i--) {
- if (i >= 0 && !canPass(i, startJ)) break;
- if (this.isOneLink(i, startJ, endI, endJ, canPass)) return true;
- }
- // 向下扫描
- for (let i = startI + 1; i <= rows; i++) {
- if (i < rows && !canPass(i, startJ)) break;
- if (this.isOneLink(i, startJ, endI, endJ, canPass)) return true;
- }
- // 向左扫描
- for (let j = startJ - 1; j >= -1; j--) {
- if (j >= 0 && !canPass(startI, j)) break;
- if (this.isOneLink(startI, j, endI, endJ, canPass)) return true;
- }
- // 向右扫描
- for (let j = startJ + 1; j <= cols; j++) {
- if (j < cols && !canPass(startI, j)) break;
- if (this.isOneLink(startI, j, endI, endJ, canPass)) return true;
- }
- return false;
- }
- static checkPath(
- startI: number,
- startJ: number,
- endI: number,
- endJ: number,
- canPass: (i: number, j: number) => boolean,
- includeStart: boolean = true,
- includeEnd: boolean = true
- ): boolean {
- // 确保起点和终点在同一直线上
- if (startI !== endI && startJ !== endJ) {
- return false;
- }
- // 水平路径检查
- if (startI === endI) {
- const minJ = Math.min(startJ, endJ);
- const maxJ = Math.max(startJ, endJ);
- // 确定循环的起始和结束位置
- const jStart = includeStart ? minJ : (minJ + 1);
- const jEnd = includeEnd ? maxJ : (maxJ - 1);
- for (let j = jStart; j <= jEnd; j++) {
- if (!canPass(startI, j)) {
- return false;
- }
- }
- }
- // 垂直路径检查
- else if (startJ === endJ) {
- const minI = Math.min(startI, endI);
- const maxI = Math.max(startI, endI);
- // 确定循环的起始和结束位置
- const iStart = includeStart ? minI : (minI + 1);
- const iEnd = includeEnd ? maxI : (maxI - 1);
- for (let i = iStart; i <= iEnd; i++) {
- if (!canPass(i, startJ)) {
- return false;
- }
- }
- }
- return true;
- }
- // 在BlockUtil中添加
- static getTwoLinkCorners1(
- startI: number,
- startJ: number,
- endI: number,
- endJ: number,
- rows: number,
- cols: number,
- canPass: (i: number, j: number) => boolean
- ): [Vec2, Vec2] | null {
- // 这里需要实现两个拐点的查找逻辑
- // 示例伪代码,需要根据实际算法实现
- for (let i = 0; i < rows; i++) {
- if (canPass(i, startJ) && canPass(i, endJ)) {
- return [
- new Vec2(i, startJ),
- new Vec2(i, endJ)
- ];
- }
- }
- return null;
- }
- static getTwoLinkCorners(
- startI: number,
- startJ: number,
- endI: number,
- endJ: number,
- rows: number,
- cols: number,
- canPass: (i: number, j: number) => boolean
- ): [{ i: number, j: number }, { i: number, j: number }] | null {
-
- // 向上扫描
- for (let i = startI - 1; i >= -1; i--) {
- if (i >= 0 && !canPass(i, startJ)) break;
- const firstCorner = { i, j: startJ };
- const secondCorner = this.getOneLinkCorner(i, startJ, endI, endJ, canPass);
- if (secondCorner) {
- return [firstCorner, secondCorner];
- }
- }
-
- // 向下扫描
- for (let i = startI + 1; i <= rows; i++) {
- if (i < rows && !canPass(i, startJ)) break;
- const firstCorner = { i, j: startJ };
- const secondCorner = this.getOneLinkCorner(i, startJ, endI, endJ, canPass);
- if (secondCorner) {
- return [firstCorner, secondCorner];
- }
- }
-
- // 向左扫描
- for (let j = startJ - 1; j >= -1; j--) {
- if (j >= 0 && !canPass(startI, j)) break;
- const firstCorner = { i: startI, j };
- const secondCorner = this.getOneLinkCorner(startI, j, endI, endJ, canPass);
- if (secondCorner) {
- return [firstCorner, secondCorner];
- }
- }
-
- // 向右扫描
- for (let j = startJ + 1; j <= cols; j++) {
- if (j < cols && !canPass(startI, j)) break;
- const firstCorner = { i: startI, j };
- const secondCorner = this.getOneLinkCorner(startI, j, endI, endJ, canPass);
- if (secondCorner) {
- return [firstCorner, secondCorner];
- }
- }
-
- return null;
- }
- }
|