mjai 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/mjai/action.rb +4 -0
- data/lib/mjai/active_game.rb +29 -8
- data/lib/mjai/game.rb +41 -16
- data/lib/mjai/game_stats.rb +47 -0
- data/lib/mjai/hora.rb +1 -1
- data/lib/mjai/jsonizable.rb +32 -12
- data/lib/mjai/mjai_command.rb +9 -1
- data/lib/mjai/mjson_archive.rb +8 -4
- data/lib/mjai/player.rb +54 -23
- data/lib/mjai/shanten_analysis.rb +1 -0
- data/lib/mjai/shanten_player.rb +1 -1
- data/lib/mjai/tcp_active_game_server.rb +10 -2
- data/lib/mjai/tcp_client_game.rb +1 -0
- data/lib/mjai/tcp_game_server.rb +37 -26
- data/lib/mjai/tcp_player.rb +2 -4
- data/lib/mjai/tenhou_archive.rb +13 -5
- data/lib/mjai/ymatsux_shanten_analysis.rb +105 -0
- data/share/html/css/style.css +28 -24
- data/share/html/css/style.scss +4 -4
- data/share/html/js/archive_player.coffee +7 -9
- data/share/html/js/archive_player.js +68 -49
- metadata +4 -2
@@ -1,10 +1,11 @@
|
|
1
|
-
|
1
|
+
// Generated by CoffeeScript 1.6.3
|
2
|
+
var BAKAZE_TO_STR, TSUPAIS, TSUPAI_TO_IMAGE_NAME, cloneBoard, comparePais, currentActionId, currentKyokuId, currentViewpoint, deleteTehai, dumpBoard, getCurrentKyoku, goBack, goNext, initPlayers, kyokus, loadAction, paiToImageUrl, parsePai, playerInfos, removeRed, renderAction, renderCurrentAction, renderHo, renderPai, renderPais, ripai, sortPais, _base, _base1;
|
2
3
|
|
3
4
|
window.console || (window.console = {});
|
4
5
|
|
5
6
|
(_base = window.console).log || (_base.log = function() {});
|
6
7
|
|
7
|
-
(
|
8
|
+
(_base1 = window.console).error || (_base1.error = function() {});
|
8
9
|
|
9
10
|
TSUPAIS = [null, "E", "S", "W", "N", "P", "F", "C"];
|
10
11
|
|
@@ -86,7 +87,9 @@ paiToImageUrl = function(pai, pose) {
|
|
86
87
|
}
|
87
88
|
ext = parsedPai.red ? "png" : "gif";
|
88
89
|
}
|
89
|
-
if (pose === void 0)
|
90
|
+
if (pose === void 0) {
|
91
|
+
pose = 1;
|
92
|
+
}
|
90
93
|
return "http://gimite.net/mjai/images/p_" + name + "_" + pose + "." + ext;
|
91
94
|
} else {
|
92
95
|
return "http://gimite.net/mjai/images/blank.png";
|
@@ -132,7 +135,9 @@ initPlayers = function(board) {
|
|
132
135
|
};
|
133
136
|
|
134
137
|
removeRed = function(pai) {
|
135
|
-
if (!pai)
|
138
|
+
if (!pai) {
|
139
|
+
return null;
|
140
|
+
}
|
136
141
|
if (pai.match(/^(.+)r$/)) {
|
137
142
|
return RegExp.$1;
|
138
143
|
} else {
|
@@ -141,7 +146,7 @@ removeRed = function(pai) {
|
|
141
146
|
};
|
142
147
|
|
143
148
|
loadAction = function(action) {
|
144
|
-
var actorPlayer, board, furos, i, kyoku, pai, prevBoard, targetPlayer, _i, _j, _len,
|
149
|
+
var actorPlayer, board, furos, i, kyoku, pai, prevBoard, targetPlayer, _i, _j, _k, _l, _len, _len1, _m, _n, _o, _ref, _ref1, _ref2;
|
145
150
|
if (kyokus.length > 0) {
|
146
151
|
kyoku = kyokus[kyokus.length - 1];
|
147
152
|
board = cloneBoard(kyoku.actions[kyoku.actions.length - 1].board);
|
@@ -161,7 +166,7 @@ loadAction = function(action) {
|
|
161
166
|
}
|
162
167
|
switch (action.type) {
|
163
168
|
case "start_game":
|
164
|
-
for (i = 0;
|
169
|
+
for (i = _i = 0; _i < 4; i = ++_i) {
|
165
170
|
playerInfos[i].name = action.names[i];
|
166
171
|
}
|
167
172
|
break;
|
@@ -182,7 +187,7 @@ loadAction = function(action) {
|
|
182
187
|
doraMarkers: [action.dora_marker]
|
183
188
|
};
|
184
189
|
initPlayers(board);
|
185
|
-
for (i = 0;
|
190
|
+
for (i = _j = 0; _j < 4; i = ++_j) {
|
186
191
|
board.players[i].tehais = action.tehais[i];
|
187
192
|
if (prevBoard) {
|
188
193
|
board.players[i].score = prevBoard.players[i].score;
|
@@ -210,10 +215,10 @@ loadAction = function(action) {
|
|
210
215
|
case "chi":
|
211
216
|
case "pon":
|
212
217
|
case "daiminkan":
|
213
|
-
targetPlayer.ho = targetPlayer.ho.slice(0,
|
218
|
+
targetPlayer.ho = targetPlayer.ho.slice(0, targetPlayer.ho.length - 1);
|
214
219
|
_ref = action.consumed;
|
215
|
-
for (
|
216
|
-
pai = _ref[
|
220
|
+
for (_k = 0, _len = _ref.length; _k < _len; _k++) {
|
221
|
+
pai = _ref[_k];
|
217
222
|
deleteTehai(actorPlayer, pai);
|
218
223
|
}
|
219
224
|
actorPlayer.furos = actorPlayer.furos.concat([
|
@@ -226,9 +231,9 @@ loadAction = function(action) {
|
|
226
231
|
]);
|
227
232
|
break;
|
228
233
|
case "ankan":
|
229
|
-
|
230
|
-
for (
|
231
|
-
pai =
|
234
|
+
_ref1 = action.consumed;
|
235
|
+
for (_l = 0, _len1 = _ref1.length; _l < _len1; _l++) {
|
236
|
+
pai = _ref1[_l];
|
232
237
|
deleteTehai(actorPlayer, pai);
|
233
238
|
}
|
234
239
|
actorPlayer.furos = actorPlayer.furos.concat([
|
@@ -242,7 +247,7 @@ loadAction = function(action) {
|
|
242
247
|
deleteTehai(actorPlayer, action.pai);
|
243
248
|
actorPlayer.furos = actorPlayer.furos.concat([]);
|
244
249
|
furos = actorPlayer.furos;
|
245
|
-
for (i = 0,
|
250
|
+
for (i = _m = 0, _ref2 = furos.length; 0 <= _ref2 ? _m < _ref2 : _m > _ref2; i = 0 <= _ref2 ? ++_m : --_m) {
|
246
251
|
if (furos[i].type === "pon" && removeRed(furos[i].taken) === removeRed(action.pai)) {
|
247
252
|
furos[i] = {
|
248
253
|
type: "kakan",
|
@@ -260,25 +265,25 @@ loadAction = function(action) {
|
|
260
265
|
case "dora":
|
261
266
|
board.doraMarkers = board.doraMarkers.concat([action.dora_marker]);
|
262
267
|
break;
|
263
|
-
case "
|
264
|
-
|
268
|
+
case "error":
|
269
|
+
null;
|
265
270
|
break;
|
266
271
|
default:
|
267
272
|
throw "unknown action: " + action.type;
|
268
273
|
}
|
269
274
|
if (action.scores) {
|
270
|
-
for (i = 0;
|
275
|
+
for (i = _n = 0; _n < 4; i = ++_n) {
|
271
276
|
board.players[i].score = action.scores[i];
|
272
277
|
}
|
273
278
|
}
|
274
279
|
if (kyoku) {
|
275
|
-
for (i = 0;
|
276
|
-
if (action.actor !== void 0 && i !== action.actor)
|
277
|
-
|
278
|
-
|
279
|
-
action.board = board;
|
280
|
-
return kyoku.actions.push(action);
|
280
|
+
for (i = _o = 0; _o < 4; i = ++_o) {
|
281
|
+
if (action.actor !== void 0 && i !== action.actor) {
|
282
|
+
ripai(board.players[i]);
|
283
|
+
}
|
281
284
|
}
|
285
|
+
action.board = board;
|
286
|
+
return kyoku.actions.push(action);
|
282
287
|
}
|
283
288
|
};
|
284
289
|
|
@@ -286,8 +291,12 @@ deleteTehai = function(player, pai) {
|
|
286
291
|
var idx;
|
287
292
|
player.tehais = player.tehais.concat([]);
|
288
293
|
idx = player.tehais.lastIndexOf(pai);
|
289
|
-
if (idx < 0)
|
290
|
-
|
294
|
+
if (idx < 0) {
|
295
|
+
idx = player.tehais.lastIndexOf("?");
|
296
|
+
}
|
297
|
+
if (idx < 0) {
|
298
|
+
throw "pai not in tehai";
|
299
|
+
}
|
291
300
|
return player.tehais[idx] = null;
|
292
301
|
};
|
293
302
|
|
@@ -300,7 +309,9 @@ ripai = function(player) {
|
|
300
309
|
_results = [];
|
301
310
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
302
311
|
pai = _ref[_i];
|
303
|
-
if (pai)
|
312
|
+
if (pai) {
|
313
|
+
_results.push(pai);
|
314
|
+
}
|
304
315
|
}
|
305
316
|
return _results;
|
306
317
|
})();
|
@@ -309,15 +320,15 @@ ripai = function(player) {
|
|
309
320
|
};
|
310
321
|
|
311
322
|
dumpBoard = function(board) {
|
312
|
-
var consumedStr, furo, hoStr, i, player, tehaisStr, _i, _len, _ref, _results;
|
323
|
+
var consumedStr, furo, hoStr, i, player, tehaisStr, _i, _j, _len, _ref, _results;
|
313
324
|
_results = [];
|
314
|
-
for (i = 0;
|
325
|
+
for (i = _i = 0; _i < 4; i = ++_i) {
|
315
326
|
player = board.players[i];
|
316
327
|
if (player.tehais) {
|
317
328
|
tehaisStr = player.tehais.join(" ");
|
318
329
|
_ref = player.furos;
|
319
|
-
for (
|
320
|
-
furo = _ref[
|
330
|
+
for (_j = 0, _len = _ref.length; _j < _len; _j++) {
|
331
|
+
furo = _ref[_j];
|
321
332
|
consumedStr = furo.consumed.join(" ");
|
322
333
|
tehaisStr += " [" + furo.taken + "/" + consumedStr + "]";
|
323
334
|
}
|
@@ -334,7 +345,9 @@ dumpBoard = function(board) {
|
|
334
345
|
};
|
335
346
|
|
336
347
|
renderPai = function(pai, view, pose) {
|
337
|
-
if (pose === void 0)
|
348
|
+
if (pose === void 0) {
|
349
|
+
pose = 1;
|
350
|
+
}
|
338
351
|
view.attr("src", paiToImageUrl(pai, pose));
|
339
352
|
switch (pose) {
|
340
353
|
case 1:
|
@@ -349,19 +362,19 @@ renderPai = function(pai, view, pose) {
|
|
349
362
|
};
|
350
363
|
|
351
364
|
renderPais = function(pais, view, poses) {
|
352
|
-
var i, _ref, _results;
|
365
|
+
var i, _i, _ref, _results;
|
353
366
|
pais || (pais = []);
|
354
367
|
poses || (poses = []);
|
355
368
|
view.resize(pais.length);
|
356
369
|
_results = [];
|
357
|
-
for (i = 0, _ref = pais.length; 0 <= _ref ?
|
370
|
+
for (i = _i = 0, _ref = pais.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
358
371
|
_results.push(renderPai(pais[i], view.at(i), poses[i]));
|
359
372
|
}
|
360
373
|
return _results;
|
361
374
|
};
|
362
375
|
|
363
376
|
renderHo = function(player, offset, pais, view) {
|
364
|
-
var i, reachIndex, _ref, _results;
|
377
|
+
var i, reachIndex, _i, _ref, _results;
|
365
378
|
if (player.reachHoIndex === null) {
|
366
379
|
reachIndex = null;
|
367
380
|
} else {
|
@@ -369,23 +382,25 @@ renderHo = function(player, offset, pais, view) {
|
|
369
382
|
}
|
370
383
|
view.resize(pais.length);
|
371
384
|
_results = [];
|
372
|
-
for (i = 0, _ref = pais.length; 0 <= _ref ?
|
385
|
+
for (i = _i = 0, _ref = pais.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
373
386
|
_results.push(renderPai(pais[i], view.at(i), i === reachIndex ? 3 : 1));
|
374
387
|
}
|
375
388
|
return _results;
|
376
389
|
};
|
377
390
|
|
378
391
|
renderAction = function(action) {
|
379
|
-
var dir, displayAction, furo, furoView, ho, i, infoView, j, k, kyoku, laidPos, pais, player, poses, v, view, wanpais, _ref, _ref2, _ref3
|
392
|
+
var dir, displayAction, furo, furoView, ho, i, infoView, j, k, kyoku, laidPos, pais, player, poses, v, view, wanpais, _i, _j, _ref, _ref1, _ref2, _ref3;
|
380
393
|
displayAction = {};
|
381
394
|
for (k in action) {
|
382
395
|
v = action[k];
|
383
|
-
if (k !== "board" && k !== "
|
396
|
+
if (k !== "board" && k !== "logs") {
|
397
|
+
displayAction[k] = v;
|
398
|
+
}
|
384
399
|
}
|
385
400
|
$("#action-label").text(JSON.stringify(displayAction));
|
386
|
-
$("#log-label").text(action.
|
401
|
+
$("#log-label").text((action.logs && action.logs[currentViewpoint]) || "");
|
387
402
|
kyoku = getCurrentKyoku();
|
388
|
-
for (i = 0;
|
403
|
+
for (i = _i = 0; _i < 4; i = ++_i) {
|
389
404
|
player = action.board.players[i];
|
390
405
|
view = Dytem.players.at((i - currentViewpoint + 4) % 4);
|
391
406
|
infoView = Dytem.playerInfos.at(i);
|
@@ -395,7 +410,7 @@ renderAction = function(action) {
|
|
395
410
|
renderPais([], view.tehais);
|
396
411
|
view.tsumoPai.hide();
|
397
412
|
} else if (player.tehais.length % 3 === 2) {
|
398
|
-
renderPais(player.tehais.slice(0,
|
413
|
+
renderPais(player.tehais.slice(0, player.tehais.length - 1), view.tehais);
|
399
414
|
view.tsumoPai.show();
|
400
415
|
renderPai(player.tehais[player.tehais.length - 1], view.tsumoPai);
|
401
416
|
} else {
|
@@ -424,8 +439,8 @@ renderAction = function(action) {
|
|
424
439
|
}
|
425
440
|
pais = furo.consumed.concat([]);
|
426
441
|
poses = [1, 1, 1];
|
427
|
-
[].splice.apply(pais, [laidPos, laidPos - laidPos].concat(
|
428
|
-
[].splice.apply(poses, [laidPos, laidPos - laidPos].concat(
|
442
|
+
[].splice.apply(pais, [laidPos, laidPos - laidPos].concat(_ref1 = [furo.taken])), _ref1;
|
443
|
+
[].splice.apply(poses, [laidPos, laidPos - laidPos].concat(_ref2 = [3])), _ref2;
|
429
444
|
}
|
430
445
|
renderPais(pais, furoView.pais, poses);
|
431
446
|
--j;
|
@@ -433,7 +448,7 @@ renderAction = function(action) {
|
|
433
448
|
}
|
434
449
|
}
|
435
450
|
wanpais = ["?", "?", "?", "?", "?", "?"];
|
436
|
-
for (i = 0,
|
451
|
+
for (i = _j = 0, _ref3 = action.board.doraMarkers.length; 0 <= _ref3 ? _j < _ref3 : _j > _ref3; i = 0 <= _ref3 ? ++_j : --_j) {
|
437
452
|
wanpais[i + 2] = action.board.doraMarkers[i];
|
438
453
|
}
|
439
454
|
return renderPais(wanpais, Dytem.wanpais);
|
@@ -448,21 +463,25 @@ renderCurrentAction = function() {
|
|
448
463
|
};
|
449
464
|
|
450
465
|
goNext = function() {
|
451
|
-
if (currentActionId === getCurrentKyoku().actions.length - 1)
|
466
|
+
if (currentActionId === getCurrentKyoku().actions.length - 1) {
|
467
|
+
return;
|
468
|
+
}
|
452
469
|
++currentActionId;
|
453
470
|
$("#action-id-label").val(currentActionId);
|
454
471
|
return renderCurrentAction();
|
455
472
|
};
|
456
473
|
|
457
474
|
goBack = function() {
|
458
|
-
if (currentActionId === 0)
|
475
|
+
if (currentActionId === 0) {
|
476
|
+
return;
|
477
|
+
}
|
459
478
|
--currentActionId;
|
460
479
|
$("#action-id-label").val(currentActionId);
|
461
480
|
return renderCurrentAction();
|
462
481
|
};
|
463
482
|
|
464
483
|
$(function() {
|
465
|
-
var action, bakazeStr, honba, i, j, kyokuNum, label, playerInfoView, playerView, _i, _len, _ref;
|
484
|
+
var action, bakazeStr, honba, i, j, kyokuNum, label, playerInfoView, playerView, _i, _j, _k, _l, _len, _ref;
|
466
485
|
$(window).bind("mousewheel", function(e) {
|
467
486
|
e.preventDefault();
|
468
487
|
if (e.originalEvent.wheelDelta < 0) {
|
@@ -491,17 +510,17 @@ $(function() {
|
|
491
510
|
loadAction(action);
|
492
511
|
}
|
493
512
|
Dytem.init();
|
494
|
-
for (i = 0;
|
513
|
+
for (i = _j = 0; _j < 4; i = ++_j) {
|
495
514
|
playerView = Dytem.players.append();
|
496
515
|
playerView.addClass("player-" + i);
|
497
|
-
for (j = 0;
|
516
|
+
for (j = _k = 0; _k < 3; j = ++_k) {
|
498
517
|
playerView.hoRows.append();
|
499
518
|
}
|
500
519
|
playerInfoView = Dytem.playerInfos.append();
|
501
520
|
playerInfoView.index.text(i);
|
502
521
|
playerInfoView.name.text(playerInfos[i].name);
|
503
522
|
}
|
504
|
-
for (i = 0, _ref = kyokus.length; 0 <= _ref ?
|
523
|
+
for (i = _l = 0, _ref = kyokus.length; 0 <= _ref ? _l < _ref : _l > _ref; i = 0 <= _ref ? ++_l : --_l) {
|
505
524
|
bakazeStr = BAKAZE_TO_STR[kyokus[i].bakaze];
|
506
525
|
honba = kyokus[i].honba;
|
507
526
|
kyokuNum = kyokus[i].kyokuNum;
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mjai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/mjai/shanten_player.rb
|
100
100
|
- lib/mjai/player.rb
|
101
101
|
- lib/mjai/tenhou_archive.rb
|
102
|
+
- lib/mjai/game_stats.rb
|
102
103
|
- lib/mjai/validation_error.rb
|
103
104
|
- lib/mjai/hora.rb
|
104
105
|
- lib/mjai/with_fields.rb
|
@@ -113,6 +114,7 @@ files:
|
|
113
114
|
- lib/mjai/tenpai_analysis.rb
|
114
115
|
- lib/mjai/archive.rb
|
115
116
|
- lib/mjai/shanten_analysis.rb
|
117
|
+
- lib/mjai/ymatsux_shanten_analysis.rb
|
116
118
|
- lib/mjai/context.rb
|
117
119
|
- lib/mjai/furo.rb
|
118
120
|
- lib/mjai/pai.rb
|