HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Better card validity check in JS card game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
cardbettervaliditygamecheck

Problem

I am writing a card game in Javascript. The game is played with a 32 card deck.

When a card is selected to be played by a user, i do a validity check on the server to check whether it matches the games rules.

These are

  • A card may be played when it matches either the color or the value of the last card on the stack



  • If a 7 is played, the next player must either draw 2 cards or counter with another 7. If he draws, he may play another card that complies the rule above.



  • A jack may be played anytime when there is no 7 to be countered or the player has drawn. It does not have to match the color or value of the last card. When a player plays a jack, he may decide the color of the next card to be played.



I created a class of game that, amongst others, implements a function iscardLegal()

Game.prototype.isCardLegal = function(card,player){

    if(player.flags.forcedDraw > 0 && card.value !== '7'){
        player.setTask('forced draw');
        return false;
    }

    // A jack may be played anytime if there is no 7 on top of the stack
    if(card.value === 'J'){
        return true;
    }

    if(this.forcedColor && this.forcedColor !== card.color){
        player.setTask('color mismatch');
        return false;
    }

    // If there is a forced color due to the playing of a jack, we must ignore the stack#s top card color
    if(this.forcedColor && this.forcedColor === card.color){
        return true;
    }

    if(this.lastCardOnStack().color !== card.color && this.lastCardOnStack().value !== card.value){
            player.setTask('invalid card');
            return false;
    }

    return true;

};


I am unhappy with this function because I end up with a chunk of if rules that need to be in a certain order to match all the rules. If I imagine writing a slightly more complex game, I think this would be unmaintainable.

I am looking for ideas and / or examples of better implemenations of this functionality.

Solution

This is my new attempt

Game.prototype.isCardLegal = function(card,player){

    var requirements = this.getRequirements();

    if(this.cardsToDraw() > 0 && card.value !== '7'){
        player.setTask('forced draw');
        return false;
    }

    if (card.color !== requirements.color && card.value !== requirements.value && card.value !== 'J') {
        player.setTask('invalid card');
        return false;
    }

    return true;

};


When a card is played the game state will be updated with the required color / value. When the played card is a jack or a 7, the respective requirements are set accordingly. So I don't have to distinguish between the color of the last card palyed and a possible forced color any more, as in both cases the game state property will be updated.

I'm still looking for ideas, though.

Code Snippets

Game.prototype.isCardLegal = function(card,player){

    var requirements = this.getRequirements();

    if(this.cardsToDraw() > 0 && card.value !== '7'){
        player.setTask('forced draw');
        return false;
    }

    if (card.color !== requirements.color && card.value !== requirements.value && card.value !== 'J') {
        player.setTask('invalid card');
        return false;
    }

    return true;

};

Context

StackExchange Code Review Q#73337, answer score: 4

Revisions (0)

No revisions yet.