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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class Player
{
	private $playerNum;  //player 1 or 2
	private $playerMark; // '0' or 'X'
	private $winnerOrLoser;
	private $moves = array(); //list of moves made by player
	private $g; //the game being played
 
	//getters and setters
	public function setPlayerNum($num)
	{
		$this->playerNum = $num;
	}
 
	public function setPlayerMark($mark)
	{
		$this->playerMark = $mark;
	}
 
	public function setPlayerWinnerLoser($winnerOrLoser)
	{
		$this->winnerOrLoser = $winnerOrLoser;
	}
 
	public function getPlayerNum()
	{
		return $this->playerNum;
	}
 
	public function getPlayerMark()
	{
		return $this->playerMark;
	}
 
	public function getPlayerWinLose()
	{
		return $this->winnerOrLoser;
	}
 
	public function getPlayerMoves()
	{
		return $this->moves;
	}
 
	//the player can put x or 0 by choosing the cell (row and column)
	public function makeMove($board, $move)
	{
		$move = $board->checkAvailable($move);
 
		$mark = $this->getPlayerMark();
		$board->markCell($move, $mark);
 
		if($move->getValid())
		{	
			$this->addMove($move);
 
			$this->getGame()->setMovesTillNow();
		}
 
		$board->display();
	}
 
	//if move is valid, add the move to the player's list of moves
	public function addMove($move)
	{
		$this->moves[] = $move;
	}
 
	public function setGame($game)
	{
		$this->g = $game;
 
	}
 
	public function getGame()
	{
		return $this->g;
	}
}

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

Game:

The game being played.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
 
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package com.tictactoe.components;
 
import java.util.ArrayList;
/**
 *
 * @author pratyush
 */
public class Player {
 
    private int playerNum;
    private char playerMark;
    private int winnerOrLoser;
    private Game g;
 
    private ArrayList<Move> moves = new ArrayList<Move>();
 
    public int getPlayerNum() {
        return playerNum;
    }
 
    public void setPlayerNum(int playerNum) {
        this.playerNum = playerNum;
    }
 
    public char getPlayerMark() {
        return playerMark;
    }
 
    public void setPlayerMark(char playerMark) {
        this.playerMark = playerMark;
    }
 
    public int getWinnerOrLoser() {
        return winnerOrLoser;
    }
 
    public void setWinnerOrLoser(int winnerOrLoser) {
        this.winnerOrLoser = winnerOrLoser;
    }
 
    public Game getGame() {
        return g;
    }
 
    public void setGame(Game g) {
        this.g = g;
    }
 
    public ArrayList getMoves() {
        return moves;
    }
 
    public void addMove(Move move) {
 
        this.moves.add(move);
    }
 
    public void makeMove(Board board, Move move)
    {
        move = board.checkAvailable(move);
 
        char mark = this.getPlayerMark();
 
        board.markCell(move, mark);
 
        if(move.isIsValid())
        {
            this.addMove(move);
            Game.setMovesTillNow();
        }
 
        board.display();
    }
 
}

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

Game:

The game being played.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace TicTacToeDotNet
{
    public class Move
    {
 
        private int row, column;
        private bool isValid;
 
        public int getRow()
        {
            return row;
        }
 
        public void setRow(int row)
        {
            this.row = row;
        }
 
        public int getColumn()
        {
            return column;
        }
 
        public void setColumn(int column)
        {
            this.column = column;
        }
 
        public bool isIsValid()
        {
            return isValid;
        }
 
        public void setIsValid(bool isValid)
        {
            this.isValid = isValid;
        }
 
    }
}

Then comes the Board class where the moves are made.

Board:

The board on which the game is played.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace TicTacToeDotNet
{
    public class Board
    {
 
        private static char[][] cells;
 
        public Board()
        {
            cells = new char[3][];
 
            cells[0] = new char[] { ' ', ' ', ' ' };
 
            cells[1] = new char[] { ' ', ' ', ' ' };
 
            cells[2] = new char[] { ' ', ' ', ' ' };
        }
 
 
        public void display()
        {
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++) { 
 
                     if (cells[i][j] == ' ') { 
 
                          Console.Write((i + 1) + ", " + (j + 1) + "\t"); 
 
                      } else { 
 
                           Console.Write(cells[i][j] + "\t"); 
 
                      } 
 
                  } Console.Write("\n\n"); 
 
            } 
 
      } 
 
      public Move checkAvailable(Move move) { 
 
            int i = move.getRow(); 
 
            int j = move.getColumn(); 
 
            bool boundValid = ((i >= 1 && i <= 3) && (j >= 1 && j <= 3));
 
            bool charValid = false;
 
            if (boundValid)
            {
                charValid = (cells[i - 1][j - 1] == ' ');
            }
 
            bool netValid = (boundValid && charValid);
 
            move.setIsValid(netValid);
 
            return move;
        }
 
        public void markCell(Move move, char mark)
        {
            if (move.isIsValid())
            {
                int i = move.getRow();
 
                int j = move.getColumn();
 
                cells[i - 1][j - 1] = mark;
            }
            else
            {
                Console.Write("INVALID MOVE!\n\n");
            }
        }
 
    }
 
}

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

