Spooky-0 / FreeBoardGames.org

FOSS platform for publishing boardgame.io games
https://www.FreeBoardGames.org
GNU Affero General Public License v3.0
0 stars 0 forks source link

Secret State #1

Closed Spooky-0 closed 4 years ago

Spooky-0 commented 4 years ago

Untill now, I have only worked locally. There are only two fields in G which should be hidden to the player. It is the deck, and your own hand. This is the interface of G

export interface IG {
  deck: ICard[];
  deckindex: number;
  trash: ICard[];
  piles: ICard[][];

  hands: IHand[];

  countdown: number;
  treats: number;
}

and I want

G.deck and G.hands[myId].cards to be hidden.

  playerView: (G, ctx, playerID) => {
    // return G
    for (var i = 0; i < G.deck.length; i++) {
      G.deck[i] = null
    }

    // Hide your own cards
    var id = parseInt(playerID) 
    if (!(isNaN(id))) { // However, if this is not a multiplayer then this is NaN. For testing only, as this game can only be played Multiplayer.
      console.log("Hiding for player", id)
      var len = G.hands[id].length
      for (var i = 0; i < len; i++) {
        G.hands[id].cards = null
      }
    }

    return G
  },

is how I tried.. but when playing a move which relies on secret state I get


(node:20488) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'id' of null
    at /home/j/Documents/boardgame/FreeBoardGames.org/server/dist/server_bgio.js:242825:39
    at Proxy.map (<anonymous>)
    at /home/j/Documents/boardgame/FreeBoardGames.org/server/dist/server_bgio.js:242807:27
    at Proxy.map (<anonymous>)
    at Proxy.movePlay (/home/j/Documents/boardgame/FreeBoardGames.org/server/dist/server_bgio.js:242792:20)
    at Proxy.<anonymous> (/home/j/Documents/boardgame/FreeBoardGames.org/node_modules/boardgame.io/dist/server.js:705:56)
    at Immer.produce (/home/j/Documents/boardgame/FreeBoardGames.org/node_modules/boardgame.io/dist/server.js:727:41)
    at result (/home/j/Documents/boardgame/FreeBoardGames.org/node_modules/boardgame.io/dist/server.js:702:34)
    at Object.processMove (/home/j/Documents/boardgame/FreeBoardGames.org/node_modules/boardgame.io/dist/server.js:2876:24)
    at /home/j/Documents/boardgame/FreeBoardGames.org/node_modules/boardgame.io/dist/server.js:3508:30
(node:20488) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:20488) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
JvSomeren commented 4 years ago

Hi!

Your moves which rely on the secret state can be changed to the following format (see here):

moves: {
  moveThatUsesSecret: {
    move: (G, ctx) => {
      ...
    },

    client: false,
  }
}

This tells boardgame.io to process these moves only on the server.

Spooky-0 commented 4 years ago

I tried this - or at least I thinki I did. I didn't quite undestand the documentation. I might have gotten something else wrong tho. But if that is indeed the way to do it, i will look more into this.

THanks.

JvSomeren commented 4 years ago

What you did here looks like it should work!

Perhaps there still is an issue with the playerView? Could you try the following?

  playerView: (G, ctx, playerID) => {
    let playerG = {...G}
    for (var i = 0; i < G.deck.length; i++) {
      playerG.deck[i] = null
    }

    // Hide your own cards
    var id = parseInt(playerID) 
    if (!(isNaN(id))) { // However, if this is not a multiplayer then this is NaN. For testing only, as this game can only be played Multiplayer.
      console.log("Hiding for player", id)
      var len = playerG.hands[id].length
      for (var i = 0; i < len; i++) {
        playerG.hands[id].cards = null
      }
    }

    return playerG
  },
Spooky-0 commented 4 years ago

I got it to work by doing the magical Immer trick:


  playerView: (G, ctx, playerID) => {
    // Hide your own cards
    var id = parseInt(playerID) 

    if (isNaN(id)) { // However, if this is not a multiplayer then this is NaN. 
            //     // For testing only, as this game can only be played Multiplayer.
      console.log(playerID)

      return G
    }

    return {
      ...G,
      deck: G.deck.map((value, index) => { return null}),
      hands: G.hands.map((hand: IHand, index: number) => {
            if (index !== id) {
              return hand
            }
            return <IHand> {
              cards: hand.cards.map((card: ICard,  index_card: number) => {return null}),
              hints: hand.hints,
              player: hand.player
            }
      })
    }

dont ask me why this works :)