2
players = {
    player1: {
        currentpos: 0,
        prevpos: 0,
        startpos: 0,
        balance: 1500
    },
    player2: {
        currentpos: 0,
        prevpos: 0,
        startpos: 0,
        balance: 1500
    }
};
positions = {
    position1: {
        title: "Cairo",
        type: "brown",
        owner: "unowned",
        purchaseprice: 60,
        rentprice: 2,
        forsale: "y"
    },
    position2: {
        title: "Schiphol Airport",
        type: "airport",
        owner: "unowned",
        purchaseprice: 200,
        rentprice: 25,
        forsale: "y"
    },
    position3: {
        title: "Vienna",
        type: "brown",
        owner: "unowned",
        purchaseprice: 60,
        rentprice: 4,
        forsale: "y"
    },
    position6: {
        title: "Brussels",
        type: "blue",
        owner: "unowned",
        purchaseprice: 100,
        rentprice: 6,
        forsale: "y"
    }
};

I want to know if a player owns a set. For instance 2 browns makes a set. It takes 3 blues to make a set. A player could own more than 1 sets. He could own 2 browns and 3 blues and thus the blue set and the brown set. Owning a set determines whether a player can build properties. At the momement when a player buys a position I just update the "owner" value from "unowned" to "playername". What properties should I add to help establish whether a player owns a set.

Pavlo
  • 43,301
  • 14
  • 77
  • 113
Elton Frederik
  • 259
  • 1
  • 3
  • 12

3 Answers3

2

It would be more convenient if you had your positions as an array rather that a plain object. We'll covert it internally using map(), so array methods such as filter() and every() can be used:

function doesOwnSet(player, type) {
    // we'll use "chaining" here, so every next method will be called upon
    // what previous method have returned

    // `return` statement will return the result of the very last method

    // first, lets take an array of `position` object keys
    // which are "position1", "position2" and so on
    return Object.keys(positions)

        // then, create an array of positions object
        // this will return Array
        .map(function (key) {
            return positions[key];
        })

        // then, pick up only positions with specified type (aka set)
        // this will return Array
        .filter(function (pos) {
            return pos.type === type;
        })

        // finally, check if specified player owns every position of the set
        // this will return Boolean
        .every(function (pos) {
            return pos.owner === player;
        });
}

You could use this function in if statement like so:

if (doesOwnSet(players.player1, 'brown')) {
    // give some reward to player1
}
Pavlo
  • 43,301
  • 14
  • 77
  • 113
  • Thanks Pavlo, I am making the monopoly board game as a learning process. So your answer is really difficult for me to understand. – Elton Frederik Dec 30 '13 at 22:48
  • Yes Pavlo, but last time I was told I should only accept an answer if it works. While your code likely would work, whether I can actually make it work is a different matter. – Elton Frederik Dec 30 '13 at 23:10
  • @EltonFrederik A quote from [the Help Center](http://stackoverflow.com/help/accepted-answer): *"Accepting an answer is not meant to be a definitive and final statement indicating that the question has now been answered perfectly."* With the scope you've given, I humbly believe this is pretty much the best answer you can get. – Pavlo Dec 30 '13 at 23:15
  • 1
    I tested the code, by artificially changing the values of the 2 brown sets from "unowned" to "player1" and running if (doesOwnSet(players.player1, 'brown')) { alert("Pavlo is God"); } But it didnt work... – Elton Frederik Dec 30 '13 at 23:22
  • @EltonFrederik that's why I've asked how do you identify players. In this case, you'll have to call it like `doesOwnSet('player1', 'brown')`. – Pavlo Dec 30 '13 at 23:28
  • Oh sorry. Yes it works now. Pavlo is God. But I have no idea what exactly is happening despite your comments. But I need to learn about filter() and every(). Thanks a lot! – Elton Frederik Dec 30 '13 at 23:32
0

The most efficient way would be to store references to the positions inside the user object, and have separate colour_group objects like so:

color_groups = {
    blue:{
        positions:[
          {..position1..},
          {..position2..}
          ...
        }
    },
    green:{
        positions:[
            {..position3..},
            {..position4..}
            ...
        ]
    },
    ....
}

If you build color_groups from the positions hash using something like this,

color_groups = {};
for (var pos_name in positions) {
    var pos = positions[pos_name];

    if (!color_groups[pos.type]) color_groups[pos.type] = {positions:{}};

    color_groups[pos.type].positions[pos_name] = pos; // Assignment works by reference, i.e. it does not copy 'pos'
}

Then each position object in the positions hash will also appear in the color_groups hash. When you change the owner of a position, its owner will also appear to change in the color_groups hash because they both refer to the same object.

You should use arrays for storing some of your data rather than objects, since arrays can be iterated over more conveniently. You should also look into creating classes using a constructor and a prototype.

It would be helpful for you to do something similar to the users object, so you can conveniently get a list of property each user owns. You would then know when a player owns a color_group if:

player1.positions[color_group_type].length == color_groups[color_group_type].length

Without changing your data structure, Pavlo's answer will work fine.

user1158559
  • 1,954
  • 1
  • 18
  • 23
0

If a player buys a place, the method buy is called with the player. The places are defined in an Array. The first for checks for all streets, whether the player has it or not. If Yes, the second for checks whether another place is owned, which is not the first. If the type of both match, there is a set owned by the player. This script only checks two places, it is easy to check more.

function player_has_set (player){
    var streets = new Array();
    streets[0]="brown";
    streets[1]="brown";
    //...
    for(var i=0;i<streets.length;i++){
        if(player.has(i)){
            var first_street_type=streets[i];
            for(var j=0;j<streets.length;j++){
                if(player.has(j)&&j!==i){
                    var second_street_type=streets[j];
                    if(first_street_type===second_street_type){
                        //SET
                    }
                }
            }
        }
    }
}
Paul Schmitz
  • 101
  • 1
  • 4