Dot-memory test

PennController for IBEX Forums Support Dot-memory test

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #9862
    April
    Participant

    Hi Jeremy,

    I am working on creating a dot-memory test, and I believe I’ve made some progress, but I might totally be on the wrong track. Here is what I have so far: https://farm.pcibex.net/r/PMcWya/

    I was able to create a 3×3 grid and manipulate the position of the dots (black squares) on the grid. The participants will be asked to remember the location of black squares and reproduce the pattern. I tried a couple of things with the Selector element, but I couldn’t make it work. Also, I will need to provide feedback for the participants as to whether the pattern they produced was a match or not. Is there a way to make this work on PCIbex? How should I proceed? I don’t have much experience with HTML or JavaScript, but if it is the only way to do it, I’ll do my best.

    I truly appreciate any help you may provide!

    Best,
    Ebru

    #9878
    Jeremy
    Keymaster

    Hi Ebru,

    You could get there by using the Selector element, if you created one per cell, but the code would quickly become cumbersome. A more concise solution would be to use three Scale elements, one per row, that you set as checkboxes. Then you manipulate the aesthetics to make a checked option appear as a black square, and an unchecked option as a white square

    The test part in wait is a little tricky, because up to PennController 2.0, .test.selected does not behave as expected on a checkbox Scale. However, one can write some concise javascript code to test that the right boxes are (un)selected

    Here’s the script:

    Template("dotmemorization.csv", row =>
        newTrial("dot-pattern",
            defaultScale.checkbox().center().log().print()
            ,
            newScale("row1", " ", " ", " "),newScale("row2", " ", " ", " "),newScale("row3", " ", " ", " ")
            ,
            getScale("row1").select(row.r1c1==1?0:-1).select(row.r1c2==1?1:-1).select(row.r1c3==1?2:-1),
            getScale("row2").select(row.r2c1==1?0:-1).select(row.r2c2==1?1:-1).select(row.r2c3==1?2:-1),
            getScale("row3").select(row.r3c1==1?0:-1).select(row.r3c2==1?1:-1).select(row.r3c3==1?2:-1)
            ,
            newTimer(850).start().wait()
            ,
            getScale("row1").unselect(0,"log").unselect(1,"log").unselect(2,"log").remove(),
            getScale("row2").unselect(0,"log").unselect(1,"log").unselect(2,"log").remove(),
            getScale("row3").unselect(0,"log").unselect(1,"log").unselect(2,"log").remove()
            ,
            newText('inst', 'Now produce the pattern').css("margin-bottom","20px").print().center()
            ,
            getScale("row1").print(),getScale("row2").print(),getScale("row3").print()
            ,
            newButton("press")
                .print()
                .wait( 
                    newFunction( 
                        ()=>[...document.querySelectorAll(".PennController-Scale input")].map(c=>Number(c.checked)).join('') 
                    )
                    .test.is([row.r1c1,row.r1c2,row.r1c3,row.r2c1,row.r2c2,row.r2c3,row.r3c1,row.r3c2,row.r3c3].join('') )
                    .failure( newText("Try again!").print() )
                )
                .center()
        )
    )

    And here’s what to put in global_main.css to make the checkboxes appear as white and black boxes:

    .PennController-row1 input, .PennController-row2 input, .PennController-row3 input {
        display: none;
    }
    .PennController-row1 input + label, .PennController-row2 input + label, .PennController-row3 input + label {
        display: inline-block;
        width: 40px;
        height: 40px;
        background-color: white;
        border: solid 1px grey;
    }
    .PennController-row1 input:checked + label, .PennController-row2 input:checked + label, .PennController-row3 input:checked + label {
        background-color: black;
    }

    Jeremy

    #9940
    April
    Participant

    Hi Jeremy,

    That works like a charm, THANK you!!

    One quick follow-up question, if I may: How can I modify the code such that a new trial starts after a ‘failure’? This code does not let me pass to a new trial until the pattern is reproduced correctly. I’d still like to provide feedback for a wrong match (e.g., ‘Be careful next time), and continue with the next trial. I played with the position of some parentheses, but couldn’t make it work.

    Thanks for your patience,
    Best,
    Ebru

    #9948
    Jeremy
    Keymaster

    Hi Ebru,

    When you place a test command inside a wait command, the latter is only validated when the test succeeds. If you’d rather always validate the wait command, just leave its parentheses blank (ie. .wait()) and move the test below it if you’d like to show some feedback once the participant clicks the button. The question then is how to move from printing the feedback to the next trial; for example, you could simply wait 2s:

            newButton("press")
                .center()
                .print()
                .wait()
            ,
            newFunction( 
                    ()=>[...document.querySelectorAll(".PennController-Scale input")].map(c=>Number(c.checked)).join('') 
                )
                .test.is([row.r1c1,row.r1c2,row.r1c3,row.r2c1,row.r2c2,row.r2c3,row.r3c1,row.r3c2,row.r3c3].join('') )
                .success( newText("Good job!").print() )
                .failure( newText("Incorrect! Better luck next time").print() )
            ,
            newTimer(2000).start().wait()
    

    Jeremy

Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.