def new_game_command(instance, player, arguments = None):
  """ Start a new game and reset any game in progress.

  Args:
    instance: The GameInstance database model for this operation.
    player: The player starting a new game. Must be the only player
      in the instance.
    arguments: Not used, can be any value.

  Returns:
    A list containing the number of guesses remaining, the starting
    score of the player, the player's historical high score and the
    number of games completed in the past.

  Raises:
    ValueError if there is more than 1 player in the instance
    or the player is not the current leader.
  """
  old_games = instance.get_messages_query('bac_game', player,
                                          sender = player,
                                          keys_only = True)
  db.delete(old_games)

  score = scoreboard.get_score(instance, player)
  if (score == 0):
    # Score is [high score, total score, games played]
    score = [0, 0, 0]
    scoreboard.set_score(instance, player, score)

  game = Message(parent = instance, sender = player,
                 msg_type = 'bac_game', recipient = player)
  game.bac_solution = sample(colors, solution_size)
  game.bac_guesses_remaining = starting_guesses
  game.bac_score = solution_size * starting_guesses * 2
  game.bac_last_guess = ['']
  game.bac_last_reply = ''
  game.put()

  return [game.bac_guesses_remaining, game.bac_score, score,
          game.key().id()]
def test_full_game():
  iid = test_utils.make_instance()
  for player in init_players:
    test_utils.add_player(iid, player)

  # Start the game
  current_round = 1
  response = test_utils.post_server_command(iid, 'ata_new_game', [])

  instance = test_utils.get_instance_model(iid)
  noun_cards_left = card_game.cards_left(instance)
  assert instance.ata_round == current_round

  # Get the cards
  for player in players:
    hand = test_utils.get_messages(iid, 'crd_hand', '', 1, pid = player)[0]
    assert len(hand['contents']) == 7
    player_cards[player] = hand['contents']

  player_submissions = {}
  # Submit cards
  for player in players:
    if player != instance.leader:
      card = player_cards[player].pop()
      response = test_utils.post_server_command(iid, 'ata_submit_card',
                                                [current_round, card],
                                                pid = player)
      player_cards[player] = response['contents'][2]
      player_submissions[player] = card
      for c in player_submissions.values():
        assert c in response['contents'][1]
    assert len(player_cards[player]) == 7

  instance = test_utils.get_instance_model(iid)
  assert noun_cards_left - len(players) + 1 == card_game.cards_left(instance)

  for player in players:
    response = test_utils.get_messages(iid, 'ata_submissions', '', 1,
                                       pid = player)[0]
    for c in player_submissions.values():
      assert c in response['contents'][1]
    assert response['contents'][0] == current_round

  # Choose a winner
  winner = [x for x in players if x != instance.leader][0]
  contents = test_utils.post_server_command(iid, 'ata_end_turn',
                                            [current_round,
                                             player_submissions[winner]],
                                            pid = instance.leader)['contents']
  assert contents[2] == 2
  assert contents[3] == winner
  assert contents[4] == player_submissions[winner]
  assert [1, winner] in contents[1]
  current_round = current_round + 1
  instance = test_utils.get_instance_model(iid)
  assert instance.ata_round == current_round

  # Check for next round messages
  for player in players:
    new_round_msg = test_utils.get_messages(iid, 'ata_new_round', '',
                                            1, pid = player)[0]['contents']
    assert new_round_msg[2] == 2
    assert new_round_msg[3] == winner
    assert new_round_msg[4] == player_submissions[winner]

  # Accelerate the game, next point wins
  for player in players:
    scoreboard.set_score(instance, player, 4)
  instance.put()

  winner = [x for x in players if x != instance.leader][0]
  winning_card = player_cards[winner][0]
  test_utils.post_server_command(iid, 'ata_submit_card',
                                 [current_round, winning_card],
                                 pid = winner)
  contents = test_utils.post_server_command(iid, 'ata_end_turn',
                                            [current_round, winning_card],
                                            pid = instance.leader)['contents']
  assert contents[0] == current_round
  assert contents[1] == winning_card
  assert [5, winner] in contents[2]

  # Check for game over messages
  for player in players:
    contents = test_utils.get_messages(iid, 'ata_game_over', '',
                                       1, pid = player)[0]['contents']
    assert contents[0] == current_round
    assert contents[1] == winning_card
    assert [5, winner] in contents[2]

  instance = test_utils.get_instance_model(iid)
  assert 'ata_round' not in instance.dynamic_properties()
  assert 'ata_char_card' not in instance.dynamic_properties()
  assert 'ata_submissions' not in instance.dynamic_properties()
