Advertisement
Guest User

Untitled

a guest
Jul 1st, 2022
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module cfunctions
  2.    use, intrinsic :: iso_c_binding, only : c_int
  3.    interface
  4.       function c_rand() bind(c, name="rand")
  5.          import c_int
  6.          integer(c_int) c_rand
  7.       end function c_rand
  8.    end interface
  9. end module cfunctions
  10.  
  11. subroutine IOHandle_Init()
  12.     use, intrinsic :: iso_c_binding, only: c_null_char
  13.     use :: m_ncurses
  14.  
  15.     integer :: rc
  16.  
  17.     stdscr = initscr()
  18.     rc     = raw()
  19.     rc     = nodelay(stdscr, true)
  20.     rc     = keypad(stdscr, true)
  21.     rc     = noecho()
  22.     rc     = curs_set(0)
  23. end subroutine IOHandle_Init
  24.  
  25. subroutine IOHandle_Quit()
  26.     use, intrinsic :: iso_c_binding, only: c_null_char
  27.     use :: m_ncurses
  28.     implicit none
  29.    
  30.     integer :: rc
  31.     rc = endwin()
  32. end subroutine IOHandle_Quit
  33.  
  34. subroutine ClearScreen()
  35.     use, intrinsic :: iso_c_binding, only: c_null_char
  36.     use :: m_ncurses
  37.  
  38.     integer :: i, rc
  39.     do i = 0, LINES - 1
  40.         rc = mvhline(i, 0, ichar(' ', 8), COLS)
  41.     end do
  42. end subroutine ClearScreen
  43.  
  44. function RandomRange(minimum, maximum)
  45.     use :: cfunctions
  46.     integer :: RandomRange
  47.     integer :: minimum, maximum
  48.  
  49.     RandomRange = modulo(c_rand() + minimum, maximum)
  50. end function RandomRange
  51.  
  52. function NewAppleLocation(boardSize, player)
  53.     use :: cfunctions
  54.     type Vec2_t
  55.         integer :: x, y
  56.     end type
  57.     type(Vec2_t) :: NewAppleLocation
  58.     type Player_t
  59.         type(Vec2_t)                            :: pos
  60.         integer                                 :: direction
  61.         type(Vec2_t), dimension(:), allocatable :: tail
  62.     end type
  63.     type(Player_t) :: player
  64.     type(Vec2_t)   :: test
  65.     integer        :: i ! iterator
  66.     integer        :: j ! iterator
  67.  
  68.     logical :: created = .false.
  69.     logical :: valid
  70.  
  71.     ! generate an array of valid apple positions
  72.     logical, dimension(boardSize.y, boardSize.x) :: available
  73.     integer                                      :: numberAvailable
  74.     numberAvailable = boardSize%y * boardSize%x
  75.     do i = 1, boardSize%y
  76.         do j = 1, boardSize%x
  77.             available(i, j) = .true.
  78.         end do
  79.     end do
  80.     do i = 1, size(player%tail) ! remove taken places
  81.         available(player%tail(i)%y, player%tail(i)%x) = .false.
  82.         numberAvailable                               = numberAvailable - 1
  83.     end do
  84.     type(Vec2_t), dimension(numberAvailable) availablePositions
  85.     type(Vec2_t) :: add
  86.     integer      :: posIndex = 1
  87.     do i = 1, boardSize%y
  88.         do j = 1, boardSize%x
  89.             if (available(i, j)) then
  90.                 add%x                        = j
  91.                 add%y                        = i
  92.                 availablePositions(posIndex) = add
  93.                 posIndex                     = posIndex + 1
  94.             end if
  95.         end do
  96.     end do
  97.  
  98.     NewAppleLocation = availablePositions(RandomRange(1, numberAvailable))
  99. end function NewAppleLocation
  100.  
  101. program snake
  102.     use, intrinsic :: iso_c_binding, only: c_null_char
  103.     use :: m_ncurses
  104.     use :: posix
  105.     implicit none
  106.  
  107.     type Vec2_t
  108.         integer :: x, y
  109.     end type
  110.  
  111.     enum, bind(c)
  112.         enumerator :: SnakeDirection_Up = 1
  113.         enumerator :: SnakeDirection_Down
  114.         enumerator :: SnakeDirection_Left
  115.         enumerator :: SnakeDirection_Right
  116.         enumerator :: SnakeDirection_None
  117.     end enum
  118.  
  119.     type Player_t
  120.         type(Vec2_t)                            :: pos
  121.         integer                                 :: direction
  122.         type(Vec2_t), dimension(:), allocatable :: tail
  123.     end type
  124.  
  125.     integer             :: rc
  126.     integer (kind = 16) :: input
  127.     logical             :: run = .true.
  128.     type(Player_t)      :: player
  129.     integer             :: sleepTime = 100 ! 1000/10 ms (10fps)
  130.     integer             :: i ! iterator
  131.     type(Vec2_t)        :: boardSize
  132.     integer             :: score = 0
  133.     type(Vec2_t)        :: apple
  134.  
  135.     player%pos%x     = 5
  136.     player%pos%y     = 5
  137.     player%direction = SnakeDirection_None
  138.     allocate(player%tail(0))
  139.  
  140.     boardSize%x = 30
  141.     boardSize%y = 15
  142.    
  143.     call IOHandle_Init
  144.  
  145.     do while (run)
  146.         ! handle input
  147.         input = getch()
  148.         select case (input)
  149.             case (KEY_RIGHT)
  150.                 player%direction = SnakeDirection_Right
  151.             case (KEY_LEFT)
  152.                 player%direction = SnakeDirection_Left
  153.             case (KEY_UP)
  154.                 player%direction = SnakeDirection_Up
  155.             case (KEY_DOWN)
  156.                 player%direction = SnakeDirection_Down
  157.             case (ichar('q'))
  158.                 run = .false.
  159.         end select
  160.  
  161.         ! update player
  162.         select case (player%direction)
  163.             case (SnakeDirection_Right)
  164.                 player%pos%x = player%pos%x + 1
  165.             case (SnakeDirection_Left)
  166.                 player%pos%x = player%pos%x - 1
  167.             case (SnakeDirection_Down)
  168.                 player%pos%y = player%pos%y + 1
  169.             case (SnakeDirection_Up)
  170.                 player%pos%y = player%pos%y - 1
  171.         end select
  172.  
  173.         ! render
  174.         call ClearScreen
  175.         do i = 0, boardSize%y
  176.             rc = mvhline(i, 0, ichar('.', 8), boardSize%x)
  177.         end do
  178.  
  179.         rc = attron(A_REVERSE);
  180.         rc = mvaddch(player%pos%y, player%pos%x, ichar('#', 8))
  181.         rc = attroff(A_REVERSE);
  182.  
  183.         rc = refresh()
  184.        
  185.         rc = napms(sleepTime)
  186.     end do
  187.  
  188.     deallocate(player%tail)
  189.     call IOHandle_Quit
  190.  
  191.     print *, "Your score was", score
  192. end program snake
  193.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement