chkgk / otree_slider_puzzle

Two-player slider puzzle for oTree
MIT License
2 stars 1 forks source link

Storing moves in the single-player version #4

Closed yukitakahashi1 closed 4 years ago

yukitakahashi1 commented 4 years ago

Hi Christian,

I'd like to store moves in the single-player version of the puzzle. The read me file says the moves can be stored in "the single player variant as well," but I couldn't figure out what I should add to the Game.html (aside from adding <input type="hidden" name="move_history" id="id_move_history"> in the content). Could you tell me what I should additionally add?

Also, I'd like to store the moves for each puzzle separately. How could we do this? Unlike the two-player version, puzzles are defined within Games.html and puzzles appear in the same round (maybe I could add <input type="hidden" name="move_history1" id="id_move_history1">, <input type="hidden" name="move_history2" id="id_move_history2">, ..., in the content? But then I have to call up different move_historyx for different puzzles).

chkgk commented 4 years ago

Hi Yuki,

Let's start by preparing the player model:

class Player(BasePlayer):
  puzzle_histories = models.LongStringField()

Add it to the page:

class Game(Page):
  form_model = 'player'
  form_fields = ['puzzle_histories']

And on the template we add a hidden input field:

<input type='hidden' name='puzzle_histories' id='id_puzzle_histories'>

Now on to the Javascript. We need a way to store the move history of each puzzle. I will use a "histories" list. Each element of the "histories" list will be a list of "moves" of the particular puzzle. Thus, for each board we define, there should be one "move" list in the "histories" list. First we define "histories" as an empty list. Then, we add one empty "move" list for each board we have defined to the "histories" list.

// add below "let current_board = 0;"
let histories = [];
for (board in boards) {
  histories.push([]); 
}

Now, we need a way to fill this history list. On each move, a "move" event is triggered. We listen for this event and react to it by storing the move in the "histories" list and replace the JSON encoded string in the hidden input field:

// add below "let sg = new SliderPuzzle(..."
sg.table.addEventListener('move', function (e) {
  histories[current_board].push(e.detail);
  $('#id_puzzle_histories').val(JSON.stringify(histories));
}, false);

That should be all. I hope I did not miss anything. I do not currently have the time to test it.

yukitakahashi1 commented 4 years ago

Thank you very much Christian, it worked perfectly!