Researching and Setting up the State Machine

At this point I am close to having a working game using local mutiplayer. With that in mind I would like to share what I have accomplished over the past week and a half.

State Machines

Recently my professor, shout out to you Matt you’re awesome, purchased a book for me that I had found online. The Unity 5.x Game AI Programming Cookbook had been a target of interest for a few weeks now, and after seeing a snippet of what the book could provide me, I had to have it. However, I didn’t know just how much information I was going to get out of it.

My initial plan was to use the sixth chapter of the book on Board AI Programming to get me started on my own AI implementation down the road. After finishing chapter six and learning about using decision tree data structures, minmax, and negamax search algorithms, I decided to back track and check out the rest of the book. This was the best decision I have made in a long time as the book had an entire chapter on handling game states.

What was great about this moment was the fact that I was just starting my implementation of my own state machine in my game. Therefore, when I saw this chapter I became beyond ecstatic and dove right in. Immediately my initial design for my state diagram became much smaller.

What once was 7 states or more had now been compacted to the four you see below:

StateDiagram.JPG

My Finished State Machine to Run the Gameplay

What I had learned from reading the chapter was mostly mechanical, how to initialize and use states, as well as creating a template to move from one state to another. The important part here is that each state needed its own file to be accessed depending on the state of the game.

Referencing the diagram above, my game has 4 distinctive states: The Player Turn, Comparison, AI Turn, and Game Over. The diagram does not do any justice of explaining the full purpose of each step, so I will be explaining them in depth.

Player Turn: 

The Player turn state starts off by enabling the ability to move the players card in accordance to which players turn it is. The way the game is set up at this moment always has Player 1 going first. Therefore, player 1 will have the ability to move their cards, but player 2 will not. When the player picks up a card with the mouse, drags it over a spot on the board, and then releases the mouse press that card will be removed from the players hand and placed on that spot on the game board. At this moment the player changes to either player 2 or the AI (which depends on whether the AI is active or not) and the ability of the cards to be dragged is reversed (player 1 no longer has the ability to move their cards but player 2 or the AI gains the ability to).

Comparison:

The comparison state begins by analyzing the last card played to the board to get and store the values of each cardinal power it possess. Afterwards, by using the location of that card that was played, the function will then evaluate all cards around the last card played. If any of the values from the last card played beat a value of a card around it, then that card will become their if and only if it belonged to their opponent. A card that already belongs to a player will not be evaluated in this situation. The game board updates with the new colors to denote which player owns which cards, and the score in the user interface will update in either corner of the screen.

AI Turn:

The AI turn is very similar to the Player Turn state as it will do most of the things that the player state can do, such as disabling dragging for the other player and moving a card to the gameboard from their hand. The difference here lies in the choosing which card to play to which location on the gameboard. This will initially be done using a search algorithm called minmax that is based on the decision to minimize the possible loss for the worst case. In other words, it runs on making the AI get the maximum score by comparing the best and worst case scenarios when selecting a move. Once the AI selects and finishes their move, the game will move back to the Comparison stage and will continue to loop.

Game Over: 

The game over state is the simplest state of the game. The only thing it does is evaluate if the game board is filled with all 9 cards and if the game board isn’t filled, then continue to the appropriate player/AI state. When all 9 cards are on the game board this state will act as the base case for the recursion that I have implemented in these states, giving the game a way to stop. When the base case is met, the user interface will flash one of four messages on the screen: Player 1 Wins!, Player 2 Wins!, AI Wins!, Tie!. Then the game will end and the player will get a prompt if they would like to play again.

Where I am Currently and My Plan To Move Forward

I have finished the Player Turn state and have it working to the point that each player can play a card then have to wait for the other to play a card before they can play another one. Currently I am implementing the comparison function inside of the Comparison state, although this process is not logically difficult, it is very difficult to keep track of all of the variables that I have floating around inside of this process. This is a slow process as I have to constantly stop and test every little detail as I go to make sure nothing breaks along the way.

Once the Comparison state is complete I will be moving on to the Game over state to get a working local multiplayer game. With that state complete I will be able to add the user interface elements such as the score boards in the corners of the screen, and the game will be completely playable. Once I have a playable game, then I will have to implement the AI opponent. I hope to have the initial AI implemented by next Saturday, but who knows what complications I could run into at this point.

Advertisements

Forward March! Entering the Final 6 Weeks.

FINALLY! After somewhere around two weeks of consistent suffering due to the issues I have been having with Unity, I am able to say that I have conquered the beast and I can finally make forward progress.

