From: Carl Worth Date: Fri, 12 Jun 2020 00:53:20 +0000 (-0700) Subject: empathy: Fix judging interface to properly merge two entire groups X-Git-Url: https://git.cworth.org/git?p=lmno.games;a=commitdiff_plain;h=2f53ad28854b9d68fcbd19ca02002c5883234638;hp=6baa178ee249fde9b660e91c6d6cc374b3d755ac empathy: Fix judging interface to properly merge two entire groups Previously, when selecting an item that was a part of a larger group, it could get pulled out of that group to be merged with the other selected item. This was absolutely bewildering to players. Instead, the right thing is to entirely merge the two groups to which each of the two selected items belong. That's what we do here, and using Set objects rather than simply arrays as we had before. --- diff --git a/empathy/empathy.jsx b/empathy/empathy.jsx index 3d70345..dee5a67 100644 --- a/empathy/empathy.jsx +++ b/empathy/empathy.jsx @@ -349,8 +349,14 @@ class Ambiguities extends React.PureComponent { constructor(props) { super(props); + const word_sets = props.words.map(word => { + const set = new Set(); + set.add(word); + return set; + }); + this.state = { - word_groups: props.words.map(word => [word]), + word_sets: word_sets, submitted: false, selected: null }; @@ -359,7 +365,7 @@ class Ambiguities extends React.PureComponent { async handle_submit() { const response = await fetch_post_json( `judging/${this.props.prompt.id}`,{ - word_groups: this.state.word_groups + word_groups: this.state.word_sets.map(set => Array.from(set)) } ); @@ -382,35 +388,42 @@ class Ambiguities extends React.PureComponent { handle_click(word) { if (this.state.selected == word) { /* Second click on same word removes the word from the group. */ - const new_groups = this.state.word_groups.filter( - group => (! group.includes(this.state.selected)) || (group.length > 1)).map( - group => { - return group.filter(w => w !== this.state.selected); - } - ); + const idx = this.state.word_sets.findIndex(s => s.has(word)); + const set = this.state.word_sets[idx]; + if (set.size === 1) + return; + const new_set = new Set([...set].filter(w => w !== word)); this.setState({ selected: null, - word_groups: [...new_groups, [word]] + word_sets: [...this.state.word_sets.slice(0, idx), + new_set, + new Set().add(word), + ...this.state.word_sets.slice(idx+1)] }); } else if (this.state.selected) { /* Click of a second word groups the two together. */ - const new_groups = this.state.word_groups.filter( - group => (! group.includes(word)) || (group.length > 1)).map( - group => { - if (group.includes(this.state.selected)) { - if (! group.includes(word)) - return [...group, word]; - else - return group; - } else { - return group.filter(w => w !== word); - } - } - ); - this.setState({ - selected: null, - word_groups: new_groups - }); + const idx1 = this.state.word_sets.findIndex(s => s.has(this.state.selected)); + const idx2 = this.state.word_sets.findIndex(s => s.has(word)); + const set1 = this.state.word_sets[idx1]; + const set2 = this.state.word_sets[idx2]; + const new_set = new Set([...set2, ...set1]); + if (idx1 < idx2) { + this.setState({ + selected: null, + word_sets: [...this.state.word_sets.slice(0, idx1), + ...this.state.word_sets.slice(idx1 + 1, idx2), + new_set, + ...this.state.word_sets.slice(idx2 + 1)] + }); + } else { + this.setState({ + selected: null, + word_sets: [...this.state.word_sets.slice(0, idx2), + new_set, + ...this.state.word_sets.slice(idx2 + 1, idx1), + ...this.state.word_sets.slice(idx1 + 1)] + }); + } } else { /* First click of a word selects it. */ this.setState({ @@ -443,24 +456,24 @@ class Ambiguities extends React.PureComponent { what goes around comes around, so it's best to be generous when judging.

- {this.state.word_groups.map(word_group => { + {this.state.word_sets.map(set => { return (
- {word_group.map(word => { - return ( - - ); - })} + {word} + + ); + })}
); })}