]>
git.siccegge.de Git - ghextris.git/blob - ghextris.py
f60c4c83179d76a4ffffeb187f8517d2ac44fe40
3 # Gnome-hextris; a free rewrite of the xhextris game in Python for Gnome
4 # Copyright 2004 Mikko Rauhala <mjr@iki.fi>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # This will be overwritten for the installed version:
47 # self.piecewidth = 20
48 # self.piecenarrow = 20
50 self
.cols
= 13 # Must be odd or weirdness ensues
52 self
.width
= (((self
.cols
/2)+2)*self
.piecewidth
+
53 ((self
.cols
/2)+1) * self
.piecenarrow
) + 2
54 self
.height
= (self
.rows
+1) * self
.pieceheight
+ 2
56 self
.colors
= ("blue", "yellow", "red", "orange", "green", "purple",
57 "cyan", "gray45", "magenta", "lightblue")
58 self
.deltax
= (-1, -1, -1, 0, 0, 0, 0, 0, -1, -1)
59 self
.deltay
= (-1, -1, -1, 0, 0, 0, 0, 0, -1, -1)
61 (((0,), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)),
62 ((0,), (0, 0, 0, 1), (0, 1, 1), (1,)),
63 ((0,), (1, 1), (0, 0, 1, 1)),
64 ((0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)),
65 ((0,), (0, 0, 0, 1, 1), (0, 1, 1)),
66 ((0,), (0, 1), (0, 0, 1, 1), (0, 0, 0, 0, 1))),
67 (((0,), (0, 0, 1), (0, 0, 1, 1), (0, 0, 0, 1)),
68 ((0,), (0, 0, 0, 1), (0, 0, 1), (0, 1, 1)),
69 ((0,), (0,), (1, 1, 1, 1)),
70 ((0, 1), (0, 1), (0, 0, 1), (0, 0, 1)),
71 ((0, 0, 0, 1), (0, 0, 1), (0, 1, 1)),
72 ((0,), (0, 1, 0, 1), (0, 0, 1, 0, 1))),
73 (((0,), (0, 0, 1), (0, 1, 1), (0, 1)),
74 ((0,), (0, 1, 0, 1), (1, 0, 1, 0)),
75 ((0, 1), (0, 0, 1), (0, 0, 1, 1)),
76 ((0, 0, 0, 1), (0, 0, 0, 1), (0, 0, 1), (0, 0, 1)),
77 ((0,), (0,), (0, 1, 1, 1, 1)),
78 ((0,), (0, 1), (0, 0, 1), (0, 0, 1, 1))),
79 (((0, 1, 0), (0, 1, 0), (1, 0, 1)),
80 ((0,), (1, 1, 1), (0, 1, 0))),
81 (((0, 1), (1,), (1, 1)),
82 ((0, 1), (1, 0, 1), (1,)),
83 ((0, 1), (1, 0, 1), (0, 0, 1)),
84 ((0, 1), (0, 0, 1), (0, 1, 1)),
85 ((0,), (0, 0, 1), (1, 1, 1)),
86 ((0,), (1,), (1, 1, 1))),
87 (((0,), (0, 1), (1, 1, 1)),
88 ((0,), (1, 1), (1, 1, 0)),
89 ((0, 1), (1, 1), (1,)),
91 ((0, 1), (0, 1, 1), (0, 0, 1)),
92 ((0,), (0, 1, 1), (0, 1, 1))),
93 (((0, 1), (0, 1), (0, 1, 1)),
94 ((0,), (0, 1, 1), (1, 1)),
95 ((0,), (1, 1), (1, 0, 1)),
96 ((0, 1), (1, 1), (0, 1)),
97 ((0, 1), (0, 1, 1), (1,)),
98 ((0,), (1, 1, 1), (0, 0, 1))),
99 (((0, 1), (0, 1), (1, 1)),
100 ((0,), (1, 1, 1), (1,)),
101 ((0, 1), (1, 1), (0, 0, 1)),
102 ((0, 1), (0, 1, 1), (0, 1)),
103 ((0,), (0, 1, 1), (1, 0, 1)),
104 ((0,), (1, 1), (0, 1, 1))),
105 (((0,), (0, 0, 1), (0, 0, 1), (0, 0, 1, 1)),
106 ((0,), (0, 0, 0, 1), (0, 1, 1), (0, 1)),
107 ((0,), (0, 1), (1, 0, 1, 1)),
108 ((0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)),
109 ((0, 0, 0, 1), (0, 0, 0, 1), (0, 1, 1)),
110 ((0,), (0, 1), (0, 0, 1, 1, 1))),
111 (((0,), (0, 0, 1), (0, 0, 1), (0, 1, 1)),
112 ((0,), (0, 0, 0, 1), (1, 1, 1)),
113 ((0, 1), (0, 1), (0, 0, 1, 1)),
114 ((0, 0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)),
115 ((0,), (0, 0, 0, 1), (0, 1, 1, 0, 1)),
116 ((0,), (0, 1), (0, 0, 1, 1), (0, 0, 0, 1)))
120 self
.speed_orig
= 400
122 self
.speed_ratio
= 0.99
123 self
.speed_reset
= False
132 self
.nextpiece
= False
136 def draw_hexagon(self
, group
, color
):
138 pts
.append ((self
.piecewidth
- self
.piecenarrow
)/2)
140 pts
.append (self
.piecewidth
- pts
[0])
142 pts
.append (self
.piecewidth
)
143 pts
.append (self
.pieceheight
/2)
145 pts
.append (self
.pieceheight
)
152 item
= group
.add ("GnomeCanvasPolygon", points
= pts
, fill_color
= color
,
153 outline_color
= "black", width_units
= 1)
156 def draw_piece(self
, group
, matrix
, color
):
157 for i
in range(len(matrix
)):
158 for j
in range(len(matrix
[i
])):
159 if matrix
[i
][j
] != 0:
160 g
= group
.add("GnomeCanvasGroup",
161 x
= (j
*(self
.piecewidth
+self
.piecenarrow
)/2),
162 y
= ((i
* (self
.pieceheight
)) +
163 ((j
%2) * self
.pieceheight
/2)))
164 self
.draw_hexagon(g
, color
)
166 def place_piece(self
, group
, matrix
, color
, x
, y
):
167 piecegroup
= group
.add("GnomeCanvasGroup",
168 x
= (x
+1)*((self
.piecewidth
+self
.piecenarrow
)/2),
169 y
= ((y
* self
.pieceheight
) -
170 (((x
%2)+1) * self
.pieceheight
/2)))
171 self
.draw_piece(piecegroup
, matrix
, color
)
174 def init_board(self
):
175 board
= self
.canvas
.root()
176 for i
in range(self
.rows
+1):
178 boardhex
= board
.add("GnomeCanvasGroup",
179 x
= j
* (self
.piecewidth
*(self
.cols
/2+1) +
180 self
.piecenarrow
*(self
.cols
/2+1)),
181 y
= i
* self
.pieceheight
)
182 self
.draw_hexagon(boardhex
, "gray")
183 for i
in range(self
.cols
/2):
184 boardhex
= board
.add("GnomeCanvasGroup",
185 x
= (i
+1) * (self
.piecewidth
+
187 y
= self
.rows
* self
.pieceheight
)
188 self
.draw_hexagon(boardhex
, "gray")
189 for i
in range(self
.cols
/2+1):
190 boardhex
= board
.add("GnomeCanvasGroup",
191 x
= (i
* (self
.piecewidth
+ self
.piecenarrow
)+
192 (self
.piecewidth
+ self
.piecenarrow
)/2),
193 y
= ((self
.rows
*2-1) * self
.pieceheight
)/2)
194 self
.draw_hexagon(boardhex
, "gray")
196 def on_new_activate(self
, event
):
197 self
.speed
= self
.speed_orig
205 if self
.board
!= False:
207 self
.board
= self
.canvas
.root().add("GnomeCanvasGroup", x
= 0, y
= 0)
210 for i
in range(self
.rows
):
211 self
.field
.append([])
212 for j
in range(self
.cols
):
213 self
.field
[i
].append(0)
216 for i
in range(self
.rows
):
217 self
.rowgroups
.append(self
.board
.add("GnomeCanvasGroup", x
= 0,
218 y
= i
* self
.pieceheight
))
220 self
.nextnum
= random
.randint(0, 9)
223 if self
.running
== False:
224 gobject
.timeout_add(self
.speed
, self
.timer_handler
)
227 self
.speed_reset
= True
231 def on_about_activate(self
, event
):
232 aTree
= gtk
.glade
.XML(self
.glade
, "about")
233 about
= aTree
.get_widget("about")
234 about
.set_property("name", "Ghextris")
235 about
.set_property("version", VERSION
)
238 def on_pause_game_activate(self
, event
):
239 if self
.lost
== True:
241 if self
.paused
== True:
247 def on_quit_activate(self
, event
):
251 gnome
.init("Ghextris", VERSION
)
252 gettext
.install("ghextris")
253 self
.glade
= os
.path
.join(SHAREDIR
, "ghextris.glade")
255 wTree
= gtk
.glade
.XML(self
.glade
, "GhextrisApp")
256 dic
= {"on_new_activate": self
.on_new_activate
,
257 "on_pause_game_activate": self
.on_pause_game_activate
,
258 "on_quit_activate": self
.on_quit_activate
,
259 "on_about_activate": self
.on_about_activate
}
260 wTree
.signal_autoconnect(dic
)
262 win
= wTree
.get_widget("GhextrisApp")
263 self
.canvas
= wTree
.get_widget("canvas")
264 preview
= wTree
.get_widget("previewcanvas")
265 appbar
= wTree
.get_widget("appbar").get_children()[0]
266 self
.appbar
= appbar
.get_children()[0]
268 win
.connect('destroy', self
.on_quit_activate
)
270 self
.canvas
.set_size_request(self
.width
, self
.height
)
271 self
.canvas
.set_scroll_region(0, 0, self
.width
, self
.height
)
274 preview
.set_size_request(self
.piecewidth
* 4, self
.pieceheight
* 5)
276 self
.preview
= preview
.root()
278 win
.connect("key-press-event", self
.key_handler
)
287 def next_piece(self
):
288 self
.piecenum
= self
.nextnum
289 self
.nextnum
= random
.randint(0, 9)
291 self
.piece_x
= (self
.cols
/2)-1 + self
.deltax
[self
.piecenum
]
292 self
.piece_y
= -3 + self
.deltax
[self
.piecenum
]
293 self
.piece
= self
.place_piece(self
.board
, self
.pieces
[self
.piecenum
][0],
294 self
.colors
[self
.piecenum
%(len(self
.colors
)+1)],
295 self
.piece_x
, self
.piece_y
)
297 if self
.nextpiece
!= False:
298 self
.nextpiece
.destroy()
299 self
.nextpiece
= self
.place_piece(self
.preview
,
300 self
.pieces
[self
.nextnum
][0],
301 self
.colors
[self
.nextnum
%(len(self
.colors
)+1)],
302 self
.deltax
[self
.nextnum
],
303 self
.deltay
[self
.nextnum
])
305 def timer_handler(self
):
306 if self
.lost
== True:
310 if self
.paused
== True:
314 if self
.check_collisions() == True:
317 if self
.top_occupied() != True:
321 if self
.hiscore
< self
.score
:
322 self
.hiscore
= self
.score
327 self
.piece
.move(0, self
.pieceheight
)
329 if self
.speed_reset
== True:
330 self
.speed_reset
= False
331 gobject
.timeout_add(int(self
.speed
), self
.timer_handler
)
336 def update_appbar(self
):
337 self
.appbar
.set_text("%s: %d | %s: %d" % (_("Score"), self
.score
,
341 def key_handler(self
, widget
, event
=None):
342 if self
.lost
== True:
345 if event
.keyval
== gtk
.keysyms
.p
and self
.lost
== False:
346 if self
.paused
== True:
352 if self
.paused
== True:
355 if event
.keyval
== gtk
.keysyms
.Up
or event
.keyval
== gtk
.keysyms
.Down
:
356 if event
.keyval
== gtk
.keysyms
.Up
:
360 old_attitude
= self
.attitude
361 self
.attitude
= ((self
.attitude
+ attitude_change
+
362 len(self
.pieces
[self
.piecenum
])) %
363 len(self
.pieces
[self
.piecenum
]))
364 if self
.check_collisions() == True:
365 self
.attitude
= old_attitude
369 self
.piece
= self
.place_piece(self
.board
,
370 self
.pieces
[self
.piecenum
][self
.attitude
],
371 self
.colors
[self
.piecenum
%(len(self
.colors
)+1)],
372 self
.piece_x
, self
.piece_y
);
375 if event
.keyval
== gtk
.keysyms
.Left
or event
.keyval
== gtk
.keysyms
.Right
:
376 if event
.keyval
== gtk
.keysyms
.Left
:
380 self
.piece_x
+= deltax
383 if self
.piece_x
%2 == 0:
384 deltay
+= self
.pieceheight
/2
386 deltay
-= self
.pieceheight
/2
388 if self
.check_collisions() == True:
390 self
.piece_x
-= deltax
393 deltay
+= self
.pieceheight
394 if self
.check_collisions() == True:
395 self
.piece_x
-= deltax
399 self
.piece
.move(deltax
*(self
.piecewidth
+self
.piecenarrow
)/2, deltay
)
402 if event
.keyval
== gtk
.keysyms
.space
:
403 orig_piece_y
= self
.piece_y
404 while self
.check_collisions() == False:
407 self
.piece
.move(0, self
.pieceheight
*(self
.piece_y
- orig_piece_y
))
408 self
.score
+= self
.piece_y
- orig_piece_y
409 if self
.score
> self
.hiscore
:
410 self
.hiscore
= self
.score
412 if self
.top_occupied() != True:
416 if self
.hiscore
< self
.score
:
417 self
.hiscore
= self
.score
424 def check_collisions(self
):
425 for i
in range(len(self
.pieces
[self
.piecenum
][self
.attitude
])):
426 for j
in range(len(self
.pieces
[self
.piecenum
][self
.attitude
][i
])):
427 if self
.pieces
[self
.piecenum
][self
.attitude
][i
][j
] != 0:
428 if j
%2 == 0 and self
.piece_x
%2 == 1:
432 if j
+ self
.piece_x
< 0 or j
+ self
.piece_x
>= self
.cols
:
434 if ((i
+ self
.piece_y
+ deltay
> 0) and
435 (i
+ self
.piece_y
+ deltay
>= self
.rows
or
436 self
.field
[i
+ self
.piece_y
+ deltay
][j
+ self
.piece_x
] != 0)):
440 def update_field(self
):
441 for i
in range(len(self
.pieces
[self
.piecenum
][self
.attitude
])):
442 for j
in range(len(self
.pieces
[self
.piecenum
][self
.attitude
][i
])):
443 if self
.pieces
[self
.piecenum
][self
.attitude
][i
][j
] != 0:
444 if j
%2 == 0 and self
.piece_x
%2 == 1:
448 if i
+self
.piece_y
+deltay
>= 0:
449 self
.field
[i
+ self
.piece_y
+ deltay
][j
+ self
.piece_x
] = 1
450 self
.place_piece(self
.rowgroups
[i
+self
.piece_y
+deltay
],
452 self
.colors
[self
.piecenum
%(len(self
.colors
)+1)],
453 j
+ self
.piece_x
- 1, 0)
457 def collapse_rows(self
):
459 for i
in range(self
.rows
):
461 for j
in range(self
.cols
):
462 if self
.field
[i
][j
] == 0:
468 self
.speed
*= self
.speed_ratio
469 self
.speed_reset
= True
470 self
.rowgroups
[i
].destroy()
471 for j
in range(i
-1, -1, -1):
472 self
.rowgroups
[j
].move(0, self
.pieceheight
)
473 self
.rowgroups
[j
+1] = self
.rowgroups
[j
]
474 self
.field
[j
+1] = self
.field
[j
]
476 for j
in range(self
.cols
):
477 self
.field
[0].append(0)
478 self
.rowgroups
[0] = self
.board
.add("GnomeCanvasGroup", x
= 0,
481 self
.score
+= row_points
482 if self
.score
> self
.hiscore
:
483 self
.hiscore
= self
.score
486 def top_occupied(self
):
487 for i
in range(self
.cols
):
488 if self
.field
[0][i
] != 0:
492 if __name__
== '__main__':