Giter Club home page Giter Club logo

node-chess's People

Contributors

adrien1251 avatar ananas-dev avatar bitdeli-chef avatar brozeph avatar cco-joshua avatar dependabot[bot] avatar ldanilek avatar piterden avatar wcandillon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-chess's Issues

dump / restore game state to / from json.

This is a feature request

It would be nice to see a simple api to dump game state to json and restore it. Something like

let json = game.dump()
game.restore(json)

This could be used to save games in a database or create save/restore points.

Cannot find module 'chess'

The latest version on npm seems to be missing the dist folder.

resulting in

require("chess")
Error: Cannot find module 'chess'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:594:15)
    at Function.Module._load (internal/modules/cjs/loader.js:520:25)
    at Module.require (internal/modules/cjs/loader.js:650:17)
    at require (internal/modules/cjs/helpers.js:20:18)

you can reproduce the issue here https://npm.runkit.com/chess

Another knight check

Your latest git commit may have fixed this, but I ran my test against the npm version 0.1.7.

The following position does not detect a check with the knight.

g.move 'd4'
g.move 'd5'
g.move 'f4'
g.move 'e6'
g.move 'g3'
g.move 'Bd6'
g.move 'b4'
g.move 'Nc6'
g.move 'c3'
g.move 'Nf6'
g.move 'Nh3'
g.move 'Nxb4'
g.move 'cxb4'
g.move 'Bxb4'
g.move 'Nd2'
g.move '0-0'
g.move 'Bb2'
g.move 'b6'
g.move 'a3'
g.move 'Bd6'
g.move 'Rc1'
g.move 'Ng4'
g.move 'Rc6'
g.move 'Ne3'
g.move 'Qc2'

g.move 'Nxc2'

Notated moves allows every piece to be promoted following a promotable pawn

Steps to reproduce:

  1. Move a white pawn up to the seventh rank.
  2. Look at the notated moves afterward -- every white piece that is notated after that pawn (all minor/major pieces, not just pawns) have promotions attached to their notated moves.

Suggested fix below:

node-chess/lib/algebraicGameClient.js (lines 79 to 86)

// iterate through each starting squares valid moves
    for (i = 0; i < validMoves.length; i++) {
        p = validMoves[i].src.piece;

        // iterate each potential move and build prefix and suffix for notation
        for (n = 0; n < validMoves[i].squares.length; n++) {
            prefix = '';

            isPromotion = false; // <---- need to reset isPromotion

en passant bug?

When you create a new game and play: d4 a6 d5 e5 the board object returns an additional black pawn out of nowhere at e6.

Looks like this has to do with en passant and the 'real' black pawn at e5 being threatened by the white pawn on d5.

This is the only issue I have encountered so far. Great work and thanks for sharing!

Not install nothing. SRC directory doesnt exist

When I install with "npm install node-chess" or "yarn add chess"

After install:
Captura de pantalla_2022-07-17_11-53-08

CODE:

const chess = require("chess");

console.log(chess);

const gameClient = chess.create({ PGN: true });
gameClient.getStatus();

Output:

node:internal/modules/cjs/loader:361
      throw err;
      ^

Error: Cannot find module '/home/darwin/Code/node/chess-whatsapp/node_modules/chess/src/main.js'. Please verify that the package.json has a valid "main" entry
    at tryPackage (node:internal/modules/cjs/loader:353:19)
    at Function.Module._findPath (node:internal/modules/cjs/loader:566:18)
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:919:27)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/home/darwin/Code/node/chess-whatsapp/game.js:1:15)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32) {
  code: 'MODULE_NOT_FOUND',
  path: '/home/darwin/Code/node/chess-whatsapp/node_modules/chess/package.json',
  requestPath: 'chess'
}

node: v16.16.0
npm: 8.11.0
yarn: 1.22.19
System:
No LSB modules are available.
Distributor ID: Kali
Description: Kali GNU/Linux Rolling
Release: 2022.2
Codename: kali-rolling

castling notation in possible moves using numbers rather than letters

here:
"0-0-0":{"src":{"file":"e","rank":8,"piece":{"moveCount":0,"side":{"name":"black"},"type":"king","notation":"K"}},"dest":{"file":"c","rank":8,"piece":null}}

0-0-0 should really be O-O-O (if wikipedia is to be trusted). Same for O-O.

It does accept either notation 0-0 || O-O but should only ever return O-O.

I hope this makes sense.

BUG regarding move.undo()

> const chess = require('chess');
undefined
> const gameClient = chess.create({ PGN: true });
undefined
> let m = gameClient.move("e4");
undefined
> m = gameClient.move("c5");
undefined
> m.undo()
undefined
> gameClient.move("e5");
{
  move: {
    algebraic: 'e5',
    capturedPiece: null,
    castle: false,
    enPassant: false,
    postSquare: Square { file: 'e', piece: [Pawn], rank: 5 },
    prevSquare: Square { file: 'e', piece: null, rank: 4 } // Here's the bug. The prevSquare should be e7
  },
  undo: [Function (anonymous)]
}

node-chess cannot be imported using common-js syntax

In the README examples, the module chess is imported using require. However, this module is an ES6 module and doesn't allow itself to be required (at least for me).

This is the error I get when trying to require the module:

var Chess = require('chess').Chess;
            ^

Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\Joey\Programming\Node.js\node_modules\chess\src\main.js from C:\Users\Joey\Programming\Node.js\chess.js not supported.
Instead change the require of main.js in C:\Users\malvi\Programming\Node.js\ChessBot\chessjstest.cjs to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (C:\Users\Joey\Programming\Node.js\chessjs.js :3:13) {
  code: 'ERR_REQUIRE_ESM'
}

Node.js v17.0.

And this is the code used to generate this error:

const Chess = require('chess').Chess;

Do the examples need to be updated, or am I doing something wrong?

Add full events coverage

I'm thinking of this as an enhancement since your objects are already extending an EventEmitter

What do you think of making this library more Events oriented? Would it add much more complexity to it?

This way we could sync a board using events only, and separate controls and feedback from the library.

If this use case seems legit to you, I might dig in.

Get/Detect Opening from a game state or PGN

I have been messing around with this for a project I am working on and I think it would be valuable to have a way to use this to detect the opening based on the match as it has been played.

Do you think this is something that would be possible? I don't think I see this capability by any other NPM package and it could be a nice feature to add to an already great tool.

Thanks!

Black pawn appears

This moveset, followed by Rg6 makes another black pawn appear in a6. Seems similar to #1

Before
before

After
before

g.move 'e4'
g.move 'e5'
g.move 'd3'
g.move 'Nc6'
g.move 'Nf3'
g.move 'Bb4'
g.move 'Nfd2'
g.move 'd6'
g.move 'a3'
g.move 'Bc5'
g.move 'Be2'
g.move 'Qf6'
g.move '0-0'
g.move 'Bxf2'
g.move 'Rxf2'
g.move 'Qe6'
g.move 'Nc4'
g.move 'Nd4'
g.move 'Bf1'
g.move 'Bd7'
g.move 'c3'
g.move 'Nb3'
g.move 'Ra2'
g.move 'Ba4'
g.move 'Qc2'
g.move 'Nh6'
g.move 'd4'
g.move 'Ng4'
g.move 'Rf3'
g.move 'b5'
g.move 'Nxe5'
g.move 'Nxc1'
g.move 'Qxc1'
g.move 'dxe5'
g.move 'Ra1'
g.move 'Rb8'
g.move 'h3'
g.move 'Rb6'
g.move 'hxg4'
g.move 'Qxg4'
g.move 'Nd2'
g.move 'a5'
g.move 'dxe5'
g.move 'Rc6'
g.move 'c4'
g.move 'h5'
g.move 'Rb1'
g.move 'Rhh6'
g.move 'Ra1'
g.move 'Rce6'
g.move 'Bd3'
g.move 'Rxe5'
g.move 'cxb5'

