Work life balance – the option for employees to be productive in work and flexible in attendance

Please follow and like us:

The world is obsessed with productivity. Everybody wants to know how we can get work done quickly with minimum effort, so we can lead a fulfilling life.

There are a huge number of apps that claim to increase productivity, but research suggests something that cannot be obtained from these apps – physical vitality.

The practice of work flexibility is in sharp contrast to the traditional approach where there is a defined set of work hours for everyone.

But the most important thing to keep in mind while implementing the flexible approach in any organisation is, to very closely assess the mutual benefits to both the employees and the organisation, otherwise it may lead to chaos and failure.

A recent study reported in the International Journal of Workplace Health says that, other than a good night sleep, exercise is the most effective productivity tool at our disposal. This report also mentions that people who exercised during the day time were 22% more productive.

Restore and Energize

It is a well known fact that the quality of work hours is more important than the quantity. Research shows that exercise build new connections among neurons of the brain that helps increase attention and focus.

Just like our smartphones, we need to recharge our batteries. This can be done through exercise, rest, play, pursuing your hobbies & passion that restores and energizes us.

As the old saying goes about the carpenter who didn’t have the time to stop and sharpen his axe ended up doing the work slower than his partner who was smart enough to take time off and sharpen his tool. This enabled him to do his work faster and more effectively.

How to Implement Work Flexibility Without Compromising on Productivity

Work flexibility does not mean coming and going as you please. It is a well-structured well planned framework . It needs to be well aligned with the values and mission of the organisation . The employees need to be tuned in and proper training provided. The first step is to choose the appropriate flexible work management based on the needs and requirements of both the organisation and the employees.

Compressed Work Week

Compressed work week involves working the same number of hours in a week but in fewer days. Most of the organizations have five working days with eight hours working each day. Under the compressed workweek schedule, the employees could choose to work ten hours everyday for four days and take the extra day off.

FlexTime

This gives the employees complete right to choose where to work and how many hours to work. Most organizations who follow this, have set some core working hours that they expect the employees to work . They have a good system in place to track remote working, through IP based attendance that helps to maintain great culture that fosters productivity while encouraging flexibility.

Customise to Meet Your Needs

Before implementing the flexible work hours structure, talk to your team. Ask for their inputs and analyse their needs. When this is done along with the decision making process, the flexible time management can be made a success. The employees get to enjoy the benefits that come along with this while the productivity and work quality still remains the best.

Tips for the Team to Attain Work Life Balance

Set Clear Cut Goals

This will allow us to be more focused and productive at work. Know exactly the work that needs to be completed and the timeline for the completion.

Take Ownership For Your Work

For some, total autonomy can lead to sloppy work as they are used to someone supervising them all the time. Be accountable and responsible towards your work.

Respect boundaries

Separate your work life from your personal life. Never discuss work related stuff at home and vice-versa.

Plan your day

Always have a to do list with you. Plan the day the night before and set priorities.

Vacations with family

Plan vacations with family. Spending quality time with family and friends will get you re-energized and come back to office with new zeal and enthusiasm.

Anger and stress

Anger and stress are hazardous to performance. As much as possible to achieve efficiency at work, we need to work on our emotional intelligence. Positive emotions build interest and energize. Negative emotions restrict thinking. A person with a positive outlook are more satisfied with work and this in turn increases productivity.

An alarming report from a research conducted in 2018, states that people spend an average of 2.8 hours only on productive tasks per day. The rest of the day is spent on neutral activities and distracting activities!

It also states that only 70% of the work gets done in the normal working hours.

Biggest Threats to Work Life Balance

Workplace distractions, wasting time and simply being inefficient are all eating into your work life balance. The biggest offender to maintaining a good work life balance is found to be  the habit of Checking e-mail and IM frequently. Most people are spending quality office time on checking email and other communications tool. 21% of our working hours is spent on our devices for entertainment, news and social media.

Our Ultimate Goal

The line between work and all other things in life is becoming increasingly blurred. We have less time than we usually think, and we end up working later in the evenings and on weekends just to catch up. The more we are able to set the boundaries on our workdays and counteract the distractions, multitasking and communication overload that take away our precious productive time, the more we can stay healthier, happier and find a balance.

Life @ PQube

At PQube, we understand the significance of maintaining a work-life balance. It all starts with setting up the ground rules first viz communication and proper training. We utilize a task management software, that helps us to be accountable and encourages work-life balance. Our performance oriented work culture allows our team to spend time on their personal pursuits while still engaging in meaningful work. To accomplish this everyone in the team is aware of their goals and what is expected from them, at the same time they are accountable for those outcomes.