The issue I was having was related to me trying to make my scripts interact with each other, mainly changing and checking variables in scripts. When done wrong, my code would infinitely error on me, saying that an object was not set to a single instance of a variable. Considering that I was working with two scripts that were each linked to 9 and 5 objects respectively, I figured that the code I used to call the script was not differentiating from the different instances that I had. It was that thought that pushed me to the limit attempting to fix the problem, and in order to explain how I fixed it, I would like to explain a bit about a concept that I learned about in Unity.

Components: In the Unity interface, a user has the ability to create objects of different types, shapes, and sizes. These objects do not have a lot of functionality at their original creation. This gives the developer complete freedom when giving certain objects specific properties. From applying physics to the infinite imagination that comes with the creation of your own scripts, components are the backbone of functionality in the Unity framework. When working with your own scripts, you are able to call upon any of these components that are attached to individual objects.

This is where the coding concepts began to lose me. In order to pull information from an objects component, a developer will need to first locate the object that the component is attached to and save a reference to it locally in that script. Once the object is locally saved, you must then reference the specific component that is holding the information that you need in your current code. After saving a reference to the specific component, all public variables of that component will be accessible in that local version of the script. A variable can dynamically change across scripts. Using this method will allow multiple scripts to make use of the same variable, giving you flexibility when writing new scripts by being able to reuse old methods and variables.

What I learned: In hindsight this concept makes complete sense to me, and it took me a ton of trial and error, countless hours reading materials on Unity, and watching tutorials to understand where the problem lay in my logic. I have lost a lot of ground due to this and I anticipate that my scope will need to be redefined when I have the chance. Although I may have gotten more familiar with the Unity Interface, I still have a long way to go if I am going to have a working game by mid-December. Only six weeks left for me to work on the project, I have to make every second count now!

Update on Progress: Switching Gears to Research

First off I would like to say that I have not had much time to spend working on my projects due to the number of tests and papers that I have had to complete in the past week. However, that is all behind me now and I can start moving forward once again!

I have been attempting to recreate some of my code in this past week, and because of that, I have not actually made much progress with my project. What has happened, however, is that I have begun to understand a bit more about Unity.

As I mentioned in my last post I was having a lot of trouble trying to get cards to “snap” to a location on the gameboard, and that problem still persists to this day. Snapping is name I have given to the action of a card being placed on the gameboard to one of the 9 possible locations. Though I believed to understand how this process would work, I was completely mistaken. Therefore, before I do anything else this week I will be revisiting the books to understand more about Unity, so I can move forward in a more efficient manner rather than continue to make rookie mistakes.

In order to learn more I will be doing some reading from PDF’s that I have received from Packt Publishing. Some months back, there was a deal based on Unity that gave me some awesome titles that have helped tremendously in this attempt to create a game in unity. These titles can be found on Packt’s website and the specific ones I am using are: Unity 5.X Cookbook, and Unity 5.X by Example.

With these resources, as well as looking to online I will be attempting to understand the following aspects of Unity:

  • How to effectively use scripting to make multiple instances of the same objects behave differently
  • How Pre-Fabs work
  • How to use and change variables from one script in another script
  • How objects interact with the game world
  • How to effectively structure scripts and allow them to interact
  • General good practices when using the Unity system

I cannot keep getting held back like this on smaller issues. In order to complete this project in a timely manner, I need to spend some time exploring resources to increase my knowledge base as much as possible. Basically everything about this project is burning around me, and I need to find some way to put it out.

thisisfine

Until next time!

Card Movement: 1 Step Forward and 2 Steps Back

Well the good news is amazing, my initial dive into coding in Unity has proven fruitful! I have been able to click a card on my screen and drag it anywhere around the gameboard! To add to that functionality I was able to make the card remain in its new location when it was dropped, which was a lot simpler than I thought it would originally be.

This simple movement of the cards is handled in Unity by two built in functions in a C# script:

OnMouseDrag () and OnMouseUpAsButton()

These two functions sense when the mouse has been clicked down on the card and when the card has been released respectively. Focusing on OnMouseDrag, I run two lines of code to make sure that the card object stays with the mouse so long as the player keeps the mouse pressed while dragging it across the screen. The first line is used to grab the coordinates of the mouse as a reference, and the second line takes the mouse coordinates and changes the cards coordinates to match the cards every single frame. These two lines are shown below:


Vector 3 WhereIsMouse = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, distanceFromCamera);

Vector3 objectPosition = Camera.main.ScreenToWorldPoint(WhereIsMouse);


The coordinate values in unity are handled on a 3D plane, with x, y, and z axes. The unity system handles these coordinates using the Vector3 data type, which holds each of these axes as a value in a 3 element list, (x, y, z). By using two of these Vector3 objects I am able to both track where the mouse is in comparison to the camera, and change the coordinates of the object being dragged.

This is my one step forward, and as I promised in the title, I have had some problems that have set me back.


