自由型象棋分析程序

Screenshot_20251007_164231

可以键盘操作。比如鼠标移到某个位置,按r出来个黑车。空格删掉棋子。还可以自己吃自己,空白吃自己等,我感觉摆残局最方便。摆完黑子,CapsLock,摆红子。

程序很乱。鄙人之前所发贴的拼凑版。再贴部分代码:

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
View Code

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":"车", "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) ? "进" : "退"
      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) ? "进" : "退"
      if ("rcpk".includes(c))
        s += "0123456789"[d]
      else
        s += x[tx]
    }
  }
  if (!moves.value.length) mc = 0
  moves.value += s + ' '
}
View Code

双击FEN则应用它和覆盖性粘贴:

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里要有line-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
}
View Code

 

posted @ 2025-10-07 16:55  华容道专家  阅读(8)  评论(0)    收藏  举报