Pet project: chessboard UI – Day 5/6/7

Last Sunday I went to a meet-up in Stockholm where developers gather in a Starbucks to work on personal projects. By speaking with a more experienced JS developer I realised that it would be nice to improve and refresh my knowledge about the raw JavaScript language. So I spent most of my programming time going through the official documentation and reading through a nice book, Eloquent Javascript. (The YDKJS series is also good, I read it a year ago but I find Eloquent Javascript to be better organised and more practical). Still, some decent progress has been made on the chess project!


Drag & Drop

Moving pieces via Drag & Drop has been successfully implemented. In react-dnd jargon, I decided to make <Piece /> a DragSource and <Square /> a DragTarget.

When a Piece is dropped on a Square, a MOVE action is dispatched to update the game position:

Screen Shot 2018-08-29 at 18.14.00

Move validation

As you might have noticed in the previous screenshot, the MOVE action is actually only dispatched if the index of the destination square is included in the props legalMoves, which is an array of all legal (valid) index moves.

I decided that those legalMoves would be calculated at the square level and passed to each piece as a prop. This way, we always know where a piece can move before it is actually moved by the user, improving the speed and the overall UX. This will also be helpful if we decide to help the user by highlighting the possible moves when a piece is being dragged.

To do so, the <Square /> container gets the legalMoves from the redux store via a selector, getLegalMoves. But since the moves are specific to a square index, I had to pass the square index to the selector. To be sure that everything was correctly memoized, I followed ideas from this article:  Computing Derived Data.

Screen Shot 2018-08-29 at 18.25.28.png
The getLegalMoves selector takes the square index as argument

Then the fun began with writing the logic of the findLegalMoves function. After quite a few Jest tests and calculations, the basic chess rules have been implemented. The code of the chess logic is not completely DRY for now: it would be good to refactor some parts. But at least it is tested, which will facilitates a lot the implementation of more advanced chess rules and the refactoring work.

Screen Shot 2018-08-29 at 18.01.00.png
All green!

There is one part of the code that I was quite satisfied with: the function to find the valid queen moves reuses the functions to find bishop and rook moves. This represents nicely the fact that a queen in chess has the combined abilities of a bishop and a rook:

Screen Shot 2018-08-29 at 18.29.33

Live demo

I deployed a demo of the app on Heroku with this handy buildpack. Feel free to try it out!

Screen Shot 2018-08-29 at 18.36.41

Next steps

I might slow down on this project to continue reading Eloquent Javascript and go through the codebase of my former project (ChineseMe) to prepare some job interviews.

Still, there are some simple ways to improve this app:

  • Complete the chess logic
  • Add basic user actions (start a new game, go to previous / next move)

I’m not that far from completing all the TODOs to achieve the simple vision I had for this pet app. I’ll make an update in the future when significant progress is done. Cheers!

Pet project: chessboard UI – Day 4

Today was a short programming session. The objective was to move pieces on the board by dispatching MOVE actions.

Handle MOVE actions in the game reducer

This is the first implementation of a move. I update the position as well as the fullMoveNumber. Note that I use a function called calculateNextPosition() to find the next position based on the origin (from) and destination (to) squares.

Screen Shot 2018-08-25 at 11.55.13

The calculateNextPosition() function was not existing yet. So I wrote a test for it:

Screen Shot 2018-08-25 at 11.53.44

Thanks to the two util functions developed yesterday (positionToArrayOfPieces() and arrayOfPiecesToPosition()), making this test pass wasn’t too difficult:

Screen Shot 2018-08-25 at 11.54.02And with that in place, all the tests are now passing!

Screen Shot 2018-08-25 at 12.08.29

Playing around in Redux devtools

According to the tests everything should be working properly. Still, it’s fun to see the pieces moving on the board! Below is a small demo recorded live.

Note: don’t try this in an actual chessgame…

Tomorrow I’ll try to implement moves via Drag & Drop using React DnD.

