This is a program to provide a board for two human players to use for the game of Tic-Tac-Toe.
It does not actualy play the game, but it does detect a victory, and it prints out some information at each move.
The board is represented as a 2-dimensional array of Character, and a 3-dimensional array of Integer is used to keep track of the various ways to have 3 in a row.
! This program provides a board for two humans to play the game of ! Tic-Tac-Toe. Program Tictac2 Implicit None Character :: Board(3, 3) Integer :: I, J, Row, Column, MoveX, MoveY Integer :: Counter = 1 Character :: WhoseMove = 'X' Logical :: Win, WinInOne Integer :: Ways(8, 3, 2) Ways(1, 1, 1) = 1 Ways(1, 1, 2) = 1 Ways(1, 2, 1) = 1 Ways(1, 2, 2) = 2 Ways(1, 3, 1) = 1 Ways(1, 3, 2) = 3 Ways(2, 1, 1) = 2 Ways(2, 1, 2) = 1 Ways(2, 2, 1) = 2 Ways(2, 2, 2) = 2 Ways(2, 3, 1) = 2 Ways(2, 3, 2) = 3 Ways(3, 1, 1) = 3 Ways(3, 1, 2) = 1 Ways(3, 2, 1) = 3 Ways(3, 2, 2) = 2 Ways(3, 3, 1) = 3 Ways(3, 3, 2) = 3 Ways(4, 1, 1) = 1 Ways(4, 1, 2) = 1 Ways(4, 2, 1) = 2 Ways(4, 2, 2) = 1 Ways(4, 3, 1) = 3 Ways(4, 3, 2) = 1 Ways(5, 1, 1) = 1 Ways(5, 1, 2) = 2 Ways(5, 2, 1) = 2 Ways(5, 2, 2) = 2 Ways(5, 3, 1) = 3 Ways(5, 3, 2) = 2 Ways(6, 1, 1) = 1 Ways(6, 1, 2) = 3 Ways(6, 2, 1) = 2 Ways(6, 2, 2) = 3 Ways(6, 3, 1) = 3 Ways(6, 3, 2) = 3 Ways(7, 1, 1) = 1 Ways(7, 1, 2) = 1 Ways(7, 2, 1) = 2 Ways(7, 2, 2) = 2 Ways(7, 3, 1) = 3 Ways(7, 3, 2) = 3 Ways(8, 1, 1) = 1 Ways(8, 1, 2) = 3 Ways(8, 2, 1) = 2 Ways(8, 2, 2) = 2 Ways(8, 3, 1) = 3 Ways(8, 3, 2) = 1 Do I= 1, 3 Do J = 1, 3 Board(I, J) = ' ' End Do End Do 40 Format(3A) Print 40, 'We are going to play Tic-Tac-Toe.' Print 40, 'Two human players can play X and O alternately.' Do While ((Counter < 10) .AND. (Win(Board, 'X', Ways) .Eqv. .False.) .AND. & (Win(Board, 'O', Ways) .Eqv. .False.)) Call PrintBoard(Board) Print * If (Counter > 1) Then 50 Format(A, I1, A, I1, A) Print 50, 'The chosen move is at (', Row, ', ', Column, ').' Print 50, 'We will now make that move.' End If If (WinInOne(Board, 'X', Ways, MoveX, MoveY)) Then 100 Format(1X, /, A, I1, A, I1, A) Print 100, 'There is a win for X in 1 move at (', MoveX, & ', ', MoveY, ')' End If If (WinInOne(Board, 'O', Ways, MoveX, MoveY)) Then Print 100, 'There is a win for O in 1 move at (', MoveX, & ', ', MoveY, ')' End If If (Counter == 1) Then Print 40, 'What is the first move? X moves first.' Else Print * Print 40, 'What is the next move for ', WhoseMove, '?' End If Print 40, 'Specify the row and column, each a number 1 to 3.' Read *, Row, Column Do While ((Row < 1) .Or. (Row > 3) .Or. (Column < 1) .Or. & (Column > 3) .Or. (Board(Row, Column) /= ' ')) Print *, 'Try again.' Read *, Row, Column End Do Board(Row, Column) = WhoseMove Counter = Counter + 1 If (WhoseMove == 'X') Then WhoseMove = 'O' Else WhoseMove = 'X' End If End Do Print 50, 'The chosen move is at (', Row, ', ', Column, ').' Print 50, 'We will now make that move.' Print * Print 40, 'The final position is:' Call PrintBoard(Board) If ((Win(Board, 'X', Ways)) .Or. (Win(Board, 'O', Ways))) Then Print 40, 'We have a winner!' Else Print 40, 'There is no winner.' End If End Program Tictac2 ! This subroutine prints the current state of the board. Subroutine PrintBoard(B) Implicit None Character :: B(3, 3) Integer :: I Print * 100 Format(T21, A) Print 100, 'Columns' 110 Format(T18, A1, T24, A1, T30, A1) Print 110, '1', '2', '3' Print * 120 Format(T16, A17) Print 120, ' | | ' Do I = 1, 3 130 Format(T8, A3, 1X, I1, T18, A1, T21, A1, T24, A1, & T27, A1, T30, A1) Print 130, 'Row', I, B(I, 1), '|', B(I, 2), & '|', B(I,3) If (I < 3) Then Print 120, ' | | ' Print 120, '-----+-----+-----' End If Print 120, ' | | ' End Do End Subroutine ! This function returns .True. if the Player has won the game and ! returns .False. otherwise. Logical Function Win(B, Player, Ways) Implicit None Character :: B(3, 3) Character :: Player Logical :: FoundWin = .False. Integer :: Ways(8, 3, 2) Integer :: I I = 1 Do While ((I <= 8) .AND. (FoundWin .EQV. .False.)) If ((B(Ways(I, 1, 1), Ways(I, 1, 2)) == Player) .AND. & (B(Ways(I, 2, 1), Ways(I, 2, 2)) == Player) .AND. & (B(Ways(I, 3, 1), Ways(I, 3, 2)) == Player)) FoundWin = .True. I = I + 1 End Do Win = FoundWin End Function Win Logical Function WinInOne(B, Player, Ways, MoveX, MoveY) Implicit None Character :: B(3, 3) Character :: Player Integer :: Ways(8, 3, 2), MoveX, MoveY Integer :: I MoveX = 0 MoveY = 0 I = 1 Do While ((I <= 8) .AND. (MoveX == 0) .AND. (MoveY == 0)) If ((B(Ways(I, 1, 1), Ways(I, 1, 2)) == Player) .AND. & (B(Ways(I, 2, 1), Ways(I, 2, 2)) == Player) .AND. & (B(Ways(I, 3, 1), Ways(I, 3, 2)) == ' ')) Then MoveX = Ways(I, 3, 1) MoveY = Ways(I, 3, 2) Else If ((B(Ways(I, 2, 1), Ways(I, 2, 2)) == Player) .AND. & (B(Ways(I, 3, 1), Ways(I, 3, 2)) == Player) .AND. & (B(Ways(I, 1, 1), Ways(I, 1, 2)) == ' ')) Then MoveX = Ways(I, 1, 1) MoveY = Ways(I, 1, 2) Else If ((B(Ways(I, 3, 1), Ways(I, 3, 2)) == Player) .AND. & (B(Ways(I, 1, 1), Ways(I, 1, 2)) == Player) .AND. & (B(Ways(I, 2, 1), Ways(I, 2, 2)) == ' ')) Then MoveX = Ways(I, 2, 1) MoveY = Ways(I, 2, 2) End If End If End If I = I + 1 End Do WinInOne = ((MoveX /= 0) .AND. (MoveY /= 0)) End Function WinInOne
What does the board look like?
Here is the output from a sample run of the program.
We are going to play Tic-Tac-Toe. Two human players can play X and O alternately. Columns 1 2 3 | | Row 1 | | | | -----+-----+----- | | Row 2 | | | | -----+-----+----- | | Row 3 | | | | What is the first move? X moves first. Specify the row and column, each a number 1 to 3. Columns 1 2 3 | | Row 1 | | | | -----+-----+----- | | Row 2 | | | | -----+-----+----- | | Row 3 | X | | | The chosen move is at (3, 2). We will now make that move. What is the next move for O? Specify the row and column, each a number 1 to 3. Columns 1 2 3 | | Row 1 | | | | -----+-----+----- | | Row 2 O | | | | -----+-----+----- | | Row 3 | X | | | The chosen move is at (2, 1). We will now make that move. What is the next move for X? Specify the row and column, each a number 1 to 3. Columns 1 2 3 | | Row 1 | | X | | -----+-----+----- | | Row 2 O | | | | -----+-----+----- | | Row 3 | X | | | The chosen move is at (1, 3). We will now make that move. What is the next move for O? Specify the row and column, each a number 1 to 3. Columns 1 2 3 | | Row 1 | | X | | -----+-----+----- | | Row 2 O | | | | -----+-----+----- | | Row 3 | X | O | | The chosen move is at (3, 3). We will now make that move. What is the next move for X? Specify the row and column, each a number 1 to 3. Columns 1 2 3 | | Row 1 | | X | | -----+-----+----- | | Row 2 O | X | | | -----+-----+----- | | Row 3 | X | O | | The chosen move is at (2, 2). We will now make that move. There is a win for X in 1 move at (1, 2) What is the next move for O? Specify the row and column, each a number 1 to 3. Columns 1 2 3 | | Row 1 | O | X | | -----+-----+----- | | Row 2 O | X | | | -----+-----+----- | | Row 3 | X | O | | The chosen move is at (1, 2). We will now make that move. There is a win for X in 1 move at (3, 1) What is the next move for X? Specify the row and column, each a number 1 to 3. The chosen move is at (3, 1). We will now make that move. The final position is: Columns 1 2 3 | | Row 1 | O | X | | -----+-----+----- | | Row 2 O | X | | | -----+-----+----- | | Row 3 X | X | O | | We have a winner!