Esempio n. 1
0
	def draw_card(self, player):
		self.draw_card_lock.acquire()

		successful = False
		# If it's the turn of player who wants to play a card and
		# he hasn't drawn a card this turn yet and
		# he has no card that fits the top of the stack
		if player == self.playing_player and \
			not player.games.uno.has_drawn_card and \
			not can_play(player.games.uno.cards, self.card_stack[-1]):

			# Give player 1 card
			self.give_cards(1, player)
			# Can he play now? (could be optimized)
			# No -> End turn
			if not can_play(player.games.uno.cards, self.card_stack[-1]):
				self.end_turn()
			# Yes -> Can't draw any more cards
			else:
				player.games.uno.has_drawn_card = True

			successful = True

			if self.debug:
				logging.info("Player '%s' drew card '%s'" % (player, 
					player.games.uno.cards[-1]))
		
		self.draw_card_lock.release()
		player.send(successful, "uno_draw_card")
Esempio n. 2
0
	def _stop(self):
		if self.playing:
			self.playing = False
			# "Deallocation" and user games namespace cleanup
			self.game.stop()
			self.game = None
			broadcast(False, "lobby_playing", self.players)

			if config.lobby_debug:
				logging.info("Lobby '%s' stopped" % self)
Esempio n. 3
0
	def __init__(self, name, host):
		self.name = name
		self.host = host

		self.players = [host]

		self.playing = False

		self.game = None

		if config.lobby_debug:
			logging.info("Lobby '%s' created by '%s'" % (self, self.host))
Esempio n. 4
0
	def change_direction(self):
		if self.direction == Uno.LEFT:
			self.direction = Uno.RIGHT
		elif self.direction == Uno.RIGHT:
			self.direction = Uno.LEFT
		else:
			# Unexpected direction -> Direction is right
			self.direction = Uno.RIGHT
		broadcast(self.direction, "uno_direction", self.lobby.players)

		if self.debug:
			logging.info("Direction changed to '%s'" % 
				("left" if self.direction == Uno.LEFT else "right"))
Esempio n. 5
0
	def start(self, player):
		successful = False
		if player == self.host and not self.playing and self.player_count >= 2:
			self.playing = True
			broadcast(True, "lobby_playing", self.players)
			# Game possible replaceable in the future
			self.game = Uno(self, debug=config.game_debug)
			successful = True

			if config.lobby_debug:
				logging.info("Game '%s' started in lobby '%s'" % (self.game, 
					self))

		player.send(successful, "lobby_start")
Esempio n. 6
0
	def closed(self, code, reason):
		# Leave the lobby
		if self.lobby != None:
			self.lobby.leave(self)
		# Free up taken user name
		if self.name != None:
			del taken_names[taken_names.index(self.name)]

		if type(reason) is bytes:
			reason = reason.decode()

		if self.logged_in:
			logging.info("User '%s' disconnected ('%s': %d)" % (self.name,
				reason, code))
		else:
			logging.info("Unauthenticated user disconnected. ('%s': '%d')" % (
				reason, code))
Esempio n. 7
0
	def end_turn(self, player_inc=1, time_expired=False):
		next_player = self.get_next_player(player_inc)

		if self.debug:
			if time_expired:
				logging.info("Turn time of '%i' expired" % self.turn_time)
			logging.info("Next player: '%s'" % next_player)


		self.playing_player.games.uno.turn_over = True
		self.playing_player.games.uno.has_drawn_card = False
		next_player.games.uno.turn_over = False

		self.playing_player = next_player

		self.reset_turn_timer()

		broadcast(self.playing_player, "uno_turn", self.lobby.players,
			json_encoder=UserEncoder)
Esempio n. 8
0
	def join(self, player):
		successful = False

		if player not in self.players and not self.playing:
			player.lobby = self
			# Announce new player
			broadcast(player.name, "lobby_user_join", self.players)
			self.players.append(player)
			# Players currently in lobby (including you)
			player.send(self.players, "lobby_players",
				json_encoder=UserEncoder)
			# If host has changed since lobby_list
			player.send(self.host.name, "lobby_host")
			successful = True

			if config.lobby_debug:
				logging.info("Player '%s' joined lobby '%s'" % (player, 
					self))

		player.send(successful, "lobby_join")
Esempio n. 9
0
	def leave(self, player):
		successful = False

		if player in self.players:
			# If game is currently being played
			if self.playing:
				# Just to be sure
				if self.game != None:
					# Invoke player leave hook *before* removing player from 
					# self.players
					self.game.player_leave(player)


			# Leave doesn't block, this could kick an unrelated player by
			# accident
			player_index = self.players.index(player)
			player.lobby = None
			

			del self.players[player_index]
			# Broadcast that a player has left
			broadcast(player_index, "lobby_user_leave", self.players)
			
			successful = True



			if self.playing:
				# Game stops when all but 1 player leaves
				if self.player_count <= 1:
					lobbies[self.name].stop()

					if config.lobby_debug:
						logging.info("Too few players in '%s'. Stopping game..." % 
							self)

			# No players left in lobby -> delete Lobby
			if self.player_count == 0:
				lobbies[self.name].stop()
				del lobbies[self.name]
				lobby_deleted = True

				if config.lobby_debug:
					logging.info("Lobby '%s' is empty. Deleting..." % 
						self)

			# Still players left
			# Host left -> Random player becomes host
			elif player == self.host:
				self.host = choice(self.players)
				broadcast(self.host.name, "lobby_host", self.players)

				if config.lobby_debug:
					logging.info("Lobby '%s' has new host '%s'" % (self, 
						self.host))



			if config.lobby_debug:
				logging.info("Player '%s' left lobby '%s'" % (player, 
					self))

		player.send(successful, "lobby_leave")
Esempio n. 10
0
	def play_card(self, card_id, player):
		self.play_card_lock.acquire()

		successful = False
		# If it's the turn of the player who wants to play a card
		if player == self.playing_player:
			# Is the card_id valid?
			if card_id in range(len(player.games.uno.cards)):
				# Acquire the card
				card = player.games.uno.cards[card_id]

				if self.debug:
					logging.info("'%s' played: %s" % (player, card))
					logging.info("Cards of '%s': %s" % (player,
						player.games.uno.cards))

				# Does the played card fit on top of the card stack?
				if self.card_stack[-1].can_play(card):
					self.card_stack.append(card)

					# Send the played card to all players
					broadcast(card, "uno_card_stack", self.lobby.players,
						json_encoder=CardEncoder)

					# Change direction
					if card.face == ROTATE:
						# Only two players -> Next turn name player
						if len(self.lobby.players) != 2:
							self.change_direction()
							self.end_turn()
						# Turn goes on if only two players are playing
						# Player can draw another card if needed
						else:
							player.games.uno.has_drawn_card = False		
						

					# Skip player
					elif card.face == BLOCK:
						if len(self.lobby.players) != 2:
							self.end_turn(player_inc=2)
						# Turn goes on if only two players are playing
						# Player can draw another card if needed
						else:
							player.games.uno.has_drawn_card = False

					# Take two cards
					elif card.face == TAKE_TWO:
						self.give_cards(2, self.next_player)
						self.end_turn()


					# Take four cards
					elif card.face == TAKE_FOUR:
						self.give_cards(4, self.next_player)
						# Turn does not end

					# End turn only if the card does not require another card
					elif card.face != PICK_COLOR:
						self.end_turn()

					# Remove the card from the players deck
					del player.games.uno.cards[card_id]

					broadcast({
						"player" : player, 
						"count" : len(player.games.uno.cards)
						}, "uno_card_count", 
						self.lobby.players, exclude=player,
						json_encoder=UserEncoder)
					successful = True
				
				else:
					if self.debug:
						logging.warning("Card does not fit on top of stack. "
							"Is the client desynchronized? (player: '%s')" %
							player)

				# If player has no cards left
				if len(player.games.uno.cards) == 0:
					broadcast(player.name, "uno_win", self.lobby.players)
					self.lobby.stop()

		self.play_card_lock.release()			
		player.send(successful, "uno_play_card")