Code Monkey home page Code Monkey logo

chess-api's People

Contributors

codemaster7000 avatar jeffersonsimaogoncalves avatar mobeendev avatar peter279k avatar programarivm avatar smashedfrenzy16 avatar

Stargazers

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

Watchers

 avatar  avatar

chess-api's Issues

Write documentation

The POST /api/play/rav endpoint has recently been implemented and now is to be documented at Chess API.

See:

Thus, a new entry in the mkdocs.yml file needs to be added as well as its corresponding file in the docs folder.

Keep it up and happy learning!

Implement the POST /api/play endpoint

This is the very first REST API endpoint to be added as per the specification below.

Method Endpoint Description
POST /api/play Allows to play a game in a stateless way.
Parameter Type Description
movetext string A PGN movetext.
Response Description
200 (OK) The PGN movetext is valid.
400 (Bad Request) The PGN movetext is not valid.

Query example:

curl -d '{"movetext":"1.e4"}' -H "Content-Type: application/json" -X POST http://localhost:8000/api/play

Response 200 (OK):

{
  "fen": "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3",
  "isCheck": false,
  "isMate": false,
  "movetext": "1.e4"
}

At this moment the POST /api/play endpoint is partially implemented in src/Controller/PlayController.php, however, in order for it to respond with a 400 status code, the Chess\Player class should first throw an exception if provided with a wrong movetext.

See:

Keep it up, and happy learning!

Write documentation

The GET /api/annotations/games endpoint has recently been implemented and now is to be documented at Chess API.

See:

Thus, a new entry in the mkdocs.yml file needs to be added as well as its corresponding file in the docs folder.

Keep it up and happy learning!

Allow to download screenshots of Capablanca games

At this moment, src/Controller/DownloadImageController.php doesn't allow to download screenshots of Capablanca chess games as shown in the animation below.

output

However, the /download_image endpoint should accept a new parameter called variant, this way a new $board object can be created accordingly to be then passed to Chess\Player\PgnPlayer.

For further information on how a $board is initialized please visit:

This issue is quite similar to the following one which has been solved already:

Remember:

There is an easy quick way to get the API up and running without an SSL certificate for when testing endpoints that don't require a database connection, e.g., api/download_image or api/download_mp4. In such cases you may want to use PHP's built-in web server.

Keep it up, and happy coding and learning!

Implement the POST /api/engine/stockfish endpoint

This endpoint is intended to play chess against the Stockfish chess engine and is to be implemented as described next.

Method Endpoint Description
POST /api/engine/stockfish Returns Stockfish's move
Parameter Type Description
movetext string LAN movetext
skillLevel string Skill level
depth string Skill level
Response Description
200 (OK) Returns Stockfish's move
400 (Bad Request) The request could not be processed

The POST /api/engine/stockfish endpoint should be implemented in a new file called src/Controller/EngineStockfishController.php.

See:

Keep it up, and happy learning and coding!

Add annotated chess games

Annotated games are games with comments that help understand what is going on the chessboard. They usually include variations showing the development of the game in selected positions that require an in-depth understanding. RAV stands for Recursive Annotation Variation. This is the standard format for annotated chess games.

Screenshot 2023-08-16 12:34:36
Figure 1. Click on Database > Annotated Games and select a chess game.

q_09_figure_02
Figure 2. Read the comments and explore the variations.

At this moment, the annotated games are being added to the data/annotations/games.json file. While the chess games database contains one million records, there are only a few annotated chess games. This is mainly because annotations may be subject to copyright.

Described next are the games to be added.

World Chess Championship 1921

World Chess Championship 1921. (2023, August 9). In Wikipedia. https://en.wikipedia.org/wiki/World_Chess_Championship_1921


© Copyrighted Annotations

Copyright permissions have been obtained from the authors to get annotated chess games published into chesslablab.com. Should you publish these games into your fork of ChesslaBlab, please also ask the authors for copyright permissions.

World Chess Championship 2004

Aron Nimzowitsch vs Siegbert Tarrasch

