1

I am having trouble trying to alert the winner, among other things. I also am trying to alert when the user trys to click on a button that has already been pressed, but have no idea what I am doing in that regard either. All help is appreciated. Thank you guys.

<table>
        <tr>
            <td id="00" onclick="makeMove(0,0)">00</td>
            <td id ="01" onclick="makeMove(0,1)">01</td>
            <td id ="02" onclick="makeMove(0,2)">02</td>
        </tr>
        <tr>
            <td id ="10" onclick="makeMove(1,0)">10</td>
            <td id ="11" onclick="makeMove(1,1)">11</td>
            <td id ="12" onclick="makeMove(1,2)">12</td>
        </tr>
        <tr>
            <td id ="20" onclick="makeMove(2,0)">20</td>
            <td id ="21" onclick="makeMove(2,1)">21</td>
            <td id ="22" onclick="makeMove(2,2)">22</td>     
 </tr>
    </table>

    <hr>
    <input id="myMoveButton" type="submit">

    <script src="java.js"></script>

Javascript:

// -1 means 0's turn
// 1 means X's turn

// AFTER EVERY MOVE
// UNTIL GAME OVER
// THIS NEEDS TO BE FLIPPED
// IF IT WAS 1, now it will be -1 and vice versa

var turn = 1;

// 0 means no move has been made yet 
// on that particular square
var grid = [
    [0, 0 ,0],
    [0, 0 ,0],
    [0, 0, 0]
];


function makeMove(row, column) {

    if (grid [row][column] == 0) {
        grid[row][column] = turn;

        var idOfSquareToChange = row +"" + column;

        if (turn == 1) {

            $("#"+idOfSquareToChange).html('X');
        }else {
            $("#"+idOfSquareToChange).html('O');
        }

        // CHECK IF GAME IS OVER

        // IF GAME ISN'T OVER   
        if (turn == 1) {
            turn = -1;
        }else {
            turn = 1;
        }
        printGrid();
    }else {
        alert('That square has been chosen');
    }
}

function printGrid(){

    var board = grid[0][0] + " " + grid [0][1] + " " + grid[0][2];
    board += "\n";
    board += grid[1][0] + " " + grid [1][1] + " " + grid[1][2];
    board += "\n";
    board += grid[2][0] + " " + grid [2][1] + " " + grid[2][2];

    alert(board);
}

function isGameOver() {
    // HERE IS WHERE OUR LOGIC WOULD GO
    // TO SEE IF SOMEONE won

}
  • `grid[row][column] = turn;` should probably go at the end as per expected logic? – sabithpocker Dec 02 '15 at 04:45
  • after the gameover function? Do you mind showing in JsFiddle? @sabithpocker – JavaScriptRookie Dec 02 '15 at 04:49
  • https://jsfiddle.net/dL3mkb6x/ in fiddle it works fine for me :) if I choose already selected field it shows the alert. Looks good. – sabithpocker Dec 02 '15 at 04:54
  • @sabithpocker yes the same button alert works! I don't know how to alert the winner, though. Also I don't know how to make the tic tac toe board look normal (like a grid, rather than numbers). Can you assist me in alerting a winner? – JavaScriptRookie Dec 02 '15 at 04:59
  • You will have to code that yourself, check this answer http://stackoverflow.com/a/1056352/427146 – sabithpocker Dec 02 '15 at 05:04
  • I just can't get it to work man. @sabithpocker I don't know where to put the grid row column, and the alert works in JsFiddle, but not in the browser. – JavaScriptRookie Dec 02 '15 at 06:12

2 Answers2

3

This is what i came up with:

function isGameOver() {
  for (var i = 0; i < grid.length; i++) {

      if(grid[i][0] == grid[i][1] && grid[i][0]==grid[i][2] && grid[i][0]!=0){
        alert(grid[i][0]+" Wins");
        _win=1;
        return;
      }
  }
  for (var i = 0; i < grid.length; i++) {

      if(grid[0][i] == grid[1][i] && grid[0][i]==grid[2][i]  && grid[0][i]!=0){
        alert(grid[0][i]+" Wins");
        _win=1;
        return;
      }
  }

  if(grid[0][0]==grid[1][1] && grid[0][0] == grid[2][2]  && grid[0][0]!=0){
    alert(grid[0][0]+" Wins");
    _win=1;
        return;
  }

  if(grid[0][2]==grid[1][1] && grid[0][2] == grid[2][0]  && grid[2][0]!=0){
    alert(grid[1][1]+" Wins");
    _win=1;
        return;
  }

}

Working fiddle

This will check whether data in a single column or in a single row or in diagonals should be same. And if a user wins then he can not click on anything else.

