0.5.0-kh.14 • Published 2 years ago

@mizarjp/yaneuraou.komoringheights-mate v0.5.0-kh.14

Weekly downloads
-
License
GPL-3.0
Repository
github
Last release
2 years ago

@mizarjp/yaneuraou.komoringheights-mate

  • KomoringHeights is a YaneuraOu based Tsume-Shogi solver using the df-pn+ algorithm. It is being developed with the goal of solving medium to long Tsume-Shogi games at high speed.
  • YaneuraOu is the World's Strongest Shogi engine(AI player) , WCSC29 1st winner , educational and USI compliant engine.
  • License: GPLv3

This project is based on the following repository.

Requirements

Secure Context (web)

This project needs access to SharedArrayBuffer, which must be placed in a secure context if it is to run on the Web. For this reason, requires these HTTP headers on the top level response:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

WebAssembly SIMD, Threads and Atomics

This project uses WebAssembly SIMD, Threads and Atomics.

Browser

  • Chrome
  • Firefox

JavaScript/WebAssembly execution environment

  • Node.js 16.10 or later

Example

JavaScript

JavaScript sample code example/example.komoringheights-mate.js:

#!/usr/bin/env node
const { writeFileSync } = require("fs");
const { join } = require("path");
const { cpus, freemem } = require("os");
const { isMainThread, Worker } = require("worker_threads");
const { TsumeData } = require("./example.mate.data");

if(isMainThread) {
  const tasks = [];
  const posQueue = Object.entries(TsumeData);
  let notQueueFinish = true;
  const addTask = () => {
    const entry = posQueue.shift();
    if (entry) {
      const [name, position] = entry;
      tasks.push(new Promise((resolve) => {
        const worker = new Worker(
          join(__dirname, "example.komoringheights-mate.worker.js"),
          { workerData: { name, position } }
        );
        worker.on("message", (mes) => {
          if(typeof mes === "object") {
            addTask();
            resolve(mes);
          } else {
            console.log(`${name} ${mes}`);
          }
        });
      }));
    } else {
      if (notQueueFinish) {
        notQueueFinish = false;
        Promise.all(tasks).then((results) => {
          writeFileSync(join(__dirname, "example.result.txt"), Array.from(results.map(e => `${JSON.stringify(e)}\n`)).join(""));
        });
      }
    }
  };
  // number of worker generate : (number of logical cores) or (free memory size / 1.5Gbyte)
  const num_worker_gen = Math.max(Math.min(cpus().length, freemem() / 1572864 | 0), 1);
  console.log(`generate ${num_worker_gen} workers`);
  for (let i = 0; i < num_worker_gen; ++i) {
    addTask();
  }
}

JavaScript worker sample code example/example.komoringheights-mate.worker.js:

const KomoringHeights_MATE = require("@mizarjp/yaneuraou.komoringheights-mate");
const { parentPort, workerData } = require("worker_threads");

KomoringHeights_MATE().then(async (yaneuraou) => {
  const name = String(workerData?.name);
  const position = String(workerData?.position);
  // utils
  const wCache = {};
  const rCache = {};
  yaneuraou.addMessageListener((line) => {
    parentPort?.postMessage(`< ${line}`);
    let f = true;
    Object.keys(wCache)
    .filter((v) => line.startsWith(v))
    .forEach((v) => { rCache[v].push(line); wCache[v] = false; f = false; });
    Object.keys(rCache)
    .filter((v) => f && line.startsWith(v))
    .forEach((v) => { rCache[v].push(line); })
  });
  const postMessage = (command) => {
    parentPort?.postMessage(`> ${command}`);
    yaneuraou.postMessage(command);
  };
  const postMessageWait = (command, waitResp, ...gatherResps) => {
    wCache[waitResp] = true;
    rCache[waitResp] = [];
    for (const gatherResp of gatherResps) {
      rCache[gatherResp] = [];
    }
    postMessage(command);
    return new Promise((resolve) => {
      const poll = () => {
        if (wCache[waitResp]) {
          setTimeout(poll, 1);
        } else {
          delete wCache[waitResp];
          const res = { name, position };
          res[waitResp] = rCache[waitResp];
          for (const gatherResp of gatherResps) {
            res[gatherResp] = rCache[gatherResp];
          }
          resolve(res);
        }
      };
      poll();
    });
  };
  // initialize engine
  await postMessageWait("usi", "usiok");
  postMessage("setoption name PvInterval value 8000");
  await postMessageWait("isready", "readyok");
  postMessage(position);
  // mate search
  const bTime = new Date().getTime();
  const res = await postMessageWait("go mate 1000000", "checkmate", "info");
  const eTime = new Date().getTime();
  res.time = eTime - bTime;
  // send results
  parentPort?.postMessage(`spent ${res.time}ms`);
  parentPort?.postMessage(res);
  // terminate engine
  yaneuraou.postMessage("quit");
  yaneuraou.terminate();
});

Execute JavaScript:

node example/example.komoringheights-mate.js
0.5.0-kh.14

2 years ago

0.5.0-kh.12

2 years ago

0.5.0-kh.13

2 years ago

0.5.0-kh.10

2 years ago

0.5.0-kh.11

2 years ago

0.5.0-kh.9

2 years ago

0.5.0-kh.8

2 years ago

0.5.0-kh.7

2 years ago

0.5.0-kh.6

2 years ago

0.5.0-kh.5

2 years ago

0.5.0-kh.4

2 years ago

0.5.0-kh.3

2 years ago

0.5.0-kh.2

2 years ago

0.5.0-kh.1

2 years ago

0.5.0-kh.0

2 years ago

0.4.1-kh.1

2 years ago

0.4.1-kh.0

2 years ago

7.0.1-kh.39

2 years ago

7.0.1-alpha.38

2 years ago

7.0.1-alpha.37

2 years ago

7.0.1-alpha.35

2 years ago