Program Solution

Backgammon

Although we typically hesitate to offer any particular implementation as a "solution", we thought it might be informative to see how control structures can be used to avoid any semblence of repetition of code for this project.

from cs1graphics import *

###############################################
# utility function to covert point 1 and 24 to x=1, points 2 and 23 to x=2,
# and so on, including the middle bar offset for right-hand side of board
###############################################
def computeX(pointNum):
    x = 12.5 - abs(12.5 - pointNum)   # so 1->1, 2->2, but also 24->1, 23->2, ...
    if x >= 6.5:
        x += 1     # everything on rightside moves over by one due to middle bar
    return x

###############################################
# create initial canvas based on user input
###############################################

size = int(raw_input('How many pixels per "grid" cell? '))
board = Canvas(15 * size, 13 * size, 'burlywood4', 'Backgammon')
midY = board.getHeight() / 2

###############################################
# add the felt and dividing line
###############################################

for x in (4, 11):    # two rectangles, one centered with x=4 and one with x=11
    felt = Rectangle(6 * size, 11 * size)
    felt.setFillColor('navajowhite')
    felt.move(x * size, midY)
    felt.setDepth(60)
    board.add(felt)

line = Path(Point(7.5 * size, 0), Point(7.5 * size, 13 * size))
line.setBorderWidth(2)
board.add(line)

###############################################
# add the numbers and triangles
###############################################

for pt in range(1, 25):
    if pt >= 13:
        dy = -1    # orient upward from y=6.5 center (i.e. top of board)
    else:
        dy = +1    # orient downward from y=6.5 center (i.e. bototm of board)

    x = computeX(pt)

    t = Text(str(pt))
    t.setFontSize(int(round(size / 3.0)))    # scale font based on grid
    t.move(size * (x + 0.5), size * (6.5 + 6 * dy))
    board.add(t)

    point = Polygon(Point(size * (x+0.5), size * (6.5 + dy*0.5)),
                    Point(size * x,       size * (6.5 + dy*5.5)),
                    Point(size * (x + 1), size * (6.5 + dy*5.5)))
    if (pt % 2 == 1):
        point.setFillColor('darkorange3')
    else:
        point.setFillColor('tan')
    board.add(point)

###############################################
# add the checkers
###############################################

checkScale = 0.9
for num,point,onTop in ((2,1,True), (5,6,False), (3,8,False), (5,12,True)):
    x = size * (computeX(point) + 0.5)

    for dy in (-1, +1):       # top then bottom
        baseY = size * (6.5 + dy * 5.5)
        for c in range(num):
            checker = Circle(checkScale * size / 2)
            checker.move(x, baseY - dy * size * checkScale * (0.5+c))
            checker.setDepth(40)
            if ((dy == -1) == onTop):
                checker.setFillColor('white')
            else:
                checker.setFillColor('black')
            board.add(checker)

Last modified: Tuesday, 21 February 2017