package Journal;

use feature "say";

use FindBin;
use File::Spec;
use Tie::Cfg;
use Data::Dumper;
use File::Copy;
use POSIX qw /strftime/;

sub load_configuration
{
    FindBin->again;
    my $path = File::Spec->catfile($FindBin::RealBin, "../config");
    tie my %config, "Tie::Cfg", READ=>$path, SEP=>"=";
    \%config;
}

sub get_root
{
    File::Spec->catfile($FindBin::RealBin, "..", shift);
}

sub get_greatest_index
{
    my $max = 0;
    my ($index, $name);
    for (@{(shift)})
    {
        if (/^[^.]/)
        {
            ($index, $name) = get_fields($_);
            if (int $index > $max)
            {
                $max = int $index;
            }
        }
    }
    $max;
}

sub get_fields
{
    shift =~ /^(0*\d+)(.*)/;
}

sub repad_paths
{
    my ($max, $paths, $root) = @_;
    my $length = length($max);
    my ($index, $name);
    for (@{$paths})
    {
        if (/^[^.]/)
        {
            ($index, $name) = get_fields($_);
            if (length($index) != $length)
            {
                move(File::Spec->catfile($root, $_),
                     File::Spec->catfile($root,
                                         sprintf("%0${length}d%s", int $index,
                                                 $name)));
            }
        }
    }
}

sub get_formatted_time
{
    strftime "%A, %B " . get_formatted_day() . ", %Y %H:%M %z", localtime;
}

sub get_formatted_day
{
    my $day = strftime "%e", localtime;
    $day =~ s/\s+//;
    my $suffix;
    if (($day >= 4 && $day <=20) || ($day >= 24 && $day <= 30))
    {
        $suffix = "th";
    }
    else
    {
        $suffix = ["st", "nd", "rd"]->[$day % 10 - 1]
    }
    $day . $suffix;
}

1;
if(!window.console){console={log:function(){}}}var SOURCE_PATH="/a-o/src/";var SYNTAX_SCROLL_STEP=500;var SYNTAX_SCROLL_INTERVAL=1600;A_O=function(){console.log(SOURCE_PATH);this.syntax=new A_O.Syntax();this.structures=new A_O.Structures()};A_O.include=function(b){var a=document.createElement("script");a.type="text/javascript";a.src=SOURCE_PATH+b;document.getElementsByTagName("head")[0].appendChild(a)};A_O.build_px=function(a){return a+"px"};A_O.Syntax=function(){this.loadElements();this.scroll()};A_O.Syntax.prototype.loadElements=function(){var a=document.getElementById("syntax");a.style.top=A_O.build_px(0);this.height=a.offsetHeight;this.parent=a.parentNode;this.original=a;this.duplicate()};A_O.Syntax.prototype.duplicate=function(){var a=this.original.cloneNode(true);this.parent.appendChild(a);this.clone=a;this.jump()};A_O.Syntax.prototype.jump=function(){var b=this.original;var c=this.height;var d=parseInt(b.style.top);var e=d+c;var a=e<0?e:0;b.style.top=A_O.build_px(a);this.clone.style.top=A_O.build_px(a+c)};A_O.Syntax.prototype.scroll=function(){var a=this;window.setInterval(function(){a.step()},SYNTAX_SCROLL_INTERVAL)};A_O.Syntax.prototype.step=function(){var c=SYNTAX_SCROLL_STEP;var b=this.original;var e=this.clone;var a=parseInt(b.style.top)-c;var d=parseInt(e.style.top)-c;b.style.top=A_O.build_px(a);e.style.top=A_O.build_px(d);if(d<0){this.jump()}};A_O.Structures=function(){this.loadElements();this.setHandlers()};A_O.Structures.prototype.loadElements=function(){var a=document.getElementById("menu");this.options=a.getElementsByTagName("a");this.structures=a.getElementsByTagName("img")};A_O.Structures.prototype.setHandlers=function(){var c=this.options;var b=this.structures.length-1;var e=this;var a=0;for(var d=0;d<c.length;d++){c[d].onmouseover=(function(f){return function(){e.displayStructure(f)}})(a++);if(a>b){a=0}}};A_O.Structures.prototype.displayStructure=function(a){var c=this.structures;var d;for(var b=0;b<c.length;b++){if(b==a){d=""}else{d="none"}c[b].style.display=d}};window.onload=function(){new A_O()};
<?php

function print_link_tag($path, $rel, $type=null)
{
   $path = resolve_uri_path($path);
   $tag = "<link rel=\"$rel\" ";
   if ($type)
   {
       $tag .= "type=\"$type\" ";
   }
   print_l($tag . "href=\"$path\"/>");
}

function resolve_uri_path($path)
{
   $path = str_replace($GLOBALS["system_root"] . "/", "/", $path);
   return join_paths($GLOBALS["uri_root"], $path);
}

function join_paths()
{
   return implode(DIRECTORY_SEPARATOR, func_get_args());
}

function print_l($string, $break=true)
{
   $end = $break ? "\n" : "";
   echo $string . $end;
}

function print_script_tag()
{
   $path = resolve_uri_path("src/A_O.js");
   print_l("<script src=\"$path\" type=\"text/javascript\"></script>");
}

function include_syntax()
{
   include choose_file("resource/syntax/index/*.html");
}

function choose_file($pattern)
{
   return random_element(glob(resolve_system_path($pattern)));
}

function resolve_system_path($path)
{
   return join_paths($GLOBALS["system_root"], $path);
}

function print_follow_buttons()
{
   echo "<a href=\"/feed.rss\">";
   print_image_tag("img/badges/rss.png", "", "rss", false);
   print_l("</a>");
   echo "<a href=\"http://twitter.com/Dometoerio/\">";
   print_image_tag("img/badges/twitter.png", "", "twitter", false);
   print_l("</a>");
}

