0

I'm working on a tic-tac-toe program. The function CHECK_WINNER is supposed to take in a board in a given state and determine if the game has been won, tied, or if players need to continue the game. CHECK_WINNER takes on different values based on the state of the board.

The block of win(n;1:3) lists the 8 possible winning configurations of a tic-tac-toe board.

I think the trouble is in the do loop. My goal is to cycle through each winning scenario for the board for each player (1 and 2) and check if a winning condition has been met. CHECK_MOVE should be 1 if player 1 wins, 2 if player 2 wins, 3 if the game is a draw, and 0 for any other case. What am I doing wrong?

program checkwinner
implicit none
integer, dimension(9) :: board
integer, external :: CHECK_WINNER
integer :: cw

!board = (/ 1,2,1,2,1,2,2,2,1 /)  ! not working correctly. 1 is winner, board full; cw returns 3
!board = (/ 1,2,1,2,0,2,2,2,1 /) ! working correctly. no winner, open spaces; cw returns 0
!board = (/ 1,1,1,0,0,0,0,0,0 /) ! not working. cw should return 1; instead cw returns 0
board = (/ 2,2,2,0,0,0,0,0,0 /) ! not working

cw = CHECK_WINNER(board)
print *, board(1:3)
print *, board(4:6)
print *, board(7:9)
print *, cw

end program checkwinner
!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!
integer function CHECK_WINNER(fboard)
implicit none
integer :: i
integer, dimension(8,3) :: win
integer, dimension(9), intent(in) :: fboard

win(1,1:3) = (/ 1,2,3 /)
win(2,1:3) = (/ 4,5,6 /)
win(3,1:3) = (/ 7,8,9 /)
win(4,1:3) = (/ 1,4,7 /)
win(5,1:3) = (/ 2,5,8 /)
win(6,1:3) = (/ 3,6,9 /)
win(7,1:3) = (/ 1,5,9 /)
win(8,1:3) = (/ 3,5,7 /)

do i = 1,8
     if (fboard(win(i,1)) == 1 .and. fboard(win(i,2)) == 1 .and. fboard(win(i,3)) == 1) then
        CHECK_WINNER = 1
    else if (fboard(win(i,1)) == 2 .and. fboard(win(i,2)) == 2 .and. fboard(win(i,3)) == 2) then
        CHECK_WINNER = 2
    else if ((fboard(win(i,1)) == 1 .or. fboard(win(i,1)) == 2) .and. (fboard(win(i,2)) == 1 .or. &
        fboard(win(i,2)) == 2) .and. (fboard(win(i,3)) == 1 .or. fboard(win(i,3)) == 2)) then
        CHECK_WINNER = 3
    else
        CHECK_WINNER = 0
    end if
end do

end function CHECK_WINNER
5
  • Why don't you use a 3x3 array for the board? It is needlesly complicated and obscures with a 1D array. Commented Nov 30, 2017 at 7:19
  • And the strategy is very strange. Go through a database of all winning positions? What will you do on a board 100x100? It will taoe a million years. Commented Nov 30, 2017 at 7:20
  • I'm not sure I see why using a 1D array complicates things. Can you explain? In regards to your second point, why is it a strange strategy to check for 8 winning conditions? The board will always be 3x3, so I'm not sure what you're trying to say about using a 100x100 board? Commented Nov 30, 2017 at 19:30
  • 1
    Up to you. In general 1D array complicates it because you don't directly see the neighbours. And tic-tac-toe is about neighbours. And why larger array? It is a natiral thing to do to not stop at 3x3 as it is pretty useless and boring at 3x3, but up to you. You decide what you want to learn and how extensible approaches you want to use. This was no attack, but a friendly recommendation. That is what I was trying to say. Commented Nov 30, 2017 at 20:37
  • @VladimirF I did not take it as an attack at all -- thank you for the feedback! Once I make this work for a 3x3 board I'll try something more complex. Commented Nov 30, 2017 at 22:19

1 Answer 1

1

So in the example you gave in your code with board = (/ 2,2,2,0,0,0,0,0,0 /) when i=1 in the do-loop of the function, it correctly sets CHECK_WINNER=2 because

fboard(win(i,1)) == 2 .and. fboard(win(i,2)) == 2 .and. fboard(win(i,3)) == 2

is true. Unfortunately when the loop gets to i=2, i=3 etc it resets CHECK_WINNER to zero because none of the win conditions match. It's the else block which is causing the problem. Change the do loop to

CHECK_WINNER = 0

do i = 1,8
  if (fboard(win(i,1)) == 1 .and. fboard(win(i,2)) == 1 .and. fboard(win(i,3)) == 1) then
    CHECK_WINNER = 1
  else if (fboard(win(i,1)) == 2 .and. fboard(win(i,2)) == 2 .and. fboard(win(i,3)) == 2) then
    CHECK_WINNER = 2
  else if ((fboard(win(i,1)) == 1 .or. fboard(win(i,1)) == 2) .and. (fboard(win(i,2)) == 1 .or. &
    fboard(win(i,2)) == 2) .and. (fboard(win(i,3)) == 1 .or. fboard(win(i,3)) == 2)) then
    CHECK_WINNER = 3
   end if
end do

so if it finds a known combination it sets CHECK_WINNER. You could also exit the loop as soon as the known combination is found using exit within each (else)if clause. (after CHECK_WINNER is set)

Sign up to request clarification or add additional context in comments.

1 Comment

That makes sense! I was a bit confused because the way I had it before, sometimes the loop would return 0 even when I commented out the line CHECK_WINNER = 0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.