GithubHelp home page GithubHelp logo

guilherme-vasconcelos / js-crazychess-lib Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 1.0 361 KB

Chess library

License: GNU General Public License v3.0

JavaScript 100.00%
chess javascript library nodejs

js-crazychess-lib's People

Contributors

dependabot[bot] avatar guilherme-vasconcelos avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Forkers

johnvictorfs

js-crazychess-lib's Issues

Implement tests for movements

  • The library should handle both valid moves (such as 1. e4 in the traditional initial position), but also throw errors when invalid moves are played (such as 1. Rxe8 in the traditional initial position).
  • The tests for each piece should probably be organized into different test suites (one file per test suite, e.g.: rooks_moves.test.js, pawns_moves.test.js, and so on).
  • Also, we could have tests for FENs (since we already have a way to get the current FEN and we already have color validation with FEN support too)
  • King and pawn tests still need more features before they can be implemented (checks, promotions, etc.)

Create a Board.getCurrentFEN method

Currently, we have a method to load a given FEN, but after that we don't track the position FEN anymore.
Features to be added in getCurrentFEN method:

  • Pieces placement
  • Current active color
  • Castling rights
  • En passant target square
  • Halfmoves
  • Fullmoves

Important: even though the basic method is already implemented, we still don't have support for castling, halfmove count and en passant. Because of that, the getCurrentFEN method does not work for these mentioned items.
Finish #1 before proceeding to implement the complete version of getCurrentFEN.

Add support for en passant

The rules for en passant are:

  • If pawn A is in a given position, and pawn B moves two squares forward and ends up in the same row as pawn A and in an adjacent column (to pawn A), pawn A can capture pawn B as if it had moved only one square forward.
  • if pawn A decides not to capture pawn B with en passant, it cannot en passant later anymore.

In order to implement en passant, it would probably be useful to keep track of which moves were played and by which piece (this can also help with #17). This way we only need to check if last move played was a pawn move and whether it fulfills the required conditions for en passant or not.

Remember that if en passant is possible the FEN must also be updated. We should have an attribute Board.isEnPassantPossible so that the FEN can be updated accordingly when user calls Board.getCurrentFEN.

Create CONTRIBUTING.md

Currently the library does not have a contributing guide. It must have:

  • Set-up instructions for contributors (clone the repository, yarn install, ...)
  • Information about issue tracking, pull requests, etc.
  • Code conventions used

Add support for stalemate

Requires #18.

The rules for stalemate are:

  • If the current active color has no legal moves at all, and yet it is not in a check(mate) position, then the game is drawn by stalemate.

Implement a Board.play method

Implement a wrapper for Board.move called Board.play, which should allow the user to move pieces like this:

  • Board.play('e4') rather than Board.move('e2', 'e4')
  • Board.play('Nf3') rather than Board.move('g1', 'f3')

Note: sometimes, writing a move like 'Nd7' can be ambiguous if more than one knight can reach d7. Because of this, the library has to throw error in case of ambiguity, which can be avoided by playing something like 'Nbd7' to specify which knight to move to d7.

Sometimes it will still be ambiguous to specify the column in which the piece you want to move is located at, in which case you should specify its row with a number (e.g.: 'N7b6' means to move knight from row 7 to b6).

Create better build and install instructions

Add better install instructions for people who want to use the library.

  • Add index.js with exports (board.js) and add reference to it on packages.json
  • Add to README the installation command (yarn add [email protected]/Guilherme-Vasconcelos/js-crazychess-lib)

After installing from GitHub, the user will be able to import the library like this: import { Board } from 'js-crazychess-lib';

Create a Board.willBeCheckAfter method

In order to implement checkmates and castling (and perhaps other stuff) it would be useful to have a method to verify if it will be a check position after moving a certain piece from position X to position Y and not throw an exception. For instance, in order to implement checkmates one correct attempt would be to verify if, for all your legal moves available, all of them will result in a check position (this attempt may be inefficient, but it works and is only an example).

What we have at the moment:

  • The method move, right after the piece is moved, will verify if you have a check position. If you do (and game mode checkless is set to false) the method will throw an error. After the new method is implemented, replace the logic for verifying checks in move method with willBeCheckAfter (except that, after this change, the willBeCheckAfter must be called in the beginning of the move method rather than in the end).

What the new method will aim to achieve:

  • Verify if moving piece from X to Y will result in a check position, but without throwing errors. This will make the code for verifying checks reusable.

Considerations:

  • The Board.willBeCheckAfter must take in two parameters: the initial position and target position.
  • If game mode checkless is set to true, the method should immediately return false (or perhaps throw?)
  • If possible, the method should warn if you are trying to make an illegal move (either piece of invalid color or target square does not belong to that piece's legal squares), but not throw an exception as you're not actually moving the piece (the job of throwing exception in case of illegal moves belongs to the move method).
  • Do not create an implementation using try { this.move(...) } catch(e) { ... }, as one of the goals of this method is to remove the check validation from move method, so an implementation like this would make the move method become infinitely recursive.

Implementation tips:

  • Start off using a similar logic to the move method. You place a copy of the piece at targetSquare, then a nullPiece at initialSquare. Verify if you have a check position (may need to call Board._updateAllLegalSquares), and in the end restore the original position by placing a copy of the piece at initialSquare and restoring whatever piece was at targetSquare before (remember, it could have been a capture move, so don't place a nullPiece at targetSquare when restoring the original position).

Sub-tasks:

  • Implement the Board.willBeCheckAfter method (remember to check considerations above).
  • Replace the logic for verifying checks in move method with the new willBeCheckAfter.
  • Implement tests.

Allow chess variants

The main purpose of the library is to allow some chess variants. In order for this to happen we have to analyze a few possible solutions:

  • Features that are very specific to traditional chess or are not intended to be implemented in all variants (such as checks) must have a way to be turned off.

OR

  • Split the Board class into multiple classes (BaseBoard, TraditionalBoard, VariantsBoard) or something like that.

Add support for pawn promotions

As soon as a pawn reaches the farthest available position in the board (i.e. from white's perspective: either the eigth row if it's a white pawn, or the first row if it's a black pawn) it can promote to another piece.

Rules for promotions:

  • A pawn cannot promote to a king
  • A pawn cannot promote to a piece of opposite color
  • The pawn can promote to any piece that is not excluded by the two rules above

Create custom exceptions

Currently everything is using a generic Exception class, so the exception tests are messy.

  • Create a file errors.js with all custom exceptions
    • Invalid piece's color
    • Invalid conversion from algebraic notation to ints (row, column)
    • Invalid conversion from ints (row, column) to algebraic notation
    • Invalid square: tried to do something with square X, but it does not contain piece
    • Illegal move: expected move from one color, but received move from another color
    • Illegal move: tried to move piece to X, but X is not allowed for that piece
    • Illegal move: your king is or would be in check after your move
    • Invalid game type: tried to verify check or checkmate in a game of type checkless
    • Invalid FEN: no kings found
  • Adapt all files that are currently using throw new Exception(...)
    • helpers.js
    • pieces.js
    • board.js
    • several tests files

If in doubt about the exception message when implementing the custom exceptions, ctrl + f the files (helpers, pieces and board) and search for throw new.

Implement a Board.move method

  • The move method must fulfill the target square with the correct piece
  • The move method must fulfill the square before with a NullPiece
  • Enhance the method by validating if the move is legal by using the Piece.legalSquares attribute (which is a set of strings). It should be noted that you first must update the legal moves for that piece before checking a move with Board._updateLegalSquares method.

Add support for check and checkmate

When calculating legal squares available, the rule that must be taken into consideration in regards to checks and mates are:

  • If the king is under attack (check), it must escape the check somehow.
  • In order to escape the check, the king can:
    • Move to a non-check square.
    • Block the check with some other piece (as long as moving that piece will not put your king in a new check)
    • Capture the piece that is checking it (as long as capturing that piece will not put your king in a new check)

If none of the conditions above will get the king out of check, then it is checkmate.

NOTE: Checks do not apply to some of the variants that will be implemented, so there should be some trigger to ignore checks and mates

Progress:

  • Checks
  • Checkmates

Add a way to iterate over all pieces

It could be useful to verify legal moves, number of pieces or other things.
Implement a method to return all pieces (either from a specific color or not).

  • getAllPieces -> method to return all pieces that are currently playing
  • getAllWhitePieces -> method to return all white pieces that are currently playing
  • getAllBlackPieces -> method to return all black pieces that are currently playing

Currently what is being done is basically iterating over the entire board, looking for anything that is not a NullPiece.

Add Unit tests

  • It will probably be necessary to use babel to use jest

Add full FEN support

  • Right now, the FEN support is still very basic. It only supports setting up pieces, but not castling / en passant / counting moves, etc.

  • For example, in a complete FEN (e.g. rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1) you can see the w KQkq in the end. This indicates that it's white to play (w), white has castling rights on both sides (KQ) and black has castling rights on both sides (kq). At the moment, the library completely ignores everything after the first space.

  • Castling

  • Determine whose turn is it

  • Threefold / fifty moves draw

  • En passant

Add support for castling

When calculating the King's legal squares, the rules that must be taken into consideration for castling are:

  • If the king has moved during the game, it can no longer castle.
  • If the king has not moved, but the rooks have, it can no longer castle.
  • If the king is under attack (check), it cannot castle at that moment (it can still castle later if the check is blocked by some other piece so that the king does not move) (Requires #8)
  • If it were to castle now, it would not go over any squares that would put it in check and it would not end up in check after castling (Requires #8)
  • If the king has not moved, and neither has the kingside rook, it can castle kingside if:
    • There are no pieces between the king and the kingside rook (plus all conditions above).
  • If the king has not moved, and neither has the queenside rook, it can castle queenside if:
    • There are no pieces between the king and the queenside rook (plus all conditions above, except for the kingside rook one).

If conditions above are fulfilled, the king can castle by:

  • Moving two squares towards the rook
  • The rook "jumps" over the king, going to the other side.

Improve logic for Pawns legal squares

  • The logic for considering pawns legal squares must consider:
    • Moving:
      • If pawn is on initial square, it can move two squares forward, except if there is a piece on the target square (in which case it cannot move there, but it still might be able to move one square forward, check the next rule)
      • A pawn can move one square forward, except if there is a piece on it
    • Capturing:
      • If there is a piece of opposite color on the reachable corner square of the pawn (always moving forward, a pawn cannot move backwards even for capturing pieces) it can be captured.

For the moment, there is no need to consider pawns promotions and en passant.

The current logic for pawns legal squares works sometimes, but it has a few problems:

  • The code can probably be shortened and become more readable
  • It does not consider the initial square and always acts as if pawns could move two squares forward (this problem can be solved by instantiating a new Pawn with the second parameter isFirstMove set to false. The problem is when we have custom FENs, which currently instantiate the Pawn with parameter set to true. This can be solved by changing Board._setFENPosition to check if a piece is a pawn, and instantiate it with the parameter set to false if the pawn is not on its initial position)

The logic for pawns legal squares is located at method Board._updateLegalSquares, case 'P' and case 'p'.

Implement a way for the board to track who should play next

The board must track who should play next.

  • In the beginning it should start with white to play (or, if the player provides a custom FEN, it should be whatever the FEN indicates, which means this issue relates to #1)
  • Check every move if the piece being moved has the correct color and throw an error if it doesn't.

This can probably be done just with a simple attribute in class Board, the hardest part will be to check for the custom FEN.

Set up CI

Probably with GitHub Actions.

Since I mistakenly commited TDD failing tests to master, probably comment them out (please don't remove them) if you're going to set up CI before implementing the features those tests need.

Also, change Babel stuff to be devDependencies since they are only needed for tests.

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.