Tic Tac Toe not working

So, i’m trying to make a tic tac toe that uses position and cloning and i was trying to detect the position, but what happens is that the if there happens to be 3 Xs then it will win for X (i didn’t make O still) , so i need help,

functions.checkWin = function()
	if canPlay then
		local partsofmove = script.Played:GetChildren()

		local X = {}

		local O = {}

		for i,v in pairs(partsofmove) do
			if v.Name == "X" then
				table.insert(X, v.Position)
			elseif v.Name == "O" then
				table.insert(O, v.Position)
			end
		end

		if #X >= 3 then
			for i = 1, 8, 1 do
				local set = winPos[i]
				
				for i,pos in ipairs(set) do
					if X[i] == pos then
						functions.Win("X")
					end
				end
			end
		end



		if moves == 9 then
			wait(1)
			functions.Tie()
		end
	end
end

here is my script, Thanks!

I think you can do this a much easier way.
Make one two dimensional array where each value is set to a number, representing nothing, ‘X’, or ‘O’.
This makes it much easier to check if a player has won, and it also makes it easier to put 'X’s and 'O’s on the board.

local board = {} -- create the board
local boardSize = 3 -- set the board size

for x = 1,boardSize do -- create x axis 
  board[x] = {}

  for y = 1,boardSize do -- create y axis
    board[x][y] = 1 -- set each one to nothing by default
  end
end

--now you can set a part of the board to X, O, or nothing very easily
board[2][3] = 2

--you can use this to translate the numbers in the board to something a human can read
local translation = { 
  1 = "Nothing",
  2 = "X",
  3 = "O",
}

--you can also check if a player is winning very easily (this checks if player is winning in a column)
function checkColumnWinner()
  for x = 1,boardSize do -- go through the rows
    local winner = true -- assume there is a winner at first
    local current -- stores the last one we went through

    for y = 1,boardSize do -- go through the columns
      if board[x][y] == current or current == nil then -- if the last one is matched with the current one or there is no last one then we store the last one as the current and continue
        current = board[x][y]
      else -- if the last one is different from the current one, then there is no winner in this column and we go on
        winner = false
        break
      end
    end

    if winner then -- if there is a winner then we print it and stop checking
      print("winner is " .. translation[current])
      break
    end
  end
end

--you can check diagonals like this
function checkDiagonal1()
  local current
  local winner = true
  for i = 1,boardSize do -- go through the board diagonally. Will check board[1][1], board[2][2], then board[3][3]
    if board[i][i] == current or current == nil then -- if the previous one is the same or does not exist, then we set it to the current one
      current = board[i][i]
    else -- if the previous one is not the same as the current one, then there is no winner and we stop searching
      winner = false
      break
    end

    if winner then -- if there is a winner then we print it and stop checking 
      print("winner is " .. translations[current])
      break
    end

  end
end

--show the parts in the roblox game
local boardFolder = game.Workspace.Board -- folder where the board is

function updateBoard() 
  boardFolder:ClearAllChildren() -- clear the board 

--go through each slot in the board
  for x = 1,boardSize do
    for y = 1,BoardSize do
      local current = board[x][y] -- current slot in the board
      local translated = translations[current] -- will be X,O, or Nothing
     -- do something with the translated
     -- could create a part where the x position is x and the z position is y

    end
  end
end

it didn’t work due to typos and errors but i’d be glad if you could help me with this script to i made it so it checks when a row is done but i sometimes if i move too much before wining (5 times+) then it stops suddenly