Player:

Either of the two players.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace TicTacToeDotNet
{
    public class Player
    {
 
        private int playerNum;
        private char playerMark;
        private int winnerOrLoser;
        private Game g;
 
        private List moves = new List();
 
        public int getPlayerNum()
        {
            return playerNum;
        }
 
        public void setPlayerNum(int playerNum)
        {
            this.playerNum = playerNum;
        }
 
        public char getPlayerMark()
        {
            return playerMark;
        }
 
        public void setPlayerMark(char playerMark)
        {
            this.playerMark = playerMark;
        }
 
        public int getWinnerOrLoser()
        {
            return winnerOrLoser;
        }
 
        public void setWinnerOrLoser(int winnerOrLoser)
        {
            this.winnerOrLoser = winnerOrLoser;
        }
 
        public Game getGame()
        {
            return g;
        }
 
        public void setGame(Game g)
        {
            this.g = g;
        }
 
        public List getMoves()
        {
            return moves;
        }
 
        public void addMove(Move move)
        {
 
            this.moves.Add(move);
        }
 
        public void makeMove(Board board, Move move)
        {
            move = board.checkAvailable(move);
 
            char mark = this.getPlayerMark();
 
            board.markCell(move, mark);
 
            if (move.isIsValid())
            {
                this.addMove(move);
                Game.setMovesTillNow();
            }
 
            board.display();
        }
 
    }
}

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

Game:

