`
CharlesCui
  • 浏览: 427495 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

公司一个大师用JS写的围棋

阅读更多
珍珑棋局,200行代码。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> 
    <title>禅棋传说</title> 
    <style type="text/css"> 
        div { position: absolute; width: 23px; height: 23px; }
        .B0 { background-image: url('B0.gif'); }
        .B1 { background-image: url('B1.gif'); }
        .B2 { background-image: url('B2.gif'); }
        .B3 { background-image: url('B3.gif'); }
        .B4 { background-image: url('B4.gif'); }
        .B5 { background-image: url('B5.gif'); }
        .B6 { background-image: url('B6.gif'); }
        .B7 { background-image: url('B7.gif'); }
        .B8 { background-image: url('B8.gif'); }
        .BX { background-image: url('BX.gif'); }
        .D0 { background-image: url('D0.gif'); }
        .D1 { background-image: url('D1.gif'); }
        .C0 { background-image: url('C0.gif'); }
        .C1 { background-image: url('C1.gif'); }
    </style> 
</head> 
<body> 
    <script type="text/javascript"> 
    //<![CDATA[      
        Array.prototype.indexOf = function (item)   //给数组扩展一个indexOf方法
        {
            for ( var i=0; i<this.length; i++)
                if (this[i] == item)
                    return i;
            return -1;
        };
    
        var Site =  //定义一个棋位类
        {
            Create: function(x, y)  //棋位类的构造函数
            {
                var me = document.createElement("div"); //建一个div对象,将其扩展并封装成棋位。
                document.body.appendChild(me);  //附加到DOM树,实现棋位的呈现。
                me.x = x;   //记录棋位的X坐标
                me.y = y;   //记录棋位的Y坐标
                me.style.left = x * 23 + "px";  //设置棋位水平方向的绝对位置
                me.style.top = y * 23 + "px";   //设置棋位垂直方向的绝对位置
                var s = ((x-9)%9?0:(x-9)/9)+1+(((y-9)%9?0:(y-9)/9)+1)*3;    //计算并背景式样
                me._backStyle = "B" + ((s==4&&(x/3)%2==1&&(y/3)%2==1) ? "X" : s);
                me.Fill = this.Fill;    //关联一个填充棋位的方法。
                me.Tight = this.Tight;  //关联计算紧气方法。
                me.Kill = this.Kill;    //关联计算死子方法。
                me.onclick = this.Play; //绑定onclick事件到Play方法。
                me.Fill();  //初始填充空子。
                return me;  //返回棋位对象,其实是一个封装了的div对象。
            },
            Fill: function(dot, going)     //填充棋子的方法
            {
                if ( dot == undefined )
                    this.className = this._backStyle    //无子,就设置为背景式样。
                else
                    this.className = (going ? "C" : "D") + dot;
                this.dot = dot;     //保存棋子状态
            },            
            Play: function()    //行棋方法,由onclick事件触发
            {
                if ( this.dot == undefined ) //无子
                {
                    var deads = this.Kill(current^1);   //计算可以杀死的子
                    if (deads.length == 1 && this == rob) return; //打劫状态
                    for(var i=0; i<deads.length; i++)
                        deads[i].Fill();
                    if(i==1)
                        rob = deads[0]  //记录打劫位置
                    else if (i>0 || !this.Tight(current))
                        rob = null  //清打劫位
                    else return;
                    sound.play();       //落子有声!
                    var step = Tracks[Tracks.length-1];
                    if(step) step.site.Fill(step.site.dot);
                    this.Fill(current, true); //填入当前该填的子
                    Tracks.push( new Step(this, deads) );
                    current ^= 1;       //用1来异或,正好反转黑白棋子。
                };
            },
            Tight: function (dot)   //计算紧气的块
            {
                var life = this.dot == undefined ? this : undefined; //当前位无子则算一口气
                dot = dot == undefined ? this.dot : dot;
                if (dot == undefined) return undefined;
                var block = this.dot == undefined ? [] : [this];
                var i = this.dot == undefined ? 0 : 1;
                var site = this;
                while (true)
                {
                    for(var dx=-1;dx<=1;dx++) for(var dy=-1;dy<=1;dy++) if(!dx^!dy)
                    {
                        link = GetSite(site.x + dx, site.y + dy);
                        if (link)   //有位
                            if (link.dot != undefined)  //有子
                            {
                                if (link.dot == dot && block.indexOf(link) < 0 )
                                    block.push(link);
                            }
                            else if (!life)
                                life = link
                            else if (life != link)
                                return undefined;   //如果有两口气以上则无须再算
                    };
                    if ( i >= block.length) break;
                    site = block[i];
                    i ++;
                };
                return block;   //返回只有一口气的块
            },
            Kill: function(dot)     //计算杀死的子
            {
                var deads = [];
                for(var dx=-1;dx<=1;dx++) for(var dy=-1;dy<=1;dy++) if(!dx^!dy)
                {
                    var site = GetSite(this.x + dx, this.y + dy);
                    if (site && (site.dot == dot))
                    {
                        var block = site.Tight();
                        if (block) deads = deads.concat(block);
                    };
                };
                return deads;   //返回可以提子的死子块
            }
        };
 
        var Board = new Array(19);  //全局的Board数组,表示棋盘。
        var Tracks = [];    //行棋线索数组,数组元素是Step对象。
        var current = 0;    //当前要下的子,0表示黑子,1表示白子,互相交替。
        var rob = null;     //如果有打劫时,记录打劫位置。
        for(var x = 0 ; x < 19; x++)
        {
            Board[x] = new Array(19);
            for(var y = 0; y < 19; y++)
                Board[x][y] = Site.Create(x, y);    //按位置创建棋位对象。
        };
        if (navigator.userAgent.indexOf(' MSIE ') > -1) //为IE浏览器构造声音对象
        {
            var sound = document.body.appendChild(document.createElement("bgsound"));
            sound.play = function(){this.src = "play.wav"};
        }
        else    //为Firefox等其他浏览器构造声音对象
        {
            var sound = document.body.appendChild(document.createElement("span"));
            sound.play = function(){this.innerHTML = "<bgsound src='play.wav'>"};
        };
        document.body.oncontextmenu = function()     //悔棋事件
        {
            var step = Tracks.pop();
            if (step)
            {
                step.site.Fill();
                for (var i=0; i<step.deads.length; i++)
                    step.deads[i].Fill(current);
                step = Tracks[Tracks.length-1];
                if (step) step.site.Fill(current, true)
                current ^= 1;       //反转黑白棋子。
            };
            return false;   //不弹出菜单。
        };
 
        function GetSite(x, y)  //从棋盘取棋位的函数,越界不抛出异常。
        {
            if (x>=0 && x<19 && y>=0 && y<19)
                return Board[x][y];
        };
        function Step(site, deads)   //棋步类,记录每一步棋的状态
        {
            this.site = site;   //记录棋步的位置
            this.deads = deads; //记录被当前棋步杀死的棋子集合
        };
 
        document.onkeypress = function(event)
        {
            var k = (window.event ? window.event.keyCode : event.which) - 49;
            if(k<0 || k>1) return;
            for(var x=0; x<19; x++) for(var y=0; y<19; y++) Board[x][y].Fill();
            Tracks.length = 0;
            current = 0;
            with(goes[k]) for(var i=0; i<length;i+=3)
                Board[charCodeAt(i+1)-65][charCodeAt(i)-65].Fill(charCodeAt(i+2)-48);
        };
var goes= ["AA0AB0AC1AE0AF1AG1AI0BA0BC1BE0BF0BG1BI0BK1CA1CB1CC1CD0CF0CG1CI0CK1\
DA0DB0DC0DD0DE0DF0DG1DH1DI0DJ0DK1EC1ED1EE1EF1EH1EK1FA1FB1FC1FE0FF1FG1FH1FI0FJ0\
FK1GA1GB0GC1GE0GF0GG0GG0GH0GI0GJ1HA0HB0HC0HD0HE0HI1HJ1IB1IF1JC1JE1JG1",
"AA0AB0AC0AF1AG1AH0AI0AJ0AK1AM0AO0AP0AR0AS0BA0BB0BF1BG1BJ0BK0BL1BM0BR0BS0CA0CB1\
CC0CD0CG0CH0CI1CJ0CK0CL1CM0CO1CP0CQ0CR1CS0DA1DB1DC0DD0DE1DF1DH1DI0DJ1DK1DL0DN0\
DP1DQ1DR1DS0EB0ED1EE0EG1EI0EK0EM0EO1ER0ES1FB0FC1FE0FF0FG1FN1FP0FR0GA0GF1GH0GJ0\
GL0GR0GS0HC0HD0HF0HI0HK0HM0HN1HP0HQ0HR1IA0IB0IC1ID0IE1IK0IL1IM0IQ1IR0IS0JA0JB0\
JC1JE1JG1JI0JJ1JK1JL0JM1JN1JO0JQ1JR0JS0KA1KC1KD1KE0KG0KI1KJ0KK0KL0KM0KN0KO1KQ0\
KR0KS0LD0LE1LI0LJ1LL0LN1LO0LP0LQ1LR0LS0MD0MG0MI0MJ0MK0ML1MM0MN1MR1MS0NC0NF0NL1\
NO0NQ0NR0NS1OB0OC0OG0OL1OO0PA1PB1PC0PD0PI0PJ0PK0PL1PM0PN0PR0QA0QC1QD0QE1QF1QG1\
QH1QK1QP0RA0RB0RC0RD1RE1RF0RG0RH1RI0RL0SA0SB0SC0SD0SE0SF0SG0SH0SI1SJ1"];
    //]]>
    </script> 
</body> 
</html>







附源码

JS对我的工作来说几乎无用,但我很喜欢这个看似简单其实很复杂的小东西,所以有机会就会把大师的作品来过来,读一读,学一学,挺有意思的一个围棋,200行代码都不到。
  • 大小: 26.7 KB
  • 大小: 29.9 KB
  • go.zip (10.2 KB)
  • 下载次数: 88
分享到:
评论

相关推荐

    html+js实现围棋棋盘

    创建一个围棋棋盘的HTML页面,我们需要一个容器元素来承载棋盘,比如一个`&lt;div&gt;`元素,我们可以将其id设为"棋盘",以便在JavaScript中引用: ```html &lt;!DOCTYPE html&gt; 围棋棋盘 棋盘"&gt; ...

    一个使用UDP协议写的围棋

    标题中的“一个使用UDP协议写的围棋”表明这是一个基于UDP(User Datagram Protocol)网络通信协议实现的围棋应用程序。UDP是传输层的一种协议,以其快速、无连接的特点被广泛应用于实时数据交换,如在线游戏、视频...

    围棋知识,写围棋程序参考

    围棋知识,写围棋程序参考

    自己写的一个围棋程序

    标题中的“自己写的一个围棋程序”表明这是一个个人开发的围棋对弈软件,它允许玩家在网络上进行对局。从描述中我们可以推断出该程序具备以下关键功能和特点: 1. **网络对弈**:程序提供了在线对弈的功能,使得...

    grid+svg+js实现简单的围棋棋盘

    在本文中,我们将深入探讨如何使用CSS Grid布局、SVG、JavaScript以及HTML来创建一个功能完备的围棋棋盘。首先,让我们逐一了解这些技术的核心概念。 **CSS Grid布局** 是一种二维布局系统,允许我们轻松地定义网页...

    一个围棋程序

    标题中的“一个围棋程序”指的是一个专门用于玩围棋的计算机软件。这个程序可能是为了帮助用户学习围棋策略,模拟对弈,或者提供一个平台让玩家在线对战。围棋是一种源自中国的古老棋类游戏,以其深邃的策略性和无尽...

    JavaScript小游戏 类似围棋游戏

    JavaScript小游戏 类似围棋游戏 JavaScript小游戏 类似围棋游戏

    围棋入门一月通 围棋

    总的来说,"围棋入门一月通"是一本适合围棋新手的教材,它将带你走过围棋世界的大门,让你在短短一个月内建立起坚实的围棋基础。通过系统学习和不断的实践,你会发现围棋不仅仅是一种游戏,更是一种生活的艺术和智慧...

    用Swift写围棋App.zip

    在本项目"用Swift写围棋App.zip"中,开发者创建了一个开源的iOS应用程序,名为GoTao,它允许用户阅读和玩围棋游戏。这个项目基于Swift编程语言,苹果公司的主要开发语言,为iOS平台提供了丰富的功能和良好的性能。...

    [纯C语言 + Win32 API]一步一步写个围棋程序之十二:增加围棋规则

    在本教程中,我们将深入探讨如何使用纯C语言和Win32 API来编写一个围棋程序,并专注于第十二个阶段——增加围棋的规则。这个过程涵盖了编程基础、图形用户界面(GUI)设计以及游戏逻辑的实现。 首先,让我们理解Win...

    javascript 围棋游戏

    标题中的“javascript 围棋游戏”表明我们要讨论的是一个基于JavaScript技术实现的围棋游戏项目。JavaScript是一种广泛应用于网页和网络应用开发的编程语言,尤其在客户端的交互式内容上表现突出。围棋是一种策略性...

    VC++ 围棋源代码

    1. **数据结构**:围棋盘通常用二维数组或矩阵表示,每个元素代表棋盘上的一个位置。黑白棋子的状态可以用整数或布尔值来表示。 2. **算法设计**:围棋的智能通常依赖于搜索算法,如Alpha-Beta剪枝,它是Minimax...

    围棋 助手 一个很好的围棋打谱软件

    围棋 助手 一个很好的围棋打谱软件围棋 助手 一个很好的围棋打谱软件围棋 助手 一个很好的围棋打谱软件围棋 助手 一个很好的围棋打谱软件围棋 助手 一个很好的围棋打谱软件围棋 助手 一个很好的围棋打谱软件围棋 ...

    Javascript围棋(含行棋路线)

    9. **禅棋传说**:这是李战在书中创造的一个概念,可能是指通过编写围棋游戏,让读者在实践中理解JavaScript的深度和魅力,体验编程的乐趣,同时学习到围棋的智慧。 10. **学习资源**:这本书提供了一个实际的项目...

    围棋AI软件源码,前端Electron + Vue,后端Python+torch.zip

    围棋AI软件源码,前端Electron + Vue,后端Python+torch,利用卷积神经网络和强化学习,提供一个强大的围棋引擎。 围棋AI软件源码,前端Electron + Vue,后端Python+torch,利用卷积神经网络和强化学习,提供一个...

    网上围棋单机版

    总的来说,这个项目提供了一个很好的学习机会,可以帮助开发者深入理解JavaScript编程、SVG图形绘制以及如何设计和实现一个分层的软件架构。无论是对围棋游戏有兴趣,还是想要提升前端开发技能,都可以从这个项目中...

    一个用vb编写的简单的围棋程序

    【标题】"一个用vb编写的简单的围棋程序"揭示了这个项目的核心——它是一个使用Visual Basic(VB)编程语言开发的简易围棋应用。VB是微软公司推出的一种面向对象的编程工具,尤其适合初学者和快速原型开发。在这个...

    围棋应用程序,用C++写的

    围棋应用程序原码,是用C++写的,请各位指教!

    Unity开发围棋源码(04是围棋)_unity围棋_围棋_Unity围棋

    本项目是一个基于Unity的围棋游戏源码,主要亮点在于实现了围棋的提子算法,这对于游戏逻辑的正确性和用户体验至关重要。 首先,我们需要理解围棋的基本规则。围棋是一种双人对弈的策略棋类游戏,棋盘为19x19的格子...

Global site tag (gtag.js) - Google Analytics