def guess_command(instance, player, arguments):
  """ Evaluate a guess and determine the score.

  Args:
    instance: The GameInstance database model for this operation.
    player: The player making the guess. Must be the leader of
      the instance.
    arguments: A two element list containg the game id and a second
      list with the guessed colors.

  new_game_command must be invoked before a guess can be made.

  Returns:
    If the player has guessed correctly:
      A two element list containg a score list and a boolean of
      whether or not this game set a new high score. The score list is
      a three element list containing the player's high score, their
      total score and their total number of games played.

    Otherwise:
      A four element list containing the player's remaining score, the
      number of guesses remaining, the number of bulls for this guess
      and the number of cows for this guess.

  Raises:
    ValueError if the player is not the current instance leader and
    only member of the game.
    ValueError if the player has no guesses remaining.
    ValueError if the guess does not have the correct number of
    elements.
    ValueError if no game has been started yet.
  """
  guess = arguments[1]
  if len(guess) != solution_size:
    raise ValueError("Guess was not the right number of elements.")

  game = db.get(Key.from_path('Message', int(arguments[0]),
                              parent = instance.key()))

  if game is None:
    raise ValueError("Game not found. Please start a new game.")
  if game.sender != player:
    raise ValueError("This is not your game. Please start a new game.")

  if guess == game.bac_last_guess:
    return simplejson.loads(game.bac_last_reply)

  if game.bac_guesses_remaining == 0:
    raise ValueError("No turns left, please start a new game.")

  return_content = None

  if guess == game.bac_solution:
    game.bac_guesses_remaining = 0
    new_high_score = False
    score = scoreboard.get_score(instance, player)
    if game.bac_score > score[0]:
      new_high_score = True
      score[0] = game.bac_score
    score[1] = score[1] + game.bac_score
    score[2] = score[2] + 1
    scoreboard.set_score(instance, player, score)
    return_content = [score, new_high_score]
  else:
    game.bac_guesses_remaining -= 1
    bulls = cows = 0
    for i in xrange(solution_size):
      if guess[i] == game.bac_solution[i]:
        bulls += 1
      elif guess[i] in game.bac_solution:
        cows += 1

    score_deduction = solution_size * 2 - cows - 2 * bulls
    game.bac_score -= score_deduction
    return_content = [game.bac_guesses_remaining, game.bac_score,
                      bulls, cows]
  game.bac_last_reply = simplejson.dumps(return_content)
  game.bac_last_guess = guess
  game.put()
  return return_content
Example #4
0
def test_full_game():
    iid = test_utils.make_instance()
    for player in init_players:
        test_utils.add_player(iid, player)

    # Start the game
    current_round = 1
    response = test_utils.post_server_command(iid, 'ata_new_game', [])

    instance = test_utils.get_instance_model(iid)
    noun_cards_left = card_game.cards_left(instance)
    assert instance.ata_round == current_round

    # Get the cards
    for player in players:
        hand = test_utils.get_messages(iid, 'crd_hand', '', 1, pid=player)[0]
        assert len(hand['contents']) == 7
        player_cards[player] = hand['contents']

    player_submissions = {}
    # Submit cards
    for player in players:
        if player != instance.leader:
            card = player_cards[player].pop()
            response = test_utils.post_server_command(iid,
                                                      'ata_submit_card',
                                                      [current_round, card],
                                                      pid=player)
            player_cards[player] = response['contents'][2]
            player_submissions[player] = card
            for c in player_submissions.values():
                assert c in response['contents'][1]
        assert len(player_cards[player]) == 7

    instance = test_utils.get_instance_model(iid)
    assert noun_cards_left - len(players) + 1 == card_game.cards_left(instance)

    for player in players:
        response = test_utils.get_messages(iid,
                                           'ata_submissions',
                                           '',
                                           1,
                                           pid=player)[0]
        for c in player_submissions.values():
            assert c in response['contents'][1]
        assert response['contents'][0] == current_round

    # Choose a winner
    winner = [x for x in players if x != instance.leader][0]
    contents = test_utils.post_server_command(
        iid,
        'ata_end_turn', [current_round, player_submissions[winner]],
        pid=instance.leader)['contents']
    assert contents[2] == 2
    assert contents[3] == winner
    assert contents[4] == player_submissions[winner]
    assert [1, winner] in contents[1]
    current_round = current_round + 1
    instance = test_utils.get_instance_model(iid)
    assert instance.ata_round == current_round

    # Check for next round messages
    for player in players:
        new_round_msg = test_utils.get_messages(iid,
                                                'ata_new_round',
                                                '',
                                                1,
                                                pid=player)[0]['contents']
        assert new_round_msg[2] == 2
        assert new_round_msg[3] == winner
        assert new_round_msg[4] == player_submissions[winner]

    # Accelerate the game, next point wins
    for player in players:
        scoreboard.set_score(instance, player, 4)
    instance.put()

    winner = [x for x in players if x != instance.leader][0]
    winning_card = player_cards[winner][0]
    test_utils.post_server_command(iid,
                                   'ata_submit_card',
                                   [current_round, winning_card],
                                   pid=winner)
    contents = test_utils.post_server_command(iid,
                                              'ata_end_turn',
                                              [current_round, winning_card],
                                              pid=instance.leader)['contents']
    assert contents[0] == current_round
    assert contents[1] == winning_card
    assert [5, winner] in contents[2]

    # Check for game over messages
    for player in players:
        contents = test_utils.get_messages(iid,
                                           'ata_game_over',
                                           '',
                                           1,
                                           pid=player)[0]['contents']
        assert contents[0] == current_round
        assert contents[1] == winning_card
        assert [5, winner] in contents[2]

    instance = test_utils.get_instance_model(iid)
    assert 'ata_round' not in instance.dynamic_properties()
    assert 'ata_char_card' not in instance.dynamic_properties()
    assert 'ata_submissions' not in instance.dynamic_properties()