Game Development Journal 9: Breaking out the Hand Logic

In my last journal, I talked about setting up the scoring system. I put that separate from the actual Hand because I don’t necessarily think it needs to be in there. I want to keep everything in the Hand that absolutely must be there.

GameNotesI find myself getting overwhelmed thinking about how all the pieces work together. I get confused and either over simplify things or overly confuse them.

I found that when this happens to me, it really helps to write things down on paper with pens like a savage.

For some reason, typing things out on my computer does not have the same cognitive resolution as physically writing things out and sketching them. I can use different colors for different things. It’s not super organized, but when I am trying to organize my thoughts, there is nothing better.

At first I was trying to figure out what properties I needed in my class. Then I realized that I was approaching things wrong. I had to think about what this class has to do rather than figuring out what I need first. If you want to cook, you figure out your recipe before you buy your ingredients.

The Hand class is basically a game loop. It plays out a hand of this game. It has to shuffle the cards and deal them to the players. It has to keep track of the current player and run a turn. If that turn does not end the game, it has to move to the next player and keep doing this until the hand ends.

This logic in pseudocode would look something like this:

    // Deal Cards/Initialize
    
    // Game Loop:
    /*
     
     Continue: Bool
     isWin: Bool
     
     Reset Players
     
     While continue is true and deck > 0. Return an optional player.
     
     1. Player plays a card
     2. Card from the stack gets played
     3. Computer checks for a match and distributes cards
     4. Computer checks for a win
     4a. If there is a win, the computer checks if someone else has called stop.
         If no, the computer asks the player if they want to go or stop. If yes,
         the loop ends.
     5a. If the player calls stop, the loop ends
     5b. If the player calls go, the computer moves to the next player and the game continues
     
    */

The loop needs to know if it continues or not. This is complicated by the game mechanic of the player being able to keep playing once they accumulate enough points to win. If a second player accumulates enough points to win after a first player has already called Go, the second player does not have the option to continue the game. This variable does not need to persist outside of the loop function, so I can make its scope confined to the loop.

The same is true with the isWin variable. We don’t care if someone has called Go after the hand is over.

It’s possible for no one to win the hand. If a player calls Go and accumulates no more points but the game plays to the end, then there could be no winner. The Game class that is going to create instances of this Hand class in its own game loop needs to know if there was a winner, and if so, who. The Player class (now) has a property that tracks how many points the player has. So when the hand is over if someone is a winner, that player gets passed back to the Game class that can check the property on the winner to distribute the chips. If a new hand is played, then these properties are reset and the game continues. This may not be the best way to organize things, so it may be refactored later.

Now that I know what the loop looks like, I can create my pseudocode of the methods that will be called by this loop:

    // Game Logic
    
    // Play a card (pass in an array)
    // Check for Match
    // Distribute cards
    // Check for win
    // Reset Players

I need to figure out what gets passed into these functions and what are mutable properties of the Hand class. However, this was far easier to figure out after I wrote out all the steps that the game loop needs to implement on each given turn.

Since I have a better understanding of what this class will do, figuring out what properties I need is simple:

    // Properties
    /*
      1. Players
      2. Current Player
      3. Shuffled Deck
      4. Cards on Board
      5. Draw Pile
    */

Conclusion

I know this doesn’t look super exciting. I haven’t written any “real” code, but I have made things a lot easier for myself whenever I pick this back up again. I can noodle around with this for 15 minutes every now and then and fill in all of these methods. I have broken this complicated piece of programming logic down into manageable tasks.

I might pull those methods called by the game loop out into functions like I did with the scoring to make it easier to test them. I can create non-random arrays to use for test data without having to create a whole instance of a Hand class where that property will always change.

Anyway, it always feels good to get anything done on this. An application is just an incredibly long series of small tasks. Doing a little every day results in progress. I’ll take it.

Why Dad Jokes are Sexist and Terrible

I decided I haven’t had enough people getting pissed off at me on Twitter recently, so I want to offload a complaint that has been building in my head for the last year or so.

We have a plague and a scourge on our society. This scourge is inhibiting our ability to have meaningful communication and is destroying our souls slowly. This scourge is, of course, the Dad Joke.

Imaging This

