Exemplo n.º 1
0
Arquivo: app.py Projeto: Kebin-Lin/STP
def joinRoom(roomInfo):
    if len(roomInfo) == 0:
        return
    if request.sid in rooms:  #Checks if the user is already in a room
        if rooms[request.sid] == roomInfo:
            return
        leave_room(rooms[request.sid])
        send("<b> " + names[request.sid] + " has left the room<b>",
             room=rooms[request.sid])
        winner = Game.removeUser(games[rooms[request.sid]], request.sid)
        if len(games[rooms[request.sid]]
               ['users']) == 0:  #Deletes game room if no-one is in it
            games.pop(rooms[request.sid])
        elif winner != None:
            send("<b>" + names[games[rooms[request.sid]][winner]] +
                 " has won the game!</b>",
                 room=rooms[request.sid])
    join_room(roomInfo)  #Places user in a room
    if roomInfo not in games:  #Create new game
        games[roomInfo] = Game.newGame()
    Game.addUser(games[roomInfo], request.sid)
    rooms[request.
          sid] = roomInfo  #Sets room of user in a dictionary for later use
    emit('joinRoom', roomInfo)
    emit('gameUpdate', games[roomInfo]['board'])
    send("<b> " + names[request.sid] + " joined " + roomInfo + "<b>",
         room=roomInfo)
Exemplo n.º 2
0
def play(board, save_normalized_matrix=True):
    """
    Parameters
    ----------
    board : numpy.array
    save_normalized_matrix : bool
        Whether to save normalized (log2 transformed) or original matrix.

    Returns
    -------
    collections.namedtuple
        Game with recorded steps.
    """

    steps = []
    render_board(board)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key in POSSIBLE_ACTIONS:
                    matrix = board.normalized_matrix if save_normalized_matrix else board.matrix
                    action = POSSIBLE_ACTIONS[event.key]
                    moved = board.move(action)

                    if moved:
                        print()
                        print(board.matrix)
                        print("SCORE:", board.score, "\tSTEP:",
                              board.n_steps_valid, "\tHIGHEST VALUE:",
                              board.highest_value)
                        steps.append(
                            Step(matrix=matrix,
                                 action=action,
                                 action_encoded=encode_action(action)))
                        render_board(board)

                        if board.is_gameover():
                            print("GAME OVER!")
                            return Game(steps=steps,
                                        score=board.score,
                                        random_seed=board.random_seed,
                                        is_gameover=True)
                    else:
                        print("\nCannot move to this direction!")
                elif event.key == pygame.K_q:
                    screen.fill(BLACK)
                    return Game(steps=steps,
                                random_seed=board.random_seed,
                                is_gameover=False)
                elif event.key == pygame.K_p:
                    screen.fill(BLACK)
                    return "quit"

        clock.tick(60)
        pygame.display.flip()
Exemplo n.º 3
0
def chooseWord(index):
    currGame = games[rooms[request.sid]]
    if (request.sid != currGame['order'][currGame['currDrawer']]
            or currGame['currWord'] != ''):
        return
    Game.chooseWord(currGame, index)
    currGame['timerTime'] = currGame['maxTime']  #Start drawing
    emit('startDrawing')
    send('<b>You have chosen ' + currGame['currWord'] + '</b>')
    currGame['currLines'] = []
    emit('clearBoard', None, broadcast=True, room=rooms[request.sid])
    emit('untint', broadcast=True, room=rooms[request.sid])
Exemplo n.º 4
0
 def get(self, game_id, player_id, x, y):
     self.response.headers['Content-Type'] = 'text/plain'
     game = Game.get_by_id(game_id)
     if not game:
         self.response.status = 412
         self.response.write(self.response.status)
         return
     p = game.player(player_id)
     Cache.setPos(game_id, player_id, x, y)
     self.response.write(p.output())
Exemplo n.º 5
0
 def get(self, game_id, player_id):
     game = Game.get_by_id(game_id)
     if not game:
         self.response.status = 404
         self.response.write(self.response.status)
         return
     player = game.player(player_id)
     self.response.headers['Content-Type'] = 'text/plain'
     self.response.status = 200
     self.response.out.write(player.seed)
