From Test-Scratch-Wiki
A chat bot is a program which allows you to talk to the computer or application. This can be developed by solely using Scratch; it involves many lists, operators, and the ask [] and wait
block in particular. This tutorial shows how to make one yourself.
Brief Description
Basically, to create a chat bot you need to use the "ask" block to enter a message. Then, the project takes that message, breaks it apart into words, and scans the list of words for specific words. Then, if your message contains those specific words, the chat bot can respond a pre-set message back to you. To break apart the answer variable into words, you have to repetitively add each letter to a list until you reach a space, and then you create a new item in the list and continue adding the letters, forming words. To program this, you will need only one list:
- words
and one or two variables:
(letter #)
(pick)
Note: | the variables and lists can be named anything you want them to |
Programming the Bot
The following code replication can be used to make the bot respond to your messages. All these scripts can go in any sprite.
when gf clicked forever ask [type a message] and wait set [letter # v] to [1] //so the iteration begins with the first letter of the answer delete (all v) of [words v] //clears the list of words; the first step is separating the words into a list insert [] at (1 v) of [words v] //it needs a blank item to start out repeat (length of (answer)) //one repetition for each letter if <(letter (letter #) of (answer)) = [ ]> then //note that a space is inserted into this string, not nothing insert [] at (1 v) of [words v] //since it is a space, create a new item else replace item (1 v) of [words v] with (join (item (1 v) of [words v]) (letter (letter #) of (answer))) //otherwise, add the letter to the current word end change [letter # v] by [1] //move on to the next letter end if <[words v] contains [hello]> then //word detection say [Hello to you, too!] for (2) secs//response end if <[words v] contains [like]> then set [pick v] to (pick random (1) to (2)) //for use in alternate responses if <(pick) = [1]> then say [I like that, too!] for (2) secs else say [Really? I don't like that too much.] for (2) secs end end end
For example, if you entered in "I like Scratch" the bot may respond "I like that too!" or "Really? I don't like that too much" because the list of words contained "like". The script can be made more complex by breaking it down into individual likes and more responses. The "pick" variable is used solely for making it respond one of multiple possible messages. However, for instance, you type in "I like Scratch", and the bot may respond "I like that too!", but if you type "I like Scratch" again, it might say "Really? I don't like that too much.". To prevent this, you can make some lists to store words that the bot already responded to.
Make two lists:
- Likes
- Dislikes
Then change this part of the script:
if <[words v] contains [like]> then set [pick v] to (pick random (1) to (2)) //for use in alternate responses if <(pick) = [1]> then add (item (last v) of [words v]) to [Likes v] else add (item (last v) of [words v]) to [Dislikes v] end if <(pick) = [1]> then if <not <[Likes v] contains (item (last v) of [words v]> say [I like that, too!] for (2) secs else delete (last v) of [Likes v] say [Didn't I already tell you I liked it?] for (2) secs end else if <not <[Dislikes v] contains (item (last v) of [words v]> say [Really? I don't like it too much.] for (2) secs else delete (last v) of [Dislikes v] say [Didn't I already tell you I didn't like it?] for (2) secs
Note: | This might not work if you have more than one word after "like" |
Final Product
Excluding scripts in the next section, the whole script would be something like this:
when gf clicked forever ask [type a message] and wait set [letter # v] to [1] //so the iteration begins with the first letter of the answer delete (all v) of [words v] //clears the list of words; the first step is separating the words into a list insert [] at (1 v) of [words v] //it needs a blank item to start out repeat (length of (answer)) //one repetition for each letter if <(letter (letter #) of (answer)) = [ ]> then //note that a space is inserted into this string, not nothing insert [] at (1 v) of [words v] //since it is a space, create a new item else replace item (1 v) of [words v] with (join (item (1 v) of [words v]) (letter (letter #) of (answer))) //otherwise, add the letter to the current word end change [letter # v] by [1] //move on to the next letter end if <[words v] contains [hello]> then //word detection say [Hello to you, too!] for (2) secs//response end if <[words v] contains [like]> then set [pick v] to (pick random (1) to (2)) //for use in alternate responses if <(pick) = [1]> then add (item (last v) of [words v]) to [Likes v] else add (item (last v) of [words v]) to [Dislikes v] end if <(pick) = [1]> then if <not <[Likes v] contains (item (last v) of [words v]> say [I like that, too!] for (2) secs else delete (last v) of [Likes v] say [Didn't I already tell you I liked it?] for (2) secs end else if <not <[Dislikes v] contains (item (last v) of [words v]> say [Really? I don't like it too much.] for (2) secs else delete (last v) of [Dislikes v] say [Didn't I already tell you I didn't like it?] for (2) secs
Taking it Further
To make the chat bot more realistic, you can create a separate list of previously stored words from your old entered messages, and make the bot refer to those later in the conversation. For example, if you tell it that you like programming, and then later say you like Scratch, it can relate the two using the list of old words and say "Of course you like Scratch, you like programming" by sensing if the list of old words contains "programming".
You could also change the script to make the bot understand even more words, by using this:
if <[words v] contains [Word you would like bot to understand]> then //word detection say [Response you would like your bot to say] for (2) secs//response end