Pretend you get called into your boss’s office. He tells you that your job has been terminated and you are to leave the building immediately.

You are blindsided. You had no idea this was coming.

You recently burned through your savings saving the family dog after it ingested a bottle of Gorilla Glue. You didn’t want your kids going to therapy in high school saying you killed the family dog, so you’ve been living paycheck to paycheck for a few months.

You don’t have another job lined up. You don’t know where you can find another one or how long you’ll be unemployed.

You’re filled with dread going home. What will your wife say? How will you feed your family? What are you going to do?

You walk into the kitchen and watch your wife. With a heavy heart, you say to her, “Honey, I lost my job today.”

Your wife puts on a goofy smile and says “Well, have you tried looking in the last place you had it?!” She nudges you with her elbow and chuckles and watches you, waiting for you to laugh.

How would this make you feel??

It fills me with a blinding rage.

I have had men make Dad Jokes in response to tweets I have put on Twitter talking about suicide attempts and PTSD flashbacks. I have asked questions for which I need answers and I get a response of a fucking Dad Joke.

This leaves me with a few ways to respond:

  • I can ignore it. If I do ignore it, especially if it’s something that I need an answer for, the guy will go about his life and never actually answer the question. He’s done his duty and he will move on without actually doing what he was asked to do.
  • I can swallow my rage and go back and rephrase the question to remove whatever offending word or phrase prompted the Dad Joke. This really pisses me off because the guy knows what I was asking but he’s forcing me to ask him again anyway.
  • I can play dumb and pretend like I don’t understand that the guy is making a Dad Joke. Then they get sulky because I didn’t do the socially acceptable thing by indulgently chuckling and praising his cleverness.

Why Do We Have Dad Jokes Anyway?

I feel for men. I really do. Our horrible toxic culture places so many stupid limitation on men and what constitutes socially acceptable behavior. Men don’t cry. Men don’t show emotions besides anger. Men don’t wear nail polish. Men don’t wear dresses. Men don’t dance. A male kindergarten teacher must be a pervert. A male nurse wasn’t good enough to get into medical school to be a doctor. Our society sucks at teaching men how to know how they feel.

Men never really learn how to have meaningful conversations with other human beings. So we train them to respond with Dad Jokes. Dad Jokes are like line dancing. No one thinks that line dancing is cool, but we allow white people to do it because it’s the thing we all can do equally badly and we all just make a social contract to not make fun of one another when we’re trying to do it.

Dad Jokes are like hipster irony. It’s a deflection device to avoid showing that you give a shit about anything. Someone is talking about something that triggers uncomfortable emotional responses, guys feel the need to shield themselves from it because they honestly don’t know what the fuck they’re supposed to do to try and fix it.

We’ve socially agreed to tolerate Dad Jokes. We’ve all agreed to chuckle indulgently at a dude making a lame Dad Joke and give him a cookie and move on with our lives.

Sometimes Dad Jokes are acceptable. I just take issue with the fact that I feel forced socially to treat them with gentle good humor when they are actively obfuscating my ability to get something done or make a meaningful point.

When to Not Make a Dad Joke

Here are the times when you don’t make a Dad Joke:

  • When someone is talking about rape/murder/cancer/anything that is a horrific life event. The person just wants to be heard. Either say nothing if you’re on Twitter or if you don’t know what to say, just say “I’m sorry that happened to you.”
  • When someone is asking you for information they need to do their job. If you must make a stupid Dad Joke, then please for the love of God also answer the question rather than forcing the other person to chuckle politely and then rephrase the question.

I sincerely hope that one day we can give men more emotional freedoms to be able to express and feel emotions. I think our society will be better whenever we reach that blessed day. Until then, please do not make me feel like shit by making stupid Dad Jokes when I phrase something oddly to try and get my character count under 140 characters. Thank you.

Video Game Research: Opening Statement

I have a confession to make: I do not play many video games.

When I was a kid, my dad would not let my brother and I get any kind of video gaming system. He thought they caused violent behavior and he preferred that we enrich our minds rather than shoot things. This was the beginning of my unfortunate addiction to buying lots and lots of books.

