The world’s leading publication for data science, AI, and ML professionals.

Developing the Go Game (围棋) using matplotlib and NumPy - Part 1

Drawing the Go Board using matplotlib

Source: https://en.wikipedia.org/wiki/Go_(game)#/media/File:FloorGoban.JPG
Source: https://en.wikipedia.org/wiki/Go_(game)#/media/File:FloorGoban.JPG

Most aspiring data scientists are no strangers to matplotlib – the data visualization library that was designed for creating static, animated, and interactive visualizations in Python. And most of the time your experience in using matplotlib might be using it to plot charts, as such bar charts, histograms, pie charts, and even 3D charts.

For me, I wanted to explore how matplotlib can be used for something more fun – using it to create a board game, such as Go. And so I set out to challenge myself to see if I could create a Go application that allows users to play the game of Go.

Go (or more commonly known in Chinese as Weiqi, Weichi (simplified Chinese: 围棋; traditional Chinese: 圍棋; pinyin: wéiqí) is an abstract strategy board game for two players in which the aim is to surround more territory than the opponent. Source: https://en.wikipedia.org/wiki/Go_(game)

My intentions for this project are simple:

  • Use matplotlib as the UI library to plot the Go board
  • Explore the interactive features of matplotlib to allow users to place stones on the Go board
  • Use NumPy to detect if a group of stones are surrounded and needs to be removed from the board
  • Calculate the amount of territory captured by a player and determine the winner for the game
  • Use sockets programming to allow users to play the game over a network
  • And in the future, use machine learning and deep learning to enable the application to play against a human opponent.

This is very much a project in progress, but I wanted to share how things are being done. If you have a better technique than I do, please be sure to share them with me in the comments.

For the first part of this series, I am going to show you how I used matplotlib to draw the Go board.

Drawing the Board

Let’s get started with drawing the Go board. For this project, I am going to create a text file named go.py.

To draw the board, I will define a function named draw_board() and add it to the go.py file:

import matplotlib.pyplot as plt
import numpy as np
def draw_board():
    # create a figure to draw the board
    fig = plt.figure(figsize=[9,9])
    # set the background color
    fig.patch.set_facecolor((0.85,0.64,0.125))
    ax = fig.add_subplot(111)
    # turn off the Axes
    ax.set_axis_off()
    return fig, ax
fig, ax = draw_board()
plt.show()

In the above function, I:

  • Created a matplotlib figure with a size of 9 inches by 9 inches (width, height)
  • Set the board color using the set_facecolor() function of the figure’s Patch object

A Patch object is a 2D artist with a face color and edge color.

  • Created a plot in the current figure, which returns an Axes object
  • Turn off the axes labels using the set_axis_off() function
  • Returned the figure and axes object to the caller of the function

To run the application, type the following in Terminal:

$ python Go.py

The empty Go board now looks like this:

Image by author
Image by author

Drawing the Grids

With the board drawn, it is now time to draw the grid. A standard Go board has 19×19 grid of lines, containing 361 points. To draw the grid lines, you first draw 19 vertical lines, with each coordinates specified as follows:

Image by author
Image by author

You can use the plot() function to draw a straight line. The plot function accepts the following arguments:

Image by author
Image by author

For horizontal lines, the coordinates look like this:

Image by author
Image by author

You can now put this into code. For this, I define the draw_grids() function to draw the 19 vertical and 19 horizontal lines:

import Matplotlib.pyplot as plt
import numpy as np
def draw_board():
    ... 
    return fig, ax
def draw_grids(ax):
    # draw the vertical lines
    for x in range(19):
        ax.plot([x, x], [0,18], 'k')
    # draw the horizontal lines
    for y in range(19):
        ax.plot([0, 18], [y,y], 'k')
fig, ax = draw_board()
draw_grids(ax)
plt.show()

The Go board now looks like this:

Image by author
Image by author

Observe that there is quite a bit of border surrounding the grids (and also off-centered), so let’s try to reduce the amount of space around the grid. To do so, let’s first print out the boundaries of the plot:

def draw_grids(ax):
    # draw the vertical lines
    for x in range(19):
        ax.plot([x, x], [0,18], 'k')
    # draw the horizontal lines
    for y in range(19):
        ax.plot([0, 18], [y,y], 'k')
    print(ax.get_position().bounds)

You will see the following output:

(0.125, 0.10999999999999999, 0.775, 0.77)

The output above corresponds to the point and dimensions shown below:

Image by author
Image by author

To center the grid, set the position of the axes as follows:

def draw_grids(ax):
    # draw the vertical lines
    for x in range(19):
        ax.plot([x, x], [0,18], 'k')
    # draw the horizontal lines
    for y in range(19):
        ax.plot([0, 18], [y,y], 'k')
    ax.set_position([0, 0, 1, 1])
    print(ax.get_position().bounds)

The grid is now at the center of the figure:

Image by author
Image by author

As I want to leave some space at the bottom (for some buttons later on), I will further adjust the y-value:

ax.set_position([0, 0.2, 1, 1])

And here is the final position of the grid:

Image by author
Image by author

Drawing the Star Points

A Go board has nine dotted points on the board called star points.

The point in the center is also known as the central star.

At this moment, it is useful to know the coordinates for the various points in the grid:

Image by author
Image by author

So if you want to plot a point as shown in the following figure, this point would have the coordinate of (3,9):

Image by author
Image by author

You can now define a function called draw_star_points() to draw all the star points:

import matplotlib.pyplot as plt
import Numpy as np
def draw_board():
    ...
return fig, ax
def draw_grids(ax):
   ...
def draw_star_points(ax, x, y):
    ax.plot(x,y,'o',markersize=8,
            markeredgecolor=(0,0,0),
            markerfacecolor='k',
            markeredgewidth=1)
fig, ax = draw_board()
draw_grids(ax)
# draw the 9 star points on the board
draw_star_points(ax, 3,3)
draw_star_points(ax, 3,9)
draw_star_points(ax, 3,15)
draw_star_points(ax, 9,3)
draw_star_points(ax, 9,9)
draw_star_points(ax, 9,15)
draw_star_points(ax, 15,3)
draw_star_points(ax, 15,9)
draw_star_points(ax, 15,15)
plt.show()

The final Go board now looks like this:

Image by author
Image by author

Summary

At this point, I have managed to draw a Go board using matplotlib. Looks good and resembles a real Go board. The next part would be to let the user put stones on the board, and have the ability to alternate between white and black stones. Stay tuned!

Join Medium with my referral link – Wei-Meng Lee


Related Articles