Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
seanyeh committed Nov 4, 2023
0 parents commit 75330f6
Show file tree
Hide file tree
Showing 15 changed files with 7,293 additions and 0 deletions.
6,327 changes: 6,327 additions & 0 deletions docs/index.9d14e10e.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/index.9d14e10e.js.map

Large diffs are not rendered by default.

197 changes: 197 additions & 0 deletions docs/index.e58a49f3.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/index.e58a49f3.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/index.e58a49f3.css">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

<script src="/index.9d14e10e.js" defer=""></script>

<title>Scaledle</title>
</head>
<body>
</body>
</html>
17 changes: 17 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/src/style.scss" />

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

<script type="module" src="src/App.ts"></script>

<title>Scaledle</title>
</head>
<body>
</body>
</html>
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"dependencies": {
"mithril": "^2.2.2",
"tonal": "^5.0.0"
},
"devDependencies": {
"@parcel/transformer-sass": "2.10.2",
"parcel": "^2.10.2"
}
}
8 changes: 8 additions & 0 deletions src/App.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import m from "mithril";
import MainPage from "./components/MainPage";

// Set up routing by connecting components to routes
m.route(document.body, "/", {
"/": MainPage,
});

132 changes: 132 additions & 0 deletions src/Util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { Note, Scale } from "tonal";

export default class Util {
static readonly SCALE_TYPES = [
"major",
"minor",
"harmonic minor",
"melodic minor",
"dorian",
"phrygian",
"lydian",
"mixolydian",
"locrian",
"pentatonic",
"whole-half diminished",
"half-whole diminished"
]

static readonly ROOTS = [
"A",
"Bb",
"B",
"C",
"C#",
"D",
"Eb",
"E",
"F",
"F#",
"G",
"Ab",
];

static readonly BLACK_NOTES = ["C#", "D#", "F#", "G#", "A#"];
static readonly BLACK_NOTES_FLAT = ["Db", "Eb", "Gb", "Ab", "Bb"];
static readonly WHITE_NOTES = ["C", "D", "E", "F", "G", "A", "B"];

static getRandomScaleNumber() {
// TODO: use the proper algorithm rather than assuming 12 roots and scale types
return Math.floor(Math.random() * 144);
}

static getScaleByNumber(i: number) {
// TODO: use the proper algorithm rather than assuming 12 roots and scale types
const root = this.ROOTS[i%12];
const scaleType = this.SCALE_TYPES[Math.floor(i/12)];

const octave = 5; // Doesn't really matter
return Scale.get(`${root}${octave} ${scaleType}`);
}

// Get midi array
static toMidiArray(notes) {
return notes.map((noteName) => Note.get(noteName).midi % 12);
}

// Returns an array of results:
// "C": correct,
// "W": wrong spot,
// "X": does not exist
static calculateGuess(guess, rawAnswer) {
// Normalize correct to be same length as guess
const answer = rawAnswer.concat(rawAnswer).slice(0, guess.length);

// Make map of answer to track note usage
const answerMap = {};
answer.forEach((note) => {
if (!(note in answerMap)) {
answerMap[note] = 0;
}
answerMap[note]++;
});

const result = Array(guess.length);

// First pass to find correct notes
guess.forEach((note, i) => {
if (note === answer[i]) {
result[i] = "C";
answerMap[note]--;
}
});

// Second pass to figure out the other results
guess.forEach((note, i) => {
if (result[i] === "C") {
return;
}

if (answerMap[note]) {
result[i] = "W";
answerMap[note]--;
}
else {
result[i] = "X";
}
});

return result;
}

static readonly EMOJI_MAP = {
"C": "🟩",
"W": "🟨",
"X": "⬛"
}
static readonly URL = "seanyeh.github.io/scaldle";

static resultsToShareable(resultsList, puzzleNumber): string {
const tries = resultsList.length;
const resultsStr = resultsList.map((results) => (
`${results.map((x) => Util.EMOJI_MAP[x]).join("")}\n`
)).join("");

return `Scale-dle #${puzzleNumber}\n${resultsStr}\n${Util.URL}`;
}

static normalizeScaleName(scaleName) {
// Remove octave from name
let newName = scaleName.replace(/[0-9]/, "");

// Rename diminished scales to octatonic
if (scaleName.includes("half-whole diminished")) {
newName = scaleName.replace("half-whole diminished", "octatonic (half-whole)");
}
else if (scaleName.includes("diminished")) {
newName = scaleName.replace("diminished", "octatonic (whole-half)");
}

return newName;
}
}
Loading

0 comments on commit 75330f6

Please sign in to comment.