def test_TH_reports_completion(self): loc_order = utils.csv_to_list(self.game.ordered_locations) # when the player visits the first location, 'complete' flag should be false self.player.highest_visited = None self.player.save() self.response = self.client.get(self.url) self.assertEqual(self.response.status_code, 200) self.assertEqual(self.response.context["game_data"]["complete"], False) # player visits next location - 'complete' still false self.location = self.game.location_set.all()[1] self.url = reverse(self.view, args=(self.location.uuid,)) self.response = self.client.get(self.url) self.assertEqual(self.response.status_code, 200) self.assertEqual(self.response.context["game_data"]["complete"], False) # set the player to have visited the next-to-last location self.player.highest_visited = self.game.location_set.filter(pk=loc_order[-2])[0] self.player.save() # visiting the last location should set 'complete' to true last_loc = self.game.location_set.filter(pk=loc_order[-1])[0] self.url = reverse(self.view, args=(last_loc.uuid,)) self.response = self.client.get(self.url) self.assertEqual(self.response.status_code, 200) self.assertEqual(self.response.context["game_data"]["complete"], True)
def test_point_order_correct(self): # only applies for TH game currently; thus, the default # should be empty self.assertEqual(self.response.context["gmap"].point_order, []) # get the page response for a TH game hunt = TreasureHuntGame.objects.all()[0] self.assertTrue(isinstance(hunt, TreasureHuntGame)) self.assertEqual(self.user, hunt.created_by) self.url = reverse(self.view, args=(hunt.pk,)) self.response = self.client.get(self.url) self.assertEqual(self.response.context["gmap"].point_order, utils.csv_to_list(hunt.ordered_locations))
def test_saving_location_updates_ordered_locations(self): # the TH game's location list should be empty self.assertEqual(self.hunt.ordered_locations, "") # add some locations to the TH game and make # sure they get added to ordered_locations ids = [] for i in range(5): loc = Location() loc.gameID = self.hunt loc.save() ids.append(loc.id) game_locs = utils.csv_to_list(self.hunt.ordered_locations) for loc_id in ids: self.assertTrue(loc_id in game_locs)
def qrcode(game, location): try: loc_order = utils.csv_to_list(game.ordered_locations) loc_index = loc_order.index(location.id) except ValueError: return '' next_index = loc_index + 1 clue = '' if next_index >= len(loc_order): clue = 'You have reaced the final location! Congratulations!' else: next_loc = Location.objects.filter(id=loc_order[next_index])[0] clue = 'Clue to next location: %s' % next_loc.clue return '%s\nURL for this location:\n' % clue
def location_save(sender, **kwargs): ''' Called after a location gets saved. Check if the location is for a TreasureHuntGame, and if so then make sure the game's ordered_locations includes the location. ''' # only need to update when a new location is added # (assuming locations are never moved to a new game # after they are created) if kwargs['created']: loc = kwargs['instance'] game = loc.gameID if isinstance(game, TreasureHuntGame): game_locs = utils.csv_to_list(game.ordered_locations) if loc.id not in game_locs: game.ordered_locations += str(loc.id) + ',' game.save()
def test_TH_game_reports_completion(self): # join the TH game form_data = {"mode": "join"} self.response = self.client.post(self.url, form_data) self.assertEqual(self.response.status_code, 200) # the returned page should state the game is not complete self.assertEqual(self.response.context["game_data"]["complete"], False) # move the player to a middle location, game should not be complete player = self.game.player_set.all()[0] player.highest_visited = self.game.location_set.all()[0] # move the player to the last location in the game last_id = utils.csv_to_list(self.game.ordered_locations)[-1] player.highest_visited = self.game.location_set.filter(pk=last_id)[0] player.save() self.response = self.client.get(self.url) self.assertEqual(self.response.status_code, 200) self.assertEqual(self.response.context["game_data"]["complete"], True)
def details(game, player): # if the player isn't given, they are not a player in this game; # thus return nothing if player is None: return {} game_data = {'clue':'', 'complete':False} loc_order = utils.csv_to_list(game.ordered_locations) # if player hasn't visited any locations, give the first clue next_index = 0 if player.highest_visited is not None: next_index = 1 + loc_order.index(player.highest_visited.id) # if player has visited the last location if next_index >= len(loc_order): game_data['complete'] = True else: next_location = get_object_or_404(Location, id=loc_order[next_index]) game_data['clue'] = next_location.clue return game_data
def process(player, location): game_data = {'clue':'', 'complete':False} loc_order = utils.csv_to_list(player.game.ordered_locations) # if the player hasn't visited any locations # yet, the next location should be the first one next_loc_id = loc_order[0] if player.highest_visited is not None: # if the player has already visited the last location, do nothing if player.highest_visited == loc_order[-1]: game_data['complete'] = True return game_data else: # otherwise, find the next location the player should be visiting next_index = 1 + loc_order.index(player.highest_visited.id) next_loc_id = loc_order[next_index] # if the given location is the one the player should be at next, # then advance the player if location.id == next_loc_id: player.highest_visited = location player.save() else: # the player shouldn't be at this location yet raise PermissionDenied('not next location') # give the player the clue for the location after # the one they just told us they visited # (unless they're done the game already) next_index = 1 + loc_order.index(location.id) if next_index >= len(loc_order): game_data['complete'] = True else: next_location = get_object_or_404(Location, id=loc_order[next_index]) game_data['clue'] = next_location.clue return game_data
def game_edit(request, game_id): # get the game game = get_object_or_404(Game, pk=game_id) # only the game's creator can edit the locations if request.user != game.created_by: return HttpResponseForbidden('Cannot access: not game creator') locations = game.location_set.all().order_by('id') error_msgs = [] if request.method == 'POST': # save locations, if they were given if request.POST['mode'] == 'update_locations': new_locations = simplejson.loads(request.POST['locations']) for loc in new_locations: # make sure this location ID exists & is # linked with the current game_id try: existing_loc = locations.get(pk=loc['id']) except ObjectDoesNotExist: error_msgs.append( 'location[%d] not linked to game[%d]' % (int(loc['id']), int(game_id))) # set the new lat/lon existing_loc.latitude = str(loc['lat']) existing_loc.longitude = str(loc['lon']) # save any game-specific data (from the edit_XX.html templates) if isinstance(game, TreasureHuntGame): existing_loc.clue = request.POST['clue_%d' % (existing_loc.id,)] existing_loc.save() # add a new point elif request.POST['mode'] == 'add_point': new_loc = Location(latitude=game.center_latitude, longitude=game.center_longitude, created=datetime.now(), visible=datetime.now(), expires=datetime.now(), gameID=game) new_loc.save() # re-load the locations to grab the new point locations = game.location_set.all().order_by('id') # if this is a game with an ordering to the points, # grab that order for the map to connect the points point_order = [] if isinstance(game, TreasureHuntGame): point_order = utils.csv_to_list(game.ordered_locations) points = utils.locations_to_points(locations) gmap = Map('gmap', points, point_order) gmap.center = (game.center_latitude, game.center_longitude) gmap.zoom = '15' context = RequestContext(request) context['gmap'] = gmap context['error_msgs'] = error_msgs context['game'] = game context['locations'] = locations a = ActivityStreamItem(actor=request.user,verb="has modified ",target=game,occurred=datetime.now()) a.save() context = page_info(context) return render_to_response('games/edit.html', context)