无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
123
返回列表 发新帖
楼主: 不点
打印 上一主题 下一主题

js (浏览器版) 中国象棋

    [复制链接]
61#
 楼主| 发表于 2022-10-3 18:42:32 | 只看该作者
前面给出了如下测试代码:

for (let n = 1; n < 1000; n++) { let m = (n+4)*(n+3)*(n+2)*(n+1)*n; let p=m+120; console.log('真实四维锥号 n = ' + n + ', 计算得到的本锥最大元素的锥号: ' + (-2+(m+5*(m+5*m**0.6)**0.6-4*m**0.2)**0.2) + ', 计算得到的下一锥最小元素的锥号: ' + (-2+(p+5*(p+5*p**0.6)**0.6-4*p**0.2)**0.2)) ;}


从结果可以发现,下一锥的最小元素的锥号,更容易抵抗电脑计算误差。因此,我们可以改进,让现在的本锥最大编号,放在下一锥最小编号的位置。让编号不是从 1 开始,而是从 0 开始,就可以达到这个目的。

回复

使用道具 举报

62#
 楼主| 发表于 2022-10-4 15:27:37 | 只看该作者
前面我们有了求四维锥号的公式:

        t = 120 * A;

        E = Math.ceil ( -2 + (t + 5*(t+5*t**0.6)**0.6 - 4 * t**0.2)**0.2 );

这公式只是近似值,并非适用于所有的序号( A 值)。但在较小的序号之下,都是正确的。

今天,通过试验,又找到了一个类似的公式:

        t = 120 * A;

        E = Math.ceil ( -2 + t**0.2 + 1/(t**0.2) + 1/(6*t**0.6) );


这个公式的精度也很高,够我们用了。在我们的应用范围内,100% 可靠,不会有问题。这个公式的优点是,只需调用一次求根函数,剩下的只是加减乘除。上述公式在 E < 700 时都是完全可靠的。而在我们处理兵的问题中,E 值总是 < 60,所以,没问题。而且,甚至我们可以继续简化,用如下的估计式:



        E = Math.ceil ( -2 + t**0.2 + 1/(t**0.2) );

它在 E < 100 时都是完全可靠的,所以,也够我们用了。



五次方程求解的难度确实很高,这些天学了不少知识,但仍然没有获得一个通用的、100% 可靠的公式。我们前面得到的有关五次方程求解的表达式,也都是近似解,只能适用于锥号较小的情况。锥号如果增大,需要添加必要的修正项才能适应。


有鉴于求解五次方程的难度,刚才得到的简单公式,是非常理想的了,因为这个结果只需要一次求根运算,这甚至比求解三次方程的那个情况还要好。




回复

使用道具 举报

63#
 楼主| 发表于 2022-10-4 22:41:21 | 只看该作者
思考一下着法的选择。

对全部着法进行评估,按照分值的高低,对所有的着法排序。排在最前的,一般也是最好的。但由于评分并不十分准确,所以,在选择着法的时候也要留有活动的余地。首先,要决定哪些着法必须舍去。下面是一个方案。

排在最前的(得分最高的),肯定要留下。它的分值,作为基础分值,来决定其它着法的取舍。然后,看第二名的分值,如果它与第一名的差额超过 20,就舍去,或者第二名的分值小于 -9000(快要被对方将死了的情况)也要舍去。只要有一个开始舍去,后面的着法当然也全都舍去了。如果第二名留下了,再看第三名。第三名与第二名的差值,不能大于 20,而且与基础分值的差额不能超过 40。也就是说,相邻两个分值的差额不超过 20,任何一个分值都不可以与基础分值的差额超过 40。不符合条件的,全都舍去。在留下的那些着法中,随机选取一个着法,来作为正式采用的着法。第一名被选中的概率应该是最高的,最后一名被选中的概率应该是最低的。

下面是一种概率设计方案。

倒数第一名,有 1 次机会被选中。
倒数第二名,有 8 次机会被选中。
倒数第三名,有 27 次机会被选中。
倒数第四名,有 64 次机会被选中。
倒数第五名,有 125 次机会被选中。

就这样,按照立方递增规律设计。相邻两个着法被选中的概率,有一定的差别,但差别不太大。




回复

使用道具 举报

64#
 楼主| 发表于 2022-10-5 09:44:14 | 只看该作者
本帖最后由 不点 于 2022-10-6 21:28 编辑

思考一下兵的子力价值。

看到 AI 很容易弃掉自己的兵,因此,子力价值的问题,就是个不得不重新考虑的问题了。

子力价值(分值),应该分为 “基础潜力分” 和 “浮动分(奖惩分)”。通常是以奖励为主,惩罚的情况,不要太多。由于问题的复杂性,要精确设计这套逻辑,还是很困难的。

兵的潜力是能过河。过河以后,最大能力,能够控制 3 个点位。而马能控制 8 个点位。兵不能后退,而马可以满盘跑。所以,兵的基础价值,大约在马的价值的 2/8 到 3/8 之间,粗略就取 2.5/8 吧,也就是 5/16,或者也近似等于 1/3。未过河的兵,它的基础分也有这么多。如果马的基础分定为 100 分,兵的基础分至少也有 30 分那么多。当然,兵的步子属于小步,运动速度慢。马走一步到达某个位置,兵就需要 3 步才能到达那个位置。这是兵的弱点,是否应该扣分呢?这么说来,兵的基础价值再减少一些,就定为马的 1/4 吧。

中国象棋 in html5 的兵的基础价值,是马的 1/12,太少了。我调整到1/6, AI 仍然频繁弃兵。看来还得再提高兵的价值。这次就调整到马的 1/4,看看情况能否改善。



【补充】AI 弃兵的问题,也不一定是兵价值太低的原因。后来发现 AI 还会胡乱弃掉别的子力,例如,弃象、弃炮。


回复

使用道具 举报

65#
 楼主| 发表于 2022-10-5 12:31:51 | 只看该作者
士相的价值,如果以控制点位个数来看,每个士相最多控制 4 个点位,比兵多一个。但士相不能过河,防守的点位又是固定不变的。似乎士相的价值比兵小。但在防守的时候,士相的价值比兵大很多。全士相可以抵抗单车的进攻。所以,士相的基础价值,大约为车的 1/4,为马的 1/2,为(未过河)兵的两倍。
回复

使用道具 举报

66#
发表于 2022-10-5 22:47:31 | 只看该作者
JavaScript很强
回复

使用道具 举报

67#
 楼主| 发表于 2022-10-6 13:37:19 | 只看该作者
为了系数优化,昨天进行了如下测试,不断变动系数 c,使得达到最优。

for (let n = 1; n < 2400; n++) { let m = (n+4)*(n+3)*(n+2)*(n+1)*n ; let p=m+120; let c=5.4647371218604141596131285041337832808494567871093749999999999999 ; let x=(-2-n+(m**0.2)+1.0/(m**0.2))+1/(c*m**0.6); let y=(-2-n+(p**0.2)+1.0/(p**0.2))+1/(c*p**0.6); if (x >= 0 || y <= 0) console.log('出错的四维锥号 n = ' + n + ', ' + x + ', ' + y ) ;}


c 末尾 4999... 中 9 的个数无关紧要,但不可以舍入成 5000。也就是说,我已经触摸到了 js 的极限精度。打印到控制台的是出错的 n 值。第一个出错的 n = 2396。就是说,当 n < 2396 时,都是正确的。我们不需要用这个结果,但这是一个数学问题。

回复

使用道具 举报

68#
 楼主| 发表于 2022-10-6 18:36:02 | 只看该作者
这个图,黑方弃炮打相,这不是一炮换双相,而是只换了一个相,肯定不划算。这说明局面评估函数有错误。


但跟踪代码,未发现问题出在哪里。那就只好放弃这个代码了。


接下来准备切换到一楼提到的 “象棋小巫师” 来学习。


弃炮打底相,局面评估混乱.png (428.8 KB, 下载次数: 9)

