News on Eazy Ad Unblocker

Hello everyone!

A few months ago, I had launched a wordpress plugin called “Eazy Ad Unblocker”.  You can read about it from https://myplugins.net/announcing-eazy-ad-unblocker/. You can download it from https://wordpress.org/plugins/eazy-ad-unblocker/.
You can preview it at https://myplugins.net/demo/
Don’t forget to keep your adblocker on while browsing the preview URL.

The plugin notifies a user of a wordpress site if they are using
an adblocker.They are prompted to disable their adblocker or
whitelist the webmasters site in their adblocker settings. This helps
all those site owners whose paid advertising is being blocked by users
by installing adblocker extensions in their browsers.

Over the past few months, since its launch a few months ago, the plugin seems to be gaining some traction on the web.

Its number of active installations has crossed 100. At the time of writing, 1,714 people had downloaded it. The plugin has also found a mention at https://www.adventurewp.com/best-anti-adblock-plugins-for-wordpress/

Adventure WP describes the plugin as a “dead-simple plugin” which is “very lightweight and simple to set up”.

Furthermore, in their words “Eazy Ad Unblocker” actually provides “less customization while also providing more. but you do have full text input available for your title and main notice text. It also uses the regular
classic-style WordPress text editor so you can include nearly anything in
your anti-adblock notice–images, HTML, video, whatever TinyMCE
allows you to embed.”

On a critical note, they believe that the design of the popup dialog is “a bit dated”. That’s something that needs to be worked on I guess. Also they note, “You don’t have different anti-adblock methods, nor do you have color customization”.

Finally, they note that Eazy Ad Unblocker is an absolutely usable plugin, which does not lock a facility to dismiss the popup behind a pay wall!

Thank you Adventure WP guys!

Note: Please note that “Eazy Ad Unblocker” now has a popup refresh button. Whitelist the site in your adblocker or disable it and then click “Refresh” at the bottom of the popup dialog. The popup will go away.

Photo credit: https://www.adventurewp.com/best-anti-adblock-plugins-for-wordpress/

Sample Code for Algorithm to Create Combinations of Characters

In my post here, I described an algorithm to create all possible combinations from a set of characters. However, it allows repetitions of characters in the generated combinations. e.g aas, aaa and so on.
In this post, I will demonstrate an implementation of this algorithm in PHP, without any parallelization of any kind. I don’t know if it’s even possible to parallelize code in PHP.

You can run this code on LAMPP, WAMP, MAMP or XAMPP if you like. Successive trials of code execution may be faster than previous ones. Maybe, you all won’t like this code since it uses the “goto” keyword which is believed to lead to the creation of spaghetti code.  However, this was the easiest way to implement the algo for me.

<?php 

$dictionary = array('a', 'b', 'c', 'd', 'e');

$startLen = 1;
$stopLen = 4;

$currLen = 1;

//function to create string combination from array of indices
function getStringFromChars($indices)
{
  global $dictionary;
  $str='';

  for($j = 0; $j < count($indices); $j++)
  {
    $str.=$dictionary[$indices[$j]];
  }
  
  return $str;
}

//check condition to stop generating combos
function timeToStop($indices)
{
  
  global $dictionary;
  
  $stop = false;
  
  for($j = 0; $j < count($indices); $j++)
  {
    if($indices[$j] < count($dictionary) - 1)
    {
      return $stop;
    }
  }

  $stop = true;
  
  return $stop;
}

//main function
function generate($startLen, $stopLen)
{
  global $dictionary;
  $attempts = 0;
  
  for($currLen = $startLen; $currLen <= $stopLen; $currLen++)
  {
    step3:
    $chars = array();
    
    $indices = array();
    
    //init the arrays
    for($i = 0; $i < $currLen; $i++ )
    {
      $indices[$i] = 0;
      
      $chars[$i] = $dictionary[$indices[$i]];
    }
    
    step4:
    $working_index = $currLen - 1;
    
    step5:
    $str = getStringFromChars($indices);
    
    step6:
    echo $str;
    echo "<br />";
    $attempts++;
    
    if(timeToStop($indices))
    {
      if($currLen < $stopLen)
      {
        
        continue;
      }
      else
      {
        break;
      }
    }
    
    if($indices[$working_index] < count($dictionary) - 1)
    {
      $indices[$working_index]++;
      goto step5;
    }
    else
    {	
      if($currLen > 1)
      {

      
        while($indices[$working_index] == count($dictionary) - 1)
          $working_index--;
          
        if($working_index == -1)
        {
          if($currLen < $stopLen)
          {
            
            continue;
          }
          else
            break;
        }
        else
        {				
          $indices[$working_index]++;
          //set all indices to the right of working_index to 0
          
          for($k = $working_index + 1; $k < count($indices); $k++)
          {
            $indices[$k] = 0;
          }
          
          goto step4;
        }	
      }
      else
      {
      
        if($currLen < $stopLen)
        {
          
          continue;
        }
        else
          break;
      }
    }
    
  }

  return $attempts;
}

$start = microtime(true);

$atts = generate($startLen, $stopLen);

$end = microtime(true);

$time_taken = $end - $start;

$rate = $atts / $time_taken;

echo "Time(seconds): ".$time_taken;
echo "<br />";

echo "Attempts: ".$atts;
echo "<br />";

echo "Rate: ".$rate." iterations per second";

 

Announcing EZee Copyright Protector

Hello again guys!

I wish to announce that I have released a new WordPress Plugin called ‘EZee Copyright Protector’.  You can find this plugin at the URL https://wordpress.org/plugins/ezee-cpyright-protector/.

What does the plugin do? Suppose you have a wordpress website where you have created original content painstakingly and published it. Ordinarily, there is nothing to prevent other webmasters from blatantly copying your content. So unless you have taken precautions to prevent it from happening,
you are in for a nasty shock, which is your content showing up on other sites without your permission.

The EZee Copyright Protector plugin prevents any person with malafide intentions from copying your content. This includes prevention of selection, copying, cutting, pasting, dragging and saving of your content.

On trying any of these operations, a modal popup is presented to the user.
This popup can only be dismissed by clicking the cross on the top right of the popup. The admin of the wordpress site can change the title and text of the copyright notice which appears as a modal popup. This plugin does not claim to support shortcodes from other plugins in its text editor field.

EZee Copyright Protector prevents copying and plagiarism of your original or copyrighted content. It works on Mozilla Firefox, Google Chrome, Microsoft Edge and Opera browsers.

As a user of this plugin, you can change the title of the popup and add text, graphics, audio and video to the body of popup. Only HTML5 based video and audio is allowed. As for images, only formats compatible with wordpress are supported.

This plugin supports internationalization in the frontend as well as wp-admin screens. You can preview this plugin at https://myplugins.net
For more details, go to https://wordpress.org/plugins/ezee-cpyright-protector/

A Simple IP Blocker Plugin for WordPress

In my post here, I had shown how to create a basic “Hello World” plugin that greets the user with a simple “hello world” message in the admin dashboard. Now, let me show you how to create a wordpress plugin that actually does something more useful. In this post, I shall discuss a plugin that restricts the number of login attempts a user can make to login to the admin dashboard of your wordpress site. It makes sense to do this to secure your dashboard from being broken into because an unauthorized user can do just about anything to your site if he manages to access your admin dashboard. This includes defacing your site, deleting your content and God knows what else!

We will call our plugin “Simple IP Blocker”. It will restrict the number of failed login attempts to a fixed number, say three. On the fourth attempt, the user will see an error message “IP address blocked”. The user will be blocked for the remainder of the day on which he made the three unsuccessful login attempts. He will be able to try again on the following day.

Now, let’s get down to the nuts and bolts of the actual plugin. The steps are:

  1. Create a folder for the plugin
  2. Create a PHP file for the code called index.php in that folder.
  3. Create a header for the plugin.
  4. Initialize the required constants.
  5. Create a database table through the activation hook.
  6. Create a function that hooks into wp_login_failed action.
    It logs the failed attempts in the database table and blocks the IP address of the user.
  7. Create a function that displays the logged data from the table.
  8. Hook the function in 7 into the admin_menu action so that the logged data can be displayed.
  9. Create a function that hooks into the login action ‘wp_authenticate’
    that will give an error on trying to login in after ip is blocked.
  10. Activate your plugin and test it.

Let us discuss these steps in detail:

1. Navigate to the wp-content folder in your wordpress installation. Go to the plugins sub folder in it.
Create a folder called “simple-ip-blocker”.

2. Create a blank file titled index.php using your text editor and save it in the folder created in step 1

3. Now, let’s create the header in the index.php file.
Print the following code in after the opening php tag in the index.php file:

<?php 
/ * 
* Plugin Name: My Simple IP Blocker 
*/ 
?>

4. We will initialize the following constants:

<?php 
global $wpdb; 
define("LOGIN_FAILURES", 3); 
define("IPBLOCKER_TABLE", $wpdb-&gt;prefix.'ip_blocker');
?>

5. The above step will create a new line in the plugins section of your wordpress installation and define
the necessary constants.

We need to create a database table to log and count failed login attempts.
We will do this by using the “register_activation_hook” function.
We will create a PHP function named “simple_ip_blocker_create_table”.
In this function, we will write a “CREATE TABLE” MYSQL query. We will execute it by calling $wpdb->query
function on the global $wpdb variable by passing the query in it as a parameter.

We will then pass the “simple_ip_blocker_create_table” function name in the “register_activation_hook” function.

The code is as follows:

<?php 

function simple_ip_blocker_create_table() { 

     global $wpdb, $table_prefix; 
     //mysql query $create_tab_query = 
"CREATE TABLE IF NOT EXISTS `".IPBLOCKER_TABLE."`( 
`id` bigint(20) NOT NULL AUTO_INCREMENT, 
`ip_addr` varchar(20) NOT NULL, `attempts` int(4) NOT NULL, 
`try_date` date NOT NULL, `is_blocked` tinyint(1) NOT NULL, 
PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8"; 

$wpdb->query($create_tab_query); } 

register_activation_hook( __FILE__, 'simple_ip_blocker_create_table' ); ?>

 

Explanation of table structure:

id – PRIMARY KEY
ip_addr – IP address of user trying to log in.
attempts – number of failed logins per user.
try_date – date on which user s trying to log in.
is_blocked – flag too indicate whether the user is blocked or not.

