⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 knight.f90

📁 fortran 95书的源程序全集
💻 F90
字号:
module STACK_UTILITY
  implicit none
  private
  integer, parameter :: TOP=50
  integer, save :: current = 0
  integer, save :: stack(TOP)
  public push, pop
contains
  ! 把数据放入堆栈中  
  subroutine push(value)
    integer value
	if ( current>TOP ) then ! 超过容量
	  write(*,*) "Stack full."
	  return
	end if
	current = current+1
	stack(current)=value
  end subroutine
  ! 从堆栈中取出数据
  integer function pop(value)
    integer value
    if ( current<=0 ) then ! 已经没有东西可以拿了
	  pop=1
	  return
	end if
	value = stack(current)
	current = current-1
	pop = 0
  end function

end module
!
! 骑士走棋盘的范例
! By Perng 1997/9/1
program knight
  use STACK_UTILITY
  implicit none
  integer, parameter :: n=5 ! 定义棋盘有多大
  integer board(n,n)      ! 记录棋盘的状态
  integer, parameter :: total = n*n ! 棋盘有几个格子要走
  integer x_move(8)       ! 骑士有8 种移动的步法
  integer y_move(8)       !
  integer x_pos,y_pos     ! 骑士目前在棋盘上的位置
  integer x_new,y_new     ! 暂时算出的下一落脚处
  integer move            ! 所要使用的步法
  integer step            ! 完成了多少步
  integer sol             ! 计算总共有几种走法可以走完
  integer error
  data x_move /1,2, 2, 1,-1,-2,-2,-1/
  data y_move /2,1,-1,-2,-2,-1, 1, 2/
  data board / total*0 /  ! 全设为0 ,代表都还没走过
  data sol /0/            ! 解的数目先设为0
        
! 假设从棋盘的正中央开始走
  x_pos=(n+1)/2           
  y_pos=(n+1)/2           
  step=1
  board(x_pos,y_pos)=step ! 第一步在此

  move=1        ! 先试第一种走法
  do while(.true.)
    do while( move <= 8 )     ! 因为只有8种走法
      ! 算出下一步
      x_new=x_pos+x_move(move)
      y_new=y_pos+y_move(move)
      ! 不能超出棋盘
      if ( x_new < 1  .or.  x_new > n ) then
        move=move+1
        cycle
      end if
      if ( y_new < 1  .or.  y_new > n ) then
        move=move+1
        cycle
      end if
      ! 当这个下一步的位置是空位时, 才可让骑士进入
      if ( board(x_new,y_new) == 0 ) then
        x_pos=x_new
        y_pos=y_new
        step=step+1 
        board(x_pos,y_pos)=step ! 成功的踏出下一步
        call push(move)   ! 把目前的步法送入堆栈
        move=1            ! 下一步再从第一种步法开始试
      else
        move=move+1             ! 地点早已来过, 换个新的步法
      end if
    end do
    ! setp=total=n*n 时代表全部都踏遍了
    if ( step == total ) then
      sol=sol+1
      write(*,"('第',I3,'个解')") sol
      call show_board(board,n)
    end if
    ! 往回退一步再向下试
    step=step-1
    ! step<=0 代表无路可退了, 跳出循环
    if ( step <= 0 ) exit 
    board(x_pos,y_pos)=0  ! 向回退, 所以这个地方要设成没来过
    error = pop(move)      ! 从堆栈中取出上一个步法
	if ( error/=0 ) then
	  write(*,*) "Stack empry"
	  stop
	end if
    ! 向回退一步
    x_pos=x_pos-x_move(move)
    y_pos=y_pos-y_move(move)
    ! 换一个新的步法来试试
    move=move+1
  end do
  write(*,"('编共有',I3,'种解法')") sol
  stop
end program
!
! 显示棋盘状态的子程序
!
subroutine show_board(board,n)
  implicit none
  integer n
  integer board(n,n)
  integer i,j
  character*(20) :: for = '(??(1x,i3))'
! 用字符串来设定输出格式
  write( for(2:3), '(i2)' ) n
  do i=n,1,-1
    write( *, fmt=for ) board(:,i)
  end do
  return
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -