mjai 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/mjai +9 -0
- data/bin/mjai-shanten +9 -0
- data/bin/mjai-tsumogiri +9 -0
- data/lib/mjai/action.rb +41 -0
- data/lib/mjai/active_game.rb +230 -0
- data/lib/mjai/archive.rb +46 -0
- data/lib/mjai/archive_player.rb +47 -0
- data/lib/mjai/context.rb +34 -0
- data/lib/mjai/file_converter.rb +86 -0
- data/lib/mjai/furo.rb +57 -0
- data/lib/mjai/game.rb +357 -0
- data/lib/mjai/hora.rb +528 -0
- data/lib/mjai/jsonizable.rb +171 -0
- data/lib/mjai/mentsu.rb +46 -0
- data/lib/mjai/mjai_command.rb +93 -0
- data/lib/mjai/mjson_archive.rb +25 -0
- data/lib/mjai/pai.rb +138 -0
- data/lib/mjai/player.rb +340 -0
- data/lib/mjai/puppet_player.rb +14 -0
- data/lib/mjai/shanten_analysis.rb +273 -0
- data/lib/mjai/shanten_player.rb +102 -0
- data/lib/mjai/tcp_client_game.rb +63 -0
- data/lib/mjai/tcp_game_server.rb +205 -0
- data/lib/mjai/tcp_player.rb +66 -0
- data/lib/mjai/tenhou_archive.rb +412 -0
- data/lib/mjai/tenpai_analysis.rb +62 -0
- data/lib/mjai/tsumogiri_player.rb +20 -0
- data/lib/mjai/validation_error.rb +7 -0
- data/lib/mjai/with_fields.rb +18 -0
- data/share/html/css/style.css +77 -0
- data/share/html/css/style.scss +106 -0
- data/share/html/images/README.txt +1 -0
- data/share/html/images/b_1_1.gif +0 -0
- data/share/html/images/b_1_2.gif +0 -0
- data/share/html/images/b_5_1.gif +0 -0
- data/share/html/images/b_5_2.gif +0 -0
- data/share/html/images/b_8_1.gif +0 -0
- data/share/html/images/b_8_2.gif +0 -0
- data/share/html/images/b_9_1.gif +0 -0
- data/share/html/images/b_9_2.gif +0 -0
- data/share/html/images/blank.png +0 -0
- data/share/html/images/c_c_1.gif +0 -0
- data/share/html/images/c_c_2.gif +0 -0
- data/share/html/images/c_c_3.gif +0 -0
- data/share/html/images/c_c_4.gif +0 -0
- data/share/html/images/c_e_1.gif +0 -0
- data/share/html/images/c_e_2.gif +0 -0
- data/share/html/images/c_e_3.gif +0 -0
- data/share/html/images/c_e_4.gif +0 -0
- data/share/html/images/c_n_1.gif +0 -0
- data/share/html/images/c_n_2.gif +0 -0
- data/share/html/images/c_n_3.gif +0 -0
- data/share/html/images/c_n_4.gif +0 -0
- data/share/html/images/c_s_1.gif +0 -0
- data/share/html/images/c_s_2.gif +0 -0
- data/share/html/images/c_s_3.gif +0 -0
- data/share/html/images/c_s_4.gif +0 -0
- data/share/html/images/c_w_1.gif +0 -0
- data/share/html/images/c_w_2.gif +0 -0
- data/share/html/images/c_w_3.gif +0 -0
- data/share/html/images/c_w_4.gif +0 -0
- data/share/html/images/dice.gif +0 -0
- data/share/html/images/p_bk_0.gif +0 -0
- data/share/html/images/p_bk_1.gif +0 -0
- data/share/html/images/p_bk_2.gif +0 -0
- data/share/html/images/p_bk_3.gif +0 -0
- data/share/html/images/p_bk_4.gif +0 -0
- data/share/html/images/p_bk_5.gif +0 -0
- data/share/html/images/p_bk_6.gif +0 -0
- data/share/html/images/p_bk_7.gif +0 -0
- data/share/html/images/p_ji_c_0.gif +0 -0
- data/share/html/images/p_ji_c_1.gif +0 -0
- data/share/html/images/p_ji_c_2.gif +0 -0
- data/share/html/images/p_ji_c_3.gif +0 -0
- data/share/html/images/p_ji_c_4.gif +0 -0
- data/share/html/images/p_ji_c_5.gif +0 -0
- data/share/html/images/p_ji_c_6.gif +0 -0
- data/share/html/images/p_ji_c_7.gif +0 -0
- data/share/html/images/p_ji_e_0.gif +0 -0
- data/share/html/images/p_ji_e_1.gif +0 -0
- data/share/html/images/p_ji_e_2.gif +0 -0
- data/share/html/images/p_ji_e_3.gif +0 -0
- data/share/html/images/p_ji_e_4.gif +0 -0
- data/share/html/images/p_ji_e_5.gif +0 -0
- data/share/html/images/p_ji_e_6.gif +0 -0
- data/share/html/images/p_ji_e_7.gif +0 -0
- data/share/html/images/p_ji_h_0.gif +0 -0
- data/share/html/images/p_ji_h_1.gif +0 -0
- data/share/html/images/p_ji_h_2.gif +0 -0
- data/share/html/images/p_ji_h_3.gif +0 -0
- data/share/html/images/p_ji_h_4.gif +0 -0
- data/share/html/images/p_ji_h_5.gif +0 -0
- data/share/html/images/p_ji_h_6.gif +0 -0
- data/share/html/images/p_ji_h_7.gif +0 -0
- data/share/html/images/p_ji_n_0.gif +0 -0
- data/share/html/images/p_ji_n_1.gif +0 -0
- data/share/html/images/p_ji_n_2.gif +0 -0
- data/share/html/images/p_ji_n_3.gif +0 -0
- data/share/html/images/p_ji_n_4.gif +0 -0
- data/share/html/images/p_ji_n_5.gif +0 -0
- data/share/html/images/p_ji_n_6.gif +0 -0
- data/share/html/images/p_ji_n_7.gif +0 -0
- data/share/html/images/p_ji_s_0.gif +0 -0
- data/share/html/images/p_ji_s_1.gif +0 -0
- data/share/html/images/p_ji_s_2.gif +0 -0
- data/share/html/images/p_ji_s_3.gif +0 -0
- data/share/html/images/p_ji_s_4.gif +0 -0
- data/share/html/images/p_ji_s_5.gif +0 -0
- data/share/html/images/p_ji_s_6.gif +0 -0
- data/share/html/images/p_ji_s_7.gif +0 -0
- data/share/html/images/p_ji_w_0.gif +0 -0
- data/share/html/images/p_ji_w_1.gif +0 -0
- data/share/html/images/p_ji_w_2.gif +0 -0
- data/share/html/images/p_ji_w_3.gif +0 -0
- data/share/html/images/p_ji_w_4.gif +0 -0
- data/share/html/images/p_ji_w_5.gif +0 -0
- data/share/html/images/p_ji_w_6.gif +0 -0
- data/share/html/images/p_ji_w_7.gif +0 -0
- data/share/html/images/p_ms1_0.gif +0 -0
- data/share/html/images/p_ms1_1.gif +0 -0
- data/share/html/images/p_ms1_2.gif +0 -0
- data/share/html/images/p_ms1_3.gif +0 -0
- data/share/html/images/p_ms1_4.gif +0 -0
- data/share/html/images/p_ms1_5.gif +0 -0
- data/share/html/images/p_ms1_6.gif +0 -0
- data/share/html/images/p_ms1_7.gif +0 -0
- data/share/html/images/p_ms2_0.gif +0 -0
- data/share/html/images/p_ms2_1.gif +0 -0
- data/share/html/images/p_ms2_2.gif +0 -0
- data/share/html/images/p_ms2_3.gif +0 -0
- data/share/html/images/p_ms2_4.gif +0 -0
- data/share/html/images/p_ms2_5.gif +0 -0
- data/share/html/images/p_ms2_6.gif +0 -0
- data/share/html/images/p_ms2_7.gif +0 -0
- data/share/html/images/p_ms3_0.gif +0 -0
- data/share/html/images/p_ms3_1.gif +0 -0
- data/share/html/images/p_ms3_2.gif +0 -0
- data/share/html/images/p_ms3_3.gif +0 -0
- data/share/html/images/p_ms3_4.gif +0 -0
- data/share/html/images/p_ms3_5.gif +0 -0
- data/share/html/images/p_ms3_6.gif +0 -0
- data/share/html/images/p_ms3_7.gif +0 -0
- data/share/html/images/p_ms4_0.gif +0 -0
- data/share/html/images/p_ms4_1.gif +0 -0
- data/share/html/images/p_ms4_2.gif +0 -0
- data/share/html/images/p_ms4_3.gif +0 -0
- data/share/html/images/p_ms4_4.gif +0 -0
- data/share/html/images/p_ms4_5.gif +0 -0
- data/share/html/images/p_ms4_6.gif +0 -0
- data/share/html/images/p_ms4_7.gif +0 -0
- data/share/html/images/p_ms5_0.gif +0 -0
- data/share/html/images/p_ms5_1.gif +0 -0
- data/share/html/images/p_ms5_2.gif +0 -0
- data/share/html/images/p_ms5_3.gif +0 -0
- data/share/html/images/p_ms5_4.gif +0 -0
- data/share/html/images/p_ms5_5.gif +0 -0
- data/share/html/images/p_ms5_6.gif +0 -0
- data/share/html/images/p_ms5_7.gif +0 -0
- data/share/html/images/p_ms5r_1.png +0 -0
- data/share/html/images/p_ms5r_3.png +0 -0
- data/share/html/images/p_ms6_0.gif +0 -0
- data/share/html/images/p_ms6_1.gif +0 -0
- data/share/html/images/p_ms6_2.gif +0 -0
- data/share/html/images/p_ms6_3.gif +0 -0
- data/share/html/images/p_ms6_4.gif +0 -0
- data/share/html/images/p_ms6_5.gif +0 -0
- data/share/html/images/p_ms6_6.gif +0 -0
- data/share/html/images/p_ms6_7.gif +0 -0
- data/share/html/images/p_ms7_0.gif +0 -0
- data/share/html/images/p_ms7_1.gif +0 -0
- data/share/html/images/p_ms7_2.gif +0 -0
- data/share/html/images/p_ms7_3.gif +0 -0
- data/share/html/images/p_ms7_4.gif +0 -0
- data/share/html/images/p_ms7_5.gif +0 -0
- data/share/html/images/p_ms7_6.gif +0 -0
- data/share/html/images/p_ms7_7.gif +0 -0
- data/share/html/images/p_ms8_0.gif +0 -0
- data/share/html/images/p_ms8_1.gif +0 -0
- data/share/html/images/p_ms8_2.gif +0 -0
- data/share/html/images/p_ms8_3.gif +0 -0
- data/share/html/images/p_ms8_4.gif +0 -0
- data/share/html/images/p_ms8_5.gif +0 -0
- data/share/html/images/p_ms8_6.gif +0 -0
- data/share/html/images/p_ms8_7.gif +0 -0
- data/share/html/images/p_ms9_0.gif +0 -0
- data/share/html/images/p_ms9_1.gif +0 -0
- data/share/html/images/p_ms9_2.gif +0 -0
- data/share/html/images/p_ms9_3.gif +0 -0
- data/share/html/images/p_ms9_4.gif +0 -0
- data/share/html/images/p_ms9_5.gif +0 -0
- data/share/html/images/p_ms9_6.gif +0 -0
- data/share/html/images/p_ms9_7.gif +0 -0
- data/share/html/images/p_no_0.gif +0 -0
- data/share/html/images/p_no_1.gif +0 -0
- data/share/html/images/p_no_2.gif +0 -0
- data/share/html/images/p_no_3.gif +0 -0
- data/share/html/images/p_no_4.gif +0 -0
- data/share/html/images/p_no_5.gif +0 -0
- data/share/html/images/p_no_6.gif +0 -0
- data/share/html/images/p_no_7.gif +0 -0
- data/share/html/images/p_ps1_0.gif +0 -0
- data/share/html/images/p_ps1_1.gif +0 -0
- data/share/html/images/p_ps1_2.gif +0 -0
- data/share/html/images/p_ps1_3.gif +0 -0
- data/share/html/images/p_ps1_4.gif +0 -0
- data/share/html/images/p_ps1_5.gif +0 -0
- data/share/html/images/p_ps1_6.gif +0 -0
- data/share/html/images/p_ps1_7.gif +0 -0
- data/share/html/images/p_ps2_0.gif +0 -0
- data/share/html/images/p_ps2_1.gif +0 -0
- data/share/html/images/p_ps2_2.gif +0 -0
- data/share/html/images/p_ps2_3.gif +0 -0
- data/share/html/images/p_ps2_4.gif +0 -0
- data/share/html/images/p_ps2_5.gif +0 -0
- data/share/html/images/p_ps2_6.gif +0 -0
- data/share/html/images/p_ps2_7.gif +0 -0
- data/share/html/images/p_ps3_0.gif +0 -0
- data/share/html/images/p_ps3_1.gif +0 -0
- data/share/html/images/p_ps3_2.gif +0 -0
- data/share/html/images/p_ps3_3.gif +0 -0
- data/share/html/images/p_ps3_4.gif +0 -0
- data/share/html/images/p_ps3_5.gif +0 -0
- data/share/html/images/p_ps3_6.gif +0 -0
- data/share/html/images/p_ps3_7.gif +0 -0
- data/share/html/images/p_ps4_0.gif +0 -0
- data/share/html/images/p_ps4_1.gif +0 -0
- data/share/html/images/p_ps4_2.gif +0 -0
- data/share/html/images/p_ps4_3.gif +0 -0
- data/share/html/images/p_ps4_4.gif +0 -0
- data/share/html/images/p_ps4_5.gif +0 -0
- data/share/html/images/p_ps4_6.gif +0 -0
- data/share/html/images/p_ps4_7.gif +0 -0
- data/share/html/images/p_ps5_0.gif +0 -0
- data/share/html/images/p_ps5_1.gif +0 -0
- data/share/html/images/p_ps5_2.gif +0 -0
- data/share/html/images/p_ps5_3.gif +0 -0
- data/share/html/images/p_ps5_4.gif +0 -0
- data/share/html/images/p_ps5_5.gif +0 -0
- data/share/html/images/p_ps5_6.gif +0 -0
- data/share/html/images/p_ps5_7.gif +0 -0
- data/share/html/images/p_ps5r_1.png +0 -0
- data/share/html/images/p_ps5r_3.png +0 -0
- data/share/html/images/p_ps6_0.gif +0 -0
- data/share/html/images/p_ps6_1.gif +0 -0
- data/share/html/images/p_ps6_2.gif +0 -0
- data/share/html/images/p_ps6_3.gif +0 -0
- data/share/html/images/p_ps6_4.gif +0 -0
- data/share/html/images/p_ps6_5.gif +0 -0
- data/share/html/images/p_ps6_6.gif +0 -0
- data/share/html/images/p_ps6_7.gif +0 -0
- data/share/html/images/p_ps7_0.gif +0 -0
- data/share/html/images/p_ps7_1.gif +0 -0
- data/share/html/images/p_ps7_2.gif +0 -0
- data/share/html/images/p_ps7_3.gif +0 -0
- data/share/html/images/p_ps7_4.gif +0 -0
- data/share/html/images/p_ps7_5.gif +0 -0
- data/share/html/images/p_ps7_6.gif +0 -0
- data/share/html/images/p_ps7_7.gif +0 -0
- data/share/html/images/p_ps8_0.gif +0 -0
- data/share/html/images/p_ps8_1.gif +0 -0
- data/share/html/images/p_ps8_2.gif +0 -0
- data/share/html/images/p_ps8_3.gif +0 -0
- data/share/html/images/p_ps8_4.gif +0 -0
- data/share/html/images/p_ps8_5.gif +0 -0
- data/share/html/images/p_ps8_6.gif +0 -0
- data/share/html/images/p_ps8_7.gif +0 -0
- data/share/html/images/p_ps9_0.gif +0 -0
- data/share/html/images/p_ps9_1.gif +0 -0
- data/share/html/images/p_ps9_2.gif +0 -0
- data/share/html/images/p_ps9_3.gif +0 -0
- data/share/html/images/p_ps9_4.gif +0 -0
- data/share/html/images/p_ps9_5.gif +0 -0
- data/share/html/images/p_ps9_6.gif +0 -0
- data/share/html/images/p_ps9_7.gif +0 -0
- data/share/html/images/p_ss1_0.gif +0 -0
- data/share/html/images/p_ss1_1.gif +0 -0
- data/share/html/images/p_ss1_2.gif +0 -0
- data/share/html/images/p_ss1_3.gif +0 -0
- data/share/html/images/p_ss1_4.gif +0 -0
- data/share/html/images/p_ss1_5.gif +0 -0
- data/share/html/images/p_ss1_6.gif +0 -0
- data/share/html/images/p_ss1_7.gif +0 -0
- data/share/html/images/p_ss2_0.gif +0 -0
- data/share/html/images/p_ss2_1.gif +0 -0
- data/share/html/images/p_ss2_2.gif +0 -0
- data/share/html/images/p_ss2_3.gif +0 -0
- data/share/html/images/p_ss2_4.gif +0 -0
- data/share/html/images/p_ss2_5.gif +0 -0
- data/share/html/images/p_ss2_6.gif +0 -0
- data/share/html/images/p_ss2_7.gif +0 -0
- data/share/html/images/p_ss3_0.gif +0 -0
- data/share/html/images/p_ss3_1.gif +0 -0
- data/share/html/images/p_ss3_2.gif +0 -0
- data/share/html/images/p_ss3_3.gif +0 -0
- data/share/html/images/p_ss3_4.gif +0 -0
- data/share/html/images/p_ss3_5.gif +0 -0
- data/share/html/images/p_ss3_6.gif +0 -0
- data/share/html/images/p_ss3_7.gif +0 -0
- data/share/html/images/p_ss4_0.gif +0 -0
- data/share/html/images/p_ss4_1.gif +0 -0
- data/share/html/images/p_ss4_2.gif +0 -0
- data/share/html/images/p_ss4_3.gif +0 -0
- data/share/html/images/p_ss4_4.gif +0 -0
- data/share/html/images/p_ss4_5.gif +0 -0
- data/share/html/images/p_ss4_6.gif +0 -0
- data/share/html/images/p_ss4_7.gif +0 -0
- data/share/html/images/p_ss5_0.gif +0 -0
- data/share/html/images/p_ss5_1.gif +0 -0
- data/share/html/images/p_ss5_2.gif +0 -0
- data/share/html/images/p_ss5_3.gif +0 -0
- data/share/html/images/p_ss5_4.gif +0 -0
- data/share/html/images/p_ss5_5.gif +0 -0
- data/share/html/images/p_ss5_6.gif +0 -0
- data/share/html/images/p_ss5_7.gif +0 -0
- data/share/html/images/p_ss5r_1.png +0 -0
- data/share/html/images/p_ss5r_3.png +0 -0
- data/share/html/images/p_ss6_0.gif +0 -0
- data/share/html/images/p_ss6_1.gif +0 -0
- data/share/html/images/p_ss6_2.gif +0 -0
- data/share/html/images/p_ss6_3.gif +0 -0
- data/share/html/images/p_ss6_4.gif +0 -0
- data/share/html/images/p_ss6_5.gif +0 -0
- data/share/html/images/p_ss6_6.gif +0 -0
- data/share/html/images/p_ss6_7.gif +0 -0
- data/share/html/images/p_ss7_0.gif +0 -0
- data/share/html/images/p_ss7_1.gif +0 -0
- data/share/html/images/p_ss7_2.gif +0 -0
- data/share/html/images/p_ss7_3.gif +0 -0
- data/share/html/images/p_ss7_4.gif +0 -0
- data/share/html/images/p_ss7_5.gif +0 -0
- data/share/html/images/p_ss7_6.gif +0 -0
- data/share/html/images/p_ss7_7.gif +0 -0
- data/share/html/images/p_ss8_0.gif +0 -0
- data/share/html/images/p_ss8_1.gif +0 -0
- data/share/html/images/p_ss8_2.gif +0 -0
- data/share/html/images/p_ss8_3.gif +0 -0
- data/share/html/images/p_ss8_4.gif +0 -0
- data/share/html/images/p_ss8_5.gif +0 -0
- data/share/html/images/p_ss8_6.gif +0 -0
- data/share/html/images/p_ss8_7.gif +0 -0
- data/share/html/images/p_ss9_0.gif +0 -0
- data/share/html/images/p_ss9_1.gif +0 -0
- data/share/html/images/p_ss9_2.gif +0 -0
- data/share/html/images/p_ss9_3.gif +0 -0
- data/share/html/images/p_ss9_4.gif +0 -0
- data/share/html/images/p_ss9_5.gif +0 -0
- data/share/html/images/p_ss9_6.gif +0 -0
- data/share/html/images/p_ss9_7.gif +0 -0
- data/share/html/js/archive_player.coffee +379 -0
- data/share/html/js/archive_player.js +505 -0
- data/share/html/js/dytem.coffee +83 -0
- data/share/html/js/dytem.js +128 -0
- data/share/html/js/jquery-1.7.2.min.js +4 -0
- data/share/html/views/archive_player.erb +61 -0
- metadata +435 -0
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,379 @@
|
|
1
|
+
window.console ||= {}
|
2
|
+
window.console.log ||= ->
|
3
|
+
window.console.error ||= ->
|
4
|
+
|
5
|
+
TSUPAIS = [null, "E", "S", "W", "N", "P", "F", "C"]
|
6
|
+
|
7
|
+
TSUPAI_TO_IMAGE_NAME =
|
8
|
+
"E": "ji_e"
|
9
|
+
"S": "ji_s"
|
10
|
+
"W": "ji_w"
|
11
|
+
"N": "ji_n"
|
12
|
+
"P": "no"
|
13
|
+
"F": "ji_h"
|
14
|
+
"C": "ji_c"
|
15
|
+
|
16
|
+
BAKAZE_TO_STR =
|
17
|
+
"E": "東"
|
18
|
+
"S": "南"
|
19
|
+
"W": "西"
|
20
|
+
"N": "北"
|
21
|
+
|
22
|
+
kyokus = []
|
23
|
+
currentKyokuId = 0
|
24
|
+
currentActionId = 0
|
25
|
+
playerInfos = [{}, {}, {}, {}]
|
26
|
+
|
27
|
+
parsePai = (pai) ->
|
28
|
+
if pai.match(/^([1-9])(.)(r)?$/)
|
29
|
+
return {
|
30
|
+
type: RegExp.$2
|
31
|
+
number: parseInt(RegExp.$1)
|
32
|
+
red: if RegExp.$3 then true else false
|
33
|
+
}
|
34
|
+
else
|
35
|
+
return {
|
36
|
+
type: "t"
|
37
|
+
number: TSUPAIS.indexOf(pai)
|
38
|
+
red: false
|
39
|
+
}
|
40
|
+
|
41
|
+
comparePais = (lhs, rhs) ->
|
42
|
+
parsedLhs = parsePai(lhs)
|
43
|
+
lhsRep = parsedLhs.type + parsedLhs.number + (if parsedLhs.red then "1" else "0")
|
44
|
+
parsedRhs = parsePai(rhs)
|
45
|
+
rhsRep = parsedRhs.type + parsedRhs.number + (if parsedRhs.red then "1" else "0")
|
46
|
+
if lhsRep < rhsRep
|
47
|
+
return -1
|
48
|
+
else if lhsRep > rhsRep
|
49
|
+
return 1
|
50
|
+
else
|
51
|
+
return 0
|
52
|
+
|
53
|
+
sortPais = (pais) ->
|
54
|
+
pais.sort(comparePais)
|
55
|
+
|
56
|
+
paiToImageUrl = (pai, pose) ->
|
57
|
+
if pai
|
58
|
+
if pai == "?"
|
59
|
+
name = "bk"
|
60
|
+
ext = "gif"
|
61
|
+
else
|
62
|
+
parsedPai = parsePai(pai)
|
63
|
+
if parsedPai.type == "t"
|
64
|
+
name = TSUPAI_TO_IMAGE_NAME[pai]
|
65
|
+
else
|
66
|
+
redSuffix = if parsedPai.red then "r" else ""
|
67
|
+
name = "#{parsedPai.type}s#{parsedPai.number}#{redSuffix}"
|
68
|
+
ext = if parsedPai.red then "png" else "gif"
|
69
|
+
if pose == undefined
|
70
|
+
pose = 1
|
71
|
+
return "http://gimite.net/mjai/images/p_#{name}_#{pose}.#{ext}"
|
72
|
+
else
|
73
|
+
return "http://gimite.net/mjai/images/blank.png"
|
74
|
+
|
75
|
+
cloneBoard = (board) ->
|
76
|
+
newBoard = {}
|
77
|
+
for bk, bv of board
|
78
|
+
if bk == "players"
|
79
|
+
newBoard[bk] = []
|
80
|
+
for player in bv
|
81
|
+
newPlayer = {}
|
82
|
+
for pk, pv of player
|
83
|
+
newPlayer[pk] = pv
|
84
|
+
newBoard[bk].push(newPlayer)
|
85
|
+
else
|
86
|
+
newBoard[bk] = bv
|
87
|
+
return newBoard
|
88
|
+
|
89
|
+
initPlayers = (board) ->
|
90
|
+
for player in board.players
|
91
|
+
player.tehais = null
|
92
|
+
player.furos = []
|
93
|
+
player.ho = []
|
94
|
+
player.reach = false
|
95
|
+
player.reachHoIndex = null
|
96
|
+
|
97
|
+
removeRed = (pai) ->
|
98
|
+
return null if !pai
|
99
|
+
if pai.match(/^(.+)r$/)
|
100
|
+
return RegExp.$1
|
101
|
+
else
|
102
|
+
return pai
|
103
|
+
|
104
|
+
loadAction = (action) ->
|
105
|
+
|
106
|
+
#console.log(action.type, action)
|
107
|
+
if kyokus.length > 0
|
108
|
+
kyoku = kyokus[kyokus.length - 1]
|
109
|
+
board = cloneBoard(kyoku.actions[kyoku.actions.length - 1].board)
|
110
|
+
else
|
111
|
+
kyoku = null
|
112
|
+
board = null
|
113
|
+
if board && ("actor" of action)
|
114
|
+
actorPlayer = board.players[action.actor]
|
115
|
+
else
|
116
|
+
actorPlayer = null
|
117
|
+
if board && ("target" of action)
|
118
|
+
targetPlayer = board.players[action.target]
|
119
|
+
else
|
120
|
+
targetPlayer = null
|
121
|
+
|
122
|
+
switch action.type
|
123
|
+
when "start_game"
|
124
|
+
for i in [0...4]
|
125
|
+
playerInfos[i].name = action.names[i]
|
126
|
+
when "end_game"
|
127
|
+
null
|
128
|
+
when "start_kyoku"
|
129
|
+
kyoku =
|
130
|
+
actions: []
|
131
|
+
doraMarkers: [action.dora_marker]
|
132
|
+
bakaze: action.bakaze
|
133
|
+
kyokuNum: action.kyoku
|
134
|
+
honba: action.honba
|
135
|
+
kyokus.push(kyoku)
|
136
|
+
prevBoard = board
|
137
|
+
board =
|
138
|
+
players: [{}, {}, {}, {}]
|
139
|
+
initPlayers(board)
|
140
|
+
for i in [0...4]
|
141
|
+
board.players[i].tehais = action.tehais[i]
|
142
|
+
if prevBoard
|
143
|
+
board.players[i].score = prevBoard.players[i].score
|
144
|
+
else
|
145
|
+
board.players[i].score = 25000
|
146
|
+
when "end_kyoku"
|
147
|
+
null
|
148
|
+
when "tsumo"
|
149
|
+
actorPlayer.tehais = actorPlayer.tehais.concat([action.pai])
|
150
|
+
when "dahai"
|
151
|
+
deleteTehai(actorPlayer, action.pai)
|
152
|
+
actorPlayer.ho = actorPlayer.ho.concat([action.pai])
|
153
|
+
when "reach"
|
154
|
+
actorPlayer.reachHoIndex = actorPlayer.ho.length
|
155
|
+
when "reach_accepted"
|
156
|
+
actorPlayer.reach = true
|
157
|
+
when "chi", "pon", "daiminkan"
|
158
|
+
targetPlayer.ho = targetPlayer.ho[0...(targetPlayer.ho.length - 1)]
|
159
|
+
for pai in action.consumed
|
160
|
+
deleteTehai(actorPlayer, pai)
|
161
|
+
actorPlayer.furos = actorPlayer.furos.concat([
|
162
|
+
type: action.type
|
163
|
+
taken: action.pai
|
164
|
+
consumed: action.consumed
|
165
|
+
target: action.target
|
166
|
+
])
|
167
|
+
when "ankan"
|
168
|
+
for pai in action.consumed
|
169
|
+
deleteTehai(actorPlayer, pai)
|
170
|
+
actorPlayer.furos = actorPlayer.furos.concat([
|
171
|
+
type: action.type
|
172
|
+
consumed: action.consumed
|
173
|
+
])
|
174
|
+
when "kakan"
|
175
|
+
deleteTehai(actorPlayer, action.pai)
|
176
|
+
actorPlayer.furos = actorPlayer.furos.concat([])
|
177
|
+
furos = actorPlayer.furos
|
178
|
+
for i in [0...furos.length]
|
179
|
+
if furos[i].type == "pon" && removeRed(furos[i].taken) == removeRed(action.pai)
|
180
|
+
furos[i] =
|
181
|
+
type: "kakan"
|
182
|
+
taken: action.pai
|
183
|
+
consumed: action.consumed
|
184
|
+
target: furos[i].target
|
185
|
+
when "hora", "ryukyoku"
|
186
|
+
null
|
187
|
+
when "dora"
|
188
|
+
board.doraMarkers = board.doraMarkers.concat([action.dora_marker])
|
189
|
+
when "log"
|
190
|
+
if kyoku
|
191
|
+
kyoku.actions[kyoku.actions.length - 1].log = action.text
|
192
|
+
else
|
193
|
+
throw "unknown action: #{action.type}"
|
194
|
+
|
195
|
+
if action.scores
|
196
|
+
for i in [0...4]
|
197
|
+
board.players[i].score = action.scores[i]
|
198
|
+
|
199
|
+
if kyoku
|
200
|
+
for i in [0...4]
|
201
|
+
if i != action.actor
|
202
|
+
ripai(board.players[i])
|
203
|
+
if action.type != "log"
|
204
|
+
action.board = board
|
205
|
+
#dumpBoard(board)
|
206
|
+
kyoku.actions.push(action)
|
207
|
+
|
208
|
+
deleteTehai = (player, pai) ->
|
209
|
+
player.tehais = player.tehais.concat([])
|
210
|
+
idx = player.tehais.lastIndexOf(pai)
|
211
|
+
if idx < 0
|
212
|
+
idx = player.tehais.lastIndexOf("?")
|
213
|
+
throw "pai not in tehai" if idx < 0
|
214
|
+
player.tehais[idx] = null
|
215
|
+
|
216
|
+
ripai = (player) ->
|
217
|
+
if player.tehais
|
218
|
+
player.tehais = (pai for pai in player.tehais when pai)
|
219
|
+
sortPais(player.tehais)
|
220
|
+
|
221
|
+
dumpBoard = (board) ->
|
222
|
+
for i in [0...4]
|
223
|
+
player = board.players[i]
|
224
|
+
if player.tehais
|
225
|
+
tehaisStr = player.tehais.join(" ")
|
226
|
+
for furo in player.furos
|
227
|
+
consumedStr = furo.consumed.join(" ")
|
228
|
+
tehaisStr += " [#{furo.taken}/#{consumedStr}]"
|
229
|
+
console.log("[#{i}] tehais: #{tehaisStr}")
|
230
|
+
if player.ho
|
231
|
+
hoStr = player.ho.join(" ")
|
232
|
+
console.log("[#{i}] ho: #{hoStr}")
|
233
|
+
|
234
|
+
renderPai = (pai, view, pose) ->
|
235
|
+
if pose == undefined
|
236
|
+
pose = 1
|
237
|
+
view.attr("src", paiToImageUrl(pai, pose))
|
238
|
+
switch pose
|
239
|
+
when 1
|
240
|
+
view.addClass("pai")
|
241
|
+
view.removeClass("laid-pai")
|
242
|
+
when 3
|
243
|
+
view.addClass("laid-pai")
|
244
|
+
view.removeClass("pai")
|
245
|
+
else
|
246
|
+
throw("unknown pose")
|
247
|
+
|
248
|
+
renderPais = (pais, view, poses) ->
|
249
|
+
pais ||= []
|
250
|
+
poses ||= []
|
251
|
+
view.resize(pais.length)
|
252
|
+
for i in [0...pais.length]
|
253
|
+
renderPai(pais[i], view.at(i), poses[i])
|
254
|
+
|
255
|
+
renderHo = (player, offset, pais, view) ->
|
256
|
+
if player.reachHoIndex == null
|
257
|
+
reachIndex = null
|
258
|
+
else
|
259
|
+
reachIndex = player.reachHoIndex - offset
|
260
|
+
view.resize(pais.length)
|
261
|
+
for i in [0...pais.length]
|
262
|
+
renderPai(pais[i], view.at(i), if i == reachIndex then 3 else 1)
|
263
|
+
|
264
|
+
renderAction = (action) ->
|
265
|
+
#console.log(action.type, action)
|
266
|
+
displayAction = {}
|
267
|
+
for k, v of action
|
268
|
+
if k != "board"
|
269
|
+
displayAction[k] = v
|
270
|
+
$("#action-label").text(JSON.stringify(displayAction))
|
271
|
+
#dumpBoard(action.board)
|
272
|
+
kyoku = getCurrentKyoku()
|
273
|
+
for i in [0...4]
|
274
|
+
player = action.board.players[i]
|
275
|
+
view = Dytem.players.at(i)
|
276
|
+
infoView = Dytem.playerInfos.at(i)
|
277
|
+
infoView.score.text(player.score)
|
278
|
+
if !player.tehais
|
279
|
+
renderPais([], view.tehais)
|
280
|
+
view.tsumoPai.hide()
|
281
|
+
else if player.tehais.length % 3 == 2
|
282
|
+
renderPais(player.tehais[0...(player.tehais.length - 1)], view.tehais)
|
283
|
+
view.tsumoPai.show()
|
284
|
+
renderPai(player.tehais[player.tehais.length - 1], view.tsumoPai)
|
285
|
+
else
|
286
|
+
renderPais(player.tehais, view.tehais)
|
287
|
+
view.tsumoPai.hide()
|
288
|
+
ho = player.ho || []
|
289
|
+
renderHo(player, 0, ho[0...6], view.hoRows.at(0).pais)
|
290
|
+
renderHo(player, 6, ho[6...12], view.hoRows.at(1).pais)
|
291
|
+
renderHo(player, 12, ho[12...], view.hoRows.at(2).pais)
|
292
|
+
view.furos.resize(player.furos.length)
|
293
|
+
if player.furos
|
294
|
+
j = player.furos.length - 1
|
295
|
+
while j >= 0
|
296
|
+
furo = player.furos[j]
|
297
|
+
furoView = view.furos.at(player.furos.length - 1 - j)
|
298
|
+
if furo.type == "ankan"
|
299
|
+
pais = ["?"].concat(furo.consumed[0...2]).concat(["?"])
|
300
|
+
poses = [1, 1, 1, 1]
|
301
|
+
else
|
302
|
+
dir = (4 + furo.target - i) % 4
|
303
|
+
if furo.type in ["daiminkan", "kakan"]
|
304
|
+
laidPos = [null, 3, 1, 0][dir]
|
305
|
+
else
|
306
|
+
laidPos = [null, 2, 1, 0][dir]
|
307
|
+
pais = furo.consumed.concat([])
|
308
|
+
poses = [1, 1, 1]
|
309
|
+
pais[laidPos...laidPos] = [furo.taken]
|
310
|
+
poses[laidPos...laidPos] = [3]
|
311
|
+
renderPais(pais, furoView.pais, poses)
|
312
|
+
--j
|
313
|
+
wanpais = ["?", "?", "?", "?", "?", "?"]
|
314
|
+
for i in [0...kyoku.doraMarkers.length]
|
315
|
+
wanpais[i + 2] = kyoku.doraMarkers[i]
|
316
|
+
renderPais(wanpais, Dytem.wanpais)
|
317
|
+
|
318
|
+
getCurrentKyoku = ->
|
319
|
+
return kyokus[currentKyokuId]
|
320
|
+
|
321
|
+
renderCurrentAction = ->
|
322
|
+
renderAction(getCurrentKyoku().actions[currentActionId])
|
323
|
+
|
324
|
+
goNext = ->
|
325
|
+
return if currentActionId == getCurrentKyoku().actions.length - 1
|
326
|
+
++currentActionId
|
327
|
+
$("#action-id-label").val(currentActionId)
|
328
|
+
renderCurrentAction()
|
329
|
+
|
330
|
+
goBack = ->
|
331
|
+
return if currentActionId == 0
|
332
|
+
--currentActionId
|
333
|
+
$("#action-id-label").val(currentActionId)
|
334
|
+
renderCurrentAction()
|
335
|
+
|
336
|
+
$ ->
|
337
|
+
|
338
|
+
$(window).bind "mousewheel", (e) ->
|
339
|
+
e.preventDefault()
|
340
|
+
if e.originalEvent.wheelDelta < 0
|
341
|
+
goNext()
|
342
|
+
else if e.originalEvent.wheelDelta > 0
|
343
|
+
goBack()
|
344
|
+
|
345
|
+
$("#prev-button").click(goBack)
|
346
|
+
$("#next-button").click(goNext)
|
347
|
+
|
348
|
+
$("#go-button").click ->
|
349
|
+
currentActionId = parseInt($("#action-id-label").val())
|
350
|
+
renderCurrentAction()
|
351
|
+
|
352
|
+
$("#kyokuSelector").change ->
|
353
|
+
currentKyokuId = parseInt($("#kyokuSelector").val())
|
354
|
+
currentActionId = 0
|
355
|
+
renderCurrentAction()
|
356
|
+
|
357
|
+
for action in allActions
|
358
|
+
loadAction(action)
|
359
|
+
|
360
|
+
Dytem.init()
|
361
|
+
for i in [0...4]
|
362
|
+
playerView = Dytem.players.append()
|
363
|
+
playerView.addClass("player-#{i}")
|
364
|
+
for j in [0...3]
|
365
|
+
playerView.hoRows.append()
|
366
|
+
playerInfoView = Dytem.playerInfos.append()
|
367
|
+
playerInfoView.index.text(i)
|
368
|
+
playerInfoView.name.text(playerInfos[i].name)
|
369
|
+
|
370
|
+
for i in [0...kyokus.length]
|
371
|
+
bakazeStr = BAKAZE_TO_STR[kyokus[i].bakaze]
|
372
|
+
honba = kyokus[i].honba
|
373
|
+
kyokuNum = kyokus[i].kyokuNum
|
374
|
+
label = "#{bakazeStr}#{kyokuNum}局 #{honba}本場"
|
375
|
+
$("#kyokuSelector").get(0).options[i] = new Option(label, i)
|
376
|
+
console.log("loaded")
|
377
|
+
|
378
|
+
#currentActionId = 78
|
379
|
+
renderCurrentAction()
|
@@ -0,0 +1,505 @@
|
|
1
|
+
var BAKAZE_TO_STR, TSUPAIS, TSUPAI_TO_IMAGE_NAME, cloneBoard, comparePais, currentActionId, currentKyokuId, deleteTehai, dumpBoard, getCurrentKyoku, goBack, goNext, initPlayers, kyokus, loadAction, paiToImageUrl, parsePai, playerInfos, removeRed, renderAction, renderCurrentAction, renderHo, renderPai, renderPais, ripai, sortPais, _base, _base2;
|
2
|
+
|
3
|
+
window.console || (window.console = {});
|
4
|
+
|
5
|
+
(_base = window.console).log || (_base.log = function() {});
|
6
|
+
|
7
|
+
(_base2 = window.console).error || (_base2.error = function() {});
|
8
|
+
|
9
|
+
TSUPAIS = [null, "E", "S", "W", "N", "P", "F", "C"];
|
10
|
+
|
11
|
+
TSUPAI_TO_IMAGE_NAME = {
|
12
|
+
"E": "ji_e",
|
13
|
+
"S": "ji_s",
|
14
|
+
"W": "ji_w",
|
15
|
+
"N": "ji_n",
|
16
|
+
"P": "no",
|
17
|
+
"F": "ji_h",
|
18
|
+
"C": "ji_c"
|
19
|
+
};
|
20
|
+
|
21
|
+
BAKAZE_TO_STR = {
|
22
|
+
"E": "東",
|
23
|
+
"S": "南",
|
24
|
+
"W": "西",
|
25
|
+
"N": "北"
|
26
|
+
};
|
27
|
+
|
28
|
+
kyokus = [];
|
29
|
+
|
30
|
+
currentKyokuId = 0;
|
31
|
+
|
32
|
+
currentActionId = 0;
|
33
|
+
|
34
|
+
playerInfos = [{}, {}, {}, {}];
|
35
|
+
|
36
|
+
parsePai = function(pai) {
|
37
|
+
if (pai.match(/^([1-9])(.)(r)?$/)) {
|
38
|
+
return {
|
39
|
+
type: RegExp.$2,
|
40
|
+
number: parseInt(RegExp.$1),
|
41
|
+
red: RegExp.$3 ? true : false
|
42
|
+
};
|
43
|
+
} else {
|
44
|
+
return {
|
45
|
+
type: "t",
|
46
|
+
number: TSUPAIS.indexOf(pai),
|
47
|
+
red: false
|
48
|
+
};
|
49
|
+
}
|
50
|
+
};
|
51
|
+
|
52
|
+
comparePais = function(lhs, rhs) {
|
53
|
+
var lhsRep, parsedLhs, parsedRhs, rhsRep;
|
54
|
+
parsedLhs = parsePai(lhs);
|
55
|
+
lhsRep = parsedLhs.type + parsedLhs.number + (parsedLhs.red ? "1" : "0");
|
56
|
+
parsedRhs = parsePai(rhs);
|
57
|
+
rhsRep = parsedRhs.type + parsedRhs.number + (parsedRhs.red ? "1" : "0");
|
58
|
+
if (lhsRep < rhsRep) {
|
59
|
+
return -1;
|
60
|
+
} else if (lhsRep > rhsRep) {
|
61
|
+
return 1;
|
62
|
+
} else {
|
63
|
+
return 0;
|
64
|
+
}
|
65
|
+
};
|
66
|
+
|
67
|
+
sortPais = function(pais) {
|
68
|
+
return pais.sort(comparePais);
|
69
|
+
};
|
70
|
+
|
71
|
+
paiToImageUrl = function(pai, pose) {
|
72
|
+
var ext, name, parsedPai, redSuffix;
|
73
|
+
if (pai) {
|
74
|
+
if (pai === "?") {
|
75
|
+
name = "bk";
|
76
|
+
ext = "gif";
|
77
|
+
} else {
|
78
|
+
parsedPai = parsePai(pai);
|
79
|
+
if (parsedPai.type === "t") {
|
80
|
+
name = TSUPAI_TO_IMAGE_NAME[pai];
|
81
|
+
} else {
|
82
|
+
redSuffix = parsedPai.red ? "r" : "";
|
83
|
+
name = "" + parsedPai.type + "s" + parsedPai.number + redSuffix;
|
84
|
+
}
|
85
|
+
ext = parsedPai.red ? "png" : "gif";
|
86
|
+
}
|
87
|
+
if (pose === void 0) pose = 1;
|
88
|
+
return "http://gimite.net/mjai/images/p_" + name + "_" + pose + "." + ext;
|
89
|
+
} else {
|
90
|
+
return "http://gimite.net/mjai/images/blank.png";
|
91
|
+
}
|
92
|
+
};
|
93
|
+
|
94
|
+
cloneBoard = function(board) {
|
95
|
+
var bk, bv, newBoard, newPlayer, pk, player, pv, _i, _len;
|
96
|
+
newBoard = {};
|
97
|
+
for (bk in board) {
|
98
|
+
bv = board[bk];
|
99
|
+
if (bk === "players") {
|
100
|
+
newBoard[bk] = [];
|
101
|
+
for (_i = 0, _len = bv.length; _i < _len; _i++) {
|
102
|
+
player = bv[_i];
|
103
|
+
newPlayer = {};
|
104
|
+
for (pk in player) {
|
105
|
+
pv = player[pk];
|
106
|
+
newPlayer[pk] = pv;
|
107
|
+
}
|
108
|
+
newBoard[bk].push(newPlayer);
|
109
|
+
}
|
110
|
+
} else {
|
111
|
+
newBoard[bk] = bv;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
return newBoard;
|
115
|
+
};
|
116
|
+
|
117
|
+
initPlayers = function(board) {
|
118
|
+
var player, _i, _len, _ref, _results;
|
119
|
+
_ref = board.players;
|
120
|
+
_results = [];
|
121
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
122
|
+
player = _ref[_i];
|
123
|
+
player.tehais = null;
|
124
|
+
player.furos = [];
|
125
|
+
player.ho = [];
|
126
|
+
player.reach = false;
|
127
|
+
_results.push(player.reachHoIndex = null);
|
128
|
+
}
|
129
|
+
return _results;
|
130
|
+
};
|
131
|
+
|
132
|
+
removeRed = function(pai) {
|
133
|
+
if (!pai) return null;
|
134
|
+
if (pai.match(/^(.+)r$/)) {
|
135
|
+
return RegExp.$1;
|
136
|
+
} else {
|
137
|
+
return pai;
|
138
|
+
}
|
139
|
+
};
|
140
|
+
|
141
|
+
loadAction = function(action) {
|
142
|
+
var actorPlayer, board, furos, i, kyoku, pai, prevBoard, targetPlayer, _i, _j, _len, _len2, _ref, _ref2, _ref3;
|
143
|
+
if (kyokus.length > 0) {
|
144
|
+
kyoku = kyokus[kyokus.length - 1];
|
145
|
+
board = cloneBoard(kyoku.actions[kyoku.actions.length - 1].board);
|
146
|
+
} else {
|
147
|
+
kyoku = null;
|
148
|
+
board = null;
|
149
|
+
}
|
150
|
+
if (board && ("actor" in action)) {
|
151
|
+
actorPlayer = board.players[action.actor];
|
152
|
+
} else {
|
153
|
+
actorPlayer = null;
|
154
|
+
}
|
155
|
+
if (board && ("target" in action)) {
|
156
|
+
targetPlayer = board.players[action.target];
|
157
|
+
} else {
|
158
|
+
targetPlayer = null;
|
159
|
+
}
|
160
|
+
switch (action.type) {
|
161
|
+
case "start_game":
|
162
|
+
for (i = 0; i < 4; i++) {
|
163
|
+
playerInfos[i].name = action.names[i];
|
164
|
+
}
|
165
|
+
break;
|
166
|
+
case "end_game":
|
167
|
+
null;
|
168
|
+
break;
|
169
|
+
case "start_kyoku":
|
170
|
+
kyoku = {
|
171
|
+
actions: [],
|
172
|
+
doraMarkers: [action.dora_marker],
|
173
|
+
bakaze: action.bakaze,
|
174
|
+
kyokuNum: action.kyoku,
|
175
|
+
honba: action.honba
|
176
|
+
};
|
177
|
+
kyokus.push(kyoku);
|
178
|
+
prevBoard = board;
|
179
|
+
board = {
|
180
|
+
players: [{}, {}, {}, {}]
|
181
|
+
};
|
182
|
+
initPlayers(board);
|
183
|
+
for (i = 0; i < 4; i++) {
|
184
|
+
board.players[i].tehais = action.tehais[i];
|
185
|
+
if (prevBoard) {
|
186
|
+
board.players[i].score = prevBoard.players[i].score;
|
187
|
+
} else {
|
188
|
+
board.players[i].score = 25000;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
break;
|
192
|
+
case "end_kyoku":
|
193
|
+
null;
|
194
|
+
break;
|
195
|
+
case "tsumo":
|
196
|
+
actorPlayer.tehais = actorPlayer.tehais.concat([action.pai]);
|
197
|
+
break;
|
198
|
+
case "dahai":
|
199
|
+
deleteTehai(actorPlayer, action.pai);
|
200
|
+
actorPlayer.ho = actorPlayer.ho.concat([action.pai]);
|
201
|
+
break;
|
202
|
+
case "reach":
|
203
|
+
actorPlayer.reachHoIndex = actorPlayer.ho.length;
|
204
|
+
break;
|
205
|
+
case "reach_accepted":
|
206
|
+
actorPlayer.reach = true;
|
207
|
+
break;
|
208
|
+
case "chi":
|
209
|
+
case "pon":
|
210
|
+
case "daiminkan":
|
211
|
+
targetPlayer.ho = targetPlayer.ho.slice(0, (targetPlayer.ho.length - 1));
|
212
|
+
_ref = action.consumed;
|
213
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
214
|
+
pai = _ref[_i];
|
215
|
+
deleteTehai(actorPlayer, pai);
|
216
|
+
}
|
217
|
+
actorPlayer.furos = actorPlayer.furos.concat([
|
218
|
+
{
|
219
|
+
type: action.type,
|
220
|
+
taken: action.pai,
|
221
|
+
consumed: action.consumed,
|
222
|
+
target: action.target
|
223
|
+
}
|
224
|
+
]);
|
225
|
+
break;
|
226
|
+
case "ankan":
|
227
|
+
_ref2 = action.consumed;
|
228
|
+
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
|
229
|
+
pai = _ref2[_j];
|
230
|
+
deleteTehai(actorPlayer, pai);
|
231
|
+
}
|
232
|
+
actorPlayer.furos = actorPlayer.furos.concat([
|
233
|
+
{
|
234
|
+
type: action.type,
|
235
|
+
consumed: action.consumed
|
236
|
+
}
|
237
|
+
]);
|
238
|
+
break;
|
239
|
+
case "kakan":
|
240
|
+
deleteTehai(actorPlayer, action.pai);
|
241
|
+
actorPlayer.furos = actorPlayer.furos.concat([]);
|
242
|
+
furos = actorPlayer.furos;
|
243
|
+
for (i = 0, _ref3 = furos.length; 0 <= _ref3 ? i < _ref3 : i > _ref3; 0 <= _ref3 ? i++ : i--) {
|
244
|
+
if (furos[i].type === "pon" && removeRed(furos[i].taken) === removeRed(action.pai)) {
|
245
|
+
furos[i] = {
|
246
|
+
type: "kakan",
|
247
|
+
taken: action.pai,
|
248
|
+
consumed: action.consumed,
|
249
|
+
target: furos[i].target
|
250
|
+
};
|
251
|
+
}
|
252
|
+
}
|
253
|
+
break;
|
254
|
+
case "hora":
|
255
|
+
case "ryukyoku":
|
256
|
+
null;
|
257
|
+
break;
|
258
|
+
case "dora":
|
259
|
+
board.doraMarkers = board.doraMarkers.concat([action.dora_marker]);
|
260
|
+
break;
|
261
|
+
case "log":
|
262
|
+
if (kyoku) kyoku.actions[kyoku.actions.length - 1].log = action.text;
|
263
|
+
break;
|
264
|
+
default:
|
265
|
+
throw "unknown action: " + action.type;
|
266
|
+
}
|
267
|
+
if (action.scores) {
|
268
|
+
for (i = 0; i < 4; i++) {
|
269
|
+
board.players[i].score = action.scores[i];
|
270
|
+
}
|
271
|
+
}
|
272
|
+
if (kyoku) {
|
273
|
+
for (i = 0; i < 4; i++) {
|
274
|
+
if (i !== action.actor) ripai(board.players[i]);
|
275
|
+
}
|
276
|
+
if (action.type !== "log") {
|
277
|
+
action.board = board;
|
278
|
+
return kyoku.actions.push(action);
|
279
|
+
}
|
280
|
+
}
|
281
|
+
};
|
282
|
+
|
283
|
+
deleteTehai = function(player, pai) {
|
284
|
+
var idx;
|
285
|
+
player.tehais = player.tehais.concat([]);
|
286
|
+
idx = player.tehais.lastIndexOf(pai);
|
287
|
+
if (idx < 0) idx = player.tehais.lastIndexOf("?");
|
288
|
+
if (idx < 0) throw "pai not in tehai";
|
289
|
+
return player.tehais[idx] = null;
|
290
|
+
};
|
291
|
+
|
292
|
+
ripai = function(player) {
|
293
|
+
var pai;
|
294
|
+
if (player.tehais) {
|
295
|
+
player.tehais = (function() {
|
296
|
+
var _i, _len, _ref, _results;
|
297
|
+
_ref = player.tehais;
|
298
|
+
_results = [];
|
299
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
300
|
+
pai = _ref[_i];
|
301
|
+
if (pai) _results.push(pai);
|
302
|
+
}
|
303
|
+
return _results;
|
304
|
+
})();
|
305
|
+
return sortPais(player.tehais);
|
306
|
+
}
|
307
|
+
};
|
308
|
+
|
309
|
+
dumpBoard = function(board) {
|
310
|
+
var consumedStr, furo, hoStr, i, player, tehaisStr, _i, _len, _ref, _results;
|
311
|
+
_results = [];
|
312
|
+
for (i = 0; i < 4; i++) {
|
313
|
+
player = board.players[i];
|
314
|
+
if (player.tehais) {
|
315
|
+
tehaisStr = player.tehais.join(" ");
|
316
|
+
_ref = player.furos;
|
317
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
318
|
+
furo = _ref[_i];
|
319
|
+
consumedStr = furo.consumed.join(" ");
|
320
|
+
tehaisStr += " [" + furo.taken + "/" + consumedStr + "]";
|
321
|
+
}
|
322
|
+
console.log("[" + i + "] tehais: " + tehaisStr);
|
323
|
+
}
|
324
|
+
if (player.ho) {
|
325
|
+
hoStr = player.ho.join(" ");
|
326
|
+
_results.push(console.log("[" + i + "] ho: " + hoStr));
|
327
|
+
} else {
|
328
|
+
_results.push(void 0);
|
329
|
+
}
|
330
|
+
}
|
331
|
+
return _results;
|
332
|
+
};
|
333
|
+
|
334
|
+
renderPai = function(pai, view, pose) {
|
335
|
+
if (pose === void 0) pose = 1;
|
336
|
+
view.attr("src", paiToImageUrl(pai, pose));
|
337
|
+
switch (pose) {
|
338
|
+
case 1:
|
339
|
+
view.addClass("pai");
|
340
|
+
return view.removeClass("laid-pai");
|
341
|
+
case 3:
|
342
|
+
view.addClass("laid-pai");
|
343
|
+
return view.removeClass("pai");
|
344
|
+
default:
|
345
|
+
throw "unknown pose";
|
346
|
+
}
|
347
|
+
};
|
348
|
+
|
349
|
+
renderPais = function(pais, view, poses) {
|
350
|
+
var i, _ref, _results;
|
351
|
+
pais || (pais = []);
|
352
|
+
poses || (poses = []);
|
353
|
+
view.resize(pais.length);
|
354
|
+
_results = [];
|
355
|
+
for (i = 0, _ref = pais.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
|
356
|
+
_results.push(renderPai(pais[i], view.at(i), poses[i]));
|
357
|
+
}
|
358
|
+
return _results;
|
359
|
+
};
|
360
|
+
|
361
|
+
renderHo = function(player, offset, pais, view) {
|
362
|
+
var i, reachIndex, _ref, _results;
|
363
|
+
if (player.reachHoIndex === null) {
|
364
|
+
reachIndex = null;
|
365
|
+
} else {
|
366
|
+
reachIndex = player.reachHoIndex - offset;
|
367
|
+
}
|
368
|
+
view.resize(pais.length);
|
369
|
+
_results = [];
|
370
|
+
for (i = 0, _ref = pais.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
|
371
|
+
_results.push(renderPai(pais[i], view.at(i), i === reachIndex ? 3 : 1));
|
372
|
+
}
|
373
|
+
return _results;
|
374
|
+
};
|
375
|
+
|
376
|
+
renderAction = function(action) {
|
377
|
+
var dir, displayAction, furo, furoView, ho, i, infoView, j, k, kyoku, laidPos, pais, player, poses, v, view, wanpais, _ref, _ref2, _ref3, _ref4;
|
378
|
+
displayAction = {};
|
379
|
+
for (k in action) {
|
380
|
+
v = action[k];
|
381
|
+
if (k !== "board") displayAction[k] = v;
|
382
|
+
}
|
383
|
+
$("#action-label").text(JSON.stringify(displayAction));
|
384
|
+
kyoku = getCurrentKyoku();
|
385
|
+
for (i = 0; i < 4; i++) {
|
386
|
+
player = action.board.players[i];
|
387
|
+
view = Dytem.players.at(i);
|
388
|
+
infoView = Dytem.playerInfos.at(i);
|
389
|
+
infoView.score.text(player.score);
|
390
|
+
if (!player.tehais) {
|
391
|
+
renderPais([], view.tehais);
|
392
|
+
view.tsumoPai.hide();
|
393
|
+
} else if (player.tehais.length % 3 === 2) {
|
394
|
+
renderPais(player.tehais.slice(0, (player.tehais.length - 1)), view.tehais);
|
395
|
+
view.tsumoPai.show();
|
396
|
+
renderPai(player.tehais[player.tehais.length - 1], view.tsumoPai);
|
397
|
+
} else {
|
398
|
+
renderPais(player.tehais, view.tehais);
|
399
|
+
view.tsumoPai.hide();
|
400
|
+
}
|
401
|
+
ho = player.ho || [];
|
402
|
+
renderHo(player, 0, ho.slice(0, 6), view.hoRows.at(0).pais);
|
403
|
+
renderHo(player, 6, ho.slice(6, 12), view.hoRows.at(1).pais);
|
404
|
+
renderHo(player, 12, ho.slice(12), view.hoRows.at(2).pais);
|
405
|
+
view.furos.resize(player.furos.length);
|
406
|
+
if (player.furos) {
|
407
|
+
j = player.furos.length - 1;
|
408
|
+
while (j >= 0) {
|
409
|
+
furo = player.furos[j];
|
410
|
+
furoView = view.furos.at(player.furos.length - 1 - j);
|
411
|
+
if (furo.type === "ankan") {
|
412
|
+
pais = ["?"].concat(furo.consumed.slice(0, 2)).concat(["?"]);
|
413
|
+
poses = [1, 1, 1, 1];
|
414
|
+
} else {
|
415
|
+
dir = (4 + furo.target - i) % 4;
|
416
|
+
if ((_ref = furo.type) === "daiminkan" || _ref === "kakan") {
|
417
|
+
laidPos = [null, 3, 1, 0][dir];
|
418
|
+
} else {
|
419
|
+
laidPos = [null, 2, 1, 0][dir];
|
420
|
+
}
|
421
|
+
pais = furo.consumed.concat([]);
|
422
|
+
poses = [1, 1, 1];
|
423
|
+
[].splice.apply(pais, [laidPos, laidPos - laidPos].concat(_ref2 = [furo.taken])), _ref2;
|
424
|
+
[].splice.apply(poses, [laidPos, laidPos - laidPos].concat(_ref3 = [3])), _ref3;
|
425
|
+
}
|
426
|
+
renderPais(pais, furoView.pais, poses);
|
427
|
+
--j;
|
428
|
+
}
|
429
|
+
}
|
430
|
+
}
|
431
|
+
wanpais = ["?", "?", "?", "?", "?", "?"];
|
432
|
+
for (i = 0, _ref4 = kyoku.doraMarkers.length; 0 <= _ref4 ? i < _ref4 : i > _ref4; 0 <= _ref4 ? i++ : i--) {
|
433
|
+
wanpais[i + 2] = kyoku.doraMarkers[i];
|
434
|
+
}
|
435
|
+
return renderPais(wanpais, Dytem.wanpais);
|
436
|
+
};
|
437
|
+
|
438
|
+
getCurrentKyoku = function() {
|
439
|
+
return kyokus[currentKyokuId];
|
440
|
+
};
|
441
|
+
|
442
|
+
renderCurrentAction = function() {
|
443
|
+
return renderAction(getCurrentKyoku().actions[currentActionId]);
|
444
|
+
};
|
445
|
+
|
446
|
+
goNext = function() {
|
447
|
+
if (currentActionId === getCurrentKyoku().actions.length - 1) return;
|
448
|
+
++currentActionId;
|
449
|
+
$("#action-id-label").val(currentActionId);
|
450
|
+
return renderCurrentAction();
|
451
|
+
};
|
452
|
+
|
453
|
+
goBack = function() {
|
454
|
+
if (currentActionId === 0) return;
|
455
|
+
--currentActionId;
|
456
|
+
$("#action-id-label").val(currentActionId);
|
457
|
+
return renderCurrentAction();
|
458
|
+
};
|
459
|
+
|
460
|
+
$(function() {
|
461
|
+
var action, bakazeStr, honba, i, j, kyokuNum, label, playerInfoView, playerView, _i, _len, _ref;
|
462
|
+
$(window).bind("mousewheel", function(e) {
|
463
|
+
e.preventDefault();
|
464
|
+
if (e.originalEvent.wheelDelta < 0) {
|
465
|
+
return goNext();
|
466
|
+
} else if (e.originalEvent.wheelDelta > 0) {
|
467
|
+
return goBack();
|
468
|
+
}
|
469
|
+
});
|
470
|
+
$("#prev-button").click(goBack);
|
471
|
+
$("#next-button").click(goNext);
|
472
|
+
$("#go-button").click(function() {
|
473
|
+
currentActionId = parseInt($("#action-id-label").val());
|
474
|
+
return renderCurrentAction();
|
475
|
+
});
|
476
|
+
$("#kyokuSelector").change(function() {
|
477
|
+
currentKyokuId = parseInt($("#kyokuSelector").val());
|
478
|
+
currentActionId = 0;
|
479
|
+
return renderCurrentAction();
|
480
|
+
});
|
481
|
+
for (_i = 0, _len = allActions.length; _i < _len; _i++) {
|
482
|
+
action = allActions[_i];
|
483
|
+
loadAction(action);
|
484
|
+
}
|
485
|
+
Dytem.init();
|
486
|
+
for (i = 0; i < 4; i++) {
|
487
|
+
playerView = Dytem.players.append();
|
488
|
+
playerView.addClass("player-" + i);
|
489
|
+
for (j = 0; j < 3; j++) {
|
490
|
+
playerView.hoRows.append();
|
491
|
+
}
|
492
|
+
playerInfoView = Dytem.playerInfos.append();
|
493
|
+
playerInfoView.index.text(i);
|
494
|
+
playerInfoView.name.text(playerInfos[i].name);
|
495
|
+
}
|
496
|
+
for (i = 0, _ref = kyokus.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
|
497
|
+
bakazeStr = BAKAZE_TO_STR[kyokus[i].bakaze];
|
498
|
+
honba = kyokus[i].honba;
|
499
|
+
kyokuNum = kyokus[i].kyokuNum;
|
500
|
+
label = "" + bakazeStr + kyokuNum + "局 " + honba + "本場";
|
501
|
+
$("#kyokuSelector").get(0).options[i] = new Option(label, i);
|
502
|
+
}
|
503
|
+
console.log("loaded");
|
504
|
+
return renderCurrentAction();
|
505
|
+
});
|