functions.checkWin = function()
	if canPlay then
		
		local click1 = script.Clicks["1"]
		local click2 = script.Clicks["2"]
		local click3 = script.Clicks["3"]
		local click4 = script.Clicks["4"]
		local click5 = script.Clicks["5"]
		local click6 = script.Clicks["6"]
		local click7 = script.Clicks["7"]
		local click8 = script.Clicks["8"]
		local click9 = script.Clicks["9"]
		
		print(move)
		
		if moves < 9 then
			if click1.canPut.Value == false and click2.canPut.Value == false and click3.canPut.Value == false then
				if script.Played:FindFirstChild(click1.Name..move) and script.Played:FindFirstChild(click2.Name..move) and script.Played:FindFirstChild(click3.Name..move) then
					functions.Win(move)
				end
			elseif click1.canPut.Value == false and click4.canPut.Value == false and click7.canPut.Value == false then
				if script.Played:FindFirstChild(click1.Name..move) and script.Played:FindFirstChild(click4.Name..move) and script.Played:FindFirstChild(click7.Name..move) then
					functions.Win(move)
				end
			elseif click1.canPut.Value == false and click5.canPut.Value == false and click9.canPut.Value == false then
				if script.Played:FindFirstChild(click1.Name..move) and script.Played:FindFirstChild(click5.Name..move) and script.Played:FindFirstChild(click9.Name..move) then
					functions.Win(move)
				end
			elseif click2.canPut.Value == false and click5.canPut.Value == false and click8.canPut.Value == false then
				if script.Played:FindFirstChild(click2.Name..move) and script.Played:FindFirstChild(click5.Name..move) and script.Played:FindFirstChild(click8.Name..move) then
					functions.Win(move)
				end
			elseif click3.canPut.Value == false and click6.canPut.Value == false and click9.canPut.Value == false then
				if script.Played:FindFirstChild(click3.Name..move) and script.Played:FindFirstChild(click6.Name..move) and script.Played:FindFirstChild(click9.Name..move) then
					functions.Win(move)
				end
			elseif click3.canPut.Value == false and click5.canPut.Value == false and click7.canPut.Value == false then
				if script.Played:FindFirstChild(click3.Name..move) and script.Played:FindFirstChild(click5.Name..move) and script.Played:FindFirstChild(click7.Name..move) then
					functions.Win(move)
				end
			elseif click4.canPut.Value == false and click5.canPut.Value == false and click6.canPut.Value == false then
				if script.Played:FindFirstChild(click4.Name..move) and script.Played:FindFirstChild(click5.Name..move) and script.Played:FindFirstChild(click6.Name..move) then
					functions.Win(move)
				end
			elseif click7.canPut.Value == false and click8.canPut.Value == false and click9.canPut.Value == false then
				if script.Played:FindFirstChild(click7.Name..move) and script.Played:FindFirstChild(click8.Name..move) and script.Played:FindFirstChild(click9.Name..move) then
					functions.Win(move)
				end
			end
		elseif moves == 9 then
			functions.Tie()
		end
	end
end

thanks

Can you please help me with it?

fixed typos

local board = {} -- create the board
local boardSize = 3 -- set the board size

for x = 1,boardSize do -- create x axis 
	board[x] = {}

	for y = 1,boardSize do -- create y axis
		board[x][y] = 1 -- set each one to nothing by default
	end
end

--now you can set a part of the board to X, O, or nothing very easily
board[2][3] = 2

--you can use this to translate the numbers in the board to something a human can read
local translations = { 
	"Nothing",
	"X",
	"O",
}

--you can also check if a player is winning very easily (this checks if player is winning in a column)
function checkColumnWinner()
	for x = 1,boardSize do -- go through the rows
		local winner = true -- assume there is a winner at first
		local current -- stores the last one we went through

		for y = 1,boardSize do -- go through the columns
			if board[x][y] == current or current == nil then -- if the last one is matched with the current one or there is no last one then we store the last one as the current and continue
				current = board[x][y]
			else -- if the last one is different from the current one, then there is no winner in this column and we go on
				winner = false
				break
			end
		end

		if winner then -- if there is a winner then we print it and stop checking
			print("winner is " .. translations[current])
			break
		end
	end
end

--you can check diagonals like this
function checkDiagonal1()
	local current
	local winner = true
	for i = 1,boardSize do -- go through the board diagonally. Will check board[1][1], board[2][2], then board[3][3]
		if board[i][i] == current or current == nil then -- if the previous one is the same or does not exist, then we set it to the current one
			current = board[i][i]
		else -- if the previous one is not the same as the current one, then there is no winner and we stop searching
			winner = false
			break
		end

		if winner then -- if there is a winner then we print it and stop checking 
			print("winner is " .. translations[current])
			break
		end

	end
end

--show the parts in the roblox game
local boardFolder = game.Workspace.Board -- folder where the board is

function updateBoard() 
	boardFolder:ClearAllChildren() -- clear the board 

	--go through each slot in the board
	for x = 1,boardSize do
		for y = 1,boardSize do
			local current = board[x][y] -- current slot in the board
			local translated = translations[current] -- will be X,O, or Nothing
			-- do something with the translated
			-- could create a part where the x position is x and the z position is y

		end
	end
end