黑方弃炮打底相,局面评估函数有错误,但这个错误难以跟踪。

黑方弃炮打底相,局面评估函数有错误,但这个错误难以跟踪。
回复

使用道具 举报

69#
发表于 2022-10-6 19:10:24 | 只看该作者
谢谢楼主分享中国象棋
回复

使用道具 举报

70#
 楼主| 发表于 2022-10-7 08:20:23 | 只看该作者
象棋小巫师对局面评估以后,对最佳评估的分值,还撒个随机数。这不科学。评估本身可能不准确,但撒随机数,这就是不合理的了。首先应该相信评估。撒随机数,就是不相信评估。其次,评估本身有局限性,不能做到 100% 准确。但这可以通过取前若干名“候选者”着法来确定。随机数应该撒在对那些 “较好的着法” 所作的选择上,而评估的分数,是一个重要的参考数据,能够决定该着法被选中的概率。但如果对评估的分数本身撒随机数,那就是添乱了,毫无道理可言。

下棋的时候,我发现局面对自己不利,然后悔棋。然而黑方往往会变招,而变招以后,对黑方不利了,黑方很快就输掉了。我怀疑,这就是胡乱撒随机数惹的祸。
回复

使用道具 举报

71#
发表于 2022-10-7 12:54:11 | 只看该作者

谢谢不点大师提供分享
回复

使用道具 举报

72#
 楼主| 发表于 2022-10-7 21:48:33 | 只看该作者
DRAW_VALUE 是个常数,貌似是表示 “谁也不能赢” 的 “和棋” 情况。然而,这个常数设置为 20,处于正常的局面评分范围内,会干扰局面评估的处理过程。我认为这不划算,而且这增加了复杂性,让代码难以被别人看懂。

我尝试着把这个常数修改成 Infinity,貌似没有出现异常情况。如果我理解正确的话,这个常数仅仅是个信号,并无大小的区分,也不参与加减乘除运算。所以,把它设置成任何一个不会用到的数即可。比如,设置为 0.123456789 也行,或者 3.1415926 也行。我把它设置成一个极端的 “数” Infinity,就是想确认,这个 DRAW_VALUE 常数确实就是一个信号。同时,我把那些影响局面评分的相应代码也都删除了。如果这样做被证明是可行的、没问题的话,那么,新的代码是更加优化的。
回复

使用道具 举报

73#
 楼主| 发表于 2022-10-7 22:11:15 | 只看该作者
象棋小巫师也会走弃兵的棋。就是白送一个卒给我吃,让我的兵白白过河。这说明局面评估的过程有错误。“象棋小巫师” 与 “中国象棋 in html5” 的子力价值表,竟然(几乎)完全一样。兵和士相的价值,给的都太少了。当然了,我不敢说给少了就不正确。说不定给少了是正确的。兵的蜗牛速度,比马差远了。从这个意义上来说,兵的价值确实不高。但无论如何,不该闹到随便弃兵的地步。兵的价值,不该少到让 AI 随便弃兵。
回复

使用道具 举报

74#
 楼主| 发表于 2022-10-10 15:10:51 | 只看该作者
好的,抓住了象棋小巫师的一个错误。【抓错误的时候,都是用最强的专业水平来测试的。】

这个图,黑方跳马企图避免子力损失。但红方下一步是炮打底象绝杀。这说明 AI 看不到被杀的情况,因此,“局面评估” 或者 “着法搜索代码” 肯定有错。

AI不知道下一步要被杀.png (811.96 KB, 下载次数: 10)

黑方逃马,不知道下一步红方炮打底象闷宫

黑方逃马,不知道下一步红方炮打底象闷宫
回复

使用道具 举报

75#
 楼主| 发表于 2022-10-11 20:58:04 | 只看该作者
今天找到一个好东西,开源的象棋打谱软件:

微思象棋播放器

https://www.xiaxiangqi.com/vschess/demo.html

希望我能学会它,然后就能制作出漂亮的棋谱了。
回复

使用道具 举报

76#
 楼主| 发表于 2022-10-11 21:13:51 | 只看该作者
