Riichi Mahjong Tiles

One thing you can do is prepare to go out, perhaps using the five-block method. If your system is slow, make sure the the first click is registered (shown below in "ar69") before clicking again.


index: 0
draws: 0
Current tile indeces: 19,52,28,62,38,83,114,74,6,124,17,115,126,98

The tile on the right is your draw. To keep it, double click on the tile you wish to discard or click the drawn tile and then the tile to discard. To discard the drawn tile, click the "Draw" button or double click on the drawn tile. If you click a tile in your hand and then the drawn tile, you will revert to having no clicked tiles.

To organize your hand, click on a tile and then click the tile located where you want to place it. This is not the way to place the drawn tile in your hand. Double clicking the tile you wish to discard and clicking the "Draw" button are the only ways to do it.

This module is in the "Riichi_Mahjong" and "Functional_JavaScript" section. Beginners could use it to arrange hands according to the five-block method.

After railing against mindlessly making variables immutable, I wanted to show that immutability sometimes serves a purpose, even in small, isolated modules such as this. As is apparent from the code below, each state of the Riichi Mahjong tiles is cloned deep enough to preserve it in an array that can be traversed. I could have used numbers for this, but Mahjong tiles make a more pleasing illustration.

Events: An array, "B", of all Riichi Mahjong tiles is shuffled. Then 14 members are spliced from its front, 13 for the hand and one for the first draw. Each time you click "Draw" or double-click the 14th tile, a number n (corresponding to image xyz[n] in the presentation) is spliced from the front of B. The code is at and is also shown below:

    import {fade} from "svelte/transition"
    import {flip} from "svelte/animate";

    function shuffle(array) {
      var m = array.length, t, i;
      // While there remain elements to shuffle…
      while (m) {
        // Pick a remaining element…
        i = Math.floor(Math.random() * m--);
        // And swap it with the current element.
        t = array[m];
        array[m] = array[i];
        array[i] = t;
      return array;
    let draws = 0;
    import M1 from '$libimages/Man1.svg';
    import M2 from '$libimages/Man2.svg';
    import M3 from '$libimages/Man3.svg';
    import M4 from '$libimages/Man4.svg';
    import M5 from '$libimages/Man5.svg';
    import M6 from '$libimages/Man6.svg';
    import M7 from '$libimages/Man7.svg';
    import M8 from '$libimages/Man8.svg';
    import M9 from '$libimages/Man9.svg';
    import P1 from '$libimages/Pin1.svg';
    import P2 from '$libimages/Pin2.svg';
    import P3 from '$libimages/Pin3.svg';
    import P4 from '$libimages/Pin4.svg';
    import P5 from '$libimages/Pin5.svg';
    import P6 from '$libimages/Pin6.svg';
    import P7 from '$libimages/Pin7.svg';
    import P8 from '$libimages/Pin8.svg';
    import P9 from '$libimages/Pin9.svg';
    import S1 from '$libimages/Sou1.svg';
    import S2 from '$libimages/Sou2.svg';
    import S3 from '$libimages/Sou3.svg';
    import S4 from '$libimages/Sou4.svg';
    import S5 from '$libimages/Sou5.svg';
    import S6 from '$libimages/Sou6.svg';
    import S7 from '$libimages/Sou7.svg';
    import S8 from '$libimages/Sou8.svg';
    import S9 from '$libimages/Sou9.svg';
    import Back from '$libimages/Back.svg';
    import Blank from '$libimages/Blank.svg'
    import Chun from '$libimages/Chun.svg'
    import Haku from '$libimages/Haku.svg'
    import Hatsu from '$libimages/Hatsu.svg'
    import Nan from '$libimages/Nan.svg'
    import Pei from '$libimages/Pei.svg'
    import Ton from '$libimages/Ton.svg'
    import Shaa from '$libimages/Shaa.svg'
    var xyz = [M1,M2,M3,M4,M5,M6,M7,M8,M9,P1,P2,P3,P4,P5,P6,P7,P8,P9,S1,S2,S3,S4,S5,S6,S7,S8,S9,Chun,Haku,Hatsu,Nan,Pei,Ton,Shaa,M1,M2,M3,M4,M5,M6,M7,M8,M9,P1,P2,P3,P4,P5,P6,P7,P8,P9,S1,S2,S3,S4,S5,S6,S7,S8,S9,Chun,Haku,Hatsu,Nan,Pei,Ton,Shaa,M1,M2,M3,M4,M5,M6,M7,M8,M9,P1,P2,P3,P4,P5,P6,P7,P8,P9,S1,S2,S3,S4,S5,S6,S7,S8,S9,Chun,Haku,Hatsu,Nan,Pei,Ton,Shaa,M1,M2,M3,M4,M5,M6,M7,M8,M9,P1,P2,P3,P4,P5,P6,P7,P8,P9,S1,S2,S3,S4,S5,S6,S7,S8,S9,Chun,Haku,Hatsu,Nan,Pei,Ton,Shaa]
    var A = Array.from(Array(136).keys())
    var B = A.slice();
    B = shuffle(B);
    var ARR = B.splice(0,14);   
    var ARCHIVE = [ARR.slice()];
    var ar69 = [];
    var argo;
    $:   argo = () => {return ar69.slice()};
    ar69 = ar69;
    let index = 0;

    function shuf() {
        B = A.slice()
        B = shuffle(B);
        ARR = B.splice(0,14);
        ARCHIVE = [ARR];
        index = 0;
        draws = 0;
        ar69 = [];
        ARCHIVE = [ARR].slice();
        return ARR; 

    function back () {
        if (index > 0) {
            index = index - 1;
            ARR = ARCHIVE[index]
    function forward () {
        if (index < ARCHIVE.length - 1) {
            index = index + 1; 
            ARR = ARCHIVE[index]
    function sw (ar) {
        ARR = ARR.slice();
        var a, b, c, d;
        [a,b,c,d] = ar;
        if (a < c) {
            for (let i = a; i < c; i+=1) {
                ARR[i] = ARR[i+1]
            ARR[c] = b;
            index = index + 1;
            ar69 = []; 
        ARCHIVE.splice(ARCHIVE.length, 0, ARR.slice());
        ARCHIVE = ARCHIVE.slice();
        else if (a > c) {
            for (let i = a; i > c; i-=1) {
                ARR[i] = ARR[i-1]
            ARR[c] = b;
            index = index + 1;
            ar69 = ar69;
        ARCHIVE.splice(ARCHIVE.length, 0, ARR.slice());
        ARCHIVE = ARCHIVE.slice();
        setTimeout(() => ar69 = [], 300);
        else if (a === c) {
            // setTimeout(() => ar69 = [], 300);
        console.log("ARCHIVE is", ARCHIVE); 
    var ar69 = [];
    function sky (a) {
        if (ar69.length === 0) ar69 = a
        else if (ar69.length === 2) {
                ar69 = ar69.concat(a);
                if (ar69[0] === 13 && ar69[2] === 13) {
                    index = getR();
                else if(ar69[0] === ar69[2]) {
                    ARR[ar69[0]] = ARR[13];
                    index = getR();
                else if (ar69[0] < 13 && ar69[2] < 13) sw(ar69)
                else { console.log("FUBAR"); shuf() }
    function getR() {
        index = index + i;
        ar69 = [];
        ARR[13] = B.splice(0,1)[0];
        ARR = ARR;
        ARCHIVE = JSON.parse(JSON.stringify(ARCHIVE));
        console.log("ARCHIVE is", ARCHIVE); 
        return index;