I do have a lot of fond memories of playing Myst and various adventure games as a high school student. I liked wandering around exploring virtual worlds and solving puzzles. I liked the slow pace of these things. There was no need for me to coordinate my shots to blow things up. They were peaceful and stimulating. I liked the stories and especially the humor.

I didn’t own a gaming console until I married my ex-husband. He had most of them. I was overwhelmed by the variety of things we had, but by the time we got married he had kind of fallen out of video gaming.

He bought me several Nintendo DS systems throughout our marriage. Two years in a row he bought me a 3DS. There is a reason we are no longer married.

I primarily stuck to really simple games. I am embarrassed at how much Bejeweled I play on my phone. When I have been bashing my brain against code for eight hours and I am in the bath, the simple joy of spending five minutes making a bunch of gems explode really can’t be overemphasized.

After my divorce, I decided that gaming was going to be my new hobby. I bought a PS4 and a bunch of games. Like seriously, I think I have 500 games in the Playstation ecosystem. I have no idea how I accumulated these fuckers.

I got stuck more in the “idea” of gaming than the actual doing of gaming. It’s like the massive number of programming books I have bought over the years for things I will never do. I liked the idea that I would sit down at the end of the day and play Random Japanese RPG:IV at the end of a long day of work.

However, I ran into a knowledge barrier with them. I started trying to play various Final Fantasy games, but I had no background knowledge about how any of them work (yes, I know they’re all the same). So I would try to play them and die about two minutes in and have no idea what the hell just happened.

I would like to get better at video games.

Why I am Doing This

First off, I am writing a game. The game I am writing is a really old game that has already been play tested over many decades and has solid game mechanics. But this still fits under the kinds of games I personally feel comfortable with. I feel comfortable with card games and things that are solidly in the “casual game” field.

I would like to push myself into less comfortable territory and actually try other things. I would like to try and get through Mass Effect without dying while trying to save Liara. I would like to figure out the game mechanics for Final Fantasy.

I want to work through several video games and write about them on my blog from the perspective of someone who does not have a long history with these things.

I feel a little that video gaming is like programming. People kind of assume that if you are interested in it, you’ve done it your whole life and have a whole base of knowledge you don’t have. It’s not really welcoming to noobs who just want to get their feet wet and enjoy themselves. I think that’s incredibly unfortunate.

I would like to write about the things I encounter as a noob that make no sense to me. I would also like to explore various genres available to establish to myself that not all video games are first person shooters. I am sure there are a lot of compelling games out there that do more than just plunk you down in Iraq and have you blow up insurgents. I think that video games get a bad rap based on the more prominent members of the community and the things they tend to enjoy.

Since I am fairly slow with these things, I don’t know how many games I will get through. I may write about a game for several weeks.

I would appreciate suggestions for games people think are worth playing. I am interested in many different genres. I do ask for no purely first person shooters as I am terrible at those.

I have the following game systems:

  • PS3
  • PS4
  • PSVita
  • Nintendo 3DS
  • Steam on Mac
  • iPhone/iPad

Fair warning, I am going to be talking about a bunch of “soft” games on here. I am unapologetically a “girl gamer” who does not kick your ass at Halo. I hope some day to be one that does, but for now I am not. I am trying to expand my horizons and experiment outside my comfort zone.

Game Development Journal 8: Scoring and Hand-Game Complexity

I am reaching a point in this project where I am trying to figure out how to proceed. I have my base deck and player functionality in place. After that, things get tricky.

Godori is a hand-based card game, similar to poker. In poker, you have multiple hands. If there were not multiple hands, then the betting would be irrelevant. There would be no point in betting on any specific hand because each hand would be all or nothing.

This means that I need to parse out how to separate the hand-based game logic from the overall game logic. This presents a tricky situation where it would be easy to try and place all of this in one massive class that has to deal with a lot of state. There will be a necessary amount of state, but I would prefer the state get handled by the right things.

Initially I was going to place most of the game logic into the Hand class, but I have realized that I don’t want everything in there. That class should simply be running the game. It should have a loop where it keeps track of the current player, ensures the player completes their turn, determines if a win condition has occurred, if the player has differed the win, then start over again with the next player. The scoring is a separate bit of functionality. It should be able to call functions that do the scoring for it rather than putting all of that into the Hand Class.