The game being played.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace TicTacToeDotNet
{
    public class Game
    {
 
        private int whoseTurn;
        private static int movesTillNow = 0;
        private bool gameOver;
 
        private Player winner = null;
 
        Move[][] winning_moves;
 
        public Game()
        {
 
            winning_moves = new Move[8][];
 
            //top row
            Move move01 = new Move();
            move01.setRow(1);
            move01.setColumn(1);
 
            Move move02 = new Move();
            move02.setRow(1);
            move02.setColumn(2);
 
            Move move03 = new Move();
            move03.setRow(1);
            move03.setColumn(3);
 
            Move[] move0;
 
            move0 = new Move[] { move01, move02, move03 };
 
 
            winning_moves[0] = move0;
 
            //middle row
 
            Move move11 = new Move();
            move11.setRow(2);
            move11.setColumn(1);
 
            Move move12 = new Move();
            move12.setRow(2);
            move12.setColumn(2);
 
            Move move13 = new Move();
            move13.setRow(2);
            move13.setColumn(3);
 
            Move[] move1;
 
            move1 = new Move[] { move11, move12, move13 };
 
            winning_moves[1] = move1;
 
            //bottom row
 
            Move move21 = new Move();
            move21.setRow(3);
            move21.setColumn(1);
 
            Move move22 = new Move();
            move22.setRow(3);
            move22.setColumn(2);
 
            Move move23 = new Move();
            move23.setRow(3);
            move23.setColumn(3);
 
            Move[] move2;
 
            move2 = new Move[] { move21, move22, move23 };
 
            winning_moves[2] = move2;
 
            //column wise
 
            //column 1
 
            Move move31 = new Move();
            move31.setRow(1);
            move31.setColumn(1);
 
            Move move32 = new Move();
            move32.setRow(2);
            move32.setColumn(1);
 
            Move move33 = new Move();
            move33.setRow(3);
            move33.setColumn(1);
 
            Move[] move3;
 
            move3 = new Move[] { move31, move32, move33 };
 
            winning_moves[3] = move3;
 
            //column 2
 
            Move move41 = new Move();
            move41.setRow(1);
            move41.setColumn(2);
 
            Move move42 = new Move();
            move42.setRow(2);
            move42.setColumn(2);
 
            Move move43 = new Move();
            move43.setRow(3);
            move43.setColumn(2);
 
            Move[] move4;
 
            move4 = new Move[] { move41, move42, move43 };
 
            winning_moves[4] = move4;
 
            //column 3
 
            Move move51 = new Move();
            move51.setRow(1);
            move51.setColumn(3);
 
            Move move52 = new Move();
            move52.setRow(2);
            move52.setColumn(3);
 
            Move move53 = new Move();
            move53.setRow(3);
            move53.setColumn(3);
 
            Move[] move5;
 
            move5 = new Move[] { move51, move52, move53 };
 
            winning_moves[5] = move5;
 
            //diagonals
 
            //diagonal 1
 
            Move move61 = new Move();
            move61.setRow(1);
            move61.setColumn(1);
 
            Move move62 = new Move();
            move62.setRow(2);
            move62.setColumn(2);
 
            Move move63 = new Move();
            move63.setRow(3);
            move63.setColumn(3);
 
            Move[] move6;
 
            move6 = new Move[] { move61, move62, move63 };
 
            winning_moves[6] = move6;
 
            //diagonal 2
 
            Move move71 = new Move();
            move71.setRow(1);
            move71.setColumn(3);
 
            Move move72 = new Move();
            move72.setRow(2);
            move72.setColumn(2);
 
            Move move73 = new Move();
            move73.setRow(3);
            move73.setColumn(1);
 
            Move[] move7;
 
            move7 = new Move[] { move71, move72, move73 };
 
            winning_moves[7] = move7;
 
        }
 
        public int getWhoseTurn()
        {
            return whoseTurn;
        }
 
        public void setWhoseTurn(Player player)
        {
            this.whoseTurn = player.getPlayerNum();
        }
 
        public static int getMovesTillNow()
        {
            return movesTillNow;
        }
 
        public static void setMovesTillNow()
        {
            Game.movesTillNow++;
        }
 
        public bool isGameOver()
        {
            return gameOver;
        }
 
        public void setGameOver(bool gameOver)
        {
            this.gameOver = gameOver;
        }
 
        public Player getWinner()
        {
            return winner;
        }
 
        public void setWinner(Player winner)
        {
            this.winner = winner;
        }
 
        private bool checkSubset(Move[] subset, Move[] winning_row)
        {
            int count = 0;
 
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (subset[i].getRow() == winning_row[j].getRow() && subset[i].getColumn() == winning_row[j].getColumn())
                    {
                        count++;
                    }
                }
            }
 
            return (count == 3);
        }
 
 
        //check the winning moves
 
        public bool checkWinningMoves(Player player)
        {
 
            /*****check winning moves*****/
 
            int movesTillNow = Game.getMovesTillNow();
 
            int whoseTurn = this.getWhoseTurn();
 
            Move[] playerMoves = player.getMoves().ToArray();
 
            int moves = movesTillNow;
 
            Move[][] winning_moves1 = this.winning_moves;
 
            switch (whoseTurn)
            {
                case 1:
 
                    if (moves < 5)
                    {
                        return false;
                    }
                    else
                    {
                        if (moves == 5)
                        {
                            Move[] player1_set1 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[2] };
 
                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player1_set1, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }
 
                        /******/
 
                        if (moves == 7)
                        {
                            Move[] player1_set2 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[3] };
 
                            Move[] player1_set4 = new Move[] { playerMoves[0], playerMoves[2], playerMoves[3] };
 
                            Move[] player1_set7 = new Move[] { playerMoves[1], playerMoves[2], playerMoves[3] };
 
                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player1_set2, winning_moves1[i]) ||
                                checkSubset(player1_set4, winning_moves1[i]) ||
                                checkSubset(player1_set7, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }
 
                        if (moves == 9)
                        {
                            Move[] player1_set3 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[4] };
 
                            Move[] player1_set5 = new Move[] { playerMoves[0], playerMoves[2], playerMoves[4] };
 
                            Move[] player1_set6 = new Move[] { playerMoves[0], playerMoves[3], playerMoves[4] };
 
                            Move[] player1_set8 = new Move[] { playerMoves[1], playerMoves[2], playerMoves[4] };
 
                            Move[] player1_set9 = new Move[] { playerMoves[1], playerMoves[3], playerMoves[4] };
 
                            Move[] player1_set10 = new Move[] { playerMoves[2], playerMoves[3], playerMoves[4] };
 
                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player1_set3, winning_moves1[i]) ||
                                checkSubset(player1_set5, winning_moves1[i]) || checkSubset(player1_set6, winning_moves1[i]) ||
                                checkSubset(player1_set8, winning_moves1[i]) || checkSubset(player1_set9, winning_moves1[i]) ||
                                checkSubset(player1_set10, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }
 
                        return false;
                    }
 
                case 2:
                    /******/
                    if (moves < 6)
                    {
                        return false;
                    }
                    else
                    {
                        /*******/
                        if (moves == 6)
                        {
                            Move[] player2_set1 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[2] };
 
                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player2_set1, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }
 
                        if (moves == 8)
                        {
                            Move[] player2_set2 = new Move[] { playerMoves[0], playerMoves[1], playerMoves[3] };
 
                            Move[] player2_set3 = new Move[] { playerMoves[0], playerMoves[2], playerMoves[3] };
 
                            Move[] player2_set4 = new Move[] { playerMoves[1], playerMoves[2], playerMoves[3] };
 
                            for (int i = 0; i < 8; i++)
                            {
                                if (checkSubset(player2_set2, winning_moves1[i]) || checkSubset(player2_set3, winning_moves1[i]) ||
                                checkSubset(player2_set4, winning_moves1[i]))
                                {
                                    return true;
                                }
                            }
                        }
 
                        return false;
                    }
                default:
                    return false;
            }
        }
 
    }
}