JavaScript vs jQuery for DOM Manipulation

Please follow and like us:

jQuery has been the savior for so many new and coming Web Developers, including myself. If you wanted to learn Web Development back in the day, learning jQuery was an absolute given. This was mainly because jQuery took much of the cross-browser compatibility issues out and enabled developers to write code without having to worry about whether the features that they are implementing will work on all browsers.

But with improvements in browser standards and most of jQuery’s API’s integrated into JavaScript, jQuery has become a little redundant. Moreover, with native browser API’s it is so much easier to debug code, and being native, most of these API’s offer better performance than jQuery’s API’s. Besides, you will have one less library to add to your script imports. If you’re still not sold on parting with jQuery maybe this answer will help.

So, if you’re considering a move away from jQuery, I have compiled a list of common jQuery methods and API’s that people use, with their Vanilla JS alternatives (Vanilla JS is a fancy name for plain JavaScript code without the use of any libraries). Let’s dive in!

Querying the DOM

The bread and butter of jQuery is it’s amazing ability to query DOM elements. This is demonstrated below:

jQuery('div.home')

However, you can achieve the same thing with JavaScript using it document.querySelector() and document.querySelectorAll() methods. Below is their implementation.

document.querySelector('div.home')

This method always returns the first element that matches the selector. If you’re expecting to query multiple elements, you will have to use the querySelectorAll() method.

document.querySelectorAll('img').forEach((_el, index) => {
      //do stuff with _el here
})

querySelectoryAll() will return an array of matched elements, hence the use of forEach to iterate over each element.

.()html

.html() method of jQuery is used to get or set the HTML content of  a node/element.

To do the same in JavaScript you can use the .innerHtml property of any HTML element.

Let’s say you need to get the HTML content of a div element with class main-div. You could do this in JavaScript like this.

var htmlContent = document.querySelector('.main-div').innerHtml;

Similarly to set the HTML content of the same div, you could do something like this:

document.querySelector('.main-div').innerHtml = '<p>Hello World</p>';

Remember, if you want to change the Html of multiple elements with the same selector, you can use the querySelectorAll() method like this:

document.querySelectorAll('.main-div').forEach((el, index) => {
    _el.innerHtml = '<p>Hello World</p>';
});

Notice that I pass in the index to the anonymous function here. You don’t really need it in this case, but it’s a good practice to keep the index of each element of the array handy. You never know when you may need it.


.val()

.val() method of jQuery is used to get or set the value of an input element.

To get or set the value of an input element in JavaScript, you can use the value property of that element. 

To set the value of an input element with class input-box to ‘new’

document.querySelector('.input-box').value = 'new';

To get the value of the same element

var inputValue = document.querySelector('.input-box').value;

.text()

jQuery offers .text() method to get all the content of an element without the markup. e.g., using jQuery to get the text of <p>Hi</p> element will return the string ‘Hi’. This can be very useful when you’re trying to get the content actually visible in the web-page.

That being said, every HTML element has a property “innerText” that essentially holds the same value. 

let textValue = document.querySelector('.main-div').innerText;

Styling the DOM

One of the most exciting features of jQuery is the ability to modify the styling of our DOM. This is highly useful when you’re trying to have a visual feedback to a user interaction.

Modifying styles can be done by one of two ways:

  1. Adding/Removing Classes:
    To add or remove a class you will most definitely use .addClass() or .removeClass() methods that ship with jQuery.
    To do the same thing in JavaScript, you can use the classList property of an element. This can be done as shown below.
    To add the class testClass to an element with Id testElement

    document.querySelector('#testElement').classList.add('testClass');

    To remove the class testClass from the element with Id testElement

    document.querySelector('#testElement').classList.remove('testClass');

     
  2. Adding/Modifying CSS:
    To directly change the CSS of an element we use the .css() method provided by jQuery. Once again, this is fairly simple to do in JavaScript.
    To set a style for an element, we simply set the value of that style as exposed by the style property of that element.

    document.querySelector('#testElement').style.color = '#ffffff';

    This will set the color of the element with Id testElement to white.
    Note: Since the styles of element are exposed as JavaScript object properties, you won’t be able to use properties such as background-color directly as there is a “-” in the property name. In these situations, you should simply use the camelCased version of these properties. e.g.,

    document.querySelector('#testElement').style.backgroundColor = '#000000';

    This will set the background-color of element with Id testElement to black.

.attr()