As long as something works, something else has to break. I was ecstatic when I was able to get the card movement to work, so with adrenaline coursing through my veins, I set off to achieve bigger and better things. I Thought “The card moves, now its time to make it snap to a location on the board!” This went well at first, as I was able to use another built in function in unity to detect the collision of a card above a board location (there will be more on that function in my next post). However, when I attempted to make this code work for all 9 board locations, instead of just one, I ran into a multitude of complications.

Everything from the dragging suddenly not working, to the cards in my game bugging out and flying off into space began to happen to my program. Most of these issues I couldn’t explain or even reproduce for others to help me with. So here I am, staring at a bunch of broken code with one thought in mind, “I have to restart”. I have taken this initial dive, and learned a lot in the process. Now its time to put that knowledge to the test, go a little behind schedule, and reproduce a better set of scripts that better suit my needs. Next goal on my list, get all five cards to snap to different locations on the board without my code breaking!


Next time I will be exploring more in depth what I mean by cards “snapping” to the board, as well as showing snippets of my code to explain where I went wrong in my previous iteration. Until next time.

 

Well, this is Awkward: Past Mistakes and Plans to Move Forward

It is with a heavy heart that I admit to a recent fault of mine. As of today it has been 22 days since my last post on this blog. For a project that requires constant documentation, this is really, really, bad. Many aspects of my personal and academic life have been getting in the way, and to be completely honest, I had completely forgotten to write any posts during this time. That is in the past! I have now set up reminders, on everything that I can to make sure that I write posts regarding the material that I work on! With no more excuses on missing blog posts, I will be planning on sending in at least 2 posts per week that will keep up with the topic that I am working on for that week.


Now that I’ve gotten that off my chest, its time to get right back into business! I have recently created a rough design document that serves as an overview of the project. Inside of this document I explain my purpose of choosing this project, what I expect to learn from it, a rough schedule of how I will be working on the project for the remainder of the semester, and the plans I have for the data models I will be following during the implementation! The best part of this document, however, is that it was completely coded in LaTeX. LaTeX has given me the creative freedom that Microsoft Word just couldn’t give me. I am able to tell the paper to do exactly what I want it to do, format it any way I like, and create these documents all for the low price of FREE. LaTeX aside, my design document is linked below for those who would like to take a look at it. This document is very rough, and shall be expanded on continually in the future. You can read my design document here, and if you have any feedback please let me know!

 

Digging Deeper: The Data Behind the Scene

TL;DR = Thinking on a much simpler level, I have decided to make use of lists to store my data rather than going over the top with databases, matrices, and dictionaries.


Over the past week I have been creating presentations that have been given to a small group of my peers in order to receive feedback on my Triple Triad project. The comments from the presentations, as well as other conversations with peers and professors alike, have opened my mind to a new way that I could approach creating my project. In other words, I have been overthinking how I would implement the program with the use of the Unity system, and I have decided to take a step back to focus on simplicity rather than complexity.

This affects my project in many ways. First, focusing on a simpler approach allows me to implement my game board using a 9 element list rather than using a 3 element list, where each element of that list is a 3 element list ( a list of lists or a 3×3 matrix). Using the 9 element list allows for a speed boost in search time when trying to keep track of what cards are on the game board as I will only have to search through 9 elements at most. Applying more layers, such as a list of lists, adds more time to the search since it has to go through multiple layers to get to the data that I need. However, even though speeding up the program is nice, the best part about having the simpler approach is that it allows for a simpler implementation of the game. Since there are distinct boundaries on my small 9 slot game board, I do not need to fear hard coding the transitions and comparisons since the game is so small. If the game were much larger, with more possibilities, then hard coding would eventually get out of hand and many algorithms would need to be put in place to handle the sheer amount of possibilities.

Second, the card objects themselves can have their values stored in lists to be applied later. In this case I will be using a 6 element list that will hold the following values for each card: Card Name, North Value, South Value, East Value, West Value, and Ownership Value. The card name will be a string variable that will be used as an identifier when moving the card object around the game screen (from the hand to the board). Each of the Cardinal Values will be integers between 1 and 9, and will denote that cards power in that cardinal direction. The ownership variable will be a string that will denote which player is currently in ownership of the card (ex. the string “player 1” will mean that player 1 owns the card, while “player 2” means player 2 owns the card).

This is only the start of a much more overarching data model. This surprises me to no end that I can theoretically complete this project using such simple data structures and hard coding most of the relationships. At this point, I have to say that I am ecstatic to begin work on this project… after a lot more planning!

The Reaping: Choosing my Favorite Project

In my  previous post I outlined three projects that I could possibly complete for my Senior Project this semester. Of those three projects, I have now honed in on the one I feel the most attached to: the Triple Triad remake.

Before I move further with the implementation of the program, I will be exploring the topic further and expanding on my previous post.

As a reminder, I will be using the Unity Game Creation Engine to create this project, as it gives me the full freedom of creating my own assets from scratch, and the writing of my own code to support the project.

To make this project much more manageable, I am going to split it into three main phases, or milestones: Object and UI Creation, Coding Gameplay, and AI creation/ Final Debugging. These three steps do not need to be completed in any specific order, but each of them is required for a complete working game that can mimic its predecessor.

Object and UI Creation

The first part of this project will revolve around me creating all the assets that I will need for the program. This step includes the creation of the game board, the playable card objects, and the user interface (UI).

When making the game board I will be expecting to make use of a matrix to keep track of each of the playable locations in the game. In this case I will be using a 3 by 3 matrix that will contain the XYZ coordinate values of an object that will reside within each element of the matrix. These objects will be used to track the availability of that specific location, and will also compare the values of the card taking residence in that space (if any) to the other cards cardinally surrounding it.

The playable card objects will be created to be held in a hand of five cards by the player, and will be visible to the player at all times during the game. What makes these objects special is that they will have 4 cardinal values (1 for each direction) that will define their “power” in that specific direction. When a player plays a card that has more power than an opposing card in any direction, then those opposing cards will fall into the current players control.

Finally the user interface of the program will have a few elements to it, but I would like to keep it as minimal as possible due to the nature of the project. This part of the creation process includes the addition of counters that will keep track of how many cards each player owns on the game board, a cursor to allow the player characters to select which card to play and where to play it, and an opening menu so the player can choose whether they would like to play against an AI opponent or a friend.

The amount of time that I estimate this section of the project taking is a total of 3-4 weeks.

Coding Gameplay

In this section of the project I will be hammering out exactly what players can do during their turn, what happens when they play cards on their turn, and will keep track of which cards belong to which player on the game board.

The player turn consists of two separate actions. First the player must choose a card from their hand, and second the player will place that card on one of the nine possible spots on the game board. Once the player has completed these two actions, their turn will immediately end, and the same process will be mirrored for the second player. When both players have completed their respective turns, a round will have passed and the turn order resets to the first player.

When a card is played from a players hand onto the game board, a series of comparison functions will be activated to see if the player wins any cards. These comparison functions are simply comparing each of the possible cards opposing cardinal values, and if the card currently being played has a higher value than any of the opposing values they will win those cards.

Once during each players turn, a function will access the current state of card ownership on the game board. In other words, the function will analyze how many cards each player owns and send that data to the UI to be displayed to the player(s).

I expect this section of the project to take some time, and I am uncertain how long it will exactly take. Just to give it a number, I can estimate this section to take anywhere from 5-6 weeks.

AI Creation / Final Debugging

This is the portion of the project that will be the most difficult for me to complete. I have no prior knowledge in creating AI for gaming programs such as this. However, after doing some research into two similar projects, I am sure that creating a complex AI for the player to play against will be possible.

The first of these two projects is from GitHub user Mnylen who based his Triple Triad recreation project on the negamax algorithm. I have never encountered this algorithm before so I decided to look it up on StackOverflow. If I implemented this algorithm I would be using a tree data structure in order to explore all possible moves on the game board given the cards in the AI’s hand. After exploring all possible moves, the AI will determine the “best” move and execute it. I do see one problem with this though, if the AI will always make the best move, then can the player ever win? If I were to base my program on the negamax algorithm I will have to create exceptions to the base algorithm in order to give the player a chance at winning.

The second project I found is from Visadb’s GitHub repository in which he created a bot to play triple triad for the player that would never lose, given that the chance to win was inherently possible. What I like about the algorithm that Visadb uses, is that he created it to be used only in this special circumstance of playing triple triad. It helps boost my confidence in the fact that if I needed to I could create my own algorithm to suit my programs needs. I don’t want to make the game impossible for the player to win, but rather give them a chance to outwit a very crafty AI system.

In addition to coding an AI for my game, I will also be using the remainder of the approximately 6-7 weeks left in my project to complete any final debugging and add any special flare that I would like to the program before calling it “finished”.

Final Thoughts

The more time I put into planning this project, the more I find possibly hang ups and roadblocks. To be completely honest, I am unsure as to how the AI system is going to work for me, if it will work at all. However, if half of a week of research can ease my thoughts on most of this process, then I am sure that as soon as I hit that roadblock I will find a way through it. I cannot wait to get started coding, the more I think about it the more excited I get.

Sources

https://github.com/mnylen/triple-triad

http://stackoverflow.com/questions/14787857/how-to-use-negamax-algorithm

https://github.com/visadb/ff8_tthelper