Author: hhubner
Date: 2007-11-14 00:27:46 -0500 (Wed, 14 Nov 2007)
New Revision: 2276
Modified:
branches/trunk-reorg/projects/scrabble/src/game.lisp
branches/trunk-reorg/projects/scrabble/src/package.lisp
branches/trunk-reorg/projects/scrabble/src/rules.lisp
branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp
branches/trunk-reorg/projects/scrabble/src/web.lisp
branches/trunk-reorg/projects/scrabble/website/scrabble.html
branches/trunk-reorg/projects/scrabble/website/scrabble.js
Log:
snapshot
Modified: branches/trunk-reorg/projects/scrabble/src/game.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/game.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/game.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -17,12 +17,10 @@
(let ((tmp (aref tiles i))
(random-index (random (fill-pointer tiles))))
(setf (aref tiles i) (aref tiles random-index))
- (setf (aref tiles random-index) tmp)))))
+ (setf (aref tiles random-index) tmp))))
+ tile-bag)
-(defmethod initialize-persistent-instance :after ((tile-bag tile-bag))
- (shake-tile-bag tile-bag))
-
-(defun make-tile-bag (language)
+(deftransaction make-tile-bag (language)
(let ((tiles (make-array 102 :adjustable t :fill-pointer 0)))
(mapcar (lambda (entry)
(destructuring-bind (letter value count) entry
@@ -30,7 +28,7 @@
(vector-push-extend (make-tile letter value) tiles))))
(or (getf *tile-sets* language)
(error "language ~A not defined" language)))
- (make-object 'tile-bag :tiles tiles)))
+ (shake-tile-bag (make-object 'tile-bag :tiles tiles))))
(define-condition no-tiles-remaining (simple-error)
())
@@ -76,8 +74,8 @@
((participant :initarg :participant
:reader participant-of)
(placed-tiles :initarg :placed-tiles
- :reader placed-tiles)
- (new-tiles-drawn :initarg :new-letters-drawn
+ :reader placed-tiles-of)
+ (new-tiles-drawn :initarg :new-tiles-drawn
:reader new-tiles-drawn-of
:documentation "New letters that have been drawn after
the move, should the move need to be undone")
@@ -91,7 +89,7 @@
(print-unreadable-object (move stream :type t)
(format stream "by ~A, ~A points (~{~A~^, ~})"
(player-of (participant-of move))
- (reduce #'+ (mapcar #'cdr (words-formed-of move)))
+ (score-of move)
(words-formed-of move))))
(defclass game (store-object)
@@ -159,14 +157,13 @@
(let ((tray-letters (mapcar #'letter-of (tray-of participant)))
(placed-letters (mapcar (compose #'letter-of #'tile-of) placed-tiles)))
(dolist (letter placed-letters)
- (let ((has-letter (find letter tray-letters :test #'letter-equal))
- (has-blank (find nil tray-letters)))
- (unless (or has-letter has-blank)
- (error "participant ~A does not have tile ~A" participant letter))
- (setf tray-letters
- (if has-letter
- (remove letter tray-letters :test #'letter-equal :count 1)
- (remove nil tray-letters :key #'letter-of :count 1)))))))
+ (let ((has-letter (find letter tray-letters :test #'letter-equal)))
+ (unless (or has-letter (find nil tray-letters))
+ (error "participant ~A does not have tile ~A" participant letter))
+ (setf tray-letters
+ (if has-letter
+ (remove letter tray-letters :test #'letter-equal :count 1)
+ (remove nil tray-letters :key #'letter-of :count 1)))))))
(defun remove-letters-from-participant-tray (participant tiles)
(let (removed-tiles)
@@ -182,30 +179,35 @@
(append drawn (tray-of participant)))
drawn))
+(deftransaction make-move% (game participant placed-tiles)
+ (let ((words-formed (mapcar (lambda (word-result)
+ (cons (word-text word-result) (word-score word-result)))
+ (words-formed (board-of game) placed-tiles))))
+ (dolist (placed-tile placed-tiles)
+ (put-letter (board-of game) (tile-of placed-tile) (x-of placed-tile) (y-of placed-tile)))
+ (let ((tiles-used (remove-letters-from-participant-tray participant (mapcar #'tile-of placed-tiles)))
+ (tiles-drawn (draw-new-letters (tile-bag-of game) participant (length placed-tiles)))
+ (score (reduce #'+ (mapcar #'cdr words-formed))))
+ (when (eql 7 (length tiles-used))
+ (incf score 50))
+ (incf (score-of participant) score)
+ (let ((move (make-object 'move
+ :participant participant
+ :placed-tiles placed-tiles
+ :new-tiles-drawn tiles-drawn
+ :words-formed words-formed
+ :score score)))
+ (push move (moves-of game))
+ (rotate-participants game)
+ move))))
+
(defun make-move (game participant placed-tiles)
(ensure-participants-turn game participant)
(ensure-participant-has-tiles participant placed-tiles)
(check-move-legality (board-of game) placed-tiles)
- (with-transaction (:make-move)
- (let ((words-formed (mapcar (lambda (word-result)
- (cons (word-text word-result) (word-score word-result)))
- (words-formed (board-of game) placed-tiles))))
- (dolist (placed-tile placed-tiles)
- (put-letter (board-of game) (tile-of placed-tile) (x-of placed-tile) (y-of placed-tile)))
- (let ((tiles-used (remove-letters-from-participant-tray participant (mapcar #'tile-of placed-tiles)))
- (tiles-drawn (draw-new-letters (tile-bag-of game) participant (length placed-tiles)))
- (score (reduce #'+ (mapcar #'cdr words-formed))))
- (when (= 7 (length tiles-used))
- (incf score 50))
- (incf (score-of participant) score)
- (push (make-object 'move
- :participant participant
- :placed-tiles placed-tiles
- :new-tiles-drawn tiles-drawn
- :words-formed words-formed
- :score score)
- (moves-of game))))
- (rotate-participants game)))
+ (make-move% game participant (mapcar (lambda (placement)
+ (list (x-of placement) (y-of placement) (tile-of placement)))
+ placed-tiles)))
(defclass move-withdrawal (store-object)
((participant :initarg :participant
@@ -214,26 +216,28 @@
:reader reason-of))
(:metaclass persistent-class))
+(deftransaction withdraw-last-move% (game reason move)
+ (with-slots (participant placed-tiles new-tiles-drawn score) move
+ (decf (score-of participant) score)
+ (setf (tray-of participant)
+ (append (set-difference (tray-of participant) new-tiles-drawn)
+ (mapcar #'tile-of placed-tiles)))
+ (undraw-tiles (tile-bag-of game) new-tiles-drawn)
+ (dolist (placement placed-tiles)
+ (put-letter (board-of game) nil (x-of placement) (y-of placement)))
+ (unrotate-participants game)
+ (push (make-object 'move-withdrawal
+ :participant participant
+ :reason reason)
+ (moves-of game))))
+
(defun withdraw-last-move (game reason)
(let ((move (car (moves-of game))))
(unless move
(error "no move in game to withdraw"))
- (unless (typep game 'move)
+ (unless (typep move 'move)
(error "last move was not a letter placement, can't be withdrawn"))
- (with-transaction (:withdraw-last-move)
- (with-slots (participant placed-tiles new-tiles-drawn score) move
- (decf (score-of participant) score)
- (setf (tiles-of (tray-of participant))
- (append (set-difference (tiles-of (tray-of participant))
- new-tiles-drawn)
- (mapcar #'tile-of placed-tiles)))
- (undraw-tiles (tile-bag-of game) new-tiles-drawn)
- (dolist (placement placed-tiles)
- (put-letter (board-of game) nil (x-of placement) (y-of placement)))
- (push (make-object 'move-withdrawal
- :participant participant
- :reason reason)
- (moves-of game))))))
+ (withdraw-last-move% game reason move)))
(defclass tile-swap (store-object)
((participant :initarg :participant
@@ -247,8 +251,7 @@
(error "not enough remaining tiles to swap"))
(with-transaction (:swap-tiles)
(setf (tray-of participant)
- (append (set-difference (tray-of participant)
- tiles)
+ (append (set-difference (tray-of participant) tiles)
(draw-tiles (tile-bag-of game) (length tiles))))
(undraw-tiles (tile-bag-of game) tiles)
(push (make-object 'tile-swap
Modified: branches/trunk-reorg/projects/scrabble/src/package.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/package.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/package.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -28,11 +28,16 @@
"TRAY-OF"
"MAKE-TILE-PLACEMENTS"
+ "X-OF"
+ "Y-OF"
+ "TILE-OF"
+
"MAKE-MOVE"
"MOVE"
"SCORE-OF"
"PARTICIPANT-OF"
"WORDS-FORMED-OF"
+ "PLACED-TILES-OF"
"GAME"
"LANGUAGE-OF"
Modified: branches/trunk-reorg/projects/scrabble/src/rules.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/rules.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/rules.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -41,7 +41,7 @@
(and (= (x-of tile-placement-1) (x-of tile-placement-2))
(= (y-of tile-placement-1) (y-of tile-placement-2))))
-(defmethod position-equal ((position list) (tile-placement tile-placement))
+(defmethod position-equal ((position list) tile-placement)
"Return non-nil if the given POSITION is at the position of PLACED-TILE"
(and (= (first position) (x-of tile-placement))
(= (second position) (y-of tile-placement))))
@@ -63,14 +63,13 @@
(format stream "~C " (aif (at-xy board x y) (letter-of it) #\.)))
(terpri stream))))
-
(defmethod at-xy ((board board) x y)
(aref (placed-tiles-of board) x y))
(defmethod at-placement ((board board) tile-placement)
(at-xy board (x-of tile-placement) (y-of tile-placement)))
-(defun put-letter (board tile x y)
+(deftransaction put-letter (board tile x y)
(setf (aref (placed-tiles-of board) x y) tile))
(defclass tile (store-object)
@@ -81,7 +80,7 @@
(defmethod print-object ((tile tile) stream)
(print-unreadable-object (tile stream :type t :identity nil)
(with-slots (letter value) tile
- (format stream "~A (~A)" (when letter (char-name letter)) value))))
+ (format stream "~A (~A) ID:~A" (when letter (char-name letter)) value (store-object-id tile)))))
(defun make-tile (letter value)
(make-object 'tile :letter letter :value value))
@@ -146,6 +145,15 @@
t)
+(defmethod x-of ((placement list))
+ (first placement))
+
+(defmethod y-of ((placement list))
+ (second placement))
+
+(defmethod tile-of ((placement list))
+ (third placement))
+
(defun words-formed% (board placed-tiles verticalp)
"Scan for words that would be formed by placing PLACED-TILES on
BOARD. VERTICALP determines the scan order, if nil, the board is
Modified: branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -1,15 +1,11 @@
(in-package :scrabble.web)
-(defclass scrabble-store (mp-store random-mixin)
- ())
-
(defun open-scrabble-store (&optional delete-old-p)
(ignore-errors (close-store))
(when delete-old-p
(asdf:run-shell-command "rm -rf /tmp/scrabble-store/"))
- (make-instance 'scrabble-store :directory "/tmp/scrabble-store/"
- :subsystems (list (make-instance 'store-object-subsystem)
- (make-instance 'random-mixin-subsystem)))
+ (make-instance 'mp-store :directory "/tmp/scrabble-store/"
+ :subsystems (list (make-instance 'store-object-subsystem)))
(unless (class-instances 'user)
(format t "creating test users and game~%")
(let ((user1 (make-user "user1" :class 'player :full-name "User Eins"))
Modified: branches/trunk-reorg/projects/scrabble/src/web.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/web.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/web.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -28,15 +28,22 @@
(encode-json-plist (list :remaining-tiles (remaining-tile-count tile-bag)) stream))
(defmethod encode-json ((move move) stream)
- (encode-json-plist (list :participant-login (user-login (player-of (participant-of move)))
+ (encode-json-plist (list :type "move"
+ :participant-login (user-login (player-of (participant-of move)))
:score (score-of move)
+ :placed-tiles (placed-tiles-of move)
:words (mapcar (lambda (word-cons)
(list :word (car word-cons)
:score (cdr word-cons)))
(words-formed-of move)))
stream))
-
+(defmethod encode-json ((move move-withdrawal) stream)
+ (encode-json-plist (list :type "move-withdrawal"
+ :participant-login (user-login (player-of (participant-of move)))
+ :reason (or (reason-of move) ""))
+ stream))
+
(defmethod encode-json ((board board) stream)
(princ #\[ stream)
(dotimes (x 15)
@@ -57,16 +64,15 @@
(length (tray-of participant)))))
stream))
-(define-easy-handler (login :uri "/login" :default-request-type :post)
+(define-easy-handler (login :uri "/login" :default-request-type :get)
(login password)
(format t "warning: password not checked~*~%" password)
(when (and login
(find-user login))
(start-session)
(setf (session-value :user) login)
- (redirect "/games"))
+ (redirect "/scrabble.html"))
(with-html-output-to-string (*standard-output* nil)
-
(:html
(:head
(:title "scrabble login"))
@@ -121,10 +127,11 @@
(progn
(let* ((game (find-game game))
(participant (find (find-user (session-value :user)) (participants-of game) :key #'player-of)))
- (scrabble:make-move game
- participant
- (parse-move participant move))
- (encode-json-plist (list :game game) s)))
+ (encode-json-plist
+ (list :move (scrabble:make-move game
+ participant
+ (parse-move participant move))
+ :tray (tray-of participant)) s)))
(error (e)
(encode-json-plist (list :error (princ-to-string e)) s)))))
Modified: branches/trunk-reorg/projects/scrabble/website/scrabble.html
===================================================================
--- branches/trunk-reorg/projects/scrabble/website/scrabble.html 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/website/scrabble.html 2007-11-14 05:27:46 UTC (rev 2276)
@@ -12,5 +12,7 @@
<body onload="init()">
<div id='playfield'>
</div>
+ <div style="position: absolute; right: 20px; top: 20px;"><a style="color: white;" href="/login?login=user1">user1</a></div>
+ <div style="position: absolute; right: 20px; top: 40px;"><a style="color: white;" href="/login?login=user2">user2</a></div>
</body>
</html>
\ No newline at end of file
Modified: branches/trunk-reorg/projects/scrabble/website/scrabble.js
===================================================================
--- branches/trunk-reorg/projects/scrabble/website/scrabble.js 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/website/scrabble.js 2007-11-14 05:27:46 UTC (rev 2276)
@@ -273,6 +273,7 @@
alert(response.error);
} else {
clearMove();
+ makeMyTray(map(function (entry) { return entry.letter }, response.tray))
}
}