【问题标题】:do loop/if statement logic做循环/if语句逻辑
【发布时间】:2017-11-30 01:56:47
【问题描述】:

我正在开发井字游戏程序。函数 CHECK_WINNER 应该接收处于给定状态的棋盘,并确定游戏是否已获胜、平局或玩家是否需要继续游戏。 CHECK_WINNER 根据棋盘的状态取不同的值。

win(n;1:3) 块列出了井字棋棋盘的 8 种可能获胜配置。

我认为问题在于 do 循环。我的目标是循环浏览每个玩家(1 和 2)的每个获胜场景,并检查是否满足获胜条件。如果玩家 1 获胜,CHECK_MOVE 应该为 1,如果玩家 2 获胜,则为 2,如果游戏是平局,则为 3,其他情况下为 0。我究竟做错了什么?

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

【问题讨论】:

  • 为什么不使用 3x3 阵列作为电路板?一维数组非常复杂且模糊不清。
  • 而且策略很奇怪。浏览所有获胜位置的数据库?你会在 100x100 的板上做什么?它将持续一百万年。
  • 我不确定我明白为什么使用一维数组会使事情复杂化。你可以解释吗?关于你的第二点,为什么检查8个获胜条件是一个奇怪的策略?该板将始终为 3x3,所以我不确定您要对使用 100x100 板说什么?
  • 由你决定。一般来说,一维数组会使它复杂化,因为您不能直接看到邻居。井字游戏是关于邻居的。为什么更大的阵列?不停止在 3x3 上是一件很自然的事情,因为在 3x3 上它非常无用和无聊,但取决于你。您决定要学习什么以及要使用的可扩展方法。这不是攻击,而是友好的建议。这就是我想说的。
  • @VladimirF 我根本没有把它当作攻击——谢谢你的反馈!一旦我为 3x3 板完成这项工作,我将尝试更复杂的东西。

标签: fortran fortran90 do-loops


【解决方案1】:

因此,在您在代码中使用board = (/ 2,2,2,0,0,0,0,0,0 /) 给出的示例中,当i=1 在函数的do-loop 中时,它正确设置了CHECK_WINNER=2,因为

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

是真的。不幸的是,当循环到达 i=2、i=3 等时,它会将 CHECK_WINNER 重置为零,因为没有任何获胜条件匹配。这是导致问题的else 块。将do循环更改为

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

所以如果它找到一个已知的组合,它会设置 CHECK_WINNER。您也可以在每个 (else)if 子句中使用 exit 找到已知组合后立即退出循环。 (设置 CHECK_WINNER 后)

【讨论】:

  • 有道理!我有点困惑,因为我以前的方式,有时即使我注释掉 CHECK_WINNER = 0 行,循环也会返回 0。
猜你喜欢
  • 2016-02-25
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
相关资源
最近更新 更多