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.
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.