Computer Science Canada

Recognising Typing Error

Author:  Nathan4102 [ Wed Mar 20, 2013 1:39 pm ]
Post subject:  Recognising Typing Error

What is it you are trying to achieve?
I'm trying to get text to appear on a screen as the user types it.


What is the problem you are having?
"Array subscript out of range" Error.


Describe what you have tried to solve this problem
I have read up on chars and Input.Keydown, and I don't see what I'm doing wrong. The examples in the documentation are almost the exact same.


Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
This isn't finished code, but for now, it should just type the typed text in the run window as its being typed, but I get a weird error, "Array subscript out of range" on the line showed below.

Turing:


import GUI

var diagramTitle : int := Pic.FileNew ("diagramTitle.bmp")

var charArray : array 1 .. 26 of char := init ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z")
var message : string := ""
var chars : array char of boolean

%View.Set ("Graphics:1000;645, offscreenonly")

%Pic.Draw (diagramTitle, 0, 0, picCopy)

loop
    Input.KeyDown (chars)
    for i : 1 .. 26
        if chars (charArray (i)) then
            message := message + charArray (i)
        end if
    end for

    if chars ("KEY_ENTER") then %"Array subscript is out of range"
        exit
    end if
   
    cls
    put message
end loop



Please specify what version of Turing you are using
4.1

Author:  Dreadnought [ Wed Mar 20, 2013 1:57 pm ]
Post subject:  Re: Recognising Typing Error

You are using a string, "KEY_ENTER", to access an array. Try looking at the examples in the documentation for Input.KeyDown that use the arrow keys.

Author:  Nathan4102 [ Wed Mar 20, 2013 2:40 pm ]
Post subject:  Re: Recognising Typing Error

Whoops! My bad, :p

One other thing though, is there a way to make it so if I hold a key for more then 100 ms, it doesn't add to the message again? This is my code atm
Turing:
import GUI

var diagramTitle : int := Pic.FileNew ("diagramTitle.bmp")

var charArray : array 1 .. 26 of char := init ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z")
var message : string := ""
var chars : array char of boolean

View.Set ("Graphics:1000;645, offscreenonly")

%Pic.Draw (diagramTitle, 0, 0, picCopy)

loop
    Input.KeyDown (chars)
    for i : 1 .. 26
        if chars (charArray (i)) then
            message := message + charArray (i)
            delay (100)
        end if
    end for

    if chars (KEY_ENTER) then %"Array subscript is out of range"
        exit
    end if

    if chars (KEY_BACKSPACE) then
        if length (message) not= 0 then
            message := message (1 .. (length (message) - 1))
            delay (100)
        end if
    end if

    cls
    put message
    View.Update
end loop

Author:  Dreadnought [ Wed Mar 20, 2013 2:49 pm ]
Post subject:  Re: Recognising Typing Error

Can you keep track of whether or not the key was held down the last time you checked the keyboard?

Author:  Nathan4102 [ Wed Mar 20, 2013 2:53 pm ]
Post subject:  RE:Recognising Typing Error

I don't believe so, I was looking for a Input.KeyUp function but I don't see it. Its ok I guess, it just limits my typing speed a lot. Thanks for all the help!

Author:  Tony [ Wed Mar 20, 2013 3:48 pm ]
Post subject:  RE:Recognising Typing Error

Why not?
code:

var num : int := 2
num := 3

Has the value of num changed? How might you be able to detect that change?

Author:  Nathan4102 [ Thu Mar 21, 2013 1:14 pm ]
Post subject:  Re: Recognising Typing Error

Alright, I think I understand what you mean. I decided to use an array of booleans to detect if the key is being held, but its still not working :/ This is what i've come up with:

E: I've only implemented the boolean thing into the letter part of the typing function.

Turing:
var hold : array 1 .. 29 of boolean

slideNumber := 1

function Typing : boolean

    loop
        Input.KeyDown (chars)
        for i : 1 .. 26
            if chars (charArray (i)) and hold(i) = false then
                message := message + charArray (i)
                delay (100)
                hold(i) := true
            else
                hold(i) := false
            end if
        end for

        if chars (chr (32)) then
            message := message + " "
            delay (100)
        end if

        if chars (chr (34)) then
            message := message + chr (34)
            delay (100)
        end if

        if chars (KEY_ENTER) then
            result true
        end if

        if chars (KEY_BACKSPACE) then
            if length (message) not= 0 then
                message := message (1 .. (length (message) - 1))
                delay (100)
            end if
        end if

        Draw.FillBox (100, 5, 300, 35, white)
        Draw.Text (message, 100, 5, defFontID, black)
        View.Update
    end loop
end Typing

Author:  Tony [ Thu Mar 21, 2013 1:53 pm ]
Post subject:  RE:Recognising Typing Error

right idea, but you might be overcomplicating things.

Input.KeyDown takes a snapshot of the state of the keyboard. For each key you get a boolean value, resulting in 2 states:

(U)p
(D)own

If you take two snapshots (Input.Keydown as it was some time in the past) and current state, you get 2 bits, corresponding to 4 states!

UU
UD
DD
DU

A much better resolution of what is happening on the keyboard.

The trick is to properly transition between frames (read keyboard only once per frame; save state from frame to frame).

Author:  Nathan4102 [ Thu Mar 21, 2013 2:57 pm ]
Post subject:  Re: Recognising Typing Error

Wow, thanks so much! I didn't really understand Input.Keydown before, I think I get it now. This is the final result, and it works perfectly! Smile

Turing:
var prev_chars : array char of boolean
var alternate : int
var start : boolean := false

slideNumber := 1

function Typing : boolean
    loop
        Input.KeyDown (chars)
       
        for i : 1 .. 26
            if chars (charArray (i)) and chars(charArray(i)) not= prev_chars(charArray(i)) then
                message := message + charArray (i)
                delay (10)
            end if
        end for

        if chars (chr (32)) and chars(chr(32)) not= prev_chars(chr(32)) then
            message := message + " "
            delay (10)
        end if

        if chars (chr (34)) and chars(chr(34)) not= prev_chars(chr(34)) then
            message := message + chr (34)
            delay (10)
        end if

        if chars (KEY_ENTER) then
            result true
        end if

        if chars (KEY_BACKSPACE) and chars(KEY_BACKSPACE) not= prev_chars(KEY_BACKSPACE) then
            if length (message) not= 0 then
                message := message (1 .. (length (message) - 1))
                delay (10)
            end if
        end if
       
        prev_chars := chars

        Draw.FillBox (100, 0, 300, 35, white)
        Draw.Text (message, 100, 5, defFontID, black)
        View.Update
    end loop
end Typing


: