I like to play with unfamiliar stuff. Not that I’ve never written an Android or java application, but this one is a bit different. It’s a simple game I’ve made while I was looking at (real life) puzzle game where you have to switch knights from a chess-game from one position to another. Not really hard, but not very simple either. I knew there are plenty of puzzle games like this out there, so I decided to create a simple game-engine that allows to create those games easily. The result: a 90% finished game called PuzzleChess. This blog-post is trying to find the last 10% of the game :)
First of all, the source: https://github.com/jaytaph/PuzzleChess
The basic idea is simple: it’s an engine where you can define a chessboard, add some initial pieces onto it, have some kind of rule-set and let the user figure out how to win. Every one of these puzzles gets added to the main index, so you can see which puzzles are done, which are still left open etc:
Each puzzle has a name, a small caption, an icon and a difficulty. When the puzzle has been solved, a check mark will appear (saved inside a small database).
Now, the actual engine is very simple: a board that can have their cells either active or inactive. Inactive cells makes it possible to create a smaller board. For instance, in the knights-game:
You can only place move pieces to active cells. Note that for this game, I needed to have some “dots” on the cells as well to mark the places of the black and white knights. It’s possible to add some extra stuff to a cell.
Another nice thing: there are themes as well! These themes are available from the menu. It basically does nothing more than change which graphics need to be plotted on every frame. This includes the pieces and the board (the dark and light cells).
Every piece have their own special way of moving: a rook can only move straight, while a bishop can only move diagonally. All pieces extend the “piece” class which defines how a piece can move.
Creating a new game
It’s quite easy to create a new game:
- Add a game class that extends “game” to the game-directory.
- Define the board (all fields visible, or only some)
- Add pieces to the board
- Add optional decoration to the board (in case of the dots at the knights-game)
- Define the objective in getObjective(). This is shown to the user to figure out what he/she needs to do
- Define a hasWon() and an optional hasLost() to let the engine know when the game is won/lost.
- Define a init() in which you define the engine parameters. The game can have an unlimited amount of moves, or only a select number. Unlimited time, or you need to figure the game out in a certain amount of time. You can define if you need to show the trace of moves, so every piece leaves a mark on where it has been (handy in games where you need to travel a knight over every cell of the board once), or maybe you can “take” pieces from the enemy. These are all defined by the GAMEOPTION_* constants.
The application itself is quite easy in setup. It has 2 activities: the main menu and the puzzlechess activity. The main menu does nothing more than select a game that is passed to the puzzleChess activity (main.java:onCreate -> the setOnItemClickListener).
The actual meat of the application starts with the puzzleChess activity. It has a timer-thread to keep track of the time by sending a MESSAGE_DURATION message. This will allow the updateHandler to update the current time (either increase or decrease the timer). Another thread is started for updating the screen itself. This timer runs every 10ms and sends a MESSAGE_UPDATE message to the handler. This will redraw the panel (chessboard) and checks if the game has been won or lost. This update is needed because when we move a piece to another screen, it’s done through a simple animation that moves the piece from cell A to cell B. This is taken care of by the ChessPanelView.java class.
The chesspanelview is nothing more than a simple view that draws the screen. It will draw the background, will allow the board to be drawn (this is done by the Board.java class itself), and displays the status like Moves Left, Moves Done and Duration of the game. When the panel is touched (onTouchEvent), it will figure out which cell has been touched, and directs it to the game class that will handle the onClick(X, Y), where X and Y are the row/col of the cell, not the actual coordinates (because that is not needed for the board/game).
The Board has got a lot of logic to deal with cells and pieces on those cells. It’s draw() method will create a cache of the board (without any pieces) so we don’t have to regenerate this on every update. Then it will draw that cached background onto the canvas (which is the panelview). Then it will draw all pieces on the board, but when a piece is animated, it means it’s in progress of moving from one cell to the next. In that case, the piece must not be drawn in a cell, but somewhere between cell A and cell B. The piece itself will interpolate the route between the two cells and returns the correct position. When we have arrived, the animate() method of the piece will return false, so the board will draw the piece correctly onto the cell (so it’s an active piece again).
More stuff will then be printed, like the tracemoves of traveled cells (if the game needs this), and border colors, which are the colors that are shown when you have clicked on a piece and will show you where the piece can move to.
The rest of the methods in this class are pretty straight-forward and takes care of handling the board, cells, and pieces on the board.
The piece.java class is an abstract class that defines a piece. Every piece has got an identifier (a tag, for instance: white rook 1, black knight etc). A color (black or white) and a boolean if the piece can be moved or not. It has got some methods to deal with animation, in case we travel from one cell to another.
This class defines “move”-methods like singleDiagonalMoves(), diagonalMoves() etc, which returns the available moves that can be made into that direction for the piece. It’s quite simple: if we are in a corner, a bishop can only move in one direction: away from that corner. When the bishop is in the center square of the board, if can move in all four directions, unless there is another piece in the way. These functions takes care of these conditions (together with the fact if the actual fields are enabled on the board or not), and returns an array with all available moves that can be done.
These move-functions will call the isValidAvailableField() method, which checks if field X, Y is available. Off course, it will take everything in account (disabled fields, traced fields, fields with pieces that we cannot take etc).
There is not much more going on for pieces. They are simple elements that can be moved and which can define their paths by themselves. The rest is taken care of by the board-class.
Every type of piece (rook, king, queen) etc, have their own class, in which we define the name (getName), the resource (the image of the piece) and a list of available moves. This list is created by calling the move-methods from the abstract class. A queen will check Piece::straightMoves() and Piece::diagonalMoves(), but not Piece::knightMoves(), a king will check Piece::singleDiagonalMoves, Piece::singleLeftRightMoves and Piece::singleUpDownMoves() etc..
The game class by itself is also an abstract class. It holds all information about the game and takes care of moving the pieces. The onClick handler, which is passed from the PanelView, will check if we already selected a piece. If not and we clicked on a piece, that piece will become active so we can show all the possible paths for that piece (_onClickNoSelection). It will check if there is a piece, if we are allowed to move it, and if so, adds “bordercolors” to the board: when the piece can overtake another piece on it’s path, it will have a red bordercolor, otherwise a green.
When we have clicked on the same piece that we activated, it means we need to deactivate it and remove all the border colors again. This is done by _onClickSelectionSameField.
When we have clicked on another field while a piece has been activated AND we are allowed to move to that field, we will move the piece. The board-class will start this move, and stores the information (animated) into the piece so on the next update, we will see this piece actually moving from cell to cell.
The game class itself has basic functionality for the game itself: hasLost, hasWon etc to check if we have won or lost the game.
Every game must extend this game class but is really easy to setup as you have read in the “creating a new game” chapter.
There are still some issues with the application. And there is still a big issue I need to figure out: we use a canvas defined by pixels so it doesn’t work quite well on every tablet or phone. I use a 480 (was 320) large panel so we have 60x60 pixel cells. We should be able to scale everything: the cells, the background, the pieces etc.
Another issue that the game isn’t finished yet. There are still some issues here and there (crashes, actually) and we need to check all the current games to see if they actually work. But on the whole, it’s almost ready.. Now just find the time to create the finish 10 percent. If you like to contribute: https://github.com/jaytaph/PuzzleChess