对 “象棋小巫师”,我做了两个修改:

1、去除撒随机数的代码,让程序总是选取最优的着法。
2、去掉了棋谱数据库 book_dat。

目的是尽量暴露出算法本身的毛病,以便能够改进算法。

做了这两项改动之后,发现我不那么容易打败它了!如果反复悔棋,总能找到它的弱点并打败它。但如果不悔棋的话,就不那么容易了。

所以,我猜测,撒随机数的代码,是一个漏洞,或者说就是一个错误。另一个猜测是,book_dat 数据库的处理过程中,可能有错,导致 AI 下出明显不正确的着法。
回复

使用道具 举报

77#
 楼主| 发表于 2022-10-14 01:34:46 | 只看该作者
这个图,黑车守6路,导致速败。下一步,红车八平六,黑士6进5,红车三进二,成必杀之势,红胜。


黑车如改守4路,红方的攻势被化解,而黑方有过河卒,反而要赢。


这说明,AI 的局面评估有毛病,需要改进。

平车6路导致速败,应占据4路才对.png (475.08 KB, 下载次数: 5)

黑车应保4路士,而不是守6路。

黑车应保4路士,而不是守6路。
回复

使用道具 举报

78#
 楼主| 发表于 2022-10-16 19:01:04 | 只看该作者
象棋小巫师,当我把电脑思考时间调高至 2000 毫秒时,它再也不会犯上一帖所说的错误了。

但它还会送卒给我吃,这样,它吃了卒的亏以后,还是容易输掉。

所以,兵卒价值给得太低,可能是一个实实在在的错误。猜测,把子力价值调整以后,它的棋力会有提高。
回复

使用道具 举报

79#
 楼主| 发表于 2022-10-17 00:12:15 | 只看该作者
把未过河兵的价值从 7 提高到 21 以后,AI 在开局阶段,就用炮打我的兵。

只把兵的价值提高到 14,它也打我的兵,但打得不那么频繁了。

好像难以两全:兵的价值如果太低,AI 会胡乱弃兵。兵的价值太高,AI 又会在开局阶段就用炮打兵。

但兵的价值定为马的四分之一,我觉得还是合理的。兵过河的话,其价值应该就是马的二分之一了。

至于说开局阶段,炮随便打兵,这个问题可以再想别的办法来解决。


比如说,把棋局分为“开局”、“中局”、“残局”三个阶段,开局阶段,兵的价值设定为一个较低的值,中局以后,就把兵的价值恢复到正常值。同理,这三个阶段,马和炮的价值,也在发生变化,因此也应该适当调整马和炮的价值。



这些“价值”,都是一个粗略的概念,有一定的模糊性。而增加 “开局”、“中局”、“残局”的区别对待,则属于“动态微调”的改进尝试。





回复

使用道具 举报

80#
 楼主| 发表于 2022-10-19 17:53:09 | 只看该作者
我昨天把 “象棋小巫师” 修改版上传到 18 楼了。是一个临时的测试版。我修改了啥?

1、(未过河)兵的价值从 7 提高到 21,过河兵的价值也有一些提升。

2、士相的价值也加倍。

我的修改,并不一定合理。

现在,AI 不再随便弃兵、弃士相了。但矫枉过正,现在它却乐意去吃对手的兵和士相。

我知道随便去贪吃对手的棋子不好,但是我竟然下不过它了!开局它就想办法吃我的兵。我让它吃,心想,它会很快输掉的。但我水平太差,很难赢它,即使赢,也是反复悔棋,等待它出错后才赢的。赢得十分艰难。

“象棋小巫师”,在基础逻辑方面,至今没有发现错误。这一点,比 “中国象棋 in html5” 强很多。
回复

使用道具 举报

81#
 楼主| 发表于 2022-10-20 17:44:21 | 只看该作者