Yes, I realize this may not be the best way of handling things. I know that you should try to encapsulate functionality within data structures, but I also hate opening up a class to find a thousand lines of code. For me, conceptually, it’s easier for me to think of the scoring in terms of stand alone functions than trying to figure out how they fit within the Hand class.

Scoring Code

So I am creating a utility file of functions that take an array of cards as an input and return an integer that represents the score.

There are four types of cards, so I am going to write four functions to score the cards and one to call all of those functions.

The easiest one to score is the Brights. According to the rules of Godori, there are five Bright cards. You do not get any points until you collect three Brights. If you collect all five, you get a whopping fifteen points! Huzzah!

The stumbling block I came across with this was how to take advantage of a design decision I implemented earlier. I made a Card protocol that all of the card types conform to. Since the type isn’t a property on the struct, I was trying to figure out how to check the type and only count the ones that are of type BrightCard.

Some Googling brought me to a conditional logic statement I have not seen yet: if-is.

If-is allows you to check if something is a certain data type. Instead of having to add another property to each struct that represents its type, I can check it directly using that logic statement.

Here is my function to score my Bright Cards:

func brightScore(cards:[Card]) -> Int {
    
    var numberOfCards:Int = 0
    var score:Int = 0
    
    for card in cards {
        if card is BrightCard {
            numberOfCards += 1
        }
    }
    
    switch numberOfCards {
    case 3:
        score = 3
    case 4:
        score = 4
    case 5:
        score = 15
    default:
        score = 0
    }
    
    return score
}

This feels rather verbose. I am sure there is a better way to write this. I will revisit it later when I have a chance to think it over for a while.

Even though this is verbose, it’s very clear about what this function does. I like that it’s clear if you look this over about how this function works. Future Janie wants to look at code that will be clear to her about what it does.

If I decide to try and do something with Map() or whatever I want to make sure that it’s still perfectly clear to anyone what this does. I don’t care about cutting out lines of code as much as I care about clarity and performance. I understand that the vast amounts of conditional logic in the scoring functions might cause a performance hit, but I don’t want to prematurely optimize.

I am putting a pin in this to check later.

I am also going to share the Animal scoring function. This type is a little more complicated. There are three bird cards in the Animal set. If you capture all three bird cards, it scores you an extra five points.

I had to add a nested if statement to this function. After determining if a card is an Animal card or not, I additionally have to determine if it’s a bird or not. Since bird is not a property on the Card protocol, I have to cast the card as an Animal card when I know it will be an animal to check its bird property.

func animalScore(cards:[Card]) -> Int {
    var numberOfCards:Int = 0
    var numberOfBirds:Int = 0
    var score:Int = 0
    
    for card in cards {
        if card is AnimalCard {
            numberOfCards += 1
            
            let animalCard = card as! AnimalCard
            
            if animalCard.isBird == true {
                numberOfBirds += 1
            }
        }
    }
    
    switch numberOfCards {
    case 5:
        score = 1
    case 6:
        score = 2
    case 7:
        score = 3
    case 8:
        score = 4
    case 9:
        score = 5
    default:
        score = 0
    }
    
    if numberOfBirds == 3 {
        score += 5
    }
    
    return score
}

Refactoring the Switch Statement

After I went through and completed all of the scoring functions, I noticed there was a lot of repetition. This got really annoying with the Junk cards where the points start accumulating at ten cards and went all the way up to a possible 26 junk cards.

The Brights don’t follow a pattern, but all the other cards do. They have a lowest number of cards to be worth any points. Each additional card is worth a point. Instead of doing switch statements, I should be able to do this with less code.

I figured out that if I check if the number of cards is equal to or greater than this barrier to entry, I can subtract a certain amount from the number of cards to get the value.

With the ribbon and animal cards, if you have five cards, it’s worth one point. Each additional card is worth an additional point. This means that I can check to see if the number of cards is above five. If so, I can subtract four from the number of cards to get the number of points. If there are seven cards and you subtract four, you get three. This is scalable in the way the switch statement is not. I don’t have to worry that I miscounted the junk cards and that I will take away the player’s points after they exceed the number I thought there were.

This is the Junk scoring function, after the refactor:

