]> git.sommitrealweird.co.uk Git - curses-crossword.git/blob - curses-crossword.py
5554f3036fd7b68b7b6e101fd3f27ab968965028
[curses-crossword.git] / curses-crossword.py
1 #!/usr/bin/python
2
3 import curses
4 import locale
5 import codecs
6
7 locale.setlocale(locale.LC_ALL, '')
8 code = locale.getpreferredencoding()
9
10 superscript_numbers = {}
11
12 try:
13     superscript_numbers = {
14         "0": unichr(8304).encode(code),
15         "1": unichr(185).encode(code),
16         "2": unichr(178).encode(code),
17         "3": unichr(179).encode(code),
18         "4": unichr(8308).encode(code),
19         "5": unichr(8309).encode(code),
20         "6": unichr(8310).encode(code),
21         "7": unichr(8311).encode(code),
22         "8": unichr(8312).encode(code),
23         "9": unichr(8313).encode(code),
24     }
25 except:
26     for number in range(0,10):
27         superscript_numbers[str(number)] = str(number)
28
29 crossworddata = codecs.open("g2-20090701.txt", "r", "utf-8").read()
30
31 def parsecrossword(crossworddata):
32     ingrid = False
33     inacross = False
34     indown = False
35     crossword = {"grid": [], "across": {}, "down": {}, "grid_questions_start": [], "grid_questions_end": []}
36
37     for line in crossworddata.split("\n"):
38         line = line.strip("\n")
39         if line == "GRID":
40             ingrid = True
41             inacross = False
42             indown = False
43         elif line == "ACROSS":
44             ingrid = False
45             inacross = True
46             indown = False
47         elif line == "DOWN":
48             ingrid = False
49             inacross = False
50             indown = True
51         else:
52             if ingrid:
53                 if line != "":
54                     crossword["grid"].append(line)
55             if inacross:
56                 if line != "":
57                     parts = line.split()
58                     question_number = int(parts[0])
59                     clue = " ".join(parts[1:])
60                     crossword["across"][int(question_number)] = clue
61             if indown:
62                 if line != "":
63                     parts = line.split()
64                     question_number = int(parts[0])
65                     clue = " ".join(parts[1:])
66                     crossword["down"][int(question_number)] = clue
67     num_cols = len(crossword["grid"][0])
68     num_rows = len(crossword["grid"])
69
70     current_clue_number = 1
71
72     for row in range(0,num_rows):
73         crossword["grid_questions_start"].append([])
74
75     for row in range(0,num_rows):
76         for col in range(0,num_cols):
77             have_clue = False
78             if col > 0 \
79                 and crossword["grid"][row][col - 1] == "x" \
80                 and crossword["grid"][row][col] != "x" \
81                 and col < (num_cols - 1) \
82                 and crossword["grid"][row][col + 1] != "x":
83                 have_clue = True
84             if col == 0 and crossword["grid"][row][col] != "x" \
85                 and crossword["grid"][row][col + 1] != "x":
86                 have_clue = True
87             if row > 0 and crossword["grid"][row-1][col] == "x" \
88                 and row < (num_rows - 1) \
89                 and crossword["grid"][row][col] != "x" \
90                 and crossword["grid"][row + 1][col] != "x":
91                 have_clue = True
92             if row == 0 and crossword["grid"][row][col] != "x" \
93                 and crossword["grid"][row + 1][col] != "x":
94                 have_clue = True
95             if have_clue:
96                 crossword["grid_questions_start"][row].append(current_clue_number)
97                 current_clue_number += 1
98             else:
99                 crossword["grid_questions_start"][row].append(0)
100
101     return crossword
102
103 def crossword(stdscr, crossworddata):
104     crossword = parsecrossword(crossworddata)
105     cury = 0
106     grid_length = len(crossword["grid"][0])
107     curx = 0
108     stdscr.addch(cury, curx, curses.ACS_ULCORNER)
109     curx += 1
110     while ((curx - 1) / 4) < grid_length:
111         stdscr.addch(cury, curx, curses.ACS_HLINE)
112         stdscr.addch(cury, curx+1, curses.ACS_HLINE)
113         stdscr.addch(cury, curx+2, curses.ACS_HLINE)
114         stdscr.addch(cury, curx+3, curses.ACS_TTEE)
115         curx += 4
116     curx -= 1
117     stdscr.addch(cury, curx, curses.ACS_URCORNER)
118     cury += 1
119     curgridy=0
120     for line in crossword["grid"]:
121         datastr = ""
122         curx = 0
123         curgridx=0
124         for c in line:
125             stdscr.addch(cury, curx, curses.ACS_VLINE)
126             if curx > 0:
127                 stdscr.addch(cury+1, curx, curses.ACS_PLUS)
128             else:
129                 stdscr.addch(cury+1, curx, curses.ACS_LTEE)
130             stdscr.addch(cury+1, curx + 1, curses.ACS_HLINE)
131             stdscr.addch(cury+1, curx + 2, curses.ACS_HLINE)
132             stdscr.addch(cury+1, curx + 3, curses.ACS_HLINE)
133             curx += 1
134             if c == "x":
135                 stdscr.addch(cury, curx, curses.ACS_BLOCK)
136                 stdscr.addch(cury, curx+1, curses.ACS_BLOCK)
137                 stdscr.addch(cury, curx+2, curses.ACS_BLOCK)
138             elif crossword["grid_questions_start"][curgridy][curgridx] > 0:
139                 stdscr.addstr(cury, curx, ''.join([superscript_numbers[x].decode(code) for x in str(crossword["grid_questions_start"][curgridy][curgridx])]).encode(code))
140             curx += 3
141             curgridx += 1
142         else:
143             stdscr.addch(cury, curx, curses.ACS_VLINE)
144             stdscr.addch(cury + 1, curx, curses.ACS_RTEE)
145         cury += 2
146         curgridy += 1
147     cury -= 1
148     curx = 0
149     stdscr.addch(cury, curx, curses.ACS_LLCORNER)
150     curx += 1
151     while ((curx - 1) / 4) < grid_length:
152         stdscr.addch(cury, curx, curses.ACS_HLINE)
153         stdscr.addch(cury, curx+1, curses.ACS_HLINE)
154         stdscr.addch(cury, curx+2, curses.ACS_HLINE)
155         stdscr.addch(cury, curx+3, curses.ACS_BTEE)
156         curx += 4
157     curx -= 1
158     stdscr.addch(cury, curx, curses.ACS_LRCORNER)
159     while 1:
160         c = stdscr.getch()
161         if c == ord('q'):
162             break
163
164 curses.wrapper(crossword, crossworddata)
165 print parsecrossword(crossworddata)