6. Next, we will create a function that will hook into “wp_login_failed”. We will call
this function simple_ip_blocker_reset_bruteforce. This function will fire whenever the
user tries to login but fails. We will maintain a counter in the $_SESSION. Each failed
login will increment the counter. On reaching 3 attempts, the IP blocked flag, is_blocked
will be marked as 1 to indicate that the particular user is blocked for the remainder of
the day. However, the user can try again on the next day. Each attempt is logged in the
database table we created. For the first failed attempt, a new row will be created in the
table. For subsequent attempts, that row will be updated.For the third failed login,
the “is_blocked” field of that row will be updated to 1.

Check out the code below:

<?php 

function simple_ip_blocker_reset_bruteforce() { 

@session_start(); 
global $wpdb, $table_prefix; 
if(!isset($_SESSION["brute_count"])) { 
$_SESSION["brute_count"] = 1; 
$query = "INSERT INTO ".IPBLOCKER_TABLE."(ip_addr, attempts, try_date, is_blocked) VALUES(%s, %d, %s, %d)"; 
$try_date = gmdate("Y-m-d"); 

$wpdb-&gt;query( $wpdb-&gt;prepare( 
        $query, 
        $_SERVER["REMOTE_ADDR"], 
        $_SESSION["brute_count"], 
        $try_date,
        0
      ) );
      
     }
     else
     {
      $_SESSION["brute_count"] = $_SESSION["brute_count"] + 1;
     
      $try_date = gmdate("Y-m-d"); 
       
       //check limit
        
      $check_query = "SELECT attempts FROM ".IPBLOCKER_TABLE." WHERE ip_addr = %s AND try_date = %s";
        
      $attempt_count = $wpdb-&gt;get_var($wpdb-&gt;prepare($check_query, $_SERVER['REMOTE_ADDR'], $try_date ));
    
       if($attempt_count &gt;= LOGIN_FAILURES)
       {
         unset($_SESSION["brute_count"]);
         
         $update_query = "UPDATE ".IPBLOCKER_TABLE." SET is_blocked = 1 WHERE ip_addr = %s AND try_date = %s";
         
         $wpdb-&gt;query($wpdb-&gt;prepare($update_query, $_SERVER['REMOTE_ADDR'], $try_date ));
         
         wp_redirect(site_url('/wp-admin/'));
         
         exit;
         
       }
       else{
         
        $query = "UPDATE ".IPBLOCKER_TABLE." SET attempts = %d WHERE ip_addr = %s AND try_date = %s";
        
        $wpdb-&gt;query( $wpdb-&gt;prepare( 
          $query,  
          $_SESSION["brute_count"],
          $_SERVER['REMOTE_ADDR'],
          $try_date
         ) ); 
         
         
       }
     } 
  }  

  add_action("wp_login_failed", "simple_ip_blocker_reset_bruteforce");
?>

 

7. So far so good. Now we will create a function to display the data of
failed logins in the wordpress backend. We will call this function
“simple_ipblocker_menu_callback”. It will simply query the database table
that we created and list out the information in tabular form.

See the code below:

<?php 

function simple_ipblocker_menu_callback() { 

  global $wpdb; 
  $get_history = "SELECT * FROM ".IPBLOCKER_TABLE; //&quot; LIMIT $offset, 10; 
  
  $history = $wpdb->get_results($get_history, ARRAY_A); ?> 
  <h1>Simple IP Blocker active!</h1> 
  <table border="0" cellspacing="5" cellpadding="5" class="widefat" > 
  <tr>
    <td>S. No.</td>
    <td>IP Address</td>
    <td>Login Attempts</td> 
    <td>Try Date</td>
    <td>Blocked</td> 
  </tr> 
  <?php foreach($history as $row){ ?>
    <tr>
      <td><?php echo $row["id"]; ?></td>
      <td><?php echo $row["ip_addr"]; ?></td>
      <td><?php echo $row["attempts"]; ?></td>
      <td><?php echo $row["try_date"]; ?></td> 
      <td><?php echo ($row["is_blocked"] == 1)?"blocked":"unblocked"; ?></td>
    </tr>
  <?php } ?> 
  </table> 
<?php } ?>

 

8. In this step, we will simply write some code to call the function created above whenever the user
clicks the link for the plugin in the admin sidebar on the left. See below:

<?php 

function simple_ipblocker_menu_add() { 

     add_menu_page("Simple IP Blocker", "Simple IP Blocker", "administrator", "simple-ip-blocker", "simple_ipblocker_menu_callback" ); 

} 

add_action("admin_menu", "simple_ipblocker_menu_add"); 

?>

 

9. The last function to be created is the function that checks if the user’s IP is blocked. If so,
the user will not be able to login to the admin dashboard on that day. However, the user may try
logging in on the next day again.
We will call this function “simple_ip_blocker_check_ip”. In this function, we will check if the user’s
IP address is marked 1 in the is_blocked field. If so, the user will be prevented from logging in.
The function hooks into “wp_authenticate” and hence will fire before every login attempt.

The code is as follows:

<?php 
       function simple_ip_blocker_check_ip() { 
               global $wpdb; 
               $try_date = gmdate("Y-m-d"); 
               $check_IP = "SELECT is_blocked FROM ".IPBLOCKER_TABLE." WHERE ip_addr = %s AND try_date = %s"; 
               $blocked = $wpdb-&gt;get_var( $wpdb-&gt;prepare( 
          $check_IP,  
          $_SERVER['REMOTE_ADDR'],
          $try_date
         ) );
         
    if($blocked == 1)
    {
      wp_die("IP address blocked!");
    }
  }

  add_action("wp_authenticate", "simple_ip_blocker_check_ip");
?>

 

10. Lastly, now that the coding is complete, we need to activate the “Simple IP Blocker” plugin listed in the
wp-admin and test it according to the functionality in the steps above.

The full listing is as follows:

<?php  
/*
* Plugin Name: My Simple IP Blocker
*/  
global $wpdb;

define("LOGIN_FAILURES", 3);
define("IPBLOCKER_TABLE", $wpdb->prefix.'ip_blocker');

function simple_ip_blocker_create_table()
{
  global $wpdb, $table_prefix;
  
  $create_tab_query = "CREATE TABLE IF NOT EXISTS `".IPBLOCKER_TABLE."`(
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `ip_addr` varchar(20) NOT NULL,
    `attempts` int(4) NOT NULL,
    `try_date` date NOT NULL,
    `is_blocked` tinyint(1) NOT NULL,
    PRIMARY KEY (`id`)
  ) ENGINE=MyISAM  DEFAULT CHARSET=utf8";
  
  $wpdb->query($create_tab_query);
}

register_activation_hook( __FILE__, 'simple_ip_blocker_create_table' );


function simple_ip_blocker_reset_bruteforce()
{ 
   @session_start(); 
   
   global $wpdb, $table_prefix;
   
   if(!isset($_SESSION["brute_count"]))
   {
    $_SESSION["brute_count"] = 1; 
    
    $query = "INSERT INTO ".IPBLOCKER_TABLE."(ip_addr, attempts, try_date, is_blocked) VALUES(%s, %d, %s, %d)";
    
    $try_date = gmdate("Y-m-d");
    
    $wpdb->query( $wpdb->prepare( 
      $query, 
      $_SERVER["REMOTE_ADDR"], 
      $_SESSION["brute_count"], 
      $try_date,
      0
    ) );
    
   }
   else
   {
    $_SESSION["brute_count"] = $_SESSION["brute_count"] + 1;
   
    $try_date = gmdate("Y-m-d"); 
     
     //check limit
      
    $check_query = "SELECT attempts FROM ".IPBLOCKER_TABLE." WHERE ip_addr = %s AND try_date = %s";
      
    $attempt_count = $wpdb->get_var($wpdb->prepare($check_query, $_SERVER['REMOTE_ADDR'], $try_date ));
  
     if($attempt_count >= LOGIN_FAILURES)
     {
       unset($_SESSION["brute_count"]);
       
       $update_query = "UPDATE ".IPBLOCKER_TABLE." SET is_blocked = 1 WHERE ip_addr = %s AND try_date = %s";
       
       $wpdb->query($wpdb->prepare($update_query, $_SERVER['REMOTE_ADDR'], $try_date ));
       
       wp_redirect(site_url('/wp-admin/'));
       
       exit;
       
     }
     else{
       
      $query = "UPDATE ".IPBLOCKER_TABLE." SET attempts = %d WHERE ip_addr = %s AND try_date = %s";
      
      $wpdb->query( $wpdb->prepare( 
        $query,  
        $_SESSION["brute_count"],
        $_SERVER['REMOTE_ADDR'],
        $try_date
       ) ); 
       
       
     }
   } 
}  

add_action("wp_login_failed", "simple_ip_blocker_reset_bruteforce");  //plugin admin panel


//pre-authentication

function simple_ip_blocker_check_ip()
{
  //die('done');
  global $wpdb;
  
  $try_date = gmdate("Y-m-d");
  
  $check_IP = "SELECT is_blocked FROM ".IPBLOCKER_TABLE." WHERE ip_addr = %s AND try_date = %s";
  
  $blocked = $wpdb->get_var( $wpdb->prepare( 
        $check_IP,  
        $_SERVER['REMOTE_ADDR'],
        $try_date
       ) );
       
  if($blocked == 1)
  {
    wp_die("IP address blocked!");
  }
}

add_action("wp_authenticate", "simple_ip_blocker_check_ip");

function simple_ipblocker_menu_callback()
{ 

  global $wpdb;
  
  /* $page = (isset($_GET['pg']))?$_GET['pg']:1;
  
  $offset = ($page - 1) * 10; */
  
  $get_history = "SELECT * FROM ".IPBLOCKER_TABLE; //" LIMIT $offset, 10";
  
  $history = $wpdb->get_results($get_history, ARRAY_A);
  
  ?>
  <h1>Simple IP Blocker active!</h1>
    <table border="0" cellspacing="5" cellpadding="5" class="widefat">
      <tr>
        <td>S. No.</td>
        <td>IP Address</td>
        <td>Login Attempts</td>
        <td>Try Date</td>
        <td>Blocked</td>
      </tr>
      <?php 
        foreach($history as $row)
        {
          ?>
          <tr>
            <td><?php echo $row["id"]; ?></td>
            <td><?php echo $row["ip_addr"]; ?></td>
            <td><?php echo $row["attempts"]; ?></td>
            <td><?php echo $row["try_date"]; ?></td>
            <td><?php echo ($row["is_blocked"] == 1)?"blocked":"unblocked"; ?></td>
          </tr>
          <?php 
        }
      ?>
    </table>
  <?php
  
  
  
}  