void
  • 36,090
  • 8
  • 62
  • 107
  • That was awesome, however, my alerts still only work in JsFiddle, and not in the browser. Do you know why this might be happening? I know that it runs from the top down and I have tried moving the code around. – JavaScriptRookie Dec 02 '15 at 07:04
  • Probably wrong placement of Javascript code. If it solves your problem can you please consider vting it up and marking it as the correct answer. – void Dec 03 '15 at 06:27
0

By using lodash, you can abstract a bunch of the pieces of this. I went ahead and re-coded it to show you how I'd do it. This will allow you to make the board whatever size you want and allow for up to 4 players.

enter image description here

Here's a jsfiddle:

https://jsfiddle.net/mckinleymedia/gqqse6cw/18/

Here's all the HTML you need:

<div class="gameboard"></div>

Here's the script:

var game = function( options ){
  options = options || [];
  var target = options.target || '.gameboard',
      size = options.size || [ 3, 3 ],
      players = options.players || 2,
      toWin = options.toWin || 3,
      symbols = [ 'o', 'x', '+', '!' ],
      current,
      grid,
      setup = function ( ) {
        $(target).empty();
        current = 0;
        grid = [];
        _.each(_.range(size[0]), function(r) {
          var row = $('<div>')
          .addClass('row');
          grid.push([]),
            _.each(_.range(size[1]), function(c) {
            grid[r].push(undefined),
              row.append( 
              $('<button>')
              .addClass('square open')
              .attr('data-pos',r + ',' + c)
              .html('&nbsp;')
            );
          })
          $(target).append(row );
        });
        $(target).append(
          $('<div>')
          .addClass('player')
          .append(
            $('<span>')
            .html('Player')
          )
          .append(
            $('<span>')
            .addClass('symbol')
            .html(symbols[0])
          )
        );
        $('.square').click( function(){ 
          if (!($(this).hasClass('disabled'))) makeMove(this) 
            });
      },
      makeMove = function (btn) {
        var btn = $(btn)
        .addClass('disabled')
        .html(symbols[current]),
            pos = btn.attr('data-pos').split(',');
        grid[pos[0]][pos[1]] = current;
        checkBoard();
      },
      checkBoard = function () {
        var winners = [];
        checkArray()
        winners = checkArray(grid,winners); // check rows
        winners = checkArray(_.zip.apply(_, grid) ,winners,'vert'); // check columns
        var diag = [],
            diagReverse = [],
            i = 0,
            di = 0,
            map = [],
            mapR = [];
        _.each(grid, function(g, gk){
          _.each(g, function(cell, ck){
            di = ck + i;
            diag[di] = diag[di] || [];
            diagReverse[di] = diagReverse[di] || [];
            map[di] = map[di] || [];
            mapR[di] = mapR[di] || [];
            diag[di].push(grid[gk][ck]);
            diagReverse[di].push( grid[ grid.length - gk - 1 ][ ck ]
                                );
            map[di].push([gk,ck]);
            mapR[di].push([(grid.length - gk - 1), ck]);
          });
          i++;
        });
        winners = checkArray(diag ,winners, map); // check diagonal
        winners = checkArray(diagReverse ,winners, mapR); // check reverse diagonal
        if ( winners.length > 0 ) playerWin(winners);
        current++;
        current = current % players;
        $(target + ' .symbol')
          .html(symbols[current]);      
      },
      checkArray = function (arr,winners,map) {
        map = map || 0;
        var winner = [],
            setRow = [],
            count = 0,
            cur = -1;
        _.each(arr, function(g, key){
          count = 0;
          _.each(g, function(cell, ckey){
            if (cell===undefined || cell !== cur) {
              count = 0;
              setRow = [];
            }
            cur = cell;
            count++;
            if (map) {
              if ( map === 'vert'){
                setRow.push([ckey,key]);
              } else if ( _.isArray(map)) {
                setRow.push([map[key][ckey]]);
              }
            } else {
              setRow.push([key,ckey]);
            }
            if (count >= toWin) winner = winner.concat(setRow);
          });
        });
        if ( winner.length > 0 ) winners = winners.concat(winner);
        return winners;
      },
      playerWin = function (winners) {
        $('.gameboard button')
          .addClass('disabled');
        _.each(winners, function(w){
          $('.gameboard button[data-pos="' + w.join() + '"]')
            .addClass('win');
        });
        $(target).append(
          $('<div>')
          .addClass('winner')
          .append(
            $('<h1>')
            .html('Congratulations, player ' + symbols[current] + '!')
          )
          .append(
            $('<button>')
            .addClass('replay')
            .html('Play Again?')
          )
        );
        $('.replay').click ( function(){
          setup();
        });
      };
  setup();
}
game();