Setting and retrieving values of the attributes of HTML elements is once again very useful when developing a web application. You may need to get the value of a data- attribute that is storing important data while working with your application. jQuery provides this ability by exposing .attr() method. You can use it with one parameter to get the value of an attribute or use an overload with two parameters to set the value of an HTML attribute. 

In JavaScript every attribute of an HTML element is exposed as a property of that element. This means that to set the value of the src attribute of an img element, you can simply do the following:

document.querySelector('img').src = '/images/image.png';

It’s that simple. For attributes such as data- you can use another approach,

document.querySelector('img').setAttribute('data-title', 'test');

To get the value of the same element,

document.querySelector('img').getAttribute('data-title');

The getAttribute() and setAttribute() bear a striking resemblance to jQuery’s attr() method. So, getting used to these shouldn’t be that difficult.

.show() / .hide()

Once again, two of the most widely used jQuery methods are the .show() and .hide() methods. These methods do exactly what they say they do, hide or show HTML elements. In their essence, these methods are simply modifying the display style property of elements. So, we can use simple style modification to achieve the same thing.

To hide an element:

document.querySelector('.test-element').style.display = 'none';

To show a hidden element

document.querySelector('.test-element').style.display = 'block';

AJAX

One of my favorite and most used jQuery functionality is sending HTTP requests using AJAX. However, we have to understand that jQuery.ajax() is a wrapper around existing JavaScript functionality. There is no doubt that jQuery makes using AJAX a breeze, but it’s not why we’re here, is it?

To send a POST request to the URL ‘home/sendmessage’ with the data {id: 23, name: ‘faisal’}, we’d do the following:

let request = new XMLHttpRequest();

// Set a event handler when the status of the request changes
request.onreadystatechange = function(response) {
    if (request.readystate == 4 && request.status == 200) {
        // do stuff with the response object
    }
}

// Open a Post request to the url home/sendmessage asynchronously.
request.open('POST', 'home/sendmessage', true);

// Set the request header/s
request..setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

//Send parameterized data as part of the Post request
request.send('id=23&name=faisal');

That’s it. You post request will be sent to the server.

If you’re a jQuery developer, you will know that these aren’t all the methods and features that jQuery ships with. There are definitely more, but I’ve simply tried to address the most common ones just to give you an idea that life without jQuery in the browser is possible.

I hope that it’s enough to push you towards using more and more JavaScript.

Why Do You Need to Automate Your Hiring Process in 2019?

Please follow and like us:

Managing recruitment and selection process is one of the most critical, time consuming tasks. It is essential for any organization to recruit well qualified and suitable employees. As a growing company, you need the right tools to manage your hiring process. A significant amount of time and resource can be taken up with the hiring process unless you automate.

According to LinkedIn, the most important recruiting KPIs are:

* Quality of hire

* Time to hire

Experts believe that by streamlining some aspects of the recruiting process, recruitment automation will enhance a human recruiter’s capabilities.

Here are some major ways recruitment automation is changing recruiting

  • Assess them Before You Interview Them

You could assess or gauge prioritization abilities, IQ and other relevant qualities even before the aspiring candidates step into your office. A vast majority of talent acquisition leaders say the hardest part of recruitment is identifying the right candidates from a large pool of applicants. The system assesses prospective candidates by surfacing key data points that cannot be found on resumes. It can be used to track the candidates’ career highlights, likelihood of switching jobs, company fit and aptitude.

  • Ensure Consistency in Hiring Process

The recruitment process involves a number of steps and when done manually there are huge mistakes created due to human error. The entire process can be streamlined and automated.

  • Free Yourself for More Productive Tasks

Free yourself or your team from mundane tasks that can be automated and utilize the same resources for other productive tasks, thus increasing efficiency and productivity.

  • Automate Screening Questions

Filter through hundreds of applicants and end up with only those candidates who are apt for your organizations vision and values, in the process helping you weed out the candidates who do not meet your requirements. Just imagine the number of hours you would have otherwise spent interviewing these candidates, setting up infrastructure for assessment tests and multiple rounds of interviews. Evaluating Common Sense, Emotional Intelligence, Communication, Fluency and many important KPI’s are key to “Quality of Hire” while screening for prospective team members, and this can be fully automated with industry standard baselines.  

  • Keep Candidates Informed via Automated Emails

Recruiters waste a lot of time responding to calls/emails from candidates they have interviewed. Use automated emails to let them know the status of their application.

  • Automate the Offer Process

