Here is the Qbasic code
1 REM Copyright (c) 2013 the authors listed at the following URL, and/or
2 REM the authors of referenced articles or incorporated external code:
3 REM http://en.literateprograms.org/Chatterbot_(QBASIC)?action=history&offset=20121023043425
4 REM
5 REM Permission is hereby granted, free of charge, to any person obtaining
6 REM a copy of this software and associated documentation files (the
7 REM "Software"), to deal in the Software without restriction, including
8 REM without limitation the rights to use, copy, modify, merge, publish,
9 REM distribute, sublicense, and/or sell copies of the Software, and to
10 REM permit persons to whom the Software is furnished to do so, subject to
11 REM the following conditions:
12 REM
13 REM The above copyright notice and this permission notice shall be
14 REM included in all copies or substantial portions of the Software.
15 REM
16 REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 REM EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 REM MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 REM IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 REM CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 REM TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 REM SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 REM
24 REM Retrieved from: http://en.literateprograms.org/Chatterbot_(QBASIC)?oldid=18699
25
26 QChatt:
27 DEFINT A-Z
28 GOSUB Initialise
29 GOSUB LoadData
30 GOSUB Converse
31 GOSUB StoreData
32 SYSTEM
33
34 Initialise:
35 LET DictionarySize = 1000
36 DIM Context$(DictionarySize) 'The character sequences that QChatt has already seen
37 DIM Alternatives$(DictionarySize) 'The characters that QChatt may print after recognising a sequence.
38 LET EmptyRow = 0
39 LET EndOfResponseCharacter$ = CHR$(180)
40 LET ContextLength = 6 'A bigger value makes QChatt more grammatical but slower learning.
41 LET CurrentContext$ = STRING$(ContextLength, EndOfResponseCharacter$)
42 LET DictionaryFile$ = "QCHATT.MEM"
43 RANDOMIZE TIMER
44 RETURN
45 Converse:
46 DO
47 LINE INPUT "Human: "; Response$
48 IF Response$ = "" THEN EXIT DO
49 LET Response$ = Response$ + EndOfResponseCharacter$
50 GOSUB MemoriseHumanResponse
51 LET Response$ = ""
52 GOSUB GenerateComputerResponse
53 PRINT "Computer: "; Response$
54 LOOP
55 RETURN
56 MemoriseHumanResponse:
57 DO WHILE Response$ > ""
58 LET CurrentCharacter$ = LEFT$(Response$, 1)
59 LET Response$ = MID$(Response$, 2)
60 GOSUB InsertCharacter
61 LET CurrentContext$ = MID$(CurrentContext$, 2) + CurrentCharacter$
62 LOOP
63 RETURN
64 GenerateComputerResponse:
65 DO
66 GOSUB Lookup
67 LET CurrentCharacter$ = MID$(Alternatives$(DictionaryIndex), INT(RND * LEN(Alternatives$(DictionaryIndex))) + 1, 1)
68 IF CurrentCharacter$ = "" THEN
69 EXIT DO
70 ELSE
71 LET CurrentContext$ = MID$(CurrentContext$, 2) + CurrentCharacter$
72 IF CurrentCharacter$ = EndOfResponseCharacter$ THEN
73 EXIT DO
74 ELSE
75 LET Response$ = Response$ + CurrentCharacter$
76 END IF
77 END IF
78 LOOP
79 RETURN
80 InsertCharacter:
81 GOSUB Lookup
82 IF INSTR(Alternatives$(DictionaryIndex), CurrentCharacter$) = 0 THEN
83 LET Alternatives$(DictionaryIndex) = Alternatives$(DictionaryIndex) + CurrentCharacter$
84 END IF
85 RETURN
86 Lookup:
87 LET Context$(EmptyRow) = CurrentContext$
88 LET DictionaryIndex = 0
89 DO WHILE CurrentContext$ <> Context$(DictionaryIndex)
90 LET DictionaryIndex = DictionaryIndex + 1
91 LOOP
92 IF DictionaryIndex = EmptyRow AND DictionaryIndex < DictionarySize THEN
93 LET Alternatives$(EmptyRow) = ""
94 LET EmptyRow = DictionaryIndex + 1
95 END IF
96 RETURN
97 LoadData:
98 OPEN DictionaryFile$ FOR APPEND AS #1
99 CLOSE #1
100 OPEN DictionaryFile$ FOR INPUT AS #1
101 DO WHILE EmptyRow < DictionarySize AND NOT EOF(1)
102 LINE INPUT #1, Context$(EmptyRow)
103 LINE INPUT #1, Alternatives$(EmptyRow)
104 LET EmptyRow = EmptyRow + 1
105 LOOP
106 CLOSE #1
107 RETURN
108
109 StoreData:
110 OPEN DictionaryFile$ FOR OUTPUT AS #1
111 FOR DictionaryIndex = 0 TO EmptyRow - 1
112 PRINT #1, Context$(DictionaryIndex)
113 PRINT #1, Alternatives$(DictionaryIndex)
114 NEXT
115 CLOSE #1
116 RETURN
So far this is what I have in DBpro
if file exist("QCHATT.TXT")=0
make file "QCHATT.TXT"
endif
QChatt:
GOSUB Initialise
GOSUB LoadData
GOSUB Converse
GOSUB StoreData
end
Initialise:
DictionarySize = 1000
DIM Context$(DictionarySize) //The character sequences that QChatt has already seen
DIM Alternatives$(DictionarySize) //The characters that QChatt may print after recognising a sequence.
EmptyRow = 0
EndOfResponseCharacter$ = CHR$(40) //original 180
ContextLength = 6 //A bigger value makes QChatt more grammatical but slower learning.
CurrentContext$ = STRING$(ContextLength, EndOfResponseCharacter$)// I dont't understand this line.
DictionaryFile$ = "QCHATT.TXT"
RANDOMIZE TIMER()
RETURN
Converse:
DO
INPUT "Human: ", Response$
cls
IF Response$ = "" THEN EXIT
Response$ = Response$ + EndOfResponseCharacter$
GOSUB MemoriseHumanResponse
Response$ = ""
GOSUB GenerateComputerResponse
PRINT "Computer: "; Response$
LOOP
RETURN
MemoriseHumanResponse:
WHILE Response$ > ""
CurrentCharacter$ = LEFT$(Response$, 1)
Response$ = MID$(Response$, 2)
GOSUB InsertCharacter
CurrentContext$ = MID$(CurrentContext$, 2) + CurrentCharacter$
ENDWHILE
RETURN
GenerateComputerResponse:
DO
GOSUB Lookup
CurrentCharacter$ = MID$(Alternatives$(DictionaryIndex), INT(RND(1) * LEN(Alternatives$(DictionaryIndex))) + 1, 1)
IF CurrentCharacter$ = ""
EXIT
ELSE
CurrentContext$ = MID$(CurrentContext$, 2) + CurrentCharacter$
IF CurrentCharacter$ = EndOfResponseCharacter$
EXIT
ELSE
Response$ = Response$ + CurrentCharacter$
ENDIF
ENDIF
LOOP
RETURN
InsertCharacter:
GOSUB Lookup
IF INSTR(Alternatives$(DictionaryIndex), CurrentCharacter$) = 0
Alternatives$(DictionaryIndex) = Alternatives$(DictionaryIndex) + CurrentCharacter$
ENDIF
RETURN
Lookup:
Context$(EmptyRow) = CurrentContext$
DictionaryIndex = 0
WHILE CurrentContext$ <> Context$(DictionaryIndex)
DictionaryIndex = DictionaryIndex + 1
ENDWHILE
IF DictionaryIndex = EmptyRow AND DictionaryIndex < DictionarySize
Alternatives$(EmptyRow) = ""
EmptyRow = DictionaryIndex + 1
ENDIF
RETURN
LoadData:
open to read 1, DictionaryFile$
//OPEN DictionaryFile$ FOR APPEND AS #1
//CLOSE #1
//OPEN DictionaryFile$ FOR INPUT AS #1
WHILE EmptyRow < DictionarySize AND FILE END(1)=0
read string 1, Context$(EmptyRow)
read string 1, Alternatives$(EmptyRow)
EmptyRow = EmptyRow + 1
ENDWHILE
CLOSE FILE 1
RETURN
StoreData:
OPEN DATAFILE TO Append 1, DictionaryFile$
//OPEN DictionaryFile$ FOR OUTPUT AS #1
FOR DictionaryIndex = 0 TO EmptyRow - 1
WRITE DATAFILE STRING 1, Context$(DictionaryIndex)
WRITE DATAFILE STRING 1, Alternatives$(DictionaryIndex)
NEXT DictionaryIndex
CLOSE FILE 1
RETURN
I can't figure out what to do with this line
CurrentContext$ = STRING$(ContextLength, EndOfResponseCharacter$)
I figure that CurrentContext$ equals EndOfResponseCharacter$ multiplied by ContextLength$ but when I try that, I don't get any result as in QBasic.
Any help is appreciated.