Exemplo n.º 6
0
def joinRoom(roomID):
    if len(roomID) == 0:
        return
    if request.sid in rooms:  #Checks if the user is already in a room
        if rooms[request.sid] == roomID:
            return
        leave_room(rooms[request.sid])
        if len(games[rooms[request.sid]]
               ['players']) == 0:  #Deletes game room if no-one is in it
            games.pop(rooms[request.sid])
    if roomID not in games:  #Create new game
        if roomID in savedgameinfo:
            games[roomID] = Game.newGame(
                request.sid,
                maxTime=savedgameinfo[roomID]['maxTime'],
                maxRounds=savedgameinfo[roomID]['maxRounds'])
            savedgameinfo.pop(roomID)
        else:
            games[roomID] = Game.newGame(request.sid)
        emit('yourturn', games[roomID]['offeredWords'])
    else:
        Game.addUser(games[roomID], request.sid)
        #dbu.agame(session['username'],games[roomID])
    join_room(roomID)  #Places user in a room
    rooms[
        request.sid] = roomID  #Sets room of user in a dictionary for later use
    emit('joinRoom', roomID)
    emit('newPlayer',
         names[request.sid],
         broadcast=True,
         include_self=False,
         room=roomID)
    scoresToSend = {}
    for i in games[roomID]['points'].keys(
    ):  #Maps request.sids to the corresponding name before sending
        scoresToSend[names[i]] = games[roomID]['points'][i]
    emit('updateScores', scoresToSend)
    emit('highlightDrawer',
         names[games[roomID]['order'][games[roomID]['currDrawer']]])
    send('<b>' + names[request.sid] + ' has joined the room</b>',
         broadcast=True,
         room=roomID)
Exemplo n.º 7
0
 def get(self, game_id, pid):
     key = ".".join([game_id, pid])
     game = Game.get_by_id(game_id)
     if key in [p.id() for p in game.players]:
         game.remove_player(key)
         return webapp2.redirect("/%s/players" % game_id)
     else:
         self.response.headers['Content-Type'] = 'text/plain'
         self.response.status = 404
         self.response.out.write("player %s not in %s" %
                                 (key, game.players))
Exemplo n.º 8
0
 def get(self, game_id, player_id, signal):
     self.response.headers['Content-Type'] = 'text/plain'
     game = Game.get_by_id(game_id)
     if not game:
         self.response.status = 412
         self.response.write(self.response.status)
         return
     p = game.player(player_id)
     p.signal_send(signal)
     self.response.status = 200
     self.response.write("sent")
Exemplo n.º 9
0
 def get(self):
     self.response.headers['Content-Type'] = 'text/html'
     games = Game.query().fetch()
     if len(games):
         self.response.write('<html><body><pre>Active games:\n' + "\n".join([
             "<a href='/%s/history'>Game #%s</a> (<a href='/%s/map'>(Map)</a>):\n\t%s (Last update: %s ago)"
             % (game.key.id(), game.key.id(), game.key.id(), game.summary(),
                datetime.now() - game.last_update) for game in sorted(
                    games, key=lambda x: x.last_update, reverse=True)
         ]) + "</pre></body></html>")
     else:
         self.response.write('<html><body>No active games...</body></html>')
Exemplo n.º 10
0
def nextTurn(currGame, roomID):
    #guessedCorrectly.remove(request.sid)
    currGame['timerTime'] = 5  #Time a player has to choose a word
    socketio.emit('notyourturn',
                  room=currGame['order'][currGame['currDrawer']])
    Game.nextUser(currGame)
    socketio.emit('yourturn',
                  currGame['offeredWords'],
                  room=currGame['order'][currGame['currDrawer']])
    socketio.emit('highlightDrawer',
                  names[currGame['order'][currGame['currDrawer']]],
                  room=roomID)
    socketio.send("<b>It is your turn to draw!</b>",
                  room=currGame['order'][currGame['currDrawer']])
    scoresToSend = {}
    for i in currGame['points'].keys(
    ):  #Maps request.sids to the corresponding name before sending
        scoresToSend[names[i]] = currGame['points'][i]
    socketio.emit('updateScores', scoresToSend, room=roomID)
    socketio.emit('tint', room=roomID)
    currGame['guessedCorrectly'] = set()