[Event "St. Petersburg"]
[Site "St. Petersburg  RUE"]
[Date "1914.04.28"]
[EventDate "1914.04.21"]
[Round "5"]
[Result "0-1"]
[White "Aron Nimzowitsch"]
[Black "Siegbert Tarrasch"]
[ECO "D30"]
[WhiteElo "?"]
[BlackElo "?"]
[PlyCount "64"]

1. d4 { Notes by Raymond Keene. Here is a brilliant win by
Tarrasch. } d5 2. Nf3 c5 3. c4 e6 4. e3 Nf6 5. Bd3 Nc6 6. O-O
Bd6 7. b3 O-O 8. Bb2 b6 9. Nbd2 Bb7 10. Rc1 Qe7 11. cxd5 {11
Qe2!? } 11...exd5 12. Nh4 g6 13. Nhf3 Rad8 14. dxc5 bxc5
15. Bb5 Ne4 16. Bxc6 Bxc6 17. Qc2 Nxd2 18. Nxd2 {'The guardian
of the king's field leaves his post for a moment, assuming
wrongly that 19 Qc3 is a major threat' -- Tartakower. If 18
Qxd2 d4 19 exd4 Bxf3 20 gxf3 Qh4 } 18...d4 {!} 19. exd4 {19
Rfe1! } Bxh2+ 20. Kxh2 Qh4+ 21. Kg1 Bxg2 {!} 22. f3 {22 Kxg2
Qg4+ 23 Kh2 Rd5-+ } 22...Rfe8 23. Ne4 Qh1+ 24. Kf2 Bxf1 25. d5
{25 Rxf1 Qh2+ or 25 Nf6+ Kf8 26 Nxe8 Qg2+ } 25...f5 26. Qc3
Qg2+ 27. Ke3 Rxe4+ 28. fxe4 f4+ {28...Qg3+! } 29. Kxf4 Rf8+
30. Ke5 Qh2+ 31. Ke6 Re8+ 32. Kd7 Bb5# 0-1

Fix the POST /api/search endpoint

figure_01
Figure 1. Click on Database Search

figure_02
Figure 2. Enter "foobar" in the SAN Movetext text field.

The API endpoint should respond with a 204 HTTP status code.

Happy coding and learning!

Implement the GET /api/autocomplete/events endpoint

The GET /autocomplete endpoint has proven to be not optimal with about one million chess games in the database. The autocomplete JSON files combined take up 1.5 MB as shown in the image attached.

Screenshot 2023-08-03 21:29:09

Thus, the src/Controller/AutocompleteController.php file needs to be split into two controllers:

  • src/Controller/AutocompleteEventsController.php
  • src/Controller/AutocompletePlayersController.php

This issue is intended to implement src/Controller/AutocompleteEventsController.php.

Happy coding!

Fix the download of videos

The MP4 video is not downloaded if playing a game after a FEN string has been previously loaded.

In the screenshot attached below the follwing FEN string is loaded:

4k2r/pp1b1pp1/8/3pPp1p/P2P1P2/1P3N2/1qr3PP/R3QR1K w k -

Then, this sequence of moves is played:

1.Rb1 Qa2 2.Ra1 Qb2

If trying to download the video though, the api/download_mp4 endpoint will respond with a status code 500.

figure-01
Figure 1. Download a video

Keep it up, and happy coding and learing!

Upload a chess game into the InterPlanetary File System

Let's upload the very first chess game in JSON format into IPFS! Any of the games in data/annotations/games.json should be okay. Let's start with the following one.

