From 5ddf3b174fe1e0c909ee2c8d865ac91629a82e80 Mon Sep 17 00:00:00 2001 From: programarivm Date: Wed, 6 Nov 2024 18:19:37 +0100 Subject: [PATCH] Deployed ac6d43b6 with MkDocs version: 1.5.3 --- heuristics/index.html | 7 ++++++- index.html | 2 +- search/search_index.json | 2 +- sitemap.xml | 16 ++++++++-------- sitemap.xml.gz | Bin 283 -> 283 bytes 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/heuristics/index.html b/heuristics/index.html index 73833c62..8aaef59f 100644 --- a/heuristics/index.html +++ b/heuristics/index.html @@ -185,7 +185,7 @@

Heuristics

Defense - +This heuristic evaluates the defensive strength of each side by analyzing how the removal of attacking pieces would affect the opponent's protection. A higher score indicates a stronger defensive position. Chess\Eval\DefenseEval @@ -214,6 +214,11 @@

Heuristics

Chess\Eval\FarAdvancedPawnEval +Flight square +The safe squares to which the king can move if it is threatened. +Chess\Eval\FlightSquareEval + + Isolated pawn A pawn without friendly pawns on the adjacent files. Since it cannot be defended by other pawns it is considered a weakness. Chess\Eval\IsolatedPawnEval diff --git a/index.html b/index.html index d0460b18..2547f522 100644 --- a/index.html +++ b/index.html @@ -326,5 +326,5 @@ diff --git a/search/search_index.json b/search/search_index.json index 3ab249b5..e2b8e078 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"PHP Chess PHP Chess is a library implemented in PHP that allows to create chess apps out-of-the-box. One key feature is that it has been designed with OOP principles in mind and is thoroughly tested with plenty of unit tests. The unit tests are the best documentation. They contain hundreds of real examples on how to use PHP Chess. Almost every class in the src folder represents a concept that is tested accordingly in the tests/unit folder, in other words, the structure of the tests/unit folder is mirroring the structure of the src folder. For further details on how to use a particular class, please feel free to browse the codebase and check out the corresponding tests. The PHP Chess docs are more of a tutorial rather than an API description. Common Formats Supported Chess moves in LAN and PGN formats. Movetext processing in LAN, SAN and RAV formats. NAG support for SAN and RAV movetexts. UCI protocol. FEN conversion to chess board. Chess board conversion to PNG and JPG image. Chess board conversion to MP4 video. Acronym Description LAN Long Algebraic Notation PGN Portable Game Notation SAN Standard Algebraic Notation RAV Recursive Annotation Variation NAG Numeric Annotation Glyphs UCI Universal Chess Interface FEN Forsyth-Edwards Notation Chess Variants Multiple variants are supported with the default one being classical chess. Variant Chessboard Capablanca Chess\\Variant\\Capablanca\\Board Capablanca-Fischer Chess\\Variant\\CapablancaFischer\\Board Chess960 Chess\\Variant\\Chess960\\Board Classical Chess\\Variant\\Classical\\Board Dunsany Chess\\Variant\\Dunsany\\Board Losing Chess Chess\\Variant\\Losing\\Board RacingKings Chess\\Variant\\RacingKings\\Board UCI Engines Listed below are the UCI engines available at the moment. Stockfish Object-Oriented The chess board representation is an object of type SplObjectStorage as opposed to a bitboard. Thoroughly Tested PHP Chess has been developed with a test-driven development (TDD) approach. The tests/unit folder contains plenty of real examples. Lightweight PHP dependencies required: Rubix ML for machine learning. Imagine for image processing.","title":"Home"},{"location":"#php-chess","text":"PHP Chess is a library implemented in PHP that allows to create chess apps out-of-the-box. One key feature is that it has been designed with OOP principles in mind and is thoroughly tested with plenty of unit tests. The unit tests are the best documentation. They contain hundreds of real examples on how to use PHP Chess. Almost every class in the src folder represents a concept that is tested accordingly in the tests/unit folder, in other words, the structure of the tests/unit folder is mirroring the structure of the src folder. For further details on how to use a particular class, please feel free to browse the codebase and check out the corresponding tests. The PHP Chess docs are more of a tutorial rather than an API description.","title":"PHP Chess"},{"location":"#common-formats-supported","text":"Chess moves in LAN and PGN formats. Movetext processing in LAN, SAN and RAV formats. NAG support for SAN and RAV movetexts. UCI protocol. FEN conversion to chess board. Chess board conversion to PNG and JPG image. Chess board conversion to MP4 video. Acronym Description LAN Long Algebraic Notation PGN Portable Game Notation SAN Standard Algebraic Notation RAV Recursive Annotation Variation NAG Numeric Annotation Glyphs UCI Universal Chess Interface FEN Forsyth-Edwards Notation","title":"Common Formats Supported"},{"location":"#chess-variants","text":"Multiple variants are supported with the default one being classical chess. Variant Chessboard Capablanca Chess\\Variant\\Capablanca\\Board Capablanca-Fischer Chess\\Variant\\CapablancaFischer\\Board Chess960 Chess\\Variant\\Chess960\\Board Classical Chess\\Variant\\Classical\\Board Dunsany Chess\\Variant\\Dunsany\\Board Losing Chess Chess\\Variant\\Losing\\Board RacingKings Chess\\Variant\\RacingKings\\Board","title":"Chess Variants"},{"location":"#uci-engines","text":"Listed below are the UCI engines available at the moment. Stockfish","title":"UCI Engines"},{"location":"#object-oriented","text":"The chess board representation is an object of type SplObjectStorage as opposed to a bitboard.","title":"Object-Oriented"},{"location":"#thoroughly-tested","text":"PHP Chess has been developed with a test-driven development (TDD) approach. The tests/unit folder contains plenty of real examples.","title":"Thoroughly Tested"},{"location":"#lightweight","text":"PHP dependencies required: Rubix ML for machine learning. Imagine for image processing.","title":"Lightweight"},{"location":"chess-tutor/","text":"Chess Tutor Explain a FEN Position \u2728 Chess beginners often think they can checkmate the opponent's king quickly. However, there are so many different things to consider in order to understand a position. Chess\\Tutor\\FenEvaluation helps you improve your chess thinking process by evaluating a FEN position in terms of chess concepts like in the example below. use Chess\\FenToBoardFactory; use Chess\\Function\\CompleteFunction; use Chess\\Tutor\\FenEvaluation; $function = new CompleteFunction(); $board = FenToBoardFactory::create('8/5k2/4n3/8/8/1BK5/1B6/8 w - - 0 1'); $paragraph = (new FenEvaluation($function, $board))->paragraph; $text = implode(' ', $paragraph); echo $text; White has a decisive material advantage. White has a slightly better control of the center. The white pieces are significantly better connected. The white player is pressuring a little bit more squares than its opponent. White has a slight absolute pin advantage. White has the bishop pair. The knight on e6 is pinned shielding the king so it cannot move out of the line of attack because the king would be put in check. Overall, 6 heuristic evaluation features are favoring White while 0 are favoring Black. A heuristic evaluation is a quick numerical estimate of a chess position that suggests who may be better without considering checkmate. Please note that a heuristic evaluation is not the same thing as a chess calculation. Heuristic evaluations are often correct but may fail as long as they are based on probabilities more than anything else. \ud83c\udf89 This is a form of abductive reasoning. Explain a PGN Move \u2728 Typically, chess engines won't provide an explanation in easy-to-understand language about how a move changes the position on the board. Chess\\Tutor\\PgnEvaluation explains how a particular move changes the position. use Chess\\Function\\CompleteFunction; use Chess\\Play\\SanPlay; use Chess\\Tutor\\PgnEvaluation; $pgn = 'd4'; $function = new CompleteFunction(); $movetext = '1.Nf3 d5 2.g3 c5'; $board = (new SanPlay($movetext))->validate()->board; $paragraph = (new PgnEvaluation($pgn, $function, $board))->paragraph; $text = implode(' ', $paragraph); echo $text; Black has a slight space advantage. White has a slight protection advantage. White has a slight attack advantage. The pawn on c5 is unprotected. The c5-square is under threat of being attacked. Overall, 3 heuristic evaluation features are favoring White while 2 are favoring Black. The resulting text may sound a little robotic but it can be easily rephrased by the AI of your choice to make it sound more human-like. Explain a Good PGN Move \u2728 It's often difficult for beginners to understand why a move is good. With the help of an UCI engine Chess\\Tutor\\GoodPgnEvaluation can explain the why of a good move. use Chess\\Function\\CompleteFunction; use Chess\\Play\\SanPlay; use Chess\\Tutor\\GoodPgnEvaluation; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $limit = new Limit(); $limit->depth = 12; $stockfish = new UciEngine('/usr/games/stockfish'); $function = new CompleteFunction(); $movetext = '1.d4 d5 2.c4 Nc6 3.cxd5 Qxd5 4.e3 e5 5.Nc3 Bb4 6.Bd2 Bxc3 7.Bxc3 exd4 8.Ne2'; $board = (new SanPlay($movetext))->validate()->board; $goodPgnEvaluation = new GoodPgnEvaluation($limit, $stockfish, $function, $board); $pgn = $goodPgnEvaluation->pgn; $paragraph = implode(' ', $goodPgnEvaluation->paragraph); echo $pgn . PHP_EOL; echo $paragraph . PHP_EOL; Bg4 The black player is pressuring a little bit more squares than its opponent. The black pieces are timidly approaching the other side's king. Black has a total relative pin advantage. Black has a slight overloading advantage. The knight on e2 is pinned shielding a piece that is more valuable than the attacking piece. The bishop on f1 is overloaded defending more than one piece at the same time. Overall, 4 heuristic evaluation features are favoring White while 9 are favoring Black. \ud83c\udf89 Let's do this!","title":"Chess Tutor"},{"location":"chess-tutor/#chess-tutor","text":"","title":"Chess Tutor"},{"location":"chess-tutor/#explain-a-fen-position","text":"\u2728 Chess beginners often think they can checkmate the opponent's king quickly. However, there are so many different things to consider in order to understand a position. Chess\\Tutor\\FenEvaluation helps you improve your chess thinking process by evaluating a FEN position in terms of chess concepts like in the example below. use Chess\\FenToBoardFactory; use Chess\\Function\\CompleteFunction; use Chess\\Tutor\\FenEvaluation; $function = new CompleteFunction(); $board = FenToBoardFactory::create('8/5k2/4n3/8/8/1BK5/1B6/8 w - - 0 1'); $paragraph = (new FenEvaluation($function, $board))->paragraph; $text = implode(' ', $paragraph); echo $text; White has a decisive material advantage. White has a slightly better control of the center. The white pieces are significantly better connected. The white player is pressuring a little bit more squares than its opponent. White has a slight absolute pin advantage. White has the bishop pair. The knight on e6 is pinned shielding the king so it cannot move out of the line of attack because the king would be put in check. Overall, 6 heuristic evaluation features are favoring White while 0 are favoring Black. A heuristic evaluation is a quick numerical estimate of a chess position that suggests who may be better without considering checkmate. Please note that a heuristic evaluation is not the same thing as a chess calculation. Heuristic evaluations are often correct but may fail as long as they are based on probabilities more than anything else. \ud83c\udf89 This is a form of abductive reasoning.","title":"Explain a FEN Position"},{"location":"chess-tutor/#explain-a-pgn-move","text":"\u2728 Typically, chess engines won't provide an explanation in easy-to-understand language about how a move changes the position on the board. Chess\\Tutor\\PgnEvaluation explains how a particular move changes the position. use Chess\\Function\\CompleteFunction; use Chess\\Play\\SanPlay; use Chess\\Tutor\\PgnEvaluation; $pgn = 'd4'; $function = new CompleteFunction(); $movetext = '1.Nf3 d5 2.g3 c5'; $board = (new SanPlay($movetext))->validate()->board; $paragraph = (new PgnEvaluation($pgn, $function, $board))->paragraph; $text = implode(' ', $paragraph); echo $text; Black has a slight space advantage. White has a slight protection advantage. White has a slight attack advantage. The pawn on c5 is unprotected. The c5-square is under threat of being attacked. Overall, 3 heuristic evaluation features are favoring White while 2 are favoring Black. The resulting text may sound a little robotic but it can be easily rephrased by the AI of your choice to make it sound more human-like.","title":"Explain a PGN Move"},{"location":"chess-tutor/#explain-a-good-pgn-move","text":"\u2728 It's often difficult for beginners to understand why a move is good. With the help of an UCI engine Chess\\Tutor\\GoodPgnEvaluation can explain the why of a good move. use Chess\\Function\\CompleteFunction; use Chess\\Play\\SanPlay; use Chess\\Tutor\\GoodPgnEvaluation; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $limit = new Limit(); $limit->depth = 12; $stockfish = new UciEngine('/usr/games/stockfish'); $function = new CompleteFunction(); $movetext = '1.d4 d5 2.c4 Nc6 3.cxd5 Qxd5 4.e3 e5 5.Nc3 Bb4 6.Bd2 Bxc3 7.Bxc3 exd4 8.Ne2'; $board = (new SanPlay($movetext))->validate()->board; $goodPgnEvaluation = new GoodPgnEvaluation($limit, $stockfish, $function, $board); $pgn = $goodPgnEvaluation->pgn; $paragraph = implode(' ', $goodPgnEvaluation->paragraph); echo $pgn . PHP_EOL; echo $paragraph . PHP_EOL; Bg4 The black player is pressuring a little bit more squares than its opponent. The black pieces are timidly approaching the other side's king. Black has a total relative pin advantage. Black has a slight overloading advantage. The knight on e2 is pinned shielding a piece that is more valuable than the attacking piece. The bishop on f1 is overloaded defending more than one piece at the same time. Overall, 4 heuristic evaluation features are favoring White while 9 are favoring Black. \ud83c\udf89 Let's do this!","title":"Explain a Good PGN Move"},{"location":"data-conversion/","text":"Data Conversion FEN to Board \u2728 FEN stands for Forsyth-Edwards Notation and is the standard way for describing chess positions using text strings. At some point you'll definitely want to convert a FEN string into a chessboard object for further processing, and this can be done with the Chess\\FenToBoardFactory class according to the variants supported. When a single parameter is passed into the factory's create method, it is assumed that you want to create a classical chess board object. use Chess\\FenToBoardFactory; $board = FenToBoardFactory::create('rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -'); $board->play('w', 'Nc3'); $board->play('b', 'Nc6'); echo $board->toFen(); r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - In this example the game history contains two moves only. var_dump($board->history); array(2) { [0]=> array(4) { [\"castlingAbility\"]=> string(4) \"KQkq\" [\"sq\"]=> string(2) \"b1\" [\"move\"]=> array(7) { [\"pgn\"]=> string(3) \"Nc3\" [\"isCapture\"]=> bool(false) [\"isCheck\"]=> bool(false) [\"type\"]=> string(48) \"N[a-h]{0,1}[1-8]{0,1}[a-h]{1}[1-8]{1}[\\+\\#]{0,1}\" [\"color\"]=> string(1) \"w\" [\"id\"]=> string(1) \"N\" [\"sq\"]=> array(2) { [\"current\"]=> string(0) \"\" [\"next\"]=> string(2) \"c3\" } } [\"fen\"]=> string(59) \"rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -\" } [1]=> array(4) { [\"castlingAbility\"]=> string(4) \"KQkq\" [\"sq\"]=> string(2) \"b8\" [\"move\"]=> array(7) { [\"pgn\"]=> string(3) \"Nc6\" [\"isCapture\"]=> bool(false) [\"isCheck\"]=> bool(false) [\"type\"]=> string(48) \"N[a-h]{0,1}[1-8]{0,1}[a-h]{1}[1-8]{1}[\\+\\#]{0,1}\" [\"color\"]=> string(1) \"b\" [\"id\"]=> string(1) \"N\" [\"sq\"]=> array(2) { [\"current\"]=> string(0) \"\" [\"next\"]=> string(2) \"c6\" } } [\"fen\"]=> string(60) \"r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -\" } } The initial FEN string can be accessed as shown below. echo $board->startFen; rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - Board to PNG Image \u2728 PNG stands for Portable Network Graphics and is a widely used format for image files. Not to be confused with PGN, the text-based file format to annotate chess games. Chess\\Media\\BoardToPng converts a chess board object to a PNG image. use Chess\\FenToBoardFactory; use Chess\\Media\\BoardToPng; $board = FenToBoardFactory::create('1rbq1rk1/p1b1nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1R1K w - - bm Nf6+'); $filename = (new BoardToPng($board, $flip = true))->output(__DIR__); Try this thing! Share a puzzling chess position with friends for further study. Board to MP4 \u2728 Text-based PGN movetexts can be easily converted to MP4, a widely-used video format which comes in handy for pausing the games. Chess\\Media\\BoardToMp4 allows to convert a chess board object to an MP4 video. use Chess\\Media\\BoardToMp4; use Chess\\Variant\\Classical\\Board; $movetext = '1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7'; $board = new Board(); $filename = (new BoardToMp4($movetext, $board, $flip = false))->output(__DIR__); MP4 videos are especially useful to pause the game at a specific position. Image to FEN \u2728 A chess piece image recognizer has been created in the chesslablab/perception repository with the help of a multilayer neural network. Chess\\Media\\ImgToPiecePlacement relies on this recognizer to convert a GD image into a piece placement in FEN format. use Chess\\Media\\ImgToPiecePlacement; $image = imagecreatefrompng(__DIR__ . '/01_kaufman.png'); $prediction = (new ImgToPiecePlacement($image))->predict(); echo $prediction; 1rbq1rk1/p1b1nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1R1K For optimal use, it is recommended to make predictions on chessboard images using classical chess pieces like the Kaufman test attached below.","title":"Data Conversion"},{"location":"data-conversion/#data-conversion","text":"","title":"Data Conversion"},{"location":"data-conversion/#fen-to-board","text":"\u2728 FEN stands for Forsyth-Edwards Notation and is the standard way for describing chess positions using text strings. At some point you'll definitely want to convert a FEN string into a chessboard object for further processing, and this can be done with the Chess\\FenToBoardFactory class according to the variants supported. When a single parameter is passed into the factory's create method, it is assumed that you want to create a classical chess board object. use Chess\\FenToBoardFactory; $board = FenToBoardFactory::create('rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -'); $board->play('w', 'Nc3'); $board->play('b', 'Nc6'); echo $board->toFen(); r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - In this example the game history contains two moves only. var_dump($board->history); array(2) { [0]=> array(4) { [\"castlingAbility\"]=> string(4) \"KQkq\" [\"sq\"]=> string(2) \"b1\" [\"move\"]=> array(7) { [\"pgn\"]=> string(3) \"Nc3\" [\"isCapture\"]=> bool(false) [\"isCheck\"]=> bool(false) [\"type\"]=> string(48) \"N[a-h]{0,1}[1-8]{0,1}[a-h]{1}[1-8]{1}[\\+\\#]{0,1}\" [\"color\"]=> string(1) \"w\" [\"id\"]=> string(1) \"N\" [\"sq\"]=> array(2) { [\"current\"]=> string(0) \"\" [\"next\"]=> string(2) \"c3\" } } [\"fen\"]=> string(59) \"rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -\" } [1]=> array(4) { [\"castlingAbility\"]=> string(4) \"KQkq\" [\"sq\"]=> string(2) \"b8\" [\"move\"]=> array(7) { [\"pgn\"]=> string(3) \"Nc6\" [\"isCapture\"]=> bool(false) [\"isCheck\"]=> bool(false) [\"type\"]=> string(48) \"N[a-h]{0,1}[1-8]{0,1}[a-h]{1}[1-8]{1}[\\+\\#]{0,1}\" [\"color\"]=> string(1) \"b\" [\"id\"]=> string(1) \"N\" [\"sq\"]=> array(2) { [\"current\"]=> string(0) \"\" [\"next\"]=> string(2) \"c6\" } } [\"fen\"]=> string(60) \"r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -\" } } The initial FEN string can be accessed as shown below. echo $board->startFen; rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -","title":"FEN to Board"},{"location":"data-conversion/#board-to-png-image","text":"\u2728 PNG stands for Portable Network Graphics and is a widely used format for image files. Not to be confused with PGN, the text-based file format to annotate chess games. Chess\\Media\\BoardToPng converts a chess board object to a PNG image. use Chess\\FenToBoardFactory; use Chess\\Media\\BoardToPng; $board = FenToBoardFactory::create('1rbq1rk1/p1b1nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1R1K w - - bm Nf6+'); $filename = (new BoardToPng($board, $flip = true))->output(__DIR__); Try this thing! Share a puzzling chess position with friends for further study.","title":"Board to PNG Image"},{"location":"data-conversion/#board-to-mp4","text":"\u2728 Text-based PGN movetexts can be easily converted to MP4, a widely-used video format which comes in handy for pausing the games. Chess\\Media\\BoardToMp4 allows to convert a chess board object to an MP4 video. use Chess\\Media\\BoardToMp4; use Chess\\Variant\\Classical\\Board; $movetext = '1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7'; $board = new Board(); $filename = (new BoardToMp4($movetext, $board, $flip = false))->output(__DIR__); MP4 videos are especially useful to pause the game at a specific position.","title":"Board to MP4"},{"location":"data-conversion/#image-to-fen","text":"\u2728 A chess piece image recognizer has been created in the chesslablab/perception repository with the help of a multilayer neural network. Chess\\Media\\ImgToPiecePlacement relies on this recognizer to convert a GD image into a piece placement in FEN format. use Chess\\Media\\ImgToPiecePlacement; $image = imagecreatefrompng(__DIR__ . '/01_kaufman.png'); $prediction = (new ImgToPiecePlacement($image))->predict(); echo $prediction; 1rbq1rk1/p1b1nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1R1K For optimal use, it is recommended to make predictions on chessboard images using classical chess pieces like the Kaufman test attached below.","title":"Image to FEN"},{"location":"heuristics/","text":"Heuristics \u2728 If you ask a chess pro why a chess move is good, they'll probably give you a bunch of reasons, many of them intuitive, about why they made that decision. It is important to develop your pieces in the opening while trying to control the center of the board at the same time. Castling is an excellent move as long as the king gets safe. Then, in the middlegame space becomes an advantage. And if a complex position can be simplified when you have an advantage, then so much the better. The pawn structure could determine the endgame. The list of reasons goes on and on. The mathematician Claude Shannon came to the conclusion that there are more chess moves than atoms in the universe. The game is complex and you need to learn how to make decisions to play chess like a pro. Since no human can calculate more than, let's say 30 moves ahead, it's all about thinking in terms of heuristics. Heuristics are quick, mental shortcuts that we humans use to make decisions and solve problems in our daily lives. While far from being perfect, heuristics are approximations that help manage cognitive load. Listed below are the chess heuristics implemented in PHP Chess. Heuristic Description Evaluation Absolute fork A tactic in which a piece attacks multiple pieces at the same time. It is a double attack. A fork involving the enemy king is an absolute fork. Chess\\Eval\\AbsoluteForkEval Absolute pin A tactic that occurs when a piece is shielding the king, so it cannot move out of the line of attack because the king would be put in check. Chess\\Eval\\AbsolutePinEval Absolute skewer A tactic in which the enemy king is involved. The king is in check, and it has to move out of danger exposing a more valuable piece to capture. Only line pieces (bishops, rooks and queens) can skewer. Chess\\Eval\\AbsoluteSkewerEval Advanced pawn A pawn that is on the fifth rank or higher. Chess\\Eval\\AdvancedPawnEval Attack If a piece is under threat of being attacked, it means it could be taken after a sequence of captures resulting in a material gain. This indicates a forcing move in that a player is to reply in a certain way. On the next turn, it should be defended by a piece or moved to a safe square. The player with the greater number of material points under attack has an advantage. Chess\\Eval\\AttackEval Backward pawn The last pawn protecting other pawns in its chain. It is considered a weakness because it cannot advance safely. Chess\\Eval\\BackwardPawnEval Bad bishop A bishop that is on the same color as most of own pawns. Chess\\Eval\\BadBishopEval Bishop outpost A bishop on an outpost square is considered a positional advantage because it cannot be attacked by enemy pawns, and as a result, it is often exchanged for another piece. Chess\\Eval\\BishopOutpostEval Bishop pair The player with both bishops may definitely have an advantage, especially in the endgame. Furthermore, two bishops can deliver checkmate. Chess\\Eval\\BishopPairEval Center It is advantageous to control the central squares as well as to place a piece in the center. Chess\\Eval\\CenterEval Checkability Having a king that can be checked is usually considered a disadvantage, and vice versa, it is considered advantageous to have a king that cannot be checked. A checkable king is vulnerable to forcing moves. Chess\\Eval\\CheckabilityEval Connectivity The connectivity of the pieces measures how loosely the pieces are. Chess\\Eval\\ConnectivityEval Defense Chess\\Eval\\DefenseEval Diagonal opposition The same as direct opposition, but the two kings are apart from each other diagonally. Chess\\Eval\\DiagonalOppositionEval Direct opposition A position in which the kings are facing each other being two squares apart on the same rank or file. In this situation, the player not having to move is said to have the opposition. Chess\\Eval\\DirectOppositionEval Discovered check A discovered check occurs when the opponent's king can be checked by moving a piece out of the way of another. Chess\\Eval\\DiscoveredCheckEval Doubled pawn A pawn is doubled if there are two pawns of the same color on the same file. Chess\\Eval\\DoubledPawnEval Far-advanced pawn A pawn that is threatening to promote. Chess\\Eval\\FarAdvancedPawnEval Isolated pawn A pawn without friendly pawns on the adjacent files. Since it cannot be defended by other pawns it is considered a weakness. Chess\\Eval\\IsolatedPawnEval King safety An unsafe king leads to uncertainty. The probability of unexpected, forced moves will increase as the opponent's pieces get closer to it. Chess\\Eval\\KingSafetyEval Knight outpost A knight on an outpost square is considered a positional advantage because it cannot be attacked by enemy pawns, and as a result, it is often exchanged for a bishop. Chess\\Eval\\KnightOutpostEval Material The player with the most material points has an advantage. The relative values of the pieces are assigned this way: 1 point to a pawn, 3.2 points to a knight, 3.33 points to a bishop, 5.1 points to a rook and 8.8 points to a queen. Chess\\Eval\\MaterialEval Overloading A piece that is overloaded with defensive tasks is vulnerable because it can be deflected, meaning it could be forced to leave the square it occupies, typically resulting in an advantage for the opponent. Chess\\Eval\\OverloadingEval Passed pawn A pawn with no opposing pawns on either the same file or adjacent files to prevent it from being promoted. Chess\\Eval\\PassedPawnEval Pressure This is a measure of the number of squares targeted by each player that require special attention. It often indicates the step prior to an attack. The player with the greater number of them has an advantage. Chess\\Eval\\PressureEval Protection If a piece is unprotected, it means that there are no other pieces defending it, and therefore it can be taken for free resulting in a material gain. This indicates a forcing move in that a player is to reply in a certain way. On the next turn, it should be defended by a piece or moved to a safe square. The player with the greater number of material points under protection has an advantage. Chess\\Eval\\ProtectionEval Relative fork A tactic in which a piece attacks multiple pieces at the same time. It is a double attack. A fork not involving the enemy king is a relative fork. Chess\\Eval\\RelativeForkEval Relative pin A tactic that occurs when a piece is shielding a more valuable piece, so if it moves out of the line of attack the more valuable piece can be captured resulting in a material gain. Chess\\Eval\\RelativePinEval Space This is a measure of the number of squares controlled by each player. Chess\\Eval\\SpaceEval Square outpost A square protected by a pawn that cannot be attacked by an opponent's pawn. Chess\\Eval\\SqOutpostEval The evaluation features are used in two heuristics classes: Chess\\FenHeuristics and Chess\\SanHeuristic . The former allows to transform a FEN position to numbers while the latter transforms an entire chess game in SAN format to numbers. use Chess\\FenHeuristics; use Chess\\FenToBoardFactory; use Chess\\Function\\CompleteFunction; $function = new CompleteFunction(); $fen = 'rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -'; $board = FenToBoardFactory::create($fen); $result = [ 'names' => $function->names(), 'balance' => (new FenHeuristics($function, $board))->getBalance(), ]; print_r($result); Array ( [names] => Array ( [0] => Material [1] => Center [2] => Connectivity [3] => Space [4] => Pressure [5] => King safety [6] => Protection [7] => Discovered check [8] => Doubled pawn [9] => Passed pawn [10] => Advanced pawn [11] => Far-advanced pawn [12] => Isolated pawn [13] => Backward pawn [14] => Defense [15] => Absolute skewer [16] => Absolute pin [17] => Relative pin [18] => Absolute fork [19] => Relative fork [20] => Outpost square [21] => Knight outpost [22] => Bishop outpost [23] => Bishop pair [24] => Bad bishop [25] => Diagonal opposition [26] => Direct opposition [27] => Attack [28] => Overloading ) [balance] => Array ( [0] => 0 [1] => 12.4 [2] => 0 [3] => 3 [4] => 0 [5] => 0 [6] => 0 [7] => 0 [8] => 0 [9] => 0 [10] => 0 [11] => 0 [12] => 0 [13] => 0 [14] => 0 [15] => 0 [16] => 0 [17] => 0 [18] => 0 [19] => 0 [20] => 0 [21] => 0 [22] => 0 [23] => 0 [24] => 0 [25] => 0 [26] => 0 [27] => 0 [28] => 0 ) ) A chess game can be plotted in terms of balance. +1 is the best possible evaluation for White and -1 the best possible evaluation for Black. Both forces being set to 0 means they're balanced. use Chess\\SanHeuristic; use Chess\\Function\\CompleteFunction; $function = new CompleteFunction(); $name = 'Space'; $movetext = '1.e4 d5 2.exd5 Qxd5'; $balance = (new SanHeuristic($function, $name, $movetext))->getBalance(); print_r($balance); Array ( [0] => 0 [1] => 1 [2] => 0.25 [3] => 0.5 [4] => -1 ) \ud83c\udf89 Chess positions and games can now be plotted on charts and processed with machine learning techniques.","title":"Heuristics"},{"location":"heuristics/#heuristics","text":"\u2728 If you ask a chess pro why a chess move is good, they'll probably give you a bunch of reasons, many of them intuitive, about why they made that decision. It is important to develop your pieces in the opening while trying to control the center of the board at the same time. Castling is an excellent move as long as the king gets safe. Then, in the middlegame space becomes an advantage. And if a complex position can be simplified when you have an advantage, then so much the better. The pawn structure could determine the endgame. The list of reasons goes on and on. The mathematician Claude Shannon came to the conclusion that there are more chess moves than atoms in the universe. The game is complex and you need to learn how to make decisions to play chess like a pro. Since no human can calculate more than, let's say 30 moves ahead, it's all about thinking in terms of heuristics. Heuristics are quick, mental shortcuts that we humans use to make decisions and solve problems in our daily lives. While far from being perfect, heuristics are approximations that help manage cognitive load. Listed below are the chess heuristics implemented in PHP Chess. Heuristic Description Evaluation Absolute fork A tactic in which a piece attacks multiple pieces at the same time. It is a double attack. A fork involving the enemy king is an absolute fork. Chess\\Eval\\AbsoluteForkEval Absolute pin A tactic that occurs when a piece is shielding the king, so it cannot move out of the line of attack because the king would be put in check. Chess\\Eval\\AbsolutePinEval Absolute skewer A tactic in which the enemy king is involved. The king is in check, and it has to move out of danger exposing a more valuable piece to capture. Only line pieces (bishops, rooks and queens) can skewer. Chess\\Eval\\AbsoluteSkewerEval Advanced pawn A pawn that is on the fifth rank or higher. Chess\\Eval\\AdvancedPawnEval Attack If a piece is under threat of being attacked, it means it could be taken after a sequence of captures resulting in a material gain. This indicates a forcing move in that a player is to reply in a certain way. On the next turn, it should be defended by a piece or moved to a safe square. The player with the greater number of material points under attack has an advantage. Chess\\Eval\\AttackEval Backward pawn The last pawn protecting other pawns in its chain. It is considered a weakness because it cannot advance safely. Chess\\Eval\\BackwardPawnEval Bad bishop A bishop that is on the same color as most of own pawns. Chess\\Eval\\BadBishopEval Bishop outpost A bishop on an outpost square is considered a positional advantage because it cannot be attacked by enemy pawns, and as a result, it is often exchanged for another piece. Chess\\Eval\\BishopOutpostEval Bishop pair The player with both bishops may definitely have an advantage, especially in the endgame. Furthermore, two bishops can deliver checkmate. Chess\\Eval\\BishopPairEval Center It is advantageous to control the central squares as well as to place a piece in the center. Chess\\Eval\\CenterEval Checkability Having a king that can be checked is usually considered a disadvantage, and vice versa, it is considered advantageous to have a king that cannot be checked. A checkable king is vulnerable to forcing moves. Chess\\Eval\\CheckabilityEval Connectivity The connectivity of the pieces measures how loosely the pieces are. Chess\\Eval\\ConnectivityEval Defense Chess\\Eval\\DefenseEval Diagonal opposition The same as direct opposition, but the two kings are apart from each other diagonally. Chess\\Eval\\DiagonalOppositionEval Direct opposition A position in which the kings are facing each other being two squares apart on the same rank or file. In this situation, the player not having to move is said to have the opposition. Chess\\Eval\\DirectOppositionEval Discovered check A discovered check occurs when the opponent's king can be checked by moving a piece out of the way of another. Chess\\Eval\\DiscoveredCheckEval Doubled pawn A pawn is doubled if there are two pawns of the same color on the same file. Chess\\Eval\\DoubledPawnEval Far-advanced pawn A pawn that is threatening to promote. Chess\\Eval\\FarAdvancedPawnEval Isolated pawn A pawn without friendly pawns on the adjacent files. Since it cannot be defended by other pawns it is considered a weakness. Chess\\Eval\\IsolatedPawnEval King safety An unsafe king leads to uncertainty. The probability of unexpected, forced moves will increase as the opponent's pieces get closer to it. Chess\\Eval\\KingSafetyEval Knight outpost A knight on an outpost square is considered a positional advantage because it cannot be attacked by enemy pawns, and as a result, it is often exchanged for a bishop. Chess\\Eval\\KnightOutpostEval Material The player with the most material points has an advantage. The relative values of the pieces are assigned this way: 1 point to a pawn, 3.2 points to a knight, 3.33 points to a bishop, 5.1 points to a rook and 8.8 points to a queen. Chess\\Eval\\MaterialEval Overloading A piece that is overloaded with defensive tasks is vulnerable because it can be deflected, meaning it could be forced to leave the square it occupies, typically resulting in an advantage for the opponent. Chess\\Eval\\OverloadingEval Passed pawn A pawn with no opposing pawns on either the same file or adjacent files to prevent it from being promoted. Chess\\Eval\\PassedPawnEval Pressure This is a measure of the number of squares targeted by each player that require special attention. It often indicates the step prior to an attack. The player with the greater number of them has an advantage. Chess\\Eval\\PressureEval Protection If a piece is unprotected, it means that there are no other pieces defending it, and therefore it can be taken for free resulting in a material gain. This indicates a forcing move in that a player is to reply in a certain way. On the next turn, it should be defended by a piece or moved to a safe square. The player with the greater number of material points under protection has an advantage. Chess\\Eval\\ProtectionEval Relative fork A tactic in which a piece attacks multiple pieces at the same time. It is a double attack. A fork not involving the enemy king is a relative fork. Chess\\Eval\\RelativeForkEval Relative pin A tactic that occurs when a piece is shielding a more valuable piece, so if it moves out of the line of attack the more valuable piece can be captured resulting in a material gain. Chess\\Eval\\RelativePinEval Space This is a measure of the number of squares controlled by each player. Chess\\Eval\\SpaceEval Square outpost A square protected by a pawn that cannot be attacked by an opponent's pawn. Chess\\Eval\\SqOutpostEval The evaluation features are used in two heuristics classes: Chess\\FenHeuristics and Chess\\SanHeuristic . The former allows to transform a FEN position to numbers while the latter transforms an entire chess game in SAN format to numbers. use Chess\\FenHeuristics; use Chess\\FenToBoardFactory; use Chess\\Function\\CompleteFunction; $function = new CompleteFunction(); $fen = 'rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -'; $board = FenToBoardFactory::create($fen); $result = [ 'names' => $function->names(), 'balance' => (new FenHeuristics($function, $board))->getBalance(), ]; print_r($result); Array ( [names] => Array ( [0] => Material [1] => Center [2] => Connectivity [3] => Space [4] => Pressure [5] => King safety [6] => Protection [7] => Discovered check [8] => Doubled pawn [9] => Passed pawn [10] => Advanced pawn [11] => Far-advanced pawn [12] => Isolated pawn [13] => Backward pawn [14] => Defense [15] => Absolute skewer [16] => Absolute pin [17] => Relative pin [18] => Absolute fork [19] => Relative fork [20] => Outpost square [21] => Knight outpost [22] => Bishop outpost [23] => Bishop pair [24] => Bad bishop [25] => Diagonal opposition [26] => Direct opposition [27] => Attack [28] => Overloading ) [balance] => Array ( [0] => 0 [1] => 12.4 [2] => 0 [3] => 3 [4] => 0 [5] => 0 [6] => 0 [7] => 0 [8] => 0 [9] => 0 [10] => 0 [11] => 0 [12] => 0 [13] => 0 [14] => 0 [15] => 0 [16] => 0 [17] => 0 [18] => 0 [19] => 0 [20] => 0 [21] => 0 [22] => 0 [23] => 0 [24] => 0 [25] => 0 [26] => 0 [27] => 0 [28] => 0 ) ) A chess game can be plotted in terms of balance. +1 is the best possible evaluation for White and -1 the best possible evaluation for Black. Both forces being set to 0 means they're balanced. use Chess\\SanHeuristic; use Chess\\Function\\CompleteFunction; $function = new CompleteFunction(); $name = 'Space'; $movetext = '1.e4 d5 2.exd5 Qxd5'; $balance = (new SanHeuristic($function, $name, $movetext))->getBalance(); print_r($balance); Array ( [0] => 0 [1] => 1 [2] => 0.25 [3] => 0.5 [4] => -1 ) \ud83c\udf89 Chess positions and games can now be plotted on charts and processed with machine learning techniques.","title":"Heuristics"},{"location":"installation/","text":"Installation Requirements PHP >= 8.1 Stockfish >= 15.1 Composer installation composer require chesslablab/php-chess","title":"Installation"},{"location":"installation/#installation","text":"","title":"Installation"},{"location":"installation/#requirements","text":"PHP >= 8.1 Stockfish >= 15.1","title":"Requirements"},{"location":"installation/#composer-installation","text":"composer require chesslablab/php-chess","title":"Composer installation"},{"location":"play-chess/","text":"Play Chess Play Randomly \u2728 Sometimes you want to play a random game of chess. You could loop 50 times and play a move by instantiating the Chess\\Computer\\RandomMove class like in the example below. use Chess\\Computer\\RandomMove; use Chess\\Variant\\Classical\\Board; $board = new Board(); for ($i = 0; $i < 50; $i++) { if ($move = (new RandomMove($board))->move()) { $board->play($board->turn, $move['pgn']); } } echo $board->movetext(); 1.e4 Nc6 2.Qf3 g6 3.b3 Rb8 4.Bb5 Nh6 5.Ke2 Na5 6.c3 Ng4 7.d3 h6 8.h4 Ra8 9.Kd1 b6 10.Ba4 h5 11.b4 Rh7 12.Bc2 Rh8 13.Ke1 a6 14.Kd1 Nb3 15.d4 Na5 16.g3 c6 17.Ne2 Ne5 18.Nf4 d6 19.Nxg6 Kd7 20.b5 Qe8 21.Na3 e6 22.Bd3 Rb8 23.dxe5 dxe5 24.Bb2 Rg8 25.Qg4 Ra8 The result obtained is a 24 move game since a move is considered to be completed after both players have played a turn. Play Like a Grandmaster \u2728 The players.json file in the Chess Server contains thousands of games by titled FIDE players. This file can be generated with the command line tools available in the Chess Data repo. Chess\\Computer\\GrandmasterMove figures out the next move to be made based on the players.json file that is passed to its constructor. use Chess\\Computer\\GrandmasterMove; use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $gmMove = (new GrandmasterMove(__DIR__.'/../data/json/players.json'))->move($board); print_r($gmMove); Array ( [pgn] => c5 [game] => Array ( [Event] => Tilburg [Site] => Tilburg [Date] => 1993.??.?? [White] => Morozevich, Alexander [Black] => Adams, Michael [Result] => 1-0 [ECO] => B23 [movetext] => 1.e4 c5 2.Nc3 Nc6 3.f4 g6 4.Nf3 Bg7 5.Bb5 Nd4 6.Nxd4 cxd4 7.Ne2 a6 8.Ba4 b5 9.Bb3 e6 10.O-O Ne7 11.d3 O-O 12.Qe1 f5 13.Bd2 Nc6 14.Kh1 Bb7 15.Ng1 h6 16.Nf3 Kh7 17.Qg3 Qe7 18.Rae1 a5 19.a3 Rab8 20.Nh4 Qf7 21.Qh3 Ba8 22.Rf3 a4 23.Ba2 b4 24.Bc1 b3 25.cxb3 axb3 26.Bb1 d6 27.Bd2 Kg8 28.g4 Ne7 29.gxf5 gxf5 30.Rg3 Kh7 31.Nf3 Bf6 32.Ng5+ Bxg5 33.fxg5 Ng6 34.Qxh6+ Kg8 35.h4 f4 36.Rh3 Rb7 37.h5 Ne5 38.Rg1 Rc7 39.Rh4 Qe8 40.g6 ) ) \ud83c\udf89 Let's now put our knowledge of chess openings to the test. Play Computer \u2728 The Universal Chess Interface (UCI) is an open communication protocol that enables chess engines to communicate with user interfaces. PHP Chess provides the Chess\\UciEngine\\UciEngine class representing an UCI engine. To follow this tutorial make sure to install Stockfish if you haven't already. sudo apt-get install stockfish Then, you are set up to play chess against the computer as described in the following example. use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $limit = new Limit(); $limit->depth = 3; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 9); $analysis = $stockfish->analysis($board, $limit); $board->playLan('b', $analysis['bestmove']); echo $board->movetext(); 1.e4 Nf6 You may want to play against Stockfish starting from a particular FEN with the help of Chess\\FenToBoardFactory . use Chess\\FenToBoardFactory; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $board = FenToBoardFactory::create('4k2r/pp1b1pp1/8/3pPp1p/P2P1P2/1P3N2/1qr3PP/R3QR1K w k -'); $limit = new Limit(); $limit->depth = 12; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 20); $analysis = $stockfish->analysis($board, $limit); $board->playLan('w', $analysis['bestmove']); echo $board->movetext(); 1.Rb1 The FEN is converted to a chess board object as described in the Data Conversion section. Then Stockfish's depth limit is set to 12 and the skill level to 20 . The same thing goes to starting a game from a particular SAN movetext. As you can see in the example below, Chess\\Play\\SanPlay is used for this purpose. use Chess\\Play\\SanPlay; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $movetext = '1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7'; $board = (new SanPlay($movetext))->validate()->board; $limit = new Limit(); $limit->depth = 12; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 20); $analysis = $stockfish->analysis($board, $limit); $board->playLan('w', $analysis['bestmove']); echo $board->movetext(); 1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7 8.h3 \ud83c\udf89 Can you beat the computer? Keep it up!","title":"Play Chess"},{"location":"play-chess/#play-chess","text":"","title":"Play Chess"},{"location":"play-chess/#play-randomly","text":"\u2728 Sometimes you want to play a random game of chess. You could loop 50 times and play a move by instantiating the Chess\\Computer\\RandomMove class like in the example below. use Chess\\Computer\\RandomMove; use Chess\\Variant\\Classical\\Board; $board = new Board(); for ($i = 0; $i < 50; $i++) { if ($move = (new RandomMove($board))->move()) { $board->play($board->turn, $move['pgn']); } } echo $board->movetext(); 1.e4 Nc6 2.Qf3 g6 3.b3 Rb8 4.Bb5 Nh6 5.Ke2 Na5 6.c3 Ng4 7.d3 h6 8.h4 Ra8 9.Kd1 b6 10.Ba4 h5 11.b4 Rh7 12.Bc2 Rh8 13.Ke1 a6 14.Kd1 Nb3 15.d4 Na5 16.g3 c6 17.Ne2 Ne5 18.Nf4 d6 19.Nxg6 Kd7 20.b5 Qe8 21.Na3 e6 22.Bd3 Rb8 23.dxe5 dxe5 24.Bb2 Rg8 25.Qg4 Ra8 The result obtained is a 24 move game since a move is considered to be completed after both players have played a turn.","title":"Play Randomly"},{"location":"play-chess/#play-like-a-grandmaster","text":"\u2728 The players.json file in the Chess Server contains thousands of games by titled FIDE players. This file can be generated with the command line tools available in the Chess Data repo. Chess\\Computer\\GrandmasterMove figures out the next move to be made based on the players.json file that is passed to its constructor. use Chess\\Computer\\GrandmasterMove; use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $gmMove = (new GrandmasterMove(__DIR__.'/../data/json/players.json'))->move($board); print_r($gmMove); Array ( [pgn] => c5 [game] => Array ( [Event] => Tilburg [Site] => Tilburg [Date] => 1993.??.?? [White] => Morozevich, Alexander [Black] => Adams, Michael [Result] => 1-0 [ECO] => B23 [movetext] => 1.e4 c5 2.Nc3 Nc6 3.f4 g6 4.Nf3 Bg7 5.Bb5 Nd4 6.Nxd4 cxd4 7.Ne2 a6 8.Ba4 b5 9.Bb3 e6 10.O-O Ne7 11.d3 O-O 12.Qe1 f5 13.Bd2 Nc6 14.Kh1 Bb7 15.Ng1 h6 16.Nf3 Kh7 17.Qg3 Qe7 18.Rae1 a5 19.a3 Rab8 20.Nh4 Qf7 21.Qh3 Ba8 22.Rf3 a4 23.Ba2 b4 24.Bc1 b3 25.cxb3 axb3 26.Bb1 d6 27.Bd2 Kg8 28.g4 Ne7 29.gxf5 gxf5 30.Rg3 Kh7 31.Nf3 Bf6 32.Ng5+ Bxg5 33.fxg5 Ng6 34.Qxh6+ Kg8 35.h4 f4 36.Rh3 Rb7 37.h5 Ne5 38.Rg1 Rc7 39.Rh4 Qe8 40.g6 ) ) \ud83c\udf89 Let's now put our knowledge of chess openings to the test.","title":"Play Like a Grandmaster"},{"location":"play-chess/#play-computer","text":"\u2728 The Universal Chess Interface (UCI) is an open communication protocol that enables chess engines to communicate with user interfaces. PHP Chess provides the Chess\\UciEngine\\UciEngine class representing an UCI engine. To follow this tutorial make sure to install Stockfish if you haven't already. sudo apt-get install stockfish Then, you are set up to play chess against the computer as described in the following example. use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $limit = new Limit(); $limit->depth = 3; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 9); $analysis = $stockfish->analysis($board, $limit); $board->playLan('b', $analysis['bestmove']); echo $board->movetext(); 1.e4 Nf6 You may want to play against Stockfish starting from a particular FEN with the help of Chess\\FenToBoardFactory . use Chess\\FenToBoardFactory; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $board = FenToBoardFactory::create('4k2r/pp1b1pp1/8/3pPp1p/P2P1P2/1P3N2/1qr3PP/R3QR1K w k -'); $limit = new Limit(); $limit->depth = 12; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 20); $analysis = $stockfish->analysis($board, $limit); $board->playLan('w', $analysis['bestmove']); echo $board->movetext(); 1.Rb1 The FEN is converted to a chess board object as described in the Data Conversion section. Then Stockfish's depth limit is set to 12 and the skill level to 20 . The same thing goes to starting a game from a particular SAN movetext. As you can see in the example below, Chess\\Play\\SanPlay is used for this purpose. use Chess\\Play\\SanPlay; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $movetext = '1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7'; $board = (new SanPlay($movetext))->validate()->board; $limit = new Limit(); $limit->depth = 12; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 20); $analysis = $stockfish->analysis($board, $limit); $board->playLan('w', $analysis['bestmove']); echo $board->movetext(); 1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7 8.h3 \ud83c\udf89 Can you beat the computer? Keep it up!","title":"Play Computer"},{"location":"read-moves/","text":"Read Moves Portable Game Notation (PGN) \u2728 Portable Game Notation is a human-readable text format that allows chess players to read and write chess games. PGN is convenient for when reading chess games annotated by humans, for example, those ones available in online databases or published in chess websites. 1.e4 e5 2.Nf3 Nf6 3.d4 Nxe4 4.Bd3 d5 5.Nxe5 Nd7 6.Nxd7 Bxd7 7.Nd2 Nxd2 8.Bxd2 Bd6 9.O-O h5 10.Qe1+ Kf8 11.Bb4 Qe7 12.Bxd6 Qxd6 13.Qd2 Re8 14.Rae1 Rh6 15.Qg5 c6 16.Rxe8+ Bxe8 17.Re1 Qf6 18.Qe3 Bd7 19.h3 h4 20.c4 dxc4 21.Bxc4 b5 22.Qa3+ Kg8 23.Qxa7 Qd8 24.Bb3 Rd6 25.Re4 Be6 26.Bxe6 Rxe6 27.Rxe6 fxe6 28.Qc5 Qa5 29.Qxc6 Qe1+ 30.Kh2 Qxf2 31.Qxe6+ Kh7 32.Qe4+ Kg8 33.b3 Qxa2 34.Qe8+ Kh7 35.Qxb5 Qf2 36.Qe5 Qb2 37.Qe4+ Kg8 38.Qd3 Qf2 39.Qc3 Qf4+ 40.Kg1 Kh7 41.Qd3+ g6 42.Qd1 Qe3+ 43.Kh1 g5 44.d5 g4 45.hxg4 h3 46.Qf3 1\u20130 World Chess Championship 2021. (2023, July 3). In Wikipedia. https://en.wikipedia.org/wiki/World_Chess_Championship_2021 As you may probably know, a chess opening is the group of initial moves of a chess game. This definition applies to classical chess, however, there is no such thing as a chess opening in either Capablanca chess or Chess960. Those two variants were originally conceived to minimize memorization, so when it comes to chess openings it is assumed that we're in the realms of classical chess. ECO, which stands for Encyclopaedia of Chess Openings, is a standard classification system for chess openings. Having said all that, let's now look at B54 which is the ECO code for \"Sicilian Defense: Modern Variations, Main Line\". use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $board->play('b', 'c5'); $board->play('w', 'Nf3'); $board->play('b', 'd6'); $board->play('w', 'd4'); $board->play('b', 'cxd4'); $board->play('w', 'Nxd4'); echo $board->toString(); r n b q k b n r p p . . p p p p . . . p . . . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R The play() method in the Chess\\Variant\\Classical\\Board class allows to make moves in PGN format. So far so good, but if you're new to chess you may well play a wrong move in the Sicilian Defense: 4...Na6. $board->play('b', 'Na6'); echo $board->toString(); r . b q k b n r p p . . p p p p n . . p . . . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R No worries! The undo() method comes to the rescue to take back a move. $board = $board->undo(); $board->play('b', 'Nf6'); echo $board->movetext(); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 The movetext() method is used to obtain the moves played in the game using Standard Algebraic Notation. Let's continue practicing chess openings. Now, what if you want to play a bunch of moves at once instead of one by one as in the previous example? Chess\\Play\\SanPlay allows to easily do so. use Chess\\Play\\SanPlay; $movetext = '1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6'; $board = (new SanPlay($movetext))->validate()->board; echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R Please note that the validate() method will throw an exception if the movetext is not valid. Once the $board object is successfully created, the game can be continued from that particular position. $board->play('w', 'Bb5+'); echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . B . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K . . R Every time a move is made, the state of the board changes. Chess\\Variant\\Classical\\Board provides you with plenty of methods to interact with a chess board object. It is a quite common use case to query the board state. As discussed in the Home section, you may want to check out the corresponding tests for further details on how to use it. The unit tests are the best documentation. They contain hundreds of real examples on how to use the PHP Chess library. The isCheck() method will confirm that the white king is in check after 5.Bb5+ while isMate() will confirm that it has not been mated. var_dump($board->isCheck()); bool(true) var_dump($board->isMate()); bool(false) Similarly, you may want to know if the current position is a draw. The isStalemate() method is to find out if the current position is a stalemate while isFivefoldRepetition() will confirm if the game is drawn because of a fivefold repetition. var_dump($board->isStalemate()); bool(false) var_dump($board->isFivefoldRepetition()); bool(false) Text comments in curly brackets can optionally be used in SAN movetexts as well as Numeric Annotation Glyphs . The example below shows how Chess\\Play\\SanPlay is used to validate a SAN movetext that contains NAGs. Remember, the validate() method will throw an exception if the movetext is not valid. use Chess\\Play\\SanPlay; $movetext = '1.e4 c5 2.Nf3 $1 d6 3.d4 cxd4 4.Nxd4 $48 Nf6 $113'; $sanPlay = (new SanPlay($movetext))->validate(); echo $sanPlay->sanMovetext->filtered(); 1.e4 c5 2.Nf3 $1 d6 3.d4 cxd4 4.Nxd4 $48 Nf6 $113 Comments and NAGs can be removed by passing the false value to the first and second arguments of the filtered() method. echo $sanPlay->sanMovetext->filtered($comments = true, $nags = false); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 \ud83c\udf89 Next, let's learn how to process chess moves from a graphical user interface. Long Algebraic Notation (LAN) \u2728 The UCI protocol enables chess engines to communicate with user interfaces (UI) using Long Algebraic Notation (LAN) for moves. use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->playLan('w', 'e2e4'); $board->playLan('b', 'c7c5'); $board->playLan('w', 'g1f3'); $board->playLan('b', 'd7d6'); $board->playLan('w', 'd2d4'); $board->playLan('b', 'c5d4'); $board->playLan('w', 'f3d4'); $board->playLan('b', 'g8f6'); echo $board->movetext(); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 Chess\\Play\\LanPlay allows to play a bunch of LAN moves at once instead of one by one. use Chess\\Play\\LanPlay; $movetext = '1.e2e4 c7c5 2.g1f3 d7d6 3.d2d4 c5d4 4.f3d4 g8f6'; $board = (new LanPlay($movetext))->validate()->board; echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R \ud83c\udf89 And, it's easy! Recursive Annotation Variation (RAV) \u2728 RAV stands for Recursive Annotation Variation. It is an extension of the Standard Algebaric Notation (SAN) format that allows to annotate chess variations. This format is especially useful for tutorials, notable games, chess studies and so on. Comments are enclosed in curly brackets. Variations are enclosed in parentheses which can be nested recursively as many times as required with the trait that the previous move may need to be undone in order to play a variation. The example below describes how to play the Open Sicilian. 1.e4 c5 {enters the Sicilian Defense, the most popular and best-scoring response to White's first move.} (2.Nf3 {is played in about 80% of Master-level games after which there are three main options for Black.} (2... Nc6) (2... e6) (2... d6 {is Black's most common move.} 3.d4 {lines are collectively known as the Open Sicilian.} cxd4 4.Nxd4 Nf6 5.Nc3 {allows Black choose between four major variations: the Najdorf, Dragon, Classical and Scheveningen.} (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}))) Sicilian Defense. (2023, July 2). In Wikipedia. https://en.wikipedia.org/wiki/Sicilian_Defence Figure 1. The Open Sicilian explained with the help of comments and variations. The RAV reader in Figure 1 displays the variation levels in different shades of gray. It is a 2D scrollable HTML table where the main line is shown in a white background color. The deeper the level, the darker the background color. Chess\\Play\\RavPlay allows to play a RAV movetext. use Chess\\Play\\RavPlay; $movetext = \"1.e4 c5 (2.Nf3 (2... Nc6) (2... e6) (2... d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6) (5...g6) (5...Nc6) (5...e6) ) )\"; $ravPlay = (new RavPlay($movetext))->validate(); print_r($ravPlay->fen); Array ( [0] => rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - [1] => rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 [2] => rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 [3] => rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - [4] => r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [5] => rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [6] => rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [7] => rnbqkbnr/pp2pppp/3p4/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq d3 [8] => rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq - [9] => rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - [10] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - [11] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq - [12] => rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [13] => rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [14] => r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [15] => rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - ) The FEN history is retrieved as an unidimensional array so it can be easily consumed by a frontend UI as shown in Figure 1. The movetext will also pass the validation if adding comments and NAGs. use Chess\\Play\\RavPlay; $movetext = \"1.e4 c5 {enters the Sicilian Defense.} (2.Nf3 (2... Nc6) (2... e6) (2... d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}) ) )\"; $ravPlay = (new RavPlay($movetext))->validate(); print_r($ravPlay->fen); Array ( [0] => rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - [1] => rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 [2] => rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 [3] => rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - [4] => r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [5] => rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [6] => rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [7] => rnbqkbnr/pp2pppp/3p4/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq d3 [8] => rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq - [9] => rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - [10] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - [11] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq - [12] => rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [13] => rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [14] => r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [15] => rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - ) This is how to obtain the validated movetext. $movetext = $ravPlay->ravMovetext->movetext; The filtered() method is to remove tabs and spaces. $movetext = $ravPlay->ravMovetext->filtered(); echo $movetext; 1.e4 c5 {enters the Sicilian Defense, the most popular and best-scoring response to White's first move.} (2.Nf3 {is played in about 80% of Master-level games after which there are three main options for Black.} (2...Nc6) (2...e6) (2...d6 {is Black's most common move.} 3.d4 {lines are collectively known as the Open Sicilian.} cxd4 4.Nxd4 Nf6 5.Nc3 {allows Black choose between four major variations: the Najdorf, Dragon, Classical and Scheveningen.} (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}))) Comments and NAGs can be removed by passing the false value to the first and second arguments of the filtered() method. $movetext = $ravPlay->ravMovetext->filtered($comments = false); echo $movetext; 1.e4 c5 (2.Nf3 (2...Nc6) (2...e6) (2...d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6) (5...g6) (5...Nc6) (5...e6))) And finally, as opposed to the start position, a RAV movetext can also be started from a particular FEN position if passing a chess board object into the constructor of the class. As you can see in the example below, Chess\\FenToBoardFactory is used for this purpose. use Chess\\FenToBoardFactory; use Chess\\Play\\RavPlay; $movetext = \"1.Ra7 Kg8 2.Kg2 Kf8 3.Kf3 Ke8 4.Ke4 Kd8 5.Kd5 Kc8 (5...Ke8 6.Kd6 Kf8 7.Ke6 Kg8 8.Kf6 Kh8 9.Kg6 Kg8 10.Ra8#) 6.Kd6 Kb8 (6...Kd8 7.Ra8#) 7.Rc7 Ka8 8.Kc6 Kb8 9.Kb6 Ka8 10.Rc8#\"; $board = FenToBoardFactory::create('7k/8/8/8/8/8/8/R6K w - -'); $ravPlay = (new RavPlay($movetext, $board))->validate(); print_r($ravPlay->fen); Array ( [0] => 7k/8/8/8/8/8/8/R6K w - - [1] => 7k/R7/8/8/8/8/8/7K b - - [2] => 6k1/R7/8/8/8/8/8/7K w - - [3] => 6k1/R7/8/8/8/8/6K1/8 b - - [4] => 5k2/R7/8/8/8/8/6K1/8 w - - [5] => 5k2/R7/8/8/8/5K2/8/8 b - - [6] => 4k3/R7/8/8/8/5K2/8/8 w - - [7] => 4k3/R7/8/8/4K3/8/8/8 b - - [8] => 3k4/R7/8/8/4K3/8/8/8 w - - [9] => 3k4/R7/8/3K4/8/8/8/8 b - - [10] => 2k5/R7/8/3K4/8/8/8/8 w - - [11] => 4k3/R7/8/3K4/8/8/8/8 w - - [12] => 4k3/R7/3K4/8/8/8/8/8 b - - [13] => 5k2/R7/3K4/8/8/8/8/8 w - - [14] => 5k2/R7/4K3/8/8/8/8/8 b - - [15] => 6k1/R7/4K3/8/8/8/8/8 w - - [16] => 6k1/R7/5K2/8/8/8/8/8 b - - [17] => 7k/R7/5K2/8/8/8/8/8 w - - [18] => 7k/R7/6K1/8/8/8/8/8 b - - [19] => 6k1/R7/6K1/8/8/8/8/8 w - - [20] => R5k1/8/6K1/8/8/8/8/8 b - - [21] => 2k5/R7/3K4/8/8/8/8/8 b - - [22] => 1k6/R7/3K4/8/8/8/8/8 w - - [23] => 3k4/R7/3K4/8/8/8/8/8 w - - [24] => R2k4/8/3K4/8/8/8/8/8 b - - [25] => 1k6/2R5/3K4/8/8/8/8/8 b - - [26] => k7/2R5/3K4/8/8/8/8/8 w - - [27] => k7/2R5/2K5/8/8/8/8/8 b - - [28] => 1k6/2R5/2K5/8/8/8/8/8 w - - [29] => 1k6/2R5/1K6/8/8/8/8/8 b - - [30] => k7/2R5/1K6/8/8/8/8/8 w - - [31] => k1R5/8/1K6/8/8/8/8/8 b - - ) \ud83c\udf89 So this is amazing! That's all we need to read and write chess tutorials, guides and how-tos.","title":"Read Moves"},{"location":"read-moves/#read-moves","text":"","title":"Read Moves"},{"location":"read-moves/#portable-game-notation-pgn","text":"\u2728 Portable Game Notation is a human-readable text format that allows chess players to read and write chess games. PGN is convenient for when reading chess games annotated by humans, for example, those ones available in online databases or published in chess websites. 1.e4 e5 2.Nf3 Nf6 3.d4 Nxe4 4.Bd3 d5 5.Nxe5 Nd7 6.Nxd7 Bxd7 7.Nd2 Nxd2 8.Bxd2 Bd6 9.O-O h5 10.Qe1+ Kf8 11.Bb4 Qe7 12.Bxd6 Qxd6 13.Qd2 Re8 14.Rae1 Rh6 15.Qg5 c6 16.Rxe8+ Bxe8 17.Re1 Qf6 18.Qe3 Bd7 19.h3 h4 20.c4 dxc4 21.Bxc4 b5 22.Qa3+ Kg8 23.Qxa7 Qd8 24.Bb3 Rd6 25.Re4 Be6 26.Bxe6 Rxe6 27.Rxe6 fxe6 28.Qc5 Qa5 29.Qxc6 Qe1+ 30.Kh2 Qxf2 31.Qxe6+ Kh7 32.Qe4+ Kg8 33.b3 Qxa2 34.Qe8+ Kh7 35.Qxb5 Qf2 36.Qe5 Qb2 37.Qe4+ Kg8 38.Qd3 Qf2 39.Qc3 Qf4+ 40.Kg1 Kh7 41.Qd3+ g6 42.Qd1 Qe3+ 43.Kh1 g5 44.d5 g4 45.hxg4 h3 46.Qf3 1\u20130 World Chess Championship 2021. (2023, July 3). In Wikipedia. https://en.wikipedia.org/wiki/World_Chess_Championship_2021 As you may probably know, a chess opening is the group of initial moves of a chess game. This definition applies to classical chess, however, there is no such thing as a chess opening in either Capablanca chess or Chess960. Those two variants were originally conceived to minimize memorization, so when it comes to chess openings it is assumed that we're in the realms of classical chess. ECO, which stands for Encyclopaedia of Chess Openings, is a standard classification system for chess openings. Having said all that, let's now look at B54 which is the ECO code for \"Sicilian Defense: Modern Variations, Main Line\". use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $board->play('b', 'c5'); $board->play('w', 'Nf3'); $board->play('b', 'd6'); $board->play('w', 'd4'); $board->play('b', 'cxd4'); $board->play('w', 'Nxd4'); echo $board->toString(); r n b q k b n r p p . . p p p p . . . p . . . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R The play() method in the Chess\\Variant\\Classical\\Board class allows to make moves in PGN format. So far so good, but if you're new to chess you may well play a wrong move in the Sicilian Defense: 4...Na6. $board->play('b', 'Na6'); echo $board->toString(); r . b q k b n r p p . . p p p p n . . p . . . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R No worries! The undo() method comes to the rescue to take back a move. $board = $board->undo(); $board->play('b', 'Nf6'); echo $board->movetext(); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 The movetext() method is used to obtain the moves played in the game using Standard Algebraic Notation. Let's continue practicing chess openings. Now, what if you want to play a bunch of moves at once instead of one by one as in the previous example? Chess\\Play\\SanPlay allows to easily do so. use Chess\\Play\\SanPlay; $movetext = '1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6'; $board = (new SanPlay($movetext))->validate()->board; echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R Please note that the validate() method will throw an exception if the movetext is not valid. Once the $board object is successfully created, the game can be continued from that particular position. $board->play('w', 'Bb5+'); echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . B . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K . . R Every time a move is made, the state of the board changes. Chess\\Variant\\Classical\\Board provides you with plenty of methods to interact with a chess board object. It is a quite common use case to query the board state. As discussed in the Home section, you may want to check out the corresponding tests for further details on how to use it. The unit tests are the best documentation. They contain hundreds of real examples on how to use the PHP Chess library. The isCheck() method will confirm that the white king is in check after 5.Bb5+ while isMate() will confirm that it has not been mated. var_dump($board->isCheck()); bool(true) var_dump($board->isMate()); bool(false) Similarly, you may want to know if the current position is a draw. The isStalemate() method is to find out if the current position is a stalemate while isFivefoldRepetition() will confirm if the game is drawn because of a fivefold repetition. var_dump($board->isStalemate()); bool(false) var_dump($board->isFivefoldRepetition()); bool(false) Text comments in curly brackets can optionally be used in SAN movetexts as well as Numeric Annotation Glyphs . The example below shows how Chess\\Play\\SanPlay is used to validate a SAN movetext that contains NAGs. Remember, the validate() method will throw an exception if the movetext is not valid. use Chess\\Play\\SanPlay; $movetext = '1.e4 c5 2.Nf3 $1 d6 3.d4 cxd4 4.Nxd4 $48 Nf6 $113'; $sanPlay = (new SanPlay($movetext))->validate(); echo $sanPlay->sanMovetext->filtered(); 1.e4 c5 2.Nf3 $1 d6 3.d4 cxd4 4.Nxd4 $48 Nf6 $113 Comments and NAGs can be removed by passing the false value to the first and second arguments of the filtered() method. echo $sanPlay->sanMovetext->filtered($comments = true, $nags = false); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 \ud83c\udf89 Next, let's learn how to process chess moves from a graphical user interface.","title":"Portable Game Notation (PGN)"},{"location":"read-moves/#long-algebraic-notation-lan","text":"\u2728 The UCI protocol enables chess engines to communicate with user interfaces (UI) using Long Algebraic Notation (LAN) for moves. use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->playLan('w', 'e2e4'); $board->playLan('b', 'c7c5'); $board->playLan('w', 'g1f3'); $board->playLan('b', 'd7d6'); $board->playLan('w', 'd2d4'); $board->playLan('b', 'c5d4'); $board->playLan('w', 'f3d4'); $board->playLan('b', 'g8f6'); echo $board->movetext(); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 Chess\\Play\\LanPlay allows to play a bunch of LAN moves at once instead of one by one. use Chess\\Play\\LanPlay; $movetext = '1.e2e4 c7c5 2.g1f3 d7d6 3.d2d4 c5d4 4.f3d4 g8f6'; $board = (new LanPlay($movetext))->validate()->board; echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R \ud83c\udf89 And, it's easy!","title":"Long Algebraic Notation (LAN)"},{"location":"read-moves/#recursive-annotation-variation-rav","text":"\u2728 RAV stands for Recursive Annotation Variation. It is an extension of the Standard Algebaric Notation (SAN) format that allows to annotate chess variations. This format is especially useful for tutorials, notable games, chess studies and so on. Comments are enclosed in curly brackets. Variations are enclosed in parentheses which can be nested recursively as many times as required with the trait that the previous move may need to be undone in order to play a variation. The example below describes how to play the Open Sicilian. 1.e4 c5 {enters the Sicilian Defense, the most popular and best-scoring response to White's first move.} (2.Nf3 {is played in about 80% of Master-level games after which there are three main options for Black.} (2... Nc6) (2... e6) (2... d6 {is Black's most common move.} 3.d4 {lines are collectively known as the Open Sicilian.} cxd4 4.Nxd4 Nf6 5.Nc3 {allows Black choose between four major variations: the Najdorf, Dragon, Classical and Scheveningen.} (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}))) Sicilian Defense. (2023, July 2). In Wikipedia. https://en.wikipedia.org/wiki/Sicilian_Defence Figure 1. The Open Sicilian explained with the help of comments and variations. The RAV reader in Figure 1 displays the variation levels in different shades of gray. It is a 2D scrollable HTML table where the main line is shown in a white background color. The deeper the level, the darker the background color. Chess\\Play\\RavPlay allows to play a RAV movetext. use Chess\\Play\\RavPlay; $movetext = \"1.e4 c5 (2.Nf3 (2... Nc6) (2... e6) (2... d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6) (5...g6) (5...Nc6) (5...e6) ) )\"; $ravPlay = (new RavPlay($movetext))->validate(); print_r($ravPlay->fen); Array ( [0] => rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - [1] => rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 [2] => rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 [3] => rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - [4] => r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [5] => rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [6] => rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [7] => rnbqkbnr/pp2pppp/3p4/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq d3 [8] => rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq - [9] => rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - [10] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - [11] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq - [12] => rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [13] => rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [14] => r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [15] => rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - ) The FEN history is retrieved as an unidimensional array so it can be easily consumed by a frontend UI as shown in Figure 1. The movetext will also pass the validation if adding comments and NAGs. use Chess\\Play\\RavPlay; $movetext = \"1.e4 c5 {enters the Sicilian Defense.} (2.Nf3 (2... Nc6) (2... e6) (2... d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}) ) )\"; $ravPlay = (new RavPlay($movetext))->validate(); print_r($ravPlay->fen); Array ( [0] => rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - [1] => rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 [2] => rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 [3] => rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - [4] => r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [5] => rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [6] => rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [7] => rnbqkbnr/pp2pppp/3p4/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq d3 [8] => rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq - [9] => rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - [10] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - [11] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq - [12] => rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [13] => rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [14] => r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [15] => rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - ) This is how to obtain the validated movetext. $movetext = $ravPlay->ravMovetext->movetext; The filtered() method is to remove tabs and spaces. $movetext = $ravPlay->ravMovetext->filtered(); echo $movetext; 1.e4 c5 {enters the Sicilian Defense, the most popular and best-scoring response to White's first move.} (2.Nf3 {is played in about 80% of Master-level games after which there are three main options for Black.} (2...Nc6) (2...e6) (2...d6 {is Black's most common move.} 3.d4 {lines are collectively known as the Open Sicilian.} cxd4 4.Nxd4 Nf6 5.Nc3 {allows Black choose between four major variations: the Najdorf, Dragon, Classical and Scheveningen.} (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}))) Comments and NAGs can be removed by passing the false value to the first and second arguments of the filtered() method. $movetext = $ravPlay->ravMovetext->filtered($comments = false); echo $movetext; 1.e4 c5 (2.Nf3 (2...Nc6) (2...e6) (2...d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6) (5...g6) (5...Nc6) (5...e6))) And finally, as opposed to the start position, a RAV movetext can also be started from a particular FEN position if passing a chess board object into the constructor of the class. As you can see in the example below, Chess\\FenToBoardFactory is used for this purpose. use Chess\\FenToBoardFactory; use Chess\\Play\\RavPlay; $movetext = \"1.Ra7 Kg8 2.Kg2 Kf8 3.Kf3 Ke8 4.Ke4 Kd8 5.Kd5 Kc8 (5...Ke8 6.Kd6 Kf8 7.Ke6 Kg8 8.Kf6 Kh8 9.Kg6 Kg8 10.Ra8#) 6.Kd6 Kb8 (6...Kd8 7.Ra8#) 7.Rc7 Ka8 8.Kc6 Kb8 9.Kb6 Ka8 10.Rc8#\"; $board = FenToBoardFactory::create('7k/8/8/8/8/8/8/R6K w - -'); $ravPlay = (new RavPlay($movetext, $board))->validate(); print_r($ravPlay->fen); Array ( [0] => 7k/8/8/8/8/8/8/R6K w - - [1] => 7k/R7/8/8/8/8/8/7K b - - [2] => 6k1/R7/8/8/8/8/8/7K w - - [3] => 6k1/R7/8/8/8/8/6K1/8 b - - [4] => 5k2/R7/8/8/8/8/6K1/8 w - - [5] => 5k2/R7/8/8/8/5K2/8/8 b - - [6] => 4k3/R7/8/8/8/5K2/8/8 w - - [7] => 4k3/R7/8/8/4K3/8/8/8 b - - [8] => 3k4/R7/8/8/4K3/8/8/8 w - - [9] => 3k4/R7/8/3K4/8/8/8/8 b - - [10] => 2k5/R7/8/3K4/8/8/8/8 w - - [11] => 4k3/R7/8/3K4/8/8/8/8 w - - [12] => 4k3/R7/3K4/8/8/8/8/8 b - - [13] => 5k2/R7/3K4/8/8/8/8/8 w - - [14] => 5k2/R7/4K3/8/8/8/8/8 b - - [15] => 6k1/R7/4K3/8/8/8/8/8 w - - [16] => 6k1/R7/5K2/8/8/8/8/8 b - - [17] => 7k/R7/5K2/8/8/8/8/8 w - - [18] => 7k/R7/6K1/8/8/8/8/8 b - - [19] => 6k1/R7/6K1/8/8/8/8/8 w - - [20] => R5k1/8/6K1/8/8/8/8/8 b - - [21] => 2k5/R7/3K4/8/8/8/8/8 b - - [22] => 1k6/R7/3K4/8/8/8/8/8 w - - [23] => 3k4/R7/3K4/8/8/8/8/8 w - - [24] => R2k4/8/3K4/8/8/8/8/8 b - - [25] => 1k6/2R5/3K4/8/8/8/8/8 b - - [26] => k7/2R5/3K4/8/8/8/8/8 w - - [27] => k7/2R5/2K5/8/8/8/8/8 b - - [28] => 1k6/2R5/2K5/8/8/8/8/8 w - - [29] => 1k6/2R5/1K6/8/8/8/8/8 b - - [30] => k7/2R5/1K6/8/8/8/8/8 w - - [31] => k1R5/8/1K6/8/8/8/8/8 b - - ) \ud83c\udf89 So this is amazing! That's all we need to read and write chess tutorials, guides and how-tos.","title":"Recursive Annotation Variation (RAV)"},{"location":"your-first-move/","text":"Your First Move \u2728 Some familiarity with chess terms and concepts is required but if you're new to chess this tutorial will guide you through how to easily create amazing apps with PHP Chess. Happy coding and learning! The Chess\\Variant\\Classical\\Board class is the easiest way to get started with PHP Chess. use Chess\\Variant\\Classical\\Board; $board = new Board(); If you have ever attended a chess tournament, you've probably noticed that each player writes down their move in PGN format on a piece of paper. PGN stands for Portable Game Notation and is a human-readable format that allows chess players to read and write chess games. When it comes to computer chess, though, a more appropriate machine-readable format called Long Algebraic Notation (LAN) is often used instead. Be that as it may, you're already set up to play classical chess either in PGN or LAN format. In PGN format: $board->play('w', 'e4'); In LAN format: $board->playLan('w', 'e2e4'); Every time a move is made, the state of the board changes. var_dump($board->toFen()); string(55) \"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3\" This is the chess position in Forsyth\u2013Edwards Notation (FEN) format after 1.e4. \ud83c\udf89 Congrats! 1.e4 is one of the best moves to start with.","title":"Your First Move"},{"location":"your-first-move/#your-first-move","text":"\u2728 Some familiarity with chess terms and concepts is required but if you're new to chess this tutorial will guide you through how to easily create amazing apps with PHP Chess. Happy coding and learning! The Chess\\Variant\\Classical\\Board class is the easiest way to get started with PHP Chess. use Chess\\Variant\\Classical\\Board; $board = new Board(); If you have ever attended a chess tournament, you've probably noticed that each player writes down their move in PGN format on a piece of paper. PGN stands for Portable Game Notation and is a human-readable format that allows chess players to read and write chess games. When it comes to computer chess, though, a more appropriate machine-readable format called Long Algebraic Notation (LAN) is often used instead. Be that as it may, you're already set up to play classical chess either in PGN or LAN format. In PGN format: $board->play('w', 'e4'); In LAN format: $board->playLan('w', 'e2e4'); Every time a move is made, the state of the board changes. var_dump($board->toFen()); string(55) \"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3\" This is the chess position in Forsyth\u2013Edwards Notation (FEN) format after 1.e4. \ud83c\udf89 Congrats! 1.e4 is one of the best moves to start with.","title":"Your First Move"}]} \ No newline at end of file +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"PHP Chess PHP Chess is a library implemented in PHP that allows to create chess apps out-of-the-box. One key feature is that it has been designed with OOP principles in mind and is thoroughly tested with plenty of unit tests. The unit tests are the best documentation. They contain hundreds of real examples on how to use PHP Chess. Almost every class in the src folder represents a concept that is tested accordingly in the tests/unit folder, in other words, the structure of the tests/unit folder is mirroring the structure of the src folder. For further details on how to use a particular class, please feel free to browse the codebase and check out the corresponding tests. The PHP Chess docs are more of a tutorial rather than an API description. Common Formats Supported Chess moves in LAN and PGN formats. Movetext processing in LAN, SAN and RAV formats. NAG support for SAN and RAV movetexts. UCI protocol. FEN conversion to chess board. Chess board conversion to PNG and JPG image. Chess board conversion to MP4 video. Acronym Description LAN Long Algebraic Notation PGN Portable Game Notation SAN Standard Algebraic Notation RAV Recursive Annotation Variation NAG Numeric Annotation Glyphs UCI Universal Chess Interface FEN Forsyth-Edwards Notation Chess Variants Multiple variants are supported with the default one being classical chess. Variant Chessboard Capablanca Chess\\Variant\\Capablanca\\Board Capablanca-Fischer Chess\\Variant\\CapablancaFischer\\Board Chess960 Chess\\Variant\\Chess960\\Board Classical Chess\\Variant\\Classical\\Board Dunsany Chess\\Variant\\Dunsany\\Board Losing Chess Chess\\Variant\\Losing\\Board RacingKings Chess\\Variant\\RacingKings\\Board UCI Engines Listed below are the UCI engines available at the moment. Stockfish Object-Oriented The chess board representation is an object of type SplObjectStorage as opposed to a bitboard. Thoroughly Tested PHP Chess has been developed with a test-driven development (TDD) approach. The tests/unit folder contains plenty of real examples. Lightweight PHP dependencies required: Rubix ML for machine learning. Imagine for image processing.","title":"Home"},{"location":"#php-chess","text":"PHP Chess is a library implemented in PHP that allows to create chess apps out-of-the-box. One key feature is that it has been designed with OOP principles in mind and is thoroughly tested with plenty of unit tests. The unit tests are the best documentation. They contain hundreds of real examples on how to use PHP Chess. Almost every class in the src folder represents a concept that is tested accordingly in the tests/unit folder, in other words, the structure of the tests/unit folder is mirroring the structure of the src folder. For further details on how to use a particular class, please feel free to browse the codebase and check out the corresponding tests. The PHP Chess docs are more of a tutorial rather than an API description.","title":"PHP Chess"},{"location":"#common-formats-supported","text":"Chess moves in LAN and PGN formats. Movetext processing in LAN, SAN and RAV formats. NAG support for SAN and RAV movetexts. UCI protocol. FEN conversion to chess board. Chess board conversion to PNG and JPG image. Chess board conversion to MP4 video. Acronym Description LAN Long Algebraic Notation PGN Portable Game Notation SAN Standard Algebraic Notation RAV Recursive Annotation Variation NAG Numeric Annotation Glyphs UCI Universal Chess Interface FEN Forsyth-Edwards Notation","title":"Common Formats Supported"},{"location":"#chess-variants","text":"Multiple variants are supported with the default one being classical chess. Variant Chessboard Capablanca Chess\\Variant\\Capablanca\\Board Capablanca-Fischer Chess\\Variant\\CapablancaFischer\\Board Chess960 Chess\\Variant\\Chess960\\Board Classical Chess\\Variant\\Classical\\Board Dunsany Chess\\Variant\\Dunsany\\Board Losing Chess Chess\\Variant\\Losing\\Board RacingKings Chess\\Variant\\RacingKings\\Board","title":"Chess Variants"},{"location":"#uci-engines","text":"Listed below are the UCI engines available at the moment. Stockfish","title":"UCI Engines"},{"location":"#object-oriented","text":"The chess board representation is an object of type SplObjectStorage as opposed to a bitboard.","title":"Object-Oriented"},{"location":"#thoroughly-tested","text":"PHP Chess has been developed with a test-driven development (TDD) approach. The tests/unit folder contains plenty of real examples.","title":"Thoroughly Tested"},{"location":"#lightweight","text":"PHP dependencies required: Rubix ML for machine learning. Imagine for image processing.","title":"Lightweight"},{"location":"chess-tutor/","text":"Chess Tutor Explain a FEN Position \u2728 Chess beginners often think they can checkmate the opponent's king quickly. However, there are so many different things to consider in order to understand a position. Chess\\Tutor\\FenEvaluation helps you improve your chess thinking process by evaluating a FEN position in terms of chess concepts like in the example below. use Chess\\FenToBoardFactory; use Chess\\Function\\CompleteFunction; use Chess\\Tutor\\FenEvaluation; $function = new CompleteFunction(); $board = FenToBoardFactory::create('8/5k2/4n3/8/8/1BK5/1B6/8 w - - 0 1'); $paragraph = (new FenEvaluation($function, $board))->paragraph; $text = implode(' ', $paragraph); echo $text; White has a decisive material advantage. White has a slightly better control of the center. The white pieces are significantly better connected. The white player is pressuring a little bit more squares than its opponent. White has a slight absolute pin advantage. White has the bishop pair. The knight on e6 is pinned shielding the king so it cannot move out of the line of attack because the king would be put in check. Overall, 6 heuristic evaluation features are favoring White while 0 are favoring Black. A heuristic evaluation is a quick numerical estimate of a chess position that suggests who may be better without considering checkmate. Please note that a heuristic evaluation is not the same thing as a chess calculation. Heuristic evaluations are often correct but may fail as long as they are based on probabilities more than anything else. \ud83c\udf89 This is a form of abductive reasoning. Explain a PGN Move \u2728 Typically, chess engines won't provide an explanation in easy-to-understand language about how a move changes the position on the board. Chess\\Tutor\\PgnEvaluation explains how a particular move changes the position. use Chess\\Function\\CompleteFunction; use Chess\\Play\\SanPlay; use Chess\\Tutor\\PgnEvaluation; $pgn = 'd4'; $function = new CompleteFunction(); $movetext = '1.Nf3 d5 2.g3 c5'; $board = (new SanPlay($movetext))->validate()->board; $paragraph = (new PgnEvaluation($pgn, $function, $board))->paragraph; $text = implode(' ', $paragraph); echo $text; Black has a slight space advantage. White has a slight protection advantage. White has a slight attack advantage. The pawn on c5 is unprotected. The c5-square is under threat of being attacked. Overall, 3 heuristic evaluation features are favoring White while 2 are favoring Black. The resulting text may sound a little robotic but it can be easily rephrased by the AI of your choice to make it sound more human-like. Explain a Good PGN Move \u2728 It's often difficult for beginners to understand why a move is good. With the help of an UCI engine Chess\\Tutor\\GoodPgnEvaluation can explain the why of a good move. use Chess\\Function\\CompleteFunction; use Chess\\Play\\SanPlay; use Chess\\Tutor\\GoodPgnEvaluation; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $limit = new Limit(); $limit->depth = 12; $stockfish = new UciEngine('/usr/games/stockfish'); $function = new CompleteFunction(); $movetext = '1.d4 d5 2.c4 Nc6 3.cxd5 Qxd5 4.e3 e5 5.Nc3 Bb4 6.Bd2 Bxc3 7.Bxc3 exd4 8.Ne2'; $board = (new SanPlay($movetext))->validate()->board; $goodPgnEvaluation = new GoodPgnEvaluation($limit, $stockfish, $function, $board); $pgn = $goodPgnEvaluation->pgn; $paragraph = implode(' ', $goodPgnEvaluation->paragraph); echo $pgn . PHP_EOL; echo $paragraph . PHP_EOL; Bg4 The black player is pressuring a little bit more squares than its opponent. The black pieces are timidly approaching the other side's king. Black has a total relative pin advantage. Black has a slight overloading advantage. The knight on e2 is pinned shielding a piece that is more valuable than the attacking piece. The bishop on f1 is overloaded defending more than one piece at the same time. Overall, 4 heuristic evaluation features are favoring White while 9 are favoring Black. \ud83c\udf89 Let's do this!","title":"Chess Tutor"},{"location":"chess-tutor/#chess-tutor","text":"","title":"Chess Tutor"},{"location":"chess-tutor/#explain-a-fen-position","text":"\u2728 Chess beginners often think they can checkmate the opponent's king quickly. However, there are so many different things to consider in order to understand a position. Chess\\Tutor\\FenEvaluation helps you improve your chess thinking process by evaluating a FEN position in terms of chess concepts like in the example below. use Chess\\FenToBoardFactory; use Chess\\Function\\CompleteFunction; use Chess\\Tutor\\FenEvaluation; $function = new CompleteFunction(); $board = FenToBoardFactory::create('8/5k2/4n3/8/8/1BK5/1B6/8 w - - 0 1'); $paragraph = (new FenEvaluation($function, $board))->paragraph; $text = implode(' ', $paragraph); echo $text; White has a decisive material advantage. White has a slightly better control of the center. The white pieces are significantly better connected. The white player is pressuring a little bit more squares than its opponent. White has a slight absolute pin advantage. White has the bishop pair. The knight on e6 is pinned shielding the king so it cannot move out of the line of attack because the king would be put in check. Overall, 6 heuristic evaluation features are favoring White while 0 are favoring Black. A heuristic evaluation is a quick numerical estimate of a chess position that suggests who may be better without considering checkmate. Please note that a heuristic evaluation is not the same thing as a chess calculation. Heuristic evaluations are often correct but may fail as long as they are based on probabilities more than anything else. \ud83c\udf89 This is a form of abductive reasoning.","title":"Explain a FEN Position"},{"location":"chess-tutor/#explain-a-pgn-move","text":"\u2728 Typically, chess engines won't provide an explanation in easy-to-understand language about how a move changes the position on the board. Chess\\Tutor\\PgnEvaluation explains how a particular move changes the position. use Chess\\Function\\CompleteFunction; use Chess\\Play\\SanPlay; use Chess\\Tutor\\PgnEvaluation; $pgn = 'd4'; $function = new CompleteFunction(); $movetext = '1.Nf3 d5 2.g3 c5'; $board = (new SanPlay($movetext))->validate()->board; $paragraph = (new PgnEvaluation($pgn, $function, $board))->paragraph; $text = implode(' ', $paragraph); echo $text; Black has a slight space advantage. White has a slight protection advantage. White has a slight attack advantage. The pawn on c5 is unprotected. The c5-square is under threat of being attacked. Overall, 3 heuristic evaluation features are favoring White while 2 are favoring Black. The resulting text may sound a little robotic but it can be easily rephrased by the AI of your choice to make it sound more human-like.","title":"Explain a PGN Move"},{"location":"chess-tutor/#explain-a-good-pgn-move","text":"\u2728 It's often difficult for beginners to understand why a move is good. With the help of an UCI engine Chess\\Tutor\\GoodPgnEvaluation can explain the why of a good move. use Chess\\Function\\CompleteFunction; use Chess\\Play\\SanPlay; use Chess\\Tutor\\GoodPgnEvaluation; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $limit = new Limit(); $limit->depth = 12; $stockfish = new UciEngine('/usr/games/stockfish'); $function = new CompleteFunction(); $movetext = '1.d4 d5 2.c4 Nc6 3.cxd5 Qxd5 4.e3 e5 5.Nc3 Bb4 6.Bd2 Bxc3 7.Bxc3 exd4 8.Ne2'; $board = (new SanPlay($movetext))->validate()->board; $goodPgnEvaluation = new GoodPgnEvaluation($limit, $stockfish, $function, $board); $pgn = $goodPgnEvaluation->pgn; $paragraph = implode(' ', $goodPgnEvaluation->paragraph); echo $pgn . PHP_EOL; echo $paragraph . PHP_EOL; Bg4 The black player is pressuring a little bit more squares than its opponent. The black pieces are timidly approaching the other side's king. Black has a total relative pin advantage. Black has a slight overloading advantage. The knight on e2 is pinned shielding a piece that is more valuable than the attacking piece. The bishop on f1 is overloaded defending more than one piece at the same time. Overall, 4 heuristic evaluation features are favoring White while 9 are favoring Black. \ud83c\udf89 Let's do this!","title":"Explain a Good PGN Move"},{"location":"data-conversion/","text":"Data Conversion FEN to Board \u2728 FEN stands for Forsyth-Edwards Notation and is the standard way for describing chess positions using text strings. At some point you'll definitely want to convert a FEN string into a chessboard object for further processing, and this can be done with the Chess\\FenToBoardFactory class according to the variants supported. When a single parameter is passed into the factory's create method, it is assumed that you want to create a classical chess board object. use Chess\\FenToBoardFactory; $board = FenToBoardFactory::create('rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -'); $board->play('w', 'Nc3'); $board->play('b', 'Nc6'); echo $board->toFen(); r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - In this example the game history contains two moves only. var_dump($board->history); array(2) { [0]=> array(4) { [\"castlingAbility\"]=> string(4) \"KQkq\" [\"sq\"]=> string(2) \"b1\" [\"move\"]=> array(7) { [\"pgn\"]=> string(3) \"Nc3\" [\"isCapture\"]=> bool(false) [\"isCheck\"]=> bool(false) [\"type\"]=> string(48) \"N[a-h]{0,1}[1-8]{0,1}[a-h]{1}[1-8]{1}[\\+\\#]{0,1}\" [\"color\"]=> string(1) \"w\" [\"id\"]=> string(1) \"N\" [\"sq\"]=> array(2) { [\"current\"]=> string(0) \"\" [\"next\"]=> string(2) \"c3\" } } [\"fen\"]=> string(59) \"rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -\" } [1]=> array(4) { [\"castlingAbility\"]=> string(4) \"KQkq\" [\"sq\"]=> string(2) \"b8\" [\"move\"]=> array(7) { [\"pgn\"]=> string(3) \"Nc6\" [\"isCapture\"]=> bool(false) [\"isCheck\"]=> bool(false) [\"type\"]=> string(48) \"N[a-h]{0,1}[1-8]{0,1}[a-h]{1}[1-8]{1}[\\+\\#]{0,1}\" [\"color\"]=> string(1) \"b\" [\"id\"]=> string(1) \"N\" [\"sq\"]=> array(2) { [\"current\"]=> string(0) \"\" [\"next\"]=> string(2) \"c6\" } } [\"fen\"]=> string(60) \"r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -\" } } The initial FEN string can be accessed as shown below. echo $board->startFen; rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - Board to PNG Image \u2728 PNG stands for Portable Network Graphics and is a widely used format for image files. Not to be confused with PGN, the text-based file format to annotate chess games. Chess\\Media\\BoardToPng converts a chess board object to a PNG image. use Chess\\FenToBoardFactory; use Chess\\Media\\BoardToPng; $board = FenToBoardFactory::create('1rbq1rk1/p1b1nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1R1K w - - bm Nf6+'); $filename = (new BoardToPng($board, $flip = true))->output(__DIR__); Try this thing! Share a puzzling chess position with friends for further study. Board to MP4 \u2728 Text-based PGN movetexts can be easily converted to MP4, a widely-used video format which comes in handy for pausing the games. Chess\\Media\\BoardToMp4 allows to convert a chess board object to an MP4 video. use Chess\\Media\\BoardToMp4; use Chess\\Variant\\Classical\\Board; $movetext = '1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7'; $board = new Board(); $filename = (new BoardToMp4($movetext, $board, $flip = false))->output(__DIR__); MP4 videos are especially useful to pause the game at a specific position. Image to FEN \u2728 A chess piece image recognizer has been created in the chesslablab/perception repository with the help of a multilayer neural network. Chess\\Media\\ImgToPiecePlacement relies on this recognizer to convert a GD image into a piece placement in FEN format. use Chess\\Media\\ImgToPiecePlacement; $image = imagecreatefrompng(__DIR__ . '/01_kaufman.png'); $prediction = (new ImgToPiecePlacement($image))->predict(); echo $prediction; 1rbq1rk1/p1b1nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1R1K For optimal use, it is recommended to make predictions on chessboard images using classical chess pieces like the Kaufman test attached below.","title":"Data Conversion"},{"location":"data-conversion/#data-conversion","text":"","title":"Data Conversion"},{"location":"data-conversion/#fen-to-board","text":"\u2728 FEN stands for Forsyth-Edwards Notation and is the standard way for describing chess positions using text strings. At some point you'll definitely want to convert a FEN string into a chessboard object for further processing, and this can be done with the Chess\\FenToBoardFactory class according to the variants supported. When a single parameter is passed into the factory's create method, it is assumed that you want to create a classical chess board object. use Chess\\FenToBoardFactory; $board = FenToBoardFactory::create('rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -'); $board->play('w', 'Nc3'); $board->play('b', 'Nc6'); echo $board->toFen(); r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - In this example the game history contains two moves only. var_dump($board->history); array(2) { [0]=> array(4) { [\"castlingAbility\"]=> string(4) \"KQkq\" [\"sq\"]=> string(2) \"b1\" [\"move\"]=> array(7) { [\"pgn\"]=> string(3) \"Nc3\" [\"isCapture\"]=> bool(false) [\"isCheck\"]=> bool(false) [\"type\"]=> string(48) \"N[a-h]{0,1}[1-8]{0,1}[a-h]{1}[1-8]{1}[\\+\\#]{0,1}\" [\"color\"]=> string(1) \"w\" [\"id\"]=> string(1) \"N\" [\"sq\"]=> array(2) { [\"current\"]=> string(0) \"\" [\"next\"]=> string(2) \"c3\" } } [\"fen\"]=> string(59) \"rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -\" } [1]=> array(4) { [\"castlingAbility\"]=> string(4) \"KQkq\" [\"sq\"]=> string(2) \"b8\" [\"move\"]=> array(7) { [\"pgn\"]=> string(3) \"Nc6\" [\"isCapture\"]=> bool(false) [\"isCheck\"]=> bool(false) [\"type\"]=> string(48) \"N[a-h]{0,1}[1-8]{0,1}[a-h]{1}[1-8]{1}[\\+\\#]{0,1}\" [\"color\"]=> string(1) \"b\" [\"id\"]=> string(1) \"N\" [\"sq\"]=> array(2) { [\"current\"]=> string(0) \"\" [\"next\"]=> string(2) \"c6\" } } [\"fen\"]=> string(60) \"r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -\" } } The initial FEN string can be accessed as shown below. echo $board->startFen; rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -","title":"FEN to Board"},{"location":"data-conversion/#board-to-png-image","text":"\u2728 PNG stands for Portable Network Graphics and is a widely used format for image files. Not to be confused with PGN, the text-based file format to annotate chess games. Chess\\Media\\BoardToPng converts a chess board object to a PNG image. use Chess\\FenToBoardFactory; use Chess\\Media\\BoardToPng; $board = FenToBoardFactory::create('1rbq1rk1/p1b1nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1R1K w - - bm Nf6+'); $filename = (new BoardToPng($board, $flip = true))->output(__DIR__); Try this thing! Share a puzzling chess position with friends for further study.","title":"Board to PNG Image"},{"location":"data-conversion/#board-to-mp4","text":"\u2728 Text-based PGN movetexts can be easily converted to MP4, a widely-used video format which comes in handy for pausing the games. Chess\\Media\\BoardToMp4 allows to convert a chess board object to an MP4 video. use Chess\\Media\\BoardToMp4; use Chess\\Variant\\Classical\\Board; $movetext = '1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7'; $board = new Board(); $filename = (new BoardToMp4($movetext, $board, $flip = false))->output(__DIR__); MP4 videos are especially useful to pause the game at a specific position.","title":"Board to MP4"},{"location":"data-conversion/#image-to-fen","text":"\u2728 A chess piece image recognizer has been created in the chesslablab/perception repository with the help of a multilayer neural network. Chess\\Media\\ImgToPiecePlacement relies on this recognizer to convert a GD image into a piece placement in FEN format. use Chess\\Media\\ImgToPiecePlacement; $image = imagecreatefrompng(__DIR__ . '/01_kaufman.png'); $prediction = (new ImgToPiecePlacement($image))->predict(); echo $prediction; 1rbq1rk1/p1b1nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1R1K For optimal use, it is recommended to make predictions on chessboard images using classical chess pieces like the Kaufman test attached below.","title":"Image to FEN"},{"location":"heuristics/","text":"Heuristics \u2728 If you ask a chess pro why a chess move is good, they'll probably give you a bunch of reasons, many of them intuitive, about why they made that decision. It is important to develop your pieces in the opening while trying to control the center of the board at the same time. Castling is an excellent move as long as the king gets safe. Then, in the middlegame space becomes an advantage. And if a complex position can be simplified when you have an advantage, then so much the better. The pawn structure could determine the endgame. The list of reasons goes on and on. The mathematician Claude Shannon came to the conclusion that there are more chess moves than atoms in the universe. The game is complex and you need to learn how to make decisions to play chess like a pro. Since no human can calculate more than, let's say 30 moves ahead, it's all about thinking in terms of heuristics. Heuristics are quick, mental shortcuts that we humans use to make decisions and solve problems in our daily lives. While far from being perfect, heuristics are approximations that help manage cognitive load. Listed below are the chess heuristics implemented in PHP Chess. Heuristic Description Evaluation Absolute fork A tactic in which a piece attacks multiple pieces at the same time. It is a double attack. A fork involving the enemy king is an absolute fork. Chess\\Eval\\AbsoluteForkEval Absolute pin A tactic that occurs when a piece is shielding the king, so it cannot move out of the line of attack because the king would be put in check. Chess\\Eval\\AbsolutePinEval Absolute skewer A tactic in which the enemy king is involved. The king is in check, and it has to move out of danger exposing a more valuable piece to capture. Only line pieces (bishops, rooks and queens) can skewer. Chess\\Eval\\AbsoluteSkewerEval Advanced pawn A pawn that is on the fifth rank or higher. Chess\\Eval\\AdvancedPawnEval Attack If a piece is under threat of being attacked, it means it could be taken after a sequence of captures resulting in a material gain. This indicates a forcing move in that a player is to reply in a certain way. On the next turn, it should be defended by a piece or moved to a safe square. The player with the greater number of material points under attack has an advantage. Chess\\Eval\\AttackEval Backward pawn The last pawn protecting other pawns in its chain. It is considered a weakness because it cannot advance safely. Chess\\Eval\\BackwardPawnEval Bad bishop A bishop that is on the same color as most of own pawns. Chess\\Eval\\BadBishopEval Bishop outpost A bishop on an outpost square is considered a positional advantage because it cannot be attacked by enemy pawns, and as a result, it is often exchanged for another piece. Chess\\Eval\\BishopOutpostEval Bishop pair The player with both bishops may definitely have an advantage, especially in the endgame. Furthermore, two bishops can deliver checkmate. Chess\\Eval\\BishopPairEval Center It is advantageous to control the central squares as well as to place a piece in the center. Chess\\Eval\\CenterEval Checkability Having a king that can be checked is usually considered a disadvantage, and vice versa, it is considered advantageous to have a king that cannot be checked. A checkable king is vulnerable to forcing moves. Chess\\Eval\\CheckabilityEval Connectivity The connectivity of the pieces measures how loosely the pieces are. Chess\\Eval\\ConnectivityEval Defense This heuristic evaluates the defensive strength of each side by analyzing how the removal of attacking pieces would affect the opponent's protection. A higher score indicates a stronger defensive position. Chess\\Eval\\DefenseEval Diagonal opposition The same as direct opposition, but the two kings are apart from each other diagonally. Chess\\Eval\\DiagonalOppositionEval Direct opposition A position in which the kings are facing each other being two squares apart on the same rank or file. In this situation, the player not having to move is said to have the opposition. Chess\\Eval\\DirectOppositionEval Discovered check A discovered check occurs when the opponent's king can be checked by moving a piece out of the way of another. Chess\\Eval\\DiscoveredCheckEval Doubled pawn A pawn is doubled if there are two pawns of the same color on the same file. Chess\\Eval\\DoubledPawnEval Far-advanced pawn A pawn that is threatening to promote. Chess\\Eval\\FarAdvancedPawnEval Flight square The safe squares to which the king can move if it is threatened. Chess\\Eval\\FlightSquareEval Isolated pawn A pawn without friendly pawns on the adjacent files. Since it cannot be defended by other pawns it is considered a weakness. Chess\\Eval\\IsolatedPawnEval King safety An unsafe king leads to uncertainty. The probability of unexpected, forced moves will increase as the opponent's pieces get closer to it. Chess\\Eval\\KingSafetyEval Knight outpost A knight on an outpost square is considered a positional advantage because it cannot be attacked by enemy pawns, and as a result, it is often exchanged for a bishop. Chess\\Eval\\KnightOutpostEval Material The player with the most material points has an advantage. The relative values of the pieces are assigned this way: 1 point to a pawn, 3.2 points to a knight, 3.33 points to a bishop, 5.1 points to a rook and 8.8 points to a queen. Chess\\Eval\\MaterialEval Overloading A piece that is overloaded with defensive tasks is vulnerable because it can be deflected, meaning it could be forced to leave the square it occupies, typically resulting in an advantage for the opponent. Chess\\Eval\\OverloadingEval Passed pawn A pawn with no opposing pawns on either the same file or adjacent files to prevent it from being promoted. Chess\\Eval\\PassedPawnEval Pressure This is a measure of the number of squares targeted by each player that require special attention. It often indicates the step prior to an attack. The player with the greater number of them has an advantage. Chess\\Eval\\PressureEval Protection If a piece is unprotected, it means that there are no other pieces defending it, and therefore it can be taken for free resulting in a material gain. This indicates a forcing move in that a player is to reply in a certain way. On the next turn, it should be defended by a piece or moved to a safe square. The player with the greater number of material points under protection has an advantage. Chess\\Eval\\ProtectionEval Relative fork A tactic in which a piece attacks multiple pieces at the same time. It is a double attack. A fork not involving the enemy king is a relative fork. Chess\\Eval\\RelativeForkEval Relative pin A tactic that occurs when a piece is shielding a more valuable piece, so if it moves out of the line of attack the more valuable piece can be captured resulting in a material gain. Chess\\Eval\\RelativePinEval Space This is a measure of the number of squares controlled by each player. Chess\\Eval\\SpaceEval Square outpost A square protected by a pawn that cannot be attacked by an opponent's pawn. Chess\\Eval\\SqOutpostEval The evaluation features are used in two heuristics classes: Chess\\FenHeuristics and Chess\\SanHeuristic . The former allows to transform a FEN position to numbers while the latter transforms an entire chess game in SAN format to numbers. use Chess\\FenHeuristics; use Chess\\FenToBoardFactory; use Chess\\Function\\CompleteFunction; $function = new CompleteFunction(); $fen = 'rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -'; $board = FenToBoardFactory::create($fen); $result = [ 'names' => $function->names(), 'balance' => (new FenHeuristics($function, $board))->getBalance(), ]; print_r($result); Array ( [names] => Array ( [0] => Material [1] => Center [2] => Connectivity [3] => Space [4] => Pressure [5] => King safety [6] => Protection [7] => Discovered check [8] => Doubled pawn [9] => Passed pawn [10] => Advanced pawn [11] => Far-advanced pawn [12] => Isolated pawn [13] => Backward pawn [14] => Defense [15] => Absolute skewer [16] => Absolute pin [17] => Relative pin [18] => Absolute fork [19] => Relative fork [20] => Outpost square [21] => Knight outpost [22] => Bishop outpost [23] => Bishop pair [24] => Bad bishop [25] => Diagonal opposition [26] => Direct opposition [27] => Attack [28] => Overloading ) [balance] => Array ( [0] => 0 [1] => 12.4 [2] => 0 [3] => 3 [4] => 0 [5] => 0 [6] => 0 [7] => 0 [8] => 0 [9] => 0 [10] => 0 [11] => 0 [12] => 0 [13] => 0 [14] => 0 [15] => 0 [16] => 0 [17] => 0 [18] => 0 [19] => 0 [20] => 0 [21] => 0 [22] => 0 [23] => 0 [24] => 0 [25] => 0 [26] => 0 [27] => 0 [28] => 0 ) ) A chess game can be plotted in terms of balance. +1 is the best possible evaluation for White and -1 the best possible evaluation for Black. Both forces being set to 0 means they're balanced. use Chess\\SanHeuristic; use Chess\\Function\\CompleteFunction; $function = new CompleteFunction(); $name = 'Space'; $movetext = '1.e4 d5 2.exd5 Qxd5'; $balance = (new SanHeuristic($function, $name, $movetext))->getBalance(); print_r($balance); Array ( [0] => 0 [1] => 1 [2] => 0.25 [3] => 0.5 [4] => -1 ) \ud83c\udf89 Chess positions and games can now be plotted on charts and processed with machine learning techniques.","title":"Heuristics"},{"location":"heuristics/#heuristics","text":"\u2728 If you ask a chess pro why a chess move is good, they'll probably give you a bunch of reasons, many of them intuitive, about why they made that decision. It is important to develop your pieces in the opening while trying to control the center of the board at the same time. Castling is an excellent move as long as the king gets safe. Then, in the middlegame space becomes an advantage. And if a complex position can be simplified when you have an advantage, then so much the better. The pawn structure could determine the endgame. The list of reasons goes on and on. The mathematician Claude Shannon came to the conclusion that there are more chess moves than atoms in the universe. The game is complex and you need to learn how to make decisions to play chess like a pro. Since no human can calculate more than, let's say 30 moves ahead, it's all about thinking in terms of heuristics. Heuristics are quick, mental shortcuts that we humans use to make decisions and solve problems in our daily lives. While far from being perfect, heuristics are approximations that help manage cognitive load. Listed below are the chess heuristics implemented in PHP Chess. Heuristic Description Evaluation Absolute fork A tactic in which a piece attacks multiple pieces at the same time. It is a double attack. A fork involving the enemy king is an absolute fork. Chess\\Eval\\AbsoluteForkEval Absolute pin A tactic that occurs when a piece is shielding the king, so it cannot move out of the line of attack because the king would be put in check. Chess\\Eval\\AbsolutePinEval Absolute skewer A tactic in which the enemy king is involved. The king is in check, and it has to move out of danger exposing a more valuable piece to capture. Only line pieces (bishops, rooks and queens) can skewer. Chess\\Eval\\AbsoluteSkewerEval Advanced pawn A pawn that is on the fifth rank or higher. Chess\\Eval\\AdvancedPawnEval Attack If a piece is under threat of being attacked, it means it could be taken after a sequence of captures resulting in a material gain. This indicates a forcing move in that a player is to reply in a certain way. On the next turn, it should be defended by a piece or moved to a safe square. The player with the greater number of material points under attack has an advantage. Chess\\Eval\\AttackEval Backward pawn The last pawn protecting other pawns in its chain. It is considered a weakness because it cannot advance safely. Chess\\Eval\\BackwardPawnEval Bad bishop A bishop that is on the same color as most of own pawns. Chess\\Eval\\BadBishopEval Bishop outpost A bishop on an outpost square is considered a positional advantage because it cannot be attacked by enemy pawns, and as a result, it is often exchanged for another piece. Chess\\Eval\\BishopOutpostEval Bishop pair The player with both bishops may definitely have an advantage, especially in the endgame. Furthermore, two bishops can deliver checkmate. Chess\\Eval\\BishopPairEval Center It is advantageous to control the central squares as well as to place a piece in the center. Chess\\Eval\\CenterEval Checkability Having a king that can be checked is usually considered a disadvantage, and vice versa, it is considered advantageous to have a king that cannot be checked. A checkable king is vulnerable to forcing moves. Chess\\Eval\\CheckabilityEval Connectivity The connectivity of the pieces measures how loosely the pieces are. Chess\\Eval\\ConnectivityEval Defense This heuristic evaluates the defensive strength of each side by analyzing how the removal of attacking pieces would affect the opponent's protection. A higher score indicates a stronger defensive position. Chess\\Eval\\DefenseEval Diagonal opposition The same as direct opposition, but the two kings are apart from each other diagonally. Chess\\Eval\\DiagonalOppositionEval Direct opposition A position in which the kings are facing each other being two squares apart on the same rank or file. In this situation, the player not having to move is said to have the opposition. Chess\\Eval\\DirectOppositionEval Discovered check A discovered check occurs when the opponent's king can be checked by moving a piece out of the way of another. Chess\\Eval\\DiscoveredCheckEval Doubled pawn A pawn is doubled if there are two pawns of the same color on the same file. Chess\\Eval\\DoubledPawnEval Far-advanced pawn A pawn that is threatening to promote. Chess\\Eval\\FarAdvancedPawnEval Flight square The safe squares to which the king can move if it is threatened. Chess\\Eval\\FlightSquareEval Isolated pawn A pawn without friendly pawns on the adjacent files. Since it cannot be defended by other pawns it is considered a weakness. Chess\\Eval\\IsolatedPawnEval King safety An unsafe king leads to uncertainty. The probability of unexpected, forced moves will increase as the opponent's pieces get closer to it. Chess\\Eval\\KingSafetyEval Knight outpost A knight on an outpost square is considered a positional advantage because it cannot be attacked by enemy pawns, and as a result, it is often exchanged for a bishop. Chess\\Eval\\KnightOutpostEval Material The player with the most material points has an advantage. The relative values of the pieces are assigned this way: 1 point to a pawn, 3.2 points to a knight, 3.33 points to a bishop, 5.1 points to a rook and 8.8 points to a queen. Chess\\Eval\\MaterialEval Overloading A piece that is overloaded with defensive tasks is vulnerable because it can be deflected, meaning it could be forced to leave the square it occupies, typically resulting in an advantage for the opponent. Chess\\Eval\\OverloadingEval Passed pawn A pawn with no opposing pawns on either the same file or adjacent files to prevent it from being promoted. Chess\\Eval\\PassedPawnEval Pressure This is a measure of the number of squares targeted by each player that require special attention. It often indicates the step prior to an attack. The player with the greater number of them has an advantage. Chess\\Eval\\PressureEval Protection If a piece is unprotected, it means that there are no other pieces defending it, and therefore it can be taken for free resulting in a material gain. This indicates a forcing move in that a player is to reply in a certain way. On the next turn, it should be defended by a piece or moved to a safe square. The player with the greater number of material points under protection has an advantage. Chess\\Eval\\ProtectionEval Relative fork A tactic in which a piece attacks multiple pieces at the same time. It is a double attack. A fork not involving the enemy king is a relative fork. Chess\\Eval\\RelativeForkEval Relative pin A tactic that occurs when a piece is shielding a more valuable piece, so if it moves out of the line of attack the more valuable piece can be captured resulting in a material gain. Chess\\Eval\\RelativePinEval Space This is a measure of the number of squares controlled by each player. Chess\\Eval\\SpaceEval Square outpost A square protected by a pawn that cannot be attacked by an opponent's pawn. Chess\\Eval\\SqOutpostEval The evaluation features are used in two heuristics classes: Chess\\FenHeuristics and Chess\\SanHeuristic . The former allows to transform a FEN position to numbers while the latter transforms an entire chess game in SAN format to numbers. use Chess\\FenHeuristics; use Chess\\FenToBoardFactory; use Chess\\Function\\CompleteFunction; $function = new CompleteFunction(); $fen = 'rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -'; $board = FenToBoardFactory::create($fen); $result = [ 'names' => $function->names(), 'balance' => (new FenHeuristics($function, $board))->getBalance(), ]; print_r($result); Array ( [names] => Array ( [0] => Material [1] => Center [2] => Connectivity [3] => Space [4] => Pressure [5] => King safety [6] => Protection [7] => Discovered check [8] => Doubled pawn [9] => Passed pawn [10] => Advanced pawn [11] => Far-advanced pawn [12] => Isolated pawn [13] => Backward pawn [14] => Defense [15] => Absolute skewer [16] => Absolute pin [17] => Relative pin [18] => Absolute fork [19] => Relative fork [20] => Outpost square [21] => Knight outpost [22] => Bishop outpost [23] => Bishop pair [24] => Bad bishop [25] => Diagonal opposition [26] => Direct opposition [27] => Attack [28] => Overloading ) [balance] => Array ( [0] => 0 [1] => 12.4 [2] => 0 [3] => 3 [4] => 0 [5] => 0 [6] => 0 [7] => 0 [8] => 0 [9] => 0 [10] => 0 [11] => 0 [12] => 0 [13] => 0 [14] => 0 [15] => 0 [16] => 0 [17] => 0 [18] => 0 [19] => 0 [20] => 0 [21] => 0 [22] => 0 [23] => 0 [24] => 0 [25] => 0 [26] => 0 [27] => 0 [28] => 0 ) ) A chess game can be plotted in terms of balance. +1 is the best possible evaluation for White and -1 the best possible evaluation for Black. Both forces being set to 0 means they're balanced. use Chess\\SanHeuristic; use Chess\\Function\\CompleteFunction; $function = new CompleteFunction(); $name = 'Space'; $movetext = '1.e4 d5 2.exd5 Qxd5'; $balance = (new SanHeuristic($function, $name, $movetext))->getBalance(); print_r($balance); Array ( [0] => 0 [1] => 1 [2] => 0.25 [3] => 0.5 [4] => -1 ) \ud83c\udf89 Chess positions and games can now be plotted on charts and processed with machine learning techniques.","title":"Heuristics"},{"location":"installation/","text":"Installation Requirements PHP >= 8.1 Stockfish >= 15.1 Composer installation composer require chesslablab/php-chess","title":"Installation"},{"location":"installation/#installation","text":"","title":"Installation"},{"location":"installation/#requirements","text":"PHP >= 8.1 Stockfish >= 15.1","title":"Requirements"},{"location":"installation/#composer-installation","text":"composer require chesslablab/php-chess","title":"Composer installation"},{"location":"play-chess/","text":"Play Chess Play Randomly \u2728 Sometimes you want to play a random game of chess. You could loop 50 times and play a move by instantiating the Chess\\Computer\\RandomMove class like in the example below. use Chess\\Computer\\RandomMove; use Chess\\Variant\\Classical\\Board; $board = new Board(); for ($i = 0; $i < 50; $i++) { if ($move = (new RandomMove($board))->move()) { $board->play($board->turn, $move['pgn']); } } echo $board->movetext(); 1.e4 Nc6 2.Qf3 g6 3.b3 Rb8 4.Bb5 Nh6 5.Ke2 Na5 6.c3 Ng4 7.d3 h6 8.h4 Ra8 9.Kd1 b6 10.Ba4 h5 11.b4 Rh7 12.Bc2 Rh8 13.Ke1 a6 14.Kd1 Nb3 15.d4 Na5 16.g3 c6 17.Ne2 Ne5 18.Nf4 d6 19.Nxg6 Kd7 20.b5 Qe8 21.Na3 e6 22.Bd3 Rb8 23.dxe5 dxe5 24.Bb2 Rg8 25.Qg4 Ra8 The result obtained is a 24 move game since a move is considered to be completed after both players have played a turn. Play Like a Grandmaster \u2728 The players.json file in the Chess Server contains thousands of games by titled FIDE players. This file can be generated with the command line tools available in the Chess Data repo. Chess\\Computer\\GrandmasterMove figures out the next move to be made based on the players.json file that is passed to its constructor. use Chess\\Computer\\GrandmasterMove; use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $gmMove = (new GrandmasterMove(__DIR__.'/../data/json/players.json'))->move($board); print_r($gmMove); Array ( [pgn] => c5 [game] => Array ( [Event] => Tilburg [Site] => Tilburg [Date] => 1993.??.?? [White] => Morozevich, Alexander [Black] => Adams, Michael [Result] => 1-0 [ECO] => B23 [movetext] => 1.e4 c5 2.Nc3 Nc6 3.f4 g6 4.Nf3 Bg7 5.Bb5 Nd4 6.Nxd4 cxd4 7.Ne2 a6 8.Ba4 b5 9.Bb3 e6 10.O-O Ne7 11.d3 O-O 12.Qe1 f5 13.Bd2 Nc6 14.Kh1 Bb7 15.Ng1 h6 16.Nf3 Kh7 17.Qg3 Qe7 18.Rae1 a5 19.a3 Rab8 20.Nh4 Qf7 21.Qh3 Ba8 22.Rf3 a4 23.Ba2 b4 24.Bc1 b3 25.cxb3 axb3 26.Bb1 d6 27.Bd2 Kg8 28.g4 Ne7 29.gxf5 gxf5 30.Rg3 Kh7 31.Nf3 Bf6 32.Ng5+ Bxg5 33.fxg5 Ng6 34.Qxh6+ Kg8 35.h4 f4 36.Rh3 Rb7 37.h5 Ne5 38.Rg1 Rc7 39.Rh4 Qe8 40.g6 ) ) \ud83c\udf89 Let's now put our knowledge of chess openings to the test. Play Computer \u2728 The Universal Chess Interface (UCI) is an open communication protocol that enables chess engines to communicate with user interfaces. PHP Chess provides the Chess\\UciEngine\\UciEngine class representing an UCI engine. To follow this tutorial make sure to install Stockfish if you haven't already. sudo apt-get install stockfish Then, you are set up to play chess against the computer as described in the following example. use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $limit = new Limit(); $limit->depth = 3; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 9); $analysis = $stockfish->analysis($board, $limit); $board->playLan('b', $analysis['bestmove']); echo $board->movetext(); 1.e4 Nf6 You may want to play against Stockfish starting from a particular FEN with the help of Chess\\FenToBoardFactory . use Chess\\FenToBoardFactory; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $board = FenToBoardFactory::create('4k2r/pp1b1pp1/8/3pPp1p/P2P1P2/1P3N2/1qr3PP/R3QR1K w k -'); $limit = new Limit(); $limit->depth = 12; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 20); $analysis = $stockfish->analysis($board, $limit); $board->playLan('w', $analysis['bestmove']); echo $board->movetext(); 1.Rb1 The FEN is converted to a chess board object as described in the Data Conversion section. Then Stockfish's depth limit is set to 12 and the skill level to 20 . The same thing goes to starting a game from a particular SAN movetext. As you can see in the example below, Chess\\Play\\SanPlay is used for this purpose. use Chess\\Play\\SanPlay; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $movetext = '1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7'; $board = (new SanPlay($movetext))->validate()->board; $limit = new Limit(); $limit->depth = 12; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 20); $analysis = $stockfish->analysis($board, $limit); $board->playLan('w', $analysis['bestmove']); echo $board->movetext(); 1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7 8.h3 \ud83c\udf89 Can you beat the computer? Keep it up!","title":"Play Chess"},{"location":"play-chess/#play-chess","text":"","title":"Play Chess"},{"location":"play-chess/#play-randomly","text":"\u2728 Sometimes you want to play a random game of chess. You could loop 50 times and play a move by instantiating the Chess\\Computer\\RandomMove class like in the example below. use Chess\\Computer\\RandomMove; use Chess\\Variant\\Classical\\Board; $board = new Board(); for ($i = 0; $i < 50; $i++) { if ($move = (new RandomMove($board))->move()) { $board->play($board->turn, $move['pgn']); } } echo $board->movetext(); 1.e4 Nc6 2.Qf3 g6 3.b3 Rb8 4.Bb5 Nh6 5.Ke2 Na5 6.c3 Ng4 7.d3 h6 8.h4 Ra8 9.Kd1 b6 10.Ba4 h5 11.b4 Rh7 12.Bc2 Rh8 13.Ke1 a6 14.Kd1 Nb3 15.d4 Na5 16.g3 c6 17.Ne2 Ne5 18.Nf4 d6 19.Nxg6 Kd7 20.b5 Qe8 21.Na3 e6 22.Bd3 Rb8 23.dxe5 dxe5 24.Bb2 Rg8 25.Qg4 Ra8 The result obtained is a 24 move game since a move is considered to be completed after both players have played a turn.","title":"Play Randomly"},{"location":"play-chess/#play-like-a-grandmaster","text":"\u2728 The players.json file in the Chess Server contains thousands of games by titled FIDE players. This file can be generated with the command line tools available in the Chess Data repo. Chess\\Computer\\GrandmasterMove figures out the next move to be made based on the players.json file that is passed to its constructor. use Chess\\Computer\\GrandmasterMove; use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $gmMove = (new GrandmasterMove(__DIR__.'/../data/json/players.json'))->move($board); print_r($gmMove); Array ( [pgn] => c5 [game] => Array ( [Event] => Tilburg [Site] => Tilburg [Date] => 1993.??.?? [White] => Morozevich, Alexander [Black] => Adams, Michael [Result] => 1-0 [ECO] => B23 [movetext] => 1.e4 c5 2.Nc3 Nc6 3.f4 g6 4.Nf3 Bg7 5.Bb5 Nd4 6.Nxd4 cxd4 7.Ne2 a6 8.Ba4 b5 9.Bb3 e6 10.O-O Ne7 11.d3 O-O 12.Qe1 f5 13.Bd2 Nc6 14.Kh1 Bb7 15.Ng1 h6 16.Nf3 Kh7 17.Qg3 Qe7 18.Rae1 a5 19.a3 Rab8 20.Nh4 Qf7 21.Qh3 Ba8 22.Rf3 a4 23.Ba2 b4 24.Bc1 b3 25.cxb3 axb3 26.Bb1 d6 27.Bd2 Kg8 28.g4 Ne7 29.gxf5 gxf5 30.Rg3 Kh7 31.Nf3 Bf6 32.Ng5+ Bxg5 33.fxg5 Ng6 34.Qxh6+ Kg8 35.h4 f4 36.Rh3 Rb7 37.h5 Ne5 38.Rg1 Rc7 39.Rh4 Qe8 40.g6 ) ) \ud83c\udf89 Let's now put our knowledge of chess openings to the test.","title":"Play Like a Grandmaster"},{"location":"play-chess/#play-computer","text":"\u2728 The Universal Chess Interface (UCI) is an open communication protocol that enables chess engines to communicate with user interfaces. PHP Chess provides the Chess\\UciEngine\\UciEngine class representing an UCI engine. To follow this tutorial make sure to install Stockfish if you haven't already. sudo apt-get install stockfish Then, you are set up to play chess against the computer as described in the following example. use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $limit = new Limit(); $limit->depth = 3; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 9); $analysis = $stockfish->analysis($board, $limit); $board->playLan('b', $analysis['bestmove']); echo $board->movetext(); 1.e4 Nf6 You may want to play against Stockfish starting from a particular FEN with the help of Chess\\FenToBoardFactory . use Chess\\FenToBoardFactory; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $board = FenToBoardFactory::create('4k2r/pp1b1pp1/8/3pPp1p/P2P1P2/1P3N2/1qr3PP/R3QR1K w k -'); $limit = new Limit(); $limit->depth = 12; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 20); $analysis = $stockfish->analysis($board, $limit); $board->playLan('w', $analysis['bestmove']); echo $board->movetext(); 1.Rb1 The FEN is converted to a chess board object as described in the Data Conversion section. Then Stockfish's depth limit is set to 12 and the skill level to 20 . The same thing goes to starting a game from a particular SAN movetext. As you can see in the example below, Chess\\Play\\SanPlay is used for this purpose. use Chess\\Play\\SanPlay; use Chess\\UciEngine\\UciEngine; use Chess\\UciEngine\\Details\\Limit; $movetext = '1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7'; $board = (new SanPlay($movetext))->validate()->board; $limit = new Limit(); $limit->depth = 12; $stockfish = (new UciEngine('/usr/games/stockfish'))->setOption('Skill Level', 20); $analysis = $stockfish->analysis($board, $limit); $board->playLan('w', $analysis['bestmove']); echo $board->movetext(); 1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 exd5 5.cxd5 d6 6.e4 g6 7.Nf3 Bg7 8.h3 \ud83c\udf89 Can you beat the computer? Keep it up!","title":"Play Computer"},{"location":"read-moves/","text":"Read Moves Portable Game Notation (PGN) \u2728 Portable Game Notation is a human-readable text format that allows chess players to read and write chess games. PGN is convenient for when reading chess games annotated by humans, for example, those ones available in online databases or published in chess websites. 1.e4 e5 2.Nf3 Nf6 3.d4 Nxe4 4.Bd3 d5 5.Nxe5 Nd7 6.Nxd7 Bxd7 7.Nd2 Nxd2 8.Bxd2 Bd6 9.O-O h5 10.Qe1+ Kf8 11.Bb4 Qe7 12.Bxd6 Qxd6 13.Qd2 Re8 14.Rae1 Rh6 15.Qg5 c6 16.Rxe8+ Bxe8 17.Re1 Qf6 18.Qe3 Bd7 19.h3 h4 20.c4 dxc4 21.Bxc4 b5 22.Qa3+ Kg8 23.Qxa7 Qd8 24.Bb3 Rd6 25.Re4 Be6 26.Bxe6 Rxe6 27.Rxe6 fxe6 28.Qc5 Qa5 29.Qxc6 Qe1+ 30.Kh2 Qxf2 31.Qxe6+ Kh7 32.Qe4+ Kg8 33.b3 Qxa2 34.Qe8+ Kh7 35.Qxb5 Qf2 36.Qe5 Qb2 37.Qe4+ Kg8 38.Qd3 Qf2 39.Qc3 Qf4+ 40.Kg1 Kh7 41.Qd3+ g6 42.Qd1 Qe3+ 43.Kh1 g5 44.d5 g4 45.hxg4 h3 46.Qf3 1\u20130 World Chess Championship 2021. (2023, July 3). In Wikipedia. https://en.wikipedia.org/wiki/World_Chess_Championship_2021 As you may probably know, a chess opening is the group of initial moves of a chess game. This definition applies to classical chess, however, there is no such thing as a chess opening in either Capablanca chess or Chess960. Those two variants were originally conceived to minimize memorization, so when it comes to chess openings it is assumed that we're in the realms of classical chess. ECO, which stands for Encyclopaedia of Chess Openings, is a standard classification system for chess openings. Having said all that, let's now look at B54 which is the ECO code for \"Sicilian Defense: Modern Variations, Main Line\". use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $board->play('b', 'c5'); $board->play('w', 'Nf3'); $board->play('b', 'd6'); $board->play('w', 'd4'); $board->play('b', 'cxd4'); $board->play('w', 'Nxd4'); echo $board->toString(); r n b q k b n r p p . . p p p p . . . p . . . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R The play() method in the Chess\\Variant\\Classical\\Board class allows to make moves in PGN format. So far so good, but if you're new to chess you may well play a wrong move in the Sicilian Defense: 4...Na6. $board->play('b', 'Na6'); echo $board->toString(); r . b q k b n r p p . . p p p p n . . p . . . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R No worries! The undo() method comes to the rescue to take back a move. $board = $board->undo(); $board->play('b', 'Nf6'); echo $board->movetext(); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 The movetext() method is used to obtain the moves played in the game using Standard Algebraic Notation. Let's continue practicing chess openings. Now, what if you want to play a bunch of moves at once instead of one by one as in the previous example? Chess\\Play\\SanPlay allows to easily do so. use Chess\\Play\\SanPlay; $movetext = '1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6'; $board = (new SanPlay($movetext))->validate()->board; echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R Please note that the validate() method will throw an exception if the movetext is not valid. Once the $board object is successfully created, the game can be continued from that particular position. $board->play('w', 'Bb5+'); echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . B . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K . . R Every time a move is made, the state of the board changes. Chess\\Variant\\Classical\\Board provides you with plenty of methods to interact with a chess board object. It is a quite common use case to query the board state. As discussed in the Home section, you may want to check out the corresponding tests for further details on how to use it. The unit tests are the best documentation. They contain hundreds of real examples on how to use the PHP Chess library. The isCheck() method will confirm that the white king is in check after 5.Bb5+ while isMate() will confirm that it has not been mated. var_dump($board->isCheck()); bool(true) var_dump($board->isMate()); bool(false) Similarly, you may want to know if the current position is a draw. The isStalemate() method is to find out if the current position is a stalemate while isFivefoldRepetition() will confirm if the game is drawn because of a fivefold repetition. var_dump($board->isStalemate()); bool(false) var_dump($board->isFivefoldRepetition()); bool(false) Text comments in curly brackets can optionally be used in SAN movetexts as well as Numeric Annotation Glyphs . The example below shows how Chess\\Play\\SanPlay is used to validate a SAN movetext that contains NAGs. Remember, the validate() method will throw an exception if the movetext is not valid. use Chess\\Play\\SanPlay; $movetext = '1.e4 c5 2.Nf3 $1 d6 3.d4 cxd4 4.Nxd4 $48 Nf6 $113'; $sanPlay = (new SanPlay($movetext))->validate(); echo $sanPlay->sanMovetext->filtered(); 1.e4 c5 2.Nf3 $1 d6 3.d4 cxd4 4.Nxd4 $48 Nf6 $113 Comments and NAGs can be removed by passing the false value to the first and second arguments of the filtered() method. echo $sanPlay->sanMovetext->filtered($comments = true, $nags = false); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 \ud83c\udf89 Next, let's learn how to process chess moves from a graphical user interface. Long Algebraic Notation (LAN) \u2728 The UCI protocol enables chess engines to communicate with user interfaces (UI) using Long Algebraic Notation (LAN) for moves. use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->playLan('w', 'e2e4'); $board->playLan('b', 'c7c5'); $board->playLan('w', 'g1f3'); $board->playLan('b', 'd7d6'); $board->playLan('w', 'd2d4'); $board->playLan('b', 'c5d4'); $board->playLan('w', 'f3d4'); $board->playLan('b', 'g8f6'); echo $board->movetext(); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 Chess\\Play\\LanPlay allows to play a bunch of LAN moves at once instead of one by one. use Chess\\Play\\LanPlay; $movetext = '1.e2e4 c7c5 2.g1f3 d7d6 3.d2d4 c5d4 4.f3d4 g8f6'; $board = (new LanPlay($movetext))->validate()->board; echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R \ud83c\udf89 And, it's easy! Recursive Annotation Variation (RAV) \u2728 RAV stands for Recursive Annotation Variation. It is an extension of the Standard Algebaric Notation (SAN) format that allows to annotate chess variations. This format is especially useful for tutorials, notable games, chess studies and so on. Comments are enclosed in curly brackets. Variations are enclosed in parentheses which can be nested recursively as many times as required with the trait that the previous move may need to be undone in order to play a variation. The example below describes how to play the Open Sicilian. 1.e4 c5 {enters the Sicilian Defense, the most popular and best-scoring response to White's first move.} (2.Nf3 {is played in about 80% of Master-level games after which there are three main options for Black.} (2... Nc6) (2... e6) (2... d6 {is Black's most common move.} 3.d4 {lines are collectively known as the Open Sicilian.} cxd4 4.Nxd4 Nf6 5.Nc3 {allows Black choose between four major variations: the Najdorf, Dragon, Classical and Scheveningen.} (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}))) Sicilian Defense. (2023, July 2). In Wikipedia. https://en.wikipedia.org/wiki/Sicilian_Defence Figure 1. The Open Sicilian explained with the help of comments and variations. The RAV reader in Figure 1 displays the variation levels in different shades of gray. It is a 2D scrollable HTML table where the main line is shown in a white background color. The deeper the level, the darker the background color. Chess\\Play\\RavPlay allows to play a RAV movetext. use Chess\\Play\\RavPlay; $movetext = \"1.e4 c5 (2.Nf3 (2... Nc6) (2... e6) (2... d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6) (5...g6) (5...Nc6) (5...e6) ) )\"; $ravPlay = (new RavPlay($movetext))->validate(); print_r($ravPlay->fen); Array ( [0] => rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - [1] => rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 [2] => rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 [3] => rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - [4] => r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [5] => rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [6] => rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [7] => rnbqkbnr/pp2pppp/3p4/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq d3 [8] => rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq - [9] => rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - [10] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - [11] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq - [12] => rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [13] => rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [14] => r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [15] => rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - ) The FEN history is retrieved as an unidimensional array so it can be easily consumed by a frontend UI as shown in Figure 1. The movetext will also pass the validation if adding comments and NAGs. use Chess\\Play\\RavPlay; $movetext = \"1.e4 c5 {enters the Sicilian Defense.} (2.Nf3 (2... Nc6) (2... e6) (2... d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}) ) )\"; $ravPlay = (new RavPlay($movetext))->validate(); print_r($ravPlay->fen); Array ( [0] => rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - [1] => rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 [2] => rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 [3] => rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - [4] => r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [5] => rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [6] => rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [7] => rnbqkbnr/pp2pppp/3p4/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq d3 [8] => rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq - [9] => rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - [10] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - [11] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq - [12] => rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [13] => rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [14] => r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [15] => rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - ) This is how to obtain the validated movetext. $movetext = $ravPlay->ravMovetext->movetext; The filtered() method is to remove tabs and spaces. $movetext = $ravPlay->ravMovetext->filtered(); echo $movetext; 1.e4 c5 {enters the Sicilian Defense, the most popular and best-scoring response to White's first move.} (2.Nf3 {is played in about 80% of Master-level games after which there are three main options for Black.} (2...Nc6) (2...e6) (2...d6 {is Black's most common move.} 3.d4 {lines are collectively known as the Open Sicilian.} cxd4 4.Nxd4 Nf6 5.Nc3 {allows Black choose between four major variations: the Najdorf, Dragon, Classical and Scheveningen.} (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}))) Comments and NAGs can be removed by passing the false value to the first and second arguments of the filtered() method. $movetext = $ravPlay->ravMovetext->filtered($comments = false); echo $movetext; 1.e4 c5 (2.Nf3 (2...Nc6) (2...e6) (2...d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6) (5...g6) (5...Nc6) (5...e6))) And finally, as opposed to the start position, a RAV movetext can also be started from a particular FEN position if passing a chess board object into the constructor of the class. As you can see in the example below, Chess\\FenToBoardFactory is used for this purpose. use Chess\\FenToBoardFactory; use Chess\\Play\\RavPlay; $movetext = \"1.Ra7 Kg8 2.Kg2 Kf8 3.Kf3 Ke8 4.Ke4 Kd8 5.Kd5 Kc8 (5...Ke8 6.Kd6 Kf8 7.Ke6 Kg8 8.Kf6 Kh8 9.Kg6 Kg8 10.Ra8#) 6.Kd6 Kb8 (6...Kd8 7.Ra8#) 7.Rc7 Ka8 8.Kc6 Kb8 9.Kb6 Ka8 10.Rc8#\"; $board = FenToBoardFactory::create('7k/8/8/8/8/8/8/R6K w - -'); $ravPlay = (new RavPlay($movetext, $board))->validate(); print_r($ravPlay->fen); Array ( [0] => 7k/8/8/8/8/8/8/R6K w - - [1] => 7k/R7/8/8/8/8/8/7K b - - [2] => 6k1/R7/8/8/8/8/8/7K w - - [3] => 6k1/R7/8/8/8/8/6K1/8 b - - [4] => 5k2/R7/8/8/8/8/6K1/8 w - - [5] => 5k2/R7/8/8/8/5K2/8/8 b - - [6] => 4k3/R7/8/8/8/5K2/8/8 w - - [7] => 4k3/R7/8/8/4K3/8/8/8 b - - [8] => 3k4/R7/8/8/4K3/8/8/8 w - - [9] => 3k4/R7/8/3K4/8/8/8/8 b - - [10] => 2k5/R7/8/3K4/8/8/8/8 w - - [11] => 4k3/R7/8/3K4/8/8/8/8 w - - [12] => 4k3/R7/3K4/8/8/8/8/8 b - - [13] => 5k2/R7/3K4/8/8/8/8/8 w - - [14] => 5k2/R7/4K3/8/8/8/8/8 b - - [15] => 6k1/R7/4K3/8/8/8/8/8 w - - [16] => 6k1/R7/5K2/8/8/8/8/8 b - - [17] => 7k/R7/5K2/8/8/8/8/8 w - - [18] => 7k/R7/6K1/8/8/8/8/8 b - - [19] => 6k1/R7/6K1/8/8/8/8/8 w - - [20] => R5k1/8/6K1/8/8/8/8/8 b - - [21] => 2k5/R7/3K4/8/8/8/8/8 b - - [22] => 1k6/R7/3K4/8/8/8/8/8 w - - [23] => 3k4/R7/3K4/8/8/8/8/8 w - - [24] => R2k4/8/3K4/8/8/8/8/8 b - - [25] => 1k6/2R5/3K4/8/8/8/8/8 b - - [26] => k7/2R5/3K4/8/8/8/8/8 w - - [27] => k7/2R5/2K5/8/8/8/8/8 b - - [28] => 1k6/2R5/2K5/8/8/8/8/8 w - - [29] => 1k6/2R5/1K6/8/8/8/8/8 b - - [30] => k7/2R5/1K6/8/8/8/8/8 w - - [31] => k1R5/8/1K6/8/8/8/8/8 b - - ) \ud83c\udf89 So this is amazing! That's all we need to read and write chess tutorials, guides and how-tos.","title":"Read Moves"},{"location":"read-moves/#read-moves","text":"","title":"Read Moves"},{"location":"read-moves/#portable-game-notation-pgn","text":"\u2728 Portable Game Notation is a human-readable text format that allows chess players to read and write chess games. PGN is convenient for when reading chess games annotated by humans, for example, those ones available in online databases or published in chess websites. 1.e4 e5 2.Nf3 Nf6 3.d4 Nxe4 4.Bd3 d5 5.Nxe5 Nd7 6.Nxd7 Bxd7 7.Nd2 Nxd2 8.Bxd2 Bd6 9.O-O h5 10.Qe1+ Kf8 11.Bb4 Qe7 12.Bxd6 Qxd6 13.Qd2 Re8 14.Rae1 Rh6 15.Qg5 c6 16.Rxe8+ Bxe8 17.Re1 Qf6 18.Qe3 Bd7 19.h3 h4 20.c4 dxc4 21.Bxc4 b5 22.Qa3+ Kg8 23.Qxa7 Qd8 24.Bb3 Rd6 25.Re4 Be6 26.Bxe6 Rxe6 27.Rxe6 fxe6 28.Qc5 Qa5 29.Qxc6 Qe1+ 30.Kh2 Qxf2 31.Qxe6+ Kh7 32.Qe4+ Kg8 33.b3 Qxa2 34.Qe8+ Kh7 35.Qxb5 Qf2 36.Qe5 Qb2 37.Qe4+ Kg8 38.Qd3 Qf2 39.Qc3 Qf4+ 40.Kg1 Kh7 41.Qd3+ g6 42.Qd1 Qe3+ 43.Kh1 g5 44.d5 g4 45.hxg4 h3 46.Qf3 1\u20130 World Chess Championship 2021. (2023, July 3). In Wikipedia. https://en.wikipedia.org/wiki/World_Chess_Championship_2021 As you may probably know, a chess opening is the group of initial moves of a chess game. This definition applies to classical chess, however, there is no such thing as a chess opening in either Capablanca chess or Chess960. Those two variants were originally conceived to minimize memorization, so when it comes to chess openings it is assumed that we're in the realms of classical chess. ECO, which stands for Encyclopaedia of Chess Openings, is a standard classification system for chess openings. Having said all that, let's now look at B54 which is the ECO code for \"Sicilian Defense: Modern Variations, Main Line\". use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->play('w', 'e4'); $board->play('b', 'c5'); $board->play('w', 'Nf3'); $board->play('b', 'd6'); $board->play('w', 'd4'); $board->play('b', 'cxd4'); $board->play('w', 'Nxd4'); echo $board->toString(); r n b q k b n r p p . . p p p p . . . p . . . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R The play() method in the Chess\\Variant\\Classical\\Board class allows to make moves in PGN format. So far so good, but if you're new to chess you may well play a wrong move in the Sicilian Defense: 4...Na6. $board->play('b', 'Na6'); echo $board->toString(); r . b q k b n r p p . . p p p p n . . p . . . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R No worries! The undo() method comes to the rescue to take back a move. $board = $board->undo(); $board->play('b', 'Nf6'); echo $board->movetext(); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 The movetext() method is used to obtain the moves played in the game using Standard Algebraic Notation. Let's continue practicing chess openings. Now, what if you want to play a bunch of moves at once instead of one by one as in the previous example? Chess\\Play\\SanPlay allows to easily do so. use Chess\\Play\\SanPlay; $movetext = '1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6'; $board = (new SanPlay($movetext))->validate()->board; echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R Please note that the validate() method will throw an exception if the movetext is not valid. Once the $board object is successfully created, the game can be continued from that particular position. $board->play('w', 'Bb5+'); echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . B . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K . . R Every time a move is made, the state of the board changes. Chess\\Variant\\Classical\\Board provides you with plenty of methods to interact with a chess board object. It is a quite common use case to query the board state. As discussed in the Home section, you may want to check out the corresponding tests for further details on how to use it. The unit tests are the best documentation. They contain hundreds of real examples on how to use the PHP Chess library. The isCheck() method will confirm that the white king is in check after 5.Bb5+ while isMate() will confirm that it has not been mated. var_dump($board->isCheck()); bool(true) var_dump($board->isMate()); bool(false) Similarly, you may want to know if the current position is a draw. The isStalemate() method is to find out if the current position is a stalemate while isFivefoldRepetition() will confirm if the game is drawn because of a fivefold repetition. var_dump($board->isStalemate()); bool(false) var_dump($board->isFivefoldRepetition()); bool(false) Text comments in curly brackets can optionally be used in SAN movetexts as well as Numeric Annotation Glyphs . The example below shows how Chess\\Play\\SanPlay is used to validate a SAN movetext that contains NAGs. Remember, the validate() method will throw an exception if the movetext is not valid. use Chess\\Play\\SanPlay; $movetext = '1.e4 c5 2.Nf3 $1 d6 3.d4 cxd4 4.Nxd4 $48 Nf6 $113'; $sanPlay = (new SanPlay($movetext))->validate(); echo $sanPlay->sanMovetext->filtered(); 1.e4 c5 2.Nf3 $1 d6 3.d4 cxd4 4.Nxd4 $48 Nf6 $113 Comments and NAGs can be removed by passing the false value to the first and second arguments of the filtered() method. echo $sanPlay->sanMovetext->filtered($comments = true, $nags = false); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 \ud83c\udf89 Next, let's learn how to process chess moves from a graphical user interface.","title":"Portable Game Notation (PGN)"},{"location":"read-moves/#long-algebraic-notation-lan","text":"\u2728 The UCI protocol enables chess engines to communicate with user interfaces (UI) using Long Algebraic Notation (LAN) for moves. use Chess\\Variant\\Classical\\Board; $board = new Board(); $board->playLan('w', 'e2e4'); $board->playLan('b', 'c7c5'); $board->playLan('w', 'g1f3'); $board->playLan('b', 'd7d6'); $board->playLan('w', 'd2d4'); $board->playLan('b', 'c5d4'); $board->playLan('w', 'f3d4'); $board->playLan('b', 'g8f6'); echo $board->movetext(); 1.e4 c5 2.Nf3 d6 3.d4 cxd4 4.Nxd4 Nf6 Chess\\Play\\LanPlay allows to play a bunch of LAN moves at once instead of one by one. use Chess\\Play\\LanPlay; $movetext = '1.e2e4 c7c5 2.g1f3 d7d6 3.d2d4 c5d4 4.f3d4 g8f6'; $board = (new LanPlay($movetext))->validate()->board; echo $board->toString(); r n b q k b . r p p . . p p p p . . . p . n . . . . . . . . . . . . . N P . . . . . . . . . . . P P P . . P P P R N B Q K B . R \ud83c\udf89 And, it's easy!","title":"Long Algebraic Notation (LAN)"},{"location":"read-moves/#recursive-annotation-variation-rav","text":"\u2728 RAV stands for Recursive Annotation Variation. It is an extension of the Standard Algebaric Notation (SAN) format that allows to annotate chess variations. This format is especially useful for tutorials, notable games, chess studies and so on. Comments are enclosed in curly brackets. Variations are enclosed in parentheses which can be nested recursively as many times as required with the trait that the previous move may need to be undone in order to play a variation. The example below describes how to play the Open Sicilian. 1.e4 c5 {enters the Sicilian Defense, the most popular and best-scoring response to White's first move.} (2.Nf3 {is played in about 80% of Master-level games after which there are three main options for Black.} (2... Nc6) (2... e6) (2... d6 {is Black's most common move.} 3.d4 {lines are collectively known as the Open Sicilian.} cxd4 4.Nxd4 Nf6 5.Nc3 {allows Black choose between four major variations: the Najdorf, Dragon, Classical and Scheveningen.} (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}))) Sicilian Defense. (2023, July 2). In Wikipedia. https://en.wikipedia.org/wiki/Sicilian_Defence Figure 1. The Open Sicilian explained with the help of comments and variations. The RAV reader in Figure 1 displays the variation levels in different shades of gray. It is a 2D scrollable HTML table where the main line is shown in a white background color. The deeper the level, the darker the background color. Chess\\Play\\RavPlay allows to play a RAV movetext. use Chess\\Play\\RavPlay; $movetext = \"1.e4 c5 (2.Nf3 (2... Nc6) (2... e6) (2... d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6) (5...g6) (5...Nc6) (5...e6) ) )\"; $ravPlay = (new RavPlay($movetext))->validate(); print_r($ravPlay->fen); Array ( [0] => rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - [1] => rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 [2] => rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 [3] => rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - [4] => r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [5] => rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [6] => rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [7] => rnbqkbnr/pp2pppp/3p4/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq d3 [8] => rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq - [9] => rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - [10] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - [11] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq - [12] => rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [13] => rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [14] => r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [15] => rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - ) The FEN history is retrieved as an unidimensional array so it can be easily consumed by a frontend UI as shown in Figure 1. The movetext will also pass the validation if adding comments and NAGs. use Chess\\Play\\RavPlay; $movetext = \"1.e4 c5 {enters the Sicilian Defense.} (2.Nf3 (2... Nc6) (2... e6) (2... d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}) ) )\"; $ravPlay = (new RavPlay($movetext))->validate(); print_r($ravPlay->fen); Array ( [0] => rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - [1] => rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 [2] => rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 [3] => rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - [4] => r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [5] => rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [6] => rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - [7] => rnbqkbnr/pp2pppp/3p4/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq d3 [8] => rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq - [9] => rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - [10] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - [11] => rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq - [12] => rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [13] => rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [14] => r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - [15] => rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq - ) This is how to obtain the validated movetext. $movetext = $ravPlay->ravMovetext->movetext; The filtered() method is to remove tabs and spaces. $movetext = $ravPlay->ravMovetext->filtered(); echo $movetext; 1.e4 c5 {enters the Sicilian Defense, the most popular and best-scoring response to White's first move.} (2.Nf3 {is played in about 80% of Master-level games after which there are three main options for Black.} (2...Nc6) (2...e6) (2...d6 {is Black's most common move.} 3.d4 {lines are collectively known as the Open Sicilian.} cxd4 4.Nxd4 Nf6 5.Nc3 {allows Black choose between four major variations: the Najdorf, Dragon, Classical and Scheveningen.} (5...a6 {is played in the Najdorf variation.}) (5...g6 {is played in the Dragon variation.}) (5...Nc6 {is played in the Classical variation.}) (5...e6 {is played in the Scheveningen variation.}))) Comments and NAGs can be removed by passing the false value to the first and second arguments of the filtered() method. $movetext = $ravPlay->ravMovetext->filtered($comments = false); echo $movetext; 1.e4 c5 (2.Nf3 (2...Nc6) (2...e6) (2...d6 3.d4 cxd4 4.Nxd4 Nf6 5.Nc3 (5...a6) (5...g6) (5...Nc6) (5...e6))) And finally, as opposed to the start position, a RAV movetext can also be started from a particular FEN position if passing a chess board object into the constructor of the class. As you can see in the example below, Chess\\FenToBoardFactory is used for this purpose. use Chess\\FenToBoardFactory; use Chess\\Play\\RavPlay; $movetext = \"1.Ra7 Kg8 2.Kg2 Kf8 3.Kf3 Ke8 4.Ke4 Kd8 5.Kd5 Kc8 (5...Ke8 6.Kd6 Kf8 7.Ke6 Kg8 8.Kf6 Kh8 9.Kg6 Kg8 10.Ra8#) 6.Kd6 Kb8 (6...Kd8 7.Ra8#) 7.Rc7 Ka8 8.Kc6 Kb8 9.Kb6 Ka8 10.Rc8#\"; $board = FenToBoardFactory::create('7k/8/8/8/8/8/8/R6K w - -'); $ravPlay = (new RavPlay($movetext, $board))->validate(); print_r($ravPlay->fen); Array ( [0] => 7k/8/8/8/8/8/8/R6K w - - [1] => 7k/R7/8/8/8/8/8/7K b - - [2] => 6k1/R7/8/8/8/8/8/7K w - - [3] => 6k1/R7/8/8/8/8/6K1/8 b - - [4] => 5k2/R7/8/8/8/8/6K1/8 w - - [5] => 5k2/R7/8/8/8/5K2/8/8 b - - [6] => 4k3/R7/8/8/8/5K2/8/8 w - - [7] => 4k3/R7/8/8/4K3/8/8/8 b - - [8] => 3k4/R7/8/8/4K3/8/8/8 w - - [9] => 3k4/R7/8/3K4/8/8/8/8 b - - [10] => 2k5/R7/8/3K4/8/8/8/8 w - - [11] => 4k3/R7/8/3K4/8/8/8/8 w - - [12] => 4k3/R7/3K4/8/8/8/8/8 b - - [13] => 5k2/R7/3K4/8/8/8/8/8 w - - [14] => 5k2/R7/4K3/8/8/8/8/8 b - - [15] => 6k1/R7/4K3/8/8/8/8/8 w - - [16] => 6k1/R7/5K2/8/8/8/8/8 b - - [17] => 7k/R7/5K2/8/8/8/8/8 w - - [18] => 7k/R7/6K1/8/8/8/8/8 b - - [19] => 6k1/R7/6K1/8/8/8/8/8 w - - [20] => R5k1/8/6K1/8/8/8/8/8 b - - [21] => 2k5/R7/3K4/8/8/8/8/8 b - - [22] => 1k6/R7/3K4/8/8/8/8/8 w - - [23] => 3k4/R7/3K4/8/8/8/8/8 w - - [24] => R2k4/8/3K4/8/8/8/8/8 b - - [25] => 1k6/2R5/3K4/8/8/8/8/8 b - - [26] => k7/2R5/3K4/8/8/8/8/8 w - - [27] => k7/2R5/2K5/8/8/8/8/8 b - - [28] => 1k6/2R5/2K5/8/8/8/8/8 w - - [29] => 1k6/2R5/1K6/8/8/8/8/8 b - - [30] => k7/2R5/1K6/8/8/8/8/8 w - - [31] => k1R5/8/1K6/8/8/8/8/8 b - - ) \ud83c\udf89 So this is amazing! That's all we need to read and write chess tutorials, guides and how-tos.","title":"Recursive Annotation Variation (RAV)"},{"location":"your-first-move/","text":"Your First Move \u2728 Some familiarity with chess terms and concepts is required but if you're new to chess this tutorial will guide you through how to easily create amazing apps with PHP Chess. Happy coding and learning! The Chess\\Variant\\Classical\\Board class is the easiest way to get started with PHP Chess. use Chess\\Variant\\Classical\\Board; $board = new Board(); If you have ever attended a chess tournament, you've probably noticed that each player writes down their move in PGN format on a piece of paper. PGN stands for Portable Game Notation and is a human-readable format that allows chess players to read and write chess games. When it comes to computer chess, though, a more appropriate machine-readable format called Long Algebraic Notation (LAN) is often used instead. Be that as it may, you're already set up to play classical chess either in PGN or LAN format. In PGN format: $board->play('w', 'e4'); In LAN format: $board->playLan('w', 'e2e4'); Every time a move is made, the state of the board changes. var_dump($board->toFen()); string(55) \"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3\" This is the chess position in Forsyth\u2013Edwards Notation (FEN) format after 1.e4. \ud83c\udf89 Congrats! 1.e4 is one of the best moves to start with.","title":"Your First Move"},{"location":"your-first-move/#your-first-move","text":"\u2728 Some familiarity with chess terms and concepts is required but if you're new to chess this tutorial will guide you through how to easily create amazing apps with PHP Chess. Happy coding and learning! The Chess\\Variant\\Classical\\Board class is the easiest way to get started with PHP Chess. use Chess\\Variant\\Classical\\Board; $board = new Board(); If you have ever attended a chess tournament, you've probably noticed that each player writes down their move in PGN format on a piece of paper. PGN stands for Portable Game Notation and is a human-readable format that allows chess players to read and write chess games. When it comes to computer chess, though, a more appropriate machine-readable format called Long Algebraic Notation (LAN) is often used instead. Be that as it may, you're already set up to play classical chess either in PGN or LAN format. In PGN format: $board->play('w', 'e4'); In LAN format: $board->playLan('w', 'e2e4'); Every time a move is made, the state of the board changes. var_dump($board->toFen()); string(55) \"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3\" This is the chess position in Forsyth\u2013Edwards Notation (FEN) format after 1.e4. \ud83c\udf89 Congrats! 1.e4 is one of the best moves to start with.","title":"Your First Move"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index a3a79d4b..2e9d69c5 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,42 +2,42 @@ https://chesslablab.github.io/php-chess/ - 2024-11-03 + 2024-11-06 daily https://chesslablab.github.io/php-chess/chess-tutor/ - 2024-11-03 + 2024-11-06 daily https://chesslablab.github.io/php-chess/data-conversion/ - 2024-11-03 + 2024-11-06 daily https://chesslablab.github.io/php-chess/heuristics/ - 2024-11-03 + 2024-11-06 daily https://chesslablab.github.io/php-chess/installation/ - 2024-11-03 + 2024-11-06 daily https://chesslablab.github.io/php-chess/play-chess/ - 2024-11-03 + 2024-11-06 daily https://chesslablab.github.io/php-chess/read-moves/ - 2024-11-03 + 2024-11-06 daily https://chesslablab.github.io/php-chess/your-first-move/ - 2024-11-03 + 2024-11-06 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index f2ad33d22eab05a89116a7bc4b43d22ad24dcb24..3057c818d40611412dd36df35a40d88636a10afe 100644 GIT binary patch delta 264 zcmV+j0r&o!0-FK{ABzYGDWxls2OWQ-s%k5n?0SOs0253M5(bwU$Mx-t9jnT|suYh9 zkC}f)pLo@$@7@j zBh$lxBBoBFwt0babIMY@GIc1jEd_3~)oLHLTB=|!lamlVoO2VMBRigji*k6d179Pu zmW%p68Ibzes$+S4;#I}V=PcQLcQS1ubmo%GmukWJxt4dH81U<$b)G9k9-EO#I>!(n|dQ!0V9z OXY~Um7Ymxt1polpP=fdX delta 264 zcmV+j0r&o!0-FK{ABzYGh=?bV2OWRYF51c_yPlvuzyuS6gu!LTaeez@$EvcgD#atj zW9FaHCtmgGyZ6P_By=$}tP&+FOwh4)p=;RZ$2)&vCv~XDq8xbaz}JYZ z<)Xe%2Bbc=>R2A1c~$Z9DN8orolIK@ow+3QrCM-)uH~KQMkRl-{sOr6oJNZ2@nKsa z;5vrw%pV`vnlU*fr+07@TtEWvfp)R8gNJ!9Z!8&Tc^|K42dr}(6Ti5Gv=aY6@H*uG OS^WT|74Buv1pokW%7f|v