Making a Chess App with Flutter

Apps made easy with Flutter

In this post, I’ll be explaining how to create a concept chess app in Flutter.

Here is a video walkthrough of the app:

The source code and play store link will be at the end of the article.

(NOTE: If you just want to use the project, I have edited some of the package source code files to make work simpler. Please change those before you use it. Copy and paste this code into External Dependencies -> Dart Packages -> flutter_chess_board -> flutter_chess_board.dart)

Getting Started

To get started with a chess application, we first and foremost need a chessboard. As there was no ChessBoard widget, I wrote my own and made it available as a package. The widget maintains game state and has a ChessBoardController for programmatically making moves.

The app has 3 sections:

Piece movement basics Chess Openings Play against a friend

As there would be a lot of chess pieces in the app, I tried to maximise use of Hero Animations.

The app is split into pages and data. The data directory holds the information to display in the app itself. The pages directory holds all the screens for it.

Creating the Screens

The screens of the app are:

Home page Piece list page Piece detail page Opening List page Opening Detail page Two-player game page

Let’s create the pages one by one.

Home Page

The home page simply displays the sections of the app. The cards are rows surrounded by InkWells to provide a splash effect.

class SectionCard extends StatelessWidget {

final Widget leftWidget;

final Widget rightWidget;

final GestureTapCallback onTap;



SectionCard(this.leftWidget, this.rightWidget, this.onTap);



@override

Widget build(BuildContext context) {

return Padding(

padding: const EdgeInsets.all(8.0),

child: Card(

shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),

elevation: 4.0,

child: InkWell(

onTap: onTap,

splashColor: Colors.blue,

child: Padding(

padding: const EdgeInsets.all(8.0),

child: Row(

children: <Widget>[

Expanded(

flex: 1,

child: leftWidget,

),

Expanded(

flex: 3,

child: Padding(

padding: const EdgeInsets.all(8.0),

child: rightWidget,

),

),

],

),

),

),

),

);

}

}

We will use a very similar card as the default card on every screen.

Piece List Page

This is a simple list of chess pieces. The main factor here is we want to implement a Hero Animation where the piece flies to the next page.

Material(

child: Hero(

child: leftWidget, // The widget on the left (Here, the icon)

tag: heroTag,

),

color: Colors.white,

),

Hero Animations are one of my favourite things about Flutter. The ease of implementation of the animations is mind-boggling. The rest of the page is simply about mapping a list of pieces to a list of widgets.

Hero Detail Page

This is the first page in which we use the chessboard itself. We have an icon at the top which is also a hero so that our hero animations actually work. We also display information about the piece itself. So this page is just a column of an Icon, a Text and a ChessBoard. I’ve used a ListView instead of a Column so that smaller screen sizes can be accomodated.

SafeArea(

child: ListView(

children: <Widget>[

_buildTitle(),

_buildContent(),

_buildChessBoard(MediaQuery.of(context).size),

],

),

),

When the screen is created, we clear the normal chess board and add pieces with a ChessBoardController provided with the package.

Future.delayed(Duration(milliseconds: 200)).then((value) {

controller.clearBoard();

controller.putPiece(

pieces[widget.position].pieceType, "e2", PieceColor.White);

controller.putPiece(

pieces[widget.position].pieceType, "e7", PieceColor.Black);

});

For any post-build methods calls, you should generally override didChangeDependencies() instead, but in this case it does not work. So we’ll use a Future.delayed instead and load after 200ms.

Opening List Page

Instead of images of chess openings, I’ve used the entire ChessBoard widget for a single list element, and I was surprised that it even worked. Using multiple ChessBoardControllers here would not work, hence, I edited a bit of the source code of the ChessBoard class itself to allow me to initialise moves when the chessboard is built.

This may cause a problem in running the project on your device, hence copy and paste this code into External Dependencies -> Dart Packages -> flutter_chess_board -> flutter_chess_board.dart. The init-from-moves feature is going to be added into a future release of the package.

Again, as we love hero animations, I made the entire chessboard a hero and it expands when clicked as well.

Opening Detail Page

This displays information about the opening and allows the user to play the opening itself. Like before, it is a simple ListView of a ChessBoard and a Text.

Two-player game Page

The two-player game has a chessboard which has an option to flip according to the user’s moves and also displays the move list played. To flip the board itself, invert the whiteSideTowardsUser parameter of the chess board.

The page has a ListView with a ChessBoard, a few options and notation.

ListView(

children: <Widget>[

_buildChessBoard(),

_buildNotationAndOptions(),

],

),

Final Notes

This was a concept to demonstrate how to make a chess app in Flutter and the package to make it. It needs to be optimised in a few places but as this is just a concept app, I’ll try to do it on the package side instead.

I’d be happy to accept collaborators to work on the future releases of the flutter_chess_board plugin as well.

Thank you for reading this article. Be sure to leave a few claps on the article if you enjoyed it.

PlayStore Link

GitHub Link

flutter_chess_board Package Link