Tic-Tac-Toe
Somebody asked me to develop a simple two-player tic-tac-toe game in Pascal. The code is provided below, and it's pretty self-explanatory.
The program follows a simple while loop, invoking a number of procedures and functions to perform the steps required to keep the game in play. The board is defined as an array of size BOARDSIZE * BOARDSIZE, e.g. 3 * 3 where BOARDSIZE is defined at the start of the program. Any array element can contain one of three integers : 1, 2 or 3. 1 indicates an 'X' being present in that array place, 2 an 'O' and 3 indicates the space is blank. When initialised, each array element is filled with a 3. The main() function follows the following algorithm:
Get players names, clear the playing board and draw the empty board.
While the game is not won by player 1 or player 2
Get the next players move
Check the move is valid, if not go back and ask for his move again
Check if the move results in that player winning
If he has, print an appropriate message and terminate loop
Else return to top of loop for next move
End (while)
The program uses many of the features we have developed in the course material. A number of developments to the program are possible - getting the computer to play as the second player and drawing a more sophisticated board are two obvious enhancements. However these would only increase the amount of code without teaching us anything more about the Pascal language, so they are not included here. The size of the board can be increased by increasing the BOARDSIZE definition at the top of the program.
program tictactoe;
const boardsize = 3;
var players : array[1..2] of string[20]; { players names}
var XO : array[1..3] of char;
var board : array[1..boardsize, 1..boardsize] of integer;
var movesleft, ok, won : boolean;
var row, column, moves : integer;
{ }
{ gets the names of the players and store in the players names array }
{ }
procedure getplayerdetails;
begin
write ('Enter Player1 Name : ');
readln (players[1]);
write ('Enter Player2 Name : ');
readln (players[2]);
writeln (players[1],' you are X');
writeln (players[2],' you are O');
end;
{ }
{ places all blanks into the playing board }
{ }
procedure clearboard;
var i, j : integer;
begin
for i := 1 to boardsize do
for j := 1 to boardsize do
board[i,j] := 3;
end;
{ }
{ draws the board and any pieces played to the output screen }
{ }
procedure drawboard;
var i, j : integer;
begin
writeln;
for i := 1 to boardsize do
begin
for j:= 1 to boardsize do
write('| ',XO[board[i,j]],' |');
if not(i = boardsize) then begin
writeln;
writeln ('--------------');
end;
end;
writeln;
end;
{ }
{ check if a given move is valid }
{ }
function checkvalidmove (r : integer; c : integer) : boolean;
begin
ok := (r <= boardsize) and (c <= boardsize); { within bounds of board }
ok := ok and (board[r,c] = 3); { space not already taken }
checkvalidmove := ok
end;
function checkmovesleft : boolean;
var check : boolean;
var i, j : integer;
begin
check := false;
for i:= 1 to boardsize do
for j := 1 to boardsize do
check := check OR (board[i,j] = 3);
checkmovesleft := check;
end;
{ }
{ check if a move a player has made has won him the game }
{ }
function checkwon : boolean;
var won, iwon : boolean;
var start, i, j : integer;
begin
iwon := FALSE;
won := FALSE;
{ 1st check the rows }
for i := 1 to boardsize do
begin
start := board[i,1];
if not(start = 3) then
begin
won := TRUE;
for j := 1 to boardsize do
won := won AND (start = board[i,j]);
end;
iwon := iwon OR won;
end;
if not(iwon) then
begin { check the columns }
for i := 1 to boardsize do
begin
start := board[1,i];
if not(start = 3) then
begin
won := TRUE;
for j := 1 to boardsize do
won := won AND (start = board[j,i]);
iwon := iwon OR won;
end;
end;
end;
if not(iwon) then
begin { check the diagonals }
i := 1; { diagonal 1,1 -> boardsize, boardsize }
start := board[i,1];
if not(start = 3) then
begin
won := TRUE;
for j := 1 to boardsize do
won := won AND (start = board[j,j]);
iwon := iwon OR won;
end;
end;
if not(iwon) then
begin
i := boardsize; { diagonal boardsize, 1 -> 1, boardsize }
start := board[i,1];
if not(start = 3) then
begin
won := TRUE;
for j := 1 to boardsize - 1 do
won := won AND (start = board[boardsize-j, boardsize-j]);
iwon := iwon OR won;
end;
end;
checkwon := iwon;
end;
{ }
{ main program }
{ }
begin
XO[1] := 'X';
XO[2] := 'O';
XO[3] := ' ';
movesleft := TRUE;
won := FALSE;
moves := 0;
getplayerdetails;
clearboard;
drawboard;
while (movesleft and not(won)) do
begin
writeln;
write ('Your move ',players[1 + (moves mod 2)]);
write (' Enter row, then column to place your ',XO[1 + (moves mod 2)],' in : ');
ok := false; { until he enters a valid move }
while not(ok) do
begin
readln (row, column);
ok := checkvalidmove (row, column);
if (ok) then board[row, column] := 1 + (moves mod 2)
else writeln ('Invalid move - Enter row and column to place your ',XO[1 + (moves mod 2)],' in : ');
end;
movesleft := checkmovesleft;
won := checkwon;
drawboard;
if (won) then
writeln ('* * * Congratulations ',players[1 + (moves mod 2)],' you have won! * * *');
moves := moves + 1;
end;
if not(movesleft) then writeln ('No valid moves left');
end.