Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions app/controllers/MathSwipeController.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ BoardSolvedService = require '../services/BoardSolvedService'
ClickHandler = require '../services/ClickHandler'
DFS = require '../services/DFS'
ExpressionGenerator = require '../services/ExpressionGenerator'
HashingService = require '../services/HashingService'
HowToPlay = require '../services/HowToPlay'
InputSolver = require '../services/InputSolver'
RandomizedFitLength = require '../services/RandomizedFitLength'
Expand Down Expand Up @@ -33,26 +34,25 @@ class MathSwipeController
TrackingService.desktopView()
@cursorToPointer()
ShareGameService.setMessage()
@initialize window.location.hash
@initialize window.location.hash, 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets change this to @initialize window.location.hash, length where length is an updated constant so it can work better with the leveling system


# # Uncomment the following line to perform general tests
# GeneralTests.tests @board

initialize: (hash) ->
initialize: (hash, length = 3) ->
solutionPlacements = []
goals = []
inputLengths = []
boardValues = []
hasCompleteBoard = false
if hash? and hash isnt ''
hasCompleteBoard = ShareGameService.decode boardValues, goals, solutionPlacements
unless hasCompleteBoard
length = 3
goals = []
solutionPlacements = []
inputs = []
inputLengths = RandomizedFitLength.generate length * length
@generateInputs inputLengths, inputs, goals
boardValues = @generateBoard inputs, length, solutionPlacements
inputs = []
goals = []

decoded = HashingService.decodeMap()
[boardValues, goals, solutionPlacements] = HashingService.parse decoded

if @malformedDecode boardValues, goals, solutionPlacements
inputLengths = RandomizedFitLength.generate length ** 2
[inputs, goals] = @generateInputs inputLengths
boardValues = @generateBoard inputs, length, solutionPlacements

@goalContainer = new GoalContainer goals, Colors
@board = new Board boardValues, @gameScene, goals, @symbols,
Expand All @@ -62,8 +62,9 @@ class MathSwipeController

ResetButton.bindClick @board, RunningSum
RunningSum.empty()
@createNewGame() unless ShareGameService.reloadPageWithHash(@board,
solutionPlacements, SolutionService)

@createNewGame() unless HashingService.reloadPageWithHash(@board,
solutionPlacements, SolutionService)

isMobile: () ->
Android: () ->
Expand Down Expand Up @@ -124,14 +125,18 @@ class MathSwipeController
generateBoard: (inputs, length, solutionPlacements) ->
DFS.setEquationsOnGrid length, inputs, AdjacentCellsCalculator, solutionPlacements

generateInputs: (inputLengths, inputs, goals) ->
generateInputs: (inputLengths, goals = [], inputs = []) ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather have goals = [], inputs = [] as the first two lines of the method since you're only calling @generateInputs using the inputLengths

for inputSize in inputLengths
value = -1
while value < 1 or value > 300
expression = ExpressionGenerator.generate inputSize
value = InputSolver.compute expression
goals.push (InputSolver.compute expression)
inputs.push expression.split('')
inputs.push (expression.split(''))
[inputs, goals]

malformedDecode: (boardValues, goals, solutionPlacements) ->
boardValues.length < 1 or goals.length < 1 or solutionPlacements.length < 1

randExpression: (length) ->
ExpressionGenerator.generate length
Expand Down
12 changes: 4 additions & 8 deletions app/services/ClickHandler.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ class ClickHandler
@clicked = []
@mouseDown = false

setMouseAsDown: ->
@mouseDown = true
setMouseAsDown: -> @mouseDown = true

setMouseAsUp: ->
unless @isMobile
Expand All @@ -23,19 +22,16 @@ class ClickHandler
@RunningSum.display @RunningSum.tilesEmptyString
@mouseDown = false

isMouseDown: ->
@mouseDown
isMouseDown: -> @mouseDown

isOnMobile: ->
@isMobile
isOnMobile: -> @isMobile

bindDefaultMouseEvents: ->
body = $('body')
body.click (e) =>
e.preventDefault()
@unselectAll()
body.mousedown (e) =>
e.preventDefault()
body.mousedown (e) => e.preventDefault()
body.mouseup (e) =>
e.preventDefault()
@unselectAll() unless @isMobile
Expand Down
125 changes: 125 additions & 0 deletions app/services/HashingService.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
class HashingService

@reloadPageWithHash: (board, solutionPlacements, SolutionService) ->
unless @checkSolutionPlacements board, solutionPlacements, SolutionService
@emptyHash()
return false
HashingService.setHash board.initialValues, board.goals, solutionPlacements

@emptyHash: -> window.location.hash = ''

@setHash: (boardValues, goals, solutionPlacements) ->
window.location.hash = @encode boardValues, goals, solutionPlacements

@encode: (boardValues, goals, solutionPlacements) ->
boardValues = (JSON.stringify boardValues).replace(/(\[|\]|"|,|{|})*/g, '')

length = Math.sqrt boardValues.length
for list in [0...solutionPlacements.length]
for pos in [0...solutionPlacements[list].length]
solutionPlacements[list][pos] =
solutionPlacements[list][pos][0] * length +
solutionPlacements[list][pos][1]

btoa(JSON.stringify {b: boardValues, g: goals, p: solutionPlacements})

@decodeMap: () ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for extra ()

try
decoded_s = atob window.location.hash.substr(1, window.location.hash.length)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be the first time using the underscore naming convention.

decoded = JSON.parse decoded_s
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could just make it one line instead of two. We'll just add a newline halfway through to keep to the 80 char limit. This will also take care of creating a new variable

catch e
decoded = null
return decoded

@parse: (decoded) ->
return [[],[],[]] unless @successfulDecode decoded
length = Math.sqrt decoded.b.length
b = @decodeBoardValues decoded.b, length
g = @decodeGoals decoded.g
p = @decodeSolutionPlacements decoded.p, length
[b, g, p]

@successfulDecode: (decoded)->
return decoded? and
decoded.p? and
decoded.g? and
decoded.p? and
@regexPass decoded

@regexPass: (decoded) ->
alphabet = ['"', '{', '}', '[', ']', ',', ':',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it could be better for us to put alphabet as a global constant for the hashing service so we don't have to reassign it each time we check

'b', 'g', 'p', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '0',
'+', '-', '*']
for char in decoded
return false if char not in alphabet
true

@decodeBoardValues: (copy, length, boardValues=[] ) ->
index = 0
for i in [0...length]
row = []
for j in [0...length]
row.push copy[index++]
boardValues.push row
boardValues

@decodeGoals: (toCopy) -> toCopy[..]

@decodeSolutionPlacements: (copy, length, solutionPlacements=[]) ->
for list in [0...copy.length]
expression = []
for coord in [0...copy[list].length]
expression.push [(Math.floor copy[list][coord] / length),
(copy[list][coord] % length)]
solutionPlacements.push expression
solutionPlacements

@checkSolutionPlacements: (board, solutionPlacements, SolutionService) ->
@initializeTempBoard board
@solutionService = new SolutionService @tempBoard, board.goals

inputs = []
for expression in solutionPlacements
clickedCells = []
for index in [0...expression.length]
cell = expression[index]
clickedCells.push {row: cell[0], col: cell[1]}
@solutionService.initialize clickedCells

solution = []
for cell in clickedCells
solution.push @tempBoard.boardValues[cell.row][cell.col]
@tempBoard.boardValues[cell.row][cell.col] = ' '
@pushDownTempBoard()

return false unless @solutionService.isSolution()
inputs.push solution

console.log expression for expression in inputs
console.log '\n'
true

@initializeTempBoard: (board) ->
@tempBoard = {}
@tempBoard.boardValues = []
for row, i in board.initialValues
@tempBoard.boardValues.push []
for col in row
@tempBoard.boardValues[i].push col

@pushDownTempBoard: ->
for row in [@tempBoard.boardValues.length-1..1]
for col in [@tempBoard.boardValues.length-1..0]
if @tempBoard.boardValues[row][col] is ' '
for up in [row-1..0]
unless @tempBoard.boardValues[up][col] is ' '
@swapCells row, col, up, col
break

@swapCells: (r1, c1, r2, c2) ->
temp = @tempBoard.boardValues[r1][c1]
@tempBoard.boardValues[r1][c1] = @tempBoard.boardValues[r2][c2]
@tempBoard.boardValues[r2][c2] = temp

module.exports = HashingService
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pesky newline

110 changes: 0 additions & 110 deletions app/services/ShareGameService.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,115 +2,6 @@ $ = require 'jquery'

class ShareGameService

@reloadPageWithHash: (board, solutionPlacements, SolutionService) ->
unless @checkSolutionPlacements board, solutionPlacements, SolutionService
window.location.hash = ''
return false
hash = @encode board.initialValues, board.goals, solutionPlacements
window.location.hash = hash

@encode: (boardValues, goals, solutionPlacements) ->
boardValues = (JSON.stringify boardValues).replace(/(\[|\]|"|,|{|})*/g, '')

length = Math.sqrt boardValues.length
for list in [0...solutionPlacements.length]
for pos in [0...solutionPlacements[list].length]
solutionPlacements[list][pos] = solutionPlacements[list][pos][0] * length +
solutionPlacements[list][pos][1]

btoa(JSON.stringify {b: boardValues, g: goals, p: solutionPlacements})

@decode: (boardValues, goals, solutionPlacements) ->
try
decoded = atob window.location.hash.substr(1, window.location.hash.length)
decoded = JSON.parse decoded
catch e
decoded = null
return false unless decoded? and decoded.b? and decoded.g? and
decoded.p? and @isValidDecode decoded

length = Math.sqrt decoded.b.length
@decodeBoardValues decoded.b, boardValues, length
@decodeGoals decoded.g, goals
@decodeSolutionPlacements decoded.p, solutionPlacements, length
true

@isValidDecode: (decoded) ->
alphabet = ['"', '{', '}', '[', ']', ',', ':',
'b', 'g', 'p', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '0',
'+', '-', '*']
for char in decoded
return false if alphabet.indexOf(char) is -1
true

@decodeBoardValues: (copy, boardValues, length) ->
index = 0
for i in [0...length]
row = []
for j in [0...length]
row.push copy[index++]
boardValues.push row

@decodeGoals: (copy, goals) ->
goals.push goal for goal in copy

@decodeSolutionPlacements: (copy, solutionPlacements, length) ->
for list in [0...copy.length]
expression = []
for coord in [0...copy[list].length]
expression.push [(Math.floor copy[list][coord] / length),
(copy[list][coord] % length)]
solutionPlacements.push expression

@checkSolutionPlacements: (board, solutionPlacements, SolutionService) ->
@initializeTempBoard board
@solutionService = new SolutionService @tempBoard, board.goals

inputs = []
for expression in solutionPlacements
clickedCells = []
for index in [0...expression.length]
cell = expression[index]
clickedCells.push {row: cell[0], col: cell[1]}
@solutionService.initialize clickedCells

solution = []
for cell in clickedCells
solution.push @tempBoard.boardValues[cell.row][cell.col]
@tempBoard.boardValues[cell.row][cell.col] = ' '
@pushDownTempBoard()

unless @solutionService.isSolution()
return false
inputs.push solution

console.log expression for expression in inputs
console.log '\n'
true

@initializeTempBoard: (board) ->
@tempBoard = {}
@tempBoard.boardValues = []
for row, i in board.initialValues
@tempBoard.boardValues.push []
for col in row
@tempBoard.boardValues[i].push col

@pushDownTempBoard: ->
for row in [@tempBoard.boardValues.length-1..1]
for col in [@tempBoard.boardValues.length-1..0]
if @tempBoard.boardValues[row][col] is ' '
for up in [row-1..0]
unless @tempBoard.boardValues[up][col] is ' '
@swapCells row, col, up, col
break

@swapCells: (r1, c1, r2, c2) ->
temp = @tempBoard.boardValues[r1][c1]
@tempBoard.boardValues[r1][c1] = @tempBoard.boardValues[r2][c2]
@tempBoard.boardValues[r2][c2] = temp

@setMessage: ->
possible = ['Play MathSwipe with me! Try to beat my score at',
'Play MathSwipe with me! Try to solve my board at',
Expand All @@ -120,5 +11,4 @@ class ShareGameService
console.log $('#fb-share')
$( '#fb-share' ).attr( 'data-href' , window.location.hash )


module.exports = ShareGameService
23 changes: 11 additions & 12 deletions app/services/SolutionService.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,24 @@ InputSolver = require './InputSolver'
class SolutionService

constructor: (@board, goals, @RunningSum) ->
@goals = []
@goals.push g for g in goals
@goals = goals[..]

initialize: (clickedCells) ->
@setSolutionString clickedCells
@value = InputSolver.compute @solution

isSolution: ->
return false unless @solution?
return false if @solution[@solution.length - 1] is '+' or
@solution[@solution.length - 1] is '-' or
@solution[@solution.length - 1] is '*'
return false unless @value in @goals
if not @isCompleteExpression()
return false unless @solution? and @finished and @value in @goals

if @isCompleteExpression()
@valueIndex = @goals.indexOf @value
@goals[@valueIndex] = ' '
true
else
@RunningSum.display @RunningSum.solutionOperatorString
return false
@valueIndex = @goals.indexOf @value
@goals[@valueIndex] = ' '
true
false

finished: -> @solution[@solution.length - 1] not in "+-*"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have to use " instead of '?


isCompleteExpression: -> @solution.search(/-?\d+[-+\*]\d+/g) is 0

Expand Down
Loading