# 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->getGame()->setMovesTillNow();
}

\$board->display();
}

//if move is valid, add the move to the player's list of moves
{
\$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 makeMove(Board board, Move move)
{
move = board.checkAvailable(move);

char mark = this.getPlayerMark();

board.markCell(move, mark);

if(move.isIsValid())
{
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;

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;

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;

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 makeMove(Board board, Move move)
{
move = board.checkAvailable(move);

char mark = this.getPlayerMark();

board.markCell(move, mark);

if (move.isIsValid())
{
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;

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;

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: ");

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: ");

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);

}

}
}```

Copy, Compile, Run and ENJOY!