[bknr-cvs] r2296 - in branches/trunk-reorg/projects/scrabble: src website

bknr at bknr.net bknr at bknr.net
Sun Dec 2 23:36:28 UTC 2007


Author: hhubner
Date: 2007-12-02 18:36:27 -0500 (Sun, 02 Dec 2007)
New Revision: 2296

Modified:
   branches/trunk-reorg/projects/scrabble/src/web.lisp
   branches/trunk-reorg/projects/scrabble/website/scrabble.js
Log:
Gameplay fixes.


Modified: branches/trunk-reorg/projects/scrabble/src/web.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/web.lisp	2007-12-02 18:46:42 UTC (rev 2295)
+++ branches/trunk-reorg/projects/scrabble/src/web.lisp	2007-12-02 23:36:27 UTC (rev 2296)
@@ -55,6 +55,7 @@
   (encode-json-plist (list :type "move"
 			   :participant-login (user-login (player-of (participant-of move)))
 			   :score (score-of move)
+                           :player-score (score-of (participant-of move))
 			   :placed-tiles (placed-tiles-of move)
 			   :words (mapcar (lambda (word-cons)
 					    (list (car word-cons) (cdr word-cons)))
@@ -64,12 +65,14 @@
 (defmethod encode-json ((move move-withdrawal) stream)
   (encode-json-plist (list :type "move-withdrawal"
 			   :participant-login (user-login (player-of (participant-of move)))
+                           :player-score (score-of (participant-of move))
 			   :reason (or (reason-of move) ""))
 		     stream))
 
 (defmethod encode-json ((move tile-swap) stream)
   (encode-json-plist (list :type "tile-swap"
 			   :participant-login (user-login (player-of (participant-of move)))
+                           :player-score (score-of (participant-of move))
 			   :reason (count-of move))
 		     stream))
 
@@ -92,6 +95,7 @@
   (start-session)
   (encode-json-plist (append (list :login (user-login (player-of participant))
 				   :name (user-full-name (player-of participant))
+                                   :score (score-of participant)
                                    :remaining-tiles)
                              (list (if (eq (player-of participant)
                                            (session-value :user))

Modified: branches/trunk-reorg/projects/scrabble/website/scrabble.js
===================================================================
--- branches/trunk-reorg/projects/scrabble/website/scrabble.js	2007-12-02 18:46:42 UTC (rev 2295)
+++ branches/trunk-reorg/projects/scrabble/website/scrabble.js	2007-12-02 23:36:27 UTC (rev 2296)
@@ -1,4 +1,4 @@
-// -*- Java -*- (really Javascript)
+// -*- JavaScript -*-
 
 var boardScoring = [["triple-word",null,null,"double-letter",null,null,null,"triple-word",
 		     null,null,null,"double-letter",null,null,"triple-word"],
@@ -38,7 +38,7 @@
   // Given the board and list of placed tiles, either throw an error or
   // return if the move is legal.
 
-  var positions = map(function (placement) { return [ placement[0], placement[1] ] }, placedTiles)
+  var positions = map(function (placement) { return [ placement.x, placement.y ] }, placedTiles)
     .sort(function (a, b) { return (a[0] - b[0]) || (a[1] - b[1])});
 
   if (filter(partial(operator.ne, positions[0][0]), map(function (position) { return position[0] }, positions)).length
@@ -133,6 +133,13 @@
   nextTurn.style.textAlign = 'left';
   setElementPosition(nextTurn, { x: border + 680, y: border + 665 });
   appendChildNodes($('playfield'), nextTurn);
+
+  var nextTurn = DIV({ id: 'status' }, "");
+  nextTurn.style.position = 'absolute';
+  nextTurn.style.width = '280px';
+  nextTurn.style.textAlign = 'left';
+  setElementPosition(nextTurn, { x: border + 680, y: border + 680 });
+  appendChildNodes($('playfield'), nextTurn);
 }
 
 function setLetter(x, y, letter, isBlank) {
@@ -147,22 +154,11 @@
 }
 
 function placeLetter(x, y, tile) {
-  var mask = IMG({ src: 'images/mask.png'});
-  mask.style.position = 'absolute';
-  mask.style.top = '3px';
-  mask.style.left = '3px';
-  mask.style.zIndex = '20';
-  appendChildNodes(board[x][y], mask);
-  board[x][y].letterNode = tile;
-  board[x][y].letter = tile.letter;
-  board[x][y].justPlaced = true;
-  tile.anim = new YAHOO.util.Motion(tile, { points: { to: [ border + x * 44 + 3,
-                                                            border + y * 44 + 3 ]}},
-                                    0.15,
-                                    YAHOO.util.Easing.easeBoth);
-  tile.anim.animate();
 }
 
+function removeLastLetterFromMove() {
+}
+
 function letterAt(x, y) {
   return board[x][y].letter && !board[x][y].justPlaced;
 }
@@ -239,28 +235,74 @@
 
 var move = [];
 
-function makeMove(x, y, letter, isBlank) {
-  move[move.length] = [x, y, letter, isBlank];
+function makeMask()
+{
+  var mask = IMG({ src: 'images/mask.png'});
+  mask.style.position = 'absolute';
+  mask.style.top = '3px';
+  mask.style.left = '3px';
+  mask.style.zIndex = '20';
+  return mask;
+}
+
+function addLetterToMove(x, y, tile) {
+  mask = makeMask();
+  appendChildNodes(board[x][y], mask);
+  board[x][y].letterNode = tile;
+  board[x][y].letter = tile.letter;
+  board[x][y].justPlaced = true;
+  tile.mask = mask;
+  tile.anim = new YAHOO.util.Motion(tile, { points: { to: [ border + x * 44 + 3,
+                                                            border + y * 44 + 3 ]}},
+                                    0.15,
+                                    YAHOO.util.Easing.easeBoth);
+  tile.anim.animate();
+
+  move[move.length] = { x: x, y: y, tile: tile };
   try {
     checkMoveLegality(move);
     $('move').onclick = submitMove;
-    $('move').innerHTML = move.toString();
+    $('move').innerHTML = "submit move";
+    displayStatus('');
   }
   catch (e) {
+    if (typeof e != 'string') {
+      alert(e.message);
+    } else {
+      displayStatus(e);
+    }
     $('move').onclick = undefined;
     $('move').innerHTML = e.toString();
   }
 }
 
-function clearMove() {
+function confirmMove() {
+  for (var i = 0; i < move.length; i++) {
+    removeElement(move[i].tile.mask);
+    move[i].tile.mask = undefined;
+  }
+  cursor.clear();
   move = [];
   $('move').onclick = null;
-  $('move').innerHTML = '[no move]';
+  $('move').innerHTML = '';
+  
 }
 
+function moveAsString() {
+  // We internally keep the move as array of objects, but send it to the server rather unstructured:
+  var serverMessage = [];
+  for (var i = 0; i < move.length; i++) {
+    serverMessage.push(move[i].x);
+    serverMessage.push(move[i].y);
+    serverMessage.push(move[i].tile.letterName);
+    serverMessage.push(move[i].tile.letterName == undefined);
+  }
+  return serverMessage.toString();
+}
+
 function submitMove()
 {
-  var queryString = MochiKit.Base.queryString({ move: move.toString(), game: gameID });
+  var queryString = MochiKit.Base.queryString({ move: moveAsString(), game: gameID });
   var res = MochiKit.Async.doXHR("/place-tiles",
       { method: 'POST',
         sendContent: queryString,
@@ -270,20 +312,27 @@
 
 function moveSuccess(result)
 {
-  var response;
   try {
-    response = eval('(' + result.responseText + ')');
+    var response;
+    try {
+      response = eval('(' + result.responseText + ')');
+    }
+    catch (e) {
+      alert("invalid JSON reply: " + result.responseText);
+      return;
+    }
+    if (response.error) {
+      alert(response.error);
+    } else {
+      confirmMove();
+      alert(response.move.playerScore);
+      $('playfield')['score-' + response.move.participantLogin].innerHTML = response.move.playerScore.toString();
+      displayMyTray(response.tray);
+    }
   }
   catch (e) {
-    alert("invalid JSON reply: " + result.responseText);
-    return;
+    alert('error during moveSuccess: ' + e.message);
   }
-  if (response.error) {
-    alert(response.error);
-  } else {
-    clearMove();
-    makeMyTray(response.tray);
-  }
 }
 
 function moveFailure(e)
@@ -315,18 +364,17 @@
     }
   }
   if (tilePosition == -1) {
-    alert("You don't have letter + '" + letter + "'!");
+    displayStatus('you-dont-have-that-letter', letter);
   } else {
     var isHoriz;
     if (move.length > 0) {
-      isHoriz = (move[0][0] != x);
+      isHoriz = (move[0].x != x);
     }
     cursor.advance(isHoriz);
     if (!letterAt(x, y)) {
       var tile = tray[tilePosition];
       tray.splice(tilePosition, 1);
-      placeLetter(x, y, tile);
-      makeMove(x, y, tile.letterName, tile.letterName == undefined);
+      addLetterToMove(x, y, tile);
     }
   }
 }
@@ -362,6 +410,10 @@
       if (!letterAt(x, ++y))
         break;
     break;
+  case backspaceKey:
+    if (move.length) {
+      removeLastLetterFromMove();
+    }
   }
   if ((x >= 0) && (x <= 14) && (y >= 0) && (y <= 14)) {
     cursor.clear();
@@ -391,7 +443,7 @@
   this.anim.animate();
 }
 
-function makeMyTray(letters) {
+function displayMyTray(letters) {
   map(removeElement, tray);
   tray = [];
   for (var i = 0; i < letters.length; i++) {
@@ -403,7 +455,7 @@
     element.style.height = '34px';
     element.style.zIndex = '10';
     element.onclick = trayClick;
-    setElementPosition(element, { x: border + 194 + i * 40, y: border + 665 });
+    setElementPosition(element, { x: border + i * 40, y: border + 665 });
     tray[i] = element;
   }
   appendChildNodes($('playfield'), tray);
@@ -428,7 +480,9 @@
 
 var otherPlayerIndex = 0;
 
-function makeTheirTray (name, tileCount) {
+function makeTheirTray (participant) {
+  var tileCount = (typeof participant.remainingTiles == 'number') ? participant.remainingTiles : participant.remainingTiles.length;
+
   var tray = [];
   for (var i = 0; i < tileCount; i++) {
     var element = IMG({src: 'images/null.png'});
@@ -441,12 +495,21 @@
   }
   appendChildNodes($('playfield'), tray);
 
-  var nameTag = DIV(null, name);
+  var nameTag = DIV(null, participant.name);
   nameTag.style.position = 'absolute';
   nameTag.style.width = '200px';
   nameTag.style.textAlign = 'left';
   setElementPosition(nameTag, { x: border + 680, y: border + 80 * otherPlayerIndex + 50 });
   appendChildNodes($('playfield'), nameTag);
+
+  var scoreTag = DIV(null, participant.score);
+  scoreTag.style.position = 'absolute';
+  scoreTag.style.width = '80px';
+  scoreTag.style.textAlign = 'right';
+  setElementPosition(scoreTag, { x: border + 870, y: border + 80 * otherPlayerIndex + 50 });
+  appendChildNodes($('playfield'), scoreTag);
+  $('playfield')['score-' + participant.login] = scoreTag;
+
   otherPlayerIndex++;
 }
 
@@ -465,32 +528,41 @@
   return retval;
 }
 
+function displayWhosTurnItIs(name) {
+  replaceChildNodes($('nextTurn'),
+                    "Next: " + name);
+}
+
 function drawGameState (gameState) {
-  for (var i = 0; i < gameState.board.length; i++) {
-    var x = gameState.board[i][0];
-    var y = gameState.board[i][1];
-    var char = gameState.board[i][2];
-    setLetter(x, y, char, gameState.board[i].length > 3);
-  }
-  var firstParticipant = gameState.participants[0];
-  replaceChildNodes($('nextTurn'),
-                    "It is "
-                    + ((typeof firstParticipant.remainingTiles == 'number') ? (firstParticipant.name + "s") : "your")
-                    + " turn");
-  for (var i = 0; i < gameState.participants.length; i++) {
-    var participant = gameState.participants[i];
-    if (typeof participant.remainingTiles == 'number') {
-      makeTheirTray(participant.name, participant.remainingTiles);
-    } else {
-      makeMyTray(participant.remainingTiles);
+  try {
+    for (var i = 0; i < gameState.board.length; i++) {
+      var x = gameState.board[i][0];
+      var y = gameState.board[i][1];
+      var char = gameState.board[i][2];
+      setLetter(x, y, char, gameState.board[i].length > 3);
     }
+    var firstParticipant = gameState.participants[0];
+    displayWhosTurnItIs(firstParticipant.name);
+    for (var i = 0; i < gameState.participants.length; i++) {
+      var participant = gameState.participants[i];
+      makeTheirTray(participant);
+      if (typeof participant.remainingTiles != 'number') {
+        displayMyTray(participant.remainingTiles);
+      }
+    }
+    for (var i = 0; i < gameState.moves.length; i++) {
+      appendChildNodes($('gameLog'), DIV(null, renderMoveAsText(gameState.moves[i])));
+    }
   }
-  for (var i = 0; i < gameState.moves.length; i++) {
-    appendChildNodes($('gameLog'), DIV(null, renderMoveAsText(gameState.moves[i])));
+  catch (e) {
+    alert('error ' + e + ' in drawGameState');
   }
 }
 
-var legalLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
+function displayStatus(status)
+{
+  replaceChildNodes('status', status);
+}
 
 function init() {
   makeBoard();
@@ -503,7 +575,7 @@
       { fn: functionKeyPressed, scope: this, correctScope: true });
   functionKeyListener.enable();
 
-  var moveDisplay = DIV({ id: 'move' }, "[no move yet]");
+  var moveDisplay = DIV({ id: 'move' }, "");
   moveDisplay.style.color = 'white';
   moveDisplay.style.position = 'absolute';
   setElementPosition(moveDisplay, { x: border + 550, y: border + 665 });




More information about the Bknr-cvs mailing list