Author: scottbw
Date: Fri Mar  2 16:41:18 2012
New Revision: 1296299

URL: http://svn.apache.org/viewvc?rev=1296299&view=rev
Log:
Various improvements to the Sudoku widget to make it more reliable and look a 
bit nicer and less like a lump of test code. Also, the widget no longer 
auto-launches a new game, which reduces the likelihood of a new game collision. 
See WOOKIE-149.

Added:
    incubator/wookie/trunk/widgets/sudoku/splash.png   (with props)
Modified:
    incubator/wookie/trunk/widgets/sudoku/config.xml
    incubator/wookie/trunk/widgets/sudoku/icon.png
    incubator/wookie/trunk/widgets/sudoku/main.js
    incubator/wookie/trunk/widgets/sudoku/style.css
    incubator/wookie/trunk/widgets/sudoku/sudoku.html

Modified: incubator/wookie/trunk/widgets/sudoku/config.xml
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/sudoku/config.xml?rev=1296299&r1=1296298&r2=1296299&view=diff
==============================================================================
--- incubator/wookie/trunk/widgets/sudoku/config.xml (original)
+++ incubator/wookie/trunk/widgets/sudoku/config.xml Fri Mar  2 16:41:18 2012
@@ -17,12 +17,24 @@
 -->
 <widget xmlns="http://www.w3.org/ns/widgets"; 
         id="http://www.getwookie.org/widgets/sudoku"; 
-        version="1.0" height="380" width="520">
-        <name>Wave Test: Sudoku</name>
-        <description>Google Wave Sudoku Widget</description>
-        <icon src="icon.png"/>
+        version="1.0" height="380" width="480">
+        <name>Sudoku</name>
+        <description>Sudoku</description>
         <content src="sudoku.html"/>
         <author>Austin Chau</author>
-        <license>Unknown (c) Google.com</license>
+        <license>
+Copyright [2007] [Austin Chau] 
+Licensed under the Apache License, Version 2.0 (the "License"); you may not 
+use this file except in compliance with the License. You may obtain a copy of
+the License at 
+
+http://www.apache.org/licenses/LICENSE-2.0 
+
+Unless required by applicable law or agreed to in writing, software 
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
+License for the specific language governing permissions and limitations 
+under the License
+               </license>
         <feature name="http://wave.google.com"; required="true"/>
 </widget>

Modified: incubator/wookie/trunk/widgets/sudoku/icon.png
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/sudoku/icon.png?rev=1296299&r1=1296298&r2=1296299&view=diff
==============================================================================
Binary files - no diff available.

Modified: incubator/wookie/trunk/widgets/sudoku/main.js
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/sudoku/main.js?rev=1296299&r1=1296298&r2=1296299&view=diff
==============================================================================
--- incubator/wookie/trunk/widgets/sudoku/main.js (original)
+++ incubator/wookie/trunk/widgets/sudoku/main.js Fri Mar  2 16:41:18 2012
@@ -20,22 +20,17 @@ window.DEBUG = false;
 window.PUZZLE_KEY = 'PUZZLE';
 window.SOLUTION_KEY = 'SOLUTION';
 window.CELL_STATE_RE = /^cell_([0-9]+)$/;
-window.PENALTY_STATE_RE = /^penalty_(.+)$/;
+window.PENALTY_STATE_RE = /^penalty_(.+)$/;
 
 // sudoku generator object
 window.generator = null;
 
 // game data
-window.gameReset = false;
-window.waveReady = false;
 window.puzzleArray = [];
 window.solutionArray = [];
 window.liveGameArray = [];
 window.playerRecords = [];
 
-// viewer data
-window.viewerId = null;
-
 // status messages on top
 window.messages = [];
 window.MAX_MESSAGES = 5;
@@ -44,84 +39,48 @@ function init() {
   window.generator = new sudoku.SudokuGenerator();
 
   if (window.DEBUG) {
-    jQuery('#debugConsole').css({display: 'block'});
+    $('#debugConsole').css({display: 'block'});
     initClickHandlers();    
   } else {
-    jQuery('#debugConsole').css({display: 'none'});
+    $('#debugConsole').css({display: 'none'});
   }
 
-  if (window.wave) {
-
+  if (window.wave) {
+    //
+    // Start collaborative play
+    //
     wave.setParticipantCallback(function() {
-
-      if (wave.getViewer() != null && window.viewerId == null) {
-        window.viewerId = wave.getViewer().getDisplayName();
-        // init the area heading
         updateMessages();
         updateRankingDisplay();
-      }
-      wave.setStateCallback(waveStateChanged);  
-    });
-        
+    });
+    wave.setStateCallback(waveStateChanged); 
   }
-}
-
-function appendMessage(msg) {
-  if (messages.length >= MAX_MESSAGES) {
-    messages.pop();    
-  }
-  messages.unshift(msg);
-
-  updateMessages();
-}
-
-function updateMessages() {
-
-  var html = [];
-  html.push('<b>Updates:</b><br><br>');
-  html.push(messages.join('<br>'));
-
-  jQuery('#messages').html(html.join(''));
-}
+}
 
