akiraheid / fairchess-web Goto Github PK
View Code? Open in Web Editor NEWWas chess fair? Well, it is now!
License: GNU General Public License v3.0
Was chess fair? Well, it is now!
License: GNU General Public License v3.0
Move accepted rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1 gameLogic.js:124:2
Opponent moved rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2 gameLogic.js:134:2
Opponent moved rnbqkbnr/ppp1pppp/8/8/4p3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 3 gameLogic.js:134:2
Move accepted rnbqkbnr/ppp1pppp/8/8/4p3/5Q2/PPPP1PPP/RNB1KBNR b KQkq - 1 4 gameLogic.js:124:2
Opponent moved rnbqkbnr/ppp1pppp/8/8/8/4pQ2/PPPP1PPP/RNB1KBNR w KQkq - 0 5 gameLogic.js:134:2
Move accepted rnbqkbnr/ppp1pppp/8/8/2B5/4pQ2/PPPP1PPP/RNB1K1NR w KQkq - 1 6 gameLogic.js:124:2
Move accepted rnbqkbnr/ppp1pQpp/8/8/2B5/4p3/PPPP1PPP/RNB1K1NR b KQkq - 0 7 gameLogic.js:124:2
Opponent moved rnbq1bnr/pppkpQpp/8/8/2B5/4p3/PPPP1PPP/RNB1K1NR b KQ - 1 8 gameLogic.js:134:2
Opponent moved rnbq1bnr/pppkpQp1/8/7p/2B5/4p3/PPPP1PPP/RNB1K1NR w KQ h6 0 9 gameLogic.js:134:2
Move accepted rnbq1bnr/pppkp1p1/4Q3/7p/2B5/4p3/PPPP1PPP/RNB1K1NR w KQ - 1 10 gameLogic.js:124:2
Move accepted rnbq1bnr/pppkp1p1/4Q3/1B5p/8/4p3/PPPP1PPP/RNB1K1NR b KQ - 2 11
When running on a server, read environment variable FAIRCHESS_ROOT for the base base to prepend every server request with so that proxy passing works smoother. This also requires updating the index.html
to point to ROOT/client/js/*
.
Allow players to choose the piece to promote to.
Multiplayer moves are checked on the client-side but still delay moving the piece until the server responds. Instead of showing that delay, allow the legal move (as checked by client) and update the board. Then, when the server validates the move, compare the server's accept/reject with client FEN and reverse/continue moves.
A major question is how to handle two moves if the player is quick and the connection is slow.
Expected
In cases like the following
1. e4 Nc6, Rb8
2. Bf4, Ra8
3. Qf3, Qxf7+
where a player has two moves, the game should be considered check instead of checkmate (note the notation above). In the game above, black has the following options that should be legal:
3. Qf3, Qxf7+ Kxf7+, Ke8
or
3. Qf3, Qxf7+ d6, Kd7
Actual
The game given in Expected
ends in white checkmating black.
Given the AI is using alpha-beta with a depth of 2, black should take e4 during its second turn.
1. e4 | Nf6, Nc6
should have been
1. e4 | Nf6, Nxe4
because the heuristic prioritizes having more pieces than the opponent and taking pieces.
Allow click to move instead of drag.
The configurable root worked locally but not on a server because the default settings for Socket.IO try to talk to /socket.io
but the server isn't forwarding that URI to the fairchess server. Need to configure the Socket.IO server path on start up with FAIRCHESS_ROOT
prefix.
Create and enable the app to run from a Docker container.
fairchess lib doesn't store history of moves. If it did, it would allow users to send bug reports by obtaining the move history easily.
Add ai opponent
21:33:05.853
Object { fen: "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:06.890
Object { fen: "rnbqkbnr/ppppppp1/8/7p/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:07.912
Object { fen: "rnbqkbnr/pp1pppp1/8/2p4p/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 3", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:09.942
Object { fen: "rnbqkbnr/pp1pppp1/8/2p1P2p/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 4", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:10.960
Object { fen: "rnbqkbnr/pp2ppp1/3p4/2p1P2p/8/8/PPPP1PPP/RNBQKBNR w KQkq - 0 5", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:15.546
Object { fen: "rnbqkbnr/pp2ppp1/3p4/2p1P2p/8/5Q2/PPPP1PPP/RNB1KBNR w KQkq - 1 6", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:20.821
Object { fen: "rnbqkbnr/pp2ppp1/3pP3/2p4p/8/5Q2/PPPP1PPP/RNB1KBNR b KQkq - 0 7", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:21.858
Object { fen: "rnbqkbnr/pp2p1p1/3pPp2/2p4p/8/5Q2/PPPP1PPP/RNB1KBNR b KQkq - 0 8", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:22.880
Object { fen: "rnbqkbnr/p3p1p1/3pPp2/1pp4p/8/5Q2/PPPP1PPP/RNB1KBNR w KQkq b6 0 9", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:30.444
Object { fen: "rnbqkbnr/p3p1p1/3pPp2/1pp4Q/8/8/PPPP1PPP/RNB1KBNR w KQkq - 0 10", winner: null, method: null, gameOver: false }
ai.js:65:2
21:33:32.045
Object { fen: "rnbqkbnr/p3pQp1/3pPp2/1pp5/8/8/PPPP1PPP/RNB1KBNR b KQkq - 1 11", winner: null, method: null, gameOver: false }
TypeError: move is undefined[Learn More] ai.js:220:31
aiMove http://localhost:8082/client/js/ai.js:220
When multiple branches have the same score, randomly pick a branch
As a courtesy to players, show the last move made with the from
and to
squares of the move highlighted.
Browser: Firefox 65.0.1
OS: Android
The webpage displays with a large scrollable section at the bottom that causes attempts to drag pieces to scroll the page instead.
Display the turn count somewhere on the multiplayer and AI pages
Display the current game's history as provided by fairchess lib
Add a slider to set the AI to "random", "beginner", or "advanced". In reality, this changes the underlying alpha-beta search depth.
Animating the player's move creates a strange view of dropping a piece and then seeing the piece slide from the original location to the dropped location.
When a player takes the opponent's king on their second turn, the opponent doesn't see a game over notification while the king-taker does.
Example FEN:
rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 2
rnbqkbnr/ppp2ppp/4p3/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 3
rnbqkbnr/ppp2ppp/4p3/1B1p4/4P3/8/PPPP1PPP/RNBQK1NR b KQkq - 1 3
rnb1kbnr/pppq1ppp/4p3/1B1p4/4P3/8/PPPP1PPP/RNBQK1NR w KQkq - 2 5
rnb1kbnr/pppB1ppp/4p3/3p4/4P3/8/PPPP1PPP/RNBQK1NR b KQkq - 0 5
Note where the chesspiece images came from in the README.md
and webpage.
Refer to Google's docs for how to implement buttons safer and why.
See title
Not sure why this is occurring but every move causes the board to flash in most games. This applies to desktop and mobile.
Take advantage of hiding elements and don't need to have redundant visuals for ai and multiplayer with just different logic in the back.
This will require the ability to switch between human and AI or "back to home screen" button while playing a game.
Currently, any exception that can be caused by a client sending data crashes the server. This is dumb. Fix this.
The ai tries to move after it get itself into a stalemate.
22:15:21.307
Object { fen: "rnbqkbnr/pppppppp/8/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq - 0 1", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:26.322
Object { fen: "rnbqkbnr/pp1ppppp/2p5/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq - 0 2", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:28.742
Object { fen: "rnb1kbnr/pp1ppppp/1qp5/8/8/2P5/PP1PPPPP/RNBQKBNR w KQkq - 1 3", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:29.778
Object { fen: "rnb1kbnr/pp1ppppp/1qp5/8/8/1QP5/PP1PPPPP/RNB1KBNR b KQkq - 2 4", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:32.038
Object { fen: "rnb1kbnr/pp1ppppp/2p5/8/8/1qP5/PP1PPPPP/RNB1KBNR w KQkq - 0 5", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:33.076
Object { fen: "rnb1kbnr/pp1ppppp/2p5/8/8/1qP4N/PP1PPPPP/RNB1KB1R w KQkq - 1 6", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:34.099
Object { fen: "rnb1kbnr/pp1ppppp/2p5/8/P7/1qP4N/1P1PPPPP/RNB1KB1R b KQkq a3 0 7", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:37.651
Object { fen: "rnb1kbnr/pp1ppppp/2p5/8/P7/2P4N/1q1PPPPP/RNB1KB1R b KQkq - 0 8", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:38.463
Object { fen: "rnb1kbnr/pp1ppppp/2p5/8/P7/2P4N/3PPPPP/qNB1KB1R w Kkq - 0 9", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:39.500
Object { fen: "rnb1kbnr/pp1ppppp/2p5/8/P4N2/2P5/3PPPPP/qNB1KB1R w Kkq - 1 10", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:40.534
Object { fen: "rnb1kbnr/pp1ppppp/2p5/8/P4N1P/2P5/3PPPP1/qNB1KB1R b Kkq h3 0 11", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:43.106
Object { fen: "rnb1kbnr/p2ppppp/2p5/1p6/P4N1P/2P5/3PPPP1/qNB1KB1R w Kkq b6 0 12", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:44.136
Object { fen: "rnb1kbnr/p2ppppp/2p5/1p6/P4N1P/2P5/3PPPPR/qNB1KB2 b kq - 1 13", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:45.920
Object { fen: "rnb1kbnr/p2ppppp/2p5/8/p4N1P/2P5/3PPPPR/qNB1KB2 b kq - 0 14", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:46.743
Object { fen: "rnb1kbnr/p2ppppp/2p5/8/5N1P/p1P5/3PPPPR/qNB1KB2 w kq - 0 15", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:47.778
Object { fen: "rnb1kbnr/p2ppppp/2p5/8/7P/p1PN4/3PPPPR/qNB1KB2 b kq - 1 16", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:51.910
Object { fen: "rnb1kbnr/p2ppppp/2p5/8/7P/2PN4/p2PPPPR/qNB1KB2 w kq - 0 17", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:52.928
Object { fen: "rnb1kbnr/p2ppppp/2p5/7P/8/2PN4/p2PPPPR/qNB1KB2 w kq - 0 18", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:53.941
Object { fen: "rnb1kbnr/p2ppppp/2p5/7P/8/2PN4/p2PPPPR/qNBK1B2 b kq - 1 19", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:56.867
Object { fen: "rnb1kbnr/p2ppppp/2p5/7P/8/2PN4/p2PPPPR/1qBK1B2 w kq - 0 20", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:57.896
Object { fen: "rnb1kbnr/p2ppppp/2p5/7P/8/2PN4/p2PPPPR/1qB1KB2 b kq - 1 21", winner: null, method: null, gameOver: false }
ai.js:64:2
22:15:59.383
Object { fen: "rnb1kbnr/p2ppppp/2p5/7P/8/2PN4/3PPPPR/qqB1KB2 b kq - 0 22", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:02.975
Object { fen: "rnb1kbnr/3ppppp/2p5/p6P/8/2PN4/3PPPPR/qqB1KB2 w kq a6 0 23", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:03.995
Object { fen: "rnb1kbnr/3ppppp/2p4P/p7/8/2PN4/3PPPPR/qqB1KB2 w kq - 0 24", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:05.008
Object { fen: "rnb1kbnr/3ppppp/2p4P/p7/5P2/2PN4/3PP1PR/qqB1KB2 b kq f3 0 25", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:06.476
Object { fen: "rnb1kbnr/3ppppp/2p4P/8/p4P2/2PN4/3PP1PR/qqB1KB2 b kq - 0 26", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:07.606
Object { fen: "rnb1kbnr/3ppppp/2p4P/8/5P2/p1PN4/3PP1PR/qqB1KB2 w kq - 0 27", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:08.635
Object { fen: "rnb1kbnr/3ppppp/2p4P/8/4PP2/p1PN4/3P2PR/qqB1KB2 b kq e3 0 28", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:12.452
Object { fen: "rnb1kbnr/3ppppp/2p4P/8/4PP2/2PN4/p2P2PR/qqB1KB2 w kq - 0 29", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:13.480
Object { fen: "rnb1kbnr/3ppppp/2p4P/4N3/4PP2/2P5/p2P2PR/qqB1KB2 w kq - 1 30", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:14.496
Object { fen: "rnb1kbnr/3Npppp/2p4P/8/4PP2/2P5/p2P2PR/qqB1KB2 b kq - 0 31", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:16.961
Object { fen: "rn2kbnr/3bpppp/2p4P/8/4PP2/2P5/p2P2PR/qqB1KB2 b kq - 0 32", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:20.299
Object { fen: "rn2kbnr/3bpp1p/2p4p/8/4PP2/2P5/p2P2PR/qqB1KB2 w kq - 0 33", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:21.318
Object { fen: "rn2kbnr/3bpp1p/2p4p/8/4PP2/2P5/p2PB1PR/qqB1K3 w kq - 1 34", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:22.330
Object { fen: "rn2kbnr/3bpp1p/2p4p/7R/4PP2/2P5/p2PB1P1/qqB1K3 b kq - 2 35", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:28.089
Object { fen: "rn2kbnr/3bpp1p/2p4p/7R/4PP2/2q5/p2PB1P1/1qB1K3 w kq - 0 36", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:29.106
Object { fen: "rn2kbnr/3bpp1p/2p4p/8/4PP1R/2q5/p2PB1P1/1qB1K3 b kq - 1 37", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:30.387
Object { fen: "rn2kbnr/3bpp1p/2p4p/8/4PP1R/2q5/3PB1P1/qqB1K3 b kq - 0 38", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:37.740
Object { fen: "rn2kbnr/3bpp1p/2p4p/4q3/4PP1R/8/3PB1P1/qqB1K3 w kq - 1 39", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:38.756
Object { fen: "rn2kbnr/3bpp1p/2p4p/4q3/4PP1R/8/3P2P1/qqB1KB2 w kq - 2 40", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:39.769
Object { fen: "rn2kbnr/3bpp1p/2p4p/4q3/4PPR1/8/3P2P1/qqB1KB2 b kq - 3 41", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:42.115
Object { fen: "rn2kbnr/3bpp1p/7p/2p1q3/4PPR1/8/3P2P1/qqB1KB2 b kq - 0 42", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:43.076
Object { fen: "rn2kbnr/3bpp1p/7p/4q3/2p1PPR1/8/3P2P1/qqB1KB2 w kq - 0 43", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:44.089
Object { fen: "rn2kbnr/3bpp1p/7p/4q3/2p1PPR1/3B4/3P2P1/qqB1K3 b kq - 1 44", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:47.061
Object { fen: "rn2kbnr/3bpp1p/7p/4q3/4PPR1/3p4/3P2P1/qqB1K3 w kq - 0 45", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:48.080
Object { fen: "rn2kbRr/3bpp1p/7p/4q3/4PP2/3p4/3P2P1/qqB1K3 w kq - 0 46", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:49.103
Object { fen: "rn2kbRr/3bpp1p/7p/4q3/4PP2/3p2P1/3P4/qqB1K3 b kq - 0 47", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:51.902
Object { fen: "rn2kbr1/3bpp1p/7p/4q3/4PP2/3p2P1/3P4/qqB1K3 w q - 0 48", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:52.913
Object { fen: "rn2kbr1/3bpp1p/7p/4q3/4PP2/3p2P1/3P1K2/qqB5 b q - 1 49", winner: null, method: null, gameOver: false }
ai.js:64:2
22:16:55.460
Object { fen: "rn2kb2/3bpp1p/7p/4q3/4PP2/3p2r1/3P1K2/qqB5 b q - 0 50", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:03.422
Object { fen: "rn2kb2/3bpp1p/8/4q2p/4PP2/3p2r1/3P1K2/qqB5 w q - 0 51", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:04.437
Object { fen: "rn2kb2/3bpp1p/8/4q2p/4PP2/3p2r1/3P4/qqB2K2 b q - 1 52", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:06.564
Object { fen: "rn2kb2/3bpp1p/8/4q3/4PP1p/3p2r1/3P4/qqB2K2 w q - 0 53", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:07.575
Object { fen: "rn2kb2/3bpp1p/8/4qP2/4P2p/3p2r1/3P4/qqB2K2 w q - 0 54", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:08.583
Object { fen: "rn2kb2/3bpp1p/8/4qP2/4P2p/3p2r1/3P4/qqB1K3 b q - 1 55", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:15.540
Object { fen: "rn2kb2/3bpp1p/8/4qP2/4P2p/3p4/3P2r1/qqB1K3 b q - 2 56", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:17.133
Object { fen: "rn2kb2/3bpp1p/8/4qP2/4P2p/3p4/3r4/qqB1K3 w q - 0 57", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:18.147
Object { fen: "rn2kb2/3bpp1p/5P2/4q3/4P2p/3p4/3r4/qqB1K3 w q - 0 58", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:19.158
Object { fen: "rn2kb2/3bpp1p/5P2/4q3/4P2p/3p4/3r4/qqB2K2 b q - 1 59", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:32.284
Object { fen: "rn2kb2/3bpp1p/5P2/4q3/4P2p/3p4/6r1/qqB2K2 w q - 2 60", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:33.293
Object { fen: "rn2kb2/3bpp1p/5P2/4q3/4P2p/3p4/6K1/qqB5 b q - 0 61", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:37.510
Object { fen: "rn2kb2/3bpp1p/5P2/4q3/4P2p/8/3p2K1/qqB5 b q - 0 62", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:40.753
Object { fen: "rn2kb2/3bpp1p/5P2/4q3/4P2p/8/6K1/qqBq4 w q - 0 63", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:41.762
Object { fen: "rn2kb2/3bpp1p/5P2/4q3/4P2p/B7/6K1/qq1q4 b q - 1 64", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:46.917
Object { fen: "rn2kb2/3bpp1p/5P2/8/4q2p/B7/6K1/qq1q4 w q - 0 65", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:47.926
Object { fen: "rn2kb2/3bpp1p/5P2/8/4q2p/B7/5K2/qq1q4 w q - 1 66", winner: null, method: null, gameOver: false }
ai.js:64:2
22:17:48.934
Object { fen: "rn2kb2/3bpp1p/5P2/8/1B2q2p/8/5K2/qq1q4 b q - 2 67", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:05.267
Object { fen: "rn2kb2/3bpp1p/5P2/8/1B2q2p/2q5/5K2/1q1q4 w q - 3 68", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:06.278
Object { fen: "rn2kb2/3bpp1p/5P2/8/4q2p/2B5/5K2/1q1q4 b q - 0 69", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:09.049
Object { fen: "rn2kb2/3bpp1p/5P2/8/4q2p/2B5/1q3K2/3q4 b q - 1 70", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:16.528
Object { fen: "rn2kb2/3bpp1p/5P2/8/4q2p/2B5/1q3K2/2q5 w q - 2 71", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:17.539
Object { fen: "rn2kb2/3bpp1p/5P2/8/4q2p/8/1q1B1K2/2q5 w q - 3 72", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:18.553
Object { fen: "rn2kb2/3bPp1p/8/8/4q2p/8/1q1B1K2/2q5 b q - 0 73", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:23.442
Object { fen: "rn2k3/3bPpbp/8/8/4q2p/8/1q1B1K2/2q5 b q - 1 74", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:24.632
Object { fen: "rn2k3/3bPp1p/5b2/8/4q2p/8/1q1B1K2/2q5 w q - 2 75", winner: null, method: null, gameOver: false }
ai.js:64:2
22:18:25.642
TypeError: move is undefined[Learn More] ai.js:206:31
One player can play as both colors on the same browser tab.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.