Skip to content

Commit

Permalink
Hangman
Browse files Browse the repository at this point in the history
Compile all files before Play_Hangman.f90.
  • Loading branch information
Jaz-JThompson authored Dec 20, 2023
1 parent c060ca9 commit 762d61e
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 0 deletions.
23 changes: 23 additions & 0 deletions AsciiHangman.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module DrawAsciiHangman
implicit none
contains
subroutine AsciiManLevel(numMistakes)
implicit none
integer :: numMistakes
character(80), dimension(7) :: hangmanStages
integer :: ii

! initalise Ascii art using array
hangmanStages(1) = ' +---+'
hangmanStages(2) = ' | |'
hangmanStages(3) = ' O |'
hangmanStages(4) = ' /|\ |'
hangmanStages(5) = ' / \ |'
hangmanStages(6) = ' |'
hangmanStages(7) = '======='

do ii = 1, numMistakes
print *, hangmanStages(ii)
end do
end subroutine AsciiManLevel
end module DrawAsciiHangman
108 changes: 108 additions & 0 deletions GuessLetter.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
module GuessLetter
implicit none
public :: AskForLetter, GetPositions

contains

function AskForLetter() result(letter)
implicit none
character(1) :: letter

! prompt user input
write(*,*) "Enter one letter: "

! read in the letter
read(*,*) letter
end function AskForLetter

! Prints the underscore of the number of letters in word
function PrintLen(wordLen) result(guessString)
character(3) :: tile
integer, intent(in) :: wordLen
integer :: ii
character((wordLen*3)) :: guessString

tile = ' _ '
guessString = repeat(tile, wordLen)

end function PrintLen

! Function to count the number of correct letters to end game
function CorrectLetterCounter(positions, randomWord, wordLen, &
guess, inputCounter) result(correctCounter)
character(1), intent(in) :: guess
integer, intent(in) :: wordLen
character(wordLen), intent(in) :: randomWord
integer, dimension(5) :: positions
integer :: ii
integer :: inputCounter
integer :: correctCounter
correctCounter = inputCounter
do ii = 1, 5
if (positions(ii) /= 0) then
correctCounter = correctCounter + 1
end if
end do
end function CorrectLetterCounter


! Make sbroutine that takes positions, word and wordlen and
! prints out guesses in the correct position
function PrintGuess(positions, randomWord, wordLen, guess, &
inputGuessString) result(guessString)

character(1), intent(in) :: guess
integer, intent(in) :: wordLen
character(wordLen), intent(in) :: randomWord
integer, dimension(5) :: positions
integer :: ii
character((wordLen*3)) :: inputGuessString
character((wordLen*3)) :: guessString
integer :: letterPosition
guessString = inputGuessString
do ii = 1, 5
if (positions(ii) /= 0) then
! Print *, "print position", positions(ii)
letterPosition = 3 * (positions(ii) - 1) + 2
guessString(letterPosition:letterPosition) = guess
end if
end do
print *,' ', guessString, ' '
end function PrintGuess

! Get the postions of the guess letter in rand word
function GetPositions(randomWord,wordLen,guess) result(positions)
character(1), intent(in) :: guess
integer, intent(in) :: wordLen
character(wordLen), intent(in) :: randomWord
integer, dimension(5) :: positions
integer :: ii
integer :: numRepeats

! initialise the number of repeated letters
numRepeats = 0

! print *, randomWord
! Check to see if guessed letter is in word
do ii = 1, len(randomWord)
! print *, "check iterator ii: ", ii
if (randomWord(ii:ii) == guess) then
!Append he postiton to the positions array
numRepeats = numRepeats + 1
positions(numRepeats) = ii
! print *, "iterator/letter position: ", ii
! print *,"letter being scanned: ", randomWord(ii:ii)
! print *, "Position : ", positions
end if
end do
positions((numRepeats+1):) = 0

! Trim the array to get the positions of the repeats

! print *, "num times letter repeats: ", numRepeats
! print *, "letter found in: ", positions

end function GetPositions

end module GuessLetter

107 changes: 107 additions & 0 deletions Play_Hangman.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
program PlayHangman
! ####################################################
! Initalise modules for the Hangman game
! ####################################################
use RandomWordModule
use DrawAsciiHangman
use GuessLetter


implicit none
character(20) :: word
integer :: wordLen
character(:), allocatable :: guessString
integer :: numMistakes
integer :: maxIncorrect
logical :: continueGame
character(1), dimension(26) :: guess
integer :: ii, trys
integer, dimension(5) :: positions
integer :: correctCounter
! call random word subroutine to get random word
call SelectRandomWord('words.txt', word)

! display random words
! print *, "Random Word: ", trim(word)
! print *, "Word Length: ", len(trim(word))

! get details of random word
wordLen = len(trim(word))

! initalise incorect count
numMistakes = 0
maxIncorrect = 7
continueGame = .true.
correctCounter = 0
trys = 0
ii = 1

allocate(character(len=wordLen) :: guessString)
guessString = PrintLen(wordLen)

! #######################################################
! Begin game with graphic
print *,"-----------------HANGMAN--------------------"
print *,' ', guessString, ' '
do while (continueGame .and. numMistakes < maxIncorrect)
guess(ii) = AskForLetter()
! print *, "Guessed letter :", guess(ii)
positions = GetPositions(word, wordLen, &
guess(ii))
! print *, "letter occurs in position: ", positions

if (all(positions == 0)) then
! print *, "INCORRECT TRY AGAIN"

numMistakes = numMistakes + 1
print *,' ', guessString, ' '

call AsciiManLevel(numMistakes)
else
! print *, "CORRECT"
guessString = PrintGuess(positions, word, wordLen,&
guess(ii), guessString)
! counts the number of correct spaces filled
correctCounter = CorrectLetterCounter(positions, &
word, wordLen, guess(ii),correctCounter)

if (numMistakes /= 0) then
call AsciiManLevel(numMistakes)
end if

end if


trys = trys + 1
! print *, "Number of letters guessed: ", trys
if (correctCounter == wordLen) then
continueGame = .false.
end if
print *,"--------------------------------------------"

end do

if (numMistakes >= maxIncorrect) then
print *, "-----------------GAME OVER-------------------"
print *, "|| Hidden word: ", word
print *, "|| Number of letters guessed: ", trys
print *, "---------------------------------------------"
else
print *, "-------------------YOU WIN-------------------"
print *, "|| Hidden word: ", word
print *, "|| Number of letters guessed: ", trys
print *, "---------------------------------------------"
print *, " REWARDS: lucky mushroom"
print *, " _ "
print *, " / O\ "
print *, " (_o__ ) "
print *, " |_| "
print *, " "
end if





deallocate(guessString)
end program PlayHangman
47 changes: 47 additions & 0 deletions RandomWordModule.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module RandomWordModule
implicit none
contains
subroutine SelectRandomWord(fileName,randomWord)
implicit none
character(9), intent(in) :: fileName
character(20), intent(out) :: randomWord
integer :: numWords
real(8) :: randomNumber
integer :: randomIndex
integer :: ii, ios

! open the file
open(unit=10,file = fileName, status = 'old', action='read')
! 'old' means opening an existing file

! Count the number of words in the file
numWords = 0 ! initialise no of words
do
read(10, *, iostat=ios) randomWord
if (ios /= 0) exit
numWords = numWords + 1
end do

! Generate random index
! get seed
call random_seed()
! gen random number between [0,1]
call random_number(randomNumber)

randomIndex = 1+modulo(int(randomNumber* numWords), numWords)
! Modulo gets the remainder of the devisor
! e.g. modulo(10,3) = 1 as 10-(3x3)=1

! rewind the file
rewind(10)

! read the random word
do ii = 1, randomIndex
read(10, *) randomWord
end do
! close file
close(10)

end subroutine SelectRandomWord
end module RandomWordModule

15 changes: 15 additions & 0 deletions words.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pink
yellow
dog
cat
fortran
python
happy
balloon
algorithms
programming
compiler
performance
bicycle
chocolate

0 comments on commit 762d61e

Please sign in to comment.