{
    "Event": "Steinitz - Zukertort World Championship Match",
    "Site": "New Orleans, LA USA",
    "Date": "1886",
    "White": "Johannes Zukertort",
    "Black": "Wilhelm Steinitz",
    "WhiteElo": "?",
    "BlackElo": "?",
    "Result": "0-1",
    "ECO": "D50",
    "movetext": "{ Adapted notes, originally by Robert James Fischer from a television interview. } 1.d4 d5 2.c4 e6 3.Nc3 Nf6 4.Bg5 Be7 5.Nf3 O-O 6.c5 { is a mistake already; instead it should be played e3, naturally. } 6...b6 7.b4 bxc5 8.dxc5 a5 9.a3 d4 { is a fantastic move; it's the winning move. The pawn can't be taken with the knight because of axb4. } 10.Bxf6 gxf6 11.Na4 e5 { because the center is easily winning. Black's kingside weakness is nothing. } 12.b5 Be6 { with the idea of dominating the game with a powerful mobile center. } 13.g3 c6 14.bxc6 Nxc6 15.Bg2 Rb8 { threatening Bb3. } 16.Qc1 d3 17.e3 e4 18.Nd2 f5 19.O-O Re8 { is a very modern move; a quiet positional move. The rook is doing nothing now, but later... } 20.f3 { to break up the center, it's the only chance for White. } 20...Nd4 21.exd4 Qxd4+ 22.Kh1 e3 (22... Qxa4 { allows Black to easily regain material. }) 23.Nc3 Bf6 24.Ndb1 d2 25.Qc2 Bb3 26.Qxf5 d1=Q 27.Nxd1 Bxd1 28.Nc3 e2 29.Raxd1 Qxc3 { and White resigns. The center has prevailed. } 0-1"
  }

See https://github.com/orgs/chesslablab/discussions/349

Keep it up,

Emanuel Lasker vs Aron Nimzowitsch

[Event "St. Petersburg"]
[Site "St. Petersburg  RUE"]
[Date "1914.04.22"]
[EventDate "1914.04.21"]
[Round "2"]
[Result "1/2-1/2"]
[White "Emanuel Lasker"]
[Black "Aron Nimzowitsch"]
[ECO "B16"]
[WhiteElo "?"]
[BlackElo "?"]
[PlyCount "83"]

1. e4 { Notes by Raymond Keene. } c6 2. d4 d5 3. Nc3 dxe4
4. Nxe4 {This was another favourite of Nimzowitsch's, but he
did not like the generally quiet situations generated by the
classical 4...Bf5, preferring the tense struggles that
resulted from 4...Nf6 and after 5 Nxf6+ the recapture with the
e-pawn. Asztalos-Nimzowitsch, Bled 1931, went 5...exf6 6 c3
Bd6 7 Bd3 O-O 8 Qc2 h6 9 Ne2 Qc7 10 Be3 Nd7 11 Qd2?! Better 11
O-O-O Re8 12 g4! 11...Re8 12 Ng3? Bf4! and Nimzowitsch was
beginning to get on top.} Nf6 5. Nxf6+ gxf6 {Nimzowitsch, on
occasion, played the alternative fifth move recapture
5...gxf6. His game against Leonhardt at Carlsbad 1911, must
have been one of the first games with this idea. } 6. Be2
{Nowadays 6 c3 Bf5 7 Bc4 or 7 Ne2 would more likely be
played. } 6...Bf5 7. Bf3 Qa5+ 8. c3 h5 {!? Intending to
prevent White castling kingside. } 9. Bxh5 Nd7 10. Bg4 Bxg4
11. Qxg4 O-O-O 12. Ne2 e6 13. Bf4 Qb5 14. O-O-O Nb6 15. Ng3 {?
15 b3 would leave White with a safe though difficult game --
Lasker. } 15...Qd5 16. Kb1 Qxg2 17. Rdg1 Qxf2 18. Ne4 Qh4
19. Qf3 Nc4 20. Ka1 f5 21. Ng5 Bd6 22. Bc1 Rd7 23. Rg2 Bc7
24. Rhg1 Nd6 25. Qe2 Ne4 26. Nf3 Qh3 {26...Qh5 is probably
better. } 27. a3 a6 28. Be3 Rhd8 29. Ka2 Rh8 30. Ka1 Rhd8
31. Ka2 Re8 32. Rg8 Rxg8 33. Rxg8+ Rd8 34. Rg7 Rd7 35. Rg8+
Rd8 36. Rg7 Rf8 {Again 36...Qh5, threat 37...Bxh2. } 37. c4
Nf6 {Better 37...Kd8. } 38. Bg5 Nh5 39. Rxf7 Rxf7 40. Qxe6+
Rd7 41. Ne5 Bxe5 42.Qe8+ {Nimzowitsch should certainly have
won this game.} 1/2-1/2