Exemplo n.º 11
0
def countdown():
    global continueTimer, timerTime
    if continueTimer:
        threading.Timer(1, countdown).start()
        gamesCopy = list(
            games
        )  #Used because gamesCopy will not be modified as the for loop is executed
        #Execute the following tasks every second
        for roomID in gamesCopy:
            try:
                currGame = games[roomID]
                # print(currGame['order'], currGame['currDrawer'], currGame['players'])
                currGame['timerTime'] -= 1
                if currGame['timerTime'] <= -1:
                    # print(currGame['gameState'])
                    if currGame[
                            'gameState'] == Game.DRAWING:  #Executed when time runs out as a player is drawing
                        nextTurn(currGame, roomID)
                    elif currGame[
                            'gameState'] == Game.CHOOSING:  #Executed when time runs out as a player is choosing a word
                        Game.chooseWord(currGame, None)
                        currGame['guessedCorrectly'] = set()
                        currGame['timerTime'] = currGame[
                            'maxTime']  #Start drawing
                        socketio.send(
                            '<b>You have chosen ' + currGame['currWord'] +
                            '</b>',
                            room=currGame['order'][currGame['currDrawer']])
                        socketio.emit(
                            'startDrawing',
                            room=currGame['order'][currGame['currDrawer']])
                        currGame['currLines'] = []
                        socketio.emit('clearBoard', None, room=roomID)
                        socketio.emit('untint', room=roomID)
                # print(games[roomID]['timerTime'])
                socketio.emit('updateTimer',
                              currGame['timerTime'],
                              room=roomID)
            except:
                continue
Exemplo n.º 12
0
    def get(self, game_id):
        game = Game.get_by_id(game_id)
        outlines = []
        for p in game.get_players():
            outlines.append("Player %s: %s" % (p.key.id(), p.bitfields))
            outlines.append("\t\t" + "\n\t\t".join([
                hl.print_line(game.start_time) for hl in p.history
                if hl.pickup().share_type != ShareType.NOT_SHARED
            ]))

        self.response.headers['Content-Type'] = 'text/plain'
        self.response.status = 200
        self.response.out.write("\n".join(outlines))
Exemplo n.º 13
0
 def get(game_id, self):
     self.response.headers['Content-Type'] = 'text/plain'
     if int(game_id) < 1000:
         self.response.status = 403
         self.response.write("No.")
     game = Game.get_by_id(game_id)
     if game:
         delete_game(game)
         self.response.status = 200
         self.response.write("All according to daijobu")
     else:
         self.response.status = 401
         self.response.write("The game... was already dead...")
Exemplo n.º 14
0
 def get(self, game_id):
     game = Game.get_by_id(game_id)
     hist = Cache.getHist(game_id)
     if not hist:
         self.response.status = 404
         self.response.write(self.response.status)
         return
     self.response.headers['Content-Type'] = 'text/plain'
     self.response.status = 200
     self.response.out.write("|".join([
         "%s:%s" % (p, ",".join([str(h.coords) for h in hls]))
         for p, hls in hist.iteritems()
     ]))
Exemplo n.º 15
0
Arquivo: app.py Projeto: Kebin-Lin/STP
def makeMove(move):
    currGame = games[rooms[request.sid]]
    if currGame['end']:  #Executes if the game is already over
        currGame['board'] = '         '
        currGame['end'] = False
        emit('gameUpdate', currGame['board'], room=rooms[request.sid])
        return
    countx = currGame['board'].count('x')
    counto = currGame['board'].count('o')
    mover = 'x' if countx == counto else 'o'
    if currGame[mover] != request.sid:
        return
    Game.makeMove(currGame, int(move[-1]) % 9, mover)
    outcome = Game.checkStatus(currGame)
    emit('gameUpdate', currGame['board'], room=rooms[request.sid])
    if outcome != None:
        if outcome == "Draw":
            send("<b>This game has resulted in a draw</b>",
                 room=rooms[request.sid])
        else:
            send("<b>" + names[currGame[outcome]] + " has won the game!</b>",
                 room=rooms[request.sid])
        currGame['end'] = True
