Expand|Select|Wrap|Line Numbers
- #!/usr/bin/perl
- # Description: This program implements the game of Tic Tac Toe
- # The grid looks like the following.
- #
- # +---+---+---+
- # | 0 | 1 | 2 |
- # |---+---+---|
- # | 3 | 4 | 5 |
- # |---+---+---|
- # | 6 | 7 | 8 |
- # +---+---+---+
- use strict;
- # define a constant value
- use constant CLEAR => 'cls';
- # Initial introduction message
- my $msg =<<END;
- This is the game of Tic Tac Toe. The game is played by two players,
- X and O. Wait wait for programs prompt and then make your move by
- entering the coordinates of the location your want to occupy in the
- grid.
- END
- system(CLEAR);
- print $msg;
- print "\nPlease press return when ready to continue ... ";
- <STDIN>;
- # use system function to run system commands
- system(CLEAR);
- my $edge_row = '+---+---+---+';
- my $mid_row = '|---+---+---|';
- # this array holds the content of the grid locations
- my @data;
- init_grid(\@data);
- my @players = ('X', 'O');
- my $game_over = 0;
- my $player = 'X';
- my $err = 0;
- for(my $turn = 0; !$game_over; $turn = !$turn)
- {
- # clear and print grid if no errors
- if(!$err)
- {
- system(CLEAR);
- print_grid(@data);
- }
- # clear the error
- $err = 0;
- print "\n\nPlayer $players[$turn] please make your move? ";
- chomp(my $move = <STDIN>);
- my ($x, $y) = split ' ', $move;
- if($x < 1 || $x > 3 || $y < 1 || $y > 3)
- {
- # set the error flag
- $err = 1;
- print "\nCoordinates must be between 1 and 3, try again";
- redo;
- }
- my $index = ($x - 1) * 3 + ($y - 1);
- if($data[$index] eq 'X' || $data[$index] eq 'O')
- {
- # set the error flag
- $err = 1;
- print "\nThis location is already occupied, enter another location";
- redo;
- }
- $data[$index] = $players[$turn];
- # check if there is a winner
- if(any_winner(@data))
- {
- system(CLEAR);
- print "\nGame over, $players[$turn] wins.";
- $game_over = 1;
- }
- # check if grid is full
- elsif(grid_full(@data))
- {
- system(CLEAR);
- print "\nGame over, nobody wins.";
- $game_over = 1;
- }
- }
- print_grid(@data);
- print "\n" x 5;
- #----------------------------------------------------------------------
- # Sub : print_data_row
- # input : data in one row
- # output : none
- # Description: pritns one row of the grid in appropriate format
- #----------------------------------------------------------------------
- sub print_data_row
- {
- printf "\n| %s | %s | %s |", $_[0], $_[1], $_[2];
- }
- #----------------------------------------------------------------------
- # Sub : print_grid
- # input : data in grid
- # output : none
- # Description: prints the entire grid in appropriate format
- #----------------------------------------------------------------------
- sub print_grid
- {
- @data = @_;
- print "\n$edge_row";
- for(my $i = 0; $i < 3; $i++)
- {
- print_data_row($data[0 + 3 * $i],$data[1 + 3 * $i],$data[2 + 3* $i]);
- print "\n$mid_row" if($i < 2);
- }
- print "\n$edge_row";
- }
- #----------------------------------------------------------------------
- # Sub : any_winner
- # input : data in grid
- # output : 1 if there is a winner, 0 otherwise
- # Description: checks the grid for a winner
- #----------------------------------------------------------------------
- sub any_winner
- {
- my @data = @_;
- for(my $i = 0; $i < 3; $i++)
- {
- # check the columns
- if(($data[$i] eq $data[3 + $i]) &&
- ($data[$i] eq $data[6 + $i]) && $data[$i] ne ' ')
- {
- return 1;
- }
- # check the rows
- if(($data[3 * $i] eq $data[1 + 3 * $i]) &&
- ($data[3 * $i] eq $data[2 + 3 * $i]) && $data[3 * $i] ne ' ')
- {
- return 1;
- }
- }
- # check diagonals
- if(($data[0] eq $data[4]) &&
- ($data[0] eq $data[8]) && $data[0] ne ' ')
- {
- return 1;
- }
- elsif(($data[2] eq $data[4]) &&
- ($data[2] eq $data[6]) && $data[2] ne ' ')
- {
- return 1;
- }
- return 0;
- }
- #----------------------------------------------------------------------
- # Sub : grid_full
- # input : grid data
- # output : 1 if grid full, 0 otherwise
- # Description: checks to see if the grid is full
- #----------------------------------------------------------------------
- sub grid_full
- {
- for(my $i = 0; $i < 9; $i++)
- {
- if($data[$i] eq ' ')
- {
- return 0;
- }
- }
- return 1;
- }
- #----------------------------------------------------------------------
- # Sub : init_grid
- # input : reference to the grdi data
- # output : none
- # Description: initializes all elements in the grid to ' '
- #----------------------------------------------------------------------
- sub init_grid
- {
- my $ref = shift;
- for(my $i = 0; $i < 9; $i++)
- {
- $ref -> [$i] = ' ';
- }
- return;
- }