Wikipedia:Reference desk/Archives/Computing/2015 June 16

From Wikipedia, the free encyclopedia
Computing desk
< June 15 << May | June | Jul >> June 17 >
Welcome to the Wikipedia Computing Reference Desk Archives
The page you are currently viewing is an archive page. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages.


June 16[edit]

Tic-tac-toe in JavaScript and HTML[edit]

i'm trying to make one tic tac toe game using only java script and html following is my code, can anyone help me how to show who wins ?? i'm trying to check the condition within win() function but its not working. can anyone help me plz ??

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>TIC TAC TOE</title>
<style>
td{
	height:100px;
	width:100px;
	font-size:70px;
	text-align:center;
}
</style>

<script>
var lastvalue;
var is_active;
function fun1(a)
{	
	if( lastvalue == 'x')
	{
	if(document.getElementById(a) != "X" && document.getElementById(a) != "O")
	{
		document.getElementById(a).innerHTML="o";
		 lastvalue="o";
		 is_active=false;
	}
	}
	else
	{
		 document.getElementById(a).innerHTML="x";
		 lastvalue="x";
		 is_active=false;	
	}
	win();
}

function win()
{
	if((document.getElementById('f1') == 'x') && (document.getElementById('f2') == 'x') && (document.getElementById('f3') == 'x'))
	{
		alert("x won");
	}	
};
</script>

</head>

