自由型象棋分析程序
可以鍵盤(pán)操作。比如鼠標(biāo)移到某個(gè)位置,按r出來(lái)個(gè)黑車(chē)。空格刪掉棋子。還可以自己吃自己,空白吃自己等,我感覺(jué)擺殘局最方便。擺完黑子,CapsLock,擺紅子。
程序很亂。鄙人之前所發(fā)貼的拼湊版。再貼部分代碼:
httpd.py
# !/usr/bin/python3 from ee import * from http.server import * from threading import * from urllib.parse import unquote from random import randint class HTTPReqHandler (SimpleHTTPRequestHandler): def __init__ (m, r, c, s): super().__init__(r, c, s, directory='www') def do_GET (m): def _200 (): m.send_response(200) m.send_header('Content-type', 'text/plain') m.end_headers() path = m.requestline.split(' ')[1] if path.startswith('/ucci?'): ee.send(unquote(path[6:])) _200() m.wfile.write(ee.recv().encode()) elif path.startswith('/rpu'): n = randint(0, 6812) f = open('pu.txt', 'rb') for i in range(n): f.readline() _200() m.wfile.write(f.readline()) f.close() else: super().do_GET() def do_HEAD (m): super().do_HEAD() def do_POST (m): super().do_POST() def end_headers (m): # callback m.send_header('Cache-Control', 'no-store') super().end_headers() def httpd_thread (): port = 8000 svr_addr = ('', port) httpd = ThreadingHTTPServer(svr_addr, HTTPReqHandler) print('Listening at', port) httpd.serve_forever() Thread(daemon=1, target=httpd_thread).start() try: while True: input() except BaseException: pass
JS
function ajax(req, param, cb){ let ax = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP') ax.onreadystatechange = function(){ if(ax.readyState != 4 || ax.status != 200) return cb(ax.responseText) } ax.open('GET', req + encodeURIComponent(param), true); ax.send() } function move (who, mv) { ucciout.innerText = 'busy' ajax('/ucci?', 'position fen ' + _brd2fen() + ' ' + who + '\ngo 999', (s)=>{ ucciout.innerText = s let i = s.indexOf('\nbestmove') if(i === -1) return // 'b' - 'a'=NaN; '9' - '0'=9 let a = 'a'.charCodeAt(0) fx = s.charCodeAt(i+10) - a tx = s.charCodeAt(i+12) - a fy = '9' - s.charAt(i+11) ty = '9' - s.charAt(i+13) //console.log(fx, fy, tx, ty) if (mv) { // 走棋而不是僅分析 recMove(fx, fy, tx, ty) _brd[ty][tx] = _brd[fy][fx]; _brd[fy][fx] = ' '; draw_all() } }) } function rpu () { ajax('/rpu', '', (s)=>{ pad.value = s loadUBB() }) } let dic = JSON.parse(`{"r":"車(chē)", "n":"馬", "c":"炮", "b":"象", "B":"相", "a":"士", "A":"仕", "k":"將", "K":"帥", "p":"卒", "P":"兵"}`) dic['R'] = dic['r']; dic['N'] = dic['n']; dic['C'] = dic['c'] function recMove(fx, fy, tx, ty) { let c = _brd[fy][fx] if (c === ' ') return let isRed = c < 'a' let d = fy - ty if (d < 0) d = -d s = dic[c] if (isRed) { let x = "九八七六五四三二一" s += x[fx] if (fy === ty) s += "平" + x[tx] else { s += (fy > ty) ? "進(jìn)" : "退" if ("RCPK".includes(c)) s += "零一二三四五六七八九"[d] else s += x[tx] } } else { let x = "123456789" s += x[fx] if (fy === ty) s += "平" + x[tx] else { s += (fy < ty) ? "進(jìn)" : "退" if ("rcpk".includes(c)) s += "0123456789"[d] else s += x[tx] } } if (!moves.value.length) mc = 0 moves.value += s + ' ' }
雙擊FEN則應(yīng)用它和覆蓋性粘貼:
pad.addEventListener('dblclick', (e) => {
function findAll (str, ch) {
let positions = [-1]
for (let pos = str.indexOf(ch); pos !== -1;) {
positions.push(pos)
pos = str.indexOf(ch, pos + 1)
}
positions.push(str.length)
return positions
}
const t = e.target
const lineHeight = parseInt(getComputedStyle(t).lineHeight)
if (Number.isNaN(lineHeight)) alert('style里要有l(wèi)ine-height')
const clickPos = e.clientY - t.getBoundingClientRect().top
let lineNum = Math.floor(clickPos / lineHeight)
const str = t.value
let a = findAll(str, '\n')
let start = a[lineNum++] + 1
let end = a[lineNum]
t.setSelectionRange(start, end)
fromFEN(str.substring(start, end))
})
function on_keydown (e) {
let c = e.key
if (e.ctrlKey && (c === 'v') || (c === 'a')) {
e.target.value = ''
return true
}
if (oob) return true // mouse pointer out of board
if (!'rnbakcp '.includes(c.toLowerCase())) return true
_brd[my][mx] = c
sx = sy = -1
draw(mx, my, 1)
e.preventDefault()
return false
}

浙公網(wǎng)安備 33010602011771號(hào)