Implement the GET /api/autocomplete/players endpoint

The GET /autocomplete endpoint has proven to be not optimal with about one million chess games in the database. The autocomplete JSON files combined take up 1.5 MB as shown in the image attached.

Screenshot 2023-08-03 21:29:09

Thus, the src/Controller/AutocompleteController.php file needs to be split into two controllers:

  • src/Controller/AutocompleteEventsController.php
  • src/Controller/AutocompletePlayersController.php

This issue is intended to implement src/Controller/AutocompletePlayersController.php.

Happy coding!

Implement the POST /api/eco endpoint

This endpoint is intended to fetch the name of a chess opening given its ECO code.

Method Endpoint Description
POST /api/eco Returns the name of the chess opening.
Parameter Type Description
eco string ECO code.
Response Description
200 (OK) The ECO code is valid.
204 (No Content) The ECO code was found in the database.

Query examples:

curl -d '{"eco":"B94"}' -H "Content-Type: application/json" -X POST http://localhost:8000/api/eco

Response:

{
  "name": "Sicilian, Najdorf"
}

The POST /api/eco endpoint should be implemented in a new file called src/Controller/EcoController.php.

Keep it up, and happy learning!

Implement the POST /api/opening endpoint

This endpoint is intended to fetch chess opening data given a set of parameters.

Method Endpoint Description
POST /api/opening Returns chess opening data.
Parameter Type Description Optional
eco string ECO code. Yes
name string Opening name. Yes
movetext string Movetext. Yes
Response Description
200 (OK) The chess opening is valid.
204 (No Content) The chess opening was found in the database.

Query examples:

curl -d '{"eco":"B94"}' -H "Content-Type: application/json" -X POST http://localhost:8000/api/opening

Response:

{
  "eco": "B94",
  "name": "Sicilian Defense: Najdorf Variation",
  "movetext": "1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 a6 6.Bg5"
}

The POST /api/opening endpoint should be implemented in a new file called src/Controller/OpeningController.php.

Implement the POST /api/ascii endpoint

This endpoint will return an ASCII representation of a chess position, and is to be implemented as per the specification below.

Method Endpoint Description
POST /api/ascii Returns an ASCII representation of a chess position.
Parameter Type Description
fen string A FEN string
Response Description
200 (OK) The FEN string is valid.
400 (Bad Request) The FEN string is not valid.

Query examples:

curl -d '{"fen":"rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq e6"}' -H "Content-Type: application/json" -X POST http://localhost:8000/api/ascii

Response:

{
  "ascii":"r  n  b  q  k  b  n  r ... R  N  B  Q  K  B  N  R"
}

The POST /api/ascii endpoint should be implemented in a new file called src/Controller/AsciiController.php.

See:

Keep it up, and happy coding.

Make the POST api/play endpoint respond with a 400 HTTP status code

At this moment, the POST api/play endpoint in src/Controller/PlayController.php will respond with a 500 Internal Server Error HTTP status code if processing an invalid movetext as shown in the image below.

Screenshot 2022-12-10 19:11:58
Figure 1. API responding with 500 Internal Server Error after 1.e4 e4 has been processed.

However, it should respond with a 400 Bad Request HTTP status code.

The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large, invalid request message framing, or deceptive request routing).

Keep it up and happy coding and learning!

Implement the POST /api/download_gif endpoint

This endpoint is intended to download a GIF animation given a movetext, and is to be implemented as per the specification below.

Method Endpoint Description
POST /api/download_gif Downloads a GIF.
Parameter Type Description
movetext string PGN movetext
Response Description
200 (OK) The PGN movetext is valid.
400 (Bad Request) The PGN movetext is not valid.

The POST /api/download_gif endpoint should be implemented in a new file called src/Controller/DownloadGifController.php.

See:

Keep it up, and happy learning!

Make the API return a JSON string when an exception is thrown

At the present moment, the POST /api/play endpoint is returning an HTML document when a 400 Bad Request occurs because of a thrown exception; however, a JSON response should be returned instead.

figure-01
Figure 1. The POST /api/play endpoint should respond with a JSON string.

See:

Keep it up, and happy learning and coding!

Install and set up a web server on pchess.net

At this moment, a chess server is running on pchess.net — a micro instance on AWS EC2 — which is the sandbox environment for development and testing, and a new issue was opened recently to install and set up a chess database on this machine by the way.

Nginx should be installed as well to host the REST API.

Thus, three different services are intended to run on pchess.net:

  • A chess server (WebSocket, port 8443)
  • A chess database (MySQL, port 3336)
  • A web server (HTTPS, 443)

See:

Happy learning, and keep it up.

Implement the POST /api/play/rav endpoint

This endpoint is intended to replace the RAV processing implemented in the chess server.

See:

<?php

namespace ChessServer\Command;

// ...

class StartCommand extends AbstractCommand
{
    // ...

    public function run(Socket $socket, array $argv, ConnectionInterface $from)
    {
        if (FenMode::NAME === $argv[2]) {
          // ...
        } elseif (SanMode::NAME === $argv[2]) {
          // ...
        } elseif (RavMode::NAME === $argv[2]) {
            try {
                $settings = (object) json_decode(stripslashes($argv[3]), true);
                if ($argv[1] === Game::VARIANT_960) {
                    $startPos = str_split($settings->startPos);
                    $board = new Chess960Board($startPos);
                    if (isset($settings->fen)) {
                        $board = FenToBoard::create($settings->fen, $board);
                    }
                    $ravPlay = new RavPlay($settings->movetext, $board);
                } elseif ($argv[1] === Game::VARIANT_CAPABLANCA) {
                    $board = new CapablancaBoard();
                    if (isset($settings->fen)) {
                        $board = FenToBoard::create($settings->fen, $board);
                    }
                    $ravPlay = new RavPlay($settings->movetext, $board);
                } else {
                    $board = new ClassicalBoard();
                    if (isset($settings->fen)) {
                        $board = FenToBoard::create($settings->fen, $board);
                    }
                    $ravPlay = new RavPlay($settings->movetext, $board);
                }
                $ravPlay->validate();
                $board = $ravPlay->getBoard();
                $sanMode = new SanMode(new Game($argv[1], $argv[2]), [$from->resourceId]);
                $game = $sanMode->getGame()->setBoard($board);
                $sanMode->setGame($game);
                $socket->getGameModeStorage()->set($sanMode);
                return $socket->sendToOne($from->resourceId, [
                    $this->name => [
                        'variant' => $argv[1],
                        'mode' => $argv[2],
                        'turn' => $game->state()->turn,
                        'filtered' => $ravPlay->getRavMovetext()->filtered(),
                        'movetext' => $ravPlay->getRavMovetext()->main(),
                        'breakdown' => $ravPlay->getRavMovetext()->getBreakdown(),
                        'fen' => $ravPlay->getFen(),
                        ...($argv[1] === Game::VARIANT_960
                            ? ['startPos' =>  $settings->startPos]
                            : []
                        ),
                    ],
                ]);
            } catch (\Throwable $e) {
                return $socket->sendToOne($from->resourceId, [
                    $this->name => [
                        'variant' => $argv[1],
                        'mode' => $argv[2],
                        'message' => 'This PGN movetext could not be loaded.',
                    ],
                ]);
            }
        } elseif (PlayMode::NAME === $argv[2]) {
            // ...
        } elseif (StockfishMode::NAME === $argv[2]) {
            // ...
        }
    }
}

The POST /api/play/rav endpoint is to be implemented in a new file called src/Controller/PlayRavController.php according to the following specification.

Method Endpoint Description
POST /api/play/rav Plays chess in recursive annotation variation (RAV) format.
Parameter Type Description Required
variant string Chess variant. Yes
movetext string SAN movetext. Yes
startPos string Start position. Only in a Chess960 game
fen string Initial FEN string. No
Response Description
200 (OK) Plays chess in RAV format.
400 (Bad Request) The request could not be processed

Keep it up, and happy learning and coding!

Implement the POST /api/grandmaster endpoint

