<commit_before>import alt from '../calt';
import _ from 'lodash';
import MultiplayerActions from '../actions/multiplayer';
import SetCard from '../setcard';

class MultiplayerStore {
  constructor() {
    this.my_player_id = undefined;
    this.players = {};
    this.cards = [];
    this.selected = new Set();      // stringify-ed SetCards
    this.current_state = 'WAITING_FOR_PLAYERS';

    this.bindListeners({
      handleUpdatePlayers: MultiplayerActions.UPDATE_PLAYERS,
      handleClearName: MultiplayerActions.CLEAR_NAME,
      handleChangeName: MultiplayerActions.CHANGE_NAME,
      handleReceiveMessage: MultiplayerActions.RECEIVE_MESSAGE,
      handleSelectCard: MultiplayerActions.SELECT_CARD,
      handleClearSelected: MultiplayerActions.CLEAR_SELECTED,
    });
  }

  handleUpdatePlayers(players) {
    console.log('MultiplayerStore.handleUpdatePlayers: players = %O', players);
    this.players = players;
  }

  handleClearName() {
    console.log('MultiplayerStore.handleClearName');
    this.my_player_id = null;
  }

  handleChangeName(new_name) {
    console.log('MultiplayerStore.handleChangeName');
    this.my_player_id = new_name;
  }

  handleSelectCard(card) {
    console.log('MultiplayerStore.handleSelectCard');
    let cardString = SetCard.stringify(card);

    if (this.selected.has(cardString)) {
      this.selected.delete(cardString);
    }
    else {
      this.selected.add(cardString);
    }
  }

  handleClearSelected() {
    console.log('MultiplayerStore.handleClearSelected');
    this.selected.clear();
  }

  handleReceiveMessage(message) {
    console.log('MultiplayerStore.handleReceiveMessage: message = %O', message);

    const
      onAddPlayer = (data) => {
        let { my_player_id, players } = data;
        // TODO: race condition here -- we would like a way to uniquely identify each requester
        if (this.my_player_id === undefined) {
          this.my_player_id = my_player_id;
        }
        this.players = players;
        if (this.current_state == 'WAITING_FOR_PLAYERS' && _.size(this.players) > 1) {
          this.current_state = 'WAITING_FOR_CLICK_START';
        }
        return true;
      },
      onChangeName = (data) => {
        let { old_name, new_name } = data;
        if (!(old_name && new_name)) {
          return false;
        }
        this.players[new_name] = this.players[old_name];
        delete this.players[old_name];
        return true;
      },
      onCountdownStart = () => {
        this.current_state = 'WAITING_FOR_COUNTDOWN';
      },
      onStartGame = (data) => {
        let { cards } = data;
        this.cards = cards;
        this.current_state = 'IN_PROGRESS';
      };

    let actions = {
      'add-player': onAddPlayer,
      'change-name': onChangeName,
      'countdown-start': onCountdownStart,
      'start-game': onStartGame,
      'verify-set': (data) => {
        let { valid, cards_to_add, cards_to_remove, player, found, game_over } = data;
        if (!valid) {
          return false;
        }

        cards_to_remove.forEach((c) => {
          this.cards[_.findIndex(this.cards, _.matches(c))] = cards_to_add.pop();
        });
        while (cards_to_add.length) {
          this.cards.push(cards_to_add.pop());
        }

        this.players[player] = found;
      }
    };

    actions[message.action].call(this, message);
  }
}

module.exports = alt.createStore(MultiplayerStore, 'MultiplayerStore');<commit_msg>deselect a SetCard if it gets removed when someone else finds a set<commit_after>import alt from '../calt';
import _ from 'lodash';
import MultiplayerActions from '../actions/multiplayer';
import SetCard from '../setcard';

class MultiplayerStore {
  constructor() {
    this.my_player_id = undefined;
    this.players = {};
    this.cards = [];
    this.selected = new Set();      // stringify-ed SetCards
    this.current_state = 'WAITING_FOR_PLAYERS';

    this.bindListeners({
      handleUpdatePlayers: MultiplayerActions.UPDATE_PLAYERS,
      handleClearName: MultiplayerActions.CLEAR_NAME,
      handleChangeName: MultiplayerActions.CHANGE_NAME,
      handleReceiveMessage: MultiplayerActions.RECEIVE_MESSAGE,
      handleSelectCard: MultiplayerActions.SELECT_CARD,
      handleClearSelected: MultiplayerActions.CLEAR_SELECTED,
    });
  }

  handleUpdatePlayers(players) {
    console.log('MultiplayerStore.handleUpdatePlayers: players = %O', players);
    this.players = players;
  }

  handleClearName() {
    console.log('MultiplayerStore.handleClearName');
    this.my_player_id = null;
  }

  handleChangeName(new_name) {
    console.log('MultiplayerStore.handleChangeName');
    this.my_player_id = new_name;
  }

  handleSelectCard(card) {
    console.log('MultiplayerStore.handleSelectCard');
    let cardString = SetCard.stringify(card);

    if (this.selected.has(cardString)) {
      this.selected.delete(cardString);
    }
    else {
      this.selected.add(cardString);
    }
  }

  handleClearSelected() {
    console.log('MultiplayerStore.handleClearSelected');
    this.selected.clear();
  }

  handleReceiveMessage(message) {
    console.log('MultiplayerStore.handleReceiveMessage: message = %O', message);

    const
      onAddPlayer = (data) => {
        let { my_player_id, players } = data;
        // TODO: race condition here -- we would like a way to uniquely identify each requester
        if (this.my_player_id === undefined) {
          this.my_player_id = my_player_id;
        }
        this.players = players;
        if (this.current_state == 'WAITING_FOR_PLAYERS' && _.size(this.players) > 1) {
          this.current_state = 'WAITING_FOR_CLICK_START';
        }
        return true;
      },
      onChangeName = (data) => {
        let { old_name, new_name } = data;
        if (!(old_name && new_name)) {
          return false;
        }
        this.players[new_name] = this.players[old_name];
        delete this.players[old_name];
        return true;
      },
      onCountdownStart = () => {
        this.current_state = 'WAITING_FOR_COUNTDOWN';
      },
      onStartGame = (data) => {
        let { cards } = data;
        this.cards = cards;
        this.current_state = 'IN_PROGRESS';
      },
      onVerifySet = (data) => {
        let { valid, cards_to_add, cards_to_remove, player, found, game_over} = data;
        if (!valid) {
          return false;
        }
        cards_to_remove.forEach((c) => {
          this.selected.delete(SetCard.stringify(c));
          this.cards[_.findIndex(this.cards, _.matches(c))] = cards_to_add.pop();
        });
        while (cards_to_add.length) {
          this.cards.push(cards_to_add.pop());
        }

        this.players[player] = found;
      };

    let actions = {
      'add-player': onAddPlayer,
      'change-name': onChangeName,
      'countdown-start': onCountdownStart,
      'start-game': onStartGame,
      'verify-set': onVerifySet,
    };

    actions[message.action].call(this, message);
  }
}

module.exports = alt.createStore(MultiplayerStore, 'MultiplayerStore');
{'fraction_non_alphanumeric': 0.12293916998294485, 'fraction_numerical': 0.0002842524161455372, 'mean_word_length': 2.767130620985011, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5306765', 'n_tokens_mistral': 2181, 'n_tokens_neox': 2151, 'n_words': 372}