function simple_ipblocker_menu_add()
{
  add_menu_page("Simple IP Blocker", "Simple IP Blocker", "administrator", "simple-ip-blocker", "simple_ipblocker_menu_callback" );
}  

add_action("admin_menu", "simple_ipblocker_menu_add");
//plugin admin panel end

?>

 

Create a Basic WordPress Plugin From Scratch

In my post here, I had shown you how to create a plugin from existing code. In this post, I will show how to create a basic ‘Hello World’ wordpress plugin from scratch.

First of all, create a ‘hello-world’ folder in your plugins subfolder under the wp-content folder of your wordpress installation.
Then, create a blank file in the ‘hello-world’ folder and name it ‘index.php’.
After that, open your index.php file and put the following code in it:

<?php
/*
Plugin Name: Hello World Plugin
Plugin URI: http://myexamplesite.com/hello-world
Description: A simple WordPress Hello World plugin
Version: 1.0
Author: Author Name 
Author URI: http://myownsite.com
License: GPL2
*/
 ?>

 

This will create a descriptive header in the listing of plugins under the plugins section in wp-admin.

Now create a simple hello_world function in the example index.php page like so:

<?php 

function hello_world()
{
     echo "<h1>Hello World!</h1>"; 
}

?>

But this function needs to be called somewhere to get its output.

To get the output, we need to add the following code to our index.php file.

<?php

function hello_world_callback()
{
      add_menu_page("Hello World", "Hello World", "administrator", "hello-world", "hello_world");
}

add_action("admin_menu", "hello_world_callback");

?>

The add_action function hooks into ‘admin_menu’ to create a link to the plugin in the admin sidebar on the left of your dashboard. On clicking this link, the ‘hello_world’ function is called and the output is displayed on that page.

We will get the output in wp-admin under the “Hello World” tab once we activate the plugin.

So the complete code that needs to be there in the index.php is the following:

<?php
/*
Plugin Name: Hello World Plugin
Plugin URI: http://myexamplesite.com/hello-world
Description: A simple WordPress Hello World plugin
Version: 1.0
Author: Author Name 
Author URI: http://myownsite.com
License: GPL2
*/

function hello_world()
{
     echo "<h1>Hello World!</h1>"; 
} 

function hello_world_callback() { 
     add_menu_page("Hello World", "Hello World", "administrator", "hello-world", "hello_world"); 
} 

add_action("admin_menu", "hello_world_callback");

?>

 

The video above shows the installation and working of the plugin.

Click the following link for a more detailed tutorial.

An elementary security plugin protecting admin dashboard

In this post, I shall discuss an elementary plugin that can protect your wordpress admin dashboard from frequent incorrect login attempts. The plugin redirects the user to the home page after a predetermined number of incorrect logins, three for example. However, if the user enters the correct password after three wrong attempts, the user is logged in to the dashboard. The code hooks into the wp_login_failed action hook and uses a counter variable stored in the session to keep track of the number of login attempts. The plugin backend only tells the administrator that the plugin is active (See image above). The code listing is given below:

<?php 
/* 
* Plugin Name: My Simple Security 
*/ 

function simple_security_reset_bruteforce($username){ 

  @session_start(); 
  if(!isset($_SESSION["brute_count"])) { 
    $_SESSION["brute_count"] = 1; 
  } else { 
    $_SESSION["brute_count"] = $_SESSION["brute_count"] + 1; 
    if($_SESSION["brute_count"] > 3) { 
    
      unset($_SESSION["brute_count"]); 
      wp_redirect(site_url()); 
      exit; 
    } 
  } 
} 

add_action("wp_login_failed", "simple_security_reset_bruteforce"); //plugin admin panel 

function simple_security_menu_callback() { 

  echo "<h1>Simple Security active!</h1>"; 
  
} 

function simple_security_menu_add() { 

  add_menu_page("Simple Security", "Simple Security", "administrator", "simple-security", "simple_security_menu_callback" ); 
  
} 

add_action("admin_menu", "simple_security_menu_add"); //plugin admin panel end 

?>

 

A recording of the plugin is given below:

 

To turn this into a plugin and use it in your wordpress:

  1. Create an empty folder in your plugins folder.
  2. Give it an easily understandable name.
  3. Then, create a blank file in any text editor.
  4. Copy the code from the code listing here, including the “<?php” at the start.
  5. Paste the code copied above in your blank file.
  6. Save this file as index.php in your empty folder created above.
  7. Go to the wp-admin and activate the plugin.
  8. Logout from admin and try logging in to wp-admin repeatedly with the wrong password.

It should work as shown in the video above.

Convert Very Large Decimal Integers to Base 62 And Back

The other day I was trying to devise a way of converting arbitrarily large base 10 integers to the order of a billion billion to base 62 and did not get much help from the web. So I devised my own solution using the BC Math extension which ships with PHP by default. So, this solution works upto PHP_INT_MAX which is 9223372036854775807 for 64-bit platform. It also works upto 99 trillion on 32-bit-platform. I used an array as a stack to store successive remainders of division by the base, which is 62, and at the end popped them one by one from the stack to generate the converted base 62 number. The converse, multiplication by successive powers of 62 and addition of those powers helped to convert base 62 back to base 10.

First I used PHP OOPS to create a class called MyBase62Converter. The code is given below:

class MyBase62Converter
{
	private $base62StrVar = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
	private $baseInt = 62;
	
	function encode($decNum)
	{
		$base = $this->baseInt;
		
		$myStack = array();

		$remainder = 0;

		$base62Str = $this->base62StrVar;

		do 
		{
			
			$remainder = bcmod($decNum, $base);
			
			array_push($myStack, $remainder);
			
			$decNum = bcdiv(bcsub($decNum, $remainder), $base); 
			
		}
		while($decNum > 0);
		
		$binNum = '';

		while(count($myStack) > 0)
		{
			
			$binNum.= substr($base62Str, array_pop($myStack), 1);
		}

		return (strlen($binNum) >= 6)?$binNum: str_pad($binNum, 6, 0, STR_PAD_LEFT);
	}
	
	function decode($baseNum)
	{
		
		$base62Str = $this->base62StrVar;
		
		$base = $this->baseInt;

		$hashLen = strlen($baseNum);
		
		$decNum = '';
		
		for($i = 0; $i < $hashLen; $i++)
		{
			$decNum = bcadd($decNum, bcmul(bcpow($base, $i), strpos($base62Str , substr($baseNum, $hashLen - $i - 1, 1))));
		}
		
		return $decNum;
	}
	
}

Using the two simple encode and decode functions we can convert base 10 integers to base 62 representation and vice versa.

You can see the example below:

require_once("lib/class.MyBase62Converter.php"); 

$encoder = new MyBase62Converter();

echo "<br />";

echo PHP_INT_MAX." encoded is ".$encoded = $encoder->encode(PHP_INT_MAX);

echo "<br />";

echo $encoded." decoded is ".$decoded = $encoder->decode($encoded);

echo "<br />";
 
$largeNum = bcpow(62, 6) - 1; 

echo $largeNum." encoded is ".$encoded = $encoder->encode($largeNum); 

echo "<br />"; 

echo $encoded." decoded is ".$decoded = $encoder->decode($encoded); 

echo "<br />"; 

$veryLargeNum = bcpow(62, 7) - 1; //getting 0 due to num expressed in scientfic exponential notation 2.183401055849E+14 

echo $veryLargeNum." encoded is ".$encoded = $encoder->encode($veryLargeNum); 

echo "<br />"; 

echo $encoded." decoded is ".$decoded = $encoder->decode($encoded); 

echo "<br  />"; 

$max_num = 99999999999999; 

echo $max_num." encoded is ".$encoded = $encoder->encode($max_num , 62); //99999999999999 

echo "<br />"; 

echo $encoded." decoded is ".$decoded = $encoder->decode($encoded); 

echo "<br />"; 

$new_num = 63; 

echo $new_num." encoded is ".$encoded = $encoder->encode($new_num , 62);  

echo "<br />"; 

echo $encoded." decoded is ".$decoded = $encoder->decode($encoded);

The result of code execution is given below:

Coding a game of tic-tac-toe using 3 different languages

I used a brute force logic to develop an algorithm for tic-tac-toe.
Firstly, there are only 8 triads of winning points or moves: three vertical, three horizontal and 2 diagonals.
Players play taking turns or making moves alternately. Player 1 makes a maximum of 5 moves and player
2 makes a maximum of 4 moves because there are a maximum of 9 moves to be made and player 1 begins the game.

Furthermore, player 1 has already made 2 moves before getting his first chance to form a winning line.
Players take turns alternately which means that when player 1 gets his first chance to form a line,
player 2 has already made 2 moves of his own. So player 1 can only form a line from move 5. Player 2
can only form his first line at move 6. Player 1 gets his second chance to win at move 7 and his third
and last chance at move 9. Similarly, player 2 gets his second and last chance at move 8.

Every time there is a chance to form a winning line, all possible permutations and combinations of
the current players moves, taken three at a time, are compared with all 8 winning triads. If a match is found,
the current player wins. If player 1 forms a line first, player 2 does not get a chance to continue the game.

The game has 3 versions: PHP, Java and C#

PHP Version

It can be played via the command-line executable of your PHP installation.

In the game of tic-tac-toe there is a 3X3 grid or board.The game is for two players. The players 1 and 2 take turns to mark the cells of the grid with their mark which is a zero or a cross.

The first player to complete a vertical, horizontal or diagonal triad of zeroes or crosses, wins.

In this implementation, I have used the OOPs or Object Oriented Programming features of PHP.

I have divided the functionality and roles or responsibilities between various classes as follows.

Player makes Move on Board to play Game. So the classes are:

  1. Move
  2. Board
  3. Player
  4. Game

First we discuss the move class:

Move:

Move made by either of the players.

class Move
{
  private $row; // between 1 and 3
  private $column; //between 1 and 3 on the 3x3 board
  private $isValid; //whether the move is valid or not
  
  //getters and setters for the properties
  public function setRow($i)
  {
    $this->row = $i;
  }
  
  public function setColumn($j)
  {
    $this->column = $j;
  }
  
  public function setValid($valid)
  {
    $this->isValid = $valid;
  }
  
  public function getRow()
  {
    return $this->row;
  }
  
  public function getColumn()
  {
    return $this->column;
  }
  
  public function getValid()
  {
    return $this->isValid;
  }
}

 

Then comes the Board class where the moves are made.

Board:

The board on which the game is played.

class Board
{
  private $cells = array(); //the 3x3 grid of cells
  
