【コーデュート!】2013/10/10の変更点

【変更点】
  • ゲームスタートのトリガを「スペースキー」から「コードの最初の文字」に変更しました。スピードやミス率の計測はコードの2文字目からになります。
【新機能】
  • 結果画面でツイートボタンを押すと、結果をツイートできるようにしました。

※いいね!ボタンやツイートボタンを押した後はキー入力が無効になっているので、リトライ時は一度画面をクリックしてください。


そろそろレーティングの算出法も見直したいと思います!
コーデュート! | https://codeute.com

【コーデュート!】2013/10/09の変更点

前回の記事からの変更点です。
【修正】

  • 結果画面でランキング登録ボタンが押せなくなるバグを修正しました。
  • 非公開コードの記録が総合ランキングに反映されていた不具合を修正しました。

【新機能】

  • C言語に対応しました。HelloWorldも追加 https://codeute.com/c/0
  • 検索結果のソート項目に「ランク登録数」を追加しました。
  • キーボードの表示/非表示の情報をアカウントに紐づけて自動保存します。(ログイン時のみ有効・Ctrl+Sで切替えます)
  • ランキング登録時に、レーティングの変動が分かるようにしました。

f:id:setchi_q:20131009184820p:plain

暇潰しにレーティング稼ぎましょう!コードも募集中です('_')
コーデュート! | https://codeute.com

【コーデュート!】総合ランキングを実装しました

全ランキングと言語別ランキングを集計した総合ランキングを実装しました!

今のところ、コード毎の

  • 本人の順位
  • 本人のスコア
  • ランキング参加人数

の3つの値をもとに総合スコアを集計しています。

総合スコアは、多くのランキングに登録してコツコツと増やすこともできますし、人気の高いランキングで上位を獲得することで劇的に稼ぐこともできます。


まだβ版なので、様子を見ながらスコアバランスを調整していく予定です。
ちなみに、ランキングは項目名をクリックするとその項目でソートすることができます。

ぜひ、総合ランキングで上位を目指してみてください!
コーデュート! | https://codeute.com/

近いうちに、タイピング結果をツイートできる機能を追加予定です。

【コーデュート!】ESCキーでのリトライ機能を実装しました

以前から要望にあがっていたESCキーでのリトライ機能をちゃんと実装しました。
ESCを押すと、リロードせずにプレイ前の状態に戻ります!