This endpoint will allow users to play like a grandmaster by checking out if a given chess game has already been played before by a grandmaster. Probably this is more of a training tool than anything else; if a particular move isn't found in the database, it means it hasn't been played before as per the current information available, which may suggest it's not a good one to make, or more simply, a new line of multiple possible variants out there is being played.

output
Figure 1. This line was not found in the grandmaster database.

Method Endpoint Description
POST /api/grandmaster Given a PGN movetext, returns the move that would follow — if found in the database.
Parameter Type Description
movetext string A PGN movetext.
Response Description
200 (OK) Returns the PGN move that follows according to a grandmaster; for example, e5.
204 (No Content) No grandmaster move was found in the database.

The POST /api/grandmaster endpoint should be implemented in a new file called src/Controller/GrandmasterController.php.

See:

Keep it up, and happy coding!

Implement the POST /api/heuristic_picture endpoint

This endpoint is intended to take a heuristic picture of a chess position, and is to be implemented as per the specification below.

Method Endpoint Description
POST /api/heuristic_picture Takes a heuristic picture of a game.
Parameter Type Description
fen string A FEN string.
Response Description
200 (OK) The FEN string is valid.
400 (Bad Request) The FEN string is not valid.

Query examples:

curl -d '{"fen":"rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R b KQkq -"}' -H "Content-Type: application/json" -X POST http://localhost:8000/api/heuristic_picture

Response:

{
  "fen": "rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R b KQkq -",
  "heuristicPicture": [ ... ],
  "dimensions": [ ... ]
}

The POST /api/heuristic_picture endpoint should be implemented in a new file called src/Controller/HeuristicPictureController.php.

See:

Keep it up, and happy learning!

Implement the POST /api/heuristics endpoint

This endpoint is intended to replace the /heuristics command implemented in the chess server.

See:

The POST /api/heuristics endpoint is to be implemented in a new file called src/Controller/HeuristicsController.php according to the following specification.

Method Endpoint Description
POST /api/heuristics Takes a balanced heuristic picture of the given PGN movetext.
Parameter Type Description Required
variant string Chess variant Yes
movetext string SAN movetext Yes
startPos string Start position Only in a Chess960 game
Response Description
200 (OK) Returns a balanced heuristic picture of the given PGN movetext.
400 (Bad Request) The request could not be processed

Keep it up, and happy learning and coding!

Improve the API documentation

The Chess API has recently been updated:

Attached below are some examples of the newest version up and running.

Figure-01
Figure 1. POST https://pchess.net/api/grandmaster

Figure-02
Figure 2. POST https://pchess.net/api/download_image

The swagger.yaml file should be proofread and updated accordingly. The API controller methods are found in the src/Controller folder.

This is the sandbox API for testing purposes:

Should you find a bug or something that needs to be upgraded, please open an issue.

Keep it up, and happy coding and learning!

Implement the POST /api/download_image endpoint

This endpoint is intended to download a PNG image given a FEN string, and is to be implemented as per the specification below.

Method Endpoint Description
POST /api/download_image Downloads a PNG image.
Parameter Type Description
fen string A FEN string
Response Description
200 (OK) The FEN string is valid.
400 (Bad Request) The FEN string is not valid.

The POST /api/download_image endpoint should be implemented in a new file called src/Controller/DownloadImageController.php.

See:

Keep it up, and happy learning!

Implement the GET /api/annotations/games endpoint

This endpoint is intended to fetch all annotated games in data/annotations/games.json.

It returns JSON data from a file in a similar way as with:

  • GET /autocomplete
  • GET /stats/opening

Thus, a new controller called ChessApi\Controller\AnnotationsGames needs to be created, and its code should be quite similar to the following:

See:

Keep it up, and happy coding!

Allow to download videos of Chess960 and Capablanca games

At this moment, src/Controller/DownloadMp4Controller.php allows to download MP4 videos of classical chess games only as shown below.

output_trimmed_enhanced

However, the /download_mp4 endpoint should accept a new parameter called variant. This way, a new $board object could be created accordingly to be then passed to Chess\Player\PgnPlayer.

In Chess960 games the start position needs to be passed to the endpoint as well.

For further information on how a $board is initialized please visit:

Keep it up and happy learning and coding!

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.