  public function __construct()
  {
    $row1 = array(" ", " ", " ");
    
    $row2 = array(" ", " ", " ");
    
    $row3 = array(" ", " ", " ");
    
    $this->cells[0] = $row1;
    
    $this->cells[1] = $row2;
    
    $this->cells[2] = $row3;
  }
  
  //display the board with moves made so far
  public function display()
  {
    for($i = 0; $i < 3; $i++)
    {
      for($j = 0; $j < 3; $j++) { if($this->cells[$i][$j] == " ")
        {
          echo ($i + 1).", ".($j + 1)."\t";
        }
        else
        {
          echo $this->cells[$i][$j]."\t";
        }
      }
      
      echo "\n\n";
    }
  }
  
  //check if a cell is already occupied or not
  public function checkAvailable($move)
  {
    $i = $move->getRow();
    $j = $move->getColumn();
    
    $valid1 = (($i >= 1 && $i <= 3) && ($j >= 1 && $j <= 3));
    
    if($valid1)
    {
      $valid2 = ($this->cells[$i - 1][$j - 1] == " ");
    }
    else
    {
      $valid2 = false;
    } 

                $valid3 = ($valid1 && $valid2); 

                $move->setValid($valid3);
    
    return $move;
  }

  //put a cross or zero in a cell if the move is valid
  public function markCell($move, $mark)
  {
    if($move->getValid())
    {
      $i = $move->getRow();
      $j = $move->getColumn();
      
      $this->cells[$i - 1][$j - 1] = $mark;
    }
    else
    {
      echo "INVALID MOVE!\n\n";
    }
  }
}

 

The Player class denotes the players who make moves on the board.

Player:

Either of the two players.

class Player
{
  private $playerNum;  //player 1 or 2
  private $playerMark; // '0' or 'X'
  private $winnerOrLoser;
  private $moves = array(); //list of moves made by player
  private $g; //the game being played
  
  //getters and setters
  public function setPlayerNum($num)
  {
    $this->playerNum = $num;
  }

  public function setPlayerMark($mark)
  {
    $this->playerMark = $mark;
  }
  
  public function setPlayerWinnerLoser($winnerOrLoser)
  {
    $this->winnerOrLoser = $winnerOrLoser;
  }
  
  public function getPlayerNum()
  {
    return $this->playerNum;
  }
  
  public function getPlayerMark()
  {
    return $this->playerMark;
  }
  
  public function getPlayerWinLose()
  {
    return $this->winnerOrLoser;
  }
  
  public function getPlayerMoves()
  {
    return $this->moves;
  }
  
  //the player can put x or 0 by choosing the cell (row and column)
  public function makeMove($board, $move)
  {
    $move = $board->checkAvailable($move);
    
    $mark = $this->getPlayerMark();
    $board->markCell($move, $mark);
      
    if($move->getValid())
    {	
      $this->addMove($move);
      
      $this->getGame()->setMovesTillNow();
    }
    
    $board->display();
  }
  
  //if move is valid, add the move to the player's list of moves
  public function addMove($move)
  {
    $this->moves[] = $move;
  }
  
  public function setGame($game)
  {
    $this->g = $game;
    
  }
  
  public function getGame()
  {
    return $this->g;
  }
}

 

The Game class is the functionality of the game with all its rules.

Game:

The game being played.

class Game
{
  private $whoseTurn; //player 1 or 2
  private static $movesTillNow = 0; //how many moves till now
  private $gameOver; //is game over yet?
  private $winningMoves; //list of combination of moves which can win the game
  private $winner = null;
  
  private $winning_moves;
  
  public function __construct()
  {
    //winning moves

    $this->winning_moves = array();
    //row wise
    
    $move01 = new Move();
    $move01->setRow(1);
    $move01->setColumn(1);
    
    $move02 = new Move();
    $move02->setRow(1);
    $move02->setColumn(2);
    
    $move03 = new Move();
    $move03->setRow(1);
    $move03->setColumn(3);
    
    $move0 = array($move01, $move02, $move03);

    $this->winning_moves[0] = $move0;
    
    $move11 = new Move();
    $move11->setRow(2);
    $move11->setColumn(1);
    
    $move12 = new Move();
    $move12->setRow(2);
    $move12->setColumn(2);
    
    $move13 = new Move();
    $move13->setRow(2);
    $move13->setColumn(3);
    
    $move1 = array($move11, $move12, $move13);

    $this->winning_moves[1] = $move1;
    
    $move21 = new Move();
    $move21->setRow(3);
    $move21->setColumn(1);
    
    $move22 = new Move();
    $move22->setRow(3);
    $move22->setColumn(2);
    
    $move23 = new Move();
    $move23->setRow(3);
    $move23->setColumn(3);
    

    $move2 = array($move21, $move22, $move23);

    $this->winning_moves[2] = $move2;

    //column wise
    
    $move31 = new Move();
    $move31->setRow(1);
    $move31->setColumn(1);
    
    $move32 = new Move();
    $move32->setRow(2);
    $move32->setColumn(1);
    
    $move33 = new Move();
    $move33->setRow(3);
    $move33->setColumn(1);
    
    $move3 = array($move31, $move32, $move33);

    $this->winning_moves[3] = $move3;
    
    $move41 = new Move();
    $move41->setRow(1);
    $move41->setColumn(2);
    
    $move42 = new Move();
    $move42->setRow(2);
    $move42->setColumn(2);
    
    $move43 = new Move();
    $move43->setRow(3);
    $move43->setColumn(2);
    
    $move4 = array($move41, $move42, $move43);

    $this->winning_moves[4] = $move4;
    
    $move51 = new Move();
    $move51->setRow(1);
    $move51->setColumn(3);
    
    $move52 = new Move();
    $move52->setRow(2);
    $move52->setColumn(3);
    
    $move53 = new Move();
    $move53->setRow(3);
    $move53->setColumn(3);
    
    $move5 = array($move51, $move52, $move53);

    $this->winning_moves[5] = $move5;

    //diagonally
    
    $move61 = new Move();
    $move61->setRow(1);
    $move61->setColumn(1);
    
    $move62 = new Move();
    $move62->setRow(2);
    $move62->setColumn(2);
    
    $move63 = new Move();
    $move63->setRow(3);
    $move63->setColumn(3);
    
    $move6 = array($move61, $move62, $move63);

    $this->winning_moves[6] = $move6;
    
    $move71 = new Move();
    $move71->setRow(1);
    $move71->setColumn(3);
    
    $move72 = new Move();
    $move72->setRow(2);
    $move72->setColumn(2);
    
    $move73 = new Move();
    $move73->setRow(3);
    $move73->setColumn(1);
    
    $move7 = array($move71, $move72, $move73);

    $this->winning_moves[7] = $move7;
  }
  
  //getters and setters
  public function getWhoseTurn()
  {
    return $this->whoseTurn;
  }	
  
  public function setWhoseTurn($player)
  {
    $this->whoseTurn = $player->getPlayerNum();
  }
  
  public function getGameOver()
  {
    return $this->gameOver;
  }	
  
  public function setGameOver($gameOver)
  {
    $this->gameOver = $gameOver;
  }
  
  public function setMovesTillNow()
  {
    self::$movesTillNow++;
  }
  
  public function getMovesTillNow()
  {
    return self::$movesTillNow;
  }
  
  public function setWinner($winner)
  {
    $this->winner = $winner;
  }
  
  public function getWinner()
  {
    return $this->winner;
  }
  
  //check if winning moves have been made by either player
  public function checkWinningMoves($player)
  {
    
    $movesTillNow = $this->getMovesTillNow();
    
    $whoseTurn = $this->getWhoseTurn();
    
    $playerMoves = $player->getPlayerMoves();
    
    $moves = $movesTillNow;
    
    $winning_moves1 = $this->winning_moves;
    
    switch($whoseTurn)
    {
      case 1:
        
        if($moves < 5)
        {
          return false;
        }
        else
        {
          
          if($moves == 5)
          {
          
            $player1_set1 = array($playerMoves[0], $playerMoves[1], $playerMoves[2]);
            
            for($i = 0; $i < 8; $i++) { if($this->checkSubset($player1_set1, $winning_moves1[$i]))
              {
                return true;
              }
            }
            
          }
          
          if($moves == 7)
          {
            $player1_set2 = array($playerMoves[0], $playerMoves[1], $playerMoves[3]);
            
            $player1_set4 = array($playerMoves[0], $playerMoves[2], $playerMoves[3]);
            
            $player1_set7 = array($playerMoves[1], $playerMoves[2], $playerMoves[3]);
            
            for($i = 0; $i < 8; $i++) { if($this->checkSubset($player1_set2, $winning_moves1[$i]) || 
              $this->checkSubset($player1_set4, $winning_moves1[$i]) || 
              $this->checkSubset($player1_set7, $winning_moves1[$i]) )
              {
                return true;
              }
            }
          }
          
          if($moves == 9)
          {
          
            $player1_set3 = array($playerMoves[0], $playerMoves[1], $playerMoves[4]);
            
            $player1_set5 = array($playerMoves[0], $playerMoves[2], $playerMoves[4]);
            
            $player1_set6 = array($playerMoves[0], $playerMoves[3], $playerMoves[4]);
            
            $player1_set8 = array($playerMoves[1], $playerMoves[2], $playerMoves[4]);
            
            $player1_set9 = array($playerMoves[1], $playerMoves[3], $playerMoves[4]);
            
            $player1_set10 = array($playerMoves[2], $playerMoves[3], $playerMoves[4]);
            
            for($i = 0; $i < 8; $i++) { if($this->checkSubset($player1_set3, $winning_moves1[$i]) ||
              $this->checkSubset($player1_set5, $winning_moves1[$i]) || $this->checkSubset($player1_set6, $winning_moves1[$i]) || 
              $this->checkSubset($player1_set8, $winning_moves1[$i]) || $this->checkSubset($player1_set9, $winning_moves1[$i]) || 
              $this->checkSubset($player1_set10, $winning_moves1[$i]))
              {
                return true;
              }
            }
            
          }
          
          return false;
           
          
        
        }
      break;
      case 2:
        if($moves < 6)
        {
          return false;
        }
        else
        {
          if($moves == 6)
          {
            $player2_set1 = array($playerMoves[0], $playerMoves[1], $playerMoves[2]);
            
            for($i = 0; $i < 8; $i++) { if($this->checkSubset($player2_set1, $winning_moves1[$i]))
              {
                return true;
              }
            }
          }
          
          if($moves == 8)
          {
    
            $player2_set2 = array($playerMoves[0], $playerMoves[1], $playerMoves[3]);
            
            $player2_set3 = array($playerMoves[0], $playerMoves[2], $playerMoves[3]);
            
            $player2_set4 = array($playerMoves[1], $playerMoves[2], $playerMoves[3]);
            
            for($i = 0; $i < 8; $i++) { if($this->checkSubset($player2_set2, $winning_moves1[$i]) || $this->checkSubset($player2_set3, $winning_moves1[$i]) ||
              $this->checkSubset($player2_set4, $winning_moves1[$i]))
              {
                return true;
              }
            }
          }
          
          
          
          return false;
        
        }
      break;
      default:
        return false;
    }
    
    
  }
  