実装に時間がかかってたのは、自分が2ヶ月前に書いたコードを読み解けなかったからです(汗
暇つぶしに遊んでみて下さい!
コーデュート! | https://codeute.com

【コーデュート!】今日の修正&変更点

送っていただいた要望を参考にして、細々とした修正を行いました。

【結果画面】

  • ヒートマップ上の空白文字(打った文字のみ)を可視化
  • ミスした文字をヒートマップ上で可視化
  • グラフにタイプ速度のペース(1分あたりのタイプ数)を追加

【その他】

  • Ctrl+Sでキーボードの表示・非表示を切り替えるようにしました(仮) 今後分かりやすいインターフェースを実装予定
  • Escを押すとリロードしてリトライできるようにしました(仮)

f:id:setchi_q:20131006225656p:plain

グラフ表示でハマった事があって、思ったより時間がかかってしまった…('_')
近いうちに、諸々ののレイアウト設定をアカウントごとに保存する仕組みを作る予定です。

あとはランキングの新システムのアイデアをひねっています。今はユーザーのやる気を引き出す仕組みが全然足りない感じですなヽ(´ρ`)ノ

まだまだ未熟ですが、暇つぶしにいかがでしょうか。問題コードも募集中です!
コーデュート!

Webアプリ「コーデュート!」をリリースしました。

書いたコードをタイピングゲームにしてシェアできるWebアプリ「コーデュート!」をリリースしました。
ネタ要素が強いですが、よかったら遊んでみて下さい!

Codeute! | https://codeute.com/

【FuelPHP】 minifyしたHTMLをデータベースにキャッシュする

前回FuelPHPからHTMLをminifyして出力するメモをしましたが、
圧縮処理に時間がかかっているようだったので、圧縮した結果をデータベースにキャッシュすることにしました。

【条件】

  • ボトルネックになっているのは、HTMLの圧縮処理そのもの
  • 同じURLでも、ユーザーごとに表示される内容が違う
  • 一度生成したページの内容が更新されることは少ないが、更新された場合は即反映したい

【データベース】

CREATE TABLE t_page_cache (
    f_user_id VARCHAR(115),
    f_uri VARCHAR(100),
    f_page MEDIUMTEXT,
    f_cache MEDIUMTEXT,
    f_date DATETIME,
    PRIMARY KEY (f_user_id, f_uri)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 collate = utf8_unicode_ci;

FuelPHP

FuelPHPのモデルは、前回のものを拡張します。

<?php
require_once APPPATH.'classes/model/vendor/autoload.php';

class Model_Html extends Model
{
    public static function minify($view, $uri = false)
    {
        // viewオブジェクトを強制レンダリングして文字列化
        $view = $view->render();
        // minify時のオプション
        $minifyOption = array(
            'doctype' => 'html5',
            'optimizationLevel' => 1
        );
        // uriが指定されていなかった場合は、強制的にminifyしてリターン
        if ($uri === false)
        {
            return zz\Html\HTMLMinify::minify($view, $minifyOption);
        }

        // ユーザーID取得
        $user_id = Session::get('user_info.id', '');

        // $user_idと$uriをもとに、該当する圧縮データを取得
        $query = DB::select('f_page', 'f_cache')
            ->from('t_page_cache')
            ->where('f_user_id', $user_id)
            ->and_where('f_uri', $uri)
            ->limit(1)->execute()->as_array();

        // 検索結果が存在した場合
        if (0 < count($query))
        {
            // 圧縮前HTMLが等しかったら、キャッシュを返す
            if ($query[0]['f_page'] === $view)
            {
                return $query[0]['f_cache'];
            }
            // 圧縮前HTMLが違っていたら、圧縮し直し&DB更新
            else
            {
                $minview = zz\Html\HTMLMinify::minify($view, $minifyOption);
                DB::update('t_page_cache')
                    ->set(array(
                        'f_page' => $view,
                        'f_cache' => $minview,
                        'f_date' => date('Y-m-d H:i:s')
                    ))->where('f_user_id', $user_id)
                    ->and_where('f_uri', $uri)
                    ->execute();

                return $minview;
            }
        }
        // 検索結果が存在しない場合、DBにデータを追加する
        else
        {
            $minview = zz\Html\HTMLMinify::minify($view, $minifyOption);
            DB::insert('t_page_cache')
                ->set(array(
                    'f_user_id' => $user_id,
                    'f_uri' => $uri,
                    'f_page' => $view,
                    'f_cache' => $minview,
                    'f_date' => date('Y-m-d H:i:s')
                ))->execute();

            return $minview;
        }
    }
}

コントローラ

<?php
...
    $view = View::forge('index');
    $view->header = View::forge('header');
    $view->footer = View::forge('footer');

    // viewとURLを渡して、minifyした結果をリターン
    return Response::forge(Model_Html::minify(
        $view,
        Uri::current()
    ));

FuelPHPでURLを取得するメソッドは色々ありますが、その中でもUri::current()は、routes.phpのパターン内部で定義されているベースURLが取得できます。
例えば、存在しないURLにアクセスされた場合は、404ページのURLが返されるので、データベースのキャッシュ数が少なくなります。

ベンチマーク

Ajaxで500回アクセスして、レスポンスタイムの平均(ms)を求めました。
キャッシュ適用前: 304.8196100000467
キャッシュ適用後: 132.88778999996836

レスポンスタイムは1/2以下になって、体感的にも速くなったと感じられました。
ただ、あくまでリリース前の状態なので、定期的に計測しながら様子を見たいと思います。

【FuelPHP】HTMLをminifyして出力する

PHPでHTMLのminifyが出来るhtml-minifierというものがありました。
これをFuelPHPから使ったのでメモ。

まずはconposerでhtml-minifierをダウンロードします。
下記を記述したconposer.jsonを作成

{
    "require": {
        "zaininnari/html-minifier": "*"
    }
}

インストール

curl -sS https://getcomposer.org/installer | php
php composer.phar install

生成されたvendorフォルダを、FuelPHPのmodelフォルダの直下に置いて、次のモデルを定義しました。

<?php
require_once APPPATH.'classes/model/vendor/autoload.php';

class Model_Html extends Model
{
    public static function minify($view)
    {
        return zz\Html\HTMLMinify::minify($view, array(
            'doctype' => 'html5',
            'optimizationLevel' => 1
        ));
    }
}

コントローラから、下記のように使用できます。

<?php
...
    $view = View::forge('home/index');
    $view->header = View::forge('header');
    $view->footer = View::forge('footer');

    // minifyして返す
    return Response::forge(Model_Html::minify($view));

minify前
f:id:setchi_q:20131004101449p:plain
minify後 (optimizationLevel: 1)
f:id:setchi_q:20131004101245p:plain

z\Html\HTMLMinify::minifyの第二引数にはオプションを渡せます。
下記のオプションが使えます(2013/10/04現在)。最初の値がデフォルト値です。

doctype: XHTML1.0 / HTML4.01 / html5
optimizationLevel: 0 / 1
emptyElementAddSlash: false / true
emptyElementAddWhitespaceBeforeSlash: false / true
removeComment: true / false
removeDuplicateAttribute: true / false


~ 追記(2013/10/05) ~
圧縮した結果をデータベースにキャッシュさせました。
【FuelPHP】 minifyしたHTMLをデータベースにキャッシュする

PHPでJSONを連想配列にパースする

PHPjson_decodeの第二引数を知らなかったのでメモ!
第二引数には、戻り値の形式を決めるフラグを指定できます。

$dec_obj = json_decode($json);        // 結果をオブジェクトで返す
$dec_arr = json_decode($json, true);  // 結果を連想配列で返す

$res_obj = $dec_obj->hoge;            // オブジェクトのアクセス方法
$res_arr = $dec_arr['hoge'];          // 連想配列のアクセス方法
 

基礎的な事ですが、ちょっとハマって悔しかった…('_')

バーチャルキーボードの操作

こんぬづわ。

今日は、今作っている「書いたコードをタイピングゲームにして遊べる」Webアプリの中のバーチャルキーボードについてです。


もしかしたらCanvasとかで実装した方がよかったのかもしれませんが、とりあえずHTML&CSSで出来ています。

f:id:setchi_q:20130928145832p:plainf:id:setchi_q:20130928145835p:plain

シフトキーが押された時の文字の切替え

良く見ると、シフトキーを押したときにキーの文字が入れ替わってますが、実はこれもCSSで表現しています。

HTML(一部抜粋)

<table id="keyboard">
    <tbody>
        <!-- 1行目 -->
        <tr>
          <td>
            <div></div>
            <div><span>!</span><span>1</span></div>
            <div><span>"</span><span>2</span></div>
            <div><span>#</span><span>3</span></div>
            <div><span>$</span><span>4</span></div>
            <div><span>%</span><span>5</span></div>
            <div><span>;</span><span>6</span></div>
            <div><span>'</span><span>7</span></div>
            <div><span>(</span><span>8</span></div>
            <div><span>)</span><span>9</span></div>
            <div><span>0</span><span>0</span></div>
            <div><span>=</span><span>-</span></div>
            <div><span>~</span><span>^</span></div>
            <div><span>|</span><span>\</span></div>
            <div></div>
          </td>
        </tr>
        <!-- 2行目… -->
        ...
    </tbody>
</table>

CSS

/* 通常時 */
#keyboard td span:first-child {
    display: none;
}

/* シフトキーが押された時 */
#keyboard.onShift td span:first-child {
    display: inline !important;
}
#keyboard.onShift td span:last-child {
    display: none !important;
}

シフトキーが押された時、JavaScript側から一番外側の#keyboardに'onShift'というクラスを付けます。
CSSでは、クラスの有無によって中の文字が切替わるように指定しています。
思い付きの実装なので、もっと良い(速い)方法があれば教えてください><