静态国际象棋
Static Chess

原始链接: https://www.val.town/v/maxm/staticChess

此 JavaScript 代码使用 Node.js 设置服务器并导入多个库,包括 chess.js、React DOM、ESM Town、CSS simple minimizer 和 GitHub forkribbon css。 “StaticChess”类具有棋盘大小、行和方格的属性,构造一个空的基于承诺的 HTTP 请求处理程序,该处理程序获取 URL 信息并根据传入的游戏信息呈现 HTML 作为响应。呈现的 HTML 包含各种链接和样式表 以及用于来源归属的 github-fork-ribbon。 另一个名为“Game”的类在“StaticChess”类中定义,该类在提供游戏对象时初始化一个新的 Chess 实例、存储选定的棋子、获取有效的棋步并通过渲染适当的 HTML 元素来相应地显示它们。 采用缩小和缓存来实现最佳性能。

用户根据特定的移动规则讨论国际象棋游戏之间的概念差异。 他们比较了一个常见的定义,即国王移动两个方格,车跳过中间的棋子,与另一个定义,允许国王移动到某些文件,而车保持在同一列内。 这些规则对于传统国际象棋来说是可以互换的,但只有第二个规则对 960 方棋盘有效。 用户对有人建议关闭游戏中的动画表示惊讶,暗示这可能是一个玩笑或对非 JavaScript 意识形态的极端坚持。 他们挑战了所讨论的游戏是纯静态的观念,指出通过后端进行动态渲染。 他们解释了对可声明和可检测的规则(如三重/五重重复和五十/七十五步棋)进行编码的重要性。 对于更强大的国际象棋引擎来说,历史可能并不总是必要的。 用户提到了 Chrome、Firefox 和 Safari 等现代浏览器之间的 URL 长度不同,但在对实际限制做出判断之前强调了 CDN、Web 服务器和搜索引擎的考虑因素。 根据他们过去的经验,他们对一种名为“黑白棋”的不同棋盘游戏进行了暴力破解,并使用最少的方法(不包括 JavaScript)实现了它。 他们还提到了这个国际象棋应用程序遇到的问题:皇后升级不正确以及无法在 EWW 浏览器中使用棋盘。 尽管偏爱轻量级和快速的网站,但用户得出的结论是,这些妥协导致了不令人满意的游戏体验。
相关文章

原文

import { modifyFetchHandler as codeOnValTown } from "https://esm.town/v/andreterron/codeOnValTown?v=45";

import { modifyResponse } from "https://esm.town/v/andreterron/codeOnVT_modifyResponse?v=9";

import { Chess, Move, Square } from "npm:chess.js";

import minify from "npm:css-simple-minifier";

import { renderToString } from "npm:react-dom/server";

class StaticChess {

size = 8;

rows = Array.from({ length: this.size }, (_, i) => i);

squares = Array.from({ length: this.size }, (_, i) => i);

constructor() {}

async fetch(req: Request): Promise<Response> {

const gameInfo = parseURL(req.url);

if (gameInfo === undefined) {

return new Response("Not Found", { status: 404, headers: { "cache-control": "max-age=86400, public" } });

}

const game = new Game(gameInfo.game, gameInfo.selected);

return new Response(

renderToString(

<html>

<head>

<title>Static Chess</title>

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link rel="icon" href="https://fav.farm/♟️" />

<style>{minify(CSS)}</style>

</head>

<body>

<div id="code-on-vt-host">

<link

rel="stylesheet"

href="https://cdnjs.cloudflare.com/ajax/libs/github-fork-ribbon-css/0.2.3/gh-fork-ribbon.min.css"

/>

<a

href="https://www.val.town/v/maxm/staticChess"

rel="source"

target="_blank"

className="github-fork-ribbon"

data-ribbon="Code on Val Town"

title="Code on Val Town"

>

Code on Val Town

</a>

</div>

<h1>Static Chess</h1>

<div>

<a href="https://www.val.town/v/maxm/staticChess">info</a> - <a href="/">reset</a>

</div>

<div className="board">

{this.rows.map(row => (

<div key={row} className="row">{this.squares.map(square => game.squareContent(row, square))}</div>

))}

</div>

<div className="info">

{game.selected

? "Click a highted square to move the selected piece, or select a different piece."

: `It is ${{ w: "white", b: "black" }[game.game.turn()]}'s turn. Click a piece to make a move.`}

</div>

</body>

</html>,

),

{ headers: { "content-type": "text/html", "cache-control": "max-age=86400, public" } },

);

}

}

class Game {

game: Chess;

selected?: string;

selectable: string[];

board;

nextMoves: { [key: string]: Move };

fen: string;

constructor(game: Chess, selected?: string) {

this.game = game;

this.selected = selected;

this.board = game.board();

this.fen = game.fen().replaceAll(" ", "_");

this.nextMoves = {};

this.selectable = game.moves({ verbose: true }).map((m) => m.from.toString());

if (this.selected) {

var moves = game.moves({

square: selected as Square,

verbose: true,

});

for (const move of moves) {

this.nextMoves[move.to] = move;

}

}

}

squareContent(row: number, square: number) {

const pos = indexToPos(row, square);

const color = this.board[row][square]?.color;

let className = "square";

联系我们 contact @ memedata.com