The system can generate automatic offer letters, contracts and other documents along with rejection letters based on customizable workflows tailored to each organization’s recruiting standards.

  • Automate Employee Onboarding

Aspiring applicants have already gone through the process of application and filling in details and majority of the organizations have to go through the same basic information to be filled in again with the employees who join. By connecting the Recruiting Platform with Company Portal systems, a vast majority of the data can be copied over and will assist in speeding up the on boarding process from Day One. There are some MNC’s who have even adopted completing paperwork via digital transformations even before the employee show up on Day One. Automation can help with a number of activities such as setting up IT access, notifying Product/Project stakeholders, operations workflow for new joiners and so on.

  • Screening resumes: Automate score | rating

Industry experts consider screening resumes is still the most   time consuming part of recruiting. Upto, 88% of resumes received for a role are considered unqualified. On an average, a recruiter spends 23 hours screening resumes for a single hire. Through the hiring automation platform, the score/ rating is allocated to the candidates based on the inputs they provide. They are assessed on several levels such as aptitude, technical skills and other relevant skills. A filter incorporated in the system helps to select only relevant skill assessment categories for a particular role.

  •  Helps in having a pipeline of Talent

Using the hiring automation platform helps in creating a database of the qualified candidates you were not able to hire, but is suitable for another role, down the road.

Looking Ahead…

In 2019, finding top talent will depend on the recruiters’ ability to intelligently automate their work flow.

It is imperative to ensure that the recruitment process is conducted in a smooth and consistent manner so as to ensure that we hire the best talent in the market. Just as salespeople and marketers have benefited from software enabled automation in recent years, recruiters are increasingly turning to automated platforms for hiring the best talents

Armed with cutting edge tools and insights, recruiters can refine the process, eliminate inefficiencies, mitigate biases and get across to the top talent in minimum time. According to a survey conducted, 75% of recruiters say technology will play a big role in their company hiring process in 2019.

 Majority of recruiters worldwide are happy to consider a more data driven approach, most of them do not have time to turn the data to actionable insights. It is found that data driven recruiting teams are far outperforming their peers. Leveraging these insights, to optimise the recruiting strategy, increases the team productivity and gives the organisation a competitive advantage. Intelligent and smart way of recruiting through hiring automation helps to analyse candidates’ data quickly and make decisions faster. It helps to ensure that all the best fit candidates were identified and engaged, resulting in better quality hires and a higher performing organisation

Adopting automation platforms is helping recruiters screen candidates and shortlist quality applicants in record time.

Research also suggests that most companies depend on employee referrals for some important roles to avoid hiring misfits. This could negatively impact their ability to attract the best talent. Utilising automation, increases efficiency, offloads tedious mundane and repetitive tasks. As a result of this, it helps in reducing time-to-fill and cost-per-hire.

PQube has been in the forefront to address these pain points of sourcing and recruiting process. Get yourself a top notch, best in class, custom made hiring automation platform and some peace of mind. Through our end-to- end automation platform, you can speed up candidate discovery and qualification processes and float best-fit candidates to the top of your talent pipeline. Work Smarter, Not harder!

Technology is not a tool. It can give learners a voice that they might not have had before George Couros

How to Write an Unbeatable Tic-Tac-Toe in JavaScript

Please follow and like us:

Writing small puzzle games is a nice way of improving your programming skills as those games tend to present you with challenge after challenge and force you to really put tremendous thought into writing your code. 

One such game is the classic Tic-Tac-Toe.

In this little walk-through (read long and descriptive) about writing an unbeatable tic-tac-toe, I will be using Vanilla JavaScript for logic and HTML/CSS for UI. I won’t be concentrating much on UI part of it, because, duh! 

Another little disclaimer – we will be concentrating on logic primarily and code will come second to that. Again, if you want to skip the “walk-through” and jump right to the code, I have a public repository on GitHub at https://github.com/FaisalST32/tic-tac-toe. I also have a live version of the game available at https://games.faisalrashid.online/tictactoe/

So, let’s dive in.

First of all you need to create the UI. Just use simple HTML to create 9 input boxes, or divs even to hold your X’s and O’s. The id’s of these input boxes are important as they will be our reference to the X’s and O’s. To keep it consistent with the positioning of our boxes, I have given the input boxes the id’s “0-0” to “2-2”. To visualize: 

0-00-10-2
1-01-11-2
2-02-12-2


This will give us an easy to use 3×3 matrix. You can design your UI whatever way you want. It should simply employ this form of queryable HTML elements. 

Here’s a screenshot of my UI. Simple boxes with a little gloss of CSS.

