2

For a school project, I'm creating a game that has a score system, and I would like to create some sort of leaderboard. Once finished, the teachers will upload it to a shared server where other students can download a copy of the game, but unfortunately students can't save to that server; if we could, leaderboards would be a piece of cake. There would at most be a few hundred scores to keep track of, and all the computers have access to the internet.

I don't know much about servers or hosting, and I don't know java, html, or any other language commonly used in web development, so other related questions don't really help. My game prints the scoring information to a text file, and from there I don't know how to get it somewhere online that everyone can access.

Is there a way to accomplish such a task with just python?

Here I have the code for updating a leaderboard file (assuming it would just be a text file) once I have the scores. This would assume that I had a copy of the leaderboard and the score file in the same place.

This is the format of my mock-leaderboard (Leaderboards.txt):

Leaderboards

1) JOE  10001
2) ANA  10000
3) JAK  8400
4) AAA  4000
5) ABC  3999

This is what the log-file would print - the initials and score (log.txt):

ABC
3999

Code (works for both python 2.7 and 3.3):

def extract_log_info(log_file = "log.txt"):
    with open(log_file, 'r') as log_info:
        new_name, new_score = [i.strip('\n') for i in log_info.readlines()[:2]]

    new_score = int(new_score)
    return new_name, new_score

def update_leaderboards(new_name, new_score, lb_file = "Leaderboards.txt"):
    cur_index = None
    with open(lb_file, 'r') as lb_info:
        lb_lines = lb_info.readlines()
        lb_lines_cp = list(lb_lines) # Make a copy for iterating over
        for line in lb_lines_cp:
            if 'Leaderboards' in line or line == '\n':
                continue

            # Now we're at the numbers
            position, name, score = [ i for i in line.split() ]

            if new_score > int(score):
                cur_index = lb_lines.index(line)
                cur_place = int(position.strip(')'))
                break

        # If you have reached the bottom of the leaderboard, and there
        # are no scores lower than yours
        if cur_index is None:
            # last_place essentially gets the number of entries thus far
            last_place = int(lb_lines[-1].split()[0].strip(')'))
            entry = "{}) {}\t{}\n".format((last_place+1), new_name, new_score)
            lb_lines.append(entry)
        else: # You've found a score you've beaten
            entry = "{}) {}\t{}\n".format(cur_place, new_name, new_score)
            lb_lines.insert(cur_index, entry)

            lb_lines_cp = list(lb_lines) # Make a copy for iterating over
            for line in lb_lines_cp[cur_index+1:]:
                position, entry_info = line.split(')', 1)
                new_entry_info = str(int(position)+1) + ')' + entry_info
                lb_lines[lb_lines.index(line)] = new_entry_info

    with open(lb_file, 'w') as lb_file_o:
        lb_file_o.writelines(lb_lines)


if __name__ == '__main__':
    name, score = extract_log_info()
    update_leaderboards(name, score)

Some more info:

  • The score would be less than 1 000 000
  • Ideally, the solution would just be some code external to the game, so that I would just make an executable that the user would run after they've finished
  • I know it doesn't sound very secure - and it isn't - but that's ok, it's doesn't need to be hackproof
JCKE
  • 386
  • 5
  • 15
  • 3
    Python can accomplish this, however please make your question more specific so that it can be answered. – Garrett Nov 24 '14 at 20:29
  • 1
    I've updated it so you can see what kind of information the game would spit out. Also, there's a mock-leaderboard – JCKE Nov 24 '14 at 20:31
  • You're asking for someone to design and build your system from a vague spec. If you want that, you have to hire a consultant. Otherwise, you are going to have to go learn the basics, read a tutorial on web services, and come back when you get stuck on something specific. – abarnert Nov 24 '14 at 20:34
  • Also, a link to external code isn't helpful. Put any relevant code and data—or, better, a [Minimal, Complete, Verifiable Example](http://stackoverflow.com/help/mcve)—in your question. That way, people looking for questions to answer, or looking for answers to similar questions, will see it in searches. And the code will still be here when someone else has a similar problem two years from now. – abarnert Nov 24 '14 at 20:36
  • I've included the code and data, although I can't really minimize the code since I don't have any errors with it – JCKE Nov 24 '14 at 20:48

1 Answers1

2

The easiest is probably to just use MongoDB or something (MongoDB is a NoSQL type database that allows you to save dictionary data easily...)

You can use the free account at https://mongolab.com (that should give you plenty of space).

You will need pymongo as well pip install pymongo.

Then you can simply save records there:

from pymongo import MongoClient, DESCENDING

uri = "mongodb://test1:test1@ds051990.mongolab.com:51990/joran1"
my_db_cli = MongoClient(uri)
db = my_db_cli.joran1  # select the database ... 

my_scores = db.scores  # this will be created if it doesn't exist!
# add a new score
my_scores.insert({"user_name": "Leeeeroy Jenkins", "score": 124, "time": "11/24/2014 13:43:22"})
my_scores.insert({"user_name": "bob smith", "score": 88, "time": "11/24/2014 13:43:22"})

# get a list of high scores (from best to worst)
print(list(my_scores.find().sort("score", DESCENDING)))

Those credentials will actually work if you want to test the system (keep in mind I added leeroy a few times).

KetZoomer
  • 2,701
  • 3
  • 15
  • 43
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • This looks like something I'll probably be able to use, thanks! Sorry if the question was too vauge, I'm still new. – JCKE Nov 24 '14 at 20:57