Task: Tic-tac-toe


C++: #include <windows.h>
#include <iostream>
#include <string>


using namespace std;


enum players { Computer, Human, Draw, None };
const int iWin[8][3] = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, { 0, 4, 8 }, { 2, 4, 6 } };


class ttt
{
public:
    ttt() { _p = rand() % 2; reset(); }

    void play()
    {
	int res = Draw;
	while( true )
	{
	    drawGrid();
	    while( true )
	    {
		if( _p ) getHumanMove();
		else getComputerMove();

		drawGrid();

		res = checkVictory();
		if( res != None ) break;

		++_p %= 2;
	    }

	    if( res == Human ) cout << "CONGRATULATIONS HUMAN --- You won!";
	    else if( res == Computer ) cout << "NOT SO MUCH A SURPRISE --- I won!";
	    else cout << "It's a draw!";

	    cout << endl << endl;

	    string r;
	    cout << "Play again( Y / N )? "; cin >> r;
	    if( r != "Y" && r != "y" ) return;

	    ++_p %= 2;
	    reset();

	}
    }

private:
    void reset() 
    {
	for( int x = 0; x < 9; x++ )
	    _field[x] = None;
    }

    void drawGrid()
    {
	system( "cls" );
		
        COORD c = { 0, 2 };
	SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), c );

	cout << " 1 | 2 | 3 " << endl;
	cout << "---+---+---" << endl;
	cout << " 4 | 5 | 6 " << endl;
	cout << "---+---+---" << endl;
	cout << " 7 | 8 | 9 " << endl << endl << endl;

	int f = 0;
	for( int y = 0; y < 5; y += 2 )
	    for( int x = 1; x < 11; x += 4 )
	    {
		if( _field[f] != None )
		{
		    COORD c = { x, 2 + y };
		    SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), c );
		    string o = _field[f] == Computer ? "X" : "O";
		    cout << o;
		}
		f++;
	    }

        c.Y = 9;
	SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), c );
    }

    int checkVictory()
    {
	for( int i = 0; i < 8; i++ )
	{
	    if( _field[iWin[i][0]] != None &&
		_field[iWin[i][0]] == _field[iWin[i][1]] && _field[iWin[i][1]] == _field[iWin[i][2]] )
	    {
		return _field[iWin[i][0]];
	    }
	}

	int i = 0;
	for( int f = 0; f < 9; f++ )
	{
	    if( _field[f] != None )
		i++;
	}
	if( i == 9 ) return Draw;

	return None;
    }

    void getHumanMove()
    {
	int m;
	cout << "Enter your move ( 1 - 9 ) ";
	while( true )
	{
	    m = 0;
	    do
	    { cin >> m; }
	    while( m < 1 && m > 9 );

	    if( _field[m - 1] != None )
		cout << "Invalid move. Try again!" << endl;
	    else break;
	}

	_field[m - 1] = Human;
    }

    void getComputerMove()
    {
	int move = 0;

	do{ move = rand() % 9; }
	while( _field[move] != None );

	for( int i = 0; i < 8; i++ )
	{
	    int try1 = iWin[i][0], try2 = iWin[i][1], try3 = iWin[i][2];

	    if( _field[try1] != None && _field[try1] == _field[try2] && _field[try3] == None )
	    {
		move = try3;
		if( _field[try1] == Computer ) break;
	    }

	    if( _field[try1] != None && _field[try1] == _field[try3] && _field[try2] == None ) 
	    {			
		move = try2;
		if( _field[try1] == Computer ) break;
	    }

	    if( _field[try2] != None && _field[try2] == _field[try3] && _field[try1] == None )
	    {
		move = try1;
		if( _field[try2] == Computer ) break;
	    }
        }
	_field[move] = Computer;
		
    }


int _p;
int _field[9];
};

int main( int argc, char* argv[] )
{
    srand( GetTickCount() );

    ttt tic;
    tic.play();

    return 0;
}











Ada: with Ada.Text_IO, Ada.Numerics.Discrete_Random;
  
  

procedure Tic_Tac_Toe is

   type The_Range is range 1 .. 3;
   type Board_Type is array (The_Range, The_Range) of Character;

   package Rand is new Ada.Numerics.Discrete_Random(The_Range);
   Gen: Rand.Generator; 

   procedure Show_Board(Board: Board_Type) is
      use Ada.Text_IO;
   begin
      for Row in The_Range loop
         for Column in The_Range loop
            Put(Board(Row, Column));
         end loop;
         Put_Line("");
      end loop;
      Put_Line("");
   end Show_Board;

   function Find_Winner(Board: Board_Type) return Character is
      

      function Three_Equal(A,B,C: Character) return Boolean is
      begin
         return (A=B) and (A=C);
      end Three_Equal;

   begin 
      for I in The_Range loop
         if    Three_Equal(Board(I,1), Board(I,2), Board(I,3)) then
            return Board(I,1);
         elsif  Three_Equal(Board(1,I), Board(2,I), Board(3,I)) then
            return Board(1,I);
         end if;
      end loop;
      if Three_Equal(Board(1,1), Board(2,2), Board (3,3)) or
         Three_Equal(Board(3,1), Board(2,2), Board (1,3)) then
         return Board(2,2);
      end if;
      return ' ';
   end Find_Winner;

   procedure Do_Move(Board: in out Board_Type;
                     New_Char: Character; Computer_Move: Boolean) is
      Done: Boolean := False;
      C: Character;
      use Ada.Text_IO;

      procedure Do_C_Move(Board: in out Board_Type; New_Char: Character) is
         Found: Boolean := False;
         X,Y: The_Range;
      begin
         while not Found loop
            X := Rand.Random(Gen);
            Y := Rand.Random(Gen);
            if (Board(X,Y) /= 'x') and  (Board(X,Y) /= 'o') then
               Found := True;
               Board(X,Y) := New_Char;
            end if;
         end loop;
      end Do_C_Move;

   begin
      if Computer_Move then
         Do_C_Move(Board, New_Char);
      else 
         Put_Line("Choose your move, " & New_Char);
         while not Done loop
            Get(C);
            for Row in The_Range loop
               for Col in The_Range loop
                  if Board(Row, Col) = C then
                     Board(Row, Col) := New_Char;
                     Done := True;
                  end if;
               end loop;
            end loop;
         end loop;
      end if;
   end Do_Move;

   The_Board : Board_Type := (('1','2','3'), ('4','5','6'), ('7','8','9'));
   Cnt_Moves: Natural := 0;
   Players: array(0 .. 1) of Character := ('x', 'o'); 
   C_Player: array(0 .. 1) of Boolean := (False, False);
   Reply: Character;

begin 

   
   for I in Players'Range loop
      Ada.Text_IO.Put_Line("Shall " & Players(I) &
                             " be run by the computer? (y=yes)");
      Ada.Text_IO.Get(Reply);
      if Reply='y' or Reply='Y' then
         C_Player(I) := True;
         Ada.Text_IO.Put_Line("Yes!");
      else
         Ada.Text_IO.Put_Line("No!");
      end if;
   end loop;
   Rand.Reset(Gen); 

   
   while (Find_Winner(The_Board) = ' ') and (Cnt_Moves < 9) loop
      Show_Board(The_Board);
      Do_Move(The_Board, Players(Cnt_Moves mod 2), C_Player(Cnt_Moves mod 2));
      Cnt_Moves := Cnt_Moves + 1;
   end loop;
   Ada.Text_IO.Put_Line("This is the end!");

   
   Show_Board (The_Board);
   if Find_Winner(The_Board) = ' ' then
      Ada.Text_IO.Put_Line("Draw");
   else
      Ada.Text_IO.Put_Line("The winner is: " & Find_Winner(The_Board));
   end if;
end Tic_Tac_Toe;