Now, the logic! First of all, whenever a user, or a participant in this case, clicks or taps an empty box, the value of that box should change to either an X or an O, depending upon whose turn it is.


Implementing that is simple. I use a global variable to hold the ‘currentPlayer‘. This variable has a value of either X or O. Then I simply write a method to toggle current player, whenever a box is tapped. I call the method changePlayer.

All this is started by tapping a box. So, we need a function to get us started. We write a function that marks the box with X or O and changes player. We call the function onCheckBox. So far, the function checks a box and and then changes player.

Now, while the boxes are being tapped, we need to keep track of the checked boxes. Using an array should help us get this job done. Simply holding the id’s of all the boxes is useful, but it’s not enough. We will definitely need to hold the id’s (co-ordinates in this case) as well as the player who checked the box. So, our checkedBoxes array will be an array of objects of this form:

[{box: ‘0-1’, player: ‘X’}, {box: ‘2-1’, player: ‘O’}, …]


We now have two global variables – one to hold currentPlayer and other to hold checkedBoxes.

Another thing that I like to keep track of is the Turn Count. I can get that from the chekedBoxes array, but this way it’s simpler and very useful if I’m manipulating the checkedBoxes array.

Since we will be writing a Player vs CPU mode only (github repo contains both 1p and 2p modes), these are all the global variables that we are going to need – checkedBoxescurrentPlayer and turnCount.

NOTE: It’s always good practice to keep your global variables at a minimum to avoid dependencies and unexpected behavior within functions.

I believe our onCheckBox method is now ready. This is what it looks like

function onCheckBox(element) {
   checkedBoxes.push({ box: element.id, player: currentPlayer });
   checkElement(element);
   turnCount++;
   var   gameStatus =checkWinner();   //Will come to this method in a bit
    switchPlayer();
}function checkElement(element){
     element.value = currentPlayer;     
     element.disabled ="disabled";
}function switchPlayer() {
    currentPlayer = currentPlayer =="X"?"O":"X";
    document.querySelector('.current-player').textContent = currentPlayer;
}

We are passing the clicked Html element as one of the parameters to the method to access it’s id for coordinates. Everytime we check a box we need to check whether there is a winner or whether the game is drawn.

This brings us to our the checkWinner method. This method simply checks whether the X’s or O’s are in a single line (rules of tic-tac-toe) to determine whether there is a winner. It’s not very difficult to build that logic. We query the checkedBoxes array and find all the coordinates with player X. If the coordinates follow the pattern (a-0, a-1, a-2) or (0-a, 1-a, 2-a) where a = 0 or 1 or 2, then we have a horizontal or vertical line checked. Well, diagonal lines are a little tricky. For right to left diagonal, we use (a-a, b-b, c-c) and for left to right diagonal we use (0-2, 1-1, 2-0). If we find any of these patterns in the checkedBox matrix then the ‘player’ having the pattern is the winner. If none of these patterns match, then we simply check whether one of the two players has checked 5 boxes to determine that it’s a draw. 

function checkWinner(isCheckOnly=false) {
if (currentPlayer =="X") {
//Get all the boxes marked by Player X
   var  xs = checkedBoxes.filter(item=> item.player =="X").map(value=> {
     return { x: Number(value.box.split("-")[0]), y: Number(value.box.split("-")[1]) }
});
returncalculateScore(xs);
}
else if (currentPlayer =="O") {
//Get all the boxes marked by Player O
   var  os = checkedBoxes.filter(item=> item.player =="O").map(value=> {
     return { x: Number(value.box.split("-")[0]), y: Number(value.box.split("-")[1]) }
});
returncalculateScore(os);
}
}function calculateScore(positions) {
//Check right diagonalif (positions.filter(i=> { return i.x == i.y }).length ==3) {
              return'game over';
}//Check Left diagonal
if (positions.filter(i=> { return (i.x ==0&& i.y ==2) 
                                    || (i.x ==1&& i.y ==1)
                                    || (i.x ==2&& i.y ==0) }).length ==3) {
                return'game over';
}
//check horizontal match
for (var i =0; i <3; i++) {
  var  consecutiveHorizontal = positions.filter(p=> p.x == i);
  if (consecutiveHorizontal.length ==3) {
       return'game over';
}
//check vertical match
  var  consecutiveVertical = positions.filter(p=> p.y == i);
  if (consecutiveVertical.length ==3) {
        return'game over';
}
}
//check draw
if (positions.length ==5) {
  return'game drawn';
}
//if none of the conditions match 'game on'
return'game on';
}

