1 from reportlab.pdfgen import canvas
2 from reportlab.lib.units import inch
3 from reportlab.lib.pagesizes import letter
4
5 import boardRep
6 import mtdf
7
8 boardSize=0.8 * inch
9 boardSlotWidth=2*boardSize
10 boardLeftMargin=0.15*inch
11 boardBottomMargin=0.05*inch
12 boardRightMargin=boardLeftMargin+boardSize-2*boardBottomMargin
13 squareSize=(boardSize-2*boardBottomMargin)/3
14 pieceSize=squareSize*0.6
15 pieceMargin=(squareSize-pieceSize)/2
16
17 boardsAcross=4
18 boardsDown=12
19 boardsOnAPage=boardsAcross*boardsDown
20
21 contentWidth=boardSlotWidth*boardsAcross
22 contentDepth=boardSize*boardsDown
23 pageWidth,pageHeight=letter
24 leftMargin=(pageWidth-contentWidth)/2
25 bottomMargin=(pageHeight-contentDepth)/2
26
27 boardIndexList=[]
28
29 -def drawBoard(c, xIndex, yIndex, hashVal, boardIndex):
30 left=xIndex*boardSlotWidth+leftMargin
31 bottom=pageHeight-((yIndex+1)*boardSize+bottomMargin)
32 c.saveState()
33 c.translate(left,bottom)
34
35 c.saveState()
36 FONTSIZE=8
37 c.setFont("Helvetica",FONTSIZE)
38 labelColor=(1.0,1.0,1.0)
39 labelBackground=(0.5, 0.5, 0.5)
40
41 c.setFillColor(labelBackground)
42 c.rect(0,boardBottomMargin,boardLeftMargin,boardSize-2*boardBottomMargin,stroke=0,fill=1)
43 c.rotate(90)
44
45 label=str(boardIndex)
46 w=c.stringWidth(label, "Helvetica", FONTSIZE)
47
48 c.setStrokeColor(labelColor)
49 c.setFillColor(labelColor)
50 c.drawString((boardSize-w)/2,-(boardLeftMargin+FONTSIZE)/2,label)
51 c.restoreState()
52
53
54 c.line(boardLeftMargin,boardBottomMargin+squareSize,boardRightMargin,boardBottomMargin+squareSize)
55 c.line(boardLeftMargin,boardBottomMargin+2*squareSize,boardRightMargin,boardBottomMargin+2*squareSize)
56 c.line(boardLeftMargin+squareSize,boardBottomMargin,boardLeftMargin+squareSize,boardSize-boardBottomMargin)
57 c.line(boardLeftMargin+2*squareSize,boardBottomMargin,boardLeftMargin+2*squareSize,boardSize-boardBottomMargin)
58
59 b=boardRep.TicTacToeBoard(hashVal)
60
61 for x in range(3):
62 for y in range(3):
63 si=3*y+x
64 sv=b.squares[si]
65 c.saveState()
66 c.translate(boardLeftMargin+pieceMargin+x*squareSize,
67 boardBottomMargin+pieceMargin+y*squareSize)
68
69 if sv==1:
70 c.line(0,0,
71 pieceSize,pieceSize)
72 c.line(0,pieceSize,
73 pieceSize,0)
74 elif sv==2:
75 c.ellipse(0,0,
76 pieceSize,pieceSize)
77 c.restoreState()
78
79 v=mtdf.mtdf(hashVal,0,12)
80 valueStr={-1000:"O Wins",
81 0:"Draw",
82 1000:"X Wins"}[v]
83
84 sm=b.successorMap()
85 bestMoves=mtdf.getBestMoves(hashVal,12,v)
86 bestMoveList=list(bestMoves)
87
88 destList=[]
89 if sm:
90 destSet=set()
91 for m in bestMoves:
92 destSet.add(1+boardIndexList.index(sm[m]))
93 destList=list(destSet)
94 destList.sort()
95
96 for m in bestMoves:
97 x=m%3
98 y=(m-x)/3
99 c.saveState()
100 c.setFont("Helvetica",pieceSize)
101 c.translate(boardLeftMargin+pieceMargin+x*squareSize,
102 boardBottomMargin+pieceMargin+y*squareSize)
103 c.drawCentredString(pieceSize/2.0,0,str(1+destList.index(1+boardIndexList.index(sm[m]))))
104 c.restoreState()
105
106 CAPTIONSIZE=5.6
107 c.setFont("Helvetica",CAPTIONSIZE)
108
109 if b.isOver():
110 wtString="Game Over"
111 else:
112 wt=b.whoseTurn()
113 wtString={1:"X to move",
114 2:"O to move"}[wt]
115
116 c.drawString(boardRightMargin,boardSize-boardBottomMargin-CAPTIONSIZE,wtString)
117 c.drawString(boardRightMargin,boardSize-boardBottomMargin-2*CAPTIONSIZE,valueStr)
118
119 moveStr=""
120 for destIndex in range(len(destList)):
121 c.drawString(boardRightMargin,
122 boardSize-boardBottomMargin-(3+destIndex)*CAPTIONSIZE,
123 "%d : %d"%(destIndex+1,destList[destIndex]))
124
125
126
127
128 c.restoreState()
129
130
131 if __name__=="__main__":
132 c = canvas.Canvas("tictactoe.pdf", pagesize=letter)
133 c.setAuthor("Dave LeCompte")
134 c.setTitle("How to Play Perfect Tic Tac Toe")
135
136 f=file("boardDescs.txt")
137 fLines=f.readlines()
138 f.close()
139
140
141 for boardIndex in range(len(fLines)):
142 splitLine=fLines[boardIndex].split(',')
143 boardHash=int(splitLine[0])
144 boardIndexList.append(boardHash)
145
146 pageCount=1
147 for boardIndex in range(len(boardIndexList)):
148 boardHash=boardIndexList[boardIndex]
149
150 pageIndex=boardIndex%boardsOnAPage
151 x=pageIndex%boardsAcross
152 y=(pageIndex-x)/boardsAcross
153
154 drawBoard(c, x, y, boardHash, boardIndex+1)
155
156 if (boardIndex+1)%boardsOnAPage==0:
157 c.drawCentredString(pageWidth/2,inch/2,"Page: %d"%pageCount)
158 pageCount += 1
159 c.showPage()
160
161 c.drawCentredString(pageWidth/2,inch/2,"Page: %d"%pageCount)
162 c.showPage()
163 c.save()
164