记录一下我对于 “绘制棋盘” 的思考。在 “象棋小巫师” 中,棋盘是一个背景图片。这个图片有几十 KB 那么大。因此,我考虑用 html、css 和 js 手段来实现棋盘。网上也能找到画棋盘的 css 代码,不过,并不特别理想。比如,用 linear-gradient 来画背景图,这 linear-gradient 就只支持较新的浏览器,所以,这会限制浏览器,是个缺点。再比如,用 canvas 来画图,这也是 html5 的新功能,不支持旧浏览器。

现在我正考虑一种完全兼容各种浏览器的方案:用 html 元素的可重叠性,来实现一个棋盘。
回复

使用道具 举报

82#
 楼主| 发表于 2022-10-20 20:17:32 | 只看该作者
本帖最后由 不点 于 2022-10-21 13:29 编辑

记录一下备忘。这个知识很重要:

html 中给表格添加斜线
https://www.lmlphp.com/user/60160/article/item/614543/


有了这个知识,就可以画九宫中的米字格了。棋盘的其它部分,用 table 来实现。这样的话,兼容性杠杠的。更正:这个方案使用了 transform,这是浏览器新特性,不具有兼容性。

回复

使用道具 举报

83#
 楼主| 发表于 2022-10-20 20:35:42 | 只看该作者
本帖最后由 不点 于 2022-10-21 13:26 编辑

这三个 unicode 字符,配合表格,也可以用来画斜线。

╱      U+2571
╲      U+2572
╳      U+2573

这种方法,说不定还更简单一些呢。当然了,字体的大小,不容易与表格完美匹配。而上一帖中的方法,应该算是一个终极的解决方案了,适应性较强。


更正:楼上的 transform 方案也是浏览器新特性,不具有兼容性。而本帖中的斜线字符,如果字体变大或变小,它的粗细也会相应变化。所以说这个方案,尽管不存在兼容性问题,也只能算是凑合。




回复

使用道具 举报

84#
 楼主| 发表于 2022-10-22 12:58:43 | 只看该作者
为了画棋盘,折腾了好几天。

首先,上网搜索 “html 画斜线”,有一篇文章说,传统(旧)的 html 规范不支持画斜线。

于是,搜 “html 画三角形”。这次运气不错,有办法。利用 html 对于矩形角部边界的处理,画出三角形。就是说,不使用任何 html 新功能,只要使用 border 的这一特性,就可以画出三角形。

既然能画出三角形,也就能画出斜线。用一个小三角形把大三角形盖住,只留下斜线,这就成功了。但这需要用到 html 的 z-index。貌似这是被各种浏览器支持的。不过,上个世纪的浏览器是否支持 z-index,也不好说。目前就看这个 z-index 的兼容性如何了。


18 楼上传了最新的改动。有兴趣者,可以试试,看有哪些浏览器不支持这种 css 画棋盘的方法。

回复

使用道具 举报

85#
 楼主| 发表于 2022-10-22 18:44:36 | 只看该作者
确实有兼容性问题。幸运的是,兼容性问题不是出在画斜线(三角形)的问题上,而是出在别的方面,比如,表格的特性。为了最大限度保持兼容性,下一步准备删除 table,而只用 div 来实现。

另外,这个象棋,运行在老机器上,由于机器运算能力弱,导致 AI 也很弱,没有多大的意思。所以,不打算支持 XP 以前的电脑。而在 XP 上,也不打算支持旧的 IE 6/7,而只打算支持最新的 IE 8。当然,火狐以及 chrome 都是要尽量给以支持的。
回复

使用道具 举报

86#
 楼主| 发表于 2022-10-24 15:00:11 | 只看该作者
这两天尝试删除 table 而用 div 来实现。结果大失所望!div 和 span 竟然也出妖蛾子!

在 IE 8 中,div 的 inline-block 就跟 block 完全一样。而如果设置为 inline,则与 span 又完全一样了,其 width 的表现,与 firefox 中的表现是完全不一样的,因此竟然没法兼顾 firefox 和 IE 了!

尽管 table 也有妖娥子,但还可以挽救,通过努力、努力、再努力,找到了一个兼容 IE 8 和火狐的方案。所以,最终还是回到了 table 上。