-function debug(msg) {
-  jQuery('#debug').prepend(msg + '<br/>');
-}
-
-function waveStateChanged() {
-  if (!window.wave) {
-    return;
-  }  
-  
-  if (window.gameReset) {
-    var keys = wave.getState().getKeys();
-    var done = true;
-    for (var i = 0; i < keys.length; i++) {
-      var key = keys[i];
-      if (window.CELL_STATE_RE.test(key) || 
-          window.PENALTY_STATE_RE.test(key)) {
-        done = false;
-        break;
-      }
-    }    
-    if (done) {
-      window.gameReset = false;
-      initGame();
-      return;
-    } else {
-      return;
-    }
+function waveStateChanged() {
+  //
+  // Check if the game has reset by comparing the current solution
+  // in the window with the wave state solution
+  //  
+  if (wave.getState().get("SOLUTION") && wave.getState().get("SOLUTION") != 
JSON.stringify(window.solutionArray) ) {
+    debug("game was reset");
+    window.puzzleArray = JSON.parse(get(PUZZLE_KEY));
+    window.solutionArray = JSON.parse(get(SOLUTION_KEY));
+    window.liveGameArray = window.puzzleArray.concat([]); // clone 
liveGameArray from puzzleArray  
+    showGame();
+      
+  } else {
+    //
+    // Check for another player's move
+    //
+    updateGameProgress();   
   }
-
-  if (!window.waveReady) {
-    window.waveReady = true;
-    initGame();
-    return;
-  }  
-
-  updateGameProgress();  
 }
-
+
+//
+// Update game board with events
+// from wave state
+//
 function updateGameProgress() {
   var keys = wave.getState().getKeys();
   for (var i = 0; i < keys.length; ++i) {   
@@ -159,124 +118,46 @@ function updateGameProgress() {
   }
 }
 
-function getPlayerRecord(playerName) {
-  var ret = null;
-
-  for (var i = 0; i < playerRecords.length; i++) {
-    var record = playerRecords[i];
-    if (record.name == playerName) {
-      ret = record;
-      break;
-    }
-  }
-
-  return ret;
-}
-
-function newPlayerRecord(playerName) {
-  playerRecord = {};
-  playerRecord.name = playerName;
-  playerRecord.points = 0;
-  playerRecord.penalty = 0;
-  playerRecords.push(playerRecord);
-  return playerRecord;
-}
-
-function addPoint(playerName) {
-
-  var playerRecord = getPlayerRecord(playerName);
-
-  if (playerRecord == null) {
-    playerRecord = newPlayerRecord(playerName);
-  }  
-
-  playerRecord.points++;
-
-  updateRankingDisplay();
-}
-
-function updateRankingDisplay() {
-  
-  // sort player record by points
-  playerRecords.sort(function(a, b) {
-    return (b.points - b.penalty) - (a.points - a.penalty);
-  });  
-
-  var html = [];
-  html.push('<b>Ranking:</b><br><br>');
-  
-  for (var i = 0; i < playerRecords.length; i++) {
-    var playerRecord = playerRecords[i];
-    var name = playerRecord.name;
-    var total = playerRecord.points - playerRecord.penalty;
-    var rank = i + 1;
-    html.push('<b>' + rank + '. </b>');
-    html.push(name + ' (' + total + ')');
-    html.push('<br/>');
-  }
-
-  jQuery('#rankingDisplay').html(html.join(''));
-}
-
-function initClickHandlers() {
-  
-  jQuery('#clear').click(function() {
-    jQuery('#debug').empty();
-  });
-
-  jQuery('#reset').click(function() {
-    resetAllStates();
-  });
-
-  jQuery('#print').click(function() {
-    printAllStates();
-  });
-
-}
-
-function hasExistingGame() {
-  var ret = false;
-
-  if (get(PUZZLE_KEY) != null) {
-    ret = true;
-  }
-
-  return ret;
-}
-
-function showGame() {
+function showGame() {
+  $('#splash').hide();
   displaySudoku(window.puzzleArray.join(''));
   updateGameProgress();
-  jQuery('#loading').css('display', 'none');
 }
-
-function initGame() {
-  debug('viewer id: ' + viewerId);
-  
-  if (hasExistingGame()) {
-    debug("has existing game");
-    // there is an existing game, read the data in
-    window.puzzleArray = JSON.parse(get(PUZZLE_KEY));
-    window.solutionArray = JSON.parse(get(SOLUTION_KEY));  
-  } else {
-    debug("generating new game");
-    // you are the first player, you need to generate the game!
-    var data = generateNewPuzzle();
-    window.puzzleArray = data.puzzle;
-    window.solutionArray = data.solution;
-    set(PUZZLE_KEY, JSON.stringify(window.puzzleArray));
-    set(SOLUTION_KEY, JSON.stringify(window.solutionArray));
-  }
-
-  window.liveGameArray = window.puzzleArray.concat([]); // clone liveGameArray 
from puzzleArray  
-
-  showGame();
-}
-
+
+function newGame(){
+    var data = generateNewPuzzle();
+    
+    if (window.wave){
+        //
+        // Create the game data and send it, but don't change our local state
+        //
+        debug("created new game - submitting delta");
+        var delta = {};
+        delta[PUZZLE_KEY] = JSON.stringify(data.puzzle);
+        delta[SOLUTION_KEY] = JSON.stringify(data.solution);
+        //
+        // Clear keys for each cell
+        //
+        for (var i=0;i<81;i++){
+            delta["cell_"+i] = null;
+        }
+        wave.getState().submitDelta(delta);
+    } else {
+        //
+        // In single player mode, just start the game
+        //
+        window.puzzleArray = data.puzzle;
+        window.solutionArray = data.solution;
+        window.liveGameArray = window.puzzleArray.concat([]); // clone 
liveGameArray from puzzleArray  
+        showGame();
+    }
+}
+
+//
+// Create the puzzle
+//
 function generateNewPuzzle() {
-  
   var data = {};
-  
   try {
     var generator = new sudoku.SudokuGenerator();
     var puzzleString = generator.generate();
@@ -290,35 +171,27 @@ function generateNewPuzzle() {
   } catch (e) {
     data = generateNewPuzzle();
   }
-
   return data;
 }
 
-function quitGame() {
-  displayActualSolution();
-}
-
 function cleanup() {
   
   // - hide the sudoku display
   // - remove all previous event listeners on all cells
   // - remove all css class attr on all cells
-  // - hide comment box if it is open
-  // - hide timer & reset timer
-  
-  jQuery('#display').hide();
+
+  $('#display').hide();
   
   for (var i=0;i<81;i++) {
     var cellId = '#cell_' + i;
-    jQuery(cellId).unbind();
-    jQuery(cellId).removeClass('blankCell');
-    jQuery(cellId).removeClass('givenCell');
-    jQuery(cellId).removeClass('solutionCell');  
+    $(cellId).unbind();
+    $(cellId).removeClass('blankCell');
+    $(cellId).removeClass('givenCell');
+    $(cellId).removeClass('solutionCell');  
   }
 }
 
 function isGameOver() { 
-
   if (liveGameArray.length == 0) {
     // the game isn't fully initialized yet
     return false;
@@ -328,15 +201,15 @@ function isGameOver() { 
 }
 
 function onGameOver() { 
-
   if (confirm('Game over. New game?')) {
     // now reset the state callback function
-    resetAllStates();
+    resetAllStates();
+    newGame();
   }
 }
 
 function closeCell(arrayIndex, value, playerName) {
-  var cell = jQuery('#cell_' + arrayIndex);
+  var cell = $('#cell_' + arrayIndex);
   cell.html(value);
   cell.addClass('solutionCell');  
 
@@ -361,23 +234,17 @@ function closeCell(arrayIndex, value, pl
 }
 
 function onRightMove(arrayIndex, value) {  
-  
   // update the local live game array
   window.liveGameArray[arrayIndex] = value;
-
   // report state change to save
   // TODO
-  set('cell_' + arrayIndex, window.viewerId);
-
-  closeCell(arrayIndex, value, window.viewerId);
+  set('cell_' + arrayIndex, getViewer());
+  closeCell(arrayIndex, value, getViewer());
 }
 
 function onWrongMove() {  
-   
-  var key = 'penalty_' + window.viewerId; //.replace(/ /g, '*');
-
+  var key = 'penalty_' + getViewer(); //.replace(/ /g, '*');
   var value = get(key);
-
   if (value == null) {
     value = 0
   }
@@ -399,8 +266,6 @@ function blurOnCell(inputBox) {
     cell.empty();
     cell.bind('click', handleCellInput);  
   }
-  
-  //checkGame();
 }
 
 function getCellValue(arrayIndex) {
@@ -413,19 +278,19 @@ function isInputCorrect(arrayIndex, inpu
 
 function handleCellInput() {
         
-  var arrayIndex = parseInt(jQuery(this).attr('id').replace('cell_', ''));  
+  var arrayIndex = parseInt($(this).attr('id').replace('cell_', ''));  
   
   debug('ans: ' + getCellValue(arrayIndex));
 
-  jQuery(this).unbind('click');
+  $(this).unbind('click');
          
   //clearAnnounce();      
         
-  var cell = jQuery(this);
+  var cell = $(this);
         
   var cellValue = (cell.html() == '')?'':'value=' +cell.html();    
 
-  var inputBox = jQuery('<input maxlength=1 ' + cellValue 
+  var inputBox = $('<input maxlength=1 ' + cellValue 
     + ' type=text id=cellOpenBox>');
         
   cell.html(inputBox);
@@ -473,16 +338,16 @@ function displaySudoku(sudokuStr) {
     
     if (value == 0) {
       // this is a blank cell      
-      jQuery(cellId).click(handleCellInput);            
-      jQuery(cellId).html('');  
+      $(cellId).click(handleCellInput);            
+      $(cellId).html('');  
       
     } else {  
       // this is a given cell
-      jQuery(cellId).html(value);  
+      $(cellId).html(value);  
     }
   }
-  jQuery('#display').fadeIn(500);
-  jQuery('#quit').show();
+  $('#display').fadeIn(500);
+  $('#info').fadeIn(500);
 }
 
 function get(key) {
@@ -494,87 +359,160 @@ function get(key) {
 }
 
 function set(key, value) {
-  var obj = {};
-  obj[key] = value;
-  if (window.wave) {
-    wave.getState().submitDelta(obj);
-  }  
-}
-
-function rm(key) {
-  var obj = {};
-  obj[key] = null;  
   if (window.wave) {
-    wave.getState().submitDelta(obj);
+    wave.getState().submitValue(key,value);
   }  
 }
 
-function getViewerId() {
-  var ret = null;
-
+function getViewer() {
+  var ret = "you";
   if (window.wave) {
-
     ret = wave.getViewer().getDisplayName();
   }
-
   return ret;
 }
 
-function printAllStates() {  
-
-  if (!window.wave) {
-    return;
-  }
-
-  var html = [];
-
-  var keys = wave.getState().getKeys();
-
-  for (var i = 0; i < keys.length; ++i) {   
-    var key = keys[i];
-    var value = wave.getState().get(key);
-
-    html.push(key + ' = ' + value);
-    html.push('<br>');
-  }
-  
-  debug(html.join(''));
-}
-
 function resetAllStates() {
 
   if (window.wave) {
 
-    var obj = {};
-
     // reset all game data
     window.puzzleArray = [];
     window.solutionArray = [];
     window.liveGameArray = [];
     window.playerRecords = [];
     window.messages = [];
-    window.gameReset = true;
-
-    obj[window.PUZZLE_KEY] = null;
-    obj[window.SOLUTION_KEY] = null;
-    
-    var keys = wave.getState().getKeys();
-
-    for (var i = 0; i < keys.length; i++) {
-      var key = keys[i];
-      if (window.CELL_STATE_RE.test(key) || 
-          window.PENALTY_STATE_RE.test(key)) {
-        obj[key] = null;
-      }
-    }
    
-    debug(JSON.stringify(obj));
-
-    wave.getState().submitDelta(obj);
-
     // clear info
     updateMessages();
     updateRankingDisplay();
   }    
 
+}
+
+///////////////
+// PLAYERS //
+///////////////
+
+function appendMessage(msg) {
+  if (messages.length >= MAX_MESSAGES) {
+    messages.pop();    
+  }
+  messages.unshift(msg);
+  updateMessages();
+}
+
+function updateMessages() {
+  var html = [];
+  html.push('<b>Updates:</b><br><br>');
+  html.push(messages.join('<br>'));
+
+  $('#messages').html(html.join(''));
+}
+
+function newPlayerRecord(playerName) {
+  playerRecord = {};
+  playerRecord.name = playerName;
+  playerRecord.points = 0;
+  playerRecord.penalty = 0;
+  playerRecords.push(playerRecord);
+  return playerRecord;
+}
+
+function addPoint(playerName) {
+  var playerRecord = getPlayerRecord(playerName);
+  if (playerRecord == null) {
+    playerRecord = newPlayerRecord(playerName);
+  }  
+  playerRecord.points++;
+  updateRankingDisplay();
+}
+
+function updateRankingDisplay() {
+  
+  // sort player record by points
+  playerRecords.sort(function(a, b) {
+    return (b.points - b.penalty) - (a.points - a.penalty);
+  });  
+
+  var html = [];
+  html.push('<b>Ranking:</b><br><br>');
+  
+  for (var i = 0; i < playerRecords.length; i++) {
+    var playerRecord = playerRecords[i];
+    var name = playerRecord.name;
+    var total = playerRecord.points - playerRecord.penalty;
+    var rank = i + 1;
+    html.push('<b>' + rank + '. </b>');
+    html.push(name + ' (' + total + ')');
+    html.push('<br/>');
+  }
+
+  $('#rankingDisplay').html(html.join(''));
+}
+
+function getPlayerRecord(playerName) {
+  var ret = null;
+
+  for (var i = 0; i < playerRecords.length; i++) {
+    var record = playerRecords[i];
+    if (record.name == playerName) {
+      ret = record;
+      break;
+    }
+  }
+
+  return ret;
+}
+
+///////////////
+// DEBUGGING //
+///////////////
+
+function debug(msg) {
+  $('#debug').prepend(msg + '<br/>');
+}
+
+function initClickHandlers() {
+  
+  $('#clear').click(function() {
+    $('#debug').empty();
+  });
+
+  $('#reset').click(function() {
+    resetAllStates();
+  });
+
+  $('#print').click(function() {
+    printAllStates();
+  });
+  
+  $('#cheat').click(function() {
+    cheat();
+  });
+}
+
+function cheat(){
+  onGameOver();
+}
+
+function printAllStates() {  
+
+  if (!window.wave) {
+    return;
+  }
+
+  var html = [];
+
+  var keys = wave.getState().getKeys();
+
+  for (var i = 0; i < keys.length; ++i) {   
+    var key = keys[i];
+    var value = wave.getState().get(key);
+
+    html.push(key + ' = ' + value);
+    html.push('<br>');
+  }
+  
+  debug(html.join(''));
 }

Added: incubator/wookie/trunk/widgets/sudoku/splash.png
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/sudoku/splash.png?rev=1296299&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/wookie/trunk/widgets/sudoku/splash.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: incubator/wookie/trunk/widgets/sudoku/style.css
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/sudoku/style.css?rev=1296299&r1=1296298&r2=1296299&view=diff
==============================================================================
--- incubator/wookie/trunk/widgets/sudoku/style.css (original)
+++ incubator/wookie/trunk/widgets/sudoku/style.css Fri Mar  2 16:41:18 2012
@@ -16,13 +16,32 @@
  */
 body {
   font: icon;
-  font-size: 15pt !important;
+  font-size: 15pt !important;
+  border: 0px;
+  margin: 0px;
 }
 
 #main {
-  width: 800px;
+  width: 480px;
+  height: 376px;
   text-align: center;
-}
+}
+
+#splash {
+  float:left;
+  width: 376px;
+  height: 376px;
+  text-align: center;
+  background: url('splash.png');
+}
+
+#splash button {
+  margin-top: 200px;
+  font-size: 30px;
+  box-shadow: 0 0 5px rgba(0, 0, 255, 1);
+  -webkit-box-shadow: 0 0 5px rgba(81, 203, 238, 1);
+  
+}
 
 #gameDisplay {
   float: left;
@@ -31,20 +50,22 @@ body {
 #messages {
   height: 100px;
   border: 0px solid red;
-  color: black;
   text-align: left;
 }
 
 #info {
-  width: 300px;
-  float: left;
-  margin-left: 20px; 
+  width: 100px;
+  height: 100%;
+  float: left;
+  background: #555;
+  color: #EEE;
+  margin-left: 0px;
+  padding-left: 4px;
   font-size: 13px;
 }
 
 #rankingDisplay {
-  border: 0px dotted red;
-  color: black;
+  color: #EEE;
   text-align: left;
   padding: 2px;
 }

Modified: incubator/wookie/trunk/widgets/sudoku/sudoku.html
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/sudoku/sudoku.html?rev=1296299&r1=1296298&r2=1296299&view=diff
==============================================================================
--- incubator/wookie/trunk/widgets/sudoku/sudoku.html (original)
+++ incubator/wookie/trunk/widgets/sudoku/sudoku.html Fri Mar  2 16:41:18 2012
@@ -28,14 +28,16 @@
   <input type=button id=clear value='Clear Debug'/>
   <input type=button id=reset value='Reset All States'/>
   <input type=button id=print value='Print All States'/>  
+  <input type=button id=cheat value='Finish game'/>  
   <br>
   <div id='debug'></div>
 </div>
-<br>
 <div align="left">
 <div id=main>
+  <div id='splash'>
+    <button id='start' onclick="newGame()">Start</button>
+  </div>
   <div id='gameDisplay'>
-      <div id='loading'><br>loading ... </div>
       <div id='display'>
         <table cellspacing="0">
           <tr>
@@ -180,7 +182,7 @@
               <table id="grid8" cellspacing="0">
                 <tr>
                   <td id=cell_57></td>
-                  <td id=cell_58></td>
+                  <td id=cell_58></td> 
                   <td id=cell_59></td>
                 </tr>
                 <tr>


Reply via email to