From 0d342f0aee3f2f800e486c0051dabe718a7b2841 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Wed, 23 Mar 2011 11:14:27 +0100 Subject: I don't like nxhtml --- emacs.d/nxhtml/util/n-back.el | 1296 ----------------------------------------- 1 file changed, 1296 deletions(-) delete mode 100644 emacs.d/nxhtml/util/n-back.el (limited to 'emacs.d/nxhtml/util/n-back.el') diff --git a/emacs.d/nxhtml/util/n-back.el b/emacs.d/nxhtml/util/n-back.el deleted file mode 100644 index 024b8e6..0000000 --- a/emacs.d/nxhtml/util/n-back.el +++ /dev/null @@ -1,1296 +0,0 @@ -;;; n-back.el --- n-back game -;; -;; Author: Lennart Borgman (lennart O borgman A gmail O com) -;; Created: 2009-05-23 Sat -(defconst n-back:version "0.5");; Version: -;; Last-Updated: 2009-08-04 Tue -;; URL: -;; Keywords: -;; Compatibility: -;; -;; Features that might be required by this library: -;; -;; `winsize'. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Commentary: -;; -;; n-back game for brain training. See `n-back-game' for more -;; information. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Change log: -;; -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or -;; (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth -;; Floor, Boston, MA 02110-1301, USA. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Code: - -;;(eval-when-compile (require 'viper)) - -;; (setq n-back-trials 2) -(eval-when-compile (require 'cl)) -(eval-when-compile (require 'nxhtml-base nil t)) -(eval-when-compile (require 'nxhtml-web-vcs nil t)) -(require 'winsize nil t) ;; Ehum... - -(defvar n-back-game-window nil) -(defvar n-back-game-buffer nil) - -(defvar n-back-ctrl-window nil) -(defvar n-back-ctrl-buffer nil) - -(defvar n-back-info-window nil) -(defvar n-back-info-buffer nil) - -(defvar n-back-trials-left nil) -(defvar n-back-timer nil) -(defvar n-back-clear-timer nil) - -(defvar n-back-result nil) -(defvar n-back-this-result nil) - -(defvar n-back-ring nil) - -(defvar n-back-num-active nil) - - -;;;###autoload -(defgroup n-back nil - "Customizations for `n-back-game' game." - :group 'games) - -(defgroup n-back-feel nil - "Customizations for `n-back-game' game keys, faces etc." - :group 'n-back) - -(defface n-back-ok - '((t (:foreground "black" :background "green"))) - "Face for OK answer." - :group 'n-back-feel) - -(defface n-back-bad - '((t (:foreground "black" :background "OrangeRed1"))) - "Face for bad answer." - :group 'n-back-feel) - -(defface n-back-hint - '((t (:foreground "black" :background "gold"))) - "Face for bad answer." - :group 'n-back-feel) - -(defface n-back-do-now - '((((background dark)) (:foreground "yellow")) - (t (:foreground "blue"))) - "Face for start and stop hints." - :group 'n-back-feel) - -(defface n-back-game-word - '((t (:foreground "black"))) - "Face for word displayed in game." - :group 'n-back-feel) - -(defface n-back-header - '((((background dark)) (:background "OrangeRed4")) - (t (:background "gold"))) - "Face for headers." - :group 'n-back-feel) - -(defface n-back-keybinding - '((((background dark)) (:background "purple4")) - (t (:background "OliveDrab1"))) - "Face for key bindings." - :group 'n-back-feel) - -(defface n-back-last-result - '((((background dark)) (:background "OliveDrab4")) - (t (:background "yellow"))) - "Face for last game result header." - :group 'n-back-feel) - -(defface n-back-welcome - '((((background dark)) (:foreground "OliveDrab3")) - (t (:foreground "OliveDrab4"))) - "Face for welcome string" - :group 'n-back-feel) - -(defface n-back-welcome-header - '((t (:height 2.0))) - "Face for welcome header." - :group 'n-back-feel) - -(defcustom n-back-level 1 - "The n-Back level." - :type '(radio (const 1) - (const 2) - (const 3) - (const 4)) - :set (lambda (sym val) - (set-default sym val) - (when (featurep 'n-back) - (n-back-update-control-buffer) - (n-back-update-info))) - :group 'n-back) - -(defcustom n-back-active-match-types '(position color sound) - "Active match types." - :type '(set (const position) - (const color) - (const sound) - (const word)) - :set (lambda (sym val) - (set-default sym val) - (setq n-back-num-active (length val)) - (when (featurep 'n-back) - (n-back-init-control-status) - (n-back-update-control-buffer) - (n-back-update-info))) - :group 'n-back) - -(defcustom n-back-allowed-match-types '(position color sound word) - "Match types allowed in auto challenging." - :type '(set (const position) - (const color) - (const sound) - (const word)) - :set (lambda (sym val) - (set-default sym val) - (when (featurep 'n-back) - (n-back-set-random-match-types (length n-back-active-match-types) nil) - (n-back-init-control-status) - (n-back-update-control-buffer) - (n-back-update-info))) - :group 'n-back) - -(defcustom n-back-auto-challenge t - "Automatic challenge decrease/increase." - :type 'boolean - :group 'n-back) - -(defun n-back-toggle-auto-challenge () - "Toggle `n-back-auto-challenge'." - (interactive) - (let ((val (not n-back-auto-challenge))) - (customize-set-variable 'n-back-auto-challenge val) - (customize-set-value 'n-back-auto-challenge val))) - -(defcustom n-back-colors - '("gold" "orange red" "lawn green" "peru" "pink" "gray" "light blue") - "Random colors to display." - :type '(repeat color) - :group 'n-back) - -(defcustom n-back-words "you cat going me forest crying brown" - "Random words to display." - :type 'string - :group 'n-back) - -(defcustom n-back-sound-volume 0.2 - "Sound volume 0-1." - :type 'float - :group 'n-back-feel) - -(defcustom n-back-sounds '("c:/program files/brain workshop/res" "piano-") - "Random sounds location." - :type '(list (directory :tag "Directory") - (regexp :tag "File name regexp")) - :group 'n-back) - -(defcustom n-back-keys - '( - [?p] - [?c] - [?s] - [?w] - ) - "Key bindings for answering." - :type '(list - (key-sequence :tag "position key") - (key-sequence :tag "color key") - (key-sequence :tag "sound key") - (key-sequence :tag "word key") - ) - ;; :set (lambda (sym val) - ;; (set-default sym val) - ;; (n-back-make-keymap)) - :group 'n-back-feel) - -(defvar n-back-control-mode-map nil) - -(defun n-back-key-binding (what) - "Return key binding used for WHAT match answers." - (nth - (case what - (position 0) - (color 1) - (sound 2) - (word 3)) - n-back-keys)) - -(defun n-back-make-keymap () - "Make keymap for the game." - (let ((map (make-sparse-keymap))) - (define-key map [?1] 'n-back-change-level) - (define-key map [?2] 'n-back-change-level) - (define-key map [?3] 'n-back-change-level) - (define-key map [?4] 'n-back-change-level) - (define-key map [?5] 'n-back-change-level) - (define-key map [?6] 'n-back-change-level) - (define-key map [??] 'n-back-help) - (define-key map [?\ ] 'n-back-play) - (define-key map [(control ?g)] 'n-back-stop) - (define-key map [?-] 'n-back-decrease-speed) - (define-key map [?+] 'n-back-increase-speed) - - (define-key map [(control ?r)] 'n-back-reset-game-to-saved) - (define-key map [(control ?s)] 'n-back-save-game-settings) - - (define-key map [?t ?p] 'n-back-toggle-position) - (define-key map [?t ?c] 'n-back-toggle-color) - (define-key map [?t ?s] 'n-back-toggle-sound) - (define-key map [?t ?w] 'n-back-toggle-word) - - (define-key map [?T ?a] 'n-back-toggle-auto-challenge) - (define-key map [up] 'n-back-challenge-up) - (define-key map [down] 'n-back-challenge-down) - - (define-key map [?T ?p] 'n-back-toggle-allowed-position) - (define-key map [?T ?c] 'n-back-toggle-allowed-color) - (define-key map [?T ?s] 'n-back-toggle-allowed-sound) - (define-key map [?T ?w] 'n-back-toggle-allowed-word) - - (define-key map (n-back-key-binding 'position) 'n-back-position-answer) - (define-key map (n-back-key-binding 'color) 'n-back-color-answer) - (define-key map (n-back-key-binding 'sound) 'n-back-sound-answer) - (define-key map (n-back-key-binding 'word) 'n-back-word-answer) - ;;(define-key map [t] 'ignore) - (setq n-back-control-mode-map map))) - -(defvar n-back-display-hint nil) -(defcustom n-back-hint t - "Display hints - learning mode." - :type 'boolean - :group 'n-back) - - - -(defvar n-back-sound-files nil) -;;(n-back-get-sound-files) -(defun n-back-get-sound-files () - "Get sound file names." - (let ((dir (nth 0 n-back-sounds)) - (regexp (nth 1 n-back-sounds))) - (when (file-directory-p dir) - (setq n-back-sound-files (directory-files dir nil regexp))))) - -(defun n-back-toggle-position () - "Toggle use of position in `n-back-active-match-types'." - (interactive) - (n-back-toggle 'position)) - -(defun n-back-toggle-color () - "Toggle use of color in `n-back-active-match-types'." - (interactive) - (n-back-toggle 'color)) - -(defun n-back-toggle-sound () - "Toggle use of sound in `n-back-active-match-types'." - (interactive) - (n-back-toggle 'sound)) - -(defun n-back-toggle-word () - "Toggle use of word in `n-back-active-match-types'." - (interactive) - (n-back-toggle 'word)) - -(defun n-back-toggle (match-type) - "Toggle use of MATCH-TYPE in `n-back-active-match-types'." - (n-back-toggle-1 match-type 'n-back-active-match-types)) - -(defun n-back-toggle-allowed-position () - "Toggle use of position in `n-back-allowed-match-types'." - (interactive) - (n-back-toggle-allowed 'position)) - -(defun n-back-toggle-allowed-color () - "Toggle use of color in `n-back-allowed-match-types'." - (interactive) - (n-back-toggle-allowed 'color)) - -(defun n-back-toggle-allowed-sound () - "Toggle use of sound in `n-back-allowed-match-types'." - (interactive) - (n-back-toggle-allowed 'sound)) - -(defun n-back-toggle-allowed-word () - "Toggle use of word in `n-back-allowed-match-types'." - (interactive) - (n-back-toggle-allowed 'word)) - -(defun n-back-toggle-allowed (match-type) - "Toggle use of MATCH-TYPE in `n-back-allowed-match-types'." - (n-back-toggle-1 match-type 'n-back-allowed-match-types)) - -(defun n-back-sort-types (types) - "Sort TYPES to order used in defcustoms here." - (sort types - (lambda (a b) - (let ((all '(position color sound word))) - (< (length (memq a all)) - (length (memq b all))))))) - -(defun n-back-toggle-1 (match-type active-list-sym) - "Toggle use of MATCH-TYPE in list ACTIVE-LIST-SYM." - (let (active-types) - (if (memq match-type (symbol-value active-list-sym)) - (setq active-types (delq match-type (symbol-value active-list-sym))) - (setq active-types (cons match-type (symbol-value active-list-sym)))) - (setq active-types (n-back-sort-types active-types)) - (customize-set-variable active-list-sym active-types) - (customize-set-value active-list-sym active-types))) - -(defcustom n-back-sec-per-trial 3.0 - "Seconds per trial." - :type 'float - :set (lambda (sym val) - (set-default sym val) - (when (featurep 'n-back) - (n-back-update-info))) - :group 'n-back) - -(defun n-back-decrease-speed () - "Decrease speed of trials." - (interactive) - (setq n-back-sec-per-trial (+ n-back-sec-per-trial 0.25)) - (when (> n-back-sec-per-trial 5.0) - (setq n-back-sec-per-trial 5.0)) - (n-back-update-info)) - -(defun n-back-increase-speed () - "Increase speed of trials." - (interactive) - (let ((sec (- n-back-sec-per-trial 0.25))) - (when (< sec 1.0) - (setq sec 1.0)) - (customize-set-variable 'n-back-sec-per-trial sec) - (customize-set-value 'n-back-sec-per-trial sec))) - -(defun n-back-help () - "Show help for `n-back-game' game." - (interactive) - (save-selected-window - (describe-function 'n-back-game))) - -(defun n-back-change-level (level) - "Change n-Back level to LEVEL." - (interactive (progn - (if (and (numberp last-input-event) - (>= last-input-event ?1) - (<= last-input-event ?9)) - (list (- last-input-event ?0)) - (list (string-to-number (read-string "n Back: ")))))) - (customize-set-variable 'n-back-level level) - (customize-set-value 'n-back-level level)) - -(defvar n-back-frame nil) - -;;;###autoload -(defun n-back-game () - "Emacs n-Back game. -This game is supposed to increase your working memory and fluid -intelligence. - -In this game something is shown for half a second on the screen -and maybe a sound is played. You should then answer if parts of -it is the same as you have seen or heard before. This is -repeated for about 20 trials. - -You answer with the keys shown in the bottom window. - -In the easiest version of the game you should answer if you have -just seen or heard what is shown now. By default the game gets -harder as you play it with success. Then first the number of -items presented in a trial grows. After that it gets harder by -that you have to somehow remember not the last item, but the item -before that \(or even earlier). That is what \"n-Back\" stands -for. - -Note that remember does not really mean remember clearly. The -game is for training your brain getting used to keep those things -in the working memory, maybe as a cross-modal unit. You are -supposed to just nearly be able to do what you do in the game. -And you are supposed to have fun, that is what your brain like. - -You should probably not overdue this. Half an hour a day playing -might be an optimal time according to some people. - -The game is shamelessly modeled after Brain Workshop, see URL -`http://brainworkshop.sourceforge.net/' just for the fun of -getting it into Emacs. The game resembles but it not the same as -that used in the report by Jaeggi mentioned at the above URL. - -Not all features in Brain Workshop are implemented here, but some -new are maybe ... - and you have it available here in Emacs." - ;; ----- - ;; Below is a short excerpt from the report by Jaeggi et al which - ;; gave the idea to the game: - - ;; Training task. For the training task, we used the same material - ;; as described by Jaeggi et al. (33), which was a dual n-Back task - ;; where squares at eight different locations were presented - ;; sequentially on a computer screen at a rate of 3 s (stimulus - ;; length, 500 ms; interstimulus interval, 2,500 ms). - ;; Simultaneously with the presentation of the squares, one of eight - ;; consonants was presented sequentially through headphones. A - ;; response was required whenever one of the presented stimuli - ;; matched the one presented n positions back in the sequence. The - ;; value of n was the same for both streams of stimuli. There were - ;; six auditory and six visual targets per block (four appearing in - ;; only one modality, and two appearing in both modalities - ;; simultaneously), and their positions were determined randomly. - ;; Participants made responses manually by pressing on the letter - ;; ‘‘A’’ of a standard keyboard with their left index finger for - ;; visual targets, and on the letter ‘‘L’’ with their right index - ;; finger for auditory targets. No responses were required for - ;; non-targets. - (interactive) - (n-back-make-keymap) - (when window-system - (unless (frame-live-p n-back-frame) - (setq n-back-frame (make-frame - (list '(name . "n-back game") - '(tool-bar-lines . 0) - '(menu-bar-lines . 0) - (case (frame-parameter nil 'background-mode) - (light '(background-color . "cornsilk")) - (dark '(background-color . "MidnightBlue")) - (otherwise nil)) - '(height . 45) - '(width . 150))))) - (select-frame n-back-frame) - (raise-frame n-back-frame)) - (n-back-cancel-timers) - (n-back-get-sound-files) - (unless n-back-sound-files - (when (memq 'sound n-back-allowed-match-types) - (n-back-toggle-allowed-sound)) - (when (memq 'sound n-back-active-match-types) - (n-back-toggle-sound))) - (n-back-init-control-status) - (n-back-setup-windows) - ) - -(defconst n-back-match-types - '((position ": position match" nil) - (color ": color match" nil) - (sound ": sound match" nil) - (word ": word match" nil) - )) - -(defvar n-back-control-status nil - "For showing status in control window.") -(setq n-back-control-status nil) - -;;(n-back-set-match-status 'position 'bad) -(defun n-back-set-match-status (match-type status) - "Set MATCH-TYPE status to STATUS for control window." - (unless (memq status '(ok bad miss nil)) (error "n-back: Bad status=%s" status)) - (let ((entry (assoc match-type n-back-control-status))) - (setcar (cddr entry) status) - )) - -;;(n-back-clear-match-status) -(defun n-back-clear-match-status () - "Clear match status for control window." - ;;(dolist (entry n-back-control-status) - (dolist (entry n-back-match-types) - (setcar (cddr entry) nil) - )) - -;; (n-back-init-control-status) -(defun n-back-init-control-status () - "Init match status for control window." - (setq n-back-control-status nil) - (dolist (what n-back-active-match-types) - (setq n-back-control-status - (cons (assoc what n-back-match-types) - n-back-control-status)))) - -(defsubst n-back-is-playing () - "Return non-nil when game is active." - (timerp n-back-timer)) - -;;(n-back-update-control-buffer) -(defun n-back-update-control-buffer () - "Update content of control buffer." - (save-match-data ;; runs in timer - (when (buffer-live-p n-back-ctrl-buffer) - (with-current-buffer n-back-ctrl-buffer - (setq buffer-read-only nil) - (erase-buffer) - (insert (propertize (format "%s %s-back" - (let ((n (length n-back-active-match-types))) - (cond - ((= 1 n) "Single") - ((= 2 n) "Dual") - ((= 3 n) "Triple") - )) - n-back-level - ) 'face 'n-back-header) - (propertize - (if (n-back-is-playing) " Press C-g to stop" " Press SPACE to play") - 'face 'n-back-do-now) - (if (n-back-is-playing) (format " Left %s" n-back-trials-left) "") - "\n") - ;;(unless n-back-control-status (n-back-init-control-status)) - (dolist (entry n-back-control-status) - (let* ((what (nth 0 entry)) - (msg (nth 1 entry)) - (sts (nth 2 entry)) - (key (key-description (n-back-key-binding what)))) - ;;(setq msg (concat (key-description (n-back-key-binding what)) msg)) - (cond - ((eq sts 'bad) - (setq msg (propertize (concat key msg) 'face 'n-back-bad))) - ((eq sts 'ok) - (setq msg (propertize (concat key msg) 'face 'n-back-ok))) - ((eq sts 'miss) - (setq msg (concat - (if n-back-display-hint - (propertize key 'face 'n-back-header) - key) - msg))) - ((not sts) - (setq msg (concat key msg))) - (t - (error "n-back:Unknown sts=%s" sts) - )) - (insert msg " ")) - ) - (when n-back-display-hint - (setq n-back-display-hint nil) - (run-with-timer 0.1 nil 'n-back-update-control-buffer)) - (setq buffer-read-only t) - (if (window-live-p n-back-ctrl-window) - (with-selected-window n-back-ctrl-window - (goto-char 1)) - (goto-char 1)))))) - -(defcustom n-back-trials 20 - "Number of trials per session." - :type 'integer - :group 'n-back) - -;;(n-back-compute-result-values n-back-result) -(defvar n-back-result-values nil) -(defun n-back-compute-single-result-value (entry) - "Compute result stored in ENTRY." - (let* ((what (nth 0 entry)) - (good (nth 1 entry)) - (bad (nth 2 entry)) - (miss (nth 3 entry)) - (err (+ bad miss)) - ;;(tot (+ good bad miss 0.0)) - ;;(gnum 6) - ;;(weighted-err (* err (/ gnum tot))) - ) - (cons what (if (= 0 good) - 0 - (/ (- n-back-trials err 0.0) - n-back-trials))))) - -(defun n-back-compute-result-values (result) - "Compute result values from game result RESULT." - (let ((results nil)) - (dolist (entry result) - (let ((res (n-back-compute-single-result-value entry))) - (setq results (cons res results)))) - (setq n-back-result-values (reverse results)))) - -;; Thresholds -(defun n-back-view-threshold-discussion-page () - "View some discussion of threshold." - (interactive) - (browse-url "http://groups.google.com/group/brain-training/browse_thread/thread/f4bfa452943c2a2d/ba31adfd0b97771c?lnk=gst&q=threshold#ba31adfd0b97771c")) - -;;(n-back-set-next-challenge) -(defvar n-back-worst nil) - -(defvar n-back-challenge-change nil) - -(defun n-back-set-next-challenge () - "Set next game difficulty level from last game result." - (let ((r 2.8)) ;; stay as default - (setq n-back-worst nil) - (dolist (res n-back-result-values) - (when (< (cdr res) r) - (setq r (cdr res)) - (setq n-back-worst res))) - (setq n-back-challenge-change (if (< r 0.74) - 'down - (if (> r 0.91) - 'up - 'stay))) - (n-back-change-challenge n-back-challenge-change))) - -(defun n-back-challenge-up () - "Make the game harder." - (interactive) - (n-back-change-challenge 'up)) - -(defun n-back-challenge-down () - "Make the game easier." - (interactive) - (n-back-change-challenge 'down)) - -(defun n-back-change-challenge (challenge-change) - "Change game difficulty level by CHALLENGE-CHANGE." - (let ((new-level n-back-level) - (new-num-active n-back-num-active) - (num-allowed (length n-back-allowed-match-types))) - (case challenge-change - (down - (if (= 1 n-back-num-active) - (unless (= 1 n-back-level) - (setq new-num-active (min 3 num-allowed)) - (setq new-level (1- n-back-level))) - (setq new-num-active (1- n-back-num-active)))) - (up - (if (or (<= 3 n-back-num-active) - (<= num-allowed n-back-num-active)) - (progn - (setq new-level (1+ n-back-level)) - (setq new-num-active 1)) - (setq new-num-active (min 3 (1+ n-back-num-active)))))) - ;;(when (= new-level 0) (setq new-level 1)) - ;;(when (= new-num-active 0) (setq new-num-active 1)) - (when (and (= new-level n-back-level) - (= new-num-active n-back-num-active)) - (setq n-back-challenge-change 'stay)) - (unless (= new-level n-back-level) - (customize-set-variable 'n-back-level new-level) - (customize-set-value 'n-back-level new-level)) - (n-back-set-random-match-types new-num-active (car n-back-worst)))) - -(defun n-back-set-random-match-types (num worst) - "Select NUM random match types. -If type WORST is non-nil try to include that." - (let ((alen (length n-back-allowed-match-types)) - (old-types n-back-active-match-types) - types) - (unless (<= num alen) - (error "n-back: Too many match types required = %s" num)) - (when (and worst - (< 1 num) - (memq worst n-back-allowed-match-types)) - (add-to-list 'types worst)) - (while (< (length types) num) - (add-to-list 'types (nth (random alen) n-back-allowed-match-types))) - (setq types (n-back-sort-types types)) - (unless (equal old-types types) - (customize-set-variable 'n-back-active-match-types types) - (customize-set-value 'n-back-active-match-types types)))) - -;; (defcustom n-back-keybinding-color "OliveDrab1" -;; "Background color for key binding hints." -;; :type 'color -;; :group 'n-back) - -(defun n-back-update-info () - "Update info buffer." - (when (buffer-live-p n-back-info-buffer) - (when (window-live-p n-back-info-window) - (set-window-buffer n-back-info-window n-back-info-buffer)) - (with-current-buffer n-back-info-buffer - (setq buffer-read-only nil) - (erase-buffer) - - (insert (propertize "n-back" 'face 'n-back-header) - " " - (propertize "Help: ?" 'face 'n-back-keybinding)) - - ;; Auto challenging - (insert "\n\nAuto challenging: " - (if n-back-auto-challenge "on " "off ") - (propertize "toggle: Ta" 'face 'n-back-keybinding)) - - (insert "\n Manually change challenging: " - (propertize "up-arrow/down-arrow" 'face 'n-back-keybinding)) - - (insert "\n Allowed match types: ") - (dolist (type n-back-allowed-match-types) - (insert (format "%s " type))) - (insert (propertize "toggle: T" 'face 'n-back-keybinding)) - - ;; Current game - (insert "\n\nCurrent game:") - - (insert (format "\n n Back: %s " n-back-level) - (propertize "change: number 1-9" 'face 'n-back-keybinding)) - (insert "\n Match types: ") - (dolist (type n-back-active-match-types) - (insert (format "%s " type))) - (insert (propertize "toggle: t" 'face 'n-back-keybinding)) - - (insert (format "\n %.2f seconds per trial " n-back-sec-per-trial) - (propertize "change: +/-" 'face 'n-back-keybinding)) - - ;; Save and restore - (insert "\n\n") - (insert "Game settings: " - (propertize "reset: C-r" 'face 'n-back-keybinding) - " " - (propertize "save: C-s" 'face 'n-back-keybinding)) - - (insert "\n\n") - (unless (or (n-back-is-playing) - (not n-back-result)) - (insert (propertize (format "Last result, %s" n-back-challenge-change) - 'face 'n-back-last-result) - "\n Good-Bad-Miss:") - (dolist (entry n-back-result) - (let* ((what (nth 0 entry)) - (good (nth 1 entry)) - (bad (nth 2 entry)) - (miss (nth 3 entry)) - (tot (+ good bad miss 0.0)) - (res (n-back-compute-single-result-value entry))) - (insert (format " %s: %s-%s-%s (%d%%)" - (key-description (n-back-key-binding what)) - good - bad - miss - (floor (* 100 (cdr res)))))))) - - (setq buffer-read-only t)))) - -(defun n-back-show-welcome (msg) - "Show welcome startup info and message MSG." - (when (and n-back-game-buffer - (buffer-live-p n-back-game-buffer)) - (with-current-buffer n-back-game-buffer - (let ((src (or (when (boundp 'nxhtml-install-dir) - (expand-file-name "nxhtml/doc/img/fun-brain-2.png" nxhtml-install-dir)) - "c:/program files/brain workshop/res/brain_graphic.png")) - img - buffer-read-only) - (erase-buffer) - ;;(insert (propertize "\nEmacs n-back game (after Brain Workshop)\n\n" 'face '(:height 2.0))) - (insert (propertize "\nEmacs n-back game (after Brain Workshop)\n\n" 'face 'n-back-welcome-header)) - (unless (file-exists-p src) - (n-back-maybe-download-files (file-name-directory src) (list (file-name-nondirectory src)))) - (if (file-exists-p src) - (condition-case err - (setq img (create-image src nil nil - :relief 0 - ;;:margin inlimg-margins - )) - (error (setq img (error-message-string err)))) - (setq img (concat "Image not found: " src))) - (if (stringp img) - (insert img) - (insert-image img)) - (insert (propertize "\n\nPlay for fun and maybe a somewhat happier brain" - 'face 'n-back-welcome)) - (when msg (insert "\n\n" msg)) - )))) - -(defun n-back-setup-windows () - "Setup game frame and windows." - (delete-other-windows) - ;; Info - (split-window-horizontally) - (setq n-back-info-window (next-window (frame-first-window))) - (setq n-back-info-buffer (get-buffer-create "* n-back info *")) - (when (< 75 (window-width n-back-info-window)) - (with-selected-window n-back-info-window - (enlarge-window (- 75 (window-width n-back-info-window)) t))) - (with-current-buffer n-back-info-buffer - (n-back-control-mode) - (setq wrap-prefix " ")) - (n-back-update-info) - ;; Control - (split-window-vertically) - (setq n-back-ctrl-window (next-window (frame-first-window))) - (setq n-back-ctrl-buffer (get-buffer-create "* n-back control *")) - (set-window-buffer n-back-ctrl-window n-back-ctrl-buffer) - (with-current-buffer n-back-ctrl-buffer (n-back-control-mode)) - (n-back-update-control-buffer) - (fit-window-to-buffer n-back-ctrl-window) - (set-window-dedicated-p n-back-ctrl-window t) - ;; Game - (setq n-back-game-window (frame-first-window)) - (setq n-back-game-buffer (get-buffer-create "*n-back game*")) - (set-window-buffer n-back-game-window n-back-game-buffer) - (set-window-dedicated-p n-back-game-window t) - (with-current-buffer n-back-game-buffer (n-back-control-mode)) - (n-back-show-welcome nil) - ;; Position in control window - (select-window n-back-ctrl-window) - ) - -;;(n-back-display "str" 1 0 3 3 6) -(defun n-back-display (str x y cols rows max-strlen color) - "Display a trial. -Display item with text STR at column X in row Y using COLS -columns and ROWS rows. Strings to display have max length -MAX-STRLEN. Display item with background color COLOR." - (unless (< x cols) (error "n-back: Not x=%s < cols=%s" x cols)) - (unless (< y rows) (error "Not y=%s < rows=%s" y rows)) - (unless str (setq str "")) - (with-current-buffer n-back-game-buffer - (let* (buffer-read-only - (tot-str "") - ;; Pad spaces left, two right, four between - (game-w (window-width n-back-game-window)) - (pad-x 0) - (scale (if (not window-system) - 1.0 - (/ (* 1.0 game-w) - (+ (* 2 pad-x) - (* (1- cols) 4) - (* cols max-strlen))))) - (str-diff (- max-strlen (length str))) - (str-l-len (/ str-diff 2)) - (str-r-len (- max-strlen (length str) str-l-len)) - (face-spec (if window-system - (list :inherit 'n-back-game-word :background color :height scale) - (list :inherit 'n-back-game-word :background color))) - (str-disp (propertize - (concat (make-string str-l-len 32) str (make-string str-r-len 32)) - 'face face-spec)) - (col-str (concat - (make-string pad-x ?p) - (make-string - (+ (* x (+ 4 max-strlen))) - 32 - ;;?x - ))) - ;; Pad lines above and below, two between - (pad-y 0) - (game-h (window-body-height n-back-game-window)) - (game-h-scaled (/ game-h scale)) - (lines-between (/ (- game-h-scaled rows (* 2 pad-y)) - (1- rows))) - (row-scaled (+ pad-y (* y (1+ lines-between)) (1- y))) - (row-num (if (= y 0) - pad-y - (round row-scaled))) - (row-str (make-string row-num ?\n))) - (setq show-trailing-whitespace nil) - ;;(setq cursor-type nil) - (erase-buffer) - (setq tot-str row-str) - (setq tot-str (concat tot-str col-str)) - (insert (propertize tot-str 'face (list :height scale))) - (insert str-disp) - ))) - -;; (setq timer-list nil) -;;(n-back-display-in-timer) -;; (setq n-back-trials-left 3) - -(defun n-back-clear-game-window () - "Erase game buffer." - (save-match-data ;; runs in timer - (with-current-buffer n-back-game-buffer - (let (buffer-read-only) - (erase-buffer))))) - -(defun n-back-play () - "Start playing." - (interactive) - (message " ") ;; For easier reading *Messages* - (n-back-update-info) - (if (not n-back-active-match-types) - (message (propertize "No active match types" - 'face 'secondary-selection)) - ;;(setq n-back-result nil) - (n-back-init-control-status) - (n-back-init-this-result) - (n-back-cancel-timers) - (winsize-set-mode-line-colors t) - (setq n-back-ring (make-ring (1+ n-back-level))) - (n-back-clear-game-window) - (setq n-back-trials-left (+ n-back-trials n-back-level)) - (random t) - (n-back-start-main-timer) - (n-back-update-control-buffer))) - -(defun n-back-start-main-timer () - "Start main game timer." - (setq n-back-timer - (run-with-timer - n-back-sec-per-trial - nil ;;n-back-sec-per-trial - 'n-back-display-in-timer))) - -(defun n-back-maybe-download-files (dir file-name-list) - (nxhtml-get-missing-files (file-relative-name dir nxhtml-install-dir) file-name-list)) - -(defun n-back-finish-game () - "Finish the game." - (n-back-cancel-timers) - (fit-window-to-buffer n-back-ctrl-window) - (setq n-back-result n-back-this-result) - (n-back-compute-result-values n-back-result) - (when n-back-auto-challenge (n-back-set-next-challenge)) - (n-back-update-info) - (n-back-init-control-status) - (n-back-clear-match-status) - (n-back-update-control-buffer) - (n-back-show-welcome "Game over") - (with-current-buffer n-back-game-buffer - ;;(setq n-back-challenge-change 'up) - (let (buffer-read-only) - (insert - "\n\n" - (case n-back-challenge-change - (up "Congratulations! I see you need more challenge, raising difficulty!") - (down "Making it a bit easier for now to make your playing more fun.") - (otherwise "This game challenges seems the right way for you now."))) - (let* ((dir (when (boundp 'nxhtml-install-dir) - (expand-file-name "nxhtml/doc/img/" nxhtml-install-dir))) - (up-imgs '("rembrandt-self-portrait.jpg" - "bacchante2.jpg" - "giraffe.jpg" - "Las_Medulas.jpg" - )) - (t-imgs '("continue-play.jpg" - "Toco_toucan.jpg" - "raindrops2.jpg" - "divine2.jpg" - ;;"butterflies.png" - "volga.jpg" - "healthy_feet2.jpg" - )) - ;; (setq n-back-trials 1) - (pic (when dir (case n-back-challenge-change - (up (nth (random (length up-imgs)) up-imgs)) - (otherwise (nth (random (length t-imgs)) t-imgs))))) - (src (when dir (expand-file-name pic dir))) - img) - (when (and src (not (file-exists-p src))) - ;; Time to download? - (n-back-maybe-download-files (file-name-directory src) (append up-imgs t-imgs nil))) - (when (and src (file-exists-p src)) - (condition-case err - (setq img (create-image src nil nil - :relief 0 - )) - (error (setq img (error-message-string err))))) - (if (stringp img) - img - (insert "\n\n") - (insert-image img))))) - (message "Game over")) - -(defun n-back-display-random () - "Display a random item." - (when (current-message) (message "")) - ;;(message "here start display") - (let* ((use-position (memq 'position n-back-active-match-types)) - (use-color (memq 'color n-back-active-match-types)) - (use-sound (memq 'sound n-back-active-match-types)) - (use-word (memq 'word n-back-active-match-types)) - (old-rec (when (n-back-match-possible) - (ring-ref n-back-ring (1- n-back-level)))) - (cols 3) - (rows 3) - (x (if use-position (random 3) 1)) - (y (if use-position (random 3) 1)) - (old-x (if use-position (nth 1 old-rec))) - (old-y (if use-position (nth 2 old-rec))) - (color (nth (if use-color (random (length n-back-colors)) 0) n-back-colors)) - (old-color (if use-color (nth 3 old-rec))) - (sound (when use-sound (expand-file-name (nth (random (length n-back-sound-files)) - n-back-sound-files) - (nth 0 n-back-sounds)))) - (old-sound (if use-sound (nth 4 old-rec))) - (words (when use-word (split-string n-back-words))) - (word (when use-word (nth (random (length words)) words))) - (old-word (when use-word (nth 5 old-rec))) - (str (if word word "")) ;(format "%s" n-back-trials-left)) - (max-strlen (if words - (+ 2 (apply 'max (mapcar (lambda (w) (length w)) words))) - 5)) - (compensate 24) - ) - ;; To get more targets make it more plausible that it is the same here. - ;; (/ (- 6 (/ 20.0 8)) 20) - (when old-rec - (when (and use-position - (not (and (= x old-x) - (= y old-y))) - (< (random 100) compensate)) - (setq x (nth 1 old-rec)) - (setq y (nth 2 old-rec))) - (when (and use-color - (not (equal color old-color)) - (< (random 100) compensate)) - (setq color (nth 3 old-rec))) - (when (and use-sound - (not (equal sound old-sound)) - (< (random 100) compensate)) - (setq sound (nth 4 old-rec))) - (when (and use-word - (not (equal word old-word)) - (< (random 100) compensate)) - (setq word (nth 5 old-rec)))) - (setq str word) ;; fix-me - (ring-insert n-back-ring (list str x y color sound word)) - ;;(message "here before display") - (n-back-display str x y cols rows max-strlen color) - ;;(when sound (play-sound (list 'sound :file sound))) - ;;(message "here before clear-m") - (n-back-clear-match-status) - ;;(message "here before position") - (when (and use-position (n-back-matches 'position)) (n-back-set-match-status 'position 'miss)) - ;;(message "here before color") - (when (and use-color (n-back-matches 'color)) (n-back-set-match-status 'color 'miss)) - ;;(message "here before sound") - (when (and use-sound (n-back-matches 'sound)) (n-back-set-match-status 'sound 'miss)) - ;;(message "here before word") - (when (and use-word (n-back-matches 'word)) (n-back-set-match-status 'word 'miss)) - (setq n-back-display-hint n-back-hint) - ;;(message "here before control") - (n-back-update-control-buffer) - ;;(message "here before clear timer") - (setq n-back-clear-timer (run-with-timer 0.5 nil 'n-back-clear-game-window)) - ;;(message "here before sound timer") - (when sound (run-with-timer 0.01 nil 'n-back-play-sound-in-timer sound)) - ;;(message "here exit display") - )) - -(defun n-back-display-in-timer () - "Display a trial in a timer." - (condition-case err - (save-match-data ;; runs in timer - (n-back-add-result) - (if (>= 0 (setq n-back-trials-left (1- n-back-trials-left))) - (n-back-finish-game) - (n-back-display-random) - (n-back-start-main-timer) - ;;(message "after start-main-timer") - )) - (error (message "n-back-display: %s" (error-message-string err)) - (n-back-cancel-timers)))) - -(defun n-back-play-sound-in-timer (sound-file) - "Play sound SOUND-FILE in a timer." - (condition-case err - (save-match-data ;; runs in timer - (play-sound (list 'sound :file sound-file :volume n-back-sound-volume))) - (error (message "n-back-sound: %s" (error-message-string err)) - (n-back-cancel-timers)))) - - -;;; Answers - -;;(defvar n-back-answers nil) - -(defun n-back-init-this-result () - "Init `n-back-this-result'." - (setq n-back-this-result nil) - (dolist (sts-entry n-back-control-status) - (let* ((what (nth 0 sts-entry)) - (res-entry (list what 0 0 0))) - (setq n-back-this-result (cons res-entry n-back-this-result))))) - -(defun n-back-match-possible () - "Return t if enouch entries have been shown to match." - (= (ring-length n-back-ring) (1+ n-back-level))) - -(defun n-back-add-result () - "Add result of last trial." - (when (n-back-match-possible) - (dolist (sts-entry n-back-control-status) - (let* ((what (nth 0 sts-entry)) - (sts (nth 2 sts-entry)) - (matches (n-back-matches what)) - (num (cond - ((eq sts 'ok) 1) - ((eq sts 'bad) 2) - ;;((eq sts nil) (when matches 3)) - ((eq sts 'miss) 3) - ((not sts) nil) - (t (error "n-back: Bad status=%s" sts)))) - (res-entry (when num (assoc what n-back-this-result))) - (lst (when num (nthcdr num res-entry)))) - (when num - (if res-entry - (setcar lst (1+ (car lst))) - (setq res-entry (list what 0 0 0)) - ;;(setq lst (nthcdr num res-entry)) - (setq n-back-this-result (cons res-entry n-back-this-result)))))))) - -(defun n-back-matches-position () - "Return non-nil iff last trial position match." - (when (n-back-match-possible) - (let* ((comp-item (ring-ref n-back-ring n-back-level)) - (curr-item (ring-ref n-back-ring 0)) - (comp-x (nth 1 comp-item)) - (curr-x (nth 1 curr-item)) - (comp-y (nth 2 comp-item)) - (curr-y (nth 2 curr-item))) - (and (= comp-y curr-y) - (= comp-x curr-x))))) - -(defun n-back-matches-color () - "Return non-nil iff last trial color match." - (when (n-back-match-possible) - (let* ((comp-item (ring-ref n-back-ring n-back-level)) - (curr-item (ring-ref n-back-ring 0)) - (comp-color (nth 3 comp-item)) - (curr-color (nth 3 curr-item))) - (equal comp-color curr-color)))) - -(defun n-back-matches-sound () - "Return non-nil iff last trial sound match." - (when (n-back-match-possible) - (let* ((comp-item (ring-ref n-back-ring n-back-level)) - (curr-item (ring-ref n-back-ring 0)) - (comp-sound (nth 4 comp-item)) - (curr-sound (nth 4 curr-item))) - (equal comp-sound curr-sound)))) - -(defun n-back-matches-word () - "Return non-nil iff last trial word match." - (when (n-back-match-possible) - (let* ((comp-item (ring-ref n-back-ring n-back-level)) - (curr-item (ring-ref n-back-ring 0)) - (comp-word (nth 5 comp-item)) - (curr-word (nth 5 curr-item))) - (equal comp-word curr-word)))) - -(defun n-back-matches (what) - "Return non-nil iff last trial part WHAT match." - (cond - ((eq what 'position) (n-back-matches-position)) - ((eq what 'color) (n-back-matches-color)) - ((eq what 'sound) (n-back-matches-sound)) - ((eq what 'word) (n-back-matches-word)) - (t (error "n-back: Unknown match type: %s" what)))) - -(defun n-back-answer (what) - "Tell that you think WHAT matched." - (when (n-back-is-playing) - (if (memq what n-back-active-match-types) - (if (n-back-match-possible) - (let ((sts (if (n-back-matches what) 'ok 'bad))) - (n-back-set-match-status what sts) - (n-back-update-control-buffer)) - (message "%s n-back items must be displayed before anything can match" - n-back-level)) - (message "%s match is not active" what) - (ding t)))) - -(defun n-back-position-answer () - "Tell that you think position matched." - (interactive) - (n-back-answer 'position)) - -(defun n-back-color-answer () - "Tell that you think color matched." - (interactive) - (n-back-answer 'color)) - -(defun n-back-sound-answer () - "Tell that you think sound matched." - (interactive) - (n-back-answer 'sound)) - -(defun n-back-word-answer () - "Tell that you think word matched." - (interactive) - (n-back-answer 'word)) - -(defun n-back-stop () - "Stop playing." - (interactive) - (n-back-cancel-timers) - (n-back-update-control-buffer) - (message "Stopped n-back game") - (n-back-show-welcome "Stopped")) - -(defvar viper-emacs-state-mode-list) ;; silence compiler -(defvar viper-emacs-state-hook) ;; silence compiler - -(define-derived-mode n-back-control-mode nil "N-back" - "Mode for controlling n-back game." - (setq cursor-type nil) - (setq buffer-read-only t) - (set (make-local-variable 'viper-emacs-state-mode-list) '(n-back-control-mode)) - (set (make-local-variable 'viper-emacs-state-hook) nil) ;; in vis cursor - (abbrev-mode -1) - (setq show-trailing-whitespace nil) - (when (fboundp 'visual-line-mode) (visual-line-mode 1)) - (n-back-make-keymap)) - -(defun n-back-cancel-timers () - "Cancel game timers." - (when (timerp n-back-timer) - (cancel-timer n-back-timer)) - (setq n-back-timer nil) - (when (timerp n-back-clear-timer) - (cancel-timer n-back-clear-timer)) - (setq n-back-clear-timer nil) - (winsize-set-mode-line-colors nil)) - -(defvar n-back-game-settings-symbols - '( - ;;n-back-keys - n-back-level - n-back-active-match-types - n-back-allowed-match-types - n-back-auto-challenge - ;;n-back-colors - ;;n-back-words - ;;n-back-sound-volume - ;;n-back-sounds - n-back-sec-per-trial - ;;n-back-keybinding-color - ;;n-back-trials - )) - -(defun n-back-save-game-settings () - "Save game settings." - (interactive) - (dolist (var n-back-game-settings-symbols) - ) - (custom-save-all)) - -(defun n-back-reset-game-to-saved () - "Reset game playing options to saved values." - (interactive) - (dolist (pass '(1 2)) - (dolist (var n-back-game-settings-symbols) - (if (= pass 1) - ;; pass 1 is for my lousy programming: - (condition-case err - (custom-reevaluate-setting var) - (error nil)) - (custom-reevaluate-setting var))))) - -(provide 'n-back) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; n-back.el ends here -- cgit v1.2.3-54-g00ecf