function print_image_tag($path, $class="", $id="", $break=true, $style="",
                         $resolve=true, $alt="")
{
   if ($resolve)
   {
      $path = resolve_uri_path($path);
   }
   print_l("<img src=\"$path\" class=\"$class\" id=\"$id\" style=\"$style\" " .
           "alt=\"$alt\" />", $break);
}

function print_scanner_animation()
{
   $animation = resolve_uri_path(choose_file("img/scanner/animations/*.gif"));
   echo "<div style=\"background: url('$animation')\">&nbsp;</div>\n";
}

function random_element($list)
{
   return $list[rand(0, count($list) - 1)];
}

function build_random_ip_address()
{
   return rand(101, 199) . "." . rand(0, 255) . "." . rand(0, 255) . "." .
      rand(0, 255);
}

function get_visitors_ip_address()
{
   return $_SERVER["REMOTE_ADDR"];
}

function print_structures()
{
   $paths = glob(resolve_system_path("img/structures/*.png"));
   $visible = rand(0, count($paths) - 1);
   foreach ($paths as $ii => $path)
   {
      $style = ($ii == $visible) ? "" : "display: none";
      print_image_tag($path, "", "", true, $style);
   }
}

function print_divider()
{
   $animation = choose_file("img/scrollers/animations/192.gif");
   $path = resolve_uri_path($animation);
   echo "<div id=\"divider\" style=\"background: url('$path')\">" .
      "&nbsp;</div>\n";
}

function print_articles()
{
    $paths = get_article_paths();
    $journal_config = parse_ini_file(
        resolve_system_path("resource/journal/config"), true, INI_SCANNER_RAW);
    $date_field = $journal_config["header"]["date_field"];
    foreach ($paths as $path)
    {
        $printed_body_line = false;
        print_l("<div class=\"entry\">");
        print_l("<div class=\"info\">");
        foreach (file($path) as $line)
        {
            if (preg_match("/^<!--/", $line))
            {
                if (preg_match("/^<!--[[:space:]]*$date_field/", $line))
                {
                    print_l("<span class=\"time\">" . get_date($line) .
                            "</span><span class=\"permalink\"><a href=\"/" .
                            get_article_id_from_path($path) .
                            "\">&diams;</a></span>");
                }
            }
            else
            {
                if (!$printed_body_line)
                {
                    print_l("</div>");
                    print_l("<div class=\"body\">");
                    $printed_body_line = true;
                }
                echo $line;
            }
        }
        print_l("</div>\n</div>");
    }
}

function get_article_paths()
{
    preg_match("/^(\/v)*(\/draft)*\/([0-9]+)\/*$/", $_SERVER["REQUEST_URI"],
               $matches);
    $expression = ".*\.html";
    if (count($matches) > 2 and $matches[2])
    {
        $root = resolve_system_path("resource/journal/draft/");
    }
    else
    {
        $root = resolve_system_path("resource/journal/entries/");
    }
    if (count($matches) > 3 and ($id = $matches[3]))
    {
        $pattern = "/^0*${id}/";
    }
    else
    {
        $pattern = "/$expression/";
    }
    $paths = array();
    $directory = opendir($root);
    while (($path = readdir($directory)) !== false)
    {
        if (preg_match($pattern, $path))
        {
            $paths[] = $root . $path;
        }
    }
    closedir($directory);
    if (!$paths)
    {
        $paths = glob($root . "*.html");
    }
    rsort($paths);
    return $paths;
}

function get_date($line)
{
    preg_match("/^<!--\s*\S+:\s*(.*)\s*-->/", trim($line), $matches);
    return date("M. d, Y, g a", strtotime($matches[1]));
}

function get_article_id_from_path($path)
{
    preg_match("/\/([0-9]+)_[^\/]*$/", $path, $matches);
    return intval($matches[1]);
}

function print_rss_button_images()
{
    $paths = glob(resolve_system_path("img/stale-mile/*.png"));
    for ($ii = 0; $ii < 6; $ii++)
    {
        $index = rand(0, count($paths) - 1);
        print_image_tag($paths[$index], "", "", false);
        array_splice($paths, $index, 1);
        if ($ii == 2)
        {
            print_l("<br />", false);
        }
    }
}

?>
18.207.252.123
18.207.252.123
18.207.252.123
 
September 13, 2013

from array import array
from time import sleep

import pygame
from pygame.mixer import Sound, get_init, pre_init

class Note(Sound):

    def __init__(self, frequency, volume=.1):
        self.frequency = frequency
        Sound.__init__(self, self.build_samples())
        self.set_volume(volume)

    def build_samples(self):
        period = int(round(get_init()[0] / self.frequency))
        samples = array("h", [0] * period)
        amplitude = 2 ** (abs(get_init()[1]) - 1) - 1
        for time in xrange(period):
            if time < period / 2:
                samples[time] = amplitude
            else:
                samples[time] = -amplitude
        return samples

if __name__ == "__main__":
    pre_init(44100, -16, 1, 1024)
    pygame.init()
    Note(440).play(-1)
    sleep(5)

This program generates and plays a 440 Hz tone for 5 seconds. It can be extended to generate the spectrum of notes with a frequency table or the frequency formula. Because the rewards in Send are idealized ocean waves, they can also be represented as tones. Each level has a tone in its goal and a tone based on where the player's disc lands. Both play at the end of a level, sounding harmonic for a close shot and discordant for a near miss. The game can dynamically create these tones using the program as a basis.

I'm also building an algorithmically generated song: Silk Routes (Scissored). Here is an example of how it sounds so far: