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.02

And 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.

The one-week quest against sugar

After starting to feel the benefits of porridge, I was convinced that better eating habits could change a lot of things for the better in my life. So I asked Alice (my new nutrition coach) recommendations about what I could improve.

She gave me a fun challenge for the week to come: try and reduce my sugar consumption, banishing pretty much all industrial products containing sugar. She also asked me to do my own research about the benefits of avoiding refined sugar in favour of brown sugar. By doing this research I not only acquired some useful knowledge, but it also taught me how to do my own research about nutrition, something that I didn’t even consider doing before.

Without trying to be scientifically exhaustive, I discovered that:

  • Sugar is quite rare in the natural state (mostly fruits), but it’s fundamental for the brain and body. So thanks to Darwin we sapiens developed a very special taste for sweet things, to incite us to go deeper in the forests and look for more berries. This craving for sugar is now exploited by the food industry to sell more products.
  • Refined sugar is basically sugar with many useful nutrients removed from it.
  • Consuming too much sugar can potentially causes all sorts of health issues.

Alice told me to try and find new sugar sources by eating fruits, maple syrup, honey or dried fruit (I went all-in on dried cranberries as a snack during that week). She also suggested to try out a few recipes to treat myself from time to time, such as an avocado-based chocolate mousse, banana ice-creams and energy bars. I tried two of them so far:

IMG_3332
The chocolate mousse was a success!
IMG_3343
The energy bars were’t that bad either but there was a bit too much honey and it melted very easily. Need to retry this once I find a blender.

That week fighting against my crave for sugar was quite fun and it wasn’t as difficult as expected. Alice had warned me and said to take it easy if the crave was too strong. But I didn’t feel any specific lack of sugar (maybe the cranberries helped). But more importantly, I experienced a few positive things:

  • My sense of smell improved. For example, walking past the bakery brought all kinds of new images in my mind (OK, that might have been a consequence of a lack of sugar…).
  • I started to eat a lot more fruits.
  • I was able to better appreciate the sweet taste of fruits.
  • I started to feel when things were ‘too sweet’.
  • If I remember well I started to sleep better around this period as well.

Another major positive point is that I realised that I could keep learning about nutrition by myself and try out new recipes. I became actively interested in the subject of food, cooking and nutrition.

The next step in my nutrition adventure came from reading a book called In Defense of Food: An Eater’s Manifesto. I will share the main ideas and the consequences it had on my eating habits in the next post.

In the beginning came the porridge

Everything happened one evening at the climbing gym. The place was about to close and a friend (let’s call him Kevin) working in the staff gently offered me and another friend (let’s call her Alice) a bowl of porridge. I had never eaten porridge before. It was delicious. Kevin and Alice were quite surprised and started asking me questions about my eating habits. It took them a few seconds to realise the gravity of the situation…


Of course I’ve always known that nutrition was important. I was also slightly interested in the topic. For example, I used to watch a few videos from a rock-climbing Youtuber exposing his view on nutrition. Still, I never considered the subject too seriously. But now it was different. It was clear that I needed a proper food education.

A few days after this realisation, I went online and looked for porridge recipes (like this one). This was literally my first time watching a cooking video. I discovered what chia seeds are (hey, new friends!) and I started eating porridge every morning. My classic recipe has a base composed of 1/3 cup of oats, warmed up in water with a pinch of salt (pro-tip from Alice – it can be soaked overnight. See here an article about the benefits), augmented with chia seeds, greek yogurt or milk (now replaced with almond or soya milk), honey (now replaced with maple syrup or marmalade) and all sort of things for topping (dark chocolate, almonds, bananas, strawberries, blueberries, the sky is the limit!)

40285206_1044384149070539_2520753212676374528_n
Best way to start the day

The ‘porridge benefits’ came quickly:

  • Breakfast was now a real feast: delicious and varied.
  • I had a new reason to wake up in the morning.
  • For the first time in a while I was feeling energetic during the whole morning.
  • My digestion improved (you don’t want more details).
  • My interest in food and cooking was starting to grow and I was appreciating eating good food again.

I’ve eventually became a fierce defender of the porridge community and I highly recommend it as a breakfast idea to anyone who haven’t tried it yet!

 

What I used to eat and the start of my nutrition revolution

From January 2017 to June 2018 I was working like a machine on a personal project and I gave little thought to what I was eating. My diet was composed almost exclusively of:

  • breakfast: a cup of coffee and some nutella spread on some of those Swedish crackers (wasa), or some muesli with milk
  • eating outside once a day: pizzas, sushis, salads, burger-king, often in take-away
  • very basic home cooking: pastas/rice with pesto or tomato sauce, pork chops, chicken breasts, beef steaks, frozen vegetables or veggie mixes and sashimi
  • snacks composed of cookies or milk chocolate

Looking backwards from where I am now, a few points (pretty obvious for most people) stand out about this diet:

  • Not healthy: lack of diversity, fast food, processed food, quite ‘greasy’, not organic
  • Produces tons of wastes from the packagings and boxes
  • Not environmental-friendly
  • Almost no fruits and very low on vegetables
  • Quite pricy
  • Not considering animal suffering (spoiler alert for my current experience with veganism)

From an external point of view though, I wasn’t looking that bad. I had been eating in a very healthy way since I was a child (thanks mom!) and I always exercise a lot. I can’t tell how exactly this diet impacted my health but I’m pretty sure it played a critical role in the depressive state I was in, as well as in the apparition of a few weird body symptoms that I’m not sure I want to talk about here.

In late June 2018 I realised that it was time for a change. OK, some friends rightly suggested that I needed, I quote, a proper food education. I don’t know if it sounds rude, but they were right (many thanks to them!). So I decided to start a personal nutrition revolution. And there came the porridge, and the very first step from getting back to reality and out of depression.