func junkScore(cards:[Card]) -> Int {
    var numberOfCards:Int = 0
    var score:Int = 0
    
    for card in cards {
        if card is JunkCard {
            numberOfCards += 1
            
            let junkCard = card as! JunkCard
            
            if junkCard.isDouble == true {
                numberOfCards += 1
            }
        }
    }
    
    if numberOfCards >= 10 {
        score = numberOfCards - 9
    } else {
        score = 0
    }
    
    return score
}

Returning the Score

Now that all the scoring is encapsulated in each of these functions, I can write a short and sweet function checking the score for the entire hand:

func currentPlayerScore(cards:[Card]) -> Int {
    return brightScore(cards: cards) +
        animalScore(cards: cards) +
        ribbonScore(cards: cards) +
        junkScore(cards: cards)
}

Wrapping Up

One advantage to breaking this out as I have is that it is now a lot easier to unit test. I don’t have to make an instance of a hand just to check the scoring. I can create mock data that checks each of the conditions within all the functions.

One of my goals with this project was to figure out how to break down everything into small, doable chunks. If you look at the entire application as a whole, it’s overwhelming. By pulling out chunks that can be knocked off one by one and building upon those chunks, you can slowly build up a stable application based on a solid foundation without worrying too much about what goes on top.

Next up I am hoping to add more functionality to the Hand class. I need to create the properties and set up the game loop that will walk through how a turn works.

Ta ta for now!

Game Development Journal 7: Creating the Player Struct

When I started out this project, I tried to figure out what pieces needed to be in place to create a working prototype of this game without a user interface. I am planning to start off making this a command line application that can be played with text input and output.

I tentatively narrowed it down to these components:

  • A representation of the game “board” with all the player’s remaining money and the current state of the game. This will determine if any player has run out of money and if the game should continue after each hand.
  • A representation of a complete hand of the game. This is where the game logic for scoring and win conditions will be stored.
  • A representation of a player.
  • A representation of a deck of cards.

Since every part of this list is dependent upon the thing that comes after it, it made sense to start with the deck, which is at the bottom and is a dependency for everything else.

Now that the deck is completed, I can build up the next lowest section, which is the Player data structure.

The Player data structure will include logic that is both transient and persistent, which is unique to this structure. The game board is primarily concerned with items that persist from hand to hand, while the hand only cares about what happens during it’s lifecycle. The player has to know both things that are transient during a specific hand and persistent throughout the game.

If I am a player, the things that should know about myself are the following:

  • Amount of money I have
  • Current cards in my hand
  • What cards I have captured
  • Number of times I have chosen to continue the game after satisfying a win scenario

A player needs to have a persistent property that tells them how much money that have at any given point in time. If you run out of money, then you can no longer play. This amount will change at the end of each hand and will be used to determine the winner.

The rest of the things a player needs to know are transient and change after each turn. A player needs to know the current cards in their hand. They need to know what cards they have captured so that a win condition can be determined. A player also needs to know if they have achieved a win scenario but decided to defer the win to try and accumulate more points.

struct Player {
    
    // There are things that are persisted from hand to hand
    var currentMoney:Double
    
    // There are hand-specific properties
    var hand:[Card]
    var capturedCards:[Card]
    var numberOfDeferrals:Int
    
}

At this point in time, I do not think that the Player needs any methods placed upon it. The way I am conceptualizing it, the Player simply needs to encapsulate all of the properties the Player needs to be aware of. These can be changed and referenced based on game specific logic in both the Board and Hand classes.

I will revisit this later after I get the other classes filled out to see if I have made a fundamental mistake on this class.

I also need a way to switch between players. Each game will have three players in it, so I also need to create a data structure to hold all of my players. This seems a good place for an enum:

enum Players {
    case PlayerA
    case PlayerB
    case PlayerC
}

Today was rather busy and so I didn’t work much on this today. The next bit is going to be a lot more complicated. I am percolating on how to approach the next chunk of my programming application.

One exciting development on this project is that I created my prototype project and made my first commit to my private repository for this project. I would like to share as much of my logic on here as possible without just completely open sourcing the application.

Next on the docket is writing the Hand data structure. That is the most complicated part of the application so far, so this may constitute multiple posts as I figure out the best way to approach it. Stay tuned!