Exemplo n.º 16
0
def message(msg, methods=['GET', 'POST']):
    #print("Message " + msg)
    global currWord  # TESTING
    if request.sid not in rooms:
        return
    currGame = games[rooms[request.sid]]
    currWord = currGame['currWord']
    #currWord = word.randword() # TESTING
    if len(msg) != 0:
        msg = msg[:200].replace('<', '&lt;').replace(
            '>', '&gt;'
        )  #Caps message length at 200 characters and replaces HTML shenanigans
        if (request.sid != currGame['order'][currGame['currDrawer']]):
            guess = msg
            if request.sid in currGame['guessedCorrectly']:
                send("You can't guess again.")
                return
            if guess.lower() != currWord:
                send("<b>" + names[request.sid] + ":</b> " + msg,
                     broadcast=True)
            else:
                Game.addPoints(currGame, request.sid)  #Add points to guesser
                Game.addPoints(currGame,
                               currGame['order'][currGame['currDrawer']],
                               drawer=True)  #Add points to drawer
                send("<b>Correct!!!</b>")
                if len(currGame['guessedCorrectly']) == 0:
                    currGame['timerTime'] = currGame['timerTime'] // 2 + 1
                currGame['guessedCorrectly'].add(request.sid)
                if len(currGame['guessedCorrectly']) >= len(
                        currGame['players']
                ) - 1:  #Skip turn if everyone has guessed correctly
                    send("Everyone guessed the word correctly", broadcast=True)
                    nextTurn(currGame, rooms[request.sid])
        else:
            send("<b>You can't chat while drawing.</b>")
Exemplo n.º 17
0
Arquivo: app.py Projeto: Kebin-Lin/STP
def disconn():  #Executed when a client disconnects from the server
    try:
        send("<b> " + names[request.sid] + " has left the room<b>",
             room=rooms[request.sid])
        winner = Game.removeUser(games[rooms[request.sid]], request.sid)
        if len(games[rooms[request.sid]]
               ['users']) == 0:  #Deletes game room if no-one is in it
            games.pop(rooms[request.sid])
        elif winner != None:
            send("<b>" + names[games[rooms[request.sid]][winner]] +
                 " has won the game!</b>",
                 room=rooms[request.sid])
        rooms.pop(request.sid)
    except:  #Fallback in case user leaves before joining a room
        pass
    names.pop(request.sid)
Exemplo n.º 18
0
def disconn():  #Executed when a client disconnects from the server
    if request.sid in rooms:
        currGame = games[rooms[request.sid]]
        #dbu.rgame(session['username'])
        currDrawerRemoved = Game.removeUser(games[rooms[request.sid]],
                                            request.sid)
        if len(currGame['players']
               ) == 0:  #Deletes game room if no-one is in it
            games.pop(rooms[request.sid])
        elif currDrawerRemoved and len(
                currGame['order']) > currGame['currDrawer']:
            socketio.emit('yourturn',
                          currGame['offeredWords'],
                          room=currGame['order'][currGame['currDrawer']])
            emit('highlightDrawer',
                 names[currGame['order'][currGame['currDrawer']]],
                 broadcast=True,
                 room=rooms[request.sid])
        socketio.send('<b>' + names[request.sid] + ' has left the room</b>')
        emit('playerLeave',
             names[request.sid],
             broadcast=True,
             room=rooms[request.sid])
        rooms.pop(request.sid)
    elif request.sid in lobbyrooms:
        currLobby = lobbies[lobbyrooms[request.sid]]
        currLobby.remove(request.sid)
        if len(currLobby) == 0:
            lobbies.pop(lobbyrooms[request.sid])
        else:
            emit('playerLeave',
                 names[request.sid],
                 broadcast=True,
                 room=lobbyrooms[request.sid],
                 namespace='/lobby')
            if request.sid == lobbyLeaders[lobbyrooms[request.sid]]:
                lobbyLeaders[lobbyrooms[request.sid]] = random.sample(
                    currLobby, 1)[0]
                emit('newLeader',
                     names[lobbyLeaders[lobbyrooms[request.sid]]],
                     broadcast=True,
                     room=lobbyrooms[request.sid],
                     namespace='/lobby')
Exemplo n.º 19
0
 def get(self, game_id):
     self.response.headers['Content-Type'] = 'text/plain'
     game = Game.get_by_id(game_id)
     if game:
         output = game.summary()
         output += "\nHistory:"
         for hl, pid in sorted(
             [(h, p.key.id().partition('.')[2]) for p in game.get_players()
              for h in p.history
              if h.pickup().share_type != ShareType.NOT_SHARED],
                 key=lambda x: x[0].timestamp,
                 reverse=True):
             output += "\n\t\t Player %s %s" % (
                 pid, hl.print_line(game.start_time))
         self.response.status = 200
         self.response.write(output)
     else:
         self.response.status = 404
         self.response.out.write("Game %s not found!" % game_id)
