Skip to main content

Simple AngularJS app TicTacToe Game

[PLACEHOLDER]


A note from the author
: “After checking AngularJS I said to my colleague let’s blog about it… so here we are”.

This article is based on a simple example that it was quickly done with this MVC library. We started reading the book AngularJS from O’Reilly, by Brad Green & Shyam Seshadri and we wanted to use it right away. We are used to the MVC pattern because of MVC.net, when we saw AngularJS we immediately wanted to try it; also we had some influence from our front-end developers (Just to let you know part of our background is back-end development).

Basically we wanted to focus to the initial part of our study around this book providing examples around simple items. In this case we selected an example that can illustrate data binding, the watch function and CSS classes. We did not wanted to do the “Hello world” example from the book; as always we tried to do something fun, so we thought, let’s do a simple TIC-TAC-TOE game experience, THAT YOU PLAY ON THE SAME DEVICE (the 2 users should share it... yes I little to simple, we know!).

It had to be quick as well, so just a simple example would do the trick. Keep in mind this code can be refactor and make it way much better. There is a potential to use ng-repeat, which we did not include it here. I believe refactoring can reduce the amount of lines of code in our example. This was thought –created-done in less than 2 hours. Writing this article took us longer.

Download it from here: https://github.com/consultingti/simpletictactoe


What you won't find in this article
  • as I mentioned before this is a basic example, no complex work, but rather demonstrating the $watch function. No security discussion, we might work on that later on. But if you are interest and want to read or learn more about sanitizing or how to make your app more secure when using angularjs then this is a good place to start: http://www.youtube.com/watch?v=18ifoT-Id54 . In that youtube video the host is using laravel, which is a php framework, but you can do the same thing by using .Net (which is my preference because of my .Net background) or any other language and framework you feel comfortable.
  • Another good read with good comments and suggestions here: http://blog.brunoscopelliti.com/deal-with-users-authentication-in-an-angularjs-web-app
  • There is no API calls or back-end functionality (data, authorization functionality, etc.). Perhaps in the future if we move to a second version of this example.

For our little experiment we used AngularJS (of course, the star of the article) and also BootStrap as we wanted to play a little more and combined tools. Below you can find a brief definition of both items. After we’ll go into the example:

  1.  AngularJS: open-source javascript framework, maintained by Google that assists with running single-page applications. Its goal is to augment browser-based applications with MVC capability, in an effort to make both development and testing easier. – definition from Wikipedia.
  2.  $watch: this is from AngularJS. It is a $scope function that is called with an expression to observe and a callback that gets invoked whenever that expression changes.
  3. Bootstrap: sleek, intuitive and powerful mobile front-end framework for faster and easier web development. – definition from Bootstrap.

The Example:

It is about a web-base, simple Tic-Tac-Toe game.

Some requirements:

  •       Responsive app, so you can load it in your phone (this is where BootStrap comes into play)
  •       MVC (angularJS role)
  •       2 users: 1 named “X” the other named “O”. The site will make it clear the turn for each user.
  •       Honor the rule of the game:  two players, X and O, who take turns marking the spaces in a 3×3 grid. The player who succeeds in placing three respective marks in a horizontal, vertical, or diagonal row wins the game.

What do you need?

  1. Download Bootstrap from http://getbootstrap.com
  2. Download AngularJS from http://angularjs.org
  3. Some knowledge about HTML, CSS, Javascript. But no expert level is required for this simple example.

Some key part from the code:

  1. The ng-app attribute tells Angularjs which parts of the page it should manage. Since we’ve placed it on the <html> element, we’re telling Angularjs that we want it to manage the whole page.<html lang="en" ng-app>
  2. The bootstrap css was added, along with a custom table.css that I created for the tic-tac-toe html section.
  3. The angular.js.  <script src="./assets/js/angular.js"></script>
  4. The code that makes the little game possible. It may need refactoring and you may even want to put it in a different file and not in the same HTML as I did. As I said this is just a simple example, introduction level.  I’ll describe the code on the next section.
  5. The ng-controller. With it you manage areas of the page with JavaScript classes called controllers. By including a controller in the body tag, you will manage everything inside the <body> area.<body ng-controller="simpleGameController" onload="inigame();" >
  6.  <div id="d11" class="cell"><a  style="color:red" href="/" ng-click="clickrow('d11')" ng-class="{playing: row1[0].played == 'true'}">{{row1[0].title}}</a></div> The ng-click. A call to action to a method of the controller when you click this element.    The ng-class. In this case we have a condition that if an object has a particular value then we’ll add the “playing” class to the element.    {{object}}. To display the value.