Pet project: chessboard UI – Day 3

Today was a really poor day for the user of our chessboard (no new feature!). BUT I’m quite satisfied with the progress made on the app structure and the development experience. Almost everything I mentioned yesterday has been implemented.


Redux and ducks

I started the day by setting up Redux. I decided to do this early because…

  • it is much more convenient to hold the state of the application in one single store.
  • it will be more convenient to handle user actions.
  • it will allow time-travel between moves (something that chess.js doesn’t support).
  • it allows me to conveniently test the app logic (by dispatching actions and comparing the expected state to the actual state.

To do so I installed the following libraries: redux, react-redux, immutable, redux-immutable, reselect, redux-devtools-extension. Then I refactored the currently very simple codebase to match the ‘ducks’ organisation, which I previously used on the ChineseMe project and found very convenient when scaling up.

Screen Shot 2018-08-24 at 16.23.54
Up and running with Redux and Redux Devtools

Improved Game State

Instead of saving the full FEN string in the store, I decided to cut it into it’s six distinct parts. This will make it easier later to update the game situation based on user actions:

Screen Shot 2018-08-24 at 15.36.41

I use Reselect to recreate the full FEN string based on those six elements:

Screen Shot 2018-08-24 at 16.29.42

Testing the app logic

With this first ‘duck’ in place I can now develop the logic following a TDD approach. With Redux, the idea is quite simple: the only thing that can happen is user actions resulting in redux actions, which are handled by reducers, which update the state in the storeThe UI then displays components by querying the store’s state via selectors.

Image result for redux action reducer store selector image
Diagram taken from this article

 

This means that we can test that every part of the flow works as expected by creating tests that:

  1. Generate an action using an action creator
  2. Calculate the next state by passing the action to the reducer
  3. Get the next state via the appropriate selector
  4. Compare the next state to the expected state

With that in mind I wrote a failing test for a future ‘MOVE’ action:

Screen Shot 2018-08-24 at 15.38.20
A useful pattern to test the logic of a redux app

As expected the test is currently failing since the position is not yet updated. I’ll handle the logic of the ‘MOVE’ action tomorrow:

Screen Shot 2018-08-24 at 15.38.36.png
As expected, it’s a fail! So far so good.

Useful util functions

When handling user actions it will be more convenient to work at the square level. If we represent the board by an array of 64 strings, it’s easy to understand what ‘moving a piece’ means: moving elements within the array.

However as far of the app state is concern, it’s much more convenient to keep track of the position as a string. And it would be more convenient if a server was added to this project (a simple string is easier to save in a database than a JS array.

With that in mind I developed two useful util functions:

  • positionToArrayOfPieces
  • arrayOfPiecesToPosition

I followed a TDD approach to facilitate the development of those functions:

Screen Shot 2018-08-24 at 10.47.28

 

 

Pet project: chessboard UI – Day 2

Today was a rather short session. I started by adding a <Game /> component that will be responsible for handling the data of the whole game (mainly the data from the FEN notation). That way we can keep track of the whole game situation, and the <Board /> only has to care about the position.

Then I played a little bit with the chess.js library. I went for a basic test implementation (there are cleaner ways to integrate third party libraries in React components).  Still, this demonstrated the possibilities offered by this library:

Screen Shot 2018-08-24 at 08.47.55
Initiating an instance of Chess in the componentDidMount() method of the <Game /> component.

With this code the board now displays the game, here after the first move ‘e4’:

Screen Shot 2018-08-24 at 08.51.52
One move in!

Now here are a few things I realised and will have in mind for the coming days:

  • Using chess.js sort sof defeat the purpose of this pet project. I’ll learn more by developing the chess logic myself, gradually adding more rules.
  • React DnD (Drag & Drop) looks like a promising option for allowing the user to move pieces. And the official tutorial even showcase this very chess example.
  • I need to start separating the react components between components (responsible for rendering UI elements) and containers (responsible for handling the data and passing it as props to the components). This distinction is sometimes called dumb vs. smart or presentational vs. container components. Here is an explanation from Dan Abramov.
  • I will soon need redux to have the whole state of the app in one place and handle user actions in a more manageable way. This article explains how to add redux.
  • Redux will also allow me to follow a TDD approach when developing the chess logic. For example, I can write a test to see if the game data is updated (using selectors) when a user move a piece (a redux action). This article looks like a good reference.

Pet project: chessboard UI – Day 1

Yesterday I decided to start a small project to practice my JS skills. The objective is to develop an interactive chessboard UI with React. I decided to give it a week of time, with 2-5 hours of programming every afternoon. Let’s see how far I can go!

I don’t have a clear idea of what degree of complexity I want to reach in terms of features (the existing UIs for popular chess websites are quite advanced, see lichess.org for example), but hopefully I’ll be able to move pieces on the board in the coming days!

The code is public on Github and can be found here: https://github.com/TimAstier/react-redux-chess


Day 1

I expected the first day to be quite a struggle because it had been about two months since I last opened a code editor. Fortunately I spend less time than expected with the initial configuration and soon I was all set up and ready to develop my first React component in the Storybook: an Empty black <Square />! Soon followed by a collection of <Piece />.

 

From there displaying a <Board /> was straightforward but still quite satisfying!

Screen Shot 2018-08-23 at 16.00.46
A soon-to-be-full-of-pieces chessboard

Displaying chess positions on the board was the funniest part of the day. I discovered that there is a convenient and standard way to store a complete chess position in a string, the FEN notation. For example, this is the initial position of a game of chess:

'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'

The first part of the string describes the pieces on the board, row after row. For example, ‘r’ stand for a black rook, and ‘K’ stand for a white king. Digits indicate a series of empty squares. Rows are delimited with ‘/’.

Since my <Board /> component had a renderSquares() method that renders the 64 squares of the board, all I needed was to render the squares based on the position described in FEN notation. I used a util function called positionToArrayOfPieces() to provide every ‘Square’ with its content.

renderSquares(position) {
    const squares = [];
    let index = 0;
    const arrayOfPieces = positionToArrayOfPieces(position);
    for (let i = 1; i <= 8; i += 1) {
      for (let j = 1; j <= 8; j += 1) {
        squares.push(
          <Square
            key={index}
            color={this.coordinatesToColor(i, j)}
            content={arrayOfPieces[index]}
          />
        );
        index += 1;
      }
    }
    return squares;
  }

And, voila! We have our starting position:

Screen Shot 2018-08-23 at 16.07.53

In the evening I did some research to find a way to avoid having to develop all the chess logic myself (chess is somewhat more complex than tic-tac-toe). It happens that most existing chess websites use a library called chess.js, so I will probably use it as well if I reach a stage where I can start playing a game of chess on this UI.

Why I like programming

By programming I mainly mean ‘web development’ as this is what I’ve mostly been doing.

I like programming because …

  • it is a mix of writing, reading, logic and art.
  • it involves personal decision making, group working and constructive feedback loops with other developers, people with different roles and users.
  • it is linked to many other disciplines or activities such as design, psychology, project management, entrepreneurship, game design …
  • it solves real-world problems.
  • it requires to constantly learn new things and better ways to do things.
  • it is a ‘hard skill’.
  • it can be used to do jobs that pay relatively well.
  • I can see the direct result of my work.
  • it is a craft that doesn’t requires me to be in a specific location. All I need is a computer and possibly an Internet connection.
  • it requires to be 100% focused on the task. When I am in this situation, I feel like anything can be done and I’m committed to do everything it takes to get it done.
  • it’s deeply satisfying to learn new concepts or understand how a piece of code works and slowly feel that everything comes together and becomes a ‘second nature’. In the good days, I think about the problems I have during the night, and when I reach the computer in the morning I know exactly what needs to be done. In those moments the coding part is almost automatic.