当前位置: 首页 > news >正文

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

① 到东萍象棋网可以下载许多棋谱。我用程序下载了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.rkmt.cn/news/16914.html

相关文章:

  • 深入解析:展会聚焦丨漫途科技亮相2025西北水务博览会!
  • 2025.10.7——2绿
  • 完整教程:无人机避障——感知部分(Ubuntu 20.04 复现Vins Fusion跑数据集)胎教级教程
  • 2025.10.6——1绿1蓝
  • 地球科学概论
  • Spring5笔记
  • qmd 模拟赛的一道题
  • PCoT: Persuasion-Augmented Chain of Thought for Detecting Fake News and Social Media Disinformation
  • 宏定义中,为什么使用:do{}while(0)这种模式是最安全的
  • 20251007J赛合订本
  • 硅芯片创新如何成为云计算成功的关键
  • 【高级数据结构】ST 表
  • 【高级算法】树形DP
  • 【高级数据结构】浅谈最短路
  • 代码随想录打卡|Day53 图论(Floyd 算法精讲 、A * 算法精讲 (A star算法)、最短路算法总结篇、图论总结 ) - 实践
  • expr命令全解
  • 斑马打印机打印头更换教程
  • 构造中国剩余定理方程组的解
  • 2025粒度仪厂家最新品牌推荐榜,喷雾粒度分析仪, 激光粒度仪,激光粒度分析仪,纳米粒度仪公司推荐
  • Xmind Pro v24 最新破解版下载及激活教程
  • 基本Dos指令
  • Ubuntu 下同名文件替换后编译链接到旧内容的现象分析 - 实践
  • Luogu P14007 「florr IO Round 1」查询游戏 题解 [ 蓝 ] [ 交互 ]
  • RK3588和FPGA桥片之间IO电平信号概率性不能通信原因 - 实践
  • 蒟蒻的第一篇随笔
  • oppoR9m刷Linux系统: 安装MTK USB VCOM驱动
  • 可视化大屏工具对比:GoView、DataRoom、积木JimuBI、Metabase、DataEase、Apache Superset 与 Grafana - 实践
  • [特殊字符] FFmpeg 学习笔记 - 详解
  • .NET周刊【9月第3期 2025-09-21】
  • 2025教练技术行业深度剖析:目标人群、费用与品牌选择