comm.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. $(function() {
  2. var connection = null;
  3. var nick = null;
  4. var self_player = null;
  5. // when creating a word
  6. var question = null;
  7. var char_list = null;
  8. // when guessing results
  9. var wordlist = null;
  10. var questionlist = null;
  11. function validate_word(word) {
  12. var allowedChars = [" ", "-", "'"];
  13. var countmap = {};
  14. for (var i = 0; i < char_list.length; i++) {
  15. var upper = char_list[i].toUpperCase();
  16. if (countmap[upper] == null) {
  17. countmap[upper] = 0;
  18. }
  19. countmap[upper] += 1;
  20. }
  21. var uppercase_word = word.toUpperCase();
  22. for (var i = 0; i < uppercase_word.length; i++) {
  23. var upper = uppercase_word.charAt(i);
  24. var count = countmap[upper];
  25. if (allowedChars.includes(upper))
  26. continue;
  27. if (count != null) {
  28. if (count <= 0) {
  29. return false;
  30. }
  31. countmap[upper] = count - 1;
  32. }
  33. else {
  34. return false;
  35. }
  36. }
  37. return word.length > 0;
  38. }
  39. $('#join').click(function() {
  40. var game_id = $('#gameId').val();
  41. nick = $('#nick').val();
  42. var msg = {
  43. join: {
  44. game_id: game_id,
  45. nick: nick,
  46. }
  47. };
  48. send(msg);
  49. });
  50. $('#create').click(function() {
  51. var game_id = $('#gameId').val();
  52. nick = $('#nick').val();
  53. var msg = {
  54. create_game: {
  55. game_id: game_id,
  56. nick: nick,
  57. }
  58. };
  59. send(msg);
  60. });
  61. $('#leave-lobby').click(function() {
  62. if (window.confirm("Are you sure you want to leave?")) {
  63. var msg = "leave_lobby";
  64. send(msg);
  65. }
  66. });
  67. $('#ready-button').click(function() {
  68. var msg = "ready";
  69. if (self_player != null && self_player.ready) {
  70. msg = "unready";
  71. }
  72. send(msg);
  73. });
  74. $('#createform').submit(function(ev) {
  75. ev.preventDefault();
  76. var word = $('#word').val();
  77. if (validate_word(word)) {
  78. var msg = {
  79. submit_word: {
  80. word: word
  81. }
  82. };
  83. send(msg);
  84. }
  85. else {
  86. statusMessage("Please use only given characters");
  87. }
  88. });
  89. $('#word').change(function(ev) {
  90. var word = $('#word').val();
  91. if (validate_word(word)) {
  92. statusMessage("all good");
  93. }
  94. else {
  95. statusMessage("Please use only given characters");
  96. }
  97. });
  98. $('#guessingform').submit(function(ev) {
  99. ev.preventDefault();
  100. var list = getDragAnswers();
  101. var msg = {
  102. submit_guess: {
  103. guesses: list
  104. }
  105. };
  106. send(msg);
  107. });
  108. $(document).on("click", "#reveal-button", function() {
  109. var msg = "reveal";
  110. send(msg);
  111. });
  112. function connect(initial_message) {
  113. if (connection != null) {
  114. disconnect();
  115. }
  116. var prot = document.location.protocol == 'https:' ? 'wss://' : 'ws://';
  117. var uri = prot + window.location.host + '/ws/';
  118. connection = new WebSocket(uri);
  119. connection.onopen = function() {
  120. connection.send(JSON.stringify(initial_message));
  121. };
  122. connection.onmessage = function(e) {
  123. onReceive(e);
  124. };
  125. connection.onclose = function() {
  126. connection = null;
  127. };
  128. }
  129. function send(message) {
  130. if (connection != null) {
  131. connection.send(JSON.stringify(message));
  132. }
  133. else {
  134. connect(message);
  135. }
  136. }
  137. function disconnect() {
  138. connection.close();
  139. connection = null;
  140. }
  141. function onReceive(msg) {
  142. var obj = JSON.parse(msg.data);
  143. if (obj.game_not_found != null) {
  144. statusMessage("Game \"" + obj.game_not_found.game_id + "\" not found");
  145. }
  146. else if (obj.game_already_started != null) {
  147. statusMessage("Game \"" + obj.game_already_started.game_id + "\" has already started.");
  148. }
  149. else if (obj.game_already_exists != null) {
  150. statusMessage("Game \"" + obj.game_already_exists.game_id + "\" already exists.");
  151. }
  152. else if (obj.nick_already_exists != null) {
  153. statusMessage("There is already a player called \"" + obj.nick_already_exists.nick +
  154. "\" in this game lobby (" + obj.nick_already_exists.game_id + ").");
  155. }
  156. else if (obj.left_lobby != null) {
  157. setView('login');
  158. $('#lobby-control').hide();
  159. }
  160. else if (obj.player_list != null) {
  161. updatePlayerList(obj.player_list);
  162. }
  163. else if (obj.game_state != null) {
  164. updatePlayerList(obj.game_state.players);
  165. var gs = obj.game_state;
  166. if (gs.state_data === "starting") {
  167. setView('starting');
  168. }
  169. else if (gs.state_data.creating != null) {
  170. var creating = gs.state_data.creating;
  171. var chars = creating.available_chars;
  172. question = creating.question;
  173. char_list = chars;
  174. $('#question-box').html(creating.question);
  175. $('#letter-box').html(chars.join(" "));
  176. $('#word').val("");
  177. setView('creating');
  178. }
  179. else if (gs.state_data.guessing != null) {
  180. var guesses = gs.state_data.guessing;
  181. displayGuessing(guesses);
  182. }
  183. else if (gs.state_data.revealing != null) {
  184. displayResult(gs.state_data.revealing.round_result, gs.state_data.players);
  185. }
  186. }
  187. else {
  188. statusMessage("Unknown message recieved: " + msg);
  189. }
  190. }
  191. function displayGuessing(guesses) {
  192. var sub_words = guesses.submitted_words;
  193. var questions = guesses.questions;
  194. questionlist = questions;
  195. wordlist = sub_words.map(pair => pair[0]);
  196. setupDraggame(questionlist, wordlist);
  197. setView('guessing');
  198. }
  199. function displayResult(result) {
  200. var sol = result.solutions;
  201. var solution_dict = {};
  202. for (var i = 0; i < sol.length; i++) {
  203. solution_dict[sol[i][0]] = sol[i][1];
  204. }
  205. var $table = $('<table/>');
  206. $table.addClass('result-table');
  207. var row_shows = result.words.map(w => w[2]);
  208. var $row = $("<tr/>");
  209. $row.append($("<th/>"));
  210. for(var i = 0; i < result.words.length; i++) {
  211. var $wordline = $("<th/>");
  212. var $word = $("<p/>");
  213. $word.text(result.words[i][1]);
  214. $wordline.append($word);
  215. if (!row_shows[i] && result.words[i][0] == nick) {
  216. var $butt = $("<button/>");
  217. $butt.attr("id", "reveal-button");
  218. $butt.attr("class", "mini-button");
  219. $butt.text("Reveal");
  220. $wordline.append($butt);
  221. }
  222. else if (row_shows[i]) {
  223. var $creator = $("<small/>");
  224. $creator.text(result.words[i][0]);
  225. $wordline.append($creator);
  226. }
  227. $row.append($wordline);
  228. }
  229. $table.append($row);
  230. for(var i = 0; i < result.questions.length; i++) {
  231. var $row = $("<tr/>");
  232. var $header = $("<th/>");
  233. $header.text(result.questions[i]);
  234. $row.append($header);
  235. for(var j = 0; j < result.words.length; j++) {
  236. var $cell = $("<td/>");
  237. if (row_shows[j]) {
  238. if (solution_dict[result.words[j][1]] == result.questions[i]) {
  239. $cell.addClass("result-correct");
  240. }
  241. else {
  242. $cell.addClass("result-wrong");
  243. }
  244. for (var k = 0; k < result.guesses[j][i].length; k++) {
  245. var $p = $('<p>');
  246. $p.text(result.guesses[j][i][k]);
  247. $cell.append($p);
  248. }
  249. $cell.text(result.guesses[j][i].join(", "));
  250. }
  251. $row.append($cell);
  252. }
  253. $table.append($row);
  254. }
  255. $('#guesses-table').html("");
  256. $('#guesses-table').append($table);
  257. $('#points-table').html("");
  258. var $header = $("<tr/>");
  259. var $points = $("<tr/>");
  260. var pl = result.point_list;
  261. for(var i = 0; i < pl.length; i++) {
  262. var $htd = $("<th/>"); $htd.text(pl[i][0]);
  263. var $ptd = $("<td/>"); $ptd.text(pl[i][1]);
  264. $header.append($htd);
  265. $points.append($ptd);
  266. }
  267. $('#points-table').append($header);
  268. $('#points-table').append($points);
  269. setView('results');
  270. }
  271. function updateReadyStates(player) {
  272. self_player = player;
  273. if (player.ready) {
  274. $("#ready-button").addClass("button-unready");
  275. $("#ready-button").removeClass("button-ready");
  276. $("#submit-word").addClass("button-unready");
  277. $("#submit-word").removeClass("button-ready");
  278. $("#submit-guess").addClass("button-unready");
  279. $("#submit-guess").removeClass("button-ready");
  280. } else {
  281. $("#ready-button").addClass("button-ready");
  282. $("#ready-button").removeClass("button-unready");
  283. $("#submit-word").addClass("button-ready");
  284. $("#submit-word").removeClass("button-unready");
  285. $("#submit-guess").addClass("button-ready");
  286. $("#submit-guess").removeClass("button-unready");
  287. }
  288. }
  289. function updatePlayerList(players) {
  290. $('#player-list').text("");
  291. for (var i = 0; i < players.length; i++) {
  292. var playerclass = players[i].ready ? "player-ready" : "player-unready";
  293. var $pitem = $('<p/>');
  294. $pitem.addClass(playerclass);
  295. $pitem.text(players[i].nick + " (" + players[i].points + ")");
  296. $('#player-list').append($pitem);
  297. if (players[i].nick == nick) {
  298. updateReadyStates(players[i]);
  299. }
  300. }
  301. $('#lobby-control').show();
  302. }
  303. function setView(view) {
  304. $('#loginform').hide();
  305. $('#startingform').hide();
  306. $('#creating').hide();
  307. $('#guessing').hide();
  308. $('#results').hide();
  309. switch (view) {
  310. case 'login':
  311. $('#loginform').show();
  312. break;
  313. case 'starting':
  314. $('#startingform').show();
  315. $('#results').show();
  316. break;
  317. case 'creating':
  318. $('#creating').show();
  319. break;
  320. case 'guessing':
  321. $('#guessing').show();
  322. break;
  323. case 'results':
  324. $('#results').show();
  325. break;
  326. }
  327. }
  328. function statusMessage(message) {
  329. $('#status').html(message);
  330. setTimeout(function () {
  331. $('#status').html("");
  332. }, 4000);
  333. }
  334. });