  //check if player moves match the winning sequence
  private function checkSubset($subset, $winning_row)
  {
    
    $count = 0;
    for($i = 0; $i < 3; $i++)
    {
      
      for($j = 0; $j < 3; $j++) { if($subset[$i]->getRow() == $winning_row[$j]->getRow() && $subset[$i]->getColumn() == $winning_row[$j]->getColumn())
        {
          $count++;
        }
      }
      
    }
    return ($count == 3);
    
  }
}

 

Putting it all together.

<?php

require("includes/move.php");  //the Move class

require("includes/player.php"); //the Player class

require("includes/board.php"); //the Board class

require("includes/game.php"); //the Game class

function main() //where all the action is
{
  $game = new Game();
  
  $player1 = new Player();
  
  $player1->setPlayerNum(1);
  
  $player1->setPlayerMark('X');
  
  $player1->setGame($game);
  
  $player2 = new Player();
  
  $player2->setPlayerNum(2);
  
  $player2->setPlayerMark('0');
  
  $player2->setGame($game);
  
  $b = new Board();

  $b->display();
  
  $game->setWhoseTurn($player1);
  
  $game->setGameOver(false);
  
  $status = $game->getGameOver();
  
  do
  {
    $movesNow = $game->getMovesTillNow();
    
    if($movesNow == 9)
    {
      
      if($game->getWinner() == null)
      {
        echo "TIE!";
        break;
      }
      
    }
    
    $turn = $game->getWhoseTurn();
    
    echo "PLAYER $turn:\n\n";
    
    $row = 0; $column = 0;
    
    echo "Enter row: ";
    
    trim(fscanf(STDIN, "%d\n", $row));
    
    echo "Enter column: ";
    
    trim(fscanf(STDIN, "%d\n", $column));
    
    echo "\n";
    
    $move = new Move();
    
    $move->setRow($row);
    
    $move->setColumn($column);
    
    switch($turn)
    {
      case 1:
        $player1->makeMove($b, $move);
        
        if($game->checkWinningMoves($player1))
        {
          
          $game->setWinner($player1);
          
          echo "PLAYER 1 WINS!\n\n";
          
          $game->setGameOver(true);
        }
        else
        {
          if($move->getValid())
          {
            $movesNow = $game->getMovesTillNow();
    
            echo "MOVE NUMBER: $movesNow\n\n";
            
            $game->setWhoseTurn($player2);
            
          }
        }
      break;
      case 2:
        $player2->makeMove($b, $move);
        
        if($game->checkWinningMoves($player2))
        {
          
          $game->setWinner($player2);
          
          echo "PLAYER 2 WINS!\n\n";
          
          $game->setGameOver(true);
        }
        else
        {
          if($move->getValid())
          {
            $movesNow = $game->getMovesTillNow();
    
            echo "MOVE NUMBER: $movesNow\n\n";
            
            $game->setWhoseTurn($player1);
          }
        }
      break;
      default:
        echo "ERROR!\n\n";
      break;
    }
    
    $status = $game->getGameOver();
    
  }while(!$status);
  
}

main(); //invoking the game play

?>

 

 

This implementation is not perfect by any means. Any suggestions for improvement are welcome. Screenshots given below:

Java Version

Here is an elementary tic-tac-toe or noughts and crosses game made in Java.
It can be played via the java interpreter from the command line. In the game of tic-tac-toe there is a 3X3 grid or board.The game is for two players. The players take turns to mark the cells of the grid with their mark which is a zero or a cross.

The first player to complete a vertical, horizontal or diagonal triad of zeroes or crosses, wins.

The PHP version can be found here

Player makes Move on Board to play Game. So the classes are:

  1. Move
  2. Board
  3. Player
  4. Game
  5. TicTacToe

There is one new class “TicTacToe” because Java needs a main class having the “main” method implemented in it.

The first four classes are in the package named “com.tictactoe.components” , while the main class is in the package named “com.tictactoe”.

First we discuss the move class:

Move:

Move made by either of the players.

package com.tictactoe.components;

/**
 *
 * @author pratyush
 */
public class Move {
    
    private int row, column;
    private boolean isValid;

    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        this.row = row;
    }

    public int getColumn() {
        return column;
    }

    public void setColumn(int column) {
        this.column = column;
    }

    public boolean isIsValid() {
        return isValid;
    }

    public void setIsValid(boolean isValid) {
        this.isValid = isValid;
    }
    
}

 

Then comes the Board class where the moves are made.

Board:

The board on which the game is played.

package com.tictactoe.components;

/**
 *
 * @author pratyush
 */
public class Board{
    
    private static char[][] cells;
    
    public Board()
    {
        cells = new char[3][3];
        
        cells[0] = new char[]{' ', ' ', ' '};
        
        cells[1] = new char[]{' ', ' ', ' '};
        
        cells[2] = new char[]{' ', ' ', ' '};
    }
    
    
   public void display()
   {
       for(int i = 0; i < 3; i++)
       {
           for(int j = 0; j < 3; j++) { 

                 if(cells[i][j] == ' ') { 

                       System.out.print((i+1)+", "+(j+1)+"\t"); 

                 } else { 

                       System.out.print(cells[i][j]+"\t");
  
                 } 

            } System.out.print("\n\n"); 

       } 

    } 

    public Move checkAvailable(Move move) { 

       int i = move.getRow(); 

       int j = move.getColumn(); 

       boolean boundValid = ((i >= 1 && i<= 3) && ( j >= 1 && j <= 3));
       
       boolean charValid = false;
       
       if(boundValid)
       {
           charValid = (cells[i - 1][j - 1] == ' ');
       }
       
       boolean netValid = (boundValid && charValid);
       
       move.setIsValid(netValid);
       
       return move;
   }
   
   public void markCell(Move move, char mark)
   {
       if(move.isIsValid())
       {
           int i = move.getRow();
           
           int j = move.getColumn();
           
           cells[i - 1][j - 1] = mark;
       }
       else
       {
           System.out.println("INVALID MOVE!\n\n");
       }
   }
   
}

 

The Player class denotes the players who make moves on the board.

Player:

Either of the two players.

package com.tictactoe.components;

import java.util.ArrayList;
/**
 *
 * @author pratyush
 */
public class Player {
    
    private int playerNum;
    private char playerMark;
    private int winnerOrLoser;
    private Game g;
    
    private ArrayList<Move> moves = new ArrayList<Move>();

    public int getPlayerNum() {
        return playerNum;
    }

    public void setPlayerNum(int playerNum) {
        this.playerNum = playerNum;
    }

    public char getPlayerMark() {
        return playerMark;
    }

    public void setPlayerMark(char playerMark) {
        this.playerMark = playerMark;
    }

    public int getWinnerOrLoser() {
        return winnerOrLoser;
    }

    public void setWinnerOrLoser(int winnerOrLoser) {
        this.winnerOrLoser = winnerOrLoser;
    }

    public Game getGame() {
        return g;
    }

    public void setGame(Game g) {
        this.g = g;
    }

    public ArrayList getMoves() {
        return moves;
    }

    public void addMove(Move move) {
        
        this.moves.add(move);
    }
    
    public void makeMove(Board board, Move move)
    {
        move = board.checkAvailable(move);
        
        char mark = this.getPlayerMark();
        
        board.markCell(move, mark);
        
        if(move.isIsValid())
        {
            this.addMove(move);
            Game.setMovesTillNow();
        }
        
        board.display();
    }
    
}

 

The Game class is the functionality of the game with all its rules.

Game:

The game being played.

package com.tictactoe.components;

import java.util.ArrayList;
/**
 *
 * @author pratyush
 */
public class Game{
 
    private int whoseTurn;
    private static int movesTillNow = 0;
    private boolean gameOver;
    
    private Player winner = null;
    
    Move[][] winning_moves;
    
    public Game()
    {
        
        winning_moves = new Move[8][3];
        
        //top row
        Move move01 = new Move();
        move01.setRow(1);
        move01.setColumn(1);
        
        Move move02 = new Move();
        move02.setRow(1);
        move02.setColumn(2);
        
        Move move03 = new Move();
        move03.setRow(1);
        move03.setColumn(3);
        
        Move[] move0;
        
        move0 = new Move[]{move01, move02, move03};
        
        
        winning_moves[0] = move0;
        
        //middle row
        
        Move move11 = new Move();
        move11.setRow(2);
        move11.setColumn(1);
        
        Move move12 = new Move();
        move12.setRow(2);
        move12.setColumn(2);
        
        Move move13 = new Move();
        move13.setRow(2);
        move13.setColumn(3);
        
        Move[] move1;
        
        move1 = new Move[]{move11, move12, move13};
        
        winning_moves[1] = move1;
        
        //bottom row
        
        Move move21 = new Move();
        move21.setRow(3);
        move21.setColumn(1);
        
        Move move22 = new Move();
        move22.setRow(3);
        move22.setColumn(2);
        
        Move move23 = new Move();
        move23.setRow(3);
        move23.setColumn(3);
        
        Move[] move2;
        
        move2 = new Move[]{move21, move22, move23};
        
        winning_moves[2] = move2;
        
        //column wise
        
        //column 1
        
        Move move31 = new Move();
        move31.setRow(1);
        move31.setColumn(1);
        
        Move move32 = new Move();
        move32.setRow(2);
        move32.setColumn(1);
        
        Move move33 = new Move();
        move33.setRow(3);
        move33.setColumn(1);
        
        Move[] move3;
        
        move3 = new Move[]{move31, move32, move33};
        
        winning_moves[3] = move3;
        
        //column 2
        
        Move move41 = new Move();
        move41.setRow(1);
        move41.setColumn(2);
        
        Move move42 = new Move();
        move42.setRow(2);
        move42.setColumn(2);
        
        Move move43 = new Move();
        move43.setRow(3);
        move43.setColumn(2);
        
        Move[] move4;
        
        move4 = new Move[]{move41, move42, move43};
        
        winning_moves[4] = move4;
        
        //column 3
        
        Move move51 = new Move();
        move51.setRow(1);
        move51.setColumn(3);
        
        Move move52 = new Move();
        move52.setRow(2);
        move52.setColumn(3);
        
        Move move53 = new Move();
        move53.setRow(3);
        move53.setColumn(3);
        
        Move[] move5;
        
        move5 = new Move[]{move51, move52, move53};
        
        winning_moves[5] = move5;
        
        //diagonals
        
        //diagonal 1
        
        Move move61 = new Move();
        move61.setRow(1);
        move61.setColumn(1);
        
        Move move62 = new Move();
        move62.setRow(2);
        move62.setColumn(2);
        
        Move move63 = new Move();
        move63.setRow(3);
        move63.setColumn(3);
        
        Move[] move6;
        
        move6 = new Move[]{move61, move62, move63};
        
        winning_moves[6] = move6;
        
        //diagonal 2
        
        Move move71 = new Move();
        move71.setRow(1);
        move71.setColumn(3);
        
        Move move72 = new Move();
        move72.setRow(2);
        move72.setColumn(2);
        
        Move move73 = new Move();
        move73.setRow(3);
        move73.setColumn(1);
        
        Move[] move7;
        
        move7 = new Move[]{move71, move72, move73};
        
        winning_moves[7] = move7;
        
    }