Exemplo n.º 20
0
    def play_single_game(strategy="random", opts=3):
        # Get show-time elements
        game = Game.random(number_of_options=opts)
        host = Host(manage_game=game)
        guest = Guest()
        print(game)

        # Ask guest to choose a door
        first_choice = guest.choose(options=host.show_options(),
                                    strategy=Guest.Strategy.RANDOM)
        print("(t=1) Guest's first choice: {}".format(first_choice))
        # Host reveals another door
        revealed_door = host.reveal(given_guest_choice=first_choice)
        print("(t=2) Host reveals door with a goat: {}".format(revealed_door))
        # Final guest choice
        final_choice = guest.choose(options=host.show_options(),
                                    strategy=strategy)
        print("(t=3) Guest's final choice: {}".format(final_choice))
        # Host ends game!
        result = host.end_game(final_choice=final_choice)
        print("(t=4) Game result {}".format(result))
Exemplo n.º 21
0
 def get(self, game_id, player_id, coords, kind, id):
     game = Game.get_by_id(game_id)
     if not game:
         self.response.status = 412
         self.response.write(self.response.status)
         return
     remove = paramFlag(self, "remove")
     coords = int(coords)
     if coords in coord_correction_map:
         coords = coord_correction_map[coords]
     if coords not in all_locs:
         print "Coord mismatch error! %s not in all_locs or correction map. Sync %s.%s, pickup %s|%s" % (
             coords, game_id, player_id, kind, id)
     dedup = not paramFlag(
         self, "override") and not remove and game.mode in DEDUP_MODES
     pickup = Pickup.n(kind, id)
     if not pickup:
         print "ERROR: Couldn't build pickup %s|%s" % (kind, id)
         self.response.status = 406
         return
     self.response.status = game.found_pickup(player_id, pickup, coords,
                                              remove, dedup)
     self.response.write(self.response.status)
Exemplo n.º 22
0
    def get(self, game_id, player_id):
        seedlines = []
        lines = paramVal(self, "seed").split(",")
        game = Game.get_by_id(game_id)
        hist = Cache.getHist(game_id)
        if not hist:
            Cache.setHist(game_id, player_id, [])
        pos = Cache.getPos(game_id)
        if not pos:
            Cache.setPos(game_id, player_id, 0, 0)
        if not game:
            flags = lines[0].split("|")
            mode_opt = [f[5:] for f in flags if f.lower().startswith("mode=")]
            shared_opt = [
                f[7:].split(" ") for f in flags
                if f.lower().startswith("shared=")
            ]
            mode = mode_opt[0].lower() if mode_opt else None
            if mode:
                mode = mode_map[mode] if mode in mode_map else int(mode)

            shared = shared_opt[0] if shared_opt else None
            game = get_new_game(_mode=mode, _shared=shared, id=game_id)
        for l in lines[1:]:
            line = l.split("|")
            if len(line) < 3:
                print "ERROR: malformed seed line %s, skipping" % l
            else:
                seedlines.append("%s:%s" %
                                 (line[0], Pickup.name(line[1], line[2])))
        player = game.player(player_id)
        player.seed = "\n".join(seedlines)
        player.put()
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.status = 200
        self.response.out.write("ok")
Exemplo n.º 23
0
def gen_games(n_games,
              job_id,
              n_jobs,
              weights=None,
              min_score=0,
              min_tile_value=0,
              verbose=0):
    games = []
    i = 0

    if not weights:
        weights = [0.25, 0.25, 0.25, 0.25]

    play_for_score = False
    play_for_tile = False
    play_for_both = False

    if min_score and not min_tile_value:
        play_for_score = True
    if min_tile_value and not min_score:
        play_for_tile = True
    if min_score and min_tile_value:
        play_for_both = True
    if not min_score and not min_tile_value:
        raise ValueError("min_score or min_tile_value or both must be > 0!")

    try:
        while len(games) != n_games:
            env = GymBoard()
            r = np.random.RandomState()
            steps = []

            while True:
                matrix = env.matrix
                action = r.choice(actions, p=weights)
                moved = env.move(action)

                if moved:
                    steps.append(
                        Step(matrix=matrix,
                             action=action,
                             action_encoded=encode_action(action)))

                if env.is_gameover():
                    if (play_for_score and env.score >= min_score) or \
                       (play_for_tile and np.any(env.matrix >= min_tile_value)) or \
                       (play_for_both and env.score >= min_score and np.any(env.matrix >= min_tile_value)):
                        if verbose:
                            print("\tchunk {}/{}...game {}/{}".format(
                                job_id, n_jobs, i + 1, n_games))
                        games.append(
                            Game(steps=steps,
                                 score=env.score,
                                 random_seed=env.random_seed,
                                 is_gameover=True))
                        i += 1
                    break
    except KeyboardInterrupt:
        pass

    return games
