See the Mozilla canvas tutorial for a detailed look at the canvas API. Let us create a simple HTML file index. Using the script tag, we will import the the JavaScript file chess.
When the HTML file is opened in a browser, the onload event on the body tag is triggered. The full source code of the index. Let us now create chess. Ensure that you have chess. The full source code of chess. The drawChessboard method gets a reference to the canvas element using the getElementById method. We then create a 2d drawing context using the getContext method of canvas object. Finally a nested loop draws all the 64 squares of the chess board. Second, when a Square component is created, the compiler will enforce the types of the props.
Third, the N4JS compiler will complain if a mandatory prop is missing. And all these validations happen at compile time during development. In pure JavaScript, we would recognize type mismatch or missing mandatory props problem much later at runtime , possibly during production. The CSS style is dynamically calculated to set the background color based on the values of the passed props. The Board React component represents the chess board.
Even though it does not have state, we define it as a class because it contains helper methods. The most important prop needed by this React component is squares that is an 8x8 array of Piece containing an arrangement of pieces on the board.
Note that the coordinates of the 8x8 Pieace array is different from that of algebraic chess notation. How can we create such a board with pure CSS? The probably easiest way is to use flexbox model. In particular, the board is defined as a flex container with flex-wrap: wrap. The squares displaying chess pieces and coordinates in algebraic chess notation are flex items.
Together with squares displaying coordinates called coordinate squares in this implementation , there are 10 x 10 squares inside the Board component in total. The following diagram graphically depicts this. Since we have to deal a lot with coordinates, we define the Coordinate data structure to represent row,column coordinates. In the class Coordinate above, we define a Spec constructor. This Spec constructor allows us to instantiate a Coordinate by supplying all public members in an object literal.
For example,. Equally interesting is the method toString which should be very familiar to Java developers. This method defines the string representation of a Coordinate. The data structure BoardProps defining the props of Board component is:. Square component informs Board component which in turn informs a parent component about a clicking event. The following screenshot graphically depicts a chess board in which the square 3,7 containing a white knight is picked by the player. The picked square is visually recognizable via the green color.
Additionally, all valid destinations of the white knight are highlighted in yellow color. The class Board , as any class representing a React component, must extend React. Component and override the render method. Note that React. Component expects two type arguments: the first type argument is the type of props and the second type argument is the type of state.
Here, in the render method we create 8x8 Squares components that make up the chess board. We also create two rows and two columns of CoordinateSquare displaying the chess board coordinates. This is the root React component of this application and hence does not have any props. Instead, it has a state represented by GameState. The game state consists of the history of the board as an array of Snapshot , among others. The reason why this is an array, instead of a single element, is that a castling move changes the positions of a king and a rook at the same time.
Further flags such as whiteKingMoved etc. These kinds of information are relevant for handling castling. The tilde symbol here indicates that structural subtyping should be used during type checking. And if yes, the object is considered a subtype of Snapshot.
This is exactly the behavior what we want here. You should read structural typing vs. Its initial value is 0. Each time when a player places a move, it is increased by 1. Here, again thanks to type checking, the N4JS compiler will complain if we, for instance, access a non-existing field of GameState or use the wrong type of a certain field of GameState at compile time. In pure JavaScript, we would recognize those mistakes only at runtime.
The Game component is quite complex because it implements the game rules. In the next section, we will look at some of the implementations of the game rules. The Game component contains logics for implementing the game rules. In this section, we will discuss logics for. We can see that the set of squares being attacked by a certain piece and the set of squares being valid destinations of a certain piece are closely related.
For rooks, knights, bishops, queens, these two sets are in fact almost identical with the exception that moving one of these pieces cannot cause the king to be in check. However, pawns are quite special because they can attack diagonal squares but can only move forwards vertically. Kings have special castling moves that jump two squares. As an example, we will have a look at the algorithm for calculating squares attacked by a bishop.
The general movement rule for a bishop looks as follows:. A bishop as any other piece cannot move if its movement would cause the king of the same color to be in check. In this tutorial, we have opted for a simple imperative implementation: starting from the current position, we iterate 4 different directions: north west, north east, south east, south west.
In each direction, we keep moving forwards as far as possible. The implementation is as follows:. The set of all valid destinations of a bishop is the set of all squares attacked by the bishop with the condition that moving it does not cause the king to be in check. The method isKingInCheckIfMove in the Game component simulates a move of a piece and checks if the move would cause the king of the same color to be in check. Checking whether a king is checkmated is interesting.
A king is checkmated if all pieces cannot move anymore, i. This logics is implemented by the method calculateWinner in Game. We use Webpack to bundle all JavaScript files of the application, including dependencies such as React, into a single JavaScript file. Webpack is configured in webpack. The following diagram graphically depicts the build process with the help of Webpack.
Note that we need to specify the entry point. We also configure a Webpack Dev server with hot loading enabled so that we can start the application locally. Chess Game Tutorial Part 1 Jump to topic.
0コメント