`

React学习之围棋记谱本制作(五)死活判断

阅读更多
  这一部分内容基本与React没有关系。判断棋子的死活,比较容易,用种子填充算法来处理。我跟种子填充算法还有些故交,记得上学时,编写挖雷的程序,就用过。
  对于围棋死活的判断,要分清块(同色相连的棋),判断整块棋的气,大致的流程如下:
  a) 遍历棋子,如果不是空,则记录颜色,作为种子压入栈中(并记录到Map中),如果遍历完成,转g);
  b) 如果栈为空,则转e) ;否则转c) ;
  c) 从栈弹出一个棋子,找周围四个棋子,如果同色、且未检查过则入栈(并记录到Map中,相连的空记到另一个Map中);
  d) 转b) ;
  e) 结束种子算法;
  f) 转a) ;
  g) 结束。

  最后得到两个Map,一个是待判断死活的一块棋,一个是这块棋对应的气。如果气等于零,则为死棋。
  会下围棋的人都知道,有一种比较特殊的情况,就是一个子放入棋盘后,如果产生两块或更多死棋,那么包含当前步的棋子的棋块,不是死棋,杀了另一方的棋。如果没有看明白,看下面图。编号为1的子放到棋盘上后,会产生两块死棋,此时实际上为黑杀白。




  简单试了一下,似乎没有问题。如有问题,欢迎反馈。

  2016-12-08:发现两个小问题:气数量为零才为死棋、返回数组中未去掉当前子所在的棋块(如果多块死棋)。

/**
 * Created by Administrator on 2016-12-08.
 * http://wallimn.iteye.com
 */
"use strick"

class JudgeDie{
    constructor(){
        //线数,根据传入的数组长度计算
        this.LINE_COUNT=19;
    }

    //取相关棋子的下标
    //当前棋子
    //dir:上右下左,对应于1234,写成数字,便于循环处理
    getRelativePiece(index,dir){
        var x = index % this.LINE_COUNT;
        var y = Math.floor( index / this.LINE_COUNT);
        if (dir===1){//上
            if (y-1<0) return null;
            else return x+(y-1)*this.LINE_COUNT;
        }
        else if (dir===2){//右
            if (x+1>=this.LINE_COUNT) return null;
            else return (x+1)+y*this.LINE_COUNT;
        }
        else if (dir===3){//下
            if (y+1>=this.LINE_COUNT) return null;
            else return x+(y+1)*this.LINE_COUNT;
        }
        else if (dir===4){//左
            if (x-1<0) return null;
            else return (x-1)+y*this.LINE_COUNT;
        }
        else{
            return null;
        }
    }

    //计算map中key的数量
    getKeyCount(map){
        var count = 0;
        for(var k in map){
            if(map.hasOwnProperty(k))
                count++;
        }
        return count;
    }

    //取出所有key,仅用于调试
    getKeyString(map){
        var result = "";
        for(var k in map){
            if(map.hasOwnProperty(k))
                result = result + k+", ";
        }
        return result;
    }

    //计算死活
    //pieces:棋子数组,0:空;1:黑;2:白
    //lastId:最后棋子的下标
    calc(pieces,lastId){
        var stack=[];//种子填充算法的栈
        var result = [];//结果
        var len = pieces.length;//棋子长度
        this.LINE_COUNT = Math.sqrt(len);

        var checkedMap = {};//检测过棋子的Map
        var blockMap = null;//保存一块棋的Map
        var airMap = null;//气Map
        var color;//当前检测棋子的颜色
        var index,relate;

        for(var i=0; i<len; i++){
            //如果当前子为空、或者已检测,则跳过
            if (pieces[i]==0 || i.toString() in checkedMap)continue;

            color = pieces[i];
            stack = [];
            stack.push(i);
            airMap = {};
            checkedMap[i.toString()]=true;
            //true为随便放入的值,没有任何意义,下同

            blockMap = {};
            blockMap[i.toString()]=true;

            while(stack.length!=0){
                index = stack.pop();
                for (var dir=1; dir<=4; dir++){
                    relate = this.getRelativePiece(index,dir);
                    if(relate!=null) {
                        //如果相关子的颜色相同、且未检测过
                        if (pieces[relate] == color && (!(relate.toString() in checkedMap))) {
                            stack.push(relate);
                            checkedMap[relate.toString()] = true;
                            blockMap[relate.toString()] = true;
                        }
                        else if (pieces[relate] == 0) {//如果为空,则为当前检测棋块的气
                            airMap[relate.toString()] = true;
                        }
                    }
                }
            }

            //console.log("气数量:%d,棋块:%s",this.getKeyCount(airMap),this.getKeyString(blockMap));
            //如果当前检测棋块的气=0,则为死棋,加入结果数组
            if(this.getKeyCount(airMap)==9) result.push(blockMap);
        }

        //有个复杂的情况,就是有时同时会出现两块以上的死棋,
        //那么如果其中一块包含当前棋子,则不为死棋
        var len = result.length;
        if(len>1 && lastId>=0){
            var delidx=-1;
            for(var i=0; i<len; i++){
                if(lastId.toString() in result[i]) {
                    delidx = i;
                    break;
                }
            }
            if (delidx!=-1){//如果死棋块中包含当前子,则该棋块不为死棋
                result.splice(delidx,1);
            }
        }

        return result;
    }
}

module.exports = new JudgeDie();
  • 大小: 52.4 KB
  • 大小: 53.6 KB
分享到:
评论

相关推荐

    React学习之围棋记谱本制作(七)总结

    在本篇“React学习之围棋记谱本制作(七)总结”中,我们将深入探讨如何利用React技术栈创建一个功能完善的围棋记谱本应用。React是Facebook开发的一个用于构建用户界面的JavaScript库,尤其适用于构建单页应用。在...

    React学习之围棋记谱本制作(一)环境准备

    在本文中,我们将探讨如何利用React技术来创建一个围棋记谱本应用。React是Facebook推出的一个用于构建用户界面的JavaScript库,尤其适用于构建组件化的、交互式的Web应用。在这个项目的第一部分,我们将专注于环境...

    React学习之围棋记谱本制作(四)前端开发初步完成

    在本项目中,“React学习之围棋记谱本制作(四)前端开发初步完成”是一个教程,旨在教授如何使用React框架构建一个围棋记谱本的前端应用。从给出的标签“源码”和“工具”来看,我们可以推断这个教程会涉及实际的...

    React学习手册.zip

    本React学习手册将深入探讨React的核心概念和实战技巧,帮助你从入门到精通。 首先,React的核心概念包括组件化开发。组件是React的基础单元,可以理解为可复用的代码块,它们像乐高积木一样组合起来构建整个应用。...

    React 学习之道

    React 学习之道 ==================================================

    React学习手册完整版带目录.zip

    "React学习手册完整版带目录.zip"包含了深入学习React所需的所有资料,包括基本概念、核心原理以及高级技巧。 首先,手册的目录可能会涵盖以下关键知识点: 1. **React基础知识**:介绍React的基本概念,如JSX语法...

    react学习课件.rar

    这个"react学习课件.rar"文件包含的"react学习课件.docx"文档,很可能是从哔哩哔哩上的一个React教程课程中提取出的学习资料。在React的世界里,有很多关键概念和技术值得深入探讨。 首先,React的核心理念是组件化...

    React学习资源汇总.pdf

    React学习资源汇总.pdf

    React学习路线脑图

    React学习路线脑图

    react-react学习心得

    在深入探讨React技术栈之前,我们首先需要理解什么是React。React是Facebook开发的一款用于构建用户界面的JavaScript库,尤其擅长于构建单页应用程序(SPA)。它主要关注视图层,但也可以与各种库和框架(如Redux、...

    React学习思维脑图

    React 学习思维脑图,有助于更好的学习react

    react入门学习文档

    React入门学习文档 React 是一个用于构建用户界面的 JavaScript 库,是一个数据驱动的 MVVM 模式的框架。学习 React 需要了解其主要特点、JSX 元素渲染、生命周期、组件事件等知识点。 React 介绍 React 是一个...

    react中文学习资料

    React中文学习资料提供了丰富的信息和教程,帮助开发者理解React的基本概念、核心原理和编程方法。 在React的学习过程中,首先需要了解的基本要求包括Node.js环境以及npm(Node Package Manager)。Node.js是一个...

    元宇宙初探React+Three.js制作3D全景漫游.zip

    元宇宙初探React+Three.js制作3D全景漫游.zip元宇宙初探React+Three.js制作3D全景漫游.zip元宇宙初探React+Three.js制作3D全景漫游.zip元宇宙初探React+Three.js制作3D全景漫游.zip元宇宙初探React+Three.js制作3D...

    React 进阶之路

    在React的世界里,进阶之路意味着深入理解其核心概念、最佳实践以及高级技巧。React作为一个流行的JavaScript库,用于构建用户界面,尤其适用于单页应用程序(SPA)。本篇将围绕React的多个关键知识点展开,帮助...

    React 官方学习模板

    "React 官方学习模板"是ReactJs官方提供的一套教程项目,旨在帮助开发者系统地学习和理解React的基本概念、API以及最佳实践。 这个模板项目,"react-tutorial-master",包含了从基础到进阶的所有教程内容,可以帮助...

    react学习.txt

    react学习资料,react入门到实战,帮助你快速掌握react。

    react 学习笔记

    本节笔记将记录 React 学习过程中的关键知识点。 一、React 组件生命周期 React 组件生命周期是指组件从创建到销毁的整个过程。生命周期方法是指在组件生命周期的不同阶段执行的函数。了解生命周期方法可以帮助...

    weiqi-react:基于React的网页围棋应用

    【标题】"weiqi-react"是一个以React技术为核心的网页围棋应用项目,旨在提供一个用户友好的在线围棋对弈平台。React是Facebook开发的JavaScript库,用于构建用户界面,特别是单页应用程序。它采用组件化的方式,...

    React学习之道

    资源名称:React 学习之道资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

Global site tag (gtag.js) - Google Analytics