    public int getWhoseTurn() {
        return whoseTurn;
    }

    public void setWhoseTurn(Player player) {
        this.whoseTurn = player.getPlayerNum();
    }

    public static int getMovesTillNow() {
        return movesTillNow;
    }

    public static void setMovesTillNow() {
        Game.movesTillNow++;
    }

    public boolean isGameOver() {
        return gameOver;
    }

    public void setGameOver(boolean gameOver) {
        this.gameOver = gameOver;
    }

    public Player getWinner() {
        return winner;
    }

    public void setWinner(Player winner) {
        this.winner = winner;
    }
    
    private boolean checkSubset(Move[] subset, Move[] winning_row)
    {
        int count = 0;
        
        for(int i = 0;i < 3; i++)
        {
            for(int j = 0; j< 3; j++)
            {
                if(subset[i].getRow() == winning_row[j].getRow() && subset[i].getColumn() == winning_row[j].getColumn())
                {
                   count++; 
                }
            }
        }
        
        return (count == 3);
    }
    
    
    //check the winning moves
    
    public boolean checkWinningMoves(Player player)
    {
        
        /*****check winning moves*****/
        
        int movesTillNow = Game.getMovesTillNow();
        
        int whoseTurn = this.getWhoseTurn();
        
        ArrayList<Move> playerMoves = player.getMoves();
        
        int moves = movesTillNow;
        
        Move[][] winning_moves1 = this.winning_moves;
        
        switch(whoseTurn)
        {
            case 1:
                
                if(moves < 5)
                {
                    return false;
                }
                else
                {
                    if(moves == 5)
                    {
                        Move[] player1_set1 = new Move[]{playerMoves.get(0), playerMoves.get(1), playerMoves.get(2)};
                        
                        for(int i = 0; i< 8; i++)
                        {
                            if(checkSubset(player1_set1, winning_moves1[i]))
                            {
                                return true;
                            }
                        }
                    }
                    
                    /******/
                    
                    if(moves == 7)
                    {
                        Move[] player1_set2 = new Move[]{playerMoves.get(0), playerMoves.get(1), playerMoves.get(3)};
            
                        Move[] player1_set4 = new Move[]{playerMoves.get(0), playerMoves.get(2), playerMoves.get(3)};

                        Move[] player1_set7 = new Move[]{playerMoves.get(1), playerMoves.get(2), playerMoves.get(3)};

                        for(int i = 0; i < 8; i++)
                        {
                                if(checkSubset(player1_set2, winning_moves1[i]) || 
                                checkSubset(player1_set4, winning_moves1[i]) || 
                                checkSubset(player1_set7, winning_moves1[i]) )
                                {
                                        return true;
                                }
                        }
                    }
                    
                    if(moves == 9)
                    {
                        Move[] player1_set3 = new Move[]{playerMoves.get(0), playerMoves.get(1), playerMoves.get(4)};
            
                        Move[] player1_set5 = new Move[]{playerMoves.get(0), playerMoves.get(2), playerMoves.get(4)};

                        Move[] player1_set6 = new Move[]{playerMoves.get(0), playerMoves.get(3), playerMoves.get(4)};

                        Move[] player1_set8 = new Move[]{playerMoves.get(1), playerMoves.get(2), playerMoves.get(4)};

                        Move[] player1_set9 = new Move[]{playerMoves.get(1), playerMoves.get(3), playerMoves.get(4)};

                        Move[] player1_set10 = new Move[]{playerMoves.get(2), playerMoves.get(3), playerMoves.get(4)};

                        for(int i = 0; i < 8; i++)
                        {
                                if(checkSubset(player1_set3, winning_moves1[i]) ||
                                checkSubset(player1_set5, winning_moves1[i]) || checkSubset(player1_set6, winning_moves1[i]) || 
                                checkSubset(player1_set8, winning_moves1[i]) || checkSubset(player1_set9, winning_moves1[i]) || 
                                checkSubset(player1_set10, winning_moves1[i]))
                                {
                                        return true;
                                }
                        }
                    }
                    
                    return false;
                }
                
            case 2:
                /******/
                if(moves < 6)
                {
                    return false;
                }
                else
                {
                    /*******/
                    if(moves == 6)
                    {
                        Move[] player2_set1 = new Move[]{playerMoves.get(0), playerMoves.get(1), playerMoves.get(2)};
            
                        for(int i = 0; i < 8; i++)
                        {
                                if(checkSubset(player2_set1, winning_moves1[i]))
                                {
                                        return true;
                                }
                        }
                    }
                    
                    if(moves == 8)
                    {
                        Move[] player2_set2 = new Move[]{playerMoves.get(0), playerMoves.get(1), playerMoves.get(3)};
            
                        Move[] player2_set3 = new Move[]{playerMoves.get(0), playerMoves.get(2), playerMoves.get(3)};

                        Move[] player2_set4 = new Move[]{playerMoves.get(1), playerMoves.get(2), playerMoves.get(3)};

                        for(int i = 0; i < 8; i++)
                        {
                            if(checkSubset(player2_set2, winning_moves1[i]) || checkSubset(player2_set3, winning_moves1[i]) ||
                            checkSubset(player2_set4, winning_moves1[i]))
                            {
                                    return true;
                            }
                        }
                    }
                    
                    return false;
                }
            default:
                return false;
        }
    }
    
}

 

Finally, the main class:

TicTacToe

The class containing the entry point of the program also called the main class.

package com.tictactoe;

import com.tictactoe.components.*;
import java.util.Scanner;
/**
 *
 * @author pratyush
 */
public class TicTacToe{

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
         // TODO code application logic here
        
        Game game = new Game();
        
        Player player1 = new Player();
        
        player1.setPlayerNum(1);
        
        player1.setPlayerMark('X');
        
        player1.setGame(game);
        
        Player player2 = new Player();
        
        player2.setPlayerNum(2);
        
        player2.setPlayerMark('0');
        
        player2.setGame(game);
        
        Board board = new Board();
        
        board.display();
        
        /*******/
        
        game.setWhoseTurn(player1);
        
        game.setGameOver(false);
        
        boolean status = game.isGameOver();
        
        Scanner sc = new Scanner(System.in);
        
        do
        {
            int movesNow = Game.getMovesTillNow();
            
            if(movesNow == 9)
            {
                if(game.getWinner() == null)
                {
                    System.out.println("TIE!\n");
                    break;
                }
            }
            
            int turn = game.getWhoseTurn();
            
            System.out.println("PLAYER "+turn+"\n");
            
            int row = 0; 
            int column = 0;
      
      boolean invalid = true;
      
      while(invalid)
      {
             //code to handle invalid moves. players cannot proceed without valid input
        try{
          System.out.println("Enter row: ");
              
          String str = sc.next();
              
          if(!str.equals(""))
          {
              
            row = Integer.parseInt(str);
            invalid = false;
              
          }
          else
          {
            continue;
          }
        }
        catch(NumberFormatException n)
        {
          System.out.println("INVALID ROW!");
          invalid = true;
        }
        catch(InputMismatchException i)
        {
          System.out.println("INVALID ROW!");
          invalid = true;
        }
      }
      
      invalid = true;
      
      while(invalid)
      {
        /*code to handle invalid moves. players cannot proceed without valid input*/
          
        try{
          System.out.println("Enter column: ");
            
          String str = sc.next();
            
          if(!str.equals(""))
          {
            
            column = Integer.parseInt(str);
            invalid = false;
            
          }
          else
          {
            continue;
          }
        }
        catch(NumberFormatException n)
        {
          System.out.println("INVALID COLUMN!");
          invalid = true;
        }
        catch(InputMismatchException i)
        {
          System.out.println("INVALID COLUMN!");
          invalid = true;
        }
      }
      
      /**/
            
            Move move = new Move();
            
            move.setRow(row);
            
            move.setColumn(column);
            
            switch(turn)
            {
                case 1:
                    player1.makeMove(board, move);
                    
                    if(game.checkWinningMoves(player1))
                    {
                        game.setWinner(player1);
                        
                        System.out.println("PLAYER 1 WINS!");
                        
                        game.setGameOver(true);
                    }
                    else
                    {
                        if(move.isIsValid())
                        {
                            movesNow = Game.getMovesTillNow();
                            
                            System.out.println("MOVE NUMBER "+movesNow+"\n");
                            
                            game.setWhoseTurn(player2);
                        }
                    }
                    break;
                case 2:
                    player2.makeMove(board, move);
                    
                    if(game.checkWinningMoves(player2))
                    {
                        game.setWinner(player2);
                        
                        System.out.println("PLAYER 2 WINS!");
                        
                        game.setGameOver(true);
                    }
                    else
                    {
                        if(move.isIsValid())
                        {
                            movesNow = Game.getMovesTillNow();
                            
                            System.out.println("MOVE NUMBER "+movesNow+"\n");
                            
                            game.setWhoseTurn(player1);
                        }
                    }
                    break;
                default:
                    System.out.println("ERROR!\n");
                    break;
            }
            
            status = game.isGameOver();
        }
        while(!status);
        
    }
    
}

 