Here I’m delegating the responsibility of finding result to calculateScore method. These two methods are essentially translating what we said above to JavaScript code. Nothing fancy here.

Let’s try something now. Shall we? I believe our game is now ready to handle all the tic-tac-toe logic. What remains is making it unbeatable. To make the game unbeatable, I want to set some ground rules to avoid making this post excruciatingly long (you’re kidding, right). The CPU will always play second and will be primarily focused on not letting the opponent win. So, our onCheckBoxmethod will see the addition of the method computerPlays for CPU’s turn. 

function onCheckBox(element) {
checkedBoxes.push({ box: element.id, player:
    currentPlayer });
  checkElement(element);
turnCount++;
  var
     gameStatus = checkWinner();
  switchPlayer();
  if (turnCount %2 == 1&&
    gameStatus == 'game on'){
    computerPlays();
}
}

As you can see the computerPlays method will only be called if the turnCount is odd, ie, it’s 2nd, 4th, 6th or 8th turn, and if gameStatus returned by the checkWinner method is ‘game on’ as there is no point in continuing the game, if the game is already over. To understand how to counter a human move, I came up with 5 cases. These five cases in the order of their priority are: 

  1. First Move
  2. Finishing Move that allows CPU to win the game.
  3. Saving Move that allows CPU to save the game.
  4. Predicting a move that will trap the CPU and avoiding it.
  5. And if none of these fit, a Random move.

Here’s a sneak preview of our computerPlays method.

function computerPlays() {
  var  nextBoxCoords;
  if(turnCount ==1){
nextBoxCoords =computeFirstMove();
}
  if (!nextBoxCoords){
nextBoxCoords =computeFinishingMove();
}  if (!nextBoxCoords) {
nextBoxCoords =computeSavingMove();
}
  if (!nextBoxCoords)
nextBoxCoords =predictTrappingMove();
  if (!nextBoxCoords) {
nextBoxCoords =computeRandomMove();
}
  var  nextBox = document.querySelector(`[id='${nextBoxCoords}']`);
  onCheckBox(nextBox);
}

1. First Move

Computing first move is out of experience, although, I could have written an algorithm for it. But to avoid complexity, I just went with past experience. If it’s CPU’s first move, we need to find where the opponent played. If it’s center box, we return a corner box. Similarly, if he played a corner box, we return an edge box adjacent to it and finally if he played an edge box, we return the center box. By the way, 1-1 is the center box, 0-1, 1-0, 1-2, 2-1 are the edge boxes and, you guessed it, 0-0, 0-2, 2-0, 2-2 are the corner boxes.

Here it is,

function computeFirstMove(){
  var  playedMove = checkedBoxes.map(b=> b.box)[0];
  var  edgeMoves = ['0-1', '1-0', '1-2', '2-1'];
  var  cornerMoves = ['0-0', '0-2', '2-0', '2-2'];
  var  centerMove = ['1-1'];
  if(edgeMoves.find(m=> m == playedMove))
    returnedgeMoveResponse(playedMove);
  else if(cornerMoves.find(m=> m == playedMove))
    return'1-1';
  else if(centerMove.find(m=> m == playedMove))
    return cornerMoves[Math.floor(Math.random()*cornerMoves.length)];
}function edgeMoveResponse(playedMove){
  if(playedMove =='1-2') 
    return'0-2';
  else if (playedMove =="0-1") 
    return"0-0";
  else if (playedMove =="1-0") 
   return"2-0";
  else if(playedMove =='2-1') 
    return'2-0';
}

To avoid cramming up the computeFirstMove method, I moved out the edgeMoveResponse method. Now, that we got the first move sorted, let’s move to the next check – computeFinishingMove

2. Finishing Move that allows CPU to win the game.

If the opponent is there for the taking we would prioritize taking him. Let’s say we have the following situation: 

Since, it’s CPU’s turn (O) we would definitely want to check the lower-right box. That’s where our computeFinishingMove method comes in. It simply iterates over all the remaining boxes and checks them one by one. It then calls the checkWinner method on each iteration and if there’s a winner, just returns the box of that iteration as the ‘nextBoxCoords‘ to the computerPlays method. Here’s the code: 

function computeFinishingMove() {
  var  remainingMoves =getRemainingMoves();
  var  finishingMoveCoords;
  for (var move of remainingMoves) {
    checkedBoxes.push({ box: move, player: currentPlayer });
    var  nextBox = document.querySelector(`[id='${move}']`)
    if (checkWinner() =='game over') {
finishingMoveCoords = move;
      onUncheckBox(nextBox, true);
      break;
}
    onUncheckBox(nextBox, true);
}
  if(finishingMoveCoords){
    console.log('Playing Finishing Move')
    return finishingMoveCoords;
}
  else{
    return'';
}
}function getRemainingMoves() {
  var  allMoves = ['0-0', '0-1', '0-2',
                  '1-0', '1-1', '1-2',
                  '2-0', '2-1', '2-2',]
  var  playedMoves = checkedBoxes.map(b=> b.box);
  return allMoves.filter(m=>!playedMoves.find(move=> move == m));
}
function onUncheckBox(elementisImplicit=false) {
checkedBoxes = checkedBoxes.filter(b=> b.box != element.id);
  if (!isImplicit) {
element.value ='';
element.removeAttribute("disabled");
turnCount--;
     switchPlayer();
}
}

While checking a box to check for winner, we have to make sure that we uncheck that box after the iteration completes to avoid bad data in checkedBoxes array. For that matter, we employ the onUncheckBox method above. If there is no ‘finishing move’ available, we check for the next condition – computeSavingMove. 

3. Saving Move that allows CPU to save the game.

Consider the following scenario: 

Here it’s CPU’s (O) turn to play. Clearly playing anywhere other than top middle box will cause the game to end in the next turn. So, we have to definitely check that box. To do this, we write a method similar to previous method where we this time iterate over all the remaining boxes and during each iteration fill them with opponent’s mark and then call the checkWinner method. If it returns ‘game over’ in any of the iterations then that is our desired box. Here’s what this translates to in JavaScript. 

function computeSavingMove() {  var  remainingMoves =getRemainingMoves();  switchPlayer();  var  savingMoveCoords;  for (var  move of remainingMoves) {          checkedBoxes.push({ box: move, player: currentPlayer });         var nextBox = document.querySelector(`[id='${move}']`)         if (checkWinner() =='game over') {                         savingMoveCoords = move;                         onUncheckBox(nextBox, true);                         break;}    onUncheckBox(nextBox, true);}    switchPlayer();   if(savingMoveCoords){      console.log('Playing Saving Move')      return savingMoveCoords;}}

You might argue that this is a clear violation of the DRY (Don’t Repeat Yourself) principle. But, sometimes, to keep the code readable and avoid complexities, you may want to take a rain check on the DRY. To make sure that I’m iterating with opponent’s move and note CPU’s, I’m calling the switchPlayer method before iterating over remainingMoves. If none of the remaining moves is a saving move we then turn our attention to the trickiest condition – predictTrappingMove

4. Predicting a move that will trap the CPU and avoiding it.

A ‘Trapping Move’, as I like to call it is when the opponent checks a box that leaves you with two Finishing boxes to fill, ultimately leading you to lose the game. Here’s a screenshot to show exactly that: 

In the image, it’s Player O’s turn and he is in a lose-lose situation. If he check tile 0-0, Player’s X will check 2-2 to win the game and vice versa. So, the only way out of this situation is to avoid it. That’s where our next method, predictTrappingMove comes in.

This method isn’t complicated in terms of execution but the planning needs to be spot on. So, what we do is, every time the opponent plays a move, we check for the possibility of a trapping move, the next time he plays. To achieve this, we will have to one by one check every box with our move. On each turn, we will then have to check each remaining box with the opponents move. Then, we check whether more than one winning move was created as a result of that. I know, I know, what the hell, right? Okay let’s break it down. Suppose we are in this situation: 


The opponent is playing for O’s. If I, for instance, play 1-0, the opponent can easily play 0-2 and trap me like this. 


Since, there was no finishing or saving move available, I wasn’t able to detect this. To detect this, I will have to check every single box till I find one that’s safe. I can accomplish that by first checking box. Then I will play opponent’s turn on each of the remaining boxes.

This way, I can determine whether any of his moves will result in a trapping move. Any of my turns that I don’t find a trapping move anywhere, will be my next move. For some turns, it won’t be possible for the opponent to play all the available boxes, eg, a turn where he has to play a saving move. In those cases, I won’t be iterating over all his possible moves, but just the saving ones. I’ll be making the assumption that the opponent will try to save himself if I play a move that forces him to do so. Okay, this is how it all translates to JavaScript. 

function predictTrappingMove() {
  var  checkedBoxesBackup = checkedBoxes.slice();
  var  remainingMoves =getRemainingMoves();
  var  nextMove;
  var  moveFound;
  for(var move of remainingMoves){
checkedBoxes.push({box: move, player: currentPlayer})
    switchPlayer();
//Check if the opponent needs to play a saving move
    var savingMove =  computeSavingMove();
    if(savingMove){
checkedBoxes.push({box: savingMove, player: currentPlayer});
      if(checkTrap() =='no trap'){
checkedBoxes.pop();
        switchPlayer();
nextMove = move;
        break;
}
checkedBoxes.pop();
      switchPlayer();
     continue;
}
//If no saving move is required, check each position  
 else{
     switchPlayer();
     for(var opponentMove ofgetRemainingMoves()){
       switchPlayer();
       moveFound =true;
       checkedBoxes.push({box: opponentMove, player: currentPlayer});
       if(checkTrap() =='trapped'){
         moveFound =false;
         checkedBoxes.pop();
         switchPlayer();
         break;
       }
         checkedBoxes.pop();
         switchPlayer();
}
}
checkedBoxes.pop();
    if(moveFound){
nextMove = move;
      break;
}
}checkedBoxes = checkedBoxesBackup;
  return nextMove;
}
function checkTrap(){
  var  boxes =getRemainingMoves();
  var  winningMoveCount =0;
  for(var  freeMove of boxes){
checkedBoxes.push({box: freeMove, player: currentPlayer});
    var result = checkWinner(true);
    if(result =='game over')
winningMoveCount++
checkedBoxes.pop();
}
  if(winningMoveCount >1){
    return 'trapped';
}
  else{
    return 'no trap';
}
}

Here, predictTrappingMove is first checking a box on my behalf. Then, it’s checking whether the opponent needs to play a saving move to counter that. If yes, it’s calling the checkTrap method to see whether more than one saving conditions were created on that opponent move.

If not, that is the move that will be returned and played. If that’s not the case, however, and the opponent’s saving move created a trap for us, we need to move forward and check the remaining boxes for ourselves, and then in each turn check the remaining boxes on the opponent’s behalf and call the checkTrap method each time. If any of the boxes creates a ‘trapping move’, we avoid that move and keep iterating over remaining moves, till we find a safe move to play.

It may be a little confusing still, but if you go over the code a few times, it should all be clear. 

5. Random move

I wrote the computeRandomMove in the first versions of the game to calculate a move if all checks don’t return a move. However, it’s not relevant now as checkTrappingMove will always return a move, irrespective of everything. Here’s the code still if you need it. 

function computeRandomMove() {  var  remainingMoves =getRemainingMoves();  return remainingMoves[Math.floor(Math.random()*remainingMoves.length)]}

It’s simply leveraging the Math.random() method of JavaScript and returning a box based on that from the remainingMoves. So, that’s it. You’re ready to create your unbeatable tic-tac-toe. You can go ahead and write your own with the same principles or even improve over these.

You can even try to write a method that forcesTrappingMove on the opponent making your player a little more aggressive. If you got this far, thanks for your patience. Till next time!

TL;DR Writing code to create an unbeatable tic-tac-toe is simple, but coming up with the logic is what matters.

5 Ways Technology Can Help A Small Business

Please follow and like us:

Technology is changing our world in the most unexpected ways. Supreeth Bhat, MD, PQube believes that every small business needs to use technology to “future proof” themselves. According to him, “Constant Innovation is the Key to Survival”.

1.  Improving collaboration

Initially small companies started utilizing technology in the form of e mail and instant messenger. Technology has now significantly grown to collaborative project management platforms that allow the small business to operate from anywhere in the world.

2.  Minimize errors

Manual processes have a lot of room for errors. This significantly increases the cost. Automation completely eliminates factors that cause human errors thereby significantly reducing costs.

3.  Enhancing customer relations

Technology has opened a lot more avenues for small businesses from opening up online stores to offering 24/7 customer service. Business growth is great but with it comes the need to organize your information. This is where a CRM is useful.

4.  Cloud space

Small businesses can keep their important files on a massive server called the cloud and access them at any time. No technical knowledge is required. Cloud storage is also the perfect backup plan for businesses. These files are stored at a remote location and once data is stored in the cloud, it is safe.

5.  Tailor made apps

Mobile apps open opportunities to engage with customers in a unique way. They make it easier to convert audience into customers. Also enables businesses to have personalized interactions with customers. We are already in the era of driverless cars, robots performing surgeries and working in factories. Through technology disruptions, have come improved quality of life. Every business needs to incorporate technology or there are high chances they might miss the opportunities or fall behind the rest or worse become irrelevant.