自制带得分和推荐走法的象棋视频

news/2025/10/7 16:28:37/文章来源:https://www.cnblogs.com/funwithwords/p/19128597

① 到东萍象棋网可以下载许多棋谱。我用程序下载了1万多个推荐的,grep -v (--invert-match)去掉了和棋的,还有6813个。bash+wget干的,python的连不通(要送user-agent?)

pu.txt 6813行,形如:

河北金环建设象棋队-申鹏-胜-山东省棋牌运动管理中心-张瑞峰=694712321927102226250010091972427967706289798070777362817343

用Python按走法长度升序,用了dict,长度做key和sorted(keys),setdefault(k, []).append(...)

② ffmpeg把一系列bmp压缩成mp4,几十步棋才几十到数百KB,KB, KB. /dev/shm是内存,不担心SSD磨损。总之这事可干,就是CPU风扇时不时会响。引擎是从象棋巫师ElephantEye的改来的,在Intel N100上每秒600万节点,中国象棋云库查询是0.98几,单位是G。

ee.py

from subprocess import Popen, PIPEclass EleEye(Popen):BM = 'bestmove'def __init__(m): Popen.__init__(m, 'eemod', stdin=PIPE, stdout=PIPE, text=True)def send(m, s): m.stdin.write(s + '\n'); m.stdin.flush()def recv(m):out = ''while True:s = m.stdout.readline()out += s.replace('info ', '')if s.find(m.BM) != -1: return outdef get_score(m, f):m.send('position fen ' + f + '\ngo')n = -900; fx = fy = tx = ty = -1while True:s = m.stdout.readline()i = s.find('score ')if i != -1:i += 6j = s.find(' ', i)n = int(s[i:j]) # j=-1: oki = s.find(m.BM)if i != -1:if i != 0: break # nobestmove# b0c2fx = ord(s[9]) - ord('a')tx = ord(s[11]) - ord('a')fy = ord('9') - ord(s[10])ty = ord('9') - ord(s[12])breakif n > 900: n = 900elif n < -900: n = -900return n,fx,fy,tx,tyee = EleEye()
View Code

img.py

#! /usr/bin/python3from PIL import Image as I, ImageDraw, ImageFont #, ImageFilterdef get_circle_img(i):img = I.new('RGBA', (144,144), (255,255,255,0)) # no LAd = ImageDraw.Draw(img)f = (255,255,255,255) if i else (0,0,0,255)d.ellipse((0,0,132,132), fill=f, outline=(68,68,68,255), width=8)return img.resize((36,36), I.LANCZOS)#return img.filter(ImageFilter.GaussianBlur(radius=1))

red = get_circle_img(1); hei = get_circle_img(0)FNT = '/usr/local/share/fonts/汉/汉仪旗黑.ttf'
fnt = ImageFont.truetype(FNT, 20)
fnt2 = ImageFont.truetype(FNT, 14)dic = {"r":"", "n":"", "c":"", "b":"", "B":"", "a":"", "A":"", "k":"", "K":"", "p":"", "P":""}
dic['R'] = dic['r']; dic['N'] = dic['n']; dic['C'] = dic['c']jpg = I.open('brd.jpg')def fen2img (f, nm, str=None):if nm.find('bmp') == -1:S = 40; L = 6; T = 4brd = I.new('L', (368,400), 255)bmp = Falseelse:S = 40; L = 6; T = 32brd = I.new('L', (368,432), 255)bmp = Truebrd.paste(jpg, (L,T-4))id = ImageDraw.Draw(brd)#id.rectangle([(0, 408), (432, 800)], fill='blue')def draw(c, x, y):if c.isupper(): img = red; tc=0else: img = hei; tc=255brd.paste(img, (x,y), mask=img.split()[-1])id.text((x+6,y+4), dic[c], font=fnt, fill=tc)f = f.split('/')b = [[' '] * 9 for i in range(10)]for y in range(10):x = 0for i in range(len(f[y])):c = f[y][i]j = ord(c) - ord('0')if j >= 1 and j <= 9: x += jelse:draw(c, L+x*S, T+y*S); b[y][x] = c; x += 1if str != None:bb = fnt2.getbbox(str)id.text(((brd.size[0]-bb[2]+bb[0])/2, 5), str, font=fnt2, fill=0)if not bmp: brd = brd.resize((736,800), I.NEAREST)brd.save(nm, compress_level=9) # smaller than jpegif __name__ == '__main__':import sysif 'cover' in sys.argv:brd = I.new('L', (1920,1080), 255)brd.save('cover.png', compress_level=9)else: fen2img(input().replace(' ', ''), '/t/fen.png')
View Code

pu.py

#! /usr/bin/python3
from ee import *
from img import *def fen2brd ():global ba = f.split('/')for y in range(10):x = 0for i in range(len(a[y])):c = a[y][i]j = ord(c) - ord('0')if j >= 1 and j <= 9: x += jelse: b[y][x] = c; x += 1def brd2fen ():global ff = ''for y in range(10):n = 0for x in range(9):c = b[y][x]if c == ' ': n += 1else:if n: f += str(n)f += c; n = 0if n: f += str(n)if y != 9: f += '/'return fdef mv2str (fx, fy, tx, ty):if fx < 0: return Noned = abs(fy - ty)c = b[fy][fx]; red = c < 'a'm = p[c]x = "九八七六五四三二一" if red else "123456789"m += x[fx]if fy == ty: m += "" + x[tx]else:m += "" if red == (fy > ty) else "退"if   c in "RCPK": m += "零一二三四五六七八九"[d]elif c in "rcpk": m += "0123456789"[d]else: m += x[tx]return mp = {"r":"", "n":"", "c":"", "b":"", "B":"","a":"", "A":"", "k":"", "K":"", "p":"", "P":""}
p['R'] = p['r']; p['N'] = p['n']; p['C'] = p['c']
b = [[' '] * 9 for i in range(10)]
f = 'rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR'; fen2brd()# 开局,go 1500 7分,300 4分,bm都是兵七进一。这个分是假设走了bm.
# 若实际帅五进一呢?应该用黑分如17。红走棋后,考虑黑方的最佳应对。
a = [4]; bms = ['兵七进一']; n = 1
s = input().split('=')[1]
for i in range(0, len(s), 4):# 处理(红)实际走法fx,fy,tx,ty = int(s[i]), int(s[i+1]), int(s[i+2]), int(s[i+3])m = mv2str(fx,fy,tx,ty)b[ty][tx] = b[fy][fx]; b[fy][fx] = ' ' # 不能放在mv2str前# 处理(黑)r,fx,fy,tx,ty = ee.get_score(brd2fen() + (' b' if n % 2 else ' w'))# brd2fen() modifies f
  a.append(r); bms.append(mv2str(fx,fy,tx,ty))##bm = bms[-2]if bm and m != bm: m += '_' + bmif n % 2: print(f'{n // 2 + 1}. {m}', end=' ')else: print(m, flush=True)##fen2img(f, f'/t/{n:02d}.bmp', m + ('' if n % 2 else '') + str(r))n += 1exit()fen2img(f, '/t/t.png')import matplotlib.pyplot as plt
#import numpy as np
plt.figure(figsize=(8, 6), dpi=72)
x = a[::2]
plt.plot(x, color='#FF0000', linewidth=1)
plt.plot(a[1::2], color='#000000', linewidth=1)
plt.xticks(rotation=45)
n = len(x)
plt.xticks(ticks=list(range(n)), labels=list(range(1, n+1)))  # 下标+1作为刻度
#plt.xticks(ticks=np.arange(len(x)), labels=np.arange(1, len(x)+1))
#plt.axis('off')

plt.savefig('/t/score.png', bbox_inches='tight', pil_kwargs={'compress_level':9})
#plt.show()
View Code

pu

# pu.htm里无对手信息; move用3字符编码if [[ $# -lt 1 ]]; then exit; fin=$1 # n=$(expr $1 + 10)
p=`sed -n ${n}p pu.txt`echo $p | xclip -f -selection clipboardif [[ $# -eq 1 ]]; then    exit; fiecho 'Pressing Enter will rm -f /t/*'
read
rm -f /t/*t=/t/t.txt
echo $p >$t
echo $p | pu.py | tee -a $t
echocd /t
v=t.mp4
ffmpeg -framerate 0.5 -i %02d.bmp -r 8 -vf format=gray,format=yuv420p -c:v h264 -b:v 100k -preset fast -loglevel 0 $v
rm -f *.bmp
#ls -lh $v | awk '{print $5}' >>$t
#cp ~/xq/cover.png .
cd - >/dev/null#kwrite $t 2>/dev/null &
View Code

视频

分辨率为368x432,都是16的倍数。除了VLC播放时会截去下面一块,ffplay,手机等都没事。在海信A5这样的墨水屏手机上,视频播放器默认背景也是大白纸,一点都不闪,真是“纸上的东西动起来了”。

0e791cfbd5264a9086da32c0ff943aed~tplv-obj_720_1041

手抖拍糊了。黑边为手机实际边框。

man ffplay, While playing, q/Esc quit; p/Space pause

VLC 3.0.21 Vetinari, debian 6.1.0-18-amd64, Intel N100,播576x432的也截(4:3, 都是16的倍数)。未排除是硬件解码器的问题。

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

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

相关文章

装修网站是怎么建设的排名检测

刚开始学create table的时候没注意&#xff0c;学到后面发现可以指定默认值。于是写了如下语句&#xff1a; 当我查询的时候发现&#xff0c;查出来的结果是这样的。。 很纳闷有没有&#xff0c;我明明指定默认值了呀&#xff0c;为什么创建出来的表还是空的呢&#xff1f;又跑…

慈溪企业排名网站怎么做点击图片跳转网站

背景 Prompt flow和LangChain都是LLM时代&#xff0c;为高效地构建LLM应用而生。 Prompt flow是Microsoft开源的&#xff0c;其诞生时&#xff0c;LangChain已经很有名气了。 所以作为后生的Prompt flow会为我们带来哪些新的东西呢&#xff1f; ​​​​​​​ Prompt flo…

C++ list数据删除、list资料访问、list反转链表、list数据排序

C++ list数据删除、list资料访问、list反转链表、list数据排序pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Con…

DP分析黑科技——闫氏DP分析法

(前置:没有在百度百科上找到,查了一下这种方法是由英国经济学家埃拉闫提出的(真DP起源于经济学)) 核心思想:从集合角度分析DP问题 在我们遇到的DP问题中,一般都是求在一个有限集内的最值,但是这些方案数量一般…

MUGEN游戏引擎等一系列相关杂谈

MUGEN游戏引擎等一系列相关杂谈也许是个相当没有质量的文章,或者说时定位错了 后面看情况出个整合包之类的吧...... 因此久违的想玩玩格斗游戏了,最好是那种全明星阵容打乱斗的 网上找了找,除了幻想印章,以外还有几…

龙岗网站建设公司河南头条最新消息 新闻

STM32 Proteus仿真LCD12864俄罗斯方块-FZ0063 Proteus仿真小实验&#xff1a; STM32 Proteus仿真LCD12864俄罗斯方块-FZ0063 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 LCD12864显示器多个按键 1.标准俄罗斯方块经典游戏玩法&#xff0c;带计时&#xff0c…

门户网站的含义做淘宝详情页好的网站

.NET 8 是微软于2021年8月24日宣布的下一代编程语言和框架&#xff0c;它是 .NET 宇宙的一部分&#xff0c;与 C# (Common Language Infrastructure) 紧密集成。.NET 8 引入了许多新功能&#xff0c;如原生编译、值类型 (Value Types)、结构化并发 (structured concurrency) 和…

中铁建设集团集采网站张家界网站建设app

1.教程简介 本教程是YouTube大佬教程视频的随笔, 目前正在更新中... 教程地址[YouTube](https://www.youtube.com/watch?vXtQMytORBmM)2.安装 本教程使用的Unity版本 2021.3.34f1&#xff0c; 安装好该LTS(长期支持)版本之后, 在左侧Install选项卡Tab中选择对应版本右边的齿…

# 20232313 2025-2026-1 《网络与系统攻防技术》实验一实验报告 - 20232313

一、实验内容 学习通过以下三种方式利用pwn1程序的漏洞执行getShell函数:篡改程序流程——直接修改可执行文件,跳转至getShell; 栈溢出攻击——利用foo函数的缓冲区溢出漏洞,覆盖返回地址触发getShell; Shellcode…

完整教程:【无标题】

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

个人空间备案网站名称wordpress贴内幻灯片

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

vector使用中的一个小问题

定义一个二维的vector时,应该使用resize进行初始化,否则直接进行访问时会出错的。 C++中vector resize用法解析 - DeepSeek

一生一芯学习:PA2:输入输出

一生一芯学习:PA2:输入输出输入输出是计算机与外界交互的基本手段,只需要向设备发送一些有意义的数字信号,设备就会按照这些信号来工作。设备有自己的专属寄存器(如CPU的通用寄存器),也有自己的功能部件(如CPU…

深入解析:展会聚焦丨漫途科技亮相2025西北水务博览会!

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering() - 指南

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering() - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; d…

2025.10.7——2绿

普及+/提高- AT_agc031_b [AGC031B] Reversi 很简单的线性DP,很快就写出来了。 AT_abc406_f [ABC406F] Compare Tree Weights 树上的dfs序+树状数组,我被卡了好久……最后还因为树状数组写错功亏一篑了。

wordpress快站wordpress恢复边栏

问题描述&#xff0c;后台返回一个参数携带在url上面&#xff0c;发的时候是空格隔开的字符串&#xff0c;但是到了前端放到地址栏打开是一个号。 类似于 // 后台返回的url https://xxx.com?aaa bxxx // 打开浏览器后地址栏显示的 https://xxx.com?aaabxxx问了一下AI说是空…

完整教程:无人机避障——感知部分(Ubuntu 20.04 复现Vins Fusion跑数据集)胎教级教程

完整教程:无人机避障——感知部分(Ubuntu 20.04 复现Vins Fusion跑数据集)胎教级教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important…

姑苏区网站建设广州专业网站改版方案

企业们正在寻找新的方式来吸引和保持观众的注意力,一种新兴的解决方案就是使用Avatar虚拟形象技术&#xff0c;这种技术可以让用户在视频拍摄或直播场景中&#xff0c;以自定义的数字人形象出现&#xff0c;同时保持所有的表情和脸部驱动。美摄科技正是这个领域的领军者&#x…

我真的博了

其实标题指的是博弈论。 [AGC002E] Candy Piles 桌子上有 \(N\) 堆糖果。每堆糖果有 \(a_i\) 颗糖果。 Snuke 和 Ciel 正在玩游戏。他们轮流走。Snuke 先走。在每个回合中,当前玩家必须执行以下两个操作之一:选择剩余…