
Peg solitaire is a board game that involves moving pegs on the board that start with one single hole. There are two different types of boards that are commonly used. In this blog, we will build an English version of the board. Aim of the game is to remove all pegs from the board (except the last one). You remove pegs by jumping over them.
I mentioned in my previous blog post that I got a 3D printer. I also started to learn the basics for a CAD software called OpenSCAD (open-ess-cad). On my journey to learn this software, the second thing I thought of creating is peg solitaire. I will detail out the steps for building this game. However, please remember that there may be a lot of different ways to achieve this goal, what you find here is the beginners way of building it.
The design
I have an old peg game, which has cylindrical pegs. So, I started by taking the dimensions for these pegs. I did not require this step, but it gave me the additional benefit of replacing the pegs I lost from the old game.

Old peg was two cylinders one on top of the other. See the dimensions on the side. I decided to update it to a more streamlined look. I put a frustum of a right circular cone instead of a cylinder and added a spherical volume on top.
Having come up with the design, it is now time to start coding in OpenSCAD. The first thing I did was to build one peg, hic.
Creating a Peg
Since this shape is fairly simple, we will just use the built in 3D shapes in OpenSCAD. In this case, we just tool 3 different shapes and put it on top of each other. The bottom is a cylinder with both radii same. On top of this we overlay one more cylinder – however in this case we have a different radius for two sides. This gives us a frustum of a conical shape. Finally we add a sphere on the very top of the design.
$fn = 50; radius_big = 3.2; radius_sml = 2.2; height_big = 8.0; height_sml = 4.8; module make_peg() { cylinder( h =height_sml, r1=radius_sml, r2=radius_sml); translate([0, 0, height_sml]) { cylinder( h =height_big, r1=radius_sml, r2=radius_big); } translate([0, 0, height_big + height_sml]) { sphere(r=radius_big); } } make_peg();

Code above generates one peg at the center. There are multiple ways of making this. We started with 3D shapes and put a cylinder first. This was followed by frustum added to the top of the cylinder. Finally we added a sphere to the top of this. We could have also started with a 2D shape and extruded it to get a cylinder. We could have also used hull to arrive at this shape.
However, this will always draw a peg at the center. Let’s add translations so that we can draw this peg anywhere on the X-Y plane. Finally we will draw 36 of these pegs on the table – so that we can print them all out in one go.
// I need 32 of these pegs printed object_sqr = 6; // For convenience object_sep = 8; module make_peg(tx, ty) { translate([tx, ty, 0]) { cylinder( h =height_sml, r1=radius_sml, :::::::: :::::::: sphere(r=radius_big); } } } mini = -1 * (object_sqr - 1)/2; // Minimum X-Y maxi = (object_sqr - 1)/2; // Maximum X-Y for (i = [mini:1:maxi]) { for (j = [mini:1:maxi]) { make_peg(i*object_sep, j*object_sep); } }

We have 36 pegs all arranged nicely in a square. We have a distance of 8 units between the pegs. During print, I will put a brim under the pegs so they stick better.
Creating the board
I have seen boards that are round and also boards that are squares. I decided to create a octagonal board as that seems to fit perfectly with the shape of the puzzle. We start by defining some constants and the drawing a octagonal shape. You will notice that we are also rotating the shape by 23.5 degrees. This way the center of sides is aligned to the X-Y co-ordinates and it is easier to draw the holes.
$fn = 50; oct_hgt = 9; dia_hol = 5; dis_hol = 8; hgt_hol = 6; cyl_dia = 5 * dis_hol + 6 * dia_hol; rotate(a=23.5) { minkowski() { cylinder(r=1); cylinder(h=oct_hgt, d=cyl_dia-1, $fn=8); } }
We are overriding $fn to 8 here, so an octagon will be drawn. We have a small cylinder rounding off the shape using minkowski(). This avoids have any very sharp edges. Next step is to draw the holes. We will use difference() and take away cylinders from the base octagon created. I will not explain the code below in detail. It just runs through three different loops and draws all the holes.
difference() { // Draw the board // Rotate so edge does not align with axes rotate(a=23.5) { minkowski() { cylinder(r=1); cylinder(h=oct_hgt, d=cyl_dia-1, $fn=8); } } // Center holes for (j = [-1:1:1]) { for (i = [-3:1:3]) { translate([i*dis_hol, j*dis_hol, oct_hgt - hgt_hol]) cylinder(d=dia_hol, h=hgt_hol+1); } } // Top Holes for (j = [-1:1:0]) { for (i = [-1:1:1]) { translate([i*dis_hol, (dis_hol*3)+j*dis_hol, oct_hgt - hgt_hol]) cylinder(d=dia_hol, h=hgt_hol+1); } } // Bottom Holes for (j = [-1:1:0]) { for (i = [-1:1:1]) { translate([i*dis_hol, -((dis_hol*3)+j*dis_hol), oct_hgt - hgt_hol]) cylinder(d=dia_hol, h=hgt_hol+1); } } }

The first loop above draws all the holes along the X-axis. The next two loops draws the holes over and below this already drawn holes to complete the puzzle.
Creating the lid
We can be fancy about the lid for this. However, I chose to just create a simple lid which should be usable. It is about 0.5 mm wider than the game board, so would be able to wrap it. There is not much to explain for the code below.
$fn = 50; oct_hgt = 12; dia_hol = 5; dis_hol = 8; hgt_hol = 6; cyl_dia = 5 * dis_hol + 6 * dia_hol; // Lid difference() { minkowski() { cylinder(r=1); cylinder(h=oct_hgt, d=cyl_dia+1, $fn=8); } cylinder(h=oct_hgt-1, d=cyl_dia+0.5, $fn=8); }
Conclusion
I have printed this object, and everything worked out fine. Now I can go back to playing peg solitaire. I will put the code in GitHub. Ciao for now!