Sam Sam - 4 months ago 16
Pascal Question

Tic Tac Toe check winner free pascal

function CheckWinner(const track:MarkArray ;const index:Integer; p1:Player; p2:Player):String;
var

i,N:Integer; //Creating index to traverse the 2D array
row,col: Integer; //creating variables to fix rows and columns
temp : String;

begin

row:=(index-1) DIV 3; //fix row to check
col:=(index-1) MOD 3; //fix column to check
N:=3;
temp:='YES';
for i:=0 to N-1 do
begin
//check for player 1
if(NOT(track[row][i]=p1.sign)) then
begin
temp:='NO';
WriteLn('P1',temp);
end;
if((i=(N-1)) AND NOT(temp='NO') AND (track[row][i]=p1.sign)) then
begin
temp:='P1';
WriteLn('P1 won');
continue;
end;

///player 2 check for rows
if(NOT(track[row][i]=p2.sign)) then
begin
temp:='NO';
WriteLn('P2',temp);
continue;
end;
if((i=N-1) AND NOT(temp='NO') AND (track[row][i]=p2.sign)) then
begin
temp:='P2';
WriteLn('P2 won');
end;
end;


Hey I am writing code for TicTacToe in pascal and stuck at check winner function.

The problem is this code always check the last index of the row for the sign and is telling only for player 1, the main problem is with checks and i can't think of any checks anymore.
Please help.

The function is being passed two player records for player 1 and player 2, player sign is tick or cross and index parameter is the box number on screen converted to a 2D array index. Please someone help with this.This is a row only check i can add to it later.

Answer

I think you are trying to do too much in that one function. Split the single tasks up in smaller functions and it will become a lot more readable and a lot simpler.

I would do something like this:

type
  TSign = (empty, nought, cross);

  TMarkArray = array[0..2, 0..2] of TSign;

  TPlayer = record
    sign: TSign;
    // other fields you may need
  end;

 function CheckSign(const track: TMarkArray; sign: TSign; p1, p2, p3: Integer): Boolean;
 begin
    Result := (track[p1 div 3, p1 mod 3] = sign) and
              (track[p2 div 3, p2 mod 3] = sign) and
              (track[p3 div 3, p3 mod 3] = sign);
 end;

 function CheckPlayer(const track: TMarkArray; sign: TSign): Boolean;
 begin
   Result := CheckSign(track, sign, 0, 1, 2) or // top row
             CheckSign(track, sign, 3, 4, 5) or // middle row
             CheckSign(track, sign, 6, 7, 8) or // bottom row
             CheckSign(track, sign, 0, 3, 6) or // left column
             CheckSign(track, sign, 1, 4, 7) or // middle column
             CheckSign(track, sign, 2, 5, 8) or // right column
             CheckSign(track, sign, 0, 4, 8) or // top-left - bottom right
             CheckSign(track, sign, 2, 4, 6);   // top right - bottom left
 end;

 function CheckWinner(const track: TMarkArray; p1, p2: TPlayer): string;
 begin
   if CheckPlayer(track, p1.sign) then
     Result := 'P1'
   else if CheckPlayer(track, p2.sign) then
     Result := 'P2'
   else
     Result := 'NO';
 end;

I don't know how your types are defined, but I made them as simple as possible for this piece of code and added a T in front to designate them as types.

You could check rows and columns in a loop and jump out if you found a winner, but for a small playfield like this, with only 8 possible winner series, I left out the loops. They would only complicate CheckPlayer. For larger playfields, loops might make sense.

Try if that works.

Comments