You definitely have the right idea with functions, but you could be making more use of functions to shorten your code!
One thing that worries me is this:
function threeSpace()
Line 125, 450, 150, 450
Line 175, 450, 200, 450
Line 225, 450, 250, 450
endfunction
function fourSpace()
Line 125, 450, 150, 450
Line 175, 450, 200, 450
Line 225, 450, 250, 450
Line 275, 450, 300, 450
endfunction
function fiveSpace()
Line 125, 450, 150, 450
Line 175, 450, 200, 450
Line 225, 450, 250, 450
Line 275, 450, 300, 450
Line 325, 450, 350, 450
endfunction
You could replace all of these functions with a single, shorter function:
function drawSpaces(n)
for i=1 to n
line 75+i*50,450,100+i*50
next i
endfunction
Then instead of this code:
li = len(gitem)
if li = 3
threeSpace()
else
if li = 4
threeSpace()
fourSpace()
else
threeSpace()
fourSpace()
fiveSpace()
endif
endif
you can write this:
li = len(gitem)
drawSpaces(li)
Another thing is the lack of formatting in your code. The following is much easier to read:
function HandleError(errors)
inc errors
select errors
case 1
head()
endcase
case 2
body()
endcase
case 3
rleg()
endcase
case 4
lleg()
endcase
case 5
rarm()
endcase
case 6
larm()
endcase
endselect
endfunction errors
Another error is that this command:
is the same as "set text size 0". This is because "normal" is a variable that doesn't exist, and when a variable doesn't exist DBPro interprets that value as zero.
This code can be shortened with a loop:
found = "no"
if guess = itemletters(1)
text 135,425, guess
usedletters = usedletters + 1
found = "yes"
endif
if guess = itemletters(2)
text 185,425, guess
usedletters = usedletters + 1
found = "yes"
endif
if guess = itemletters(3)
text 235,425, guess
usedletters = usedletters + 1
found = "yes"
endif
if guess = itemletters(4)
text 285,425, guess
usedletters = usedletters + 1
found = "yes"
endif
if guess = itemletters(5)
text 335, 425, guess
usedletters = usedletters + 1
found = "yes"
endif
to:
for n=1 to li
if guess=itemletters(n)
text 85+50*n,425,guess
usedletters=usedletters+1
found="yes"
endif
next n
The giant thing of nested if-else statements was unnecessary, and can be replaced with this. I shortened it using the "greater than or equal to" operator.
//if nothing was found, increase the error count
if found="no" then inc Error
if error>=1 then head()
if error>=2 then body()
if error>=3 then rleg()
if error>=4 then lleg()
if error>=5 then rarm()
if error>=6 then larm()
And... I'm sorry to say... the whole while loop is really unclear.
The first problem is the formatting. It's hard for people who aren't already familiar with this code to read it. The second problem is that it's difficult to visualize the flow of the program. A "while" function is supposed to repeat until the condition isn't met, but you jump FROM the while loop to OUTSIDE the while loop, rendering it useless (as far as I can tell). GOTOs are generally considered bad practice for that exact reason.
To solve it, and to help compartmentalize everything, you can make use of global variables. Global variables can be changed from
inside functions, and their values carry over into every other function and loop. All you have to do is add the "global" keyword before your variables:
global num as integer
global gitem as string
global li as integer
global found as string
global Error as integer
global guess as string
global usedletters as integer
global letterguess as integer
So now, instead of using goto to restart the program each time, we're just going to have an initialize function.
function initialize()
cls
rem draw title
title()
rem draw gallows
gallows()
set text size 18
set text font "times new roman"
num = rnd(12)
gitem = wordlist(num)
li = len(gitem)
rem draw underscores
drawSpaces(li)
rem fill the itemletters array
for c = 1 to li
itemletters(c) = mid$(gitem, c)
next c
found=""
Error=0
guess=""
usedletters=0
endfunction
this function resets all variables
So this is the final, readable code. I removed the variable "letterguess", and the functions handleerror and letterwrong, because they weren't being used.
`Hangman
randomize timer()
rem variable declaration section
dim wordlist(12) as string
dim itemletters(5) as string
global num as integer
global gitem as string
global li as integer
global found as string
global Error as integer
global guess as string
global usedletters as integer
rem assignment of value section
wordlist(0) = "queen"
wordlist(1) = "sword"
wordlist(2) = "spear"
wordlist(3) = "noble"
wordlist(4) = "fire"
wordlist(5) = "fief"
wordlist(6) = "serf"
wordlist(7) = "moat"
wordlist(8) = "bows"
wordlist(9) = "sly"
wordlist(10) = "die"
wordlist(11) = "oat"
wordlist(12) = "spy"
initialize()
while guess<> "qq"
input "Guess a letter or press qq to quit: ", guess
found = "no"
rem check for matches
for n=1 to li
if guess=itemletters(n)
text 85+50*n,425,guess
usedletters=usedletters+1
found="yes"
endif
next n
rem if nothing was found, increase the error count
if found="no" then inc Error
if error>=1 then head()
if error>=2 then body()
if error>=3 then rleg()
if error>=4 then lleg()
if error>=5 then rarm()
if error>=6 then larm()
if usedletters = li
sleep 200
CLS
Winner()
sleep 1000
initialize()
endif
if Error = 6
sleep 200
cls
Lose()
sleep 1000
initialize()
endif
endwhile
end
function initialize()
cls
rem draw title
title()
rem draw gallows
gallows()
set text size 18
set text font "times new roman"
num = rnd(12)
gitem = wordlist(num)
li = len(gitem)
rem draw underscores
drawSpaces(li)
rem fill the itemletters array
for c = 1 to li
itemletters(c) = mid$(gitem, c)
next c
found=""
Error=0
guess=""
usedletters=0
endfunction
rem draw titles:
function title()
set text font "algerian"
set text size 32
ink rgb(255, 255, 255), 0
text 250, 80, "Welcome To Hang-Man!"
ink rgb(255, 0, 0), 0
text 252, 82, "Welcome To Hang-Man!"
ink rgb(255, 0, 0), 0
endfunction
function Winner()
set text font "algerian"
set text size 45
ink rgb(255,0,0),0
text 200,45, "You win!!! You win!!!"
ink rgb (0,0,255),0
text 201,46, "You win!!! You win!!!"
endfunction
function Lose()
set text font "algerian"
set text size 45
ink rgb(255,0,0),0
text 200,45, "You Lose!!!"
ink rgb (0,0,255),0
text 201,46, "You Lose!!!"
endfunction
rem Functions to draw body parts:
function gallows()
line 225, 175, 225, 425
line 225, 175, 325, 175
line 325, 175, 325, 225
endfunction
function head()
circle 325, 240, 15
endfunction
function body()
line 325, 255, 325, 310
endfunction
function rleg()
line 325, 310, 300, 360
endfunction
function lleg()
line 325, 310, 350, 360
endfunction
function rarm()
line 325, 255, 300, 295
endfunction
function larm()
line 325, 255, 350, 245
endfunction
rem draw underscores for letters:
function drawSpaces(n)
for i=1 to n
line 75+i*50,450,100+i*50,450
next i
endfunction
So... Now on to your actual question! Sorry, it's just that... it's difficult to help people if their code isn't cleared up first, because whenever you run in to an issue (wrong letter shows up, system doesn't respond), you can't be sure where the problem is until you've made sense of messy code.
Your loading code looks perfect to me. One thing you might have messed up with is that wordarray and wordlist are two separate arrays, so only one will be used. The problem might be that you're trying to load from "hangmanfinal/hangman.txt". This means that if your executable was in "C:\hangmanfinal\", the program would look for hangman.txt in the directory "C:\hangmanfinal\hangmanfinal\hangman.txt". Your code works perfectly for me.
Anyways, it turns out that it's possible to handle words of ANY size, with a word list of ANY length! First what we're going to do is initialize the array with 0 elements:
dim wordlist(-1) as string
dim itemletters(-1) as string
-1 means that they have absolutely NO elements. We can't even say wordlist(0)="HI". Now we're going to create another variable keeping track of the number of elements in "wordlist".
global numwords as integer
numwords=-1
Now we'll want to open word list, read string after string from it, and add each string to the array, increasing its size each time. This code accomplishes that using the "array insert at bottom" command.
open to read 1, "hangman.txt"
while file end(1) = 0
read string 1, words$
rem increase the counter storing the size of wordlist
inc numwords
rem add another element to the array
array insert at bottom wordlist()
rem add the word to the wordlist
wordlist(numwords)=words$
endwhile
close file 1
Now when we pick a random value, we'll say this instead:
num = rnd(numwords)
gitem = wordlist(num)
To fill up the letter array after we've selected a new word, we can do this:
rem empty the itemletters array
undim itemletters()
dim itemletters(-1) as string
rem fill the itemletters array
for c = 0 to li-1
array insert at bottom itemletters()
itemletters(c)=mid$(gitem,c+1)
next c
first the array is emptied by completely redeclaring it. There's also a little quirk here, because now this is programmed so that itemletters starts from the index 0. So we need to subtract one from some parts and add one to other parts. Likewise, the "check for matches" part will have to go from 0 to li-1:
rem check for matches
for n=0 to li-1
if guess=itemletters(n)
text 85+50*n,425,guess
usedletters=usedletters+1
found="yes"
endif
next n