Explanation of the Controller code:

  • simpleGameController: is our AngularJS controller receiving the scope object, which refers to the application model.
  • Player variable: to flag if is “X” or “O” that is playing. In our example “X” is the starting user always. As I said it is a simple demo so in this example you don’t get to choose who plays first, in this case the “X” will always play first.
  • There are 3 arrays (row1, row2, row3) for the rows. In each array you have:
    • Title. Initialize with string ”xod”. As the player clicks this value will change either to “X” or “O”, depending on the user.
    • Played. Initialize to “false”. As the player clicks it will change to “true” indicating you cannot click again on that cell.
  • Winner: function that indicates if a user won.
  • Clickrow: it is triggered when you click a cell where the user is playing. It received the parameter rowCoord, which indicates what cell was clicked. It also loads the modal window indicating the turn of the user.
  • Inigame: just called when the page loads to start the game, indicating the first player.
  • $watch: angularjs goodie that we use to observe the player variable. When this variable changes the value the winner function gets trigger to check if there was a winner or not.

The controller code:
<script>
     
     function simpleGameController($scope)
     {
     $scope.test = "1";
     $scope.player="X";
     $scope.win = "";
     $scope.lost="";
   
   
      $scope.row1 =  [{title: 'xod', played: 'false'},
                       {title: 'xod',played: 'false'},
                       {title: 'xod',played: 'false'}];
      $scope.row2 =  [{title: 'xod',played: 'false'},{title: 'xod',played: 'false'},{title: 'xod',played: 'false'}];
      $scope.row3 = [{title: 'xod',played: 'false'},{title: 'xod',played: 'false'},{title: 'xod',played: 'false' }];
                      
          
       $scope.winner = function()
       {
          var a = [
                    [$scope.row1[0].title,$scope.row1[1].title, $scope.row1[2].title],
                    [$scope.row2[0].title,$scope.row2[1].title, $scope.row2[2].title],
                    [$scope.row3[0].title,$scope.row3[1].title, $scope.row3[2].title]
                   
                  ]
          var matches = 1;
          //check the winner by evaluating who hit 3 in a line (vertical, horizontal, diagonal)
          //check horizontal
             //a. checking 1st array
             //b. checking 2nd array
             //c. checking 3rd array
           for (var i=0; i< 3;i++)
           {
             for (var j=0; j<3;j++)
             {
               if ((matches<=2)&& (j>0))
                {
                  if ((a[i][j-1]==a[i][j])&&(a[i][j-1]!="xod"))
                  {
                    matches=matches+1;
                  }
                }
             }
             if (matches<3)
                  matches=1;
             else
                {
                   $scope.test="winner";
                   $scope.lost = $scope.player;
                if ($scope.player=="X")
                     $scope.win = "O";
                     else
                     $scope.win = "X";
                return "winner";                    
                }
           }
            
          //check vertical
          for (var i=0; i< 3;i++)
           {
             for (var j=0; j<3;j++)
             {
               if ((matches<=2)&& (j>0))
                {
                  if ((a[j-1][i]==a[j][i])&&(a[j-1][i]!="xod"))
                  {
                    matches=matches+1;
                  }
                }
             }
             if (matches<3)
                  matches=1;
             else
              {
                $scope.test="winner";
                $scope.lost = $scope.player;
                if ($scope.player=="X")
                     $scope.win = "O";
                     else
                     $scope.win = "X";
               
                return "winner";           
              }
           }
          //check diagonal
          for (var i=0; i< 3;i++)
           {
            // for (var j=0; j<3;j++)
             //{
               if ((matches<=2)&& (i>0))
                {
                  if ((a[i-1][i-1]==a[i][i])&&(a[i-1][i-1]!="xod"))
                  {
                    matches=matches+1;
                  }
                }
             //}
             if (i==2)
             {
             if (matches<3)
                  matches=1;
             else
              {
                $scope.test="winner";
                $scope.lost = $scope.player;
                if ($scope.player=="X")
                     $scope.win = "O";
                     else
                     $scope.win = "X";
                return "winner";           
              }
              }
           }
        if (!($scope.test=="winner"))
        {
         $('#myModal').modal('show');
         }
       }
      
   
       $scope.clickrow = function(rowCoord)
       {
         //$scope.row1[0].title="wao";
         if (($scope.player.length > 0)&& !($scope.test=="winner"))
         {
          
            if (rowCoord.length >0)
            {
                var s = rowCoord.split("");
             
                if (s[1]=="1")
                {
                //row1
                     if ($scope.row1[parseInt(s[2])-1].title=="xod")
                     {
                         $scope.row1[parseInt(s[2])-1].title = $scope.player; 
                         //turn the value visible by chaging the background to white
                         $scope.row1[parseInt(s[2])-1].played="true";
                     }   
                }
                if (s[1]=="2")
                {
                //row2
                 if ($scope.row2[parseInt(s[2])-1].title=="xod")
                     {
                         $scope.row2[parseInt(s[2])-1].title = $scope.player; 
                         //turn the value visible by chaging the background to white
                         $scope.row2[parseInt(s[2])-1].played="true";
                     }   
                }
                if (s[1]=="3")
                {
                //row3
                 if ($scope.row3[parseInt(s[2])-1].title=="xod")
                     {
                         $scope.row3[parseInt(s[2])-1].title = $scope.player; 
                         //turn the value visible by chaging the background to white
                         $scope.row3[parseInt(s[2])-1].played="true";
                     }   
                }
               
                 
                  if ($scope.player=="X")
                     $scope.player="O";
                     else
                     $scope.player="X";
            }
         }
       
       }
      
       $scope.userturn = function(turn)
       {
          if (turn==null)
          {
            
             $('#myModal').modal('show');
             }
       }
      
       $scope.$watch('player',$scope.winner);
     }
   
     function inigame()
     {
     //$scope.player="X";
         $('#myModal').modal('show');
     }
   
      function restart()
       {
         location.reload();
       }
   
    </script>

Trending posts

CRM - Overview Diagram

CRM is an interesting topic. I had the opportunity to work for a company where I participated in a project for the integration of: Microsoft Dynamics GP Microsoft Dynamics CRM Sharepoint (for the intranet)     I’ve also worked in the Digital Agency industry, involved in Web App solutions, where CRM strategies play an important role. For a client (Eg: An online company in retail selling shoes) would be beneficial to find a Shop (Digital Agency) that understands CRM from the strategic point of view and also offers services using software tools that facilitate the finding of insights, track consumer behaviors and helps to provide a personalize experience to the consumer; bringing value to the business. There are CRM solution providers out there that a Shop can partner with. To name a couple: Salesforce SDL There could also be a case where a Shop can create their own custom solution that could have as their center piece a BI system, created as a produc

Gaming trends: What to expect

Gaming continues with an accelerated evolution and significant business growth. The incredible virtual worlds are receiving thousands of real-time players, becoming another avenue for networking, as well as entertainment. This is just impossible to ignore. The gaming industry is one of the most dynamic and innovative sectors, constantly evolving and adapting to new technologies, consumer preferences, and market opportunities. Photo by Mikhail Nilov via Pexels   Newzoo forecast the game market will grow to $217.9 billion in 2023. Newzoo 2020 Global Game Market Cloud and gaming There was a time, not too long ago, when you would buy your games and play them by inserting them into your console or computer. As more gamers demand access to high-quality games on any device, anywhere, anytime, cloud gaming will become a mainstream option for delivering games over the internet. Games are now becoming available via subscription model. An example of this is the Microsoft Xbox game pass and Xbox L

Analytics and Attribution models

The customer journey is packed with multiple touchpoints, making it challenging to determine which of these “moments” (actions taken by the user) have played the most significant role in the conversion of the customer.  Photo by Mikael Blomkvist from Pexels Model attribution provides insights into how users interacts with your web and mobile apps. The decision-makers leverage the insights to understand what marketing efforts are driving “value”, allowing them to focus on the channels that provide the best Return on Investment (ROI).  There are several attribution models that can be used to assign credit. We will go through some of those in this article. Customer Journey - Beolle.com First touch attribution It is an awareness focus, being an introduction to the brand. This model gives the conversion credit to the first point of contact (i.e. a video or a social link).  Last touch attribution It is a model that gives the conversion credit entirely to the final touchpoint from which a lea

Your platform as a positive force in the world

If you are managing a platform, even if it is small, then you are leveraging one of the elements and popular channels used to build digital communities. These platforms, and channels, can come in the shape of websites, blogs, mobile apps, podcasts, vlogs, social media, or a combination of the ones mentioned. Photo by Tatiana Syrikova from Pexels   There are many reasons for building a community, such as sharing knowledge, promoting businesses, branding, the need for engaging with others, etc. However as Spiderman’s Uncle Ben said: “With great power comes great responsibility.” If you like to build better communities with more collaboration and less silos then how would you do it? How can communities come together to drive a “ positive force ”? The current world is mired in conflicts. How long are we willing to go on in such disarray? All the continents are in some kind of “a demonstration of partisanship, intolerance and selfishness”. There are nations in the Americas, Africa, Middl

This blog uses cookies to improve your browsing experience. Simple analytics might be in place for pageviews purposes. They are harmless and never personally identify you.

Agreed