<commit_before># Super hacky scripts used to analyse some basic Spelunky data.
# Plenty of copy+paste and all the good stuff.

import argparse
from common import *
from config import *
from process import *
from turtle_common import *

screen_width = 800
screen_height = 800
padding = 20
zoom = 1

parser = argparse.ArgumentParser()
parser.add_argument('file', help='Data file path.')
parser.add_argument('--raw', action='store_true', default=False,
    help='Load a raw file instead of json?')

args = parser.parse_args()

game_runs = load_raw_run(args.file) if args.raw else load_run(args.file)


def is_death_level(i, levels):
    return i != 15 and i == len(levels) - 1

def no_deaths(levels):
    """Filter out level plays where the player died."""
    for i, level in enumerate(levels):
        if is_death_level(i, levels):
            continue
        yield (i, level)

def keycode_to_name(code):
    if code == SPRINT:
        return 'sprint'
    if code == UP:
        return 'up'
    if code == DOWN:
        return 'down'
    if code == LEFT:
        return 'left'
    if code == RIGHT:
        return 'right'
    if code == JUMP:
        return 'jump'
    if code == BOMB:
        return 'bomb'
    if code == WHIP:
        return 'whip'
    if code == USE:
        return 'use'
    if code == BUY:
        return 'buy'
    if code == ROPE:
        return 'rope'
    return str(code)

def print_key_code_pair(k, v, format = "%s: %s"):
    print(format % (keycode_to_name(k), v))

def print_key_map(map, line = "%s: %s"):
    for k, v in map.iteritems():
        print_key_code_pair(k, v, format=line)

def process_run_data(raw_levels):
    levels = []
    for i, raw_level in enumerate(raw_levels):
        level = []
        state = {}
        for command in raw_level:
            code = command['code']
            end = command['date']
            if command['up'] and code in state:
                start = state[code]
                del state[code]
                level.append({
                    'start': end,
                    'end': end,
                    'duration': end - start,
                    'key': code
                })
            elif not command['up'] and not code in state:
                state[code] = end
        
        levels.append({
            'area': get_area(i),
            'start': level[0]['start'],
            'end': level[-1]['end'],
            'duration': level[-1]['end'] - level[0]['start'],
            'events': level
        })
    
    # Remove initial actions before movement (pressed to skip transition)
    for level in levels:
        events = level['events']
        while len(events) > 0 and events[0]['key'] in ACTIONS:
            del events[0]
    
    return {
        'start': levels[0]['start'],
        'end': levels[-1]['end'],
        'duration': levels[-1]['end'] - levels[0]['start'],
        'levels': levels
    }
    

def load_raw_run_data(path):
    with open(path, 'r') as f:
        runs = split_runs(f.readlines())
    return [process_run_data(run) for run in runs]

# Build a list of just keypresses
all_run_data = load_raw_run_data('raw_data/combined.txt')

if True:
    print("\nAvg duration of movement keypresses:")
    counts = {}
    total_times = {}
    
    for run in all_run_data:
        levels = run['levels']
        for i, level in enumerate(levels):
            for evt in level['events']:
                key = evt['key']
                if not key in MOVEMENTS:
                    continue
                if not key in counts:
                    counts[key] = 0
                    total_times[key] = 0
                counts[key] += 1
                total_times[key] += evt['duration'].total_seconds()

    avgs = {}

    for key, sum in total_times.iteritems():
        avgs[key] = float(sum) / counts[key]
    
    print("counts")
    print_key_map(counts)
    print('\navgs')
    print_key_map(avgs)

if True:
    print("\nAvg duration of movement keypresses per area:")
    counts = [{}, {}, {}, {}, {}]
    total_times = [{}, {}, {}, {}, {}]
    
    for run in all_run_data:
        levels = run['levels']
        for i, level in enumerate(levels):
            area = get_area(i)
            for evt in level['events']:
                key = evt['key']
                if not key in MOVEMENTS:
                    continue
                if not key in counts[area]:
                    counts[area][key] = 0
                    total_times[area][key] = 0
                counts[area][key] += 1
                total_times[area][key] += evt['duration'].total_seconds()

    for area, keys in enumerate(total_times):
        avgs = {}
        for key, sum in keys.iteritems():
            avgs[key] = float(sum) / counts[area][key]
    
        print(area)
        print_key_map(avgs)
        print("")


if False:
    print("\nDeath duration data")
    
    target_area = 2
    
    for run in all_run_data:
        levels = run['levels']
        for i, level in enumerate(levels):
            area = get_area(i)
            #if area != target_area:
            #    continue
            if not is_death_level(i, levels):
                continue
            print("%s, %s" % (area, level['duration'].total_seconds()))
            
if True:
    print("\nAvg actions per area (no death):")
    counts = [0] * 5
    moves = [0] * 5
<commit_msg>Added avg movement per area keypress.<commit_after># Super hacky scripts used to analyse some basic Spelunky data.
# Plenty of copy+paste and all the good stuff.

import argparse
from common import *
from config import *
from process import *
from turtle_common import *

screen_width = 800
screen_height = 800
padding = 20
zoom = 1

parser = argparse.ArgumentParser()
parser.add_argument('file', help='Data file path.')
parser.add_argument('--raw', action='store_true', default=False,
    help='Load a raw file instead of json?')

args = parser.parse_args()

game_runs = load_raw_run(args.file) if args.raw else load_run(args.file)


def is_death_level(i, levels):
    return i != 15 and i == len(levels) - 1

def no_deaths(levels):
    """Filter out level plays where the player died."""
    for i, level in enumerate(levels):
        if is_death_level(i, levels):
            continue
        yield (i, level)

def keycode_to_name(code):
    if code == SPRINT:
        return 'sprint'
    if code == UP:
        return 'up'
    if code == DOWN:
        return 'down'
    if code == LEFT:
        return 'left'
    if code == RIGHT:
        return 'right'
    if code == JUMP:
        return 'jump'
    if code == BOMB:
        return 'bomb'
    if code == WHIP:
        return 'whip'
    if code == USE:
        return 'use'
    if code == BUY:
        return 'buy'
    if code == ROPE:
        return 'rope'
    return str(code)

def print_key_code_pair(k, v, format = "%s: %s"):
    print(format % (keycode_to_name(k), v))

def print_key_map(map, line = "%s: %s"):
    for k, v in map.iteritems():
        print_key_code_pair(k, v, format=line)

def process_run_data(raw_levels):
    levels = []
    for i, raw_level in enumerate(raw_levels):
        level = []
        state = {}
        for command in raw_level:
            code = command['code']
            end = command['date']
            if command['up'] and code in state:
                start = state[code]
                del state[code]
                level.append({
                    'start': end,
                    'end': end,
                    'duration': end - start,
                    'key': code
                })
            elif not command['up'] and not code in state:
                state[code] = end
        
        levels.append({
            'area': get_area(i),
            'start': level[0]['start'],
            'end': level[-1]['end'],
            'duration': level[-1]['end'] - level[0]['start'],
            'events': level
        })
    
    # Remove initial actions before movement (pressed to skip transition)
    for level in levels:
        events = level['events']
        while len(events) > 0 and events[0]['key'] in ACTIONS:
            del events[0]
    
    return {
        'start': levels[0]['start'],
        'end': levels[-1]['end'],
        'duration': levels[-1]['end'] - levels[0]['start'],
        'levels': levels
    }
    

def load_raw_run_data(path):
    with open(path, 'r') as f:
        runs = split_runs(f.readlines())
    return [process_run_data(run) for run in runs]

# Build a list of just keypresses
all_run_data = load_raw_run_data('raw_data/combined.txt')

if True:
    print("\nAvg duration of movement keypresses:")
    counts = {}
    total_times = {}
    
    for run in all_run_data:
        levels = run['levels']
        for i, level in enumerate(levels):
            for evt in level['events']:
                key = evt['key']
                if not key in MOVEMENTS:
                    continue
                if not key in counts:
                    counts[key] = 0
                    total_times[key] = 0
                counts[key] += 1
                total_times[key] += evt['duration'].total_seconds()

    avgs = {}

    for key, sum in total_times.iteritems():
        avgs[key] = float(sum) / counts[key]
    
    print("counts")
    print_key_map(counts)
    print('\navgs')
    print_key_map(avgs)

if True:
    print("\nAvg duration of movement keypresses per area:")
    counts = [{}, {}, {}, {}, {}]
    total_times = [{}, {}, {}, {}, {}]
    
    for run in all_run_data:
        levels = run['levels']
        for i, level in enumerate(levels):
            area = get_area(i)
            for evt in level['events']:
                key = evt['key']
                if not key in MOVEMENTS:
                    continue
                if not key in counts[area]:
                    counts[area][key] = 0
                    total_times[area][key] = 0
                counts[area][key] += 1
                total_times[area][key] += evt['duration'].total_seconds()

    for area, keys in enumerate(total_times):
        avgs = {}
        for key, sum in keys.iteritems():
            avgs[key] = float(sum) / counts[area][key]
    
        print(area)
        print_key_map(avgs)
        print("")
    
if True:
    print("\nPercent of time spent sprinting per area:")
    sprinting_time = [0] * 5
    total_time = [0] * 5
    
    for run in all_run_data:
        levels = run['levels']
        for i, level in enumerate(levels):
            area = get_area(i)
            total_times[area] += level['duration'].total_seconds()
            for evt in level['events']:
                key = evt['key']
                if key != SPRINT:
                    continue
                sprinting_time[area] += evt['duration'].total_seconds()

    for area, sprint_time in enumerate(sprinting_time):
        print_key_code_pair(area, float(sprint_time) / total_time[area])


if False:
    print("\nDeath duration data")
    
    target_area = 2
    
    for run in all_run_data:
        levels = run['levels']
        for i, level in enumerate(levels):
            area = get_area(i)
            #if area != target_area:
            #    continue
            if not is_death_level(i, levels):
                continue
            print("%s, %s" % (area, level['duration'].total_seconds()))
            
if True:
    print("\nAvg actions per area (no death):")
    counts = [0] * 5
    moves = [0] * 5

{'fraction_non_alphanumeric': 0.1253172311192789, 'fraction_numerical': 0.006300866369125755, 'mean_word_length': 1.8591443582687015, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1138551', 'n_tokens_mistral': 3580, 'n_tokens_neox': 3438, 'n_words': 987}