新代码上载在 18 楼了。
回复

使用道具 举报

87#
 楼主| 发表于 2022-10-28 10:39:57 | 只看该作者
本帖最后由 不点 于 2022-10-29 13:22 编辑

画棋盘的事还没完,其复杂程度,超乎想象。定义 border 的粗细,不同浏览器,结果不一样。而且,单元格同样都是那么宽,可是不同浏览器显示的实际宽度却有微调。这就麻烦了,单元格的宽度不一致,画出的网格线,有的粗,有的细。好不容易让网格线均匀了,但配合画三角形(斜线),又产生了新的问题。最后的结果是,用 table 也失败了!如果不计较粗细不均的现象,则很多方法都行,都算成功。但那该是多么 “低标准” 的成功啊!无异于失败。

最后,又回到了用 div 的路子上了,期望单一的 div 不会带来不兼容。

然而,想不到的是,单一 div 在不同浏览器下的表现也不同!ie 8 把 border 算在 width 和 height 以内,而火狐却把 border 放在 width 和 height 之外!应付这个差异,又得想办法!


2022-10-29:办法有了。只用 div 的上边框和左边框,不用下边框和右边框,这样就可以在各种浏览器下做到兼容(一致)了。目前这个方案,支持 ie8 和火狐,我猜很可能会支持所有 WinXP 以后开发出来的浏览器。WinXP 上的默认浏览器是 IE 6,应该也能支持。IE 5 有可能不支持,也有可能支持(估计现在大家很难有条件去验证了)。最新改动已经上载在 18 楼了。

回复

使用道具 举报

88#
发表于 2022-10-29 10:34:39 | 只看该作者
大师要开发象棋软件?

点评

年岁高了,记忆力差,精力不旺盛,再加上本来只是一个电脑业余爱好者,也就搞不动操作系统之类的大玩艺了。更重要的是,心态变了,感觉整个世界面临危险,技术发展得越快,世界就毁灭得越快。因此,对那些所谓操作系  详情 回复 发表于 2022-10-29 13:10
回复

使用道具 举报

89#
 楼主| 发表于 2022-10-29 13:10:54 | 只看该作者
linux爱好者 发表于 2022-10-29 10:34
大师要开发象棋软件?

年岁高了,记忆力差,精力不旺盛,再加上本来只是一个电脑业余爱好者,也就搞不动操作系统之类的大玩艺了。更重要的是,心态变了,感觉整个世界面临危险,技术发展得越快,世界就毁灭得越快。因此,对那些所谓操作系统、CPU 等 “核心技术”,已经失去热情了。就让那些能够控制核武器的人去搞这些好了,我就吃瓜了,我就打酱油了。

不是开发象棋软件,是学习,是修补和完善,是做脑保健操,不让脑子彻底萎缩。
回复

使用道具 举报

90#
 楼主| 发表于 2022-11-1 21:17:28 | 只看该作者
关于画棋盘,前面说,用 div 的上边框和左边框,避免使用 width 和 height,这样来保持兼容性。这个方案居然也失败了!问题出在哪儿呢?问题出在:画九宫里面的斜线时,直角边的粗细,在不同浏览器下不一样,导致九宫里面的横竖线与九宫外面的横竖线粗细不一样,很难看。于是,只好放弃使用边框,而改用画三角形这一个办法,来构成棋盘。这已经是逼上梁山、没有退路、只此一招了。下面这个图片,展示了这种画法。到目前为止,这是兼容性最好的方法了,在我测试的几个浏览器下,都成功了。


统一使用三角形,其好处是,算法一致,这样,“边框”的粗细能够保持恒定。“边框”就是两个相邻三角形之间留出的缝隙。不同浏览器下 “边框”的粗细是不同的。但在任意一个 “当前” 浏览器下,边框的粗细是一样的,这就基本算是完美解决了。

用三角形画棋盘.png (12.63 KB, 下载次数: 3)

统一使用三角形, 算法一致,兼容性强

统一使用三角形, 算法一致,兼容性强
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2025-12-12 04:29

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表