By
Chimp
After watching this movie (https://www.youtube.com/watch?v=cPiDHXtM0VA) I wanted to try the test to see how much i could compete with that chimpanzee so i created this script.
well, actually passing that test is a lot harder than it sounds. With the difficulty set to seven numbers and a display time of one second, I can only remember 2 or 3 numbers ... (what a disappointment)
I can only do better if I reduce the slider to 5 numbers and increase the storage time to 2 seconds (the easyest level), a very poor performance. That chimpanzee is great.
The script offers you a sequence of 10 random quizzes. At the end it gives you the percentage of your "level". The chimpanzee resolves on average 8 out of 10 (80%), so you can compare your performance to that of the chimpanzee.
How to play:
Run the script. At the beginning there are 2 sliders at the bottom of the screen where you can set the difficulty level by varying the memorization time and the amount of numbers to memorize as you like. After setting the difficulty, click the circle on the bottom left to get started.
after the first move the sliders are no longer displayed until the next game, (the game lasts 10 attempts, there is a progress bar at the bottom of the screen to see where you are)
between one test and the other of the ten, click on the circle to move on to the next test
have fun.
#include <GUIConstants.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <WinAPIMisc.au3>
; HotKeySet("{ESC}", "_EndOfGame")
Global $iNumbersToGuess = 7, $iExpositionTime = 1000, $iMatches = 10, $iMatchesWon
Global $aNumbers[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Global $aButtons[10], $aControls[5]
Global $iWinWidth = @DesktopWidth / 2, $iWinHeight = @DesktopHeight / 2, $iButtonXSide = Int($iWinWidth / UBound($aNumbers)), $iButtonYSide = Int($iWinHeight / UBound($aNumbers)), $sWinTitle = "Beat the Chimp"
Global $aX[Int($iWinWidth / $iButtonXSide)], $aY[Int($iWinHeight / $iButtonYSide)], $iNdx = 0, $aPoints[3], $score, $GUIGetMsg, $iDockHeight = 50, $iProgrssHeight = 5
For $i = 0 To (Int($iWinWidth / $iButtonXSide) - 1) * $iButtonXSide Step $iButtonXSide
$aX[$iNdx] = $i
$iNdx += 1
Next
$iNdx = 0
For $i = 0 To (Int($iWinHeight / $iButtonYSide) - 1) * $iButtonYSide Step $iButtonYSide
$aY[$iNdx] = $i
$iNdx += 1
Next
Global Const $iDockLeftBorder = 200, $iForeColor = 0xFFFFFF, $iBackColor = 0x000000
Global $hGUI = GUICreate($sWinTitle, $iWinWidth, $iWinHeight + $iDockHeight + $iProgrssHeight, @DesktopWidth / 4, @DesktopHeight / 5)
GUISetBkColor($iBackColor, $hGUI)
; the circle to continue playing
$aControls[0] = GUICtrlCreateLabel(ChrW(0x25EF), 0, $iWinHeight + 1, 100, $iDockHeight, 0x01)
; GUICtrlSetTip(-1, "Click the circle," & @CRLF & "then click the squares" & @CRLF & "in numeric order.")
GUICtrlSetFont(-1, 24, 900)
GUICtrlSetColor(-1, $iForeColor)
GUICtrlSetBkColor(-1, $iBackColor)
; slider for the amount of numbers to guess
$aControls[2] = GUICtrlCreateSlider($iDockLeftBorder, $iWinHeight, $iWinWidth - $iDockLeftBorder, Int($iDockHeight / 2))
GUICtrlSetLimit(-1, 10, 5) ; 5 steps 5 (easy) to 10 (hard)
GUICtrlSetData(-1, $iNumbersToGuess)
; label for the amount of quizzes
$aControls[1] = GUICtrlCreateLabel("Numbers : " & GUICtrlRead($aControls[2]), 100, $iWinHeight + 1, 100)
GUICtrlSetColor(-1, $iForeColor)
; slider for the exposition time
$aControls[4] = GUICtrlCreateSlider($iDockLeftBorder, $iWinHeight + (Int($iDockHeight / 2)), $iWinWidth - $iDockLeftBorder, $iDockHeight / 2)
GUICtrlSetLimit(-1, 8, 1) ; 8 steps (0f 250ms each)
GUICtrlSetData(-1, $iExpositionTime / 250)
; label for the exposition time
$aControls[3] = GUICtrlCreateLabel("ms to show : " & GUICtrlRead($aControls[4]) * 250, 100, $iWinHeight + 1 + (Int($iDockHeight / 2)), 100)
GUICtrlSetColor(-1, $iForeColor)
; progress bar of the match
Global $idProgressbar = GUICtrlCreateProgress(0, $iWinHeight + $iDockHeight, $iWinWidth, $iProgrssHeight)
; Create buttons
For $i = 0 To 9
$aButtons[$i] = GUICtrlCreateLabel($i + 1, $iWinWidth + 5, $iWinHeight + $iDockHeight + $iProgrssHeight + 5, $iButtonXSide, $iButtonYSide, 0x01)
GUICtrlSetFont($aButtons[$i], 24)
GUICtrlSetColor($aButtons[$i], $iForeColor)
GUICtrlSetBkColor($aButtons[$i], $iBackColor)
Next
GUISetState(@SW_SHOW)
; --- Main loop ---
Do ; New game
$iMatchesWon = 0
GUICtrlSetData($idProgressbar, 0)
For $iRound = 1 To $iMatches ; the game lasts $iMatches rounds
$iNdx = 0 ; reset pointer (index to the next correct answer)
_HideControls(__get_IDs_by_indexes($aButtons, $aNumbers)) ; remove the numbers from the screen
; show the dock and wait (only in the first round are also shown the sliders)
_ShowControls($iRound = 1 ? $aControls : $aControls[0]) ; display the dock's control(s)
While 1
Switch GUIGetMsg()
Case $aControls[0] ; The circle (play a new quiz)
ExitLoop
Case $aControls[2] ; slider to choose how many numbers to guess
$iNumbersToGuess = GUICtrlRead($aControls[2])
GUICtrlSetData($aControls[1], "Numbers : " & $iNumbersToGuess)
Case $aControls[4] ; slider to choose how long (milliseconds) to show the numbers
$iExpositionTime = GUICtrlRead($aControls[4]) * 250 ; 8 steps of 250 milliseconds each
GUICtrlSetData($aControls[3], "ms to show : " & $iExpositionTime)
Case $GUI_EVENT_CLOSE
_EndOfGame()
EndSwitch
WEnd
_HideControls($aControls) ; hide the dock
Sleep(750) ; wait a bit
$aQuiz = _GenerateQuiz($iNumbersToGuess) ; generate random elements to guess
_SpreadControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; scatter the numbers on the GUI
_ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; display the numbers
Sleep($iExpositionTime) ; leave numbers visible for a short time
_MaskControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; mask the numbers
GUICtrlSetData($idProgressbar, Round($iRound / $iMatches * 100))
; _ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; <------------- keep numbers visible FOR DEBUG PURPOSE ONLY!
While 1 ; wait for a move
$GUIGetMsg = GUIGetMsg()
If $GUIGetMsg = $GUI_EVENT_CLOSE Then _EndOfGame()
; scan all quiz buttons to check if one was pressed
For $i = 0 To UBound($aQuiz) - 1 ; $aButtons) - 1
If $GUIGetMsg = $aButtons[$aQuiz[$i] - 1] Then
If $i = $iNdx Then
; --------------------------
; actions for a right move
; --------------------------
; hide the guessed number
_HideControls($aButtons[$aQuiz[$i] - 1])
; ---------------------------------
; check if this round is complete
; ---------------------------------
If $iNdx = (UBound($aQuiz) - 1) Then
_WinAPI_PlaySound("SystemExclamation", Null, BitOR($SND_ALIAS, $SND_ASYNC))
$iMatchesWon += 1
ExitLoop 2
EndIf
; play a short ok sound
; _WinAPI_PlaySound("FaxBeep", Null, BitOR($SND_ALIAS, $SND_ASYNC)) ; "SystemAsterisk"
$iNdx += 1 ; set index to next correct answer
Else
; --------------------------
; actions for a wrong move
; --------------------------
; show all the right sequence
_ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz))
_WinAPI_PlaySound("DeviceFail", Null, BitOR($SND_ALIAS, $SND_ASYNC))
; give a little time to the user to control it
Sleep(1500)
; go to next step
ExitLoop 2
EndIf
EndIf
Next
WEnd ; loop till end of match
$score = Round($iMatchesWon / $iMatches * 100, 2) ; percentage
Select
Case $score < 80
$sResult = "The chimp beat you!"
Case $score > 80
$sResult = "You beat the chimp!"
Case $score = 80
$sResult = "You tied the chimp."
EndSelect
Next ; next round
; game over?
Until MsgBox($MB_YESNO + $MB_ICONINFORMATION + $MB_TASKMODAL + $MB_SETFOREGROUND, _
"Game over", _
"You got " & $score & "% correct." & @CRLF & _
"Ayumu averages 80% correct." & @CRLF & $sResult & @CRLF & @CRLF & _
"do you want to try again?") <> 6
Func _SpreadControls($aTemp)
; place the required numbers scattered on the GUI
SRandom(@YEAR + @MON + @MDAY + @HOUR + @MIN + @SEC)
_ArrayShuffle($aX)
_ArrayShuffle($aY)
; first, place all buttons out of GUI
For $i = 0 To UBound($aButtons) - 1
GUICtrlSetPos($aButtons[$i], $iWinWidth + 5, $iWinHeight + $iDockHeight + $iProgrssHeight + 5)
GUICtrlSetState($aButtons[$i], $GUI_DISABLE)
Next
; Then place only the numbers of this quiz in visible area
For $i = 0 To UBound($aTemp) - 1
GUICtrlSetPos($aTemp[$i], $aX[$i], $aY[$i])
GUICtrlSetState($aTemp[$i], $GUI_ENABLE)
Next
EndFunc ;==>_SpreadControls
Func _GenerateQuiz($iNumElements)
; generate an array of required random numbers
SRandom(@YEAR + @MON + @MDAY + @HOUR + @MIN + @SEC)
Local $aTemp[$iNumElements]
_ArrayShuffle($aNumbers)
For $i = 0 To $iNumElements - 1
$aTemp[$i] = $aNumbers[$i]
Next
_ArraySort($aTemp)
Return $aTemp
EndFunc ;==>_GenerateQuiz
Func _ShowControls($aTemp)
; render controls visible (and enabled)
$aTemp = _EnforceArray($aTemp)
For $i = 0 To UBound($aTemp) - 1
GUICtrlSetState($aTemp[$i], $GUI_SHOW)
GUICtrlSetColor($aTemp[$i], $iForeColor)
GUICtrlSetBkColor($aTemp[$i], $iBackColor)
Next
EndFunc ;==>_ShowControls
Func _MaskControls($aTemp)
; mask the controls
$aTemp = _EnforceArray($aTemp)
For $i = 0 To UBound($aTemp) - 1
GUICtrlSetColor($aTemp[$i], $iForeColor)
GUICtrlSetBkColor($aTemp[$i], $iForeColor)
Next
EndFunc ;==>_MaskControls
Func _HideControls($aTemp)
; hide the controls (implies disable)
$aTemp = _EnforceArray($aTemp)
For $i = 0 To UBound($aTemp) - 1
GUICtrlSetState($aTemp[$i], $GUI_HIDE) ; $GUI_DISABLE)
; GUICtrlSetColor($aButtons[$aTemp[$i] - 1], $iBackColor)
; GUICtrlSetBkColor($aButtons[$aTemp[$i] - 1], $iBackColor)
Next
EndFunc ;==>_HideControls
Func _EnforceArray($vParam)
; if only one value is passed, turn it into an array of only 1 element
If Not IsArray($vParam) Then
Local $aTemp[1] = [$vParam]
Return $aTemp
EndIf
Return $vParam
EndFunc ;==>_EnforceArray
Func __get_IDs_by_indexes(ByRef $aCtrls, ByRef $aNdxs)
; returns the handles of the controls pointed to by the indexes
Local $aTemp[UBound($aNdxs)]
For $i = 0 To UBound($aNdxs) - 1
$aTemp[$i] = $aCtrls[$aNdxs[$i] - 1]
Next
Return $aTemp
EndFunc ;==>__get_IDs_by_indexes
Func _EndOfGame()
; _WinAPI_PlaySound ("SystemExit" , Null, $SND_ALIAS)
GUIDelete()
Exit
EndFunc ;==>_EndOfGame
P.S. At this link (https://web.archive.org/web/20131006161544/http://games.lumosity.com/chimp.html) there is a Flash version of this game.