Copy, Compile, Run and ENJOY!

 

C# version

Here is an elementary tic-tac-toe or noughts and crosses game I made in C#, arguably the most popular language of the DotNET platform. It can be played from the command line after compiling it as an executable. In the game of tic-tac-toe there is a 3X3 grid or board.The game is for two players. The players 1 and 2 take turns to mark the cells of the grid with their mark which is a zero or a cross.

The first player to complete a vertical, horizontal or diagonal triad of zeroes or crosses, wins.

The PHP version can be found here

Player makes Move on Board to play Game. So the classes are:

  1. Move
  2. Board
  3. Player
  4. Game
  5. TicTacToe

There is one new class “TicTacToe” because C# needs a main class having the “Main” method implemented in it.

The classes are in the namespace called “TicTacToeDotNet”.

 

First we discuss the move class:

Move:

Move made by either of the players.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TicTacToeDotNet
{
    public class Move
    {

        private int row, column;
        private bool isValid;

        public int getRow()
        {
            return row;
        }

        public void setRow(int row)
        {
            this.row = row;
        }

        public int getColumn()
        {
            return column;
        }

        public void setColumn(int column)
        {
            this.column = column;
        }

        public bool isIsValid()
        {
            return isValid;
        }

        public void setIsValid(bool isValid)
        {
            this.isValid = isValid;
        }

    }
}

 

Then comes the Board class where the moves are made.

Board:

The board on which the game is played.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TicTacToeDotNet
{
    public class Board
    {

        private static char[][] cells;

        public Board()
        {
            cells = new char[3][];

            cells[0] = new char[] { ' ', ' ', ' ' };

            cells[1] = new char[] { ' ', ' ', ' ' };

            cells[2] = new char[] { ' ', ' ', ' ' };
        }


        public void display()
        {
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++) { 

                     if (cells[i][j] == ' ') { 

                          Console.Write((i + 1) + ", " + (j + 1) + "\t"); 

                      } else { 

                           Console.Write(cells[i][j] + "\t"); 

                      } 

                  } Console.Write("\n\n"); 

            } 

      } 

      public Move checkAvailable(Move move) { 

            int i = move.getRow(); 

            int j = move.getColumn(); 

            bool boundValid = ((i >= 1 && i <= 3) && (j >= 1 && j <= 3));

            bool charValid = false;

            if (boundValid)
            {
                charValid = (cells[i - 1][j - 1] == ' ');
            }

            bool netValid = (boundValid && charValid);

            move.setIsValid(netValid);

            return move;
        }

        public void markCell(Move move, char mark)
        {
            if (move.isIsValid())
            {
                int i = move.getRow();

                int j = move.getColumn();

                cells[i - 1][j - 1] = mark;
            }
            else
            {
                Console.Write("INVALID MOVE!\n\n");
            }
        }

    }

}

 

The Player class denotes the players who make moves on the board.

Player:

Either of the two players.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TicTacToeDotNet
{
    public class Player
    {

        private int playerNum;
        private char playerMark;
        private int winnerOrLoser;
        private Game g;

        private List moves = new List();

        public int getPlayerNum()
        {
            return playerNum;
        }

        public void setPlayerNum(int playerNum)
        {
            this.playerNum = playerNum;
        }

        public char getPlayerMark()
        {
            return playerMark;
        }

        public void setPlayerMark(char playerMark)
        {
            this.playerMark = playerMark;
        }

        public int getWinnerOrLoser()
        {
            return winnerOrLoser;
        }

        public void setWinnerOrLoser(int winnerOrLoser)
        {
            this.winnerOrLoser = winnerOrLoser;
        }

        public Game getGame()
        {
            return g;
        }

        public void setGame(Game g)
        {
            this.g = g;
        }

        public List getMoves()
        {
            return moves;
        }

        public void addMove(Move move)
        {

            this.moves.Add(move);
        }

        public void makeMove(Board board, Move move)
        {
            move = board.checkAvailable(move);

            char mark = this.getPlayerMark();

            board.markCell(move, mark);

            if (move.isIsValid())
            {
                this.addMove(move);
                Game.setMovesTillNow();
            }

            board.display();
        }

    }
}

 

The Game class is the functionality of the game with all its rules.

Game:

The game being played.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TicTacToeDotNet
{
    public class Game
    {

        private int whoseTurn;
        private static int movesTillNow = 0;
        private bool gameOver;

        private Player winner = null;

        Move[][] winning_moves;

        public Game()
        {

            winning_moves = new Move[8][];

            //top row
            Move move01 = new Move();
            move01.setRow(1);
            move01.setColumn(1);

            Move move02 = new Move();
            move02.setRow(1);
            move02.setColumn(2);

            Move move03 = new Move();
            move03.setRow(1);
            move03.setColumn(3);

            Move[] move0;

            move0 = new Move[] { move01, move02, move03 };


            winning_moves[0] = move0;

            //middle row

            Move move11 = new Move();
            move11.setRow(2);
            move11.setColumn(1);

            Move move12 = new Move();
            move12.setRow(2);
            move12.setColumn(2);

            Move move13 = new Move();
            move13.setRow(2);
            move13.setColumn(3);

            Move[] move1;

            move1 = new Move[] { move11, move12, move13 };

            winning_moves[1] = move1;

            //bottom row

            Move move21 = new Move();
            move21.setRow(3);
            move21.setColumn(1);

            Move move22 = new Move();
            move22.setRow(3);
            move22.setColumn(2);

            Move move23 = new Move();
            move23.setRow(3);
            move23.setColumn(3);

            Move[] move2;

            move2 = new Move[] { move21, move22, move23 };

            winning_moves[2] = move2;

            //column wise

            //column 1

            Move move31 = new Move();
            move31.setRow(1);
            move31.setColumn(1);

            Move move32 = new Move();
            move32.setRow(2);
            move32.setColumn(1);

            Move move33 = new Move();
            move33.setRow(3);
            move33.setColumn(1);

            Move[] move3;

            move3 = new Move[] { move31, move32, move33 };

            winning_moves[3] = move3;

            //column 2

            Move move41 = new Move();
            move41.setRow(1);
            move41.setColumn(2);

            Move move42 = new Move();
            move42.setRow(2);
            move42.setColumn(2);

            Move move43 = new Move();
            move43.setRow(3);
            move43.setColumn(2);

            Move[] move4;

            move4 = new Move[] { move41, move42, move43 };

            winning_moves[4] = move4;

            //column 3

            Move move51 = new Move();
            move51.setRow(1);
            move51.setColumn(3);

            Move move52 = new Move();
            move52.setRow(2);
            move52.setColumn(3);

            Move move53 = new Move();
            move53.setRow(3);
            move53.setColumn(3);

            Move[] move5;

            move5 = new Move[] { move51, move52, move53 };

            winning_moves[5] = move5;

            //diagonals

            //diagonal 1

            Move move61 = new Move();
            move61.setRow(1);
            move61.setColumn(1);

            Move move62 = new Move();
            move62.setRow(2);
            move62.setColumn(2);

            Move move63 = new Move();
            move63.setRow(3);
            move63.setColumn(3);

            Move[] move6;

            move6 = new Move[] { move61, move62, move63 };

            winning_moves[6] = move6;

            //diagonal 2

            Move move71 = new Move();
            move71.setRow(1);
            move71.setColumn(3);

            Move move72 = new Move();
            move72.setRow(2);
            move72.setColumn(2);

            Move move73 = new Move();
            move73.setRow(3);
            move73.setColumn(1);

            Move[] move7;

            move7 = new Move[] { move71, move72, move73 };

            winning_moves[7] = move7;

        }

        public int getWhoseTurn()
        {
            return whoseTurn;
        }

        public void setWhoseTurn(Player player)
        {
            this.whoseTurn = player.getPlayerNum();
        }

        public static int getMovesTillNow()
        {
            return movesTillNow;
        }

        public static void setMovesTillNow()
        {
            Game.movesTillNow++;
        }

        public bool isGameOver()
        {
            return gameOver;
        }

        public void setGameOver(bool gameOver)
        {
            this.gameOver = gameOver;
        }

        public Player getWinner()
        {
            return winner;
        }

        public void setWinner(Player winner)
        {
            this.winner = winner;
        }

        private bool checkSubset(Move[] subset, Move[] winning_row)
        {
            int count = 0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (subset[i].getRow() == winning_row[j].getRow() && subset[i].getColumn() == winning_row[j].getColumn())
                    {
                        count++;
                    }
                }
            }

            return (count == 3);
        }


        //check the winning moves

        public bool checkWinningMoves(Player player)
        {

            /*****check winning moves*****/

            int movesTillNow = Game.getMovesTillNow();

            int whoseTurn = this.getWhoseTurn();

            Move[] playerMoves = player.getMoves().ToArray();

            int moves = movesTillNow;

            Move[][] winning_moves1 = this.winning_moves;

            switch (whoseTurn)
            {
                case 1:

                    if (moves < 5)
                    {
                        return false;
                    }
                    else
                    {
                        if (moves == 5)
                        {
                            Move[] player1_set1 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[2] };

                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player1_set1, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }

                        /******/

                        if (moves == 7)
                        {
                            Move[] player1_set2 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[3] };

                            Move[] player1_set4 = new Move[] { playerMoves[0], playerMoves[2], playerMoves[3] };

                            Move[] player1_set7 = new Move[] { playerMoves[1], playerMoves[2], playerMoves[3] };

                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player1_set2, winning_moves1[i]) ||
                                checkSubset(player1_set4, winning_moves1[i]) ||
                                checkSubset(player1_set7, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }

                        if (moves == 9)
                        {
                            Move[] player1_set3 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[4] };

                            Move[] player1_set5 = new Move[] { playerMoves[0], playerMoves[2], playerMoves[4] };

                            Move[] player1_set6 = new Move[] { playerMoves[0], playerMoves[3], playerMoves[4] };

                            Move[] player1_set8 = new Move[] { playerMoves[1], playerMoves[2], playerMoves[4] };

                            Move[] player1_set9 = new Move[] { playerMoves[1], playerMoves[3], playerMoves[4] };

                            Move[] player1_set10 = new Move[] { playerMoves[2], playerMoves[3], playerMoves[4] };

                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player1_set3, winning_moves1[i]) ||
                                checkSubset(player1_set5, winning_moves1[i]) || checkSubset(player1_set6, winning_moves1[i]) ||
                                checkSubset(player1_set8, winning_moves1[i]) || checkSubset(player1_set9, winning_moves1[i]) ||
                                checkSubset(player1_set10, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }

                        return false;
                    }

                case 2:
                    /******/
                    if (moves < 6)
                    {
                        return false;
                    }
                    else
                    {
                        /*******/
                        if (moves == 6)
                        {
                            Move[] player2_set1 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[2] };

                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player2_set1, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }

                        if (moves == 8)
                        {
                            Move[] player2_set2 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[3] };

                            Move[] player2_set3 = new Move[] { playerMoves[0], playerMoves[2], playerMoves[3] };

                            Move[] player2_set4 = new Move[] { playerMoves[1], playerMoves[2], playerMoves[3] };

                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player2_set2, winning_moves1[i]) || checkSubset(player2_set3, winning_moves1[i]) ||
                                checkSubset(player2_set4, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }

                        return false;
                    }
                default:
                    return false;
            }
        }

    }
}

 

