Last active
February 12, 2017 13:12
-
-
Save TatsuoWatanabe/2d369f739348e45da3aaa393821c3dab to your computer and use it in GitHub Desktop.
A song of "Grandfather's Clock" as a javascript source code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************************** | |
Copyright (c) 2017 tatsuo watanabe<[email protected]> | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
SOFTWARE. | |
****************************************************************************/ | |
/** | |
* Tick the lifetime | |
*/ | |
class TickTockable { | |
constructor(opts) { | |
const options = opts || {}; | |
this.duration = options.duration || 1000; | |
this.narrator = options.narrator || console.log; | |
this.age = 0; | |
this.isBorn = false; | |
this.isAlive = true; | |
this.promise = new Promise((resolve) => { this.resolve = resolve; }); | |
} | |
/** Tick the time. */ | |
tick() { this.alive(() => this.tock()); const s = this.sound('tick'); if (!s) { return; } this.narrator(s); } | |
/** Tock the time. */ | |
tock() { this.alive(() => this.tick()); const s = this.sound('tock'); if (!s) { return; } this.narrator(s); } | |
/** Variety of somethig will affair. */ | |
affair() { this.narrator('Variety of somethig will affair.'); } | |
/** There are many things if you live. */ | |
alive(callback) { | |
if (!this.isAlive) { return; } | |
if (this.isBorn) { this.age += 1; } | |
this.affair(); | |
setTimeout(() => { | |
callback(); | |
}, this.duration); | |
} | |
/** Sounds of your story. */ | |
sound(key) { | |
const sounds = { tick: 'tick...', tock: 'tock...' }; | |
return sounds[key]; | |
} | |
rnd(accuracy) { | |
return Math.ceil(Math.random() * accuracy) === accuracy; | |
} | |
} | |
class Oldman extends TickTockable { | |
constructor(clock, opts, name) { | |
super(opts); | |
this.name = name; | |
this.clock = clock; | |
this.isBorn = false; | |
this.alive(() => this.tick()); | |
} | |
sound() { | |
const footstep = !this.isBorn ? 'throb...' : | |
this.age < 3 ? 'mewl...' : | |
this.age === 13 ? 'giggle...' : | |
this.age === 17 ? 'yeah...' : | |
this.age === 24 ? 'you are my pleasure...' : | |
this.age === 75 ? 'what a faithful clock...' : | |
''; | |
return footstep; | |
} | |
affair() { | |
this.born(); | |
this.marry(); | |
this.babyBorn(); | |
this.grandChildBorn(); | |
this.die(); | |
} | |
born() { | |
if (this.isBorn) { return; } | |
if (!this.rnd(10)) { return; } | |
this.isBorn = true; | |
this.clock.owner = this; | |
this.narrator(`${this.name} was born.`); | |
} | |
marry() { | |
if (this.age !== 24 || this.married) { return; } | |
this.married = true; | |
this.narrator(`Blooming and beautiful bride came.`); | |
} | |
babyBorn() { | |
if (this.age !== 30 || this.hasChild) { return; } | |
this.hasChild = true; | |
this.narrator(`${this.name} had a baby born.`); | |
} | |
grandChildBorn() { | |
if (this.age !== 60 || this.hasGrandchild) { return; } | |
this.hasGrandchild = true; | |
this.narrator( | |
`${this.name} had a grandchild born.\nI was born.` | |
); | |
} | |
die() { | |
if (this.age < 90) { return; } | |
this.isAlive = false; | |
setTimeout(() => { | |
this.narrator(`${this.name} was died.`); | |
this.resolve(); | |
}, this.duration * 2); | |
} | |
} | |
class Clock extends TickTockable { | |
constructor(opts) { | |
super(opts); | |
this.isBorn = true; | |
this.isBought = false; | |
this.owner = undefined; | |
this.alive(() => this.tick()); | |
} | |
affair() { | |
this.bought(); | |
this.die(); | |
} | |
bought() { | |
if (!this.owner || this.isBought) { return; } | |
this.isBought = true; | |
this.narrator(`The clock was bought for ${this.owner.name}.` ); | |
} | |
die() { | |
if (!this.owner || this.owner.isAlive) { return; } | |
this.isAlive = false; | |
setTimeout(() => { | |
this.narrator(`The clock stopped short, never to go again.`); | |
this.resolve(); | |
}, this.duration * 2); | |
} | |
} | |
/** | |
* "Grandfather's Clock" is a song written in 1876 by Henry Clay Work, | |
* the author of "Marching Through Georgia". | |
* It is a standard of British brass bands and colliery bands, | |
* and is also popular in bluegrass music. | |
* It has also been sung by male choruses such as the Robert Shaw Chorale. | |
* --- From Wikipedia, the free encyclopedia | |
* | |
* @see https://en.wikipedia.org/wiki/My_Grandfather's_Clock | |
*/ | |
function myGrandfathersClock(opts) { | |
const options = opts || {}; | |
options.narrator = options.narrator || console.log; | |
options.duration = options.duration || 1000; | |
const narrator = options.narrator; | |
const clock = new Clock(options); | |
const grandfather = new Oldman(clock, options, 'My grandfather'); | |
Promise.all([ | |
clock.promise, | |
grandfather.promise | |
]).then(() => | |
setTimeout(() => narrator('I remember you.'), options.duration) | |
); | |
} | |
myGrandfathersClock(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment