def verify_card(self,cards,card_num):
		'''Verifica se la carta card_num puo' essere giocata nel turno corrente.'''

		# di mano, carta valida
		if self.table.count(0) == len(self.table):
			return True

		# verifica se possiamo rispondere
		ver = []
		for c in cards:
			ver.append(deck.get_card(c)[0])

		prev = deck.get_card(self.table[self.current_order[0]])
		this = deck.get_card(card_num)

		# possiamo rispondere, verifica se la carta precedente e' dello stesso seme
		print "Verification seems:",ver,"starting seem of",self.table[self.current_order[0]],"is",prev[0],"my seem for card",card_num,"is",this[0]
		if prev[0] in ver:
			if prev[0] == this[0]:
				return True

		# non possiamo rispondere
		else:
			return True

		return False
Exemple #2
0
def _next_round(r, k, players):
    """
    PLAYER:: CAMP => UNDECIDED

    Clear the table, move everyone from CAMP to UNDECIDED, and deal an
    artifact and a card.
    """
    # push everything on the table and captured back into the deck
    return_to_deck = r.lrange(path(k, TABLE), 0, -1) + r.lrange(path(k, CAPTURED), 0, -1)
    if len(return_to_deck):
        r.sadd(path(k, DECK), *return_to_deck)
        r.delete(path(k, TABLE), path(k, CAPTURED))

    r.set(path(k, POT), 0)

    for player in players:
        r.hset(path(k, PLAYERS, player[NAME]), STATE, UNDECIDED)

    new_artifact = r.spop(path(k, ARTIFACTS_UNSEEN))
    _round = r.incr(path(k, ROUND))
    _save_update(r, k, { ROUND: int(_round) } )
    _save_update(r, k, { ARTIFACTS_IN_PLAY: get_card(new_artifact).name } )
    assert r.sadd(path(k, DECK), new_artifact) == 1
    r.rpush(path(k, ARTIFACTS_IN_PLAY), new_artifact)
    _deal_card(r, k)
Exemple #3
0
def _deal_card(r, k, hans=[]):
    """
    PLAYER:: HAN => UNDECIDED | CAMP

    This will deal another card and push any hans either back to camp
    (death) or back to undecided.

    A single card is moved from a random point in the deck onto the
    right side of the table.
    """
    prior_card_names = [get_card(idx).name for idx in r.lrange(path(k, TABLE), 0, -1)]
    card_idx = r.spop(path(k, DECK))

    r.rpush(path(k, TABLE), card_idx)
    card = get_card(card_idx)
    _save_update(r, k, { CARD : card.name })

    if isinstance(card, Hazard) and card.name in prior_card_names:
        _save_update(r, k, { DEATH : { PLAYERS: sorted([h[NAME] for h in hans]),
                                       CARD: card.name } })
        # save intermediate game state for death
        for han in hans:
            r.hset(path(k, PLAYERS, han[NAME]), STATE, DEATH)

        _save_game_state(r, k, True)
        _publish_update(r, k)

        coro_sleep(DEATH_SLEEP)
        new_state = CAMP
    else:
        new_state = UNDECIDED
        if hans:
            _save_update(r, k, { HAN : { PLAYERS : sorted([h[NAME] for h in hans])}})
        if isinstance(card, Artifact):
            artifacts_seen_count = r.incr(path(k, ARTIFACTS_SEEN_COUNT))
            _save_update(r, k, { ARTIFACTS_SEEN_COUNT: int(artifacts_seen_count) })

    for han in hans:
        r.hset(path(k, PLAYERS, han[NAME]), STATE, new_state)
Exemple #4
0
def _save_game_state(r, k, reveal=False):
    """
    Saves a JSON representation of the game's current state.

    If reveal is true, the players hash will reveal everyone's move.
    """
    players = _get_players(r, k)

    update_id = r.incr(path(k, UPDATE_ID))

    for player in players:
        r.rpush(path(k, PLAYERS, player[NAME], SAVED), json.dumps(player))

    game_state = {
        UPDATE_ID: update_id,
        PLAYERS:
            [ p if p[STATE] in [WON, LOST] else
              { NAME: p[NAME],
                STATE: MOVED if (p[STATE] in [HAN, LANDO] and not reveal) else p[STATE] }
              for p in players],
        TABLE:
            [get_card(idx).name for idx in r.lrange(path(k, TABLE), 0, -1)],
        CAPTURED:
            [get_card(idx).name for idx in r.lrange(path(k, CAPTURED), 0, -1)],
        POT: int(r.get(path(k, POT)) or 0),
        ARTIFACTS_DESTROYED:
            [get_card(idx).name for idx in r.lrange(path(k, ARTIFACTS_DESTROYED), 0, -1)],
        ARTIFACTS_SEEN_COUNT: int(r.get(path(k, ARTIFACTS_SEEN_COUNT)) or 0),
        ARTIFACTS_IN_PLAY:
            [get_card(idx).name for idx in r.lrange(path(k, ARTIFACTS_IN_PLAY), 0, -1)]
        }

    if r.exists(path(k, ROUND)):
        game_state[ROUND] = r.get(path(k, ROUND))

    r.rpush(path(k, SAVED), json.dumps(game_state))
Exemple #5
0
def _get_players(r, k):
    """
    Get a list of all players in the game formed as dictionaries.
    Notates them with their artifacts.
    """
    players = [r.hgetall(path(k, PLAYERS, name))
               for name in sorted(r.smembers(path(k, PLAYERS)))]

    for player in players:
        player[player[STATE]] = True  # a bit hacky, but this makes templating easier
        player[ARTIFACTS_CAPTURED] = [
            get_card(idx).name
            for idx in r.lrange(path(k, PLAYERS, player[NAME], ARTIFACTS_CAPTURED), 0, -1)]

    return players
Exemple #6
0
def _take_loot(r, k, landos):
    """
    PLAYER:: LANDO => CAMP

    This will move all Landos back to CAMP, giving them loot.
    """
    loot = int(r.get(path(k, POT)) or 0)
    for card_idx in r.lrange(path(k, TABLE), 0, -1):
        card = get_card(card_idx)
        if isinstance(card, Treasure):
            loot += card.value
            r.lrem(path(k, TABLE), 1, card_idx)
            r.rpush(path(k, CAPTURED), card_idx)
        elif isinstance(card, Artifact):
            r.lrem(path(k, TABLE), 1, card_idx)
            artifact_value = ARTIFACT_VALUES[int(r.get(path(k, ARTIFACTS_SEEN_COUNT))) - 1]
            r.lrem(path(k, ARTIFACTS_IN_PLAY), 1, card_idx)
            if len(landos) == 1: #  lucky lando
                _save_update(r, k,
                             { ARTIFACTS_CAPTURED :
                                   { PLAYERS : landos[0][NAME],
                                     CARD: card.name,
                                     VALUE: artifact_value } })
                loot += artifact_value
                r.rpush(path(k, PLAYERS, landos[0][NAME], ARTIFACTS_CAPTURED), card_idx)
            else:
                _save_update(r, k,
                             { ARTIFACTS_DESTROYED :
                                   { PLAYERS : sorted([l[NAME] for l in landos]),
                                     CARD: card.name,
                                     VALUE: artifact_value } })
                r.rpush(path(k, ARTIFACTS_DESTROYED), card_idx)

    remainder = loot % len(landos)
    payout = (loot - remainder) / len(landos)
    r.set(path(k, POT), remainder)

    for lando in landos:
        r.hset(path(k, PLAYERS, lando[NAME]), STATE, CAMP) # LANDO => CAMP
        r.hincrby(path(k, PLAYERS, lando[NAME]), LOOT, payout)

    _save_update(r, k, { LANDO : { PLAYERS : sorted([l[NAME] for l in landos]),
                                      VALUE : payout,
                                      POT: remainder }})
	def _round_points_to_team(self, position, cards):
		'''Consegna il punteggio delle carte alla squadra del giocatore in position.'''

		team = position % 2

		# calcola punteggio
		cumul = self.hand_points[team][0]
		third = self.hand_points[team][1]
		for c in cards:

			s,v = deck.get_card(c)

			if v == 1:
				cumul = cumul + 1

			if v == 2 or v == 3 or (v >= 8 and v <= 10):
				third = third + 1
				if third == 3:
					cumul = cumul + 1
					third = 0

		print "(SERVER) Giving",cumul,"points to team",team
		self.hand_points[team][0] = cumul
		self.hand_points[team][1] = third
	def turn_next(self, card_num):
		'''Continua il giro al giocatore successivo.

		card_num: carta giocata in questo turno
		'''

		# rilascia il turno dal giocatore precedente
		position = self.current_order[len(self.table)-self.table.count(0)]
		self.players[position].set_state(player.STATE_TURNWAIT)

		self.table[position] = card_num

		print "(SERVER) Cards on table:",self.table

		if self.table.count(0) == 0:
			# fine giro, determina chi prende e dichiara
			print "(SERVER) End round!"

			# elimina ogni chat pendente
			for p in self.players:
				p.cancel_chat_pending()

			primary = deck.get_card(self.table[self.current_order[0]])
			take = self.current_order[0]
			print "(SERVER) Commanding seem is",primary

			for c in self.table:
				s,v = deck.get_card(c)

				print "(SERVER) Card value:",(v,CARDS_VALUE.index(v)),(primary[1],CARDS_VALUE.index(primary[1]))
				if s == primary[0] and CARDS_VALUE.index(v) > CARDS_VALUE.index(primary[1]):
					print "(SERVER) Found major card:",c
					take = self.table.index(c)
					primary = s,v

			print "(SERVER) Position",take,"takes the head"
			# consegna i punti alla squdra del giocatore
			self._round_points_to_team(take,self.table)

			self.conn.send_all(interfaces.NetMethod(protocol.TAKES,take))
			self.conn.send_all(interfaces.NetMethod(protocol.POINTS,self.hand_points))

			self.turn_count = self.turn_count + 1
			if self.turn_count >= ROUNDS:
				# fine mano!
				print "(SERVER) End hand!"
				self._update_game_points(take)

				time.sleep(3.0)
				self.conn.send_all(interfaces.NetMethod(protocol.GAME_POINTS,self.points))

				if self.points[0] >= MAX_POINTS or self.points[1] >= MAX_POINTS:
					# fine partita! raggiunto 41...

					ret = self.points.index(max(self.points))
					if self.points[0] == self.points[1]:
						# mitici... solo voi ce potete riusci!
						ret = -1

					# dichiara fine partita...
					self.conn.send_all(interfaces.NetMethod(protocol.END_GAME,ret))

				else:
					self.conn.send_all(interfaces.NetMethod(protocol.END_HAND))

					# inizia nuova mano...
					# dovrebbe funzionare...
					self._make_deck()
					for p in self.players:
						p.conn.user_data['state'] = PSTATE_JOINED
						p.set_state(player.STATE_WAIT)

			else:
				# ricomincia giro dalla posizione di take
				time.sleep(3.0)
				self.turn(take)

		else:
			# dai il turno al giocatore successivo
			if position >= 3: position = -1

			# dichiarazione pubblica accusi
			if ( len(self.table) - self.table.count(0) ) == 1 and self.turn_count == 1:
				for p in self.players:
					if len(p.accusations) > 0: self.conn.send_all(interfaces.NetMethod(protocol.ACCUSATIONS,p.position,p.accusations))

			self.players[position+1].set_state(player.STATE_TURN)
		print "Verification seems:",ver,"starting seem of",self.table[self.current_order[0]],"is",prev[0],"my seem for card",card_num,"is",this[0]
		if prev[0] in ver:
			if prev[0] == this[0]:
				return True

		# non possiamo rispondere
		else:
			return True

		return False

if __name__ == '__main__':
		table = [3, 2, 1, 8]
		print "(SERVER) Table:",table

		primary = deck.get_card(table[0])
		take = 0
		print "Commanding:",primary

		for c in table:
			s,v = deck.get_card(c)

			print "(SERVER) Card value:",(v,CARDS_VALUE.index(v)),(primary[1],CARDS_VALUE.index(primary[1]))
			if s == primary[0] and CARDS_VALUE.index(v) > CARDS_VALUE.index(primary[1]):
				#print "(SERVER) Found major card:",c
				take = table.index(c)

		print "(SERVER) Position",take,"takes the head"

		team = take % 2