Course:CPSC312-2017 Checkers

From UBC Wiki


Authors: Sam Holdcroft, Katie Li-Wong, Nicholas Wu

What is the problem?

What is Checkers?

Checkers (or Draughts) is a two player strategy game, where opponents take it in turns to move pieces around a board and 'take' pieces belonging to the other player. The ultimate goal of the game is to remove all of your opponents pieces from the board. The game is played with diagonal movements, on each players turn they are allowed to move one of their pieces forward 1 space diagonally. If there is an opponents piece on the square they want to move to, but the square on the other side of this piece is free (the square two spaces away), then they are allowed to move over the opponents piece and 'take' it - remove it from the board. When a piece gets to the far side of the board, so when player 1's piece gets to the back row of player 2's side, the piece becomes a 'king' and is allowed to move backwards.

What are we going to do?

We would like to implement the game of Checkers in Haskell. Our program should automatically create an 8x8 checkers board, correctly populated with pieces in the correct position. It should allow us to move the checkers pieces across the board, with support for 'taking' other player pieces and promoting a piece to a 'King' when the piece reaches the opposite side of the board. Finally, it should not allow the user to make incorrect moves. We also decided that the core program would not strictly play the game, it would just simulate a board. The core program does not enforce players to take turns, but this is very similar to the real life version of the game. A cmd UI was created and alternates between player 1 (white) and player 2 (black) turns and asks for the x and y coordinate of the piece they would like to move and shows all the valid moves for the piece chosen. The move can either be a 'move' or 'take'. Then asks for the x and y coordinate of where it would like to move to. The board is then updated and prints the new state of the board.

How did we do it?

In order to facilitate the creation of this program we made a few new types. The first is CPiece, it describes a checkers piece and can be either Black, BlackKing, White or WhiteKing. We also make a type called CBoard, which describes a Checkers board. This is of type Maybe CPiece - it is a 2D list (where each inner list represents a row of the board, and the outer list is a list of rows) where each item can either be Just a CPiece (i.e there is a checkers piece at this location) or Nothing (No piece here). We made one final type, CMove, that describes the two types of movement a piece can make - so a Move (x1,y1) (x2,y2) is a movement of the piece at (x1,y1) to (x2,y2), and a Take (x1,y1) (x2,y2) is also a movement of the piece at (x1,y1) to (x2,y2), but it removes the opposing piece found at (x1+x2/2,y1+y2/2).

We used these types to create functions that make a board and allow players to move pieces around a board.

What is the something extra?

As an extension we would like to create a UI to help users play the game. This could be as simple as a text based interface, or a full on GUI.

What did we learn from doing this?

Haskell seemed to work very well for this kind of application, it allowed us to make a very compact representation of a board. It was tricky to manipulate the board, the recursive nature of Haskell is not the most intuitive method to create and modify a game board. However, the simplistic nature of it means that there were very few bugs. We also could not take advantage of lazy evaluation too much - after every move we had to display the board, so Haskell had to evaluate the entire board upon moving a piece. With the possibility of making a graphic user interface, there were some errors in package installation which halted this process which led to a text based cmd user interface. This most tricky part was how to keep track of a 'global' board state which could be updated as each piece was moved.

Guide to using the program

Using the core code

To create a new standard Checkers board, use makeStandardBoard. To execute a move, use the following command move board movement, where boards is a CBoard (such as the one made with makeStandardBoard), and movement is a CMove (such as Move (1,2) (2,3)). This function returns a CBoard with the movement executed on it - so save this somewhere!

If you want to see your board, the function printBoard displays a rudimentary representation of a given board. Whilst this may not be a pretty site, it's still nicer than the default mess of lists that a CBoard prints as.

After starting the UI, each turn consists of four inputs, (2 x's and 2 y's). First the x and y location of the desired piece to move and second, the x and y location of where to move. The board then updates accordingly. The Board axis: 11403749dd.png


All of our code can be found on our GitHub repository, where it is available under a Attribution-ShareAlike 4.0 International license.