Changeset 9465 for branches/session_centric/src/tictactoe.py
- Timestamp:
- 04/15/08 07:32:45 (7 months ago)
- Files:
-
- 1 modified
-
branches/session_centric/src/tictactoe.py (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/session_centric/src/tictactoe.py
r9459 r9465 10 10 # implements <http://pidgin-games.sourceforge.net/xep/tictactoe.html#invite> 11 11 12 games_ns = 'http://jabber.org/protocol/games' 13 12 14 class InvalidMove(Exception): 13 15 pass … … 25 27 self.role_o = 'x' 26 28 29 self.send_invitation() 30 31 self.next_move_id = 1 32 self.received = self.wait_for_invite_response 33 34 def send_invitation(self): 27 35 msg = xmpp.Message() 28 36 29 37 invite = msg.NT.invite 30 invite.setNamespace( 'http://jabber.org/protocol/games')38 invite.setNamespace(games_ns) 31 39 32 40 game = invite.NT.game 33 game.setAttr('var', 'http://jabber.org/protocol/games/tictactoe')41 game.setAttr('var', games_ns + '/tictactoe') 34 42 35 43 x = xmpp.DataForm(typ='submit') … … 39 47 self.send(msg) 40 48 41 self.next_move_id = 1 42 self.state = 'sent_invite' 49 def read_invitation(self, msg): 50 invite = msg.getTag('invite', namespace=games_ns) 51 game = invite.getTag('game') 52 x = game.getTag('x', namespace='jabber:x:data') 53 54 form = xmpp.DataForm(node=x) 55 56 if form.getField('role'): 57 self.role_o = form.getField('role').getValues()[0] 58 else: 59 self.role_o = 'x' 60 61 if form.getField('rows'): 62 self.rows = int(form.getField('rows').getValues()[0]) 63 else: 64 self.rows = 3 65 66 if form.getField('cols'): 67 self.cols = int(form.getField('cols').getValues()[0]) 68 else: 69 self.cols = 3 70 71 if form.getField('strike'): 72 self.strike = int(form.getField('strike').getValues()[0]) 73 else: 74 self.strike = 3 43 75 44 76 # received an invitation 45 77 def invited(self, msg): 46 invite = msg.getTag('invite', namespace='http://jabber.org/protocol/games') 47 game = invite.getTag('game') 48 x = game.getTag('x', namespace='jabber:x:data') 49 50 form = xmpp.DataForm(node=x) 51 52 if form.getField('role'): 53 self.role_o = form.getField('role').getValues()[0] 54 55 if form.getField('rows'): 56 self.rows = int(form.getField('rows').getValues()[0]) 57 58 if form.getField('cols'): 59 self.cols = int(form.getField('cols').getValues()[0]) 60 61 # XXX 'strike' 62 63 if not hasattr(self, 'rows'): 64 self.rows = 3 65 66 if not hasattr(self, 'cols'): 67 self.cols = 3 78 self.read_invitation(msg) 79 80 # XXX prompt user 81 # "accept, reject, ignore" 68 82 69 83 # the number of the move about to be made 70 84 self.next_move_id = 1 71 85 86 # display the board 72 87 self.board = TicTacToeBoard(self, self.rows, self.cols) 73 88 … … 76 91 77 92 join = response.NT.join 78 join.setNamespace( 'http://jabber.org/protocol/games')93 join.setNamespace(games_ns) 79 94 80 95 self.send(response) 81 96 82 if not hasattr(self, 'role_o') orself.role_o == 'x':97 if self.role_o == 'x': 83 98 self.role_s = 'o' 84 self.role_o = 'x'85 99 86 100 self.their_turn() … … 92 106 93 107 def is_my_turn(self): 94 return self.state == 'get_input' 95 96 def received(self, msg): 97 # just sent an invitation, expecting a reply 98 if self.state == 'sent_invite': 99 if msg.getTag('join', namespace='http://jabber.org/protocol/games'): 100 self.board = TicTacToeBoard(self, self.rows, self.cols) 101 102 if self.role_s == 'x': 103 self.our_turn() 104 else: 105 self.their_turn() 106 107 return 108 109 # ignore messages unless we're expecting a move 110 if self.state != 'waiting': 111 return 112 113 turn = msg.getTag('turn', namespace='http://jabber.org/protocol/games') 114 108 # XXX not great semantics 109 return self.received == self.ignore 110 111 # just sent an invitation, expecting a reply 112 def wait_for_invite_response(self, msg): 113 if msg.getTag('join', namespace=games_ns): 114 self.board = TicTacToeBoard(self, self.rows, self.cols) 115 116 if self.role_s == 'x': 117 self.our_turn() 118 else: 119 self.their_turn() 120 121 elif msg.getTag('decline', namespace=games_ns): 122 self.XXX() 123 124 # silently ignores any received messages 125 def ignore(self, msg): 126 pass 127 128 def wait_for_move(self, msg): 129 turn = msg.getTag('turn', namespace=games_ns) 115 130 move = turn.getTag('move', namespace='http://jabber.org/protocol/games/tictactoe') 116 131 … … 129 144 return 130 145 131 # XXX check win conditions 132 133 self.next_move_id += 1 134 135 self.our_turn() 146 # check win conditions 147 if self.board.check_for_strike(self.role_o, row, col, self.strike): 148 self.lost() 149 elif self.board.full(): 150 self.drawn() 151 else: 152 self.next_move_id += 1 153 154 self.our_turn() 136 155 137 156 def our_turn(self): 138 self.state = 'get_input' 157 # ignore messages until we've made our move 158 self.received = self.ignore 139 159 self.board.win.set_title(self.board.title + ': your turn') 140 160 141 161 def their_turn(self): 142 self. state = 'waiting'162 self.received = self.wait_for_move 143 163 self.board.win.set_title(self.board.title + ': their turn') 144 164 145 165 # called when the board receives input 146 def move(self, row, col umn):166 def move(self, row, col): 147 167 try: 148 self.board.mark(row, col umn, self.role_s)168 self.board.mark(row, col, self.role_s) 149 169 except InvalidMove, e: 150 print ' invalid move'170 print 'you made an invalid move' 151 171 return 152 172 153 self.send_move(row, column) 154 155 # XXX check win conditions 173 self.send_move(row, col) 174 175 # check win conditions 176 if self.board.check_for_strike(self.role_s, row, col,self.strike): 177 self.won() 178 elif self.board.full(): 179 self.drawn() 180 else: 181 self.next_move_id += 1 182 183 self.their_turn() 156 184 157 185 def send_move(self, row, column): 158 186 msg = xmpp.Message() 187 msg.setType('chat') 159 188 160 189 turn = msg.NT.turn 161 turn.setNamespace( 'http://jabber.org/protocol/games')190 turn.setNamespace(games_ns) 162 191 163 192 move = turn.NT.move 164 move.setNamespace( 'http://jabber.org/protocol/games/tictactoe')193 move.setNamespace(games_ns+'/tictactoe') 165 194 166 195 move.setAttr('row', str(row)) … … 170 199 self.send(msg) 171 200 172 self.next_move_id += 1173 174 self.their_turn()175 176 201 class TicTacToeBoard: 202 def check_for_strike(self, p, r, c, strike): 203 # up and down, left and right 204 tallyI = 0 205 tally_ = 0 206 207 # right triangles: L\ , F/ 208 tallyL = 0 209 tallyF = 0 210 211 # convert real columns to internal columns 212 r -= 1 213 c -= 1 214 215 for d in xrange(-strike, strike): 216 # vertical check 217 try: 218 tallyI = tallyI + 1 if self.board[r+d][c] == p else 0 219 except IndexError: 220 pass 221 222 # horizontal check 223 try: 224 tally_ = tally_ + 1 if self.board[r][c+d] == p else 0 225 except IndexError: 226 pass 227 228 # diagonal checks 229 try: 230 tallyL = tallyL + 1 if self.board[r+d][c+d] == p else 0 231 except IndexError: 232 pass 233 234 try: 235 tallyF = tallyF + 1 if self.board[r+d][c-d] == p else 0 236 except IndexError: 237 pass 238 239 if any([t == strike for t in (tallyL, tallyF, tallyI, tally_)]): 240 return True 241 242 return False 243 177 244 def __init__(self, session, rows, cols): 178 245 self.session = session … … 184 251 185 252 self.setup_window() 253 254 # is the board full? 255 def full(self): 256 for r in xrange(self.rows): 257 for c in xrange(self.cols): 258 if self.board[r][c] == None: 259 return False 260 261 return True 186 262 187 263 def setup_window(self): … … 215 291 self.session.move(row, column) 216 292 293 # this actually draws the board 217 294 def expose(self, widget, event): 218 295 win = widget.window