Finally, the main class:

TicTacToe

The class containing the entry point of the program also called the main class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TicTacToeDotNet
{
    public class TicTacToe
    {

        /**
         * @param args the command line arguments
         */
        public static void Main(string[] args)
        {
            // TODO code application logic here

            Game game = new Game();

            Player player1 = new Player();

            player1.setPlayerNum(1);

            player1.setPlayerMark('X');

            player1.setGame(game);

            Player player2 = new Player();

            player2.setPlayerNum(2);

            player2.setPlayerMark('0');

            player2.setGame(game);

            Board board = new Board();

            board.display();

            /*******/

            game.setWhoseTurn(player1);

            game.setGameOver(false);

            bool status = game.isGameOver();

            //

            do
            {
                int movesNow = Game.getMovesTillNow();

                if (movesNow == 9)
                {
                    if (game.getWinner() == null)
                    {
                        Console.WriteLine("TIE!\n");
                        break;
                    }
                }

                int turn = game.getWhoseTurn();

                Console.WriteLine("PLAYER " + turn + "\n");

                int row = 0;
                int column = 0;

                bool invalid = true;

                while (invalid)
                {
                    //code to handle invalid moves. players cannot proceed without valid input
                    try
                    {
                        Console.WriteLine("Enter row: ");

                        string str = Convert.ToString(Console.ReadLine());

                        if (!(str == ""))
                        {

                            row = Convert.ToInt32(str);
                            invalid = false;

                        }
                        else
                        {
                            continue;
                        }
                    }
                    catch (FormatException n)
                    {
                        Console.WriteLine("INVALID ROW!");
                        invalid = true;
                    }
                    /**/
                }

                invalid = true;

                while (invalid)
                {
                    /*code to handle invalid moves. players cannot proceed without valid input*/

                    try
                    {
                        Console.WriteLine("Enter column: ");

                        String str = Convert.ToString(Console.ReadLine());

                        if (!(str == ""))
                        {

                            column = Convert.ToInt32(str);
                            invalid = false;

                        }
                        else
                        {
                            continue;
                        }
                    }
                    catch (FormatException n)
                    {
                        Console.WriteLine("INVALID COLUMN!");
                        invalid = true;
                    }
                    /**/
                }

                /**/

                Move move = new Move();

                move.setRow(row);

                move.setColumn(column);

                switch (turn)
                {
                    case 1:
                        player1.makeMove(board, move);

                        if (game.checkWinningMoves(player1))
                        {
                            game.setWinner(player1);

                            Console.WriteLine("PLAYER 1 WINS!");

                            game.setGameOver(true);
                        }
                        else
                        {
                            if (move.isIsValid())
                            {
                                movesNow = Game.getMovesTillNow();

                                Console.WriteLine("MOVE NUMBER " + movesNow + "\n");

                                game.setWhoseTurn(player2);
                            }
                        }
                        break;
                    case 2:
                        player2.makeMove(board, move);

                        if (game.checkWinningMoves(player2))
                        {
                            game.setWinner(player2);

                            Console.WriteLine("PLAYER 2 WINS!");

                            game.setGameOver(true);
                        }
                        else
                        {
                            if (move.isIsValid())
                            {
                                movesNow = Game.getMovesTillNow();

                                Console.WriteLine("MOVE NUMBER " + movesNow + "\n");

                                game.setWhoseTurn(player1);
                            }
                        }
                        break;
                    default:
                        Console.WriteLine("ERROR!\n");
                        break;
                }

                status = game.isGameOver();
            }
            while (!status);

            Console.Read();

        }

    }
}

 

Copy, Compile, Run and ENJOY!

PHP Web Services: What they are, what they do and how to make one.

A “Web Service” is a bunch of code that resides on a server in an intranet or the internet. It performs some function and returns some data required by the client application that calls it. e.g. A foreign exchange web service might return the rates at which euros are converted to US dollars. A weather web service will return local temperature during any day. These web services can then be used in client applications like an e-commerce site that shows product prices in euros or dollars depending on the country the buyer is in, etc.

One common use of web services is in smartphone apps as a backend. A smartphone does not typically query a site’s database directly since it is not good to store database credentials locally on it. So the app calls a web service residing on a server. This web service fetches data from a web application and returns the data found to the smartphone app. e.g. An mobile e-commerce store allows users to search products by keywords. This app will call a web service which acts like a function that will accept the search keyword as a parameter. The web service returns a list of products to the calling app either as JSON or XML. The calling app will parse the results and display a list of products with names and images to the buyer.

But how is this achieved from the coding standpoint ? How does one create a PHP web service? There are many ways but I shall discuss about SOAP-based web services and illustrate with an example containing both the web service and the calling code in PHP. I will be using the NUSOAP library in my example. This will be an parameterized hello world web service. The client will call the web service and pass a name as a parameter to it. The result will be a
“Hello” greeting to the name given.

We need to do two things, (1) Setup the server side and (2) Setup the client side, from which we will call our web service.

DISCLAIMER: It is assumed that the reader knows basics of PHP development and can work on web servers or locally setup development servers.

Setting Up The Server Side

  1. Check SOAP is enabled on the server: Your server phpinfo() should look like this.If your phpinfo() does not look like the screenshot above, you need to locate your php.ini file and uncomment the semi-colon in the lines containing the soap DLL file (php_soap.dll in Windows). Save the modified php.ini and restart Apache Server. Then check your phpinfo() again.
  2. Create a new project folder on server.
  3. Install the PHP NUSOAP library: Download it from here.
  4. Extract the archive and keep the lib folder in your project folder.
  5. Call lib/nusoap.php in your PHP file where you will be working.
    <?php require('lib/nusoap.php'); //make sure that the nusoap.php file is found at this path relative to your php source file ?>
  6. Create a SOAP server object.
    <?php $soapServer = new soap_server(); //create the soap server object ?>
  7. Configure WSDL
    <?php $soapServer-&gt;configureWSDL("HelloWorldWSDL", "http://www.helloworldsite.com"); //configure the WSDL ?>
  8. Register a method with your SOAP server.
    <?php $soapServer-&gt;register('helloWorldWebSvc', array('name'=&gt;'xsd:string'),array('return'=&gt;"xsd:string"), "http://www.helloworldsite.com", "http://www.helloworldsite.com#helloWorldWebSvc", 'rpc', 'encoded', 'Hello World App!'); //register the method with the server ?>
  9. Make sure you call the service method of the SOAP server.
    <?php /*$soapServer-&gt;service($HTTP_RAW_POST_DATA); //Fault:SOAP-ENV:Client error in msg parsing: xml was empty, didn't parse! */ @$soapServer-&gt;service(file_get_contents("php://input")); //FIXED ?>
  10. Putting It All Together
    <?php 
    
    require("lib/nusoap.php"); 
    
    $soapServer = new soap_server(); //create the soap server object 
    
    $soapServer->configureWSDL("HelloWorldWSDL", "http://www.helloworldsite.com"); //configure the WSDL 
    
    $soapServer->register('helloWorldWebSvc', array('name'=&amp;gt;'xsd:string'),array('return'=&amp;gt;"xsd:string"), "http://www.helloworldsite.com", "http://www.helloworldsite.com#helloWorldWebSvc", 'rpc', 'encoded', 'Hello World App!'); //register the method with the server 
    
    function helloWorldWebSvc($name) //our function with business logic. Also called the server-side method. 
    { return "Hello $name!"; } 
    
    $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA)?$HTTP_RAW_POST_DATA:''; 
    /*$soapServer->service($HTTP_RAW_POST_DATA); //Fault:SOAP-ENV:Client error in msg parsing: xml was empty, didn't parse! */
    
    @$soapServer->service(file_get_contents("php://input")); //FIXED 
    
    exit; ?>

     

Important Note

It is important to note that there are outdated code snippets out there using $soapServer->service($HTTP_RAW_POST_DATA);

This wont work with NUSOAP in PHP 7. It will give the error:

Fault:SOAP-ENV:Client error in msg parsing: xml was empty, didn’t parse!

Fix it by using the following:

@$soapServer->service(file_get_contents(“php://input”));

Setting Up the Client Side

  1. Check SOAP is enabled on the server: This step is identical to its counterpart in the server-side above.
  2. Create a new project folder on server: This step is identical to its counterpart in the server-side above.
  3. Install the PHP NUSOAP library: This step is identical to its counterpart in the server-side above.
  4. Call lib/nusoap.php in your PHP file where you will be working: This step is identical to its counterpart in the server-side above.
  5. Create a SOAP client object.
    <?php $client = new nusoap_client("http://localhost/HelloSvc/hello_world_web_svc.php?wsdl"); ?>
  6. Call the server-side method.
    <?php $response = $client-&gt;call("helloWorldWebSvc", array("Some User")); //calling the registered method of the web service from client. ?>
  7. Putting It All Together
    <?php 
    
    require("lib/nusoap.php"); 
    
    $client = new nusoap_client("http://localhost/HelloSvc/hello_world_web_svc.php?wsdl"); 
    
    $response = $client->call("helloWorldWebSvc", array("Some User")); //calling the registered method of the web service from client 
    
    if($client->fault) { 
      
      echo "Fault:".$client->faultcode." ".$client->faultstring; 
      
    } else { 
    
      print_r($response); 
    
    } 
      
    exit; 
      
    ?>

 

 

Note: In Android and iOS apps, no PHP client is used generally. Instead coding is done in Java or Objective-C, etc that uses the HTTP Client API of the respective programming languages.

 

The End Result

If all goes well you will see a screen like the one below when you invoke the PHP Web Service client in your browser.

Note: This example is compliant with PHP 7.