g.move 'Rg6'

No check/checkmate detected with knights

This position is registered as a check, and it should be a checkmate. I am able to do Kf7 to move the king to a position capturable by the knight.
board

g.move 'e4'
g.move 'e5'
g.move 'Nc3'
g.move 'd6'
g.move 'Bc4'
g.move 'Be6'
g.move 'Bb3'
g.move 'Nf6'
g.move 'Nge2'
g.move 'Nh5'
g.move 'Bxe6'
g.move 'fxe6'
g.move 'd4'
g.move 'Be7'
g.move 'dxe5'
g.move 'dxe5'
g.move 'Qxd8'
g.move 'Bxd8'
g.move 'Be3'
g.move '0-0'
g.move '0-0-0'
g.move 'Nc6'
g.move 'Rhf1'
g.move 'Bh4'
g.move 'Nb5'
g.move 'Rac8'
g.move 'f3'
g.move 'a6'
g.move 'Nbc3'
g.move 'Nb4'
g.move 'Bc5'
g.move 'Nxa2'
g.move 'Nxa2'
g.move 'b6'
g.move 'Bxf8'
g.move 'Rxf8'
g.move 'Nb4'
g.move 'a5'
g.move 'Nc6'
g.move 'Ra8'
g.move 'Nxe5'
g.move 'c5'
g.move 'Rd6'
g.move 'Rc8'
g.move 'Rxb6'
g.move 'c4'
g.move 'f4'
g.move 'c3'
g.move 'Nxc3'
g.move 'Rxc3'
g.move 'Rb8'

g.move 'Kf7'

Similarly, in this case it should detect a check:

g.move 'e4'
g.move 'e5'
g.move 'd3'
g.move 'Bc5'
g.move 'Nf3'
g.move 'Qf6'
g.move 'Be3'
g.move 'Na6'
g.move 'd4'
g.move 'Bb6'
g.move 'dxe5'
g.move 'Qe6'
g.move 'Bd4'
g.move 'Nc5'
g.move 'Ng5'
g.move 'Qg6'
g.move 'Be3'
g.move 'Nxe4'
g.move 'Nxe4'
g.move 'Qxe4'
g.move 'Na3'
g.move 'Qxe5'
g.move 'Bc4'
g.move 'Qxb2'
g.move 'Nb5'
g.move 'Nf6'
g.move '0-0'
g.move 'd5'
g.move 'Bb3'
g.move 'c6'
g.move 'Nd6'

Incorrect pawn moves

First, thank you for putting your chess engine on npms. I built a chess engine a few years ago and was comparing my results with yours for the first 4 plys. I found that the results were slightly off. I wasn't sure which one was incorrect; so, I modified both to output the results in the same format. I then wrote another app to digest the values and determine the differences. Long story short, the issue was on the chess.js side. Your logic for pawn movements has a small bug. It's not accounting for potential double-jump if there is also a capture possible.

Try this: e2e4,a7a5,f1a6,b7b5. The last move presented is a very valid move which you can verify on another chess app or manually. However, chess.js does not realize this is a valid move. I believe the pawn logic below is getting confused because there is a capture scenario. Though the pawn can... capture, it doesn't have to. It is very legal to still double-jump.

We should definitely sync up sometime. I did a ton of optimization earlier for my chess engine. Feel free to reach out to me. I hope you are able to get this defect fixed soon. I can double check your results again afterwards.

Thanks,
Ronnie
[email protected]

//pawn logic that I found below
// check for double square first move
if (opt.piece.moveCount === 0 &&
opt.destSquares.length === 1 &&
opt.destSquares[0].piece === null) { // Fix for issue #1
sq = this.board.getNeighborSquare(
opt.destSquares[0],
opt.piece.side === piece.SideType.White ?
board.NeighborType.Above :
board.NeighborType.Below
);

    if (!sq.piece) {
        opt.destSquares.push(sq);
    }

Upgrade dependencies

[email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.

So please update dependencies from @babel/runtime-corejs2

add additional info to moves history

This is a feature request rather than an issue. I am using the moves history (game.moveHistory) to generate a moves string that is compatible with UCI based chess engines. Looks like this: a2a4 e7d6 ...
This works fine however a pawn promotions in this notation is: h7h8q (for a promotion to queen). The move history does not include details of the promotion or even the algebraic notated move which could use to reconstruct this.

Is tis info available elsewhere or any chance you can include it?

Pawns not promoted properly in algebraicGameClient.js

I encountered this bug a while back so hopefully my thinking is still accurate.

Steps to reproduce: underpromote any pawn or explicitly promote the pawn to a queen (i.e. append "Q" to notation)

Issue: Pawn is not promoted at all.

Suggested Fix:

        // check for pawn promotion
        if (notation.charAt(notation.length - 1).match(/[BNQR]/)) {
            promo = notation.charAt(notation.length - 1);
            notation = notation.slice(0, notation.length - 1); // <------- remove it from the notation
        }

Basically, if I can recall correctly, the notation when not stripped of the promotion character will cause the function to recurse on line 267 and return immediately, and thus never hit the promotion code on lines 275 and onward. Taking away the promo character allows it to fall through to the promotion code.

Store captured pieces

It would be nice to have quick access to the array of captured pieces inside the Game instance.

I think it should be possible.

Undoing first move throws exception

To repro:

const gameClient = chess.create();
let gameMove = gameClient.move("e4");
gameMove.undo();

Throws this exception:

TypeError: Cannot read properties of undefined (reading 'piece')

Type error: ';' expected.

I am building a nextjs project with the library but I can't get the typescript compilation to work.

Screenshot from 2021-02-26 23-36-57

this is my tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve"
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

Pieces disappearing

g2 to g4
e7 to e5
f1 to h3
f7 to f5
g1 to f3
f5 to g4
h3 to g4
g8 to f6

After this set of moves the white bishop always disappears
try { gameClient.move(start, to); } catch (e) { console.error('Chess Client: ',e.message); }

logs Chess Client: move is not defined when start is g4 ( where the bishop is supposed to be) after that if another white piece is moves the bishop is removed from the board and the square has no piece. I'm using simple game client if that matters, and the issue is reproducible and happens every time.

Update moveHistory and notatedMoves when calling undo()

I stored all the played moves and looped through to call undo().
The board and its pieces update to the previous locations but game.moveHistory and getStatus().notatedMoves do not.

I don't know if this was done on purpose or not, just thought i should report it .

Pawn Promotion

Didn't see anything in the docs/api section with regards to pawn promotion.

I moved a white pawn across the board to e7. Available moves at that point when it was my turn again was e8, but I would expect to see e8Q, e8N, e8R, etc.

I have created a fork and may consider implementing and testing this myself. We'll see if I have time.

Thoughts/concerns?

Strange issue with spontaneous pawn

I was using node-chess as the backend for a small chess-focussed app that I'm building, and I noticed some strange behavior. If you play through the following moves, you'll notice that an additional black pawn appears spontaneously.

1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Nd6 6. Bxc6...

After the first half of the sixth move, a ninth black pawn appears at c5.

Add Square to capturedPiece (Piece)

It would be nice to have the square of captured piece to avoid calculating variants like enPassant

const { move } = this.game.move(algebraic)
if (move.capturedPiece) {
  console.log('Captured Piece', move.capturedPiece.square) // { file: 'd', rank: 5, piece: Pawn }
}

I understand this would be recursive adding a Square in a Piece type, but I'd like to find a way to make it simple.

What do you think?

En passant notation

I'm unsure if related to #43

I've tried this dumb game for trying the en passant:

game.move('e4')
game.move('d5')
game.move('e5')
game.move('f5')
game.move('exf6') // En passant

It seems exf6 is not in the list, but rather f6 is present. I need to import/export moves in PGN and f6 wouldn't be valid I believe. Since I'm not an expert in PGN format at all, maybe I'm lost in some ambiguity there? How should we address this kind of issue then?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.