<body>
<table border="1px">
<tr><td id="f1" onClick="fun1('f1')"></td><td id="f2" onClick="fun1('f2')"></td><td id="f3" onClick="fun1('f3')"></td></tr>
<tr><td id="f4" onClick="fun1('f4')"></td><td id="f5" onClick="fun1('f5')"></td><td id="f6" onClick="fun1('f6')"></td></tr>
<tr><td id="f7" onClick="fun1('f7')"></td><td id="f8" onClick="fun1('f8')"></td><td id="f9" onClick="fun1('f9')"></td></tr>
</table>
</body>
</html>
I formatted the code for you and added a section heading. Also, it looks like you're checking the f1 table cell three times as the win condition. --Canley (talk) 07:10, 16 June 2015 (UTC)[reply]
The most obvious problem with your code is that you are checking for equality between an Element and a string. Instead of document.getElementById('f1') == 'x' you should retrieve the text string contained in the DOM element using document.getElementById('f1').innerHTML == 'x' (I haven't checked that this works). —Noiratsi (talk) 12:51, 16 June 2015 (UTC)[reply]
This is a common problem. There is no "trick" to it. You literally must check every possible win scenario. There are 8 possible win scenarios for X and 8 possible win scenarios for O. You also need to see if 9 moves have been made. If you have 9 moves and nobody wins, it is a draw. 209.149.113.240 (talk) 12:52, 16 June 2015 (UTC)[reply]
@Noiratsi:Thats funny I was just about to say the same thing and yes, your suggestion does work. I think that checking all possible combinations could be done by a for loop. Give me a few minutes and maybe I can come up with something to demonstrate. —SGA314 I am not available on weekends (talk) 12:57, 16 June 2015 (UTC)[reply]
In reply to 209.149.113.240, I can think of a few 'tricks', though maybe this isn't the kind of thing you meant. You could use a Magic Square, or perhaps XOR the moves made by each player in some way. —Noiratsi (talk) 13:06, 16 June 2015 (UTC)[reply]
Ok Got it! I used the principal of a magic square(with a little modification. Good idea Noiratsi):
Very long code
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>TIC TAC TOE</title>
<style>
td{
	height:100px;
	width:100px;
	font-size:70px;
	text-align:center;
}
</style>
<script>

var lastvalue;
var is_active;
var MoveCount;
MoveCount = 0;
function fun1(a)
{
  if (document.getElementById(a).innerHTML != 'x' && document.getElementById(a).innerHTML != 'o')
  {
    MoveCount += 1;
    if (MoveCount <= 9)
    {
      if (lastvalue == 'x')
      {
        document.getElementById(a).innerHTML = 'o';
        lastvalue = 'o';
        is_active = false;
      }
      else
      {
        document.getElementById(a).innerHTML = 'x';
        lastvalue = 'x';
       is_active = false;
      }

      //Check to see if X has won.
      checkX();

      //Check to see if O has won.
      checkO();

      if (MoveCount == 9)
      {
        MoveCount = 10
        alert('Game Over! Its a Tie!')
      }
    }
  }
}

function checkX()
{
  for (var i = 1; i < 10; i++)
  {
    for (var c = 1 + i; c < 10; c++)
    {
      for (var d = 1 + c; d < 10; d++)
      {
        //alert(document.getElementById('f' + i).innerHTML);
        if (document.getElementById('f' + i).innerHTML != null)
        {
          if (document.getElementById('f' + c).innerHTML != null)
          {
            if (document.getElementById('f' + d).innerHTML != null)
            {
              //Check X diag
              if (i == 1)
              {
                if (c == 5)
                {
                  if (d == 9)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'x')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'x')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'x')
                        {
                          alert('x won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Check X diag

              //Check X -Diag
              if (i == 3)
              {
                if (c == 5)
                {
                  if (d == 7)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'x')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'x')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'x')
                        {
                          alert('x won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Check X -Diag

              //Check X Horizontal
              //Line 1
              if (i == 1)
              {
                if (c == 2)
                {
                  if (d == 3)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'x')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'x')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'x')
                        {
                          alert('x won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Line 1

              //Line 2
              if (i == 4)
              {
                if (c == 5)
                {
                  if (d == 6)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'x')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'x')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'x')
                        {
                          alert('x won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Line 2

              //Line 3
              if (i == 7)
              {
                if (c == 8)
                {
                  if (d == 9)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'x')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'x')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'x')
                        {
                          alert('x won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Line 3
              //End Check X Horizontal

              //Check X Vertical
              //Column 1
              if (i == 1)
              {
                if (c == 4)
                {
                  if (d == 7)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'x')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'x')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'x')
                        {
                          alert('x won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Column 1

              //Column 2
              if (i == 2)
              {
                if (c == 5)
                {
                  if (d == 8)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'x')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'x')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'x')
                        {
                          alert('x won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Column 2

              //Column 3
              if (i == 3)
              {
                if (c == 6)
                {
                  if (d == 9)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'x')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'x')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'x')
                        {
                          alert('x won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Column 3
              //End Check X Vertical

            }
          }
        }
      }
    }
  }
}

function checkO()
{
  for (var i = 1; i < 10; i++)
  {
    for (var c = 1 + i; c < 10; c++)
    {
      for (var d = 1 + c; d < 10; d++)
      {
        //alert(document.getElementById('f' + i).innerHTML);
        if (document.getElementById('f' + i).innerHTML != null)
        {
          if (document.getElementById('f' + c).innerHTML != null)
          {
            if (document.getElementById('f' + d).innerHTML != null)
            {
              //Check O diag
              if (i == 1)
              {
                if (c == 5)
                {
                  if (d == 9)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'o')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'o')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'o')
                        {
                          alert('o won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Check O diag

              //Check O -Diag
              if (i == 3)
              {
                if (c == 5)
                {
                  if (d == 7)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'o')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'o')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'o')
                        {
                          alert('o won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Check O -Diag

              //Check O Horizontal
              //Line 1
              if (i == 1)
              {
                if (c == 2)
                {
                  if (d == 3)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'o')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'o')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'o')
                        {
                          alert('o won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Line 1

              //Line 2
              if (i == 4)
              {
                if (c == 5)
                {
                  if (d == 6)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'o')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'o')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'o')
                        {
                          alert('o won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Line 2

              //Line 3
              if (i == 7)
              {
                if (c == 8)
                {
                  if (d == 9)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'o')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'o')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'o')
                        {
                          alert('o won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Line 3
              //End Check O Horizontal

              //Check O Vertical
              //Column 1
              if (i == 1)
              {
                if (c == 4)
                {
                  if (d == 7)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'o')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'o')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'o')
                        {
                          alert('o won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Column 1

              //Column 2
              if (i == 2)
              {
                if (c == 5)
                {
                  if (d == 8)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'o')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'o')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'o')
                        {
                          alert('o won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Column 2

              //Column 3
              if (i == 3)
              {
                if (c == 6)
                {
                  if (d == 9)
                  {
                    if (document.getElementById('f' + i).innerHTML == 'o')
                    {
                      if (document.getElementById('f' + c).innerHTML == 'o')
                      {
                        if (document.getElementById('f' + d).innerHTML == 'o')
                        {
                          alert('o won');
                          MoveCount = 10;
                          return;
                        }
                      }
                    }
                  }
                }
              }
              //End Column 3
              //End Check O Vertical
            }
          }
        }
      }
    }
  }
}

function Reset()
{
  for (var i = 1; i < 10; i++)
  {
    document.getElementById('f' + i).innerHTML = ''
  }
  MoveCount = 0;
  lastvalue = 0;
}
 
</script>

<style>
  #ResetBtn {position: relative; right:-400px; bottom:-325px}
</style>
</head>

<body>
<h1 align="center">Tic Tac Toe</h1>
<table border="1px" align="center">
<tr><td id="f1" onClick="fun1('f1')"></td>

<td id="f2" onClick="fun1('f2')"></td>

<td id="f3" onClick="fun1('f3')"></td></tr>

<tr><td id="f4" onClick="fun1('f4')"></td>

<td id="f5" onClick="fun1('f5')"></td>

<td id="f6" onClick="fun1('f6')"></td></tr>

<tr><td id="f7" onClick="fun1('f7')"></td>

<td id="f8" onClick="fun1('f8')"></td>

<td id="f9" onClick="fun1('f9')"></td></tr>

<button onclick="Reset()" id="ResetBtn">Reset Board</button>

</table>
</body>
</html>
I know its a lot of code, but it works though. If you don't want to game to reset every time you win, just comment out the Reset(); line. Hope you like it. —SGA314 I am not available on weekends (talk) 15:32, 16 June 2015 (UTC)[reply]
Explanation: the Function checkX() checks to see if there is 3 Xs in either diagonal direction or in the Horizontal direction. It does this by means of 3 nested for loops, one for each x. The function first checks to see if the for loop variables i, c, and d are equal to 1, 5, and 9. Then if this returns true, the program will check if the squares 1, 5, and 9 have Xs in them. The reverse is done for the other diagonal direction. So instead of checking to see if the for loop variables are 1, 5, and 9, we check to see if the variables are 3, 5, and 7. After the program has check the diagonals, it moves on to the horizontal. The horizontal part checks if the variables c and d are equal to the previous variable + 1. Example:
 
if (i + 1 == c)
{
  if (c + 1 == d)
  {
    //do whatever
  }
}
This will work in either forward or reverse. Now for the Vertical, I just used the same setup as I did for the horizontal. Basicaly, I hard coded all the possible win scenarios. checkO() does the same thing as checkX() but checks for Os instead. —SGA314 I am not available on weekends (talk) 16:17, 16 June 2015 (UTC)[reply]
Looping over all possible values of i, c, d only to check whether they are one of 8 specific triples is pointless. Instead, remove the loop and just assign the eight triples in turn. Or just substitute the values into the code and do away with the variables entirely. That makes the code much shorter, but it's still very long because you're still checking each of the 16 winning conditions separately.
I think what Noiratsi had in mind was to look up the Lo Shu values of each cell and see if they sum to 15, like this:
function check(xo) {
    var get = function(pos) {
        return document.getElementById('f' + pos).innerHTML;
    }
    var loshu = [undefined, 4, 9, 2, 3, 5, 7, 8, 1, 6];
    for (var i = 1; i <= 7; ++i)
        for (var j = i + 1; j <= 8; ++j)
            for (var k = j + 1; k <= 9; ++k)
                if (loshu[i] + loshu[j] + loshu[k] === 15) && xo === get(i) && xo === get(j) && xo === get(k))
                    return true;
    return false;
}
There are other ways to check whether a combination of three squares is a winning combination, but however you do it, the important thing is to collapse the 16 cases into one, and avoid copy and paste programming. -- BenRG (talk) 20:48, 16 June 2015 (UTC)[reply]

I thought of a neat trick: Regular expressions. Unless I've made a mistake, the expression /(^(...){0,2}x{3}(...){0,2}$)|((x..){2}x)|((x...){2}x)|(..(x.){3})/ matches all winning configurations for 'x', given a string of cells like 'xoxxxxxox'. I used jQuery to iterate over the cells in the table and turn them into a string like that.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>TIC TAC TOE</title>
<style>
td {
	height:100px;
	width:100px;
	font-size:70px;
	text-align:center;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> 
<script>
var turn = 0, TOKENS = ['x','o'], table;

$(function(){
    (table = $('#ttt')).find("td").click(function(){
        if (!$(this).text()) $(this).text(TOKENS[1 - (turn = 1 - turn)]);
        for (player in [0,1]) {
            if (cellvalues().match(new RegExp("(^(...){0,2}"+TOKENS[player]+"{3}(...){0,2}$)|(("+TOKENS[player]+"..){2}"+TOKENS[player]+")
|(("+TOKENS[player]+"...){2}"+TOKENS[player]+")|(..("+TOKENS[player]+".){3})"))) alert(TOKENS[player]+" wins");
        }  
    });
});

function cellvalues() {
    var text = '';
    table.find("td").each(function() {text += ($(this).text()?$(this).text():'#')});
    return text;
}
</script>
</head>
<body>
<table border=1 id="ttt">
    <tr><td></td><td></td><td></td></tr>
    <tr><td></td><td></td><td></td></tr>
    <tr><td></td><td></td><td></td></tr>
</table>
</body>
</html>

Noiratsi (talk) 17:17, 16 June 2015 (UTC)[reply]

I came up with a way to get the values without Jquery. And for some reason, I keep getting an error that $ is not defined. I am using firefox and I have a felling that this is related to Regular expressions. —SGA314 I am not available on weekends (talk) 17:45, 16 June 2015 (UTC)[reply]
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>TIC TAC TOE</title>
<style>
td {
	height:100px;
	width:100px;
	font-size:70px;
	text-align:center;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> 
<script>
var turn = 0, TOKENS = ['x','o'], table;

$(function(){
    (table = $('#ttt')).find("td").click(function(){
        if (!$(this).text()) $(this).text(TOKENS[1 - (turn = 1 - turn)]);
        for (player in [0,1]) {
            if (cellvalues().match(new RegExp("(^(...){0,2}"+TOKENS[player]+"{3}(...){0,2}$)|(("+TOKENS[player]+"..){2}"+TOKENS[player]+")
|(("+TOKENS[player]+"...){2}"+TOKENS[player]+")|(..("+TOKENS[player]+".){3})"))) alert(TOKENS[player]+" wins");
        }  
    });
});

function cellvalues() {
    var text = '';
    for (var i = 1; i < 10; i++)
    {
      text += document.getElementById('f' + i).innerHTML
    }
    //table.find("td").each(function() {text += ($(this).text()?$(this).text():'#')});
    return text;
}
</script>
</head>
<body>
<table border="1px" id = "ttt">
<tr><td id="f1" onClick="fun1('f1')"></td><td id="f2" onClick="fun1('f2')"></td><td id="f3" onClick="fun1('f3')"></td></tr>
<tr><td id="f4" onClick="fun1('f4')"></td><td id="f5" onClick="fun1('f5')"></td><td id="f6" onClick="fun1('f6')"></td></tr>
<tr><td id="f7" onClick="fun1('f7')"></td><td id="f8" onClick="fun1('f8')"></td><td id="f9" onClick="fun1('f9')"></td></tr>
</table>
</body>
</html>
Ok here is a good question. using my method(using the table with the onclick cells) how would you draw a strike through line that tells you who won? Look at this image to see what I am talking about: Tictactoe-X.svgSGA314 I am not available on weekends (talk) 19:44, 16 June 2015 (UTC)[reply]
OH...GOOD...GRIEF - the code shown above is abysmal! Use data structures people!
  • Label your squares 0..8...store the board as a 1 dimensional array:
 board [ 9 ] 
  • Use 0 to represent an empty square, +1 for an 'X' and -1 for a 'O'. Note that you can add up the the numbers in any line - and +3 represents a victory for X, -3 for O. This is a very handy property!
  • Build a (constant) hard-coded 2D array with one row for each line on the board (3 vertical, 3 horizontal and 2 diagonals). Each row contains the numbers of the three squares that make up that line.
 lines [ 8 ] [ 3 ] = {
  { 0, 1, 2 },  // Horizontal lines
  { 3, 4, 5 },
  { 6, 7, 8 },
  { 0, 3, 6 },  // Vertical lines
  { 1, 4, 7 },
  { 2, 5, 8 },
  { 0, 4, 8 },  // Diagonals
  { 2, 4, 6 } } ;
  • Now, to see if someone won:
  for ( i = 0 ; i < 8 ; i++ ) // Search each of the 8 lines.
  {
    var total = board[lines[i][0]] + board[lines[i][1]] + board[lines[i][2]] ;
    if ( total ==  3 ) { ...X wins!... ; break ; }
    if ( total == -3 ) { ...O wins!... ; break ; }
  }
Easy, 16 lines of code and just one for loop to test for victory.
Just like everything else in computer science, it's just a matter of getting the right data structures.
Having that array of lines makes generating computer strategy easy too.
WORTHWHILE EFFORT: Try doing the game on a three-dimensional board with 4x4x4 cells. It's hard to play and turns the game into a serious challenge. SteveBaker (talk) 02:54, 17 June 2015 (UTC)[reply]
@SteveBaker: I like your idea using 1 array to store the cells and another to identify the 'lines', that's a neat way to find the winner. It also begins to answer SGA314's last question about drawing the strikethrough line to identify the winning move. Please, there is no call to be rude to others who have volunteered their time to try and help answer this question. Much of the code offered in answers to this question is functional and even imaginative. Constructive criticisms might still be welcome; comments like "OH...GOOD...GRIEF - the code shown above is abysmal!"—in bold all caps, no less—are certainly not. As to the criticism itself, I would still contend that my code is a neat solution to the problem the OP was trying to solve, which was to identify winning configurations given an HTML document containing a filled tic-tac-toe board. I agree that, given the large difference between my code and the original, there wasn't much reason not to go all out and separate the data from the view. On the other hand, it's possible that might have been less helpful or comprehensible as an answer to the OP's question. —Noiratsi (talk) 07:09, 17 June 2015 (UTC)[reply]
@SteveBaker: The lines array won't work. I put it in the code and it just keeps giving me an error saying "SyntaxError: missing ; before statement." How do I fix this? Here is the code:
const lines [ 8 ]  [ 3 ]: = {
  { 0, 1, 2 },  // Horizontal lines
  { 3, 4, 5 },
  { 6, 7, 8 },
  { 0, 3, 6 },  // Vertical lines
  { 1, 4, 7 },
  { 2, 5, 8 },
  { 0, 4, 8 },  // Diagonals
  { 2, 4, 6 } } ;
Notes: I put the : after the [ 3 ] because it gave me an error other wise and I added the const to the beginning to make it a constant. —SGA314 I am not available on weekends (talk) 13:34, 17 June 2015 (UTC)[reply]
Ah Ha! Fixed it. Just deleted the [ 8 ] [ 3 ]: = from the line delcration and replaced the { and the } with [ and ]. I also had to increase all the values by 1. This is because the OP's method had a start number of 1, not 0.
var lines;
lines = 
  [[ 1, 2, 3],  // Horizontal lines
  [ 4, 5, 6 ],
  [ 7, 8, 9 ],
  [ 1, 4, 7 ],  // Vertical lines
  [ 2, 5, 8 ],
  [ 3, 6, 9 ],
  [ 1, 5, 9 ],  // Diagonals
  [ 3, 5, 7 ]] ;

SGA314 I am not available on weekends (talk) 15:27, 17 June 2015 (UTC)[reply]

Sorry - I'm a C++ guy, I was trying to sketch out an algorithm rather than deliver functional code...I leave that as "an exercise for the reader".
I originally wrote something like this for a 4x4x4 3DTicTacToe player. In that case, there are 16 vertical lines, 16 north-south lines, 16 east-west lines, 24 axis-aligned diagonals and 4 diagonal-diagonals - so writing code the long way is tough and speed starts to really matter when searching the board for places to play, etc. Also in my code (which has an "AI" computer player) - the lines array is critical in evaluating where the best place to play is. In the 3x3 case where the computer is playing 'X', the computer's strategy looks something like this:
  1. If any line sums to +2 then play in the empty slot and declare victory.
  2. If any line sums to -2 then play in the empty slot to prevent the other guy from winning.
  3. If two or more lines have just one 'O' in them and share a square that's empty, then play into that square to avoid being 'forked'.
  4. If one or more lines have just one 'X' in them then play at the square that's shared by the most of those lines.
  5. If one or more lines are completely empty, play at the square that's shared by most of those lines.
  6. Play in any empty square.
If there are multiple candidates at any of those stages, pick one of them at random to avoid being predictable.
Extending this to a 4x4x4 board is relatively painless, but you can see that using the brute-force "gazillions of for-loops" approach to doing this would rapidly become untenable.
SteveBaker (talk) 16:45, 17 June 2015 (UTC)[reply]
You can download my C++ code for the 4x4x4 TTT player here: http://sjbaker.org/steve/toys/ttt3d.html SteveBaker (talk) 17:04, 17 June 2015 (UTC)[reply]
I came up with an AI strategy based on your lines array idea. The AI works like this(The AI is O so just switch the - and +2 in the first two rules):
  1. AI follows your first rule.
  2. AI follows your second rule.
  3. If The first 2 rules haven't happened, pick at random one of the possible winning combinations from your list then place an O at on a random square in the selected winning combination.
  4. If X has eliminated all possible winning combinations, then pick at random an empty square and play on it.
My strategy is basically the same as yours(I came up with this before I read your post) but with some small differences. In a little while I am going to implement this AI into my implementation of your idea. Can't wait to take a look at your code. —SGA314 I am not available on weekends (talk) 17:25, 17 June 2015 (UTC)[reply]
For the 3x3 game, it hardly matters - even little kids can turn a game into a draw almost every time. In the 4x4x4 game, it's always possible for the first player to win - so it's not so simple! But even in the 3x3 game there is one subtle trick that can possibly let you win - which is to try to make a 'fork' situation where you create two lines with just two X's in them with a single move. If you can do that then your opponent can't block both of them - so you can win. If this is ever going to work, you need to do it subtly. My list of strategies is good at making situations where forks are likely and exploiting them. I think I could actually beat your algorithm on a 3x3 board some of the time by creating a fork situation that it would be unable to recognize until too late. Look at this game - human plays 'X':
 ___|_X_|___
 ___|___|___
    |   | 
 ___|_X_|___
 ___|_O_|___  <== Oooh!  He let me grab the middle square!
    |   | 
 ___|_X_|___
 _X_|_O_|___
    |   | 
 ___|_X_|___
 _X_|_O_|___
    |   | O   <== This dumb move lost O the game.
                  Any of the other three corners is OK.
                  But you're picking at random, so this will happen 25% of the time.
 _X_|_X_|___
 _X_|_O_|___
    |   | O
X wins no matter how O plays.
So what in your algorithm would stop it from screwing up that way if it's playing as 'O'? And, much more subtly...what would help it to try to make this happen if it's playing as 'X' against an un-cautious human?
SteveBaker (talk) 18:41, 17 June 2015 (UTC)[reply]
Good point. I can code all possible forks that could happen and check if the human player is starting to fork. What I could do is after the first 2 moves in your game, I could use a basic version of lookup tables to be able to recognize this situation and place my O in the upper left hand corner and stop the human from making a fork. Thanks for the advice, I never though of it that way. —SGA314 I am not available on weekends (talk) 19:15, 17 June 2015 (UTC)[reply]
You are correct. Tac-Tac-Toe is a "solved" game. Every possible iteration has been mapped out in a big tree. You can do the same. The tree isn't as big as you might think. If you defined every possible board as a 9-character string (one way to do it that is easy for humans to read), each node would have a label like "xx xo o". Each node would also have a status of only five possibilities: x moves next, o moves next, x wins, y wins, draw. I think you would be rather surprised how quickly you can build this state tree and easy it would be to use it. However, you remove any form of AI from the programming as all you will do is pick a move that has the highest number of leaf nodes that end in a win. 199.15.144.250 (talk) 15:29, 19 June 2015 (UTC)[reply]

What is Asynchronous (Javascript)?[edit]

What does the word "Asynchronous" means in this context? Please give the simplest explanation possible, I am a total Rookie in JS. Ben-Yeudith (talk) 15:06, 16 June 2015 (UTC)[reply]

Asynchronous is a term used to mean to run something in a another thread or precess. This is a term frequently used in mutlithreaded programming. —SGA314 I am not available on weekends (talk) 15:45, 16 June 2015 (UTC)[reply]
To be more precise... Asynchronous, in this context, refers to processing order. It is common to write a Javascript function as a single, highly ordered, procedure. It is commonly called procedural programming. It is also common to write Javascript in what Java programmers like to call an event-based or trigger-based manner. As such, you do not know the exact order that the set of functions will use. A very very simple example that I show students is to write a function that sends out 10 alert functions with a timeout, each with a 10 second timeout. Each one says, "I am X" with X being replaced with the numbers 0 through 9. I call them in order from 0 to 9, but they are all called in under a millisecond. So, technically, the computer sets the timeout for all them to be the same millisecond - ten seconds in the future. When that time comes, I get the first alert (most browsers cache alerts, making you clear one to see the next). Does the first one say "I am 0"? Not always. This is asynchronous. It could easily say "I am 5" followed by "I am 3" followed by "I am 8". To get really get into what is happening, you have to look at multithreading, which is what SGA314 was talking about. 209.149.113.240 (talk) 16:20, 16 June 2015 (UTC)[reply]
Wow that sounds fascinating. —SGA314 I am not available on weekends (talk) 17:22, 16 June 2015 (UTC)[reply]
I'd say that for functions, "asynchronous" quite simply is the opposite of "blocking", and for events, asynchronous means that they may occur at any place in the program. a non-blocking "read bytes" function is asynchronous, because it returns immediately and a user-defined callback function is called when data is available. the callback function itself may or may not be synchronous. it is, if it can be called by the system at any time (like an ISR can.) it is not, if the program dispatches callback calls by polling a message queue. similarly, keypresses are asynchronous at the most basic level (the computer doesn't know when the user decides to flex his/her finger to press a key (actually, the user himself doesn't, lol)), but if the program receives keypresses by polling a message queue, this is synchronous because it happens at a specific place in the program (inside the message loop, and usually in order.) Asmrulz (talk) 18:27, 16 June 2015 (UTC)[reply]
Most of JS is single-threaded and the bits of it that are asynchronous are simulated by a message loop mechanism somewhere deep inside the JS engine. This also means that, unlike in "true" concurrency (with interrupts, preemption, hardware parallelity etc), it would take the engine extra steps to interleave data in a random manner. thus, code like setTimeout(f, 1000); setTimeout(g, 1000); setTimeout(h, 1000), the functions f,g, and h will ideally be called in that order, but don't count on it. Asmrulz (talk) 18:52, 16 June 2015 (UTC)[reply]
Asynchronous I/O is the article. -- BenRG (talk) 20:59, 16 June 2015 (UTC)[reply]
I have a feeling that asynchronous I/O will confuse the issue. It appears to me that the question is about asynchronous programming. Asynchronous I/O is related in the fact that messages are not sent and received in order. Therefore, the program needs to expect out-of-order (or completely lost or randomly repeated) messages. I can write a highly ordered procedural program that uses asynchronous I/O (Asmrulz noted the evil polling method). It is likely due to years of teaching, but I avoid giving every bit of the answer that I can possibly think of. Instead, I just want to get the questioner a step past the current stopping point. 209.149.113.240 (talk) 15:13, 17 June 2015 (UTC)[reply]

☀️[edit]

I just encountered the ☀️ character. Even the most obscure normal characters get some links, e.g. Special:WhatLinksHere/🌞 is linked by Miscellaneous Symbols and Pictographs, Emoji, and {{Unicode chart Miscellaneous Symbols and Pictographs}}, but Special:WhatLinksHere/☀️ shows absolutely nothing. What kind of character is it? Nyttend (talk) 20:19, 16 June 2015 (UTC)[reply]

It's U+2600, which Miscellaneous Symbols notes is called "Black sun with rays" -- Finlay McWalterTalk 20:23, 16 June 2015 (UTC)[reply]
does exist, as a redirect to Solar symbol. More specifically it is "Black Sun With Rays". Your text also includes an invisible character, Variation Selector 16, which is why your link doesn't work. You can see it percent-encoded in the URL: Special:WhatLinksHere/%E2%98%80%EF%B8%8F. "%E2%98%80" is the solar symbol, %EF%B8%8F is the VS-16, which indicates the emoji variant of the symbol should be used, though not all browsers support that. Mr.Z-man 20:37, 16 June 2015 (UTC)[reply]
Weird. How is it that the single character ☀️ and the single character ☀ can be different? If I use the arrow keys to move through the sentence, it treats both like a single character; it's not like ☀​, the sun character followed by a zero-width space, which the arrow key notices and creates the appearance of going nowhere when you move past the zero-width space. Nyttend (talk) 22:17, 16 June 2015 (UTC)[reply]
They are both a single character. One is represented by two code points, but that's not unusual, and most editors will skip over whole characters as a unit even if they're more than one code point long. Whether they are the same character or two different characters is a tricky question. Unicode equivalence may be relevant. Apparently, none of the Unicode normalization algorithms delete variation selectors, so they are not even compatible characters as far as the standard is concerned, though it seems like they should be. -- BenRG (talk) 00:13, 17 June 2015 (UTC)[reply]
On my (work) computer, the second code point shows up as a box - in the same way as all unrecognised characters. Which made this conversation rather confusing! MChesterMC (talk) 08:27, 17 June 2015 (UTC)[reply]
Let it be made clear: to view these special characters correctly, your user agent (web browser, or whatever other software and hardware you use to view Wikipedia) must support modern Unicode and must supply a default font that will render these code points. Loosely speaking, this means a recent iOS, OS X, Windows, or Android system. Some Linux front-ends will correctly display Unicode but by default you might not have a font which can render these glyphs.
For example, if you view these characters on an Apple device running iOS 8 or iOS 9, the Unicode "Black Sun with Rays" will render as a colorful picture of a yellow sun with rays (and variant form codepoints are not evaluated). If you feel that this colorful glyph flagrantly violates the spirit of adherence to the Unicode standard, please file a bug report! (Conversely, if you feel that the Unicode standards committee was out of line by specifying glyph rendering instructions in a code point definition, please email them!) Nimur (talk) 14:48, 17 June 2015 (UTC)[reply]
Ha! Of all the problems in the world today, the level of control that code point definitions should have over rendering should not be ignored! I'm pretty sure I know how Donald Knuth would have responded - keep presentation and content separate, or suffer the consequences! But do you know of any other good discussions of the topic as it pertains to unicode and font rendering? I'm still a little conflicted myself, so I'd like to be more informed before I lodge a complaint one way or the other. But I think we can agree that the situation as it stands is not good. Sure, today it might just be somebody's emoji-laden love letter that gets misinterpreted, but this issue could creep in to other important character definitions and renderings, like '💩' - and I don't think I could tolerate that ;) SemanticMantis (talk) 14:17, 18 June 2015 (UTC)[reply]
Yes, this has been an active area of official standardization, and there is a lot of accompanying documentation:
It seems, whether this is a good idea or not, that this is happening, and it is already standardized. Unicode will specify rendering instructions, and perhaps some day will even provide a technical means to standardize embedded raster graphics in character streams.
There are some profound linguistic/semantic/philosophical issues at stake here (and documented in these Unicode Consortium reports): for example, should an emoji code-point specify gender? Should rendering instructions be provided to explicitly specify neutral gender? Overly-specific instructions might entail semantic problems in languages where these details do matter. Overly-vague instructions may allow the very same stream of characters to have completely different semantic meanings when rendered by two different operating systems. It is a conundrum.
Probably the most obvious way to make this problem apparent to the lay-person: " ☀️" and "☀" render differently on OS X, and render identically on iOS. Suppose an iMessage crosses the bounds between these operating systems? Semantic meaning in a message has been lost because of the way the Unicode standard interplays with the default font! And these are minor details are on systems produced by the same company. What will this entail when we start using emoji for important communication?
Nimur (talk) 17:00, 18 June 2015 (UTC)[reply]