Finally, the main class:

TicTacToe

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace TicTacToeDotNet
{
    public class TicTacToe
    {
 
        /**
         * @param args the command line arguments
         */
        public static void Main(string[] args)
        {
            // TODO code application logic here
 
            Game game = new Game();
 
            Player player1 = new Player();
 
            player1.setPlayerNum(1);
 
            player1.setPlayerMark('X');
 
            player1.setGame(game);
 
            Player player2 = new Player();
 
            player2.setPlayerNum(2);
 
            player2.setPlayerMark('0');
 
            player2.setGame(game);
 
            Board board = new Board();
 
            board.display();
 
            /*******/
 
            game.setWhoseTurn(player1);
 
            game.setGameOver(false);
 
            bool status = game.isGameOver();
 
            //
 
            do
            {
                int movesNow = Game.getMovesTillNow();
 
                if (movesNow == 9)
                {
                    if (game.getWinner() == null)
                    {
                        Console.WriteLine("TIE!\n");
                        break;
                    }
                }
 
                int turn = game.getWhoseTurn();
 
                Console.WriteLine("PLAYER " + turn + "\n");
 
                int row = 0;
                int column = 0;
 
                bool invalid = true;
 
                while (invalid)
                {
                    //code to handle invalid moves. players cannot proceed without valid input
                    try
                    {
                        Console.WriteLine("Enter row: ");
 
                        string str = Convert.ToString(Console.ReadLine());
 
                        if (!(str == ""))
                        {
 
                            row = Convert.ToInt32(str);
                            invalid = false;
 
                        }
                        else
                        {
                            continue;
                        }
                    }
                    catch (FormatException n)
                    {
                        Console.WriteLine("INVALID ROW!");
                        invalid = true;
                    }
                    /**/
                }
 
                invalid = true;
 
                while (invalid)
                {
                    /*code to handle invalid moves. players cannot proceed without valid input*/
 
                    try
                    {
                        Console.WriteLine("Enter column: ");
 
                        String str = Convert.ToString(Console.ReadLine());
 
                        if (!(str == ""))
                        {
 
                            column = Convert.ToInt32(str);
                            invalid = false;
 
                        }
                        else
                        {
                            continue;
                        }
                    }
                    catch (FormatException n)
                    {
                        Console.WriteLine("INVALID COLUMN!");
                        invalid = true;
                    }
                    /**/
                }
 
                /**/
 
                Move move = new Move();
 
                move.setRow(row);
 
                move.setColumn(column);
 
                switch (turn)
                {
                    case 1:
                        player1.makeMove(board, move);
 
                        if (game.checkWinningMoves(player1))
                        {
                            game.setWinner(player1);
 
                            Console.WriteLine("PLAYER 1 WINS!");
 
                            game.setGameOver(true);
                        }
                        else
                        {
                            if (move.isIsValid())
                            {
                                movesNow = Game.getMovesTillNow();
 
                                Console.WriteLine("MOVE NUMBER " + movesNow + "\n");
 
                                game.setWhoseTurn(player2);
                            }
                        }
                        break;
                    case 2:
                        player2.makeMove(board, move);
 
                        if (game.checkWinningMoves(player2))
                        {
                            game.setWinner(player2);
 
                            Console.WriteLine("PLAYER 2 WINS!");
 
                            game.setGameOver(true);
                        }
                        else
                        {
                            if (move.isIsValid())
                            {
                                movesNow = Game.getMovesTillNow();
 
                                Console.WriteLine("MOVE NUMBER " + movesNow + "\n");
 
                                game.setWhoseTurn(player1);
                            }
                        }
                        break;
                    default:
                        Console.WriteLine("ERROR!\n");
                        break;
                }
 
                status = game.isGameOver();
            }
            while (!status);
 
            Console.Read();
 
        }
 
    }
}

Copy, Compile, Run and ENJOY!

Leave a Reply

Your email address will not be published. Required fields are marked *