1. guess the animal - editor
previously I posted a persistent database version
of guess the animal (available on euphoria web site)
the following is a database editor for the database used
by that program.
Overall the database isn't extendable into other applications,
but you might find the mechanism used to link nodes of interest.
-------------------
---------------------------
-- DATA EDITOR FOR --
-- GUESS THE ANIMAL --
-- (C) Doug Edmunds --
-- VERS 1.20 8/9/97 --
---------------------------
include get.e
include wildcard.e
constant
-- NODE_TYPE = 1,
DESCRIPTION = 1,
ANIMAL = 2,
QUESTION = 2,
WHEN_TRUE = 3,
WHEN_FALSE = 4,
EDIT_VALUE = 5,
ADD_ANIMAL = 6,
REVIEW_CHAIN = 7,
UP = 1,
QUIT = 0
constant
TRUE = 1,
FALSE = 0
constant
KEYBOARD = 0,
SCREEN = 1
constant
DB_NAME = "animal.dat",
BACK_NAME = "animal.dbk"
--ideally, there would be no global variables (horrid bugs usually result)
object database, pl, prev_answer
integer db, data_changed
--initialize
data_changed = FALSE
function Yes() -- returns TRUE if the answer is yes
object answer
answer = '?'
while answer = '?' do
answer = upper(gets(KEYBOARD))
if length(answer) > 1 then
if answer[1] = 'Y' then
answer = TRUE
elsif answer[1] = 'N' then
answer = FALSE
else
answer = '?'
end if
else
answer = '?'
end if
if answer = '?' then
puts(SCREEN, "\nPlease answer Y or N: ")
end if
end while
return answer
end function
function MoveAround(sequence chain)
object answer
if length(chain) > 0 and database[pl][1] = DESCRIPTION then
puts(SCREEN, "\n\tSelect: Edit Yes No Up Review Quit: ")
elsif length(chain) = 0 and database[pl][1] = DESCRIPTION then
puts(SCREEN, "\n\tSelect: Edit Yes No Review Quit: ")
else
--Animal
puts(SCREEN, "\n\tSelect: Edit Add Up Review Quit: ")
end if
answer = '?'
while answer = '?' do
answer = upper(gets(KEYBOARD))
if length(answer) > 1 then
if answer[1] = 'Y' then
answer = WHEN_TRUE
elsif answer[1] = 'N' then
answer = WHEN_FALSE
elsif answer[1] = 'U' then
answer = UP
elsif answer[1] = 'Q' then
answer = QUIT
elsif answer[1] = 'E' then
answer = EDIT_VALUE
elsif answer[1] = 'A' then
answer = ADD_ANIMAL
elsif answer[1] = 'R' then
answer = REVIEW_CHAIN
else
answer = '?'
end if
else
answer = '?'
end if
if answer = '?' then
if length(chain) > 0 and database[pl][1] = DESCRIPTION then
puts(SCREEN, "\n\tSelect: Edit Yes No Up Review Quit: ")
elsif length(chain) = 0 and database[pl][1] = DESCRIPTION then
puts(SCREEN, "\n\tSelect: Edit Yes No Review Quit: ")
else
puts(SCREEN, "\n\tSelect: Edit Add Up Review Quit: ")
end if
end if
end while
return answer
end function
function Change_Value(sequence old_value)
sequence new_value
printf(SCREEN, "\n\n\t-----EDIT MODE-----\n\tLeave blank to
exit",{old_value})
printf(SCREEN, "\n\tOld Value: %s", {old_value})
printf(SCREEN, "\n\tNew Value: ", {old_value})
new_value = gets(KEYBOARD)
if length(new_value) > 1 then
printf(SCREEN, "\n\tSave these changes (to memory)? ", {old_value})
if Yes() then
data_changed = TRUE
new_value = new_value[1..length(new_value)-1] -- remove return key
if new_value[length(new_value)] = '?' then
new_value = new_value[1..length(new_value)-1] --remove ques.mark
end if
return new_value
else
return old_value
end if
else
return old_value
end if
end function
function Add_Animal (object database_entry, sequence chain)
object new_animal, new_question, new_record
puts(SCREEN, "\n\tName of new animal: ")
new_animal = gets(KEYBOARD)
if length(new_animal) > 1 then
new_animal = new_animal[1..length(new_animal)-1]
database = append(database, {ANIMAL, new_animal})
new_record = length(database)
else
return database_entry
end if
while TRUE do
printf(SCREEN, "\n%s%s%s%s\n",
{"Type a question to distinguish ",
database[pl][QUESTION], " from ", new_animal})
new_question = gets(KEYBOARD)
if length(new_question) >1 then
new_question = new_question[1..length(new_question)-1]
if new_question[length(new_question)] = '?' then
new_question = new_question[1..length(new_question)-1]
end if
exit
end if
end while
printf(SCREEN, "\nFor %s the answer would be: ", {new_animal})
if Yes() then
database = append(database, {DESCRIPTION, new_question, new_record, pl})
else
database = append(database, {DESCRIPTION, new_question, pl, new_record})
end if
database[chain[length(chain)]][prev_answer] = length(database)
data_changed = TRUE
return database_entry
end function
procedure Review_Chain (sequence chain)
-- review the links that got to this point
puts(1,"\n")
if length(chain) = 0 then
puts(1,"\n\t--top of chain--")
else
for x = 1 to length(chain)-1 do
printf(1,"\n\t%s",{database[chain[x]][2]})
if database[chain[x]][WHEN_TRUE] = chain[x+1] then
puts(1, "\t-- YES")
else
puts(1, "\t-- NO")
end if
end for
printf(1,"\n\t%s",{database[chain[length(chain)]][2]})
if database[chain[length(chain)]][WHEN_TRUE] = pl then
puts(1, "\t-- YES")
else
puts(1, "\t-- NO")
end if
end if
end procedure
global procedure Main_Loop()
-- updates database of animal information
object answer
integer direction
sequence chain --history of traversal
direction = 1
pl = 1 --db record now visiting
chain ={}
printf(SCREEN, "%s\n",
{"\nHit <cr> when you are ready, q to quit"})
answer = gets(KEYBOARD)
if length(answer) > 1 then
if upper(answer[1]) = 'Q' then
return
end if
end if
while direction != QUIT do
printf(SCREEN, "\n\n\tBranch: %s",
{database[pl][QUESTION]})
if database[pl][1] = DESCRIPTION then
printf(SCREEN, "\n\t Yes: %s \n\t No: %s",
{database[database[pl][3]][2],
database[database[pl][4]][2]})
end if
direction = MoveAround(chain)
if direction = WHEN_TRUE and database[pl][1] = DESCRIPTION then
chain = append (chain, pl)
pl = database[pl][WHEN_TRUE]
prev_answer = WHEN_TRUE
elsif direction = WHEN_FALSE and database[pl][1] = DESCRIPTION then
chain = append (chain,pl)
pl = database[pl][WHEN_FALSE]
prev_answer = WHEN_FALSE
elsif direction = UP and length(chain) > 0 then
pl = chain[length(chain)]
chain = chain[1..length(chain)-1]
elsif direction = EDIT_VALUE then
database[pl][2] = Change_Value(database[pl][2])
elsif direction = ADD_ANIMAL then
Review_Chain(chain)
database[pl] = Add_Animal(database[pl], chain)
elsif direction = REVIEW_CHAIN then
Review_Chain(chain)
end if
end while
end procedure
procedure Open_File()
-- open database file on disk
sequence new_database
--the next line starts a database if one is not found
new_database = {{1,"Change to a Yes-No question",2,3},
{2,"Put the Yes answer here"},
{2,"Put the No answer here"}}
db = open(DB_NAME, "r")
if db = -1 then
puts(1, "\nError opening data file\nIf first use, just continue")
puts(1, "\nContinue? ")
if Yes() then
database = new_database
db = open (DB_NAME,"w")
print (db, database)
close (db)
db = open(DB_NAME,"r")
else
abort(1)
end if
end if
database = get (db)
if database[1] != 0 then
puts(1, "\nError accessing data\n")
abort(1)
else
database = database[2]
end if
close(db)
end procedure
procedure Save_and_Close_File()
-- save the data to file for next run
if data_changed then
printf(SCREEN, "%s", {"\n\tMake changes permanent? (Save to disk) "})
if Yes() then
system("copy " & DB_NAME & " " & BACK_NAME & " > NUL", 2)
db = open(DB_NAME, "w")
if db = -1 then
system("copy " & BACK_NAME & " " & DB_NAME & " > NUL", 2)
puts (1,"\nCan't save database - recover from backup file")
abort(1)
end if
print (db, database)
end if
close (db)
end if
end procedure
---main program starts here
printf(SCREEN, "%s\n",
{"\nEditor for Animaldb.ex Database\nPress first letter of selection"})
Open_File()
Main_Loop() -- loop
Save_and_Close_File()
close(db)