Skip to content
Browse files

Looking like a game now, just needs a timer

  • Loading branch information...
1 parent 48dc437 commit 1b2a8002931b82d96ccc604710448ad96b7828b2 @caseywebdev committed May 5, 2012
Showing with 216 additions and 42 deletions.
  1. +83 −0 client/app.coffee
  2. +41 −6 controllers/socket.coffee
  3. +5 −0 models/battle.coffee
  4. +31 −15 models/rack.coffee
  5. +49 −15 stylus/app.coffee
  6. +6 −5 views/battle-view.coffee
  7. +1 −1 views/lobby-view.coffee
View
83 client/app.coffee
@@ -71,16 +71,69 @@
(new ChallengeView model: name1: user1.get 'name').render()
@on battle: ->
+ user.set
+ inBattle: true
+ words: []
_.PopUp.hide()
battle = new Battle @data.battle
battle.set
users: new User.Collection battle.get 'users'
rack: new Rack battle.get 'rack'
(new BattleView model: battle).render()
+ playMessage 'green', 'GO!!!'
@on declineChallenge: ->
_.PopUp.show "#{_.escape @data.name2} declined your challenge.", duration: 2000
+ @on battleOver: ->
+ user.set inBattle: false
+ lobby()
+
+ @on play: ->
+ battle.get('users').reset [@data.user1, @data.user2]
+ user.set if user.get('name') is @data.user1.name then @data.user1 else user.set @data.user2
+ $('#user1-container .score').html Rack.wordValue @data.user1.words
+ $('#user1-container .words')
+ .html(_.reduce @data.user1.words, (html, word) ->
+ html + "<strong>#{Rack.wordValue word}</strong> #{word}<br>"
+ , '')
+ .scrollTop $('#user1-container .words').prop 'scrollHeight'
+ $('#user2-container .score').html Rack.wordValue @data.user2.words
+ $('#user2-container .words')
+ .html(_.reduce @data.user2.words, (html, word) ->
+ html + "<strong>#{Rack.wordValue word}</strong> #{word}<br>"
+ , '')
+ .scrollTop $('#user2-container .words').prop 'scrollHeight'
+
+ @on alreadyPlayed: ->
+ alreadyPlayed()
+
+ alreadyPlayed = ->
+ playMessage 'red', 'Already played!'
+
+ @on notAWord: ->
+ notAWord()
+
+ notAWord = ->
+ playMessage 'red', 'Not a word!'
+
+ @on playedWord: ->
+ playedWord()
+
+ playedWord = ->
+ playMessage 'green', 'Played word!'
+
+ playMessage = (color, text) ->
+ $('#play-message')
+ .removeClass()
+ .addClass(color)
+ .text(text)
+ .stop()
+ .css(
+ opacity: 1
+ display: 'block'
+ ).animate opacity: 0, 1000, -> $(@).css display: 'none'
+
$ =>
lobby()
@@ -122,3 +175,33 @@
@emit declineChallenge:
name1: $(e.currentTarget).data 'name1'
)
+
+ lastChar = ''
+
+ $(document).on('keydown', (e) =>
+ if user.get 'inBattle'
+ if e.keyCode is 8
+ battle.get('rack').removeLast()
+ $("#played-tiles .tile").last().appendTo $ '#rack'
+ e.preventDefault()
+ lastChar = ''
+ else if e.keyCode is 13
+ word = battle.get('rack').word()
+ if word.length > 2
+ unless Rack.wordValue
+ notAWord()
+ else if battle.wordPlayed word
+ alreadyPlayed()
+ else
+ @emit play:
+ word: word
+ battle.get('rack').removeAll()
+ $("#played-tiles .tile").appendTo $ '#rack'
+ lastChar = ''
+ else
+ char = String.fromCharCode e.keyCode
+ unless lastChar is 'Q' and char is 'U'
+ if battle.get('rack').play char
+ $("#rack .letter-#{char}").first().appendTo $ '#played-tiles'
+ lastChar = char
+ )
View
47 controllers/socket.coffee
@@ -12,11 +12,20 @@ _ = require 'underscore'
@on disconnect: ->
if name = @client.user.get 'name'
+ if @client.user.get 'inBattle'
+ battle = battles.filter((battle) ->
+ battle.get('users').where(name: name).length
+ )[0]
+ opponent = battle.get('users').find (u) ->
+ u.get('name') isnt name
+ battle.destroy()
+ opponent.set inBattle: false
+ @broadcast notice:
+ text: "#{_.escape opponent.get 'name'} defeated #{_.escape name}!"
+ @io.sockets.socket(opponent.get 'socketId').emit 'battleOver'
@broadcast notice:
- battle: @client.user.get 'battle'
text: "#{name} has disconnected."
@client.user.destroy()
- @emit users: users.toJSON()
@broadcast users: users.toJSON()
@on attr: ->
@@ -43,7 +52,6 @@ _ = require 'underscore'
@emit 'signedIn'
else
@emit 'nameUnavailable'
-
@on say: ->
text = @data.text.replace(/\s+/, ' ').replace /^ | $/, ''
@@ -66,8 +74,14 @@ _ = require 'underscore'
users: new User.Collection [user1, user2]
rack: (new Rack).randomize()
battles.add battle
- user1.set inBattle: true
- user2.set inBattle: true
+ user1.set
+ number: 1
+ inBattle: true
+ words: []
+ user2.set
+ number: 2
+ inBattle: true
+ words: []
@emit users: users.toJSON()
@broadcast users: users.toJSON()
@emit 'battle', battle: battle.toJSON()
@@ -76,5 +90,26 @@ _ = require 'underscore'
@on declineChallenge: ->
user1 = users.where(name: @data.name1)[0]
@io.sockets.socket(user1.get 'socketId').emit 'declineChallenge', name2: @client.user.get 'name'
-
+
+ @on play: ->
+ name = @client.user.get 'name'
+ word = @data.word
+ battle = battles.find (battle) ->
+ battle.get('users').where(name: name).length
+ unless Rack.wordValue word
+ @emit 'notAWord'
+ else if battle.wordPlayed word
+ @emit 'alreadyPlayed'
+ else
+ @client.user.get('words').push word
+ opponent = battle.get('users').find (u) ->
+ u.get('name') isnt name
+ user1 = battle.get('users').where(number: 1)[0]
+ user2 = battle.get('users').where(number: 2)[0]
+ data =
+ user1: user1.toJSON()
+ user2: user2.toJSON()
+ @emit 'playedWord'
+ @emit play: data
+ @io.sockets.socket(opponent.get 'socketId').emit 'play', data
View
5 models/battle.coffee
@@ -7,6 +7,11 @@ Backbone = require 'backbone'
class root.Battle extends Backbone.Model
+ wordPlayed: (word) ->
+ @get('users').reduce (check, user) ->
+ check or word in user.get 'words'
+ , false
+
class root.Battle.Collection extends Backbone.Collection
model: Battle
View
46 models/rack.coffee
@@ -9,18 +9,16 @@ Backbone = require 'backbone'
class root.Rack extends Backbone.Collection
model: Tile
-
- played: []
-
+
randomize: ->
@reset _.map Tile.DISTRIBUTION, (die) ->
new Tile letter: die[Math.floor Math.random() * die.length]
word: ->
- @reduce (letters, tile) ->
+ (@reduce (letters, tile) ->
letters += tile.get 'letter' if tile.get 'isPlayed'
letters
- , ''
+ , '').toLowerCase()
validWord: ->
Dictionary.hasWord @word()
@@ -31,21 +29,39 @@ Backbone = require 'backbone'
Rack.wordValue @word()
@wordValue: (word) ->
- length = word.length
- if Dictionary.hasWord(word) and length > 2
- switch length
- when 3, 4 then return 1
- when 5 then return 2
- when 6 then return 3
- when 7 then return 5
- else return 11
- 0
+ if word instanceof Array
+ _.reduce word, (total, w) ->
+ total + Rack.wordValue w
+ , 0
+ else
+ length = word.length
+ if Dictionary.hasWord(word) and length > 2
+ switch length
+ when 3, 4 then return 1
+ when 5 then return 2
+ when 6 then return 3
+ when 7 then return 5
+ else return 11
+ 0
play: (letter) ->
- letter = 'qu' if letter == 'q'
+ letter = 'Qu' if letter == 'Q'
for tile in @models
if tile.get('letter') is letter and not tile.get 'isPlayed'
+ tile.set isPlayed: true
@remove tile
@add tile
return true
false
+
+ removeLast: ->
+ last = @last().set isPlayed: false
+ @remove last
+ @unshift last
+ @
+
+ removeAll: ->
+ @each (tile) ->
+ tile.set isPlayed: false
+ @
+
View
64 stylus/app.coffee
@@ -53,7 +53,7 @@
#main
container()
padding-bottom: 200px
- height: 400px;
+ height: 410px;
background: url('/images/footer.png') center bottom no-repeat
#footer
@@ -71,6 +71,9 @@
color: #fff
text-decoration: underline
+ #sign-in
+ margin-top: 5px
+
#users-container
float: left
width: 200px
@@ -143,11 +146,12 @@
border-radius: 3px
background: #fff noise
box-shadow: 0 1px 3px rgba(0, 0, 0, .5)
+ text-align: center
#user1-container,
#user2-container
float: left
- width: 200px
+ width: 230px
border-radius: 3px
background: #fff noise
box-shadow: 0 1px 3px rgba(0, 0, 0, .5)
@@ -156,7 +160,7 @@
line-height: 40px
color: #fff
text-shadow: 0 1px 1px rgba(0, 0, 0, .5)
- background: #f66 noise
+ background: #f96 noise
text-align: center
font-size: 20px
border-top-left-radius: 3px
@@ -166,28 +170,58 @@
line-height: 50px
color: #fff
text-shadow: 0 1px 1px rgba(0, 0, 0, .5)
- background: #f96 noise
+ background: #f66 noise
text-align: center
font-size: 30px
.words
height: 210px
overflow-y: auto
padding: 10px
+
+ #user2-container
+ float: right
+
+ #accept-challenge,
+ #decline-challenge
+ dislay: inline-block
+ padding: 5px
+ color: #fff
+ text-shadow: 0 1px 1px rgba(0, 0, 0, .5)
+ background: #9f9 noise
+
+ #decline-challenge
+ background-color: #f66
+
+ #play-message
+ position: absolute
+ display: none
+ width: 100%
+ line-height: 80px
+ font-size: 50px
+ text-align: center
+ text-shadow: 0 1px 1px rgba(0, 0, 0, .5)
+ &.red
+ color: #f66
+
+ &.green
+ color: #9f9
+
#rack
float: left
- width: 400px
+ padding: 0 10px
+ width: 320px
text-align: center
- .tile
- display: inline-block
- width: 80px
- padding-top: 20px
- height: 60px
- color: #fff
- text-shadow: 0 1px 1px rgba(0, 0, 0, .75)
- font-size: 30px
- text-align: center
- background: url('/images/tile.png') center no-repeat
+ .tile
+ display: inline-block
+ width: 80px
+ padding-top: 20px
+ height: 60px
+ color: #fff
+ text-shadow: 0 1px 1px rgba(0, 0, 0, .75)
+ font-size: 30px
+ text-align: center
+ background: url('/images/tile.png') center no-repeat
'''
View
11 views/battle-view.coffee
@@ -9,15 +9,17 @@ Backbone = require 'backbone'
el: '#main'
template: _.template '''
- <div id='played-tiles'></div>
+ <div id='played-tiles'><div id='play-message'></div></div>
<div id='user1-container'>
<div class='name'><%= get('users').models[0].get('name') %></div>
<div class='score'>0</div>
<div class='words'></div>
</div>
- <div id='rack'>
- <% get('rack').each(function(tile, i) { if (i > 0 && !(i % 4)) print('<br>'); %><div class='tile'><%= tile.get('letter') %></div><% }) %>
- </div>
+ <div id='rack'><%
+ get('rack').each(function(tile, i) {
+ %><div class='tile letter-<%= tile.get('letter')[0] %>'><%= tile.get('letter') %></div><%
+ })
+ %></div>
<div id='user2-container'>
<div class='name'><%= get('users').models[1].get('name') %></div>
<div class='score'>0</div>
@@ -27,6 +29,5 @@ Backbone = require 'backbone'
'''
render: ->
- console.log @model
@$el.html @template @model
@
View
2 views/lobby-view.coffee
@@ -11,7 +11,7 @@ Backbone = require 'backbone'
template: _.template '''
<div id='users-container'>
<h1>Users</h1>
- <p>Click on a user to battle them.</p>
+ <p>Click a user to challenge them.</p>
<div id='users-list'></div>
</div><div id='chat-container'>
<div id='chat-log'></div>

0 comments on commit 1b2a800

Please sign in to comment.
Something went wrong with that request. Please try again.