X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=main.coffee;h=89bc69503ccad5ab719cfaeae58fd7dd18994afc;hb=f22ca7c08d0628d1b4a021820afdd406b4e826a0;hp=b44afb6b5cc0e21a7141199f07be543b20c7d9c3;hpb=418e647c63e4edd7853456a0f9b462f1ebe37fb6;p=hexbog.git diff --git a/main.coffee b/main.coffee index b44afb6..89bc695 100644 --- a/main.coffee +++ b/main.coffee @@ -127,18 +127,19 @@ new_letter_queue = [] new_letter = -> if new_letter_queue.length l = new_letter_queue.shift() - if l is 'Q' - return 'Qu' - else - return l + l.letter = l.letter.toUpperCase() + if l.letter is 'Q' + l.letter = 'Qu' + return l + hp = 1 + Math.floor(Math.random() * (HP_MAX - 1)) r = Math.floor Math.random() * (letter_distribution_total + 1) for i in [0..25] r -= letter_distribution[i] if r <= 0 if letters[i] is 'Q' - return 'Qu' - return letters[i] - return 'Z' # just in case + return letter: 'Qu', hp: hp + return letter: letters[i], hp: hp + return letter: 'Z', hp: hp # just in case @@ -224,6 +225,48 @@ init_board_layout = () -> col_offset += board_col_heights[col_num] +# support obsolete save data format +load_game_0 = (encoded) -> + letters = (encoded.substr 0, board_tiles).split '' + for l in letters + new_letter_queue.push { + letter: l, + hp: 1 + Math.floor(Math.random() * (HP_MAX - 1)) + } + score = parseInt(encoded.substr(board_tiles), 10) + +load_game_1 = (encoded) -> + int = 0 + encoded = encoded.substr 1 + score = parseInt(encoded.substr(board_tiles * 3 / 2), 10) + for t in [0...(tiles.length * 3 / 2)] by 3 + int = 0 + for d in [0...3] + int *= 44 + char = encoded[t + 2 - d] + int += save_charset.indexOf(char) + t2hp = int % 11 + int = Math.floor(int / 11) + t2letter = String.fromCharCode(char_a + (int % 26)) + int = Math.floor(int / 26) + t1hp = int % 11 + int = Math.floor(int / 11) + t1letter = String.fromCharCode(char_a + (int % 26)) + new_letter_queue.push { + letter: t1letter, + hp: t1hp + } + new_letter_queue.push { + letter: t2letter, + hp: t2hp + } + +load_game = (encoded) -> + switch encoded.substr 0, 1 + when "1" + load_game_1(encoded) + else + load_game_0(encoded) init_board = -> encoded = window.location.hash @@ -232,8 +275,7 @@ init_board = -> unless encoded? and encoded.length > board_tiles encoded = get_cookie 'hexbog' if encoded? and encoded.length > board_tiles - new_letter_queue = (encoded.substr 0, board_tiles).split '' - score = parseInt(encoded.substr(board_tiles), HP_MAX) + load_game encoded # work out which grid spaces are connected # (neighbors, above, down) @@ -293,28 +335,40 @@ unselect_all = -> _unselect_tile() update_selection_display() -shrink_selection = (leave_count) -> - while selected.length > leave_count - _unselect_tile() - update_selection_display() - selected_word = -> word = '' word += tiles[i].text for i in selected return word.toLowerCase() +save_charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR' +char_a = "a".charCodeAt(0) save_game = -> - encoded = '' - for t in tiles - encoded += t.text.substr 0, 1 + encoded = '1' # save format + for i in [0...tiles.length] by 2 + int = tiles[i].text.toLowerCase().charCodeAt(0) - char_a + int *= 11 + int += tiles[i].hp + int *= 26 + int += tiles[i+1].text.toLowerCase().charCodeAt(0) - char_a + int *= 11 + int += tiles[i+1].hp + for d in [0...3] + encoded += save_charset.substr(int % 44, 1) + int = Math.floor(int / 44) encoded += score set_cookie 'hexbog', encoded, 365 window.location.hash = encoded +unsink = (tile) -> + tile.new_hp = 10 + tile.text = new_letter().letter + tile.dom.html tile.text + # remove the selected tiles from the board, create new tiles, and slide everything into place blip_selection = -> - difficulty = 7 # higher numbers are easier - unsink = difficulty * score_for selected_word() # how much tile restoration we have left to do + difficulty = 11 - Math.log(400 + score) # higher numbers are easier + force = difficulty * score_for selected_word() # how much tile restoration we have left to do + word_length = selected_word().length faders = selected.num_sort() selected = [] update_selection_display() @@ -335,20 +389,77 @@ blip_selection = -> # convert to arrays so we can sort, etc nneighbors = (v for k, v of nneighbors) neighbors = (v for k, v of neighbors) - # TODO randsort neighbors and nneighbors - for nei in [neighbors, nneighbors] - if unsink > 0 - for i in nei - if i.hp is 0 and unsink >= 15 - i.new_hp = 10 - unsink -= 15 - i.text = new_letter() - i.dom.html i.text - if unsink > 0 - for i in nei - if i.hp > 0 and unsink > 0 - unsink -= 10 - i.hp - i.new_hp = 10 + boom = [ + { + tiles: neighbors, + up: [], + down: [] + }, + { + tiles: nneighbors, + up: [], + down: [] + } + ] + for n in boom + for t in n.tiles + if t.hp is 0 + n.down.push t + else + n.up.push t + switch word_length + when 3 + boom[0].flips = 1 + boom[0].force = 2 + boom[1].flips = 0 + boom[1].force = 0 + when 4 + boom[0].flips = 'all' + boom[0].force = 4 + boom[1].flips = 0 + boom[1].force = 2 + when 5 + boom[0].flips = 'all' + boom[0].force = 6 + boom[1].flips = 2 + boom[1].force = 4 + when 6 + boom[0].flips = 'all' + boom[0].force = 10 + boom[1].flips = 5 + boom[1].force = 6 + when 7 + boom[0].flips = 'all' + boom[0].force = 10 + boom[1].flips = 'all' + boom[1].force = 10 + else + boom[0].flips = 0 + boom[0].force = 0 + boom[1].flips = 0 + boom[1].force = 0 + # unsink/heal the whole board + for t in tiles + if t.hp is 0 + unsink t + else + t.new_hp = 10 + for b in boom + if b.flips is 'all' or b.flips >= b.down.length + for t in b.down + unsink t + else + down_count = b.down.length + while b.flips > 0 and down_count + b.flips -= 1 + flipper = Math.floor(Math.random() * down_count) + unsink b.down[flipper] + down_count -= 1 + # move the last tile back into range + b.down[flipper] = b.down[down_count] + if b.force > 0 + for t in b.up + t.new_hp = t.hp + b.force for i in tiles i.new_hp ?= i.hp - 1 if i.new_hp < 0 @@ -443,9 +554,9 @@ select_tile = (num) -> return new_tile = (num, x, y) -> - letter = new_letter() - - hp = Math.floor(Math.random() * HP_MAX) + l = new_letter() + letter = l.letter + hp = l.hp html_tile = $("
#{letter}
") $board.append(html_tile) @@ -456,27 +567,20 @@ new_tile = (num, x, y) -> html_tile.click -> me = $(this) num = me.data 'tile_number' + return if tiles[num].hp < 1 if num in selected - nth_of_word = selected.indexOf(num) - first = nth_of_word is 0 - last = nth_of_word is selected.length - 1 - - if first and last - unselect_all() # Clicking only selected letter unselects it - else if first and !last - shrink_selection 1 # Clicking start of word goes back to just that letter - # should this unselect all? - else if last + if selected_word().length > 2 and num is selected.last() activate_selection() else - shrink_selection nth_of_word + 1 - else # (not clicking on selected tile) - if selected.length is 0 - select_tile num - else - unless num in board_neighbors[selected.last()] + if selected.length > 1 unselect_all() - select_tile num + select_tile num + else + unselect_all() + else # (not clicking on selected tile) + if selected.length > 0 and not (num in board_neighbors[selected.last()]) + unselect_all() + select_tile num $board = null