Exemplo n.º 24
0
        board = g.ret_board()
        print(board)
        row, col = P1.play(board, free)
        g.update_spot(row, col, P1sym)
        board = g.ret_board()
        print(board)
        if (g.check_victory(P1) == P1sym):
            AI_1.AI_update_state_record('loss')
            break
        free = g.get_play_spots()
        if len(free) == 0:
            print("Game Drawn")
            AI_1.AI_update_state_record('draw')
            break
        bcop = np.copy(board)
        row, col = AI_1.play(bcop, free)
        g.update_spot(row, col, AIsym)
        if (g.check_victory(AI_1) == AIsym):
            AI_1.AI_update_state_record('win')
            break


g = Game()
print("game1")
start_game(g)
g.reset_board()
print("game2")
start_game(g)
print("printing State Record after 2 games")
print(Player.state_record)
Exemplo n.º 25
0
    def post(self):
        mode = self.request.get("mode").lower()
        pathdiff = self.request.get("pathdiff").lower()
        variations = set([
            x for x in [
                "forcetrees", "hardmode", "notp", "starved", "ohko",
                "noplants", "discmaps", "0xp", "nobonus"
            ] if self.request.get(x)
        ])
        logic_paths = [
            x for x in [
                "normal", "speed", "lure", "speed-lure", "dboost",
                "dboost-light", "dboost-hard", "cdash", "dbash", "extended",
                "lure-hard", "timed-level", "glitched", "extended-damage",
                "extreme"
            ] if self.request.get(x)
        ]
        playercount = self.request.get("playerCount")
        syncid = self.request.get("syncid")
        syncmode = self.request.get("syncmode").lower()
        syncmode = mode_map[syncmode] if syncmode in mode_map else int(
            syncmode)
        seed = self.request.get("seed")
        share_types = [f for f in share_map.keys() if self.request.get(f)]

        game_id = False
        if not seed:
            seed = str(random.randint(10000000, 100000000))
        if syncid:
            syncid = int(syncid)
            oldGame = Game.get_by_id(syncid)
            if oldGame != None:
                if syncid > 999:
                    delete_game(oldGame)
                    game_id = get_new_game(_mode=syncmode,
                                           _shared=share_types,
                                           id=syncid).key.id()
                else:
                    self.response.status = 405
                    self.response.write(
                        "Seed ID in use! Leave blank or pick a different number."
                    )
                    return
            else:
                game_id = get_new_game(_mode=syncmode,
                                       _shared=share_types,
                                       id=syncid).key.id()

        if not game_id:
            game_id = get_new_game(_mode=syncmode,
                                   _shared=share_types).key.id()

        urlargs = ["m=%s" % mode]
        urlargs.append("vars=%s" % "|".join(variations))
        urlargs.append("lps=%s" % "|".join(logic_paths))
        urlargs.append("s=%s" % seed)
        urlargs.append("pc=%s" % playercount)
        urlargs.append("pd=%s" % pathdiff)
        urlargs.append("shr=%s" % "+".join(share_types))
        urlargs.append("sym=%s" % syncmode)
        urlargs.append("gid=%s" % game_id)
        for flg in ["dk", "ev", "sk", "rb", "tp", "hot", "wild"]:
            if self.request.get(flg):
                urlargs.append("%s=1" % flg)
        self.response.headers['Content-Type'] = 'text/html'
        out = "<html><body>"
        url = '/getseed?%s' % "&".join(urlargs)
        out += "<div><a target='_blank' href='%s&p=spoiler'>Spoiler</a></div>" % url
        out += "<div><a target='_blank' href='/%s/map?paths=%s'>Map</a></div>" % (
            game_id, "+".join(logic_paths))
        out += "<div><a target='_blank' href='/%s/history'>History</a></div>" % game_id

        for i in range(1, 1 + int(playercount)):
            purl = url + "&p=%s" % i
            out += "<div>Player %s: <a target='_blank' href=%s>%s%s</a></div>" % (
                i, purl, base_site, purl)
        out += "</body></html>"
        self.response.out.write(out)