Compare commits

...

255 Commits

Author SHA1 Message Date
bdaloukas 62cf80b78c New: Auto detects common problems in millionaire 7 years ago
bdaloukas f806d6a1bd New: Auto detects common problems in millionaire 7 years ago
bdaloukas 4d354b6809 Fix: Score on hangman with multiple words 7 years ago
bdaloukas 2c4b59b1ec Fix: Score on hangman with multiple words 7 years ago
bdaloukas 07d60b818b New: High score 7 years ago
bdaloukas b8ee927e95 New: High score 7 years ago
bdaloukas 8aa56b2dce New: High score 7 years ago
bdaloukas a90db32a79 Fix: check params of crossword/cryptex 7 years ago
bdaloukas 8d83a8dd03 New: check params of crossword/cryptex 7 years ago
bdaloukas 27ad0335b9 New: check params of crossword/cryptex 7 years ago
bdaloukas 7d6471ebd0 New: check params of crossword/cryptex 7 years ago
bdaloukas c833a32441 Fix: Completion support 8 years ago
bdaloukas ee1f4c711d New: icon.png and icon.svg 8 years ago
bdaloukas b7bebd211a New: icon.png and icon.svg 8 years ago
bdaloukas 7fe559449e Fix: Cloning a game 8 years ago
bdaloukas f19b922da9 Fix problems on backup/restore 8 years ago
bdaloukas 832e080056 Fix problems on backup/restore 8 years ago
bdaloukas 40f8c036b4 Fix problems on backup/restore 8 years ago
bdaloukas 654f6fb342 Fix problems on backup/restore 8 years ago
Vasilis Daloukas 44acd8201d New: support for global glossaries 8 years ago
Vasilis Daloukas 5eb4ad0378 Fix: showanswers.php shows the correct questions 8 years ago
bdaloukas 4c34cc5c88 Fix problems on backup/restore 8 years ago
bdaloukas 2ab98c29c6 Fix problems on backup/restore 8 years ago
bdaloukas 9b34146b22 Fix problems on backup/restore 8 years ago
bdaloukas c89ba8c108 Fix problems on backup/restore 8 years ago
bdaloukas b8c2e4fa78 Message with common problems 8 years ago
bdaloukas a219838adf Message with common problems 8 years ago
bdaloukas a013974a0b Message with common problems 8 years ago
Vasilis Daloukas c62fb5b91e Message with common problems 8 years ago
bdaloukas ab7c945647 Message with common problems 8 years ago
bdaloukas ff577e272f Fix mod_form, show_answers: show numbers of entries in each glossary and question category 8 years ago
bdaloukas 4fbea1a66a Fix mod_form, show_answers: show numbers of entries in each glossary and question category 8 years ago
bdaloukas 2a82e9c5fd Fix mod_form, show_answers: show numbers of entries in each glossary and question category 8 years ago
Vasilis Daloukas 8f25c8cb85 Fix: In millionaire shows the correct number of good multichoice questions 8 years ago
Vasilis Daloukas d0cd349f51 In mod_form.php checks if the selected category corresponds to selected glossary 8 years ago
Vasilis Daloukas e4f9841f37 In mod_form.php checks if the selected category corresponds to selected glossary 8 years ago
bdaloukas a83d03cd8e Fix mod_form: show numbers of entries in each glossary category 8 years ago
bdaloukas 32cdd35c0c In showanswers of millionaire have to show only question with single answer 8 years ago
bdaloukas 781af84c38 Fix MariaDB compatibility 8 years ago
bdaloukas 9e773e6df0 Fix MariaDB compatibility 8 years ago
Vasilis Daloukas 1359a81320 Fix MariaDB compatibility 8 years ago
Vasilis Daloukas e0d4367d99 Fix MariaDB compatibility 8 years ago
Vasilis Daloukas 482cc7713e Fix MariaDB compatibility 8 years ago
bdaloukas 92ec919bab Change name of game_snakes_databases.cols to usedcols 8 years ago
bdaloukas 6d1e03283b Change name of game_snakes_databases.cols to usedcols 8 years ago
bdaloukas 000d4ed082 Change name of game_snakes_databases.cols to usedcols 8 years ago
bdaloukas b96c598cfd Change name of game_snakes_databases.cols to usedcols 8 years ago
bdaloukas c8f99fa305 Change name of game_snakes_databases.cols to usedcols 8 years ago
bdaloukas 38138811bc Change name of game_snakes_databases.cols to usedcols 8 years ago
bdaloukas 503b2a51cd Change name of game_snakes_databases.cols to usedcols 8 years ago
Vasilis Daloukas 07953be271 Stable version 8 years ago
bdaloukas 165456da47 phpdoc compatibility 8 years ago
bdaloukas eb859c7b84 phpdoc compatibility 8 years ago
bdaloukas 1936b9a821 phpdoc compatibility 8 years ago
bdaloukas 79fac57b82 phpdoc compatibility 8 years ago
bdaloukas 639fc36a78 phpdoc compatibility 8 years ago
bdaloukas c490d9e5b3 phpdoc compatibility 8 years ago
bdaloukas 8c05fef0ac phpdoc compatibility 8 years ago
bdaloukas 26325ae71c phpdoc compatibility 8 years ago
bdaloukas 510b1f1976 phpdoc compatibility 8 years ago
bdaloukas 1b8f995352 phpdoc compatibility 8 years ago
bdaloukas 9d6ca6d5f9 phpdoc compatibility 8 years ago
bdaloukas b2a525f003 phpdoc compatibility 8 years ago
bdaloukas d7bb030b0c phpdoc compatibility 8 years ago
bdaloukas 9eaf09d48a phpdoc compatibility 8 years ago
bdaloukas a1ba8e940c phpdoc compatibility 8 years ago
bdaloukas d073e41ed8 phpdoc compatibility 8 years ago
bdaloukas 79c7fc0fe0 phpdoc compatibility 8 years ago
bdaloukas 5d67c8daf7 phpdoc compatibility 8 years ago
bdaloukas 1422796e64 phpdoc compatibility 8 years ago
bdaloukas a2780c58b0 phpdoc compatibility 8 years ago
bdaloukas de3c6c80ad phpdoc compatibility 8 years ago
bdaloukas 4adeba2823 phpdoc compatibility 8 years ago
bdaloukas 294d945be6 phpdoc compatibility 8 years ago
bdaloukas 249309e65d phpdocs compatibility 8 years ago
bdaloukas 80b6fb422d Change name of game_cross.rows to usedrows (MariaDB compatibility) 8 years ago
bdaloukas bb5212d08b Change name of game_cross.rows to usedrows (MariaDB compatibility) 8 years ago
bdaloukas 6bc7177e69 Change name of game_cross.rows to usedrows (MariaDB compatibility) 8 years ago
bdaloukas a16cc8846c Change name of game_cross.rows to usedrows (MariaDB compatibility) 8 years ago
bdaloukas 6ee163b73e phpdocs compatibility 8 years ago
Vasilis Daloukas d02b3da435 lang/en/game.php 8 years ago
bdaloukas 4184be8f11 phpdocs compatibility 8 years ago
bdaloukas 4eaaa8833a phpdocs compatibility 8 years ago
bdaloukas f1d28dda08 phpdocs compatibility 8 years ago
bdaloukas 1a8cde8e86 Fix phpdocs problems 8 years ago
bdaloukas 526fdd2377 Fix phpdocs problems 8 years ago
bdaloukas da1a95eb41 Moodle 3.4 compatibility 8 years ago
bdaloukas 5886d0b7fe Moodle 3.4 compatibility 8 years ago
bdaloukas 961f7ae3c7 Moodle 3.4 compatibility 8 years ago
bdaloukas 1d372a47bd Moodle 3.4 compatibility 8 years ago
bdaloukas e8f682adec Moodle 3.4 compatibility 8 years ago
Vasilis Daloukas 177d1a1b2b Moodle 3.3 compatibility - Export hangman 8 years ago
bdaloukas cd542ba6c4 Menu export is not a sub menu now 8 years ago
Vasilis Daloukas 7fdf1ba09b Moodle 3.3 compatibility 8 years ago
bdaloukas 86b08f1f2a Moodle 3.3 compatibility 8 years ago
bdaloukas 3eede57da9 Fix: Moodle 3.3 compatibility 8 years ago
bdaloukas 830567b24e Fix: PHP coding style problems 8 years ago
bdaloukas 552fad457f Fix: PHP coding style problems 8 years ago
bdaloukas b0ffb2d355 Fix: PHP coding style problems 8 years ago
bdaloukas bdd03e33dd Fix: PHP coding style problems 8 years ago
bdaloukas df488915dd Fix: PHP coding style problems 8 years ago
bdaloukas 80c129876f Moodle 3.3 compatibility 8 years ago
Vasilis Daloukas 01ec387ab6 Fix: recent activity on lib.php 8 years ago
Vasilis Daloukas 2e011ce790 Fix: Moodle 3.1 compatibility problems 8 years ago
Vasilis Daloukas 2ca44530df Fix: allow null at field game_cros.createscrore 8 years ago
Vasilis Daloukas ac04eeab1d Fix Moodle 3.1 compatibility 8 years ago
Vasilis Daloukas 8ca0c4d57c New string (millionaire_lettersall) that will be used to Deutsch language 8 years ago
Vasilis Daloukas 2b2d80c1c2 Fix change type of game_cross 9 years ago
Vasilis Daloukas ac3a48891d Fix Moodle 31 compatibility 9 years ago
Vasilis Daloukas 6036c8c372 Fix Moodle 31 compatibility 9 years ago
Vasilis Daloukas 0fc4259f94 Fix permission problems 9 years ago
Vasilis Daloukas ccdb266d02 Fix permission problems 9 years ago
Vasilis Daloukas ee70032d4f Fix permission problems 9 years ago
Vasilis Daloukas 054f8f335b Fix permission problems 9 years ago
Vasilis Daloukas 2df0ed4ff9 Use get_types or get_shortcuts depended of version of Moodle 9 years ago
Vasilis Daloukas 5df3dcb124 Use get_types or get_shortcuts depended on version of Moodle 9 years ago
Vasilis Daloukas 8ffa4077d9 New: Ability to use only approved glossary entries 9 years ago
Vasilis Daloukas 1902c85eff New: Max compute time in crossword and cryptex 9 years ago
Vasilis Daloukas 11a905dfc2 New: Max compute time in crossword and cryptex 9 years ago
Vasilis Daloukas 8c2daeafea New: Max compute time in crossword and cryptex 9 years ago
Vasilis Daloukas f88407584f Fix compatibility problems with Moodle 2.5 9 years ago
Vasilis Daloukas f16c4f05b4 Fix compatibility problems with Moodle 2.5 9 years ago
Vasilis Daloukas 4713b45e2e Fix compatibility problems with Moodle 2.5 9 years ago
Vasilis Daloukas 7ffef31be4 Fix missing string gameopenclose at lang/en/game.php 9 years ago
bdaloukas 5de0693410 Merge pull request #10 from grigory-catalyst/MOODLE_20_STABLE 9 years ago
Evan Giles 2acccac58c Fix syntax error (missed fullstop for concatenation) 9 years ago
Grigory Baleevskiy ad17ac873c missed semicolon 9 years ago
Vasilis Daloukas 701af20429 Changes on README.md 9 years ago
Vasilis Daloukas 5961b50cfc Fix translations check at translate.php 9 years ago
Vasilis Daloukas 8429cfebdd Fixing how is shows multichoice question on show answers. 9 years ago
Vasilis Daloukas 2ade4d5978 Fixing how is shows multichoice question on show answers. 9 years ago
Vasilis Daloukas f552665ebf Fixing how is shows multichoice question on show answers. 9 years ago
Vasilis Daloukas 2b344cae64 Moodle 3.1 compatibility. 9 years ago
Vasilis Daloukas 1e90449033 Fix not to show how many correct letters are when printing the crossword. 9 years ago
Vasilis Daloukas 6bb87dbcf2 Fix at backup. 9 years ago
Vasilis Daloukas 8ef376b60a Fix at backup. 9 years ago
Vasilis Daloukas 2e6e0e3f21 CONTRIB-5605: Quotation marks breaks the js-code in game Cryptex. 9 years ago
Vasilis Daloukas c8ccbfca96 CONTRIB-5605: Quotation marks breaks the js-code in game Cryptex. 9 years ago
Vasilis Daloukas dac0a0e456 CONTRIB-5605: Quotation marks breaks the js-code in game Cryptex. 9 years ago
Vasilis Daloukas d74a422455 Fixing in crossword no horizontal legend and print button. 9 years ago
Vasilis Daloukas d118183673 Fixing problems on Millionaire with quiz 9 years ago
Vasilis Daloukas f16521bcba More RTL fixes 9 years ago
Vasilis Daloukas 52b4fb3c09 Add missing language string game:addinstance 9 years ago
Vasilis Daloukas b1090cf018 Prevent Style Override of Crossword 9 years ago
Vasilis Daloukas d42bebb1c2 Adding composer.json 9 years ago
Vasilis Daloukas 006174a9a3 CONTRIB-5605: Quotation marks breaks the js-code in game Cryptex. 9 years ago
Vasilis Daloukas 0203d1ecb9 Disable summarize of attempts 9 years ago
Vasilis Daloukas 5f06017913 Fix:Coding style 9 years ago
Vasilis Daloukas 6885a1619d Fix:Coding style 9 years ago
Vasilis Daloukas 938c92ff7b Fix:Coding style 9 years ago
Vasilis Daloukas ecf33ae476 Fix:Coding style 9 years ago
Vasilis Daloukas 95740ab5ae Fix:Coding style 9 years ago
Vasilis Daloukas b57eeead23 Fix:Coding style 9 years ago
Vasilis Daloukas 1bba3bc469 Fix:Coding style 9 years ago
Vasilis Daloukas f8145ebaae Fix:Coding style 9 years ago
Vasilis Daloukas 0ca1e046ba Fix:Coding style 9 years ago
Vasilis Daloukas ddb5311c9f Fix:Coding style 9 years ago
Vasilis Daloukas 3367e7a1df Fix:Coding style 9 years ago
Vasilis Daloukas febd678901 Fix:Coding style 9 years ago
Vasilis Daloukas 593362a22e Fix:Coding style 9 years ago
Vasilis Daloukas dda27f2ccf Fix:Coding style 9 years ago
Vasilis Daloukas b5f11fca18 Fix:Coding style 9 years ago
Vasilis Daloukas f28cb9eb36 Fix:Coding style 9 years ago
Vasilis Daloukas acbd0158ff Fix:Coding style 9 years ago
Vasilis Daloukas 0751505215 Fix:Coding style 9 years ago
Vasilis Daloukas 7b957611bd Fix:Coding style 9 years ago
Vasilis Daloukas f8897ab43d Fix:Coding style 9 years ago
Vasilis Daloukas 6f025e372d Fix:Coding style 9 years ago
Vasilis Daloukas dd33150416 Fix:Field userlanguage in table game 9 years ago
Vasilis Daloukas 8a27fc600f Fix: Millionaire with no random quiz questions 10 years ago
Vasilis Daloukas ab99b86308 New: User defined language at hangman and crossword 10 years ago
Vasilis Daloukas 43a520bd2f Fix: Multianswer questions 10 years ago
Vasilis Daloukas a9501acb77 Fix: Hangman with greek and english words in the same game 10 years ago
Vasilis Daloukas 8e66c259a3 New: Multianswer questions on Book with questions Game 10 years ago
Vasilis Daloukas 15b6bd5c67 Fix: Ignore multianswer questions on Millionaire Game 10 years ago
Vasilis Daloukas 481631eea9 New: Multianswer question on Sudoku Game 10 years ago
Vasilis Daloukas f8f3f7a19b New: Multianswer question on Snakes and Ladders Game 10 years ago
Vasilis Daloukas da980b85e8 New: FinishGame button on Cryptex Game 10 years ago
Vasilis Daloukas 3439e213c2 New: FinishGame button on Cryptex Game 10 years ago
Vasilis Daloukas 0eb760cdd1 New: Print button on Cryptex Game 10 years ago
Vasilis Daloukas 3fbfad1601 Fix: Cryptex - Show grade while game continues 10 years ago
Vasilis Daloukas 3a5f76eb37 CONTRIB-5816: Question bank category not retrieved when Crossword is edited 10 years ago
Vasilis Daloukas 8a61501665 CONTRIB-5816: Question bank category not retrieved when Crossword is edited 10 years ago
Vasilis Daloukas 2ae9e83f7c Fix:Problem on deletion of a game and restore a course 10 years ago
Vasilis Daloukas 02c7d5f414 Fix:Moodle 2.8 compatibility 10 years ago
Vasilis Daloukas b51a602932 Fix: Change in description of parameters for game 'Snake and Laddes' 11 years ago
Vasilis Daloukas ac6b79ad5b New: Image set in hangman 11 years ago
Vasilis Daloukas a77b48a3fb Fix: version.php compatibility with Moodle 2.7 11 years ago
Vasilis Daloukas 1964401125 Fix: Images in questions 11 years ago
Vasilis Daloukas db723d0297 Fix: Images in questions 11 years ago
Vasilis Daloukas bbee9a1b04 Fix: Snakes compatibility with Moodle 1.6 11 years ago
Vasilis Daloukas 438a270743 Fix: Event compatibility with Moodle 1.6 11 years ago
Vasilis Daloukas 6f76a17613 New: parameter disabletransformuppercase in crossword 11 years ago
Vasilis Daloukas 34ff572dd5 Fix: Compatibility with Moodle 2.7 11 years ago
Vasilis Daloukas 6d5c6a378b New: Events in Moodle 2.7 11 years ago
Vasilis Daloukas 42f5e3e4d8 New: Events in Moodle 2.7 11 years ago
Vasilis Daloukas 2ce72b99f3 Fix rtl: very basic fix so all games can be displayed in RTL 11 years ago
bdaloukas 221d08ab04 Fix: Problem when viewing the second page of game attempts 11 years ago
bdaloukas a88e92562c Fix: Millionaire error on Moodle 2.5 11 years ago
bdaloukas 1582066f3e Fix: print_table deprecated 11 years ago
Vasilis Daloukas 8a639e8343 Fix: export to html of millionaire 11 years ago
ubuntu 6f89852b8a Fix: export to html of cross and millionaire 11 years ago
ubuntu e0349fd2d4 CONTRIB-4724: New function module_scale_used_anywhere() should be implemented 11 years ago
ubuntu 02a46f653a CONTRIB-4773 fixed various errors from Tim Lock 11 years ago
ubuntu 2f46048aea CONTRIB-4774 fix:crossword game activity throws database error 11 years ago
ubuntu 5084c94d40 New: Ability to hide some games 11 years ago
bdaloukas e4dd3cab3c Fix: Remove time limit 11 years ago
bdaloukas faa9d5d13e my message 11 years ago
bdaloukas 8204f722c6 Fix: Moodle 2.6 compatibility 11 years ago
bdaloukas 9f8ff52581 New Cross:Show/Hide print button 11 years ago
bdaloukas ad2f652766 Fix: English language file game/lang/en/game.php does not contain $string[modulename] 11 years ago
bdaloukas 08bc04b6b3 Fix: field game_attempts.lastremoteip now saves only the first 30 characters 11 years ago
bdaloukas 94638a3ec3 Deleting file header.php for theme Essential 12 years ago
bdaloukas 14691ab9a5 Deleting file header.php for theme Essential 12 years ago
bdaloukas 4e48edf6d0 Fix: Backward compatibility with Moodle 2.0 and textlib 12 years ago
bdaloukas 01ee1b06c3 Fix: Backward compatibility with Moodle 2.0 and textlib 12 years ago
bdaloukas 76e002e15b Fix: Backward compatibility with Moodle 2.0 and textlib 12 years ago
bdaloukas 887afdefe6 Fix: Backward compatibility with Moodle 2.0 and textlib 12 years ago
root 138c3226e2 Fix: Backward compatibility with Moodle 2.0 and textlib 12 years ago
bdaloukas 03b96e27d0 Fix: install.xml is now compatible with moodle 2.0 12 years ago
ubuntu 4b99463645 Fix: Rename header.php to headergame.php 12 years ago
root c15aabc45d my message 12 years ago
bdaloukas 379b259f85 Fix: Backups the field game.maxattempts 12 years ago
bdaloukas 974d20341e Fix: Problem when a question contains an apostrophe 12 years ago
root 93cf9f15ed Fix: Problem when a question containts an apostrophe 12 years ago
bdaloukas e96f74222b my messag 12 years ago
bdaloukas 3d37cc8c9b Fix: Computing score in cross when using spaces 12 years ago
bdaloukas eb90fd20d3 my message 12 years ago
root 70708fd18a Fix: Show the correct number of attempts to a user 12 years ago
root fe0cf9a1fb New: In parameters you can set the maximum number of attempts 12 years ago
bdaloukas 6f8d9703a5 Fix: Grading method now works ok 12 years ago
bdaloukas fb05776caf New: Writes the version of game at the form of editing the game 12 years ago
bdaloukas 978ab454c7 New: Cross,Cryptex can set the minimum number of words that a cross/cryptex can have 12 years ago
bdaloukas 6a117da888 New: Cross,Cryptex can set the minimum number of words that a cross/cryptex can have 12 years ago
ubuntu b5b2b1a378 Remove translations 12 years ago
ubuntu 25f5f6aa76 Remove translations 12 years ago
ubuntu 530e647902 New string: modulename_help 12 years ago
ubuntu df9e29d3b0 Fix: Moodle 2.5 missing settype 12 years ago
ubuntu 1ba5422c9c Fix: Moodle 2.5 missing settype 12 years ago
bdaloukas 754723e380 Fix: Problem when using subcategories in questions 12 years ago
bdaloukas 8f60fe5da0 Fix: Snakes - Show message when not specified background images 12 years ago
bdaloukas 1156d56bb2 Fix: Millionaire - Problem when using question with question with less than two answers 12 years ago
bdaloukas ff7d6f8c9f Fix: ShowAnswers database error when using categories in glossaries 12 years ago
bdaloukas 41d4517ce7 Cross: Set N20 at least 15 (usefull when contains only small words) 12 years ago
bdaloukas 083b6be6a0 Snake: Fix a problem with imasrc on heavy load 12 years ago
ubuntu c9fa062db8 Fix: HiddenPicture show answers when using a quiz 12 years ago
ubuntu d1293ede85 Fix: HiddenPicture: Default width / height 12 years ago
ubuntu 40df7e9eb8 Fix: Completion settings 12 years ago
bdaloukas fdfad00957 Fix: creating new object 12 years ago
bdaloukas 4da1b966e8 Fix: creating new object 12 years ago
bdaloukas 3600e9b2a3 Change version 12 years ago
bdaloukas fa1760abc7 Fix: Remove reference to yui2_lib 12 years ago
bdaloukas 8632b2c4f7 Fix version.php 12 years ago
bdaloukas 4f19d7fc5b Fix: release in version.php 12 years ago
bdaloukas ebcd4567da First commit 2.0 to git 12 years ago
  1. 233
      CHANGES.md
  2. 52
      README.md
  3. 299
      attempt.php
  4. 74
      backup/moodle2/backup_game_activity_task.class.php
  5. 196
      backup/moodle2/backup_game_stepslib.php
  6. 254
      backup/moodle2/restore_game_activity_task.class.php
  7. 387
      backup/moodle2/restore_game_stepslib.php
  8. 454
      bookquiz/play.php
  9. 195
      bookquiz/questions.php
  10. 142
      bookquiz/toc.php
  11. 236
      bookquiz/view.php
  12. 315
      check.php
  13. 51
      classes/event/course_module_instance_list_viewed.php
  14. 86
      classes/event/course_module_viewed.php
  15. 107
      classes/event/game_played.php
  16. 49
      classes/plugininfo/gametool.php
  17. 10
      composer.json
  18. 920
      cross/cross_class.php
  19. 318
      cross/crossdb_class.php
  20. 1206
      cross/play.php
  21. 320
      cryptex/cryptexdb_class.php
  22. 427
      cryptex/play.php
  23. 118
      db/access.php
  24. 28
      db/createsnakes.php
  25. 82
      db/importsnakes.php
  26. 3554
      db/importsudoku.php
  27. 358
      db/install.xml
  28. 1728
      db/upgrade.php
  29. BIN
      docs/Readme_en.pdf
  30. BIN
      docs/database.pdf
  31. 1048
      docs/database.xmi
  32. BIN
      docs/readme_el.pdf
  33. 338
      export.php
  34. 497
      export/exporthtml.php
  35. 373
      export/exporthtml_hangman.php
  36. 537
      export/exporthtml_millionaire.php
  37. 800
      export/exporthtml_snakes.php
  38. 510
      export/exportjavame.php
  39. 28
      export/html/snakes/css/game.css
  40. 47
      export/html/snakes/css/modal.css
  41. 125
      export/html/snakes/css/snakes.css
  42. 17
      export/html/snakes/css/style.css
  43. 70
      export/html/snakes/css/subModal.css
  44. BIN
      export/html/snakes/js/js.zip
  45. BIN
      export/html/snakes/maskBG.png
  46. 18
      export/html/snakes/modalContent.html
  47. BIN
      export/javame/hangman/simple/KeyCanvas.class
  48. 537
      export/javame/hangman/simple/KeyCanvas.java
  49. BIN
      export/javame/hangman/simple/hangman-1.class
  50. BIN
      export/javame/hangman/simple/hangman.class
  51. 566
      export/javame/hangman/simple/hangman.java
  52. 3
      export/javame/hangman/simple/lang/el_utf8/language.txt
  53. 3
      export/javame/hangman/simple/lang/en_utf8/language.txt
  54. 3
      export/javame/hangman/simple/lang/es_utf8/language.txt
  55. BIN
      export/javame/hangmanp/simple/hangmanp-1.class
  56. BIN
      export/javame/hangmanp/simple/hangmanp.class
  57. 33
      export/javame/hangmanp/simple/hangmanp.java
  58. BIN
      export/javame/hangmanp/simple/keycanvasp.class
  59. 570
      export/javame/hangmanp/simple/keycanvasp.java
  60. 3
      export/javame/hangmanp/simple/lang/el_utf8/language.txt
  61. 3
      export/javame/hangmanp/simple/lang/en_utf8/language.txt
  62. 3
      export/javame/hangmanp/simple/lang/es_utf8/language.txt
  63. 584
      hangman/play.php
  64. 101
      headergame.php
  65. BIN
      hiddenpicture/numbers.png
  66. 152
      hiddenpicture/picture.php
  67. 510
      hiddenpicture/play.php
  68. BIN
      images/soundplay.gif
  69. 111
      index.php
  70. 373
      lang/en/game.php
  71. 1487
      lib.php
  72. 2573
      locallib.php
  73. 766
      millionaire/play.php
  74. 657
      mod_form.php
  75. BIN
      pix/bookquiz/add.gif
  76. BIN
      pix/bookquiz/generateimscp.gif
  77. BIN
      pix/bookquiz/nav_exit.gif
  78. BIN
      pix/bookquiz/nav_next.gif
  79. BIN
      pix/bookquiz/nav_prev.gif
  80. BIN
      pix/bookquiz/nav_prev_dis.gif
  81. BIN
      pix/bookquiz/nav_sep.gif
  82. BIN
      pix/bookquiz/print_book.gif
  83. BIN
      pix/bookquiz/print_chapter.gif
  84. BIN
      pix/hangman/1/hangman_0.jpg
  85. BIN
      pix/hangman/1/hangman_1.jpg
  86. BIN
      pix/hangman/1/hangman_2.jpg
  87. BIN
      pix/hangman/1/hangman_3.jpg
  88. BIN
      pix/hangman/1/hangman_4.jpg
  89. BIN
      pix/hangman/1/hangman_5.jpg
  90. BIN
      pix/hangman/1/hangman_6.jpg
  91. BIN
      pix/icon.gif
  92. BIN
      pix/icon.png
  93. 848
      pix/icon.svg
  94. BIN
      pix/millionaire/1/5050.png
  95. BIN
      pix/millionaire/1/5050x.png
  96. BIN
      pix/millionaire/1/people.png
  97. BIN
      pix/millionaire/1/peoplex.png
  98. BIN
      pix/millionaire/1/telephone.png
  99. BIN
      pix/millionaire/1/telephonex.png
  100. BIN
      pix/millionaire/1/x.png

233
CHANGES.md

@ -0,0 +1,233 @@
Changes in version 2017-08-11 (2017081103)
- New: High score
Changes in version 2017-08-08 (2017080601)
- New: check params of crossword/cryptex
Changes in version 2017-07-19 (2017071902)
- Fix: Completion support
Changes in version 2017-07-18 (2017071801)
- New: icon.png and icon.svg
Changes in version 2017-07-16 (2017071601)
- Fix: Cloning a game
Changes in version 2017-07-06 (2017070606)
- New: Global glossaries
Changes in version 2017-07-05 (2017070502)
- Fix: Problems on backup/restore
Changes in version 2017-07-03 (2017070301)
- New: Auto check for common problem (mod_form.php and view.php for teachers)
Changes in version 2017-06-30 (2017063002)
- in mod_form.php shows the correct numbers of correspondings questions/glossaryentries
- in showanswrs.php shows the correspondings questions/glossaryentries
Changes in version 2017-06-27 (20170627)
- Fix conversation of columns (cols,rows) from string to int
Changes in version 2017-06-20 (20170620)
- Fix conversation of columns (cols,rows) from string to int
Changes in version 2017-06-19 (20170619)
- Change field name game_snakes_database.cols => usedcols
- Change field name game_snakes_database.rows => usedrows
Changes in version 2017-06-10 (20170610)
- Fix phpdocs problems
Changes in version 2017-06-09 (20170609)
- Fix Moodle 3.4 compatibility problems
- Fix stylings problems
Changes in version 2016-08-19 (20160819)
- New string (millionaire_lettersall) that will be used to Deutsch language
Changes in version 2016-06-26 (20160626)
- Change type of game_cross.createscore to double
Changes in version 2016-06-14 (20160614)
- Fix Moodle 31 compatibility
Changes in version 2016-09-17 (20160917)
----------------------------------------
- Fix Moodle 3.1 compatibility problems
Changes in version 2016-04-26 (20160426)
----------------------------------------
- Fix Use get_types or get_shortcuts depended on version of Moodle
Changes in version 2016-03-03 (20160302)
------------------------------------------------------------------
- New: Max compute time in crossword and cryptex
Changes in version 2016-02-14 (20160214)
------------------------------------------------------------------
- Fix syntax error (missed fullstop for concatenation)
- Merge pull request #10 from grigory-catalyst/MOODLE_20_STABLE
- Fix missing string gameopenclose at lang/en/game.php
- Fix compatibility with Moodle 2.5
Changes in version 2015-12-31 (4) (2015123104)
------------------------------------------------------------------
- Fix translations check at translate.php
Changes in version 2015-12-31 (3) (2015123103)
------------------------------------------------------------------
- Fix at backup.
- Fix not to show how many correct letters are when printing the crossword.
- Moodle 3.1 compatibility.
- Fixing how is shows multichoice question on show answers.
Changes in version 3.36.30.1 (2015123001)
------------------------------------------------------------------
- New: Disable summarize of attempts.
- CONTRIB-5605: Quotation marks breaks the js-code in game Cryptex.
- Prevent Style Override of Crossword.
- Add missing language string game:addinstance.
- More RTL fixes.
- Fixing problems on Millionaire with quiz.
- Fixing in crossword no horizontal legend and print button.
Changes in version 3.36.29.1 (2015122901)
------------------------------------------------------------------
- Fixing coding style.
Change for year 2015
------------------------------------------------------------------
- Fix: Millionaire with no random quiz questions.
- New: User defined language at hangman and crossword.
- Fix: Multianswer questions.
- Fix: Hangman with greek and english words in the same game.
- New: Multianswer questions on Book with questions Game.
- Fix: Ignore multianswer questions on Millionaire Game.
- New: Multianswer question on Sudoku Game.
- New: Multianswer question on Snakes and Ladders Game.
- New: FinishGame button on Cryptex Game.
- New: Print button on Cryptex Game
- Fix: Cryptex - Show grade while game continues
- CONTRIB-5816: Question bank category not retrieved when Crossword is …
- CONTRIB-5816: Question bank category not retrieved when Crossword is …
Changes for year 2014
-----------------------
- Fix:Problem on deletion of a game and restore a course
- Fix:Moodle 2.8 compatibility
- Fix: Change in description of parameters for game 'Snake and Laddes'
- New: Image set in hangman
- Fix: version.php compatibility with Moodle 2.7
- Fix: Images in questions
- Fix: Snakes compatibility with Moodle 1.6
- Fix: Event compatibility with Moodle 1.6
- New: parameter disabletransformuppercase in crossword
- Fix: Compatibility with Moodle 2.7
- New: Events in Moodle 2.7
- Fix rtl: very basic fix so all games can be displayed in RTL
- Fix: Problem when viewing the second page of game attempts
- Fix: Millionaire error on Moodle 2.5
- Fix: print_table deprecated
- Fix: export to html of millionaire
Changes for year 2013
------------------------------------------------------------------
- Fix: export to html of cross and millionaire
- CONTRIB-4724: New function module_scale_used_anywhere() should be imp…
- CONTRIB-4773 fixed various errors from Tim Lock
- CONTRIB-4774 fix:crossword game activity throws database error
- New: Ability to hide some games
- Fix: Remove time limit
- Fix: Moodle 2.6 compatibility
- New Cross:Show/Hide print button
- Fix: English language file game/lang/en/game.php does not contain $st…
- Fix: field game_attempts.lastremoteip now saves only the first 30 cha…
- Deleting file header.php for theme Essential
- Fix: Backward compatibility with Moodle 2.0 and textlib
- Fix: install.xml is now compatible with moodle 2.0
- Fix: Rename header.php to headergame.php
- Fix: Backups the field game.maxattempts
- Fix: Problem when a question contains an apostrophe
- Fix: Computing score in cross when using spaces
- Fix: Show the correct number of attempts to a user
- New: In parameters you can set the maximum number of attempts
- Fix: Grading method now works ok
- New: Writes the version of game at the form of editing the game
- New: Cross,Cryptex can set the minimum number of words that a cross/c…
- Remove translations
- New string: modulename_help
- Fix: Moodle 2.5 missing settype
- Fix: Problem when using subcategories in questions
- Fix: Snakes - Show message when not specified background images
- Fix: Millionaire - Problem when using question with question with les…
- Fix: ShowAnswers database error when using categories in glossaries.
- Cross: Set N20 at least 15 (usefull when contains only small words)
- Snake: Fix a problem with imasrc on heavy load
Changes for year 2012
------------------------------------------------------------------
- Fix: HiddenPicture show answers when using a quiz
- Fix: HiddenPicture: Default width / height
- Fix: Completion settings
- Fix: creating new object
- Fix: Remove reference to yui2_lib
- Fix: release in version.php
- First commit 2.0 to git
Changes for year 2011
------------------------------------------------------------------
Changes for year 2010
------------------------------------------------------------------
- Basque (eu) translation by Juan Ezeiza
- Complete German translation by Joachim Vogelgesang
- Translations of some Spanish (es) words from Carolina Avila
- The games now checks how many times is used each word
- Fix: syntax error in get_records_select
- Fix for questions and quiz as input
- Support for right to left allignment in Hangman, Crossword and Cryptex
- First version for Moodle 2
Changes for year 2009
-----------------------
- Millionaire: Select questions from quiz not randomly but serial
- Better German (de) translation by Mike graf
- Better random selection
- Cryptex: Max tries on each question
- Hebrew (he) translation by Nadav Kavalerchik
- Hangman: Export picture-hangman to mobile phone
- Hangman: Now support attachements from glossary
Changes for year 2008
-----------------------
- Cross: Export to html and printing capability
- Fixes: Problem when we select a category in glossary
- New: First version of gradebook on moodle 1.9
- Hangman: Fix - After guessing the word correctly the message displayed after "Congratulations" is not the feedback to the correct answer, but the feedback to the last incorrect question.
- Hidden picture: Fixes a problem when filenames are capitals
- Crossword: '-','/' are not bad chars now
- Doesn't select the correct answer where there are more answers in one question
- Database postgres compatibility
- Polish (pl) translation
- Include subcategories of questions
- Translation to Dutch (nl)
- Hangman: Export to html - works with other languages
- Fix: Problem in mod.html
- Javame: If can't create the jar file creates a zip file instead
- Tables for exporting to javame
- Translaton to Rusian (ru) by Ивченко Анатолий
- Problem when the language of hangman words is different from current language
- When you finish a game and press the 'New game' show some errors
- CONTRIB-446 : When an answer is wrong in millionaire game, the correct answer shown by the system is also wrong
- MDL-15454: After editing a new game for the first time should go to mod.php/update page to make the settings for this game
- Norwegian (no) translation
- Adding game module to CONTRIB.

52
README.md

@ -1,5 +1,5 @@
Game module for Moodle Game module for Moodle
Copyright (C) 2004-2012 Vasilis Daloukas (http://bdaloukas.gr) Copyright (C) 2004-2015 by Vasilis Daloukas (http://bdaloukas.gr)
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -11,20 +11,19 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details: GNU General Public License for more details:
http:www.gnu.org/copyleft/gpl.html http: www.gnu.org/copyleft/gpl.html
Game module for Moodle Game module for Moodle
=============================================================================== ===============================================================================
Created by: Created by: Vasilis Daloukas (bdaloukas)
Vasilis Daloukas (bdaloukas)
Many ideas and code were taken from other Moodle modules and Moodle itself Many ideas and code were taken from other Moodle modules and Moodle itself
Installation:
* see http://docs.moodle.org/en/Installing_contributed_modules_or_plugins
This module gets input from quiz, glossary or questions and plays some games. The games are: This module gets input from quiz, glossary or questions and plays some games. The games are:
* hangman * hangman
* crossword * crossword
* cryptex * cryptex
@ -34,35 +33,16 @@ This module gets input from quiz, glossary or questions and plays some games. Th
* The hidden picture * The hidden picture
* Book with questions * Book with questions
If you like the idea goto http://play2learn.gr/moodle for a demo in Moodle 1.9 or goto to http://ebusiness-lab.epdo.teimes.gr/play2learn/ for a demo in Moodle 2. If you like the Game activity module please consider donating at https://www.paypal.me/moodlegame to help me have more time to continue working on this project. This module is and will remain free, but your donation allows me to continue the development, and any amount is greatly appreciated.
Currently works with 17 languages Català (ca), Deutsch (de), Ελληνικά (el), English (en), Español - Internacional (es), Euskara (eu), Français (fr), ית (he), Hrvatski (hr), Italiano (it), Nederlands (nl), Norsk - bokmal ( no), Polski (pl), Português - Brasil (pt_br), Русский (ru), Shqip (sq), Українська (uk), 简体中文 (zh_cn) languages.
If you like the module Game please donate at http://bdaloukas.gr/donate/moodlegame/, help me to have more time to continue working on this project. This module is and will remain free, but your donation allows me to continue the development, and any amount is greatly appreciated.
Documentation http://docs.moodle.org/en/Game_module
Browse source code http://cvs.moodle.org/contrib/plugins/mod/game/
Changelog https://docs.google.com/document/pub?id=1-WJUa_Hbdo9eualKSjjP9wTnI4GVMs4JYDaLypU2IDQ
Discussion http://moodle.org/mod/forum/view.php?id=7220
Download for Moodle 2.0 http://download.moodle.org/download.php/plugins/mod/game.zip
Download for Moodle 1.9 http://download.moodle.org/download.php/plugins19/mod/game.zip
Bugs and Issues http://tracker.moodle.org/browse/CONTRIB/component/10295
Interface:
* The interface is like a quiz. The student plays games and teacher can see the grades
* You can set a text that will be visible at the bottom of the game. In this way will be a picture at the bottom and a crossword with questions about the picture
* You can use pictures inside questions
Restrictions:
* You can only backup/restore the data of game not the user attempts. (not works backup now)
* In the report overview you can see only what students said for questions not for glossaryentries
Upgrade * Changelog: CHANGES.md
* Documentation: http://docs.moodle.org/en/Game_module
* Browse source code: https://github.com/bdaloukas/moodle-mod_game
* Download for Moodle 2 & 3: https://codeload.github.com/bdaloukas/moodle-mod_game/zip/MOODLE_20_STABLE
* Download for Moodle 1.9: https://codeload.github.com/bdaloukas/moodle-mod_game/zip/MOODLE_19_STABLE
* Download with git: type the next command in the root of your Moodle install: "git clone -b MOODLE_20_STABLE https://github.com/bdaloukas/moodle-mod_game.git mod/game"
* Discussion: http://moodle.org/mod/forum/view.php?id=7220
* Bugs and Issues: http://tracker.moodle.org/browse/CONTRIB/component/10295
* Installation: http://docs.moodle.org/en/Installing_contributed_modules_or_plugins
* Delete the files from mod/game Supported languages: Català (ca), Deutsch (de), Ελληνικά (el), English (en), Español - Internacional (es), Euskara (eu), Français (fr), ית (he), Hrvatski (hr), Italiano (it), Nederlands (nl), Norsk - bokmal ( no), Polski (pl), Português - Brasil (pt_br), Русский (ru), Shqip (sq), Українська (uk), 简体中文 (zh_cn).
* Copy the new files to mod/game

299
attempt.php

@ -0,0 +1,299 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page prints a particular attempt of game
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
**/
require_once( "../../config.php");
require_once( "lib.php");
require_once( "locallib.php");
require_once( "hangman/play.php");
require_once( "cross/play.php");
require_once( "cryptex/play.php");
require_once( "millionaire/play.php");
require_once( "sudoku/play.php");
require_once( "bookquiz/play.php");
require_once( "snakes/play.php");
require_once( "hiddenpicture/play.php");
$action = optional_param('action', "", PARAM_ALPHANUM); // Is the param action.
game_show_header( $id, $game, $course, $context);
game_do_attempt( $id, $game, $action, $course, $context);
/**
* Do the required checks and print header.
*
* @param int $id
* @param stdClass $game
* @param stdClass $course
* @param stdClass $context
*/
function game_show_header( &$id, &$game, &$course, &$context) {
global $DB, $USER, $PAGE, $OUTPUT;
$id = optional_param('id', 0, PARAM_INT); // It represents Course Module ID.
$q = optional_param('q', 0, PARAM_INT); // It represents game id.
if ($id) {
if (! $cm = get_coursemodule_from_id('game', $id)) {
print_error('invalidcoursemodule');
}
if (! $course = $DB->get_record('course', array('id' => $cm->course))) {
print_error('coursemisconf');
}
if (! $game = $DB->get_record('game', array('id' => $cm->instance))) {
print_error('invalidcoursemodule');
}
} else {
if (! $game = $DB->get_record('game', array('id' => $q))) {
print_error('invalidgameid', 'game');
}
if (! $course = $DB->get_record('course', array('id' => $game->course))) {
print_error('invalidcourseid');
}
if (! $cm = get_coursemodule_from_instance('game', $game->id, $course->id)) {
print_error('invalidcoursemodule');
}
}
// Check login and get context.
require_login($course->id, false, $cm);
$context = game_get_context_module_instance( $cm->id);
require_capability('mod/game:view', $context);
// Cache some other capabilites we use several times.
$canattempt = has_capability('mod/game:attempt', $context);
$canreviewmine = has_capability('mod/game:reviewmyattempts', $context);
// Create an object to manage all the other (non-roles) access rules.
$timenow = time();
// Log this request.
if ( game_use_events()) {
require( 'classes/event/game_played.php');
\mod_game\event\game_played::played($game, $context)->trigger();
} else {
add_to_log($course->id, 'game', 'view', "view.php?id=$cm->id", $game->id, $cm->id);
}
// Initialize $PAGE, compute blocks.
$PAGE->set_url('/mod/game/view.php', array('id' => $cm->id));
$edit = optional_param('edit', -1, PARAM_BOOL);
if ($edit != -1 && $PAGE->user_allowed_editing()) {
$USER->editing = $edit;
}
// Note: MDL-19010 there will be further changes to printing header and blocks.
// The code will be much nicer than this eventually.
$title = $course->shortname . ': ' . format_string($game->name);
if ($PAGE->user_allowed_editing() && !empty($CFG->showblocksonmodpages)) {
$buttons = '<table><tr><td><form method="get" action="view.php"><div>'.
'<input type="hidden" name="id" value="'.$cm->id.'" />'.
'<input type="hidden" name="edit" value="'.($PAGE->user_is_editing() ? 'off' : 'on').'" />'.
'<input type="submit" value="'.get_string($PAGE->user_is_editing() ? 'blockseditoff' : 'blocksediton').
'" /></div></form></td></tr></table>';
$PAGE->set_button($buttons);
}
$PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
}
/**
* Do one attempt.
*
* @param int $id
* @param stdClass $game
* @param string $action
* @param stdClass $course
* @param stdClass $context
*/
function game_do_attempt( $id, $game, $action, $course, $context) {
global $OUTPUT;
$forcenew = optional_param('forcenew', false, PARAM_BOOL); // Teacher has requested new preview.
$endofgame = optional_param('endofgame', false, PARAM_BOOL);
$pos = optional_param('pos', 0, PARAM_INT);
$num = optional_param('num', 0, PARAM_INT);
$q = optional_param('q', 0, PARAM_INT);
$attemptid = optional_param('attemptid', 0, PARAM_INT);
$g = optional_param('g', '', PARAM_RAW);
$finishattempt = optional_param('finishattempt', '', PARAM_TEXT);
$answer = optional_param('answer', '', PARAM_TEXT);
$continue = false;
// Print the main part of the page.
switch ( $action) {
case 'crosscheck':
$attempt = game_getattempt( $game, $detail);
$g = game_cross_unpackpuzzle( $g);
game_cross_continue( $id, $game, $attempt, $detail, $g, $finishattempt, $context);
break;
case 'crossprint':
$attempt = game_getattempt( $game, $detail);
game_cross_play( $id, $game, $attempt, $detail, '', true, false, false, true, $context);
break;
case 'sudokucheck': // The student tries to answer a question.
$attempt = game_getattempt( $game, $detail);
game_sudoku_check_questions( $id, $game, $attempt, $detail, $finishattempt, $course, $context);
$continue = true;
break;
case 'sudokucheckg': // The student tries to guess a glossaryenry.
$attempt = game_getattempt( $game, $detail);
$endofgame = array_key_exists( 'endofgame', $_GET);
$continue = game_sudoku_check_glossaryentries( $id, $game, $attempt, $detail, $endofgame, $course);
$continue = true;
break;
case 'sudokucheckn': // The user tries to guess a number.
$attempt = game_getattempt( $game, $detail);
game_sudoku_check_number( $id, $game, $attempt, $detail, $pos, $num, $context);
$continue = false;
break;
case 'cryptexcheck': // The user tries to guess a question.
$attempt = game_getattempt( $game, $detail);
game_cryptex_check( $id, $game, $attempt, $detail, $q, $answer, $finishattempt, $context);
break;
case 'bookquizcheck': // The student tries to answer a question.
$attempt = game_getattempt( $game, $detail);
game_bookquiz_check_questions( $id, $game, $attempt, $detail, $context);
break;
case 'snakescheck': // The student tries to answer a question.
$attempt = game_getattempt( $game, $detail);
game_snakes_check_questions( $id, $game, $attempt, $detail, $context);
break;
case 'snakescheckg': // The student tries to answer a question from glossary.
$attempt = game_getattempt( $game, $detail);
game_snakes_check_glossary( $id, $game, $attempt, $detail, $context);
break;
case 'hiddenpicturecheckg': // The student tries to guess a glossaryentry.
$attempt = game_getattempt( $game, $detail);
game_hiddenpicture_check_mainquestion( $id, $game, $attempt, $detail, $endofgame, $context);
break;
default:
$continue = true;
break;
}
if ($continue) {
game_create( $game, $id, $forcenew, $course, $context);
}
// Finish the page.
echo $OUTPUT->footer();
}
/**
* Creates one game.
*
* @param stdClass $game
* @param int $id
* @param int $forcenew
* @param stdClass $course
* @param stdClass $context
*/
function game_create( $game, $id, $forcenew, $course, $context) {
global $USER, $CFG, $DB;
$attempt = game_getattempt( $game, $detail);
$chapterid = optional_param('chapterid', 0, PARAM_INT);
$newletter = optional_param('newletter', '', PARAM_ALPHA);
$action2 = optional_param('action2', '', PARAM_ALPHA);
switch ( $game->gamekind) {
case 'cross':
game_cross_continue( $id, $game, $attempt, $detail, '', $forcenew, $context);
break;
case 'hangman':
game_hangman_continue( $id, $game, $attempt, $detail, $newletter, $action2, $context);
break;
case 'millionaire':
game_millionaire_continue( $id, $game, $attempt, $detail, $context);
break;
case 'bookquiz':
game_bookquiz_continue( $id, $game, $attempt, $detail, $chapterid, $context);
break;
case 'sudoku':
game_sudoku_continue( $id, $game, $attempt, $detail, '', $context);
break;
case 'cryptex':
game_cryptex_continue( $id, $game, $attempt, $detail, $forcenew, $context);
break;
case 'snakes':
game_snakes_continue( $id, $game, $attempt, $detail, $context);
break;
case 'hiddenpicture':
game_hiddenpicture_continue( $id, $game, $attempt, $detail, $context);
break;
default:
print_error( "Game {$game->gamekind} not found");
break;
}
}
/**
* Unpacks the cross.
*
* @param string $g
*/
function game_cross_unpackpuzzle( $g) {
$ret = "";
$len = game_strlen( $g);
while ($len) {
for ($i = 0; $i < $len; $i++) {
$c = game_substr( $g, $i, 1);
if ( $c >= '1' and $c <= '9') {
if ( $i > 0) {
// Found escape character.
if (game_substr( $g, $i - 1, 1) == '/') {
$g = game_substr( $g, 0, $i - 1).game_substr( $g, $i);
$i--;
$len--;
continue;
}
}
break;
}
}
if ($i < $len) {
// Found the start of a number.
for ($j = $i + 1; $j < $len; $j++) {
$c = game_substr( $g, $j, 1);
if ($c < '0' or $c > '9') {
break;
}
}
$count = game_substr( $g, $i, $j - $i);
$ret .= game_substr( $g, 0, $i) . str_repeat( '_', $count);
$g = game_substr( $g, $j);
$len = game_strlen( $g);
} else {
$ret .= $g;
break;
}
}
return $ret;
}

74
backup/moodle2/backup_game_activity_task.class.php

@ -0,0 +1,74 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Defines backup_glossary_activity_task class
*
* @package mod_game
* @subpackage backup-moodle2
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
**/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/game/backup/moodle2/backup_game_stepslib.php'); // Because it exists (must).
/**
* Fame backup task that provides all the settings and steps to perform one complete backup of the activity
*
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class backup_game_activity_task extends backup_activity_task {
/**
* Define (add) particular settings this activity can have
*/
protected function define_my_settings() {
// No particular settings for this activity.
}
/**
* Define (add) particular steps this activity can have
*/
protected function define_my_steps() {
// Game only has one structure step.
$this->add_step(new backup_game_activity_structure_step('game_structure', 'game.xml'));
}
/**
* Encodes URLs to the index.php and view.php scripts
*
* @param string $content some HTML text that eventually contains URLs to the activity instance scripts
* @return string the content with the URLs encoded
*/
static public function encode_content_links($content) {
global $CFG;
$base = preg_quote($CFG->wwwroot, "/");
// Link to the list of games.
$search = "/(".$base."\/mod\/game\/index.php\?id\=)([0-9]+)/";
$content = preg_replace($search, '$@GAMEINDEX*$2@$', $content);
// Link to game view by moduleid.
$search = "/(".$base."\/mod\/game\/view.php\?id\=)([0-9]+)/";
$content = preg_replace($search, '$@GAMEVIEWBYID*$2@$', $content);
return $content;
}
}

196
backup/moodle2/backup_game_stepslib.php

@ -0,0 +1,196 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Define all the backup steps that will be used by the backup_game_activity_task
*
* @package mod_game
* @subpackage backup-moodle2
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Define the complete game structure for backup, with file and id annotations
*
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Define the complete game structure for backup, with file and id annotations
*
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class backup_game_activity_structure_step extends backup_activity_structure_step {
/**
* Defines the needed structures.
*/
protected function define_structure() {
// To know if we are including userinfo.
$userinfo = $this->get_setting_value('userinfo');
// Define each element separated (exclude fields: course).
$game = new backup_nested_element('game', array('id'), array(
'name', 'sourcemodule', 'timeopen', 'timeclose', 'quizid',
'glossaryid', 'glossarycategoryid', 'questioncategoryid', 'bookid',
'gamekind', 'param1', 'param2', 'param3',
'param4', 'param5', 'param6', 'param7', 'param8', 'param9', 'param10',
'shuffle', 'timemodified', 'toptext', 'bottomtext',
'grademethod', 'grade', 'decimalpoints', 'popup',
'review', 'attempts', 'glossaryid2', 'glossarycategoryid2',
'language', 'subcategories', 'maxattempts', 'userlanguage', 'disablesummarize', 'glossaryonlyapproved'
));
$exporthtmls = new backup_nested_element('game_export_htmls');
$exporthtml = new backup_nested_element('game_export_html', array('id'), array(
'filename', 'title', 'checkbutton', 'printbutton', 'inputsize', 'maxpicturewidth', 'maxpictureheight', 'type'));
$exportjavames = new backup_nested_element('game_export_javames');
$exportjavame = new backup_nested_element('game_export_javame', array('id'), array(
'filename', 'icon', 'createdby', 'vendor', 'name', 'description', 'version',
'maxpicturewidth', 'maxpictureheight', 'type'));
$grades = new backup_nested_element('game_grades');
$grade = new backup_nested_element('game_grade', array('id'), array(
'userid', 'score', 'timemodified'));
$repetitions = new backup_nested_element('game_repetitions');
$repetition = new backup_nested_element('game_repetition', array('id'), array(
'userid', 'questionid', 'glossaryentryid', 'repetitions'));
$attempts = new backup_nested_element('game_attempts');
$attempt = new backup_nested_element('game_attempt', array('id'), array(
'userid', 'timestart', 'timefinish', 'timelastattempt', 'lastip',
'lastremotehost', 'preview', 'attempt', 'score', 'attempts', 'language'));
$querys = new backup_nested_element('game_queries');
$query = new backup_nested_element('game_query', array('id'), array(
'gamekind', 'userid', 'sourcemodule', 'questionid', 'glossaryentryid',
'questiontext', 'score', 'timelastattempt', 'studentanswer', 'col', 'row',
'horizontal', 'answertext', 'correct', 'attachment', 'answerid', 'tries'));
$bookquizquestions = new backup_nested_element('game_bookquiz_questions');
$bookquizquestion = new backup_nested_element('game_bookquiz_question', array('id'), array(
'chapterid', 'questioncategoryid'));
// The games attemtps.
$bookquiz = new backup_nested_element('game_bookquiz', array('id'), array('lastchapterid'));
$bookquizchapters = new backup_nested_element('game_bookquiz_chapters');
$bookquizchapter = new backup_nested_element('game_bookquiz_chapter', array('id'), array( 'chapterid'));
$cross = new backup_nested_element('game_cross', array('id'), array(
'usedcols', 'usedrows', 'words', 'wordsall', 'createscore', 'createtries',
'createtimelimit', 'createconnectors', 'createfilleds', 'createspaces', 'triesplay'));
$cryptex = new backup_nested_element('game_cryptex', array('id'), array('letters'));
$hangman = new backup_nested_element('game_hangman', array('id'), array(
'queryid', 'letters', 'allletters', 'try', 'maxtries', 'finishedword',
'corrects', 'iscorrect'));
$hiddenpicture = new backup_nested_element('game_hiddenpicture', array('id'), array('correct', 'wrong', 'found'));
$millionaire = new backup_nested_element('game_millionaire', array('id'), array('queryid', 'state', 'level'));
$snake = new backup_nested_element('game_snake', array('id'), array('snakesdatabaseid', 'position', 'queryid', 'dice'));
$sudoku = new backup_nested_element('game_sudoku', array('id'), array('level', 'data', 'opened', 'guess'));
// Build the tree.
$game->add_child( $bookquizquestions);
$bookquizquestions->add_child( $bookquizquestion);
$game->add_child( $exporthtmls);
$exporthtmls->add_child( $exporthtml);
$game->add_child( $exportjavames);
$exportjavames->add_child( $exportjavame);
// All these source definitions only happen if we are including user info.
if ($userinfo) {
$game->add_child( $grades);
$grades->add_child( $grade);
$game->add_child( $repetitions);
$repetitions->add_child( $repetition);
$game->add_child( $attempts);
$attempts->add_child( $attempt);
$attempt->add_child( $querys);
$querys->add_child( $query);
// All games.
$attempt->add_child( $bookquiz);
$attempt->add_child( $bookquizchapters);
$bookquizchapters->add_child($bookquizchapter);
$attempt->add_child( $cross);
$attempt->add_child( $cryptex);
$attempt->add_child( $hangman);
$attempt->add_child( $hiddenpicture);
$attempt->add_child( $millionaire);
$attempt->add_child( $snake);
$attempt->add_child( $sudoku);
}
// Define sources.
$game->set_source_table('game', array('id' => backup::VAR_ACTIVITYID));
$bookquizquestion->set_source_table('game_bookquiz_questions', array('gameid' => backup::VAR_ACTIVITYID));
$exporthtml->set_source_table('game_export_html', array('id' => backup::VAR_ACTIVITYID));
$exportjavame->set_source_table('game_export_javame', array('id' => backup::VAR_ACTIVITYID));
// All the rest of elements only happen if we are including user info.
if ($userinfo) {
$grade->set_source_table('game_grades', array('gameid' => backup::VAR_ACTIVITYID));
$repetition->set_source_table('game_repetitions', array('gameid' => backup::VAR_ACTIVITYID));
$attempt->set_source_table('game_attempts', array( 'gameid' => backup::VAR_ACTIVITYID));
$query->set_source_table('game_queries', array( 'attemptid' => backup::VAR_PARENTID));
$bookquiz->set_source_table('game_bookquiz', array( 'id' => backup::VAR_ACTIVITYID));
$bookquizchapter->set_source_table('game_bookquiz_chapters', array( 'id' => backup::VAR_PARENTID));
$cross->set_source_table('game_cross', array( 'id' => backup::VAR_PARENTID));
$cryptex->set_source_table('game_cryptex', array( 'id' => backup::VAR_PARENTID));
$hangman->set_source_table('game_hangman', array( 'id' => backup::VAR_PARENTID));
$hiddenpicture->set_source_table('game_hiddenpicture', array( 'id' => backup::VAR_PARENTID));
$millionaire->set_source_table('game_millionaire', array( 'id' => backup::VAR_PARENTID));
$snake->set_source_table('game_snakes', array( 'id' => backup::VAR_PARENTID));
$sudoku->set_source_table('game_sudoku', array( 'id' => backup::VAR_PARENTID));
}
// Define id annotations.
$attempt->annotate_ids('user', 'userid');
$grade->annotate_ids('user', 'userid');
$repetition->annotate_ids('user', 'userid');
$repetition->annotate_ids('question', 'questionid');
$repetition->annotate_ids('glossary_entries', 'glossaryentryid');
$query->annotate_ids('user', 'userid');
$query->annotate_ids('question', 'questionid');
$query->annotate_ids('glossary_entries', 'glossaryentryid');
$query->annotate_ids('question_answer', 'answerid');
$bookquizquestion->annotate_ids('book_chapter', 'chapterid');
$bookquizquestion->annotate_ids('question_category', 'questioncategoryid');
$bookquizchapter->annotate_ids('book_chapter', 'chapterid');
// Define file annotations.
$game->annotate_files('mod_game', 'snakes_file', null); // This file area hasn't itemid.
$game->annotate_files('mod_game', 'snakes_board', null); // This file area hasn't itemid.
// Return the root element (game), wrapped into standard activity structure.
return $this->prepare_activity_structure( $game);
}
}

254
backup/moodle2/restore_game_activity_task.class.php

@ -0,0 +1,254 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Restores a game
*
* @package mod_game
* @subpackage backup-moodle2
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/game/backup/moodle2/restore_game_stepslib.php'); // Because it exists (must).
/**
* game restore task that provides all the settings and steps to perform one complete restore of the activity
*
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_game_activity_task extends restore_activity_task {
/**
* Define (add) particular settings this activity can have
*/
protected function define_my_settings() {
// No particular settings for this activity.
}
/**
* Define (add) particular steps this activity can have
*/
protected function define_my_steps() {
// Game only has one structure step.
$this->add_step(new restore_game_activity_structure_step('game_structure', 'game.xml'));
}
/**
* Define the contents in the activity that must be
* processed by the link decoder
*/
static public function define_decode_contents() {
$contents = array();
$contents[] = new restore_decode_content('game', array('toptext'), 'game');
$contents[] = new restore_decode_content('game', array('bottomtext'), 'game');
return $contents;
}
/**
* Define the decoding rules for links belonging
* to the activity to be executed by the link decoder
*/
static public function define_decode_rules() {
$rules = array();
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* game logs. It must return one array
* of {@link restore_log_rule} objects
*/
static public function define_restore_log_rules() {
$rules = array();
$rules[] = new restore_log_rule('game', 'add', 'view.php?id={course_module}', '{game}');
$rules[] = new restore_log_rule('game', 'update', 'view.php?id={course_module}', '{game}');
$rules[] = new restore_log_rule('game', 'view', 'view.php?id={course_module}', '{game}');
$rules[] = new restore_log_rule('game', 'choose', 'view.php?id={course_module}', '{game}');
$rules[] = new restore_log_rule('game', 'choose again', 'view.php?id={course_module}', '{game}');
$rules[] = new restore_log_rule('game', 'report', 'report.php?id={course_module}', '{game}');
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* course logs. It must return one array
* of {@link restore_log_rule} objects
*
* Note this rules are applied when restoring course logs
* by the restore final task, but are defined here at
* activity level. All them are rules not linked to any module instance (cmid = 0)
*/
static public function define_restore_log_rules_for_course() {
$rules = array();
// Fix old wrong uses (missing extension).
$rules[] = new restore_log_rule('game', 'view all', 'index?id={course}', null,
null, null, 'index.php?id={course}');
$rules[] = new restore_log_rule('game', 'view all', 'index.php?id={course}', null);
return $rules;
}
/**
* Do something at end of restore.
*/
public function after_restore() {
global $DB;
// Get the blockid.
$gameid = $this->get_activityid();
// Extract Game configdata and update it to point to the new glossary.
$rec = $DB->get_record_select( 'game', 'id='.$gameid,
null, 'id,quizid,glossaryid,glossarycategoryid,questioncategoryid,bookid,glossaryid2,glossarycategoryid2');
$restoreid = $this->get_restoreid();
$ret = restore_dbops::get_backup_ids_record($restoreid, 'quiz', $rec->quizid);
if ($ret != false) {
$rec->quizid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($restoreid, 'glossary', $rec->glossaryid);
if ($ret != false) {
$rec->glossaryid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($restoreid, 'glossary_categories', $rec->glossarycategoryid);
if ($ret != false) {
$rec->glossarycategoryid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($restoreid, 'question_categories', $rec->questioncategoryid);
if ($ret != false) {
$rec->questioncategoryid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($restoreid, 'book', $rec->bookid);
if ($ret != false) {
$rec->bookid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($restoreid, 'glossary', $rec->glossaryid2);
if ($ret != false) {
$rec->glossaryid2 = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($restoreid, 'glossary_categories', $rec->glossarycategoryid);
if ($ret != false) {
$rec->glossarycategoryid = $ret->newitemid;
}
$DB->update_record( 'game', $rec);
// Read game_repetitions.
$recs = $DB->get_records_select( 'game_repetitions', 'gameid='.$gameid, null, '',
'id,questionid,glossaryentryid');
if ($recs != false) {
foreach ($recs as $rec) {
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question', $rec->questionid);
if ($ret != false) {
$rec->questionid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary_entry', $rec->glossaryentryid);
if ($ret != false) {
$rec->glossaryentryid = $ret->newitemid;
}
$DB->update_record( 'game_repetitions', $rec);
}
}
// Read game_queries.
$recs = $DB->get_records_select( 'game_queries', 'gameid='.$gameid, null, '',
'id,questionid,glossaryentryid,answerid');
if ($recs != false) {
foreach ($recs as $rec) {
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question', $rec->questionid);
if ($ret != false) {
$rec->questionid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary_entry', $rec->glossaryentryid);
if ($ret != false) {
$rec->glossaryentryid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question_answers', $rec->glossaryentryid);
if ($ret != false) {
$rec->answerid = $ret->newitemid;
}
$DB->update_record( 'game_queries', $rec);
}
}
// Read bookquiz.
$recs = $DB->get_records_select( 'game_bookquiz', 'id='.$gameid, null, '', 'id,lastchapterid');
if ($recs != false) {
foreach ($recs as $rec) {
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book_chapters', $rec->lastchapterid);
if ($ret != false) {
$rec->lastchapterid = $ret->newitemid;
}
$DB->update_record( 'game_bookquiz', $rec);
}
}
// Read bookquiz_chapters.
$sql = "SELECT gbc.* ".
"FROM {game_bookquiz_chapters} gbc LEFT JOIN {game_attempts} a ON gbc.attemptid = a.id".
" WHERE a.gameid=$gameid";
$recs = $DB->get_records_sql( $sql);
if ($recs != false) {
foreach ($recs as $rec) {
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book_chapters', $rec->chapterid);
if ($ret != false) {
$rec->chapterid = $ret->newitemid;
}
$DB->update_record( 'game_bookquiz_chapter', $rec);
}
}
// Read bookquiz_questions.
$recs = $DB->get_records_select( 'game_bookquiz_questions', 'id='.$gameid, null, '', 'id,chapterid,questioncategoryid');
if ($recs != false) {
foreach ($recs as $rec) {
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book_chapters', $rec->chapterid);
if ($ret != false) {
$rec->chapterid = $ret->newitemid;
}
$ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book_chapters', $rec->questioncategoryid);
if ($ret != false) {
$rec->questioncategoryid = $ret->newitemid;
}
$DB->update_record( 'game_bookquiz_questions', $rec);
}
}
}
}

387
backup/moodle2/restore_game_stepslib.php

@ -0,0 +1,387 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Define all the restore steps that will be used by the restore_game_activity_task
*
* @package mod_game
* @subpackage backup-moodle2
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/game/locallib.php');
/**
* Structure step to restore one game activity
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_game_activity_structure_step extends restore_activity_structure_step {
/**
* Defines the neeeded structures.
*
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
protected function define_structure() {
$paths = array();
$userinfo = $this->get_setting_value('userinfo');
$paths[] = new restore_path_element('game', '/activity/game');
$paths[] = new restore_path_element('game_export_html', '/activity/game/game_export_htmls/game_export_html');
$paths[] = new restore_path_element('game_export_javame', '/activity/game/game_export_htmls/game_export_javame');
$paths[] = new restore_path_element(
'game_bookquiz_question', '/activity/game/game_bookquiz_questions/game_bookquiz_question');
if ($userinfo) {
$paths[] = new restore_path_element('game_grade', '/activity/game/game_grades/game_grade');
$paths[] = new restore_path_element('game_repetition', '/activity/game/game_repetiotions/game_repetition');
$paths[] = new restore_path_element('game_attempt', '/activity/game/game_attempts/game_attempt');
$paths[] = new restore_path_element('game_query', '/activity/game/game_attempts/game_attempt/game_queries/game_query');
// The games.
$paths[] = new restore_path_element('game_bookquiz', '/activity/game/game_attempts/game_attempt/game_bookquiz');
$paths[] = new restore_path_element('game_bookquiz_chapter',
'/activity/game/game_attempts/game_attempt/game_bookquiz_chapters/game_bookquiz_chapter');
$paths[] = new restore_path_element('game_cross', '/activity/game/game_attempts/game_attempt/game_cross');
$paths[] = new restore_path_element('game_cryptex', '/activity/game/game_attempts/game_attempt/game_cryptex');
$paths[] = new restore_path_element('game_hangman', '/activity/game/game_attempts/game_attempt/game_hangman');
$paths[] = new restore_path_element('game_hiddenpicture',
'/activity/game/game_attempts/game_attempt/game_hiddenpicture');
$paths[] = new restore_path_element('game_millionaire', '/activity/game/game_attempts/game_attempt/game_millionaire');
$paths[] = new restore_path_element('game_snake', '/activity/game/game_attempts/game_attempt/game_snake');
$paths[] = new restore_path_element('game_sudoku', '/activity/game/game_attempts/game_attempt/game_sudoku');
}
// Return the paths wrapped into standard activity structure.
return $this->prepare_activity_structure($paths);
}
/**
* Restores the game table.
*
* @param stdClass $data
*/
protected function process_game($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->course = $this->get_courseid();
$data->timemodified = $this->apply_date_offset($data->timemodified);
// Insert the game record.
$newitemid = $DB->insert_record('game', $data);
$this->set_mapping('game', $oldid, $newitemid);
// Immediately after inserting "activity" record, call this.
$this->apply_activity_instance($newitemid);
}
/**
* Restores the game_export_html table.
*
* @param stdClass $data
*/
protected function process_game_export_html($data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game');
if ($data->id != 0) {
$DB->insert_record('game_export_html', $data);
}
}
/**
* Restores the game_export_javame table.
*
* @param stdClass $data
*/
protected function process_game_export_javame( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game');
if ($data->id != 0) {
$DB->insert_record('game_export_javame', $data);
}
}
/**
* Restores the game_grades table.
*
* @param stdClass $data
*/
protected function process_game_grade( $data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->gameid = $this->get_new_parentid('game');
$data->userid = $this->get_mappingid('user', $data->userid);
$DB->insert_record('game_grades', $data);
}
/**
* Restores the game_repetitions table.
*
* @param stdClass $data
*/
protected function process_game_repetition( $data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->gameid = $this->get_new_parentid('game');
$data->userid = $this->get_mappingid('user', $data->userid);
$data->questionid = $this->get_mappingid('question', $data->questionid);
$data->glossaryentrydid = $this->get_mappingid('glossary_entries', $data->questionid);
$DB->insert_record('game_repetitions', $data);
}
/**
* Restores the game_attempts table.
*
* @param stdClass $data
*/
protected function process_game_attempt( $data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->gameid = $this->get_new_parentid('game');
$data->userid = $this->get_mappingid('user', $data->userid);
if (!isset( $data->timestart)) {
$data->timestart = 0;
}
if (!isset( $data->timefinish)) {
$data->timefinish = 0;
}
if (!isset( $data->timelastattempt)) {
$data->timelastattempt = 0;
}
$data->timestart = $this->apply_date_offset($data->timestart);
$data->timefinish = $this->apply_date_offset($data->timefinish);
$data->timelastattempt = $this->apply_date_offset($data->timelastattempt);
$newitemid = $DB->insert_record('game_attempts', $data);
$this->set_mapping('game_attempt', $oldid, $newitemid);
}
/**
* Restores the game_queries table.
*
* @param stdClass $data
*/
protected function process_game_query( $data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->gameid = $this->get_new_parentid('game');
$data->attemptid = $this->get_new_parentid('game_attempt');
$data->userid = $this->get_mappingid('user', $data->userid);
$data->questionid = $this->get_mappingid('question', $data->questionid);
$data->glossaryentryid = $this->get_mappingid('glossary_entry', $data->glossaryentryid);
$data->answerid = $this->get_mappingid('question_answers', $data->answerid);
$newitemid = $DB->insert_record('game_queries', $data);
$this->set_mapping('game_queries', $oldid, $newitemid);
}
/**
* Restores the game_bookquiz table.
*
* @param stdClass $data
*/
protected function process_game_bookquiz( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game');
$data->lastchapterid = $this->get_mappingid('book_chapters', $data->lastchapterid);
$DB->insert_record('game_bookquiz', $data);
}
/**
* Restores the game_bookauiz_chapters table.
*
* @param stdClass $data
*/
protected function process_game_bookquiz_chapter( $data) {
global $DB;
$data = (object)$data;
$data->attemptid = $this->get_new_parentid('game_attempts');
$data->chapterid = $this->get_mappingid('book_chapters', $data->chapterid);
$DB->insert_record('game_bookquiz_chapters', $data);
}
/**
* Restores the game_bookquiz_questions table.
*
* @param stdClass $data
*/
protected function process_game_bookquiz_question( $data) {
global $DB;
$data = (object)$data;
$data->gameid = $this->get_new_parentid('game');
$data->chapterid = $this->get_mappingid('book_chapters', $data->chapterid);
$data->questioncategoryid = $this->get_mappingid('question_category', $data->questioncategoryid);
$DB->insert_record('game_bookquiz_questions', $data);
}
/**
* Restores the game_cross table.
*
* @param stdClass $data
*/
protected function process_game_cross( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game_attempt');
game_insert_record( 'game_cross', $data);
}
/**
* Restores the game_cryptex table.
*
* @param stdClass $data
*/
protected function process_game_cryptex( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game_attempt');
game_insert_record( 'game_cryptex', $data);
}
/**
* Restores the game_hangman table.
*
* @param stdClass $data
*/
protected function process_game_hangman( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game_attempt');
$data->queryid = $this->get_mappingid('game_queries', $data->queryid);
game_insert_record( 'game_hangman', $data);
}
/**
* Restores the game_hiddenpicture table.
*
* @param stdClass $data
*/
protected function process_game_hiddenpicture( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game_attempt');
game_insert_record( 'game_hiddenpicture', $data);
}
/**
* Restores the game_millionaire table.
*
* @param stdClass $data
*/
protected function process_game_millionaire( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game_attempt');
$data->queryid = $this->get_mappingid('game_queries', $data->queryid);
game_insert_record( 'game_millionaire', $data);
}
/**
* Restores the game_snakes table.
*
* @param stdClass $data
*/
protected function process_game_snake( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_mappingid('game_attempt', $data->id);
$data->queryid = $this->get_mappingid('game_queries', $data->queryid);
game_insert_record( 'game_snakes', $data);
}
/**
* Restores the game_sudoku table.
*
* @param stdClass $data
*/
protected function process_game_sudoku( $data) {
global $DB;
$data = (object)$data;
$data->id = $this->get_new_parentid('game_attempt');
game_insert_record( 'game_sudoku', $data);
}
/**
* Add Game related files, no need to match by itemname (just internally handled context).
*/
protected function after_execute() {
$this->add_related_files('mod_game', 'snakes_file', null);
$this->add_related_files('mod_game', 'snakes_board', null);
}
}

454
bookquiz/play.php

@ -0,0 +1,454 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Plays the game bookquiz.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Plays the game bookquiz.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $bookquiz
* @param int $chapterid
* @param stdClass $context
*/
function game_bookquiz_continue( $id, $game, $attempt, $bookquiz, $chapterid, $context) {
if ($attempt != false and $bookquiz != false) {
return game_bookquiz_play( $id, $game, $attempt, $bookquiz, $chapterid, $context);
}
if ($attempt == false) {
$attempt = game_addattempt( $game);
}
$bookquiz = new stdClass();
$bookquiz->lastchapterid = 0;
$bookquiz->id = $attempt->id;
$bookquiz->bookid = $game->bookid;
if ( !game_insert_record( 'game_bookquiz', $bookquiz)) {
print_error( 'game_bookquiz_continue: error inserting in game_bookquiz');
}
return game_bookquiz_play( $id, $game, $attempt, $bookquiz, 0, $context);
}
/**
* Plays the game bookquiz.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $bookquiz
* @param int $chapterid
* @param stdClass $context
*/
function game_bookquiz_play( $id, $game, $attempt, $bookquiz, $chapterid, $context) {
global $DB, $OUTPUT, $cm;
if ($bookquiz->lastchapterid == 0) {
game_bookquiz_play_computelastchapter( $game, $bookquiz);
if ($bookquiz->lastchapterid == 0) {
print_error( get_string( 'bookquiz_empty', 'game'));
}
}
if ($chapterid == 0) {
$chapterid = $bookquiz->lastchapterid;
} else {
if (($DB->set_field( 'game_bookquiz', 'lastchapterid', $chapterid, array( 'id' => $bookquiz->id))) == false) {
print_error( "Can't update table game_bookquiz with lastchapterid to $chapterid");
}
}
$book = $DB->get_record( 'book', array('id' => $game->bookid));
if (!$chapter = $DB->get_record( 'book_chapters', array('id' => $chapterid))) {
print_error('Error reading book chapters.');
}
$select = "bookid = $game->bookid AND hidden = 0";
$chapters = $DB->get_records_select('book_chapters', $select, null, 'pagenum', 'id, pagenum, subchapter, title, hidden');
$okchapters = array();
if (($recs = $DB->get_records( 'game_bookquiz_chapters', array( 'attemptid' => $attempt->id))) != false) {
foreach ($recs as $rec) {
// The 1 means correct answer.
$okchapters[ $rec->chapterid] = 1;
}
}
// The 2 means current.
$showquestions = false;
$a = array( 'gameid' => $game->id, 'chapterid' => $chapterid);
if (($questions = $DB->get_records( 'game_bookquiz_questions', $a)) === false) {
if (!array_key_exists( $chapterid, $okchapters)) {
$okchapters[ $chapterid] = 1;
$newrec = new stdClass();
$newrec->attemptid = $attempt->id;
$newrec->chapterid = $chapterid;
if (!$DB->insert_record( 'game_bookquiz_chapters', $newrec)) {
print_error( "Can't insert to table game_bookquiz_chapters");
}
}
} else {
// Have to select random one question.
$questionid = game_bookquiz_selectrandomquestion( $questions);
if ($questionid != 0) {
$showquestions = true;
}
}
// Prepare chapter navigation icons.
$previd = null;
$nextid = null;
$found = 0;
$scoreattempt = 0;
$lastid = 0;
foreach ($chapters as $ch) {
$scoreattempt++;
if ($found) {
$nextid = $ch->id;
break;
}
if ($ch->id == $chapter->id) {
$found = 1;
}
if (!$found) {
$previd = $ch->id;
}
$lastid = $ch->id;
}
if ($ch == current($chapters)) {
$nextid = $ch->id;
}
if (count( $chapters)) {
$scoreattempt = ($scoreattempt - 1) / count( $chapters);
}
$chnavigation = '';
if ($previd) {
$chnavigation .= '<a title="'.get_string('navprev', 'book').'" href="attempt.php?id='.$id.
'&chapterid='.$previd.'"><img src="'.$OUTPUT->pix_url('bookquiz/nav_prev', 'mod_game').
'" class="bigicon" alt="'.get_string('navprev', 'book').'"/></a>';
} else {
$chnavigation .= '<img src="'.$OUTPUT->pix_url('bookquiz/nav_prev_dis', 'mod_game').'" class="bigicon" alt="" />';
}
$nextbutton = '';
if ($nextid) {
if (!$showquestions) {
$chnavigation .= '<a title="'.get_string('navnext', 'book').'" href="attempt.php?id='.
$id.'&chapterid='.$nextid.'"><img src="'.
$OUTPUT->pix_url('bookquiz/nav_next', 'mod_game').'" class="bigicon" alt="'.get_string('navnext', 'book').'" ></a>';
$nextbutton = '<center>';
$nextbutton .= '<form name="form" method="get" action="attempt.php">';
$nextbutton .= '<input type="hidden" name="id" value="'.$id.'" >'."\r\n";
$nextbutton .= '<input type="hidden" name="chapterid" value="'.$nextid.'" >'."\r\n";
$nextbutton .= '<input type="submit" value="'.get_string( 'continue').'">';
$nextbutton .= '</center>';
$showquestions = false;
game_updateattempts_maxgrade( $game, $attempt, $scoreattempt, 0);
}
} else {
game_updateattempts_maxgrade( $game, $attempt, 1, 0);
$sec = '';
if (!isset( $cm)) {
$cm = get_coursemodule_from_instance('game', $game->id, $game->course);
}
if ($section = $DB->get_record('course_sections', array( 'id' => $cm->section))) {
$sec = $section->section;
}
if (! $cm = $DB->get_record('course_modules', array( 'id' => $id))) {
print_error("Course Module ID was incorrect id=$id");
}
$chnavigation .= '<a title="'.get_string('navexit', 'book').'" href="attempt.php?id='.
$id.'&chapterid='.$lastid.'><img src="'.$OUTPUT->pix_url('bookquiz/nav_exit', 'mod_game').
'" class="bigicon" alt="'.get_string('navexit', 'book').'" /></a>';
}
require( 'toc.php');
$tocwidth = '10%';
if ($showquestions) {
if ($game->param3 == 0) {
game_bookquiz_showquestions( $id, $questionid, $chapter->id, $nextid, $scoreattempt, $game, $context);
}
}
?>
<table border="0" cellspacing="0" width="100%" valign="top" cellpadding="2">
<!-- subchapter title and upper navigation row //-->
<tr>
<td width="<?php echo 10;?>" valign="bottom">
</td>
<td valign="top">
<table border="0" cellspacing="0" width="100%" valign="top" cellpadding="0">
<tr>
<td align="right"><?php echo $chnavigation ?></td>
</tr>
</table>
</td>
</tr>
<!-- toc and chapter row //-->
<tr>
<td width="<?php echo $tocwidth ?>" valign="top" align="left">
<?php
echo $OUTPUT->box_start('generalbox');
echo $toc;
echo $OUTPUT->box_end();
?>
</td>
<td valign="top" align="left">
<?php
echo $OUTPUT->box_start('generalbox');
$content = '';
if (!$book->customtitles) {
if ($currsubtitle == '&nbsp;') {
$content .= '<p class="book_chapter_title">'.$currtitle.'</p>';
} else {
$content .= '<p class="book_chapter_title">'.$currtitle.'<br />'.$currsubtitle.'</p>';
}
}
$cmbook = get_coursemodule_from_instance( 'book', $game->bookid, $game->course);
$modcontext = game_get_context_module_instance( $cmbook->id);
$content .= game_filterbook( $chapter->content, $chapter->id, $modcontext->id, $game->course);
$nocleanoption = new stdClass;
$nocleanoption->noclean = true;
echo '<div>';
if ($nextbutton != '') {
echo $nextbutton;
}
echo format_text($content, FORMAT_HTML, $nocleanoption);
if ($nextbutton != '') {
echo $nextbutton;
}
echo '</div>';
echo $OUTPUT->box_end();
// Lower navigation.
echo '<p align="right">'.$chnavigation.'</p>';
?>
</td>
</tr>
</table>
<?php
if ($showquestions) {
if ($game->param3 != 0) {
game_bookquiz_showquestions( $id, $questionid, $chapter->id, $nextid, $scoreattempt, $game, $context);
}
}
}
/**
* Computes the last chapter.
*
* @param stdClass $game
* @param stdClass $bookquiz
*/
function game_bookquiz_play_computelastchapter( $game, &$bookquiz) {
global $DB;
if ($game->bookid == 0) {
print_error( 'Not defined a book on this game');
}
$pagenum = $DB->get_field( 'book_chapters', 'min(pagenum) as p', array('bookid' => $game->bookid));
if ($pagenum) {
$bookquiz->lastchapterid = $DB->get_field( 'book_chapters', 'id', array('bookid' => $game->bookid, 'pagenum' => $pagenum));
if ($bookquiz->lastchapterid) {
// Update the data in table game_bookquiz.
if (($DB->set_field( 'game_bookquiz', 'lastchapterid', $bookquiz->lastchapterid,
array('id' => $bookquiz->id))) == false) {
print_error( "Can't update table game_bookquiz with lastchapterid to $bookquiz->lastchapterid");
}
}
}
}
/**
* Shows questions.
*
* @param int $id
* @param int $questionid
* @param int $chapterid
* @param int $nextchapterid
* @param int $scoreattempt
* @param stdClass $game
* @param stdClass $context
*/
function game_bookquiz_showquestions( $id, $questionid, $chapterid, $nextchapterid, $scoreattempt, $game, $context) {
$onlyshow = false;
$showsolution = false;
$questionlist = $questionid;
$questions = game_sudoku_getquestions( $questionlist);
global $CFG;
// Start the form.
echo "<form id=\"responseform\" method=\"post\" action=\"{$CFG->wwwroot}/mod/game/attempt.php\" ".
" onclick=\"this.autocomplete='off'\">\n";
if (($onlyshow === false) and ($showsolution === false)) {
echo "<center><input type=\"submit\" name=\"finishattempt\" value=\"".get_string('sudoku_submit', 'game')."\"></center>\n";
}
// Add a hidden field with the quiz id.
echo '<div>';
echo '<input type="hidden" name="id" value="' . s($id) . "\" />\n";
echo '<input type="hidden" name="action" value="bookquizcheck" />';
echo '<input type="hidden" name="chapterid" value="'.$chapterid.'" />';
echo '<input type="hidden" name="scoreattempt" value="'.$scoreattempt.'" />';
echo '<input type="hidden" name="nextchapterid" value="'.$nextchapterid.'" />';
// Print all the questions.
// Add a hidden field with questionids.
echo '<input type="hidden" name="questionids" value="'.$questionlist."\" />\n";
$number = 0;
foreach ($questions as $question) {
game_print_question( $game, $question, $context);
}
echo "</div>";
// Finish the form.
echo '</div>';
if (($onlyshow === false) and ($showsolution === false)) {
echo "<center><input type=\"submit\" name=\"finishattempt\" value=\"".get_string('sudoku_submit', 'game')."\"></center>\n";
}
echo "</form>\n";
}
/**
* Selects random one question from the input list.
*
* @param array $questions
*
* @return the position of the random question.
*/
function game_bookquiz_selectrandomquestion( $questions) {
global $DB;
$categorylist = '';
if ($questions == false) {
return 0;
}
foreach ($questions as $rec) {
$categorylist .= ',' . $rec->questioncategoryid;
}
$select = 'category in ('.substr( $categorylist, 1). ") AND qtype in ('shortanswer', 'truefalse', 'multichoice')";
if (($recs = $DB->get_records_select( 'question', $select, null, '', 'id,id')) == false) {
return 0;
}
$a = array();
foreach ($recs as $rec) {
$a[ $rec->id] = $rec->id;
}
if (count( $a) == 0) {
return 0;
} else {
return array_rand( $a);
}
}
/**
* Check if the answers are correct.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $bookquiz
* @param stdClass $context
*/
function game_bookquiz_check_questions( $id, $game, $attempt, $bookquiz, $context) {
global $USER, $DB;
$scoreattempt = optional_param('scoreattempt', 0, PARAM_INT);
$responses = data_submitted();
$questionlist = $responses->questionids;
$questions = game_sudoku_getquestions( $questionlist);
$grades = game_grade_questions( $questions);
$scorequestion = 0;
$scoreattempt = 0;
$chapterid = required_param('chapterid', PARAM_INT);
$nextchapterid = required_param('nextchapterid', PARAM_INT);
foreach ($questions as $question) {
if (!array_key_exists( $question->id, $grades)) {
// No answered.
continue;
}
$grade = $grades[ $question->id];
if ($grade->grade < 0.99) {
continue;
}
// Found one correct answer.
if (!$DB->get_field( 'game_bookquiz_chapters', 'id', array( 'attemptid' => $attempt->id, 'chapterid' => $chapterid))) {
$newrec = new stdClass();
$newrec->attemptid = $attempt->id;
$newrec->chapterid = $chapterid;
if (!$DB->insert_record( 'game_bookquiz_chapters', $newrec, false)) {
print_error( "Can't insert to table game_bookquiz_chapters");
}
}
// Have to go to next page.
$bookquiz->lastchapterid = $nextchapterid;
$scorequestion = 1;
break;
}
$query = new stdClass();
$query->id = 0;
$query->attemptid = $attempt->id;
$query->gameid = $game->id;
$query->userid = $USER->id;
$query->sourcemodule = 'question';
$query->questionid = $question->id;
$query->glossaryentryid = 0;
$query->questiontext = $question->questiontext;
$query->timelastattempt = time();
game_update_queries( $game, $attempt, $query, $scorequestion, '');
game_updateattempts( $game, $attempt, $scoreattempt, 0);
game_bookquiz_continue( $id, $game, $attempt, $bookquiz, $bookquiz->lastchapterid, $context);
}

195
bookquiz/questions.php

@ -0,0 +1,195 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The script supports book
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
**/
defined('MOODLE_INTERNAL') || die();
require_once( "../headergame.php");
require_once("../locallib.php");
$attempt = game_getattempt( $game, $detail);
if ($game->bookid == 0) {
print_error( get_string( 'bookquiz_not_select_book', 'game'));
}
if ($form = data_submitted()) { // Filename.
$ids = explode( ',', $form->ids);
game_bookquiz_save( $game->id, $game->bookid, $ids, $form);
}
// Print upload form.
$OUTPUT->heading( $course->fullname);
$select = "gameid={$game->id}";
$categories = array();
if (($recs = $DB->get_records_select( 'game_bookquiz_questions', $select, null, '', 'chapterid,questioncategoryid')) != false) {
foreach ($recs as $rec) {
$categories[ $rec->chapterid] = $rec->questioncategoryid;
}
}
$context = game_get_context_course_instance( $COURSE->id);
$select = " contextid in ($context->id)";
$a = array();
if ($recs = $DB->get_records_select( 'question_categories', $select, null, 'id,name')) {
foreach ($recs as $rec) {
$s = $rec->name;
if (($count = $DB->count_records( 'question', array( 'category' => $rec->id))) != 0) {
$s .= " ($count)";
}
$a[ $rec->id] = $s;
}
}
$sql = "SELECT chapterid, COUNT(*) as c ".
"FROM {game_bookquiz_questions} gbq,{question} q ".
"WHERE gbq.questioncategoryid=q.category ".
"AND gameid=$game->id ".
"GROUP BY chapterid";
$numbers = array();
if (($recs = $DB->get_records_sql( $sql)) != false) {
foreach ($recs as $rec) {
$numbers[ $rec->chapterid] = $rec->c;
}
}
echo '<form name="form" method="post" action="questions.php">';
echo '<table border=1>';
echo '<tr>';
echo '<td><center>'.get_string( 'bookquiz_chapters', 'game').'</td>';
echo '<td><center>'.get_string( 'bookquiz_categories', 'game').'</td>';
echo '<td><center>'.get_string( 'bookquiz_numquestions', 'game').'</td>';
echo "</tr>\r\n";
$ids = '';
if (($recs = $DB->get_records( 'book_chapters', array('bookid' => $game->bookid), 'pagenum', 'id,title')) != false) {
foreach ($recs as $rec) {
echo '<tr>';
echo '<td>'.$rec->title.'</td>';
echo '<td>';
if (array_key_exists( $rec->id, $categories)) {
$categoryid = $categories[ $rec->id];
} else {
$categoryid = 0;
}
echo game_showselectcontrol( 'categoryid_'.$rec->id, $a, $categoryid, '');
echo '</td>';
echo '<td>';
if (array_key_exists( $rec->id, $numbers)) {
echo '<center>'.$numbers[ $rec->id].'</center>';
} else {
echo '&nbsp;';
}
echo '</td>';
echo "</tr>\r\n";
$ids .= ','.$rec->id;
}
}
?>
</table>
<br>
<!-- These hidden variables are always the same -->
<input type="hidden" name=id value="<?php p($id) ?>" />
<input type="hidden" name=q value="<?php p($q) ?>" />
<input type="hidden" name=ids value="<?php p( substr( $ids, 1)) ?>" />
<center>
<input type="submit" value="<?php print_string("savechanges") ?>" />
</center>
</form>
<?php
echo $OUTPUT->footer($course);
/**
* Save infos to database.
*
* @param int $gameid
* @param int $bookid
* @param array $ids
* @param stdClass $form
*/
function game_bookquiz_save( $gameid, $bookid, $ids, $form) {
global $DB;
$questions = array();
$recids = array();
if (($recs = $DB->get_records( 'game_bookquiz_questions',
array( 'gameid' => $gameid), '', 'id,chapterid,questioncategoryid')) != false) {
foreach ($recs as $rec) {
$questions[ $rec->chapterid] = $rec->questioncategoryid;
$recids[ $rec->chapterid] = $rec->id;
}
}
foreach ($ids as $chapterid) {
$name = 'categoryid_'.$chapterid;
$categoryid = $form->$name;
if (!array_key_exists( $chapterid, $questions)) {
if ($categoryid == 0) {
continue;
}
$rec = new stdClass();
$rec->gameid = $gameid;
$rec->chapterid = $chapterid;
$rec->questioncategoryid = $categoryid;
if (($newid = $DB->insert_record('game_bookquiz_questions', $rec)) == false) {
print_error( "Can't insert to game_bookquiz_questions");
}
continue;
}
$cat = $questions[ $chapterid];
if ($cat == $categoryid) {
$recids[ $chapterid] = 0;
continue;
}
if ($categoryid == 0) {
if (!delete_records( 'game_bookquiz_questions', 'id', $recids[ $chapterid])) {
print_error( "Can't delete game_bookquiz_questions");
}
} else {
$updrec = new StdClass;
$updrec->id = $recids[ $chapterid];
$updrec->questioncategoryid = $categoryid;
if (($DB->update_record( 'game_bookquiz_questions', $updrec)) == false) {
print_error( "Can't update game_bookquiz_questions");
}
}
$recids[ $chapterid] = 0;
}
foreach ($recids as $chapterid => $id) {
if ($id == 0) {
continue;
}
}
}

142
bookquiz/toc.php

@ -0,0 +1,142 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Table of contents.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
define('NUM_NONE', '0');
define('NUM_NUMBERS', '1');
define('NUM_BULLETS', '2');
define('NUM_INDENTED', '3');
$currtitle = ''; // Active chapter title (plain text).
$currsubtitle = ''; // Active subchapter if any.
$prevtitle = '&nbsp;';
$toc = ''; // Representation of toc (HTML).
$nch = 0; // Chapter number.
$ns = 0; // Subchapter number.
$title = '';
$first = 1;
if (!isset($print)) {
$print = 0;
}
switch ($book->numbering) {
case NUM_NONE:
$toc .= '<div class="book_toc_none">';
break;
case NUM_NUMBERS:
$toc .= '<div class="book_toc_numbered">';
break;
case NUM_BULLETS:
$toc .= '<div class="book_toc_bullets">';
break;
case NUM_INDENTED:
$toc .= '<div class="book_toc_indented">';
break;
}
if ($print) {
// TOC for printing.
$toc .= '<a name="toc"></a>';
if ($book->customtitles) {
$toc .= '<h1>'.get_string('toc', 'book').'</h1>';
} else {
$toc .= '<p class="book_chapter_title">'.get_string('toc', 'book').'</p>';
}
$titles = array();
$toc .= '<ul>';
foreach ($chapters as $ch) {
$title = trim(strip_tags($ch->title));
if (!$ch->hidden) {
if (!$ch->subchapter) {
$nch++;
$ns = 0;
$toc .= ($first) ? '<li>' : '</ul></li><li>';
if ($book->numbering == NUM_NUMBERS) {
$title = "$nch $title";
}
} else {
$ns++;
$toc .= ($first) ? '<li><ul><li>' : '<li>';
if ($book->numbering == NUM_NUMBERS) {
$title = "$nch.$ns $title";
}
}
$titles[$ch->id] = $title;
$toc .= '<a title="'.htmlspecialchars($title).'" href="#ch'.$ch->id.'">'.$title.'</a>';
$toc .= (!$ch->subchapter) ? '<ul>' : '</li>';
$first = 0;
}
}
$toc .= '</ul></li></ul>';
} else {
// Normal students view.
$toc .= '<font size="-1"><ul>';
foreach ($chapters as $ch) {
$title = trim(strip_tags($ch->title));
if (!$ch->hidden) {
if (!$ch->subchapter) {
$nch++;
$ns = 0;
$toc .= ($first) ? '<li>' : '</ul></li><li>';
if ($book->numbering == NUM_NUMBERS) {
$title = "$nch $title";
}
$prevtitle = $title;
} else {
$ns++;
$toc .= ($first) ? '<li><ul><li>' : '<li>';
if ($book->numbering == NUM_NUMBERS) {
$title = "$nch.$ns $title";
}
}
if ($ch->id == $chapter->id) {
$toc .= '<strong>'.$title.'</strong>';
if ($ch->subchapter) {
$currtitle = $prevtitle;
$currsubtitle = $title;
} else {
$currtitle = $title;
$currsubtitle = '&nbsp;';
}
} else {
if (array_key_exists( $ch->id, $okchapters)) {
$toc .= '<a title="'.htmlspecialchars($title).'" href="attempt.php?id='
.$id.'&chapterid='.$ch->id.'">'.$title.'</a>';
} else {
$toc .= htmlspecialchars($title);
}
}
$toc .= (!$ch->subchapter) ? '<ul>' : '</li>';
$first = 0;
}
}
$toc .= '</ul></li></ul></font>';
}
$toc .= '</div>';
$toc = str_replace('<ul></ul>', '', $toc); // Cleanup of invalid structures.

236
bookquiz/view.php

@ -0,0 +1,236 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* View a bookquiz.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../../config.php');
require_once('lib.php');
$id = required_param('id', PARAM_INT); // Course Module ID.
$chapterid = optional_param('chapterid', 0, PARAM_INT); // Chapter ID.
$edit = optional_param('edit', -1, PARAM_BOOL); // Edit mode.
/* =========================================================================
* security checks START - teachers edit; students view
* =========================================================================
*/
if (!$cm = get_coursemodule_from_id('book', $id)) {
print_error('Course Module ID was incorrect');
}
if (!$course = $DB->get_record('course', array( 'id' => $cm->course))) {
print_error('Course is misconfigured');
}
if (!$book = $DB->get_record('book', array( 'id' => $cm->instance))) {
print_error('Course module is incorrect');
}
require_course_login($course, true, $cm);
$context = game_get_context_module_instance( $cm->id);
// Read chapters.
$select = $allowedit ? "bookid = $book->id" : "bookid = $book->id AND hidden = 0";
$chapters = $DB->get_records_select('book_chapters', $select, null, 'pagenum', 'id, pagenum, subchapter, title, hidden');
// Check chapterid and read chapter data.
if ($chapterid == '0') {
// Go to first chapter if no given.
foreach ($chapters as $ch) {
if ($allowedit) {
$chapterid = $ch->id;
break;
}
if (!$ch->hidden) {
$chapterid = $ch->id;
break;
}
}
}
if (!$chapter = $DB->get_record('book_chapters', array('id' => $chapterid))) {
print_error('Error reading book chapters.');
}
// Check all variables.
unset($id);
unset($chapterid);
// Chapter is hidden for students.
if (!$allowedit && $chapter->hidden) {
print_error('Error reading book chapters.');
}
// Chapter not part of this book!
if ($chapter->bookid != $book->id) {
print_error('Chapter not part of this book!');
}
/* =========================================================================
* security checks END
* =========================================================================
*/
add_to_log($course->id, 'book', 'view', 'view.php?id='.$cm->id.'&amp;chapterid='.$chapter->id, $book->id, $cm->id);
// Read standard strings.
$strbooks = get_string('modulenameplural', 'book');
$strbook = get_string('modulename', 'book');
// Prepare header.
if ($course->category) {
$navigation = '<a href="../../course/view.php?id='.$course->id.'">'.$course->shortname.'</a> ->';
} else {
$navigation = '';
}
$buttons = $allowedit ? '<table cellspacing="0" cellpadding="0"><tr><td>'.
update_module_button($cm->id, $course->id, $strbook).'</td>'.
'<td>&nbsp;</td><td>'.book_edit_button($cm->id, $course->id, $chapter->id).'</td></tr></table>' : '&nbsp;';
// Prepare chapter navigation icons.
$previd = null;
$nextid = null;
$found = 0;
foreach ($chapters as $ch) {
if ($found) {
$nextid = $ch->id;
break;
}
if ($ch->id == $chapter->id) {
$found = 1;
}
if (!$found) {
$previd = $ch->id;
}
}
if ($ch == current($chapters)) {
$nextid = $ch->id;
}
$chnavigation = '';
echo "previd=$previd nextid=$nextid<br>";
if ($previd) {
$chnavigation .= '<a title="'.get_string('navprev', 'book').'" href="view.php?id='.$cm->id.
'&amp;chapterid='.$previd.'"><img src="'.$OUTPUT->pix_url('bookquiz/nav_prev', 'mod_game').
'" class="bigicon" alt="'.get_string('navprev', 'book').'"/></a>';
} else {
$chnavigation .= '<img src="'.$OUTPUT->pix_url('bookquiz/nav_prev_dis', 'mod_game').'" class="bigicon" alt="" />';
}
if ($nextid) {
$chnavigation .= '<a title="'.get_string('navnext', 'book').'" href="view.php?id='.$cm->id.
'&amp;chapterid='.$nextid.'"><img src="'.$OUTPUT->pix_url('bookquiz/nav_next', 'mod_game').
'" class="bigicon" alt="'.get_string('navnext', 'book').'" /></a>';
} else {
$sec = '';
if ($section = $DB->get_record('course_sections', array( 'id' => $cm->section))) {
$sec = $section->section;
}
$chnavigation .= '<a title="'.get_string('navexit', 'book').'" href="../../course/view.php?id='.
$course->id.'#section-'.$sec.'"><img src="'.
$OUTPUT->pix_url('bookquiz/nav_exit', 'mod_game').'" class="bigicon" alt="'.get_string('navexit', 'book').
'" /></a>';
}
echo "chnavigation=$chnavigation<br>";
// Prepare print icons.
if ($book->disableprinting) {
$printbook = '';
$printchapter = '';
} else {
$printbook = '<a title="'.get_string('printbook', 'book').'" href="print.php?id='.$cm->id.
'" onclick="this.target=\'_blank\'"><img src="'.
$OUTPUT->pix_url('bookquiz/print_book', 'mod_game').
'" class="bigicon" alt="'.get_string('printbook', 'book').'"/></a>';
$printchapter = '<a title="'.get_string('printchapter', 'book').'" href="print.php?id='.
$cm->id.'&amp;chapterid='.$chapter->id.
'" onclick="this.target=\'_blank\'"><img src="'.
$OUTPUT->pix_url('bookquiz/print_chapter', 'mod_game').'" class="bigicon" alt="'.
get_string('printchapter', 'book').'"/></a>';
}
/* =====================================================
* Book display HTML code
* =====================================================
*/
echo "OK";
?>
<table border="0" cellspacing="0" width="100%" valign="top" cellpadding="2">
<!-- subchapter title and upper navigation row //-->
<tr>
<td width="<?php echo 10;?>" valign="bottom">
</td>
<td valign="top">
<table border="0" cellspacing="0" width="100%" valign="top" cellpadding="0">
<tr>
<td align="right"><?php echo 'help'.$chnavigation ?></td>
</tr>
</table>
</td>
</tr>
<!-- toc and chapter row //-->
<tr>
<td width="<?php echo $tocwidth ?>" valign="top" align="left">
<?php
echo $OUTPUT->box_start('generalbox');
echo $toc;
echo $OUTPUT->box_end();
if ($allowedit && $edit) {
echo '<font size="1"><br />';
helpbutton('faq', get_string('faq', 'book'), 'book', true, true);
echo '</font>';
}
?>
</td>
<td valign="top" align="right">
<?php
echo $OUTPUT->box_start('generalbox');
$content = '';
if (!$book->customtitles) {
if ($currsubtitle == '&nbsp;') {
$content .= '<p class="book_chapter_title">'.$currtitle.'</p>';
} else {
$content .= '<p class="book_chapter_title">'.$currtitle.'<br />'.$currsubtitle.'</p>';
}
}
$content .= $chapter->content;
$nocleanoption = new stdClass;
$nocleanoption->noclean = true;
echo '<div class="book_content">';
echo format_text($content, FORMAT_HTML, $nocleanoption, $course->id);
echo '</div>';
echo $OUTPUT->box_end();
// Lower navigation.
echo '<p>'.$chnavigation.'</p>';
?>
</td>
</tr>
</table>
<?php
echo $OUTPUT->footer($course);

315
check.php

@ -0,0 +1,315 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Basic library.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Checks for common problems
*
* @param stdClass $context
* @param stdClass $game
*/
function game_check_common_problems($context, $game) {
if (!has_capability('mod/game:viewreports', $context)) {
return '';
}
$warnings = array();
switch( $game->gamekind) {
case 'millionaire':
game_check_common_problems_multichoice( $game, $warnings);
break;
case 'hangman':
game_check_common_problems_shortanswer( $game, $warnings);
break;
case 'cross':
case 'cryptex':
game_check_common_problems_shortanswer( $game, $warnings);
game_check_common_problems_crossword_cryptex( $game, $warnings);
break;
}
if (count( $warnings) == 0) {
return '';
}
$s = '<ul><b>'.get_string( 'common_problems', 'game').'</b>';
foreach ($warnings as $line) {
$s .= '<li>'.$line.'</li>';
}
return $s.'</ul>';
}
/**
* Checks for common problems on multichoice answers
*
* @param stdClass $game
* @param string $warnings
*/
function game_check_common_problems_multichoice($game, &$warnings) {
if ($game->sourcemodule == 'question') {
game_check_common_problems_multichoice_question($game, $warnings);
} else if ( $game->sourcemodule == 'quiz') {
game_check_common_problems_multichoice_quiz($game, $warnings);
}
}
/**
* Checks for common problems on multichoice answers (questions)
*
* @param stdClass $game
* @param string $warnings
*/
function game_check_common_problems_multichoice_question($game, &$warnings) {
global $CFG, $DB;
if ($game->questioncategoryid == 0) {
$warnings[] = get_string( 'must_select_questioncategory', 'game');
return;
}
// Include subcategories.
$select = 'category='.$game->questioncategoryid;
if ($game->subcategories) {
$cats = question_categorylist( $game->questioncategoryid);
if (count( $cats)) {
$select = 'q.category in ('.implode(',', $cats).')';
}
}
$select0 = $select;
if (game_get_moodle_version() < '02.06') {
$table = "{$CFG->prefix}question q, {$CFG->prefix}question_multichoice qmo";
$select .= " AND qtype='multichoice' AND qmo.single <> 1 AND qmo.question=q.id";
} else {
$table = "{$CFG->prefix}question q, {$CFG->prefix}qtype_multichoice_options qmo";
$select .= " AND qtype='multichoice' AND qmo.single <> 1 AND qmo.questionid=q.id";
}
$sql = "SELECT COUNT(*) as c FROM $table WHERE $select";
$rec = $DB->get_record_sql( $sql);
if ($rec->c != 0) {
$warnings[] = get_string( 'millionaire_also_multichoice', 'game').': '.$rec->c;
}
$select = $select0;
if (game_get_moodle_version() < '02.06') {
$select .= " AND qtype='multichoice' AND qmo.single = 1 AND qmo.question=q.id";
} else {
$select .= " AND qtype='multichoice' AND qmo.single = 1 AND qmo.questionid=q.id";
}
$sql = "SELECT COUNT(*) as c FROM $table WHERE $select";
$rec = $DB->get_record_sql( $sql);
if ($rec->c == 0) {
$warnings[] = get_string( 'millionaire_no_multichoice_questions', 'game');
}
}
/**
* Checks for common problems on multichoice answers (quiz)
*
* @param stdClass $game
* @param string $warnings
*/
function game_check_common_problems_multichoice_quiz($game, &$warnings) {
global $CFG, $DB;
if (game_get_moodle_version() < '02.06') {
$select = "qtype='multichoice' AND quiz='$game->quizid' AND qmo.question=q.id".
" AND qqi.question=q.id";
$table = "{quiz_question_instances} qqi,{question} q, {question_multichoice} qmo";
} else if (game_get_moodle_version() < '02.07') {
$select = "qtype='multichoice' AND quiz='$game->quizid' AND qmo.questionid=q.id".
" AND qqi.question=q.id";
$table = "{quiz_question_instances} qqi,{question} q, {qtype_multichoice_options} qmo";
} else {
$select = "qtype='multichoice' AND qs.quizid='$game->quizid' AND qmo.questionid=q.id".
" AND qs.questionid=q.id";
$table = "{quiz_slots} qs,{question} q, {qtype_multichoice_options} qmo";
}
$sql = "SELECT COUNT(*) as c FROM $table WHERE $select";
$rec = $DB->get_record_sql( $sql);
if ($rec->c != 0) {
$warnings[] = get_string( 'millionaire_also_multichoice', 'game').': '.$rec->c;
}
}
/**
* Checks for common problems on short answers
*
* @param stdClass $game
* @param string $warnings
*/
function game_check_common_problems_shortanswer($game, &$warnings) {
if ($game->sourcemodule == 'question') {
game_check_common_problems_shortanswer_question($game, $warnings);
} else if ( $game->sourcemodule == 'glossary') {
game_check_common_problems_shortanswer_glossary($game, $warnings);
}
}
/**
* Checks for common problems on short answers (glossaries)
*
* @param stdClass $game
* @param string $warnings
*/
function game_check_common_problems_shortanswer_glossary($game, &$warnings) {
global $CFG, $DB;
$sql = "SELECT id,concept FROM {$CFG->prefix}glossary_entries WHERE glossaryid={$game->glossaryid}";
$recs = $DB->get_records_sql( $sql);
$a = array();
foreach ($recs as $rec) {
$a[] = $rec->concept;
}
game_check_common_problems_shortanswer_allowspaces( $game, $warnings, $a);
if ($game->gamekind == 'hangman') {
game_check_common_problems_shortanswer_hangman( $game, $warnings, $a);
}
}
/**
* Checks for common problems on short answers (questions)
*
* @param stdClass $game
* @param string $warnings
*/
function game_check_common_problems_shortanswer_question($game, &$warnings) {
global $CFG, $DB;
if ($game->questioncategoryid == 0) {
$warnings[] = get_string( 'must_select_questioncategory', 'game');
return;
}
$select = 'category='.$game->questioncategoryid;
if ($game->subcategories) {
$cats = question_categorylist( $game->questioncategoryid);
if (count( $cats) > 0) {
$s = implode( ',', $cats);
$select = 'category in ('.$s.')';
}
}
$select .= " AND qtype='shortanswer'";
$sql = "SELECT id FROM {$CFG->prefix}question WHERE $select";
if (($recs = $DB->get_records_sql( $sql)) === false) {
return;
}
$a = array();
foreach ($recs as $rec) {
// Maybe there are more answers to one question. I use as correct the one with bigger fraction.
$sql = "SELECT DISTINCT answer FROM {$CFG->prefix}question_answers WHERE question={$rec->id} ORDER BY fraction DESC";
$recs2 = $DB->get_records_sql( $sql);
foreach ($recs2 as $rec2) {
$a[] = $rec2->answer;
break;
}
}
game_check_common_problems_shortanswer_allowspaces( $game, $warnings, $a);
if ($game->gamekind == 'hangman') {
game_check_common_problems_shortanswer_hangman( $game, $warnings, $a);
}
}
/**
* Checks for common problems (check if are answers with spaces and the game doesn't allow spaces)
*
* @param stdClass $game
* @param string $warnings
* @param array $a the words contained
*/
function game_check_common_problems_shortanswer_allowspaces( $game, &$warnings, $a) {
if ($game->param7 != 0) {
// Allow spaces, so no check is needed.
return;
}
$ret = array();
foreach ($a as $word) {
if (strpos( $word, ' ') === false) {
continue;
}
$ret[] = $word;
}
if (count( $ret) != 0) {
$warnings[] = get_string( 'common_problems_allowspaces', 'game').': '.count($ret).' ('.implode( ', ', $ret).')';
}
}
/**
* Checks for common problems (check if are answers with spaces and the game doesn't allow spaces)
*
* @param stdClass $game
* @param string $warnings
* @param array $a the words contained
*/
function game_check_common_problems_shortanswer_hangman( $game, &$warnings, $a) {
$ret = array();
foreach ($a as $word) {
$word = game_upper( str_replace( ' ', '', $word), $game->language);
if ($game->language == '') {
$game->language = game_detectlanguage( $word);
$word = game_upper( $word, $game->language);
}
$allletters = game_getallletters( $word, $game->language, $game->userlanguage);
if ($allletters != '') {
continue;
}
$ret[] = $word;
}
if (count( $ret) != 0) {
$warnings[] = get_string( 'common_problems_shortanswer_hangman', 'game').': '.count($ret).' ('.implode( ', ', $ret).')';
}
}
/**
* Checks for common problems (check crossword/cryptex parameters)
*
* @param stdClass $game
* @param string $warnings
*/
function game_check_common_problems_crossword_cryptex($game, &$warnings) {
global $CFG, $DB;
if (($game->param1 < 10) && ($game->param1 > 0)) {
$warnings[] = get_string( 'common_problems_crossword_param1', 'game').' (='.$game->param1.')';
}
}

51
classes/event/course_module_instance_list_viewed.php

@ -0,0 +1,51 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The mod_game instance list viewed event.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_game\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_game instance list viewed event class.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed {
/**
* Create the event.
*
* @param stdClass $course
*/
public static function create_from_course(\stdClass $course) {
$params = array(
'context' => \context_course::instance($course->id)
);
$event = self::create( $params);
$event->add_record_snapshot('course', $course);
return $event;
}
}

86
classes/event/course_module_viewed.php

@ -0,0 +1,86 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The mod_game course module viewed event.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_game\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_game course module viewed event class.
*
* @package mod_game
* @since Moodle 2.6
* @copyright 2014 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_viewed extends \core\event\course_module_viewed {
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \stdClass $game
* @param \context_module $context
* @return course_module_viewed
*/
public static function viewed(\stdClass $game, \context_module $context) {
$data = array(
'context' => $context,
'objectid' => $game->id
);
$event = self::create($data);
$event->add_record_snapshot('game', $game);
return $event;
}
/**
* Create instance of event.
*
* @param stdClass $game
* @param context_module $context
*
* @return event
*/
public static function played(\stdClass $game, \context_module $context) {
$data = array(
'context' => $context,
'objectid' => $game->id
);
$event = self::create($data);
$event->add_record_snapshot('game', $game);
return $event;
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'game';
}
}

107
classes/event/game_played.php

@ -0,0 +1,107 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The mod_game chapter viewed event.
*
* @package mod_game
* @copyright 2014 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_game\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_game chapter viewed event class.
*
* @package mod_game
* @since Moodle 2.6
* @copyright 2014 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class game_played extends \core\event\base {
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' played the game with id '$this->objectid' for the game with the " .
"course module id '$this->contextinstanceid'.";
}
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \stdClass $game
* @param \context_module $context
* @return event
*/
public static function played(\stdClass $game, \context_module $context) {
$data = array(
'context' => $context,
'objectid' => $game->id
);
$event = self::create($data);
$event->add_record_snapshot('game', $game);
return $event;
}
/**
* Return the legacy event log data.
*
* @return array|null
*/
protected function get_legacy_logdata() {
return array($this->courseid, 'game', 'view', 'view.php?id=' . $this->contextinstanceid,
$this->objectid, $this->contextinstanceid);
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventgameviewed', 'mod_game');
}
/**
* Get URL related to the action.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/game/view.php', array('id' => $this->contextinstanceid));
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'game';
}
}

49
classes/plugininfo/gametool.php

@ -0,0 +1,49 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Subplugin info class.
*
* @package mod_game
* @copyright 2014 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_game\plugininfo;
use core\plugininfo\base;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_game gametool.
*
* @package mod_game
* @since Moodle 2.6
* @copyright 2014 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class gametool extends base {
/**
* returns true to is_uninstall_allowed.
*
* @return true
*/
public function is_uninstall_allowed() {
return true;
}
}

10
composer.json

@ -0,0 +1,10 @@
{
"name": "bdaloukas/moodle-mod_game",
"type": "moodle-mod",
"require": {
"composer/installers": "~1.0"
},
"extra": {
"installer-name": "game"
}
}

920
cross/cross_class.php

@ -0,0 +1,920 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Cross class
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/*
Crossing Words for
Codewalkers PHP Coding Contest of July 2002
(http://codewalkers.com/php-contest.php)
Author Àngel Fenoy from Arenys de Mar, Barcelona.
*/
/**
* The class cross computes a crossword.
*
* @package mod_game
* @copyright 2014 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class Cross
{
/** @var int Contains the words and the answers. */
public $minputanswers;
/** @var The words that will be used. */
public $mwords;
/** @var Time limit for computing the cross */
public $mtimelimit = 3;
// Computed by computenextcross.
/** @var Best score post */
public $mbestcrosspos;
/** @var Best score dir */
public $mbestcrossdir;
/** @var Best score crossword */
public $mbestcrossword;
/** @var Best puzzle */
public $mbestpuzzle;
/** @var The best score as a phrase. */
public $mbests;
/** @var The best score */
public $mbestscore;
/** @var The best connectors */
public $mbestconnectors;
/** @var The best filleds */
public $mbestfilleds;
/** @var The best spaces */
public $mbestspaces;
/** @var The best n20 */
public $mbestn20;
/** @var Computed by ComputePuzzleInfo. */
public $mmincol;
/** @var Computed by ComputePuzzleInfo. */
public $mmaxcol;
/** @var Computed by ComputePuzzleInfo. */
public $mminrow;
/** @var Computed by ComputePuzzleInfo. */
public $mmaxrow;
/** @var Computed by ComputePuzzleInfo. */
public $mcletter;
/** @var Repetition of each word. */
public $mreps;
/** @var Average of repetitions. */
public $maveragereps;
/**
* Set words for computing.
*
* @param array $answers
* @param int $maxcols
* @param array $reps
*
* @return moodle_url
*/
public function setwords( $answers, $maxcols, $reps) {
$this->mreps = array();
foreach ($reps as $word => $r) {
$this->mreps[ game_upper( $word)] = $r;
}
$this->maveragereps = 0;
foreach ($reps as $r) {
$this->maveragereps += $r;
}
if (count( $reps)) {
$this->maveragereps /= count( $reps);
}
$this->minputanswers = array();
foreach ($answers as $word => $answer) {
$this->minputanswers[ game_upper( $word)] = $answer;
}
$this->mwords = array();
$maxlen = 0;
foreach ($this->minputanswers as $word => $answer) {
$len = game_strlen( $word);
if ($len > $maxlen) {
$maxlen = $len;
}
}
$n20 = $maxlen;
if ($n20 < 15) {
$n20 = 15;
}
$this->mn20min = round( $n20 - $n20 / 4);
$this->mn20max = round( $n20 + $n20 / 4);
if ( $this->mn20max > $maxcols and $maxcols > 0) {
$this->mn20max = $maxcols;
}
if ($this->mn20min > $this->mn20max) {
$this->mn20min = $this->mn20max;
}
$this->mwords = array();
foreach ($this->minputanswers as $word => $answer) {
$len = game_strlen( $word);
if ($len <= $this->mn20max) {
$this->mwords[] = game_upper( $word);
}
}
$this->randomize();
return count( $this->mwords);
}
/**
* Randomizes the words.
*/
public function randomize() {
$n = count( $this->mwords);
for ($j = 0; $j <= $n / 4; $j++) {
$i = array_rand( $this->mwords);
$this->swap( $this->mwords[ $i], $this->mwords[ 0]);
}
}
/**
* Compute one crossword.
*
* @param stdClass $crossm
* @param stdClass $crossd
* @param string $letters
* @param int $minwords
* @param int $maxwords
* @param int $mtimelimit
*
* @return the crossword
*/
public function computedata( &$crossm, &$crossd, &$letters, $minwords, $maxwords, $mtimelimit=3) {
$t1 = time();
$ctries = 0;
$mbestscore = 0;
$mbestconnectors = $mbestfilleds = $mbestspaces = 0;
$mbestn20 = 0;
$nochange = 0;
$this->mtimelimit = $mtimelimit;
if ($this->mtimelimit == 30) {
$this->mtimelimit = 27;
}
for (;;) {
// Selects the size of the cross.
$n20 = mt_rand( $this->mn20min, $this->mn20max);
if (!$this->computenextcross( $n20, $ctries, $minwords, $maxwords, $nochange)) {
break;
}
$ctries++;
if (time() - $t1 > $this->mtimelimit) {
break;
}
if ($nochange > 10) {
break;
}
}
$this->computepuzzleinfo( $this->mbestn20, $this->mbestcrosspos, $this->mbestcrossdir, $this->mbestcrossword, false);
return $this->savepuzzle( $crossm, $crossd, $ctries, time() - $t1);
}
/**
* Compute the next crossword.
*
* @param int $n20
* @param int $ctries
* @param int $minwords
* @param int $maxwords
* @param int $nochange
*
* @return \moodle_url
*/
public function computenextcross( $n20, $ctries, $minwords, $maxwords, &$nochange) {
$maxw = $n20;
$n21 = $n20 + 1;
$n22 = $n20 + 2;
$n2222 = $n22 * $n22;
$basepuzzle = str_repeat('0', $n22) .
str_repeat('0' . str_repeat('.', $n20) . '0', $n20) .
str_repeat('0', $n22);
$crosspos = array();
$crossdir = array();
$crossword = array();
$magics = array();
for ($n = 2; $n < $n21; $n++) {
$a = array();
for ($r = 2; $r < ($n + 2); $r++) {
$a[] = $r;
}
uasort($a, array( $this, 'cmp_magic'));
$magics[ $n] = $a;
}
uasort($this->mwords, array( $this, 'cmp'));
$words = ';' . implode(';', $this->mwords) . ';';
$puzzle = $basepuzzle;
$row = mt_rand(3, max( 3, $n20 - 3));
$col = mt_rand(3, max( 3, $n20 - 3));
$pos = $n22 * $row + $col;
$poss = array();
$ret = $this->scan_pos($pos, 'h', true, $puzzle, $words, $magics, $poss, $crosspos, $crossdir, $crossword, $n20);
while ($s = count($poss)) {
$p = array_shift($poss);
if ($this->scan_pos($p[0], $p[1], false, $puzzle, $words, $magics, $poss, $crosspos, $crossdir, $crossword, $n20)) {
$nwords = count( $crossword);
if ($maxwords) {
if ($nwords >= $maxwords) {
break;
}
}
}
}
$nwords = count( $crossword);
if ($minwords) {
if ($nwords < $minwords) {
return true;
}
}
$score = $this->computescore( $puzzle, $n20, $n22, $n2222, $nwords, $nconnectors, $nfilleds, $cspaces, $crossword);
if ($score > $this->mbestscore) {
$this->mbestcrosspos = $crosspos;
$this->mbestcrossdir = $crossdir;
$this->mbestcrossword = $crossword;
$this->mbestpuzzle = $puzzle;
$this->mbests = array('Words' => "$nwords * 5 = " . ($nwords * 5),
'Connectors' => "$nconnectors * 3 = " . ($nconnectors * 3),
'Filled in spaces' => $nfilleds,
"N20" => $n20
);
$this->mbestscore = $score;
$this->mbestconnectors = $nconnectors;
$this->mbestfilleds = $nfilleds;
$this->mbestspaces = $cspaces;
$this->mbestn20 = $n20;
$nochange = 0;
} else {
$nochange++;
}
return true;
}
/**
* Compute the scrore of one crossword.
*
* @param string $puzzle
* @param int $n20
* @param int $n22
* @param int $n2222
* @param int $nwords
* @param int $nconnectors
* @param int $nfilleds
* @param int $cspaces
* @param stdClass $crossword
*
* @return \moodle_url
*/
public function computescore( $puzzle, $n20, $n22, $n2222, $nwords, &$nconnectors, &$nfilleds, &$cspaces, $crossword) {
$nconnectors = $nfilleds = 0;
$puzzle00 = str_replace('.', '0', $puzzle);
$used = 0;
for ($n = 0; $n < $n2222; $n++) {
if ($puzzle00[$n]) {
$used ++;
if (($puzzle00[$n - 1] or $puzzle00[$n + 1]) and ($puzzle00[$n - $n22] or $puzzle00[$n + $n22])) {
$nconnectors++;
} else {
$nfilleds++;
}
}
}
$cspaces = substr_count( $puzzle, ".");
$score = ($nwords * 5) + ($nconnectors * 3) + $nfilleds;
$sumrep = 0;
foreach ($crossword as $word) {
$word = game_substr( $word, 1, -1);
if (array_key_exists( $word, $this->mreps)) {
$sumrep += $this->mreps[ $word] - $this->maveragereps;
}
}
return $score - 10 * $sumrep;
}
/**
* Compute puzzle info.
*
* @param int $n20
* @param int $crosspos
* @param int $crossdir
* @param stdClass $crossword
* @param boolean $bprint
*/
public function computepuzzleinfo( $n20, $crosspos, $crossdir, $crossword, $bprint=false) {
$bprint = false;
$n22 = $n20 + 2;
$this->mmincol = $n22;
$this->mmaxcol = 0;
$this->mminrow = $n22;
$this->mmaxrow = 0;
$this->mcletter = 0;
if (count( $crossword) == 0) {
return;
}
if ($bprint) {
echo "<br><br>PuzzleInfo n20=$n20 words=".count( $crossword)."<BR>";
}
for ($i = 0; $i < count($crosspos); $i++) {
$pos = $crosspos[ $i];
$col = $pos % $n22;
$row = floor( $pos / $n22);
$dir = $crossdir[ $i];
$len = game_strlen( $crossword[ $i]) - 3;
if ($bprint) {
echo "col=$col row=$row dir=$dir word=".$crossword[ $i]."<br>";
}
$this->mcletter += $len;
if ($col < $this->mmincol) {
$this->mmincol = $col;
}
if ($row < $this->mminrow) {
$this->mminrow = $row;
}
if ($dir == 'h') {
$col += $len;
} else {
$row += $len;
}
if ($col > $this->mmaxcol) {
$this->mmaxcol = $col;
}
if ($row > $this->mmaxrow) {
$this->mmaxrow = $row;
}
}
if ($bprint) {
echo "mincol={$this->mmincol} maxcol={$this->mmaxcol} minrow={$this->mminrow} maxrow={$this->mmaxrow}<br>";
}
if ($this->mmincol > $this->mmaxcol) {
$this->mmincol = $this->mmaxcol;
}
if ($this->mminrow > $this->mmaxrow) {
$this->mminrow = $this->mmaxrow;
}
}
/**
* Save the crossword to database.
*
* @param array $crossm
* @param array $crossd
* @param int $ctries
* @param int $time
*/
public function savepuzzle( &$crossm, &$crossd, $ctries, $time) {
$n22 = $this->mbestn20 + 2;
$cols = $this->mmaxcol - $this->mmincol + 1;
$rows = $this->mmaxrow - $this->mminrow + 1;
$bswapcolrow = false;
if ($bswapcolrow) {
swap( $cols, $rows);
swap( $this->mmincol, $this->mminrow);
swap( $this->mmaxcol, $this->mmaxrow);
}
$crossm = new stdClass();
$crossm->datebegin = time();
$crossm->time = $time;
$crossm->usedcols = $cols;
$crossm->usedrows = $rows;
$crossm->words = count( $this->mbestcrosspos);
$crossm->wordsall = count( $this->minputanswers);
$crossm->createscore = $this->mbestscore;
$crossm->createtries = $ctries;
$crossm->createtimelimit = $this->mtimelimit;
$crossm->createconnectors = $this->mbestconnectors;
$crossm->createfilleds = $this->mbestfilleds;
$crossm->createspaces = $this->mbestspaces;
for ($i = 0; $i < count($this->mbestcrosspos); $i++) {
$pos = $this->mbestcrosspos[ $i];
$col = $pos % $n22;
$row = floor( ($pos - $col) / $n22);
$col += -$this->mmincol + 1;
$row += -$this->mminrow + 1;
$dir = $this->mbestcrossdir[ $i];
$word = $this->mbestcrossword[ $i];
$word = substr( $word, 1, strlen( $word) - 2);
$rec = new stdClass();
$rec->col = $col;
$rec->row = $row;
$rec->horizontal = ($dir == "h" ? 1 : 0);
$rec->answertext = $word;
$rec->questiontext = $this->minputanswers[ $word];
if ($rec->horizontal) {
$key = sprintf( 'h%10d %10d', $rec->row, $rec->col);
} else {
$key = sprintf( 'v%10d %10d', $rec->col, $rec->row);
}
$crossd[ $key] = $rec;
}
if (count( $crossd) > 1) {
ksort( $crossd);
}
return (count( $crossd) > 0);
}
/**
* Swaps two variables.
*
* @param object $a
* @param object $b
*/
public function swap( &$a, &$b) {
$temp = $a;
$a = $b;
$b = $temp;
}
/**
* Displays a crossword.
*
* @param sting $puzzle
* @param int $n20
*/
public function displaycross($puzzle, $n20) {
$n21 = $n20 + 1;
$n22 = $n20 + 2;
$n2222 = $n22 * $n22;
$n2221 = $n2222 - 1;
$n2200 = $n2222 - $n22;
$ret = "<table border=0 cellpadding=2 cellspacing=1><tr>";
for ($n = 0;; $n ++) {
$c = game_substr( $puzzle, $n, 1);
if (($m = $n % $n22) == 0 or $m == $n21 or $n < $n22 or $n > $n2200) {
$ret .= "<td class=marc> </td>";
} else if ( $c == '0') {
$ret .= "<td class=limit> </td>";
} else if ($c == '.') {
$ret .= "<td class=blanc> </td>";
} else {
if ((game_substr( $puzzle, $n - 1, 1) > '0' or
game_substr( $puzzle, $n + 1, 1) > '0') and
(game_substr( $puzzle, $n - $n22, 1) > '0'
or game_substr( $puzzle, $n + $n22, 1) > '0')) {
$ret .= "<td align=center class=connector>$c</td>";
} else {
$ret .= "<td align=center class=filled>$c</td>";
}
}
if ($n == $n2221) {
return "$ret</tr></table>";
} else if ($m == $n21) {
$ret .= "</tr><tr>";
}
}
return $ret.'</tr></table>';
}
/**
* Scans a position.
*
* @param int $pos
* @param int $dir
* @param int $valblanc
* @param string $puzzle
* @param array $words
* @param object $magics
* @param object $poss
* @param int $crosspos
* @param int $crossdir
* @param object $crossword
* @param int $n20
*
* @return true if it is ok.
*/
public function scan_pos($pos, $dir, $valblanc, &$puzzle, &$words, &$magics,
&$poss, &$crosspos, &$crossdir, &$crossword, $n20) {
$maxw = $n20;
$n22 = $n20 + 2;
$n2222 = $n22 * $n22;
if ($dir == 'h') {
$inc = 1;
if ($pos + $inc >= $n2222) {
return false;
}
$oinc = $n22;
$newdir = 'v';
} else {
$inc = $n22;
if ($pos + $inc >= $n2222) {
return false;
}
$oinc = 1;
$newdir = 'h';
}
$regex = game_substr( $puzzle, $pos, 1);
if ( ($regex == '0' or $regex == '.') and (!$valblanc)) {
return false;
}
if ((game_substr( $puzzle, $pos - $inc, 1) > '0')) {
return false;
}
if ((game_substr( $puzzle, $pos + $inc, 1) > '0')) {
return false;
}
$left = $right = 0;
for ($limita = $pos - $inc; ($w = game_substr( $puzzle, $limita, 1)) !== '0'; $limita -= $inc) {
if ($w == '.' and ((game_substr( $puzzle, $limita - $oinc, 1) > '0') or
(game_substr( $puzzle, $limita + $oinc, 1) > '0'))) {
break;
}
if (++$left == $maxw) {
$left --;
break;
}
$regex = $w . $regex;
}
for ($limitb = $pos + $inc; ($w = game_substr( $puzzle, $limitb, 1)) !== '0'; $limitb += $inc) {
if ($w == '.' and ((game_substr( $puzzle, $limitb - $oinc, 1) > '0')
or (game_substr( $puzzle, $limitb + $oinc, 1) > '0'))) {
break;
}
if (++$right == $maxw) {
$right--;
break;
}
$regex .= $w;
}
if (($lenregex = game_strlen($regex)) < 2) {
return false;
}
foreach ($magics[$lenregex] as $m => $lens) {
$ini = max(0, ($left + 1) - $lens);
$fin = $left;
$posp = max($limita + $inc, $pos - (($lens - 1 ) * $inc));
for ($posc = $ini; $posc <= $fin; $posc++, $posp += $inc) {
if (game_substr( $puzzle, $posp - $inc, 1) > '0') {
continue;
}
$w = game_substr($regex, $posc, $lens);
if (!$this->my_preg_match( $w, $words, $word)) {
continue;
}
$larr0 = $posp + ((game_strlen( $word) - 2) * $inc);
if ($larr0 >= $n2222) {
continue;
}
if (game_substr( $puzzle, $larr0, 1) > '0') {
continue;
}
$words = str_replace( $word, ';', $words);
$len = game_strlen( $word);
for ($n = 1, $pp = $posp; $n < $len - 1; $n++, $pp += $inc) {
$this->setchar( $puzzle, $pp, game_substr( $word , $n, 1));
if ($pp == $pos) {
continue;
}
$c = game_substr( $puzzle, $pp, 1);
$poss[] = array($pp, $newdir, ord( $c));
}
$crosspos[] = $posp;
$crossdir[] = ($newdir == 'h' ? 'v' : 'h');
$crossword[] = $word;
$this->setchar( $puzzle, $posp - $inc, '0');
$this->setchar( $puzzle, $pp, '0');
return true;
}
}
return false;
}
/**
* my_preg_match (backward compatibility).
*
* @param string $w
* @param string $words
* @param string $word
*
* @return true if it is ok.
*/
public function my_preg_match( $w, $words, &$word) {
$a = explode( ";", $words);
$lenw = game_strlen( $w);
foreach ($a as $test) {
if (game_strlen( $test) != $lenw) {
continue;
}
for ($i = 0; $i < $lenw; $i++) {
if (game_substr( $w, $i, 1) == '.') {
continue;
}
if (game_substr( $w, $i, 1) != game_substr( $test, $i, 1) ) {
break;
}
}
if ($i < $lenw) {
continue;
}
$word = ';'.$test.';';
return true;
}
return false;
}
/**
* Set a char to the specified position.
*
* @param string $s
* @param int $pos
* @param string $char
*/
public function setchar( &$s, $pos, $char) {
$ret = "";
if ($pos > 0) {
$ret .= game_substr( $s, 0, $pos);
}
$s = $ret . $char . game_substr( $s, $pos + 1, game_strlen( $s) - $pos - 1);
}
/**
* Show html base.
*
* @param object $crossm
* @param object $crossd
* @param boolean $showsolution
* @param boolean $showhtmlsolutions
* @param boolean $showstudentguess
* @param stdClass $context
* @param stdClass $game
*/
public function showhtml_base( $crossm, $crossd, $showsolution, $showhtmlsolutions, $showstudentguess, $context, $game) {
global $CFG, $DB;
$this->mLegendh = array();
$this->mLegendv = array();
$sret = "CrosswordWidth = {$crossm->usedcols};\n";
$sret .= "CrosswordHeight = {$crossm->usedrows};\n";
$sret .= "Words=".count( $crossd).";\n";
$swordlength = "";
$sguess = "";
$ssolutions = '';
$shtmlsolutions = '';
$swordx = "";
$swordy = "";
$sclue = "";
$lasthorizontalword = -1;
$i = -1;
$legendv = array();
$legendh = array();
if ($game->glossaryid) {
$sql = "SELECT id,course FROM {$CFG->prefix}glossary WHERE id={$game->glossaryid}";
$glossary = $DB->get_record_sql( $sql);
$cmglossary = get_coursemodule_from_instance('glossary', $game->glossaryid, $glossary->course);
$contextglossary = game_get_context_module_instance( $cmglossary->id);
}
foreach ($crossd as $rec) {
if ($rec->horizontal == false and $lasthorizontalword == -1) {
$lasthorizontalword = $i;
}
$i++;
$swordlength .= ",".game_strlen( $rec->answertext);
if ($rec->questionid != 0) {
$q = game_filterquestion(str_replace( '\"', '"', $rec->questiontext),
$rec->questionid, $context->id, $game->course);
$rec->questiontext = game_repairquestion( $q);
} else {
// Glossary.
$q = game_filterglossary(str_replace( '\"', '"', $rec->questiontext),
$rec->glossaryentryid, $contextglossary->id, $game->course);
$rec->questiontext = game_repairquestion( $q);
}
$sclue .= ',"'.game_tojavascriptstring( game_filtertext( $rec->questiontext, 0))."\"\r\n";
if ($showstudentguess) {
$sguess .= ',"'.$rec->studentanswer.'"';
} else {
$sguess .= ",''";
}
$swordx .= ",".($rec->col - 1);
$swordy .= ",".($rec->row - 1);
if ($showsolution) {
$ssolutions .= ',"'.$rec->answertext.'"';
} else {
$ssolutions .= ',""';
}
if ($showhtmlsolutions) {
$shtmlsolutions .= ',"'.base64_encode( $rec->answertext).'"';
}
$attachment = '';
$s = $rec->questiontext.$attachment;
if ($rec->horizontal) {
if (array_key_exists( $rec->row, $legendh)) {
$legendh[ $rec->row][] = $s;
} else {
$legendh[ $rec->row] = array( $s);
}
} else {
if (array_key_exists( $rec->col, $legendv)) {
$legendv[ $rec->col][] = $s;
} else {
$legendv[ $rec->col] = array( $s);
}
}
}
$letters = get_string( 'lettersall', 'game');
$this->mlegendh = array();
foreach ($legendh as $key => $value) {
if (count( $value) == 1) {
$this->mlegendh[ $key] = $value[ 0];
} else {
for ($i = 0; $i < count( $value); $i++) {
$this->mlegendh[ $key.game_substr( $letters, $i, 1)] = $value[ $i];
}
}
}
$this->mlegendv = array();
foreach ($legendv as $key => $value) {
if (count( $value) == 1) {
$this->mlegendv[ $key] = $value[ 0];
} else {
for ($i = 0; $i < count( $value); $i++) {
$this->mlegendv[ $key.game_substr( $letters, $i, 1)] = $value[ $i];
}
}
}
ksort( $this->mlegendh);
ksort( $this->mlegendv);
$sret .= "WordLength = new Array( ".game_substr( $swordlength, 1).");\n";
$sret .= "Clue = new Array( ".game_substr( $sclue, 1).");\n";
$sguess = str_replace( ' ', '_', $sguess);
$sret .= "Guess = new Array( ".game_substr( $sguess, 1).");\n";
$sret .= "Solutions = new Array( ".game_substr( $ssolutions, 1).");\n";
if ($showhtmlsolutions) {
$sret .= "HtmlSolutions = new Array( ".game_substr( $shtmlsolutions, 1).");\n";
}
$sret .= "WordX = new Array( ".game_substr( $swordx, 1).");\n";
$sret .= "WordY = new Array( ".game_substr( $swordy, 1).");\n";
$sret .= "LastHorizontalWord = $lasthorizontalword;\n";
return $sret;
}
/**
* Compares length of two strings.
*
* @param string $a
* @param string $b
*
* @return -1 if a < b, 0 if equal
*/
public function cmp($a, $b) {
return game_strlen($b) - game_strlen($a);
}
/**
* Compares two strings with random
*
* @param string $a
* @param string $b
*
* @return -1 if a < b, 0 if equal
*/
public function cmp_magic($a, $b) {
return (game_strlen($a) + mt_rand(0, 3)) - (game_strlen($b) - mt_rand(0, 1));
}
}

318
cross/crossdb_class.php

@ -0,0 +1,318 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CrossDB class
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* This class is a cross that can load and save to a table
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
**/
class CrossDB extends Cross {
/**
* Save cross.
*
* @param stdClass $game
* @param array $crossm
* @param array $crossd
* @param int $id
*/
public function savecross( $game, &$crossm, $crossd, $id) {
global $DB, $USER;
$crossm->id = $id;
$crossm->sourcemodule = $game->sourcemodule;
$this->delete_records( $id);
if (!(game_insert_record( "game_cross", $crossm))) {
print_error( 'Insert page: new page game_cross not inserted');
}
foreach ($crossd as $rec) {
$rec->attemptid = $id;
$rec->questiontext = addslashes( $rec->questiontext);
$rec->gamekind = $game->gamekind;
$rec->gameid = $game->id;
$rec->userid = $USER->id;
$rec->sourcemodule = $game->sourcemodule;
if (!$DB->insert_record( 'game_queries', $rec)) {
print_error( 'Insert page: new page game_queries not inserted');
}
game_update_repetitions($game->id, $USER->id, $rec->questionid, $rec->glossaryentryid);
}
return true;
}
/**
* Delete records.
*
* @param int $id
*/
public function delete_records( $id) {
global $DB;
if (!$DB->delete_records( 'game_queries', array( 'attemptid' => $id))) {
print_error( "Can't delete from game_queries attemptid=$id");
}
if (!$DB->delete_records( 'game_cross', array( 'id' => $id))) {
print_error( "Can't delete from game_cross id=$id");
}
}
/**
* Load cross.
*
* @param string $g
* @param boolean $done
* @param string $html
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $crossrec
* @param boolean $onlyshow
* @param boolean $showsolution
* @param boolean $finishattempt
* @param boolean $showhtmlsolutions
* @param string $language
* @param boolean $showstudentguess
* @param stdClass $context
*/
public function loadcross( $g, &$done, &$html, $game, $attempt, $crossrec, $onlyshow, $showsolution,
&$finishattempt, $showhtmlsolutions, &$language, $showstudentguess, $context) {
global $DB;
$info = '';
$correctletters = 0;
$allletters = 0;
$wrongletters = 0;
$html = '';
$done = false;
$loadfromdb = ( $g == "");
$this->mmincol = $this->mminrow = 0;
$this->mmaxcol = $crossrec->usedcols;
$this->mmaxrow = $crossrec->usedrows;
if ($g == "") {
$g = str_repeat( ' ', $this->mmaxcol * $this->mmaxrow);
}
$load = false;
$puzzle = str_repeat('.', $this->mmaxrow * $this->mmaxcol);
if ($recs = $DB->get_records( 'game_queries', array( 'attemptid' => $crossrec->id))) {
$a = array();
foreach ($recs as $rec) {
if ($rec->horizontal) {
$key = sprintf( 'h%10d %10d', $rec->row, $rec->col);
} else {
$key = sprintf( 'v%10d %10d', $rec->col, $rec->row);
}
$a[ $key] = $rec;
}
ksort( $a);
$b = array();
$correctletters = $wrongletters = $restletters = 0;
foreach ($a as $rec) {
$this->updatecrossquestions( $rec, $g, $pos, $correctletters,
$wrongletters, $restletters, $game, $attempt, $crossrec, $loadfromdb);
$b[] = $rec;
if (($rec->col != 0) and ($rec->row != 0)) {
$load = true;
}
if ($language == '') {
$language = game_detectlanguage( $rec->answertext);
}
}
$info = $this->game_cross_computecheck( $correctletters, $wrongletters,
$restletters, $game, $attempt, $done, $onlyshow, $showsolution, $finishattempt);
$html = $this->showhtml_base( $crossrec, $b, $showsolution, $showhtmlsolutions, $showstudentguess, $context, $game);
}
if ($load == false) {
$finishattempt = true;
}
return $info;
}
/**
* Compute check.
*
* @param int $correctletters
* @param int $wrongletters
* @param string $restletters
* @param stdClass $game
* @param stdClass $attempt
* @param boolean $done
* @param boolean $onlyshow
* @param boolean $showsolution
* @param boolean $finishattempt
*/
public function game_cross_computecheck( $correctletters, $wrongletters, $restletters, $game,
$attempt, &$done, $onlyshow, $showsolution, $finishattempt) {
$ret = '';
$and = get_string( 'and', 'game');
$a = array();
if ($correctletters) {
$a[] = $correctletters.' '.
( $correctletters > 1 ? get_string( 'cross_corrects', 'game') : get_string( 'cross_correct', 'game'));
}
if ($wrongletters) {
$a[] = '<b>'.$wrongletters.' '.
( $wrongletters > 1 ? get_string( 'cross_errors', 'game') : get_string( 'cross_error', 'game')).'</b>';
}
if ($correctletters > 1 or $wrongletters > 1) {
$ret = get_string( 'cross_found_many', 'game');
} else if ( count( $a)) {
$ret = get_string( 'cross_found_one', 'game');
} else {
$ret = '';
}
$i = 0;
foreach ($a as $msg) {
$i++;
if ($i == 1) {
$ret .= ' '.$msg;
} else if ( $i == count($a)) {
$ret .= ' '.get_string( 'and', 'game').' '.$msg;
} else {
$ret .= ', '.$msg;
}
}
$done = ( $restletters == 0 ? true : false);
if ($finishattempt == false) {
if ($onlyshow or $showsolution) {
return $ret;
}
} else {
$done = 1;
}
$grade = $correctletters / ($correctletters + $restletters);
$ret .= '<br>'.get_string( 'grade', 'game').' '.round( $grade * 100).' %';
game_updateattempts( $game, $attempt, $grade, $done);
return $ret;
}
/**
* Update cross questions.
*
* @param stdClass $rec (is a record of cross_questions).
* @param string $g
* @param int $pos
* @param int $correctletters
* @param int $wrongletters
* @param int $restletters
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $crossrec
* @param boolean $loadfromdb
*/
public function updatecrossquestions( &$rec, &$g, &$pos, &$correctletters, &$wrongletters,
&$restletters, $game, $attempt, $crossrec, $loadfromdb) {
global $DB, $USER;
$word = $rec->answertext;
$len = game_strlen( $word);
if ($loadfromdb) {
$guess = $rec->studentanswer;
} else {
$guess = game_substr( $g, $pos, $len);
}
$lenguess = game_strlen( $guess);;
$pos += $len;
$isempty = true;
for ($i = 0; $i < $len; $i++) {
if ($i < $lenguess) {
$letterguess = game_substr( $guess, $i, 1);
} else {
$letterguess = " ";
}
if ($letterguess != ' ') {
$isempty = false;
}
$letterword = game_substr( $word, $i, 1);
if ($letterword != $letterguess) {
if (($letterguess != ' ' and $letterguess != '_')) {
$wrongletters++;
}
game_setchar( $guess, $i, '_');
$restletters++;
} else if ($letterguess == ' ') {
if ($guess == $word) {
$correctletters++;
}
} else {
$correctletters++;
}
}
if ($isempty) {
return;
}
if (($rec->studentanswer == $guess )) {
return;
}
$rec->studentanswer = $guess;
$updrec = new stdClass();
$updrec->studentanswer = $guess;
$updrec->id = $rec->id;
if (!$DB->update_record( 'game_queries', $updrec, $rec->id)) {
print_error( 'Update game_queries: not updated');
}
$score = $correctletters / $len;
game_update_queries( $game, $attempt, $rec, $score, $guess);
}
}

1206
cross/play.php

File diff suppressed because it is too large

320
cryptex/cryptexdb_class.php

@ -0,0 +1,320 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The class CryptexDB loads/save the cryptex from/to database.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* The class CryptexDB loads/save the cryptex from/to database.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class CryptexDB extends CrossDB {
/**
* Save cryptex.
*
* @param stdClass $game
* @param array $crossm
* @param array $crossd
* @param int $id
* @param string $letters
*
* @return the saved record
*/
public function savecryptex( $game, &$crossm, $crossd, $id, $letters) {
global $USER;
CrossDB::delete_records( $id);
if ((CrossDB::savecross( $game, $crossm, $crossd, $id)) == false) {
return false;
}
$crossm->id = $id;
$newrec = new stdClass();
$newrec->id = $id;
$newrec->letters = $letters;
if (!($cryptexid = game_insert_record( "game_cryptex", $newrec))) {
print_error( 'Insert page: new page game_cryptex not inserted');
}
return $newrec;
}
/**
* Compute letters.
*
* @param array $crossm
* @param array $crossd
*
* @return the letters.
*/
public function computeletters( $crossm, $crossd) {
$letters = '';
$cols = $crossm->usedcols + 1;
$letters = str_repeat('.', $crossm->usedcols).'#';
$letters = str_repeat($letters, $crossm->usedrows);
$freqs1 = array();
$count1 = $count2 = 0;
foreach ($crossd as $rec) {
$pos = $rec->col - 1 + ($rec->row - 1) * $cols;
$s = $rec->answertext;
$len = game_strlen( $s);
$a = array();
for ($i = 0; $i < $len; $i++) {
$a[] = game_substr( $s, $i, 1);
}
for ($i = 0; $i < $len; $i++) {
$this->setchar( $letters, $pos, $a[ $i]);
$pos += ( $rec->horizontal ? 1 : $cols);
$freqs1[ ++$count1] = $a[ $i];
if ($i + 1 < $len) {
$freqs2[ ++$count2] = $a[ $i].$a[ $i + 1];
}
}
}
$len = game_strlen( $letters);
$spaces = 0;
for ($i = 0; $i < $len; $i++) {
if (game_substr( $letters, $i, 1) == '.') {
$spaces++;
}
}
$step = 1;
while ($spaces) {
if ($step == 1) {
$step = 2;
$i = array_rand( $freqs1);
$this->insertchar( $letters, $crossm->usedcols, $crossm->usedrows, $freqs1[ $i], $spaces);
} else {
$step = 1;
$i = array_rand( $freqs2);
$this->insertchars( $letters, $crossm->usedcols, $crossm->usedrows, $freqs2[ $i], $spaces);
}
}
$retletters = "";
for ($row = 0; $row < $crossm->usedrows; $row++) {
$retletters .= game_substr( $letters, $cols * $row, ($cols - 1));
}
return $retletters;
}
/**
* Displays the cryptex.
*
* @param int $cols
* @param int $rows
* @param string $letters
* @param string $mask
* @param boolean $showsolution
* @param boolean $textdir
*/
public function displaycryptex( $cols, $rows, $letters, $mask, $showsolution, $textdir) {
echo "<table border=1 $textdir>";
for ($row = 0; $row < $rows; $row++) {
echo "<tr>";
for ($col = 0; $col < $cols; $col++) {
$pos = $cols * $row + $col;
$c = game_substr( $letters, $pos, 1);
$m = game_substr( $mask, $pos, 1);
if ($showsolution and $m > '0') {
echo "<td align=center><b><FONT color=red>".$c."</font></td>";
} else if ( $m == '1') {
echo "<td align=center><b><FONT color=red>".$c."</font></td>";
} else {
echo "<td align=center>".$c."</td>";
}
}
echo "</tr>\r\n";
}
echo "</table>";
}
/**
* Inserts a char.
*
* @param string $letters
* @param int $cols
* @param int $rows
* @param string $char
* @param int $spaces
*/
public function insertchar( &$letters, $cols, $rows, $char, &$spaces) {
$len = game_strlen( $letters);
for ($i = 0; $i < $len; $i++) {
if (game_substr( $letters, $i, 1) == '.') {
$this->setchar( $letters, $i, $char);
$spaces--;
return;
}
}
}
/**
* Inserts chars.
*
* @param string $letters
* @param int $cols
* @param int $rows
* @param string $char
* @param int $spaces
*/
public function insertchars( &$letters, $cols, $rows, $char, &$spaces) {
$len = game_strlen( $letters);
for ($i = 0; $i < $len; $i++) {
if (game_substr( $letters, $i, 1) == '.' and game_substr( $letters, $i + 1, 1) == '.' ) {
$this->setchar( $letters, $i, game_substr( $char, 0, 1));
$this->setchar( $letters, $i + 1, game_substr( $char, 1, 1));
$spaces -= 2;
return true;
}
if (game_substr( $letters, $i, 1) == '.' and game_substr( $letters, $i + $cols + 1, 1) == '.' ) {
$this->setchar( $letters, $i, game_substr( $char, 0, 1));
$this->setchar( $letters, $i + $cols + 1, game_substr( $char, 1, 1));
$spaces -= 2;
return true;
}
}
return false;
}
/**
* Gets the hash of a word.
*
* @param string $word
*
* @return the hash
*/
public function gethash( $word) {
$x = 37;
$len = count( game_strlen( $word));
for ($i = 0; $i < $len; $i++) {
$x = $x xor ord( game_substr( $word, $i, 1));
}
return $x;
}
/**
* Loads the cryptex from database.
*
* @param array $crossm
* @param string $mask
* @param int $corrects
* @param string $language
*
* @return questions
*/
public function loadcryptex( $crossm, &$mask, &$corrects, &$language) {
global $DB;
$questions = array();
$corrects = array();
$mask = str_repeat( '0', $crossm->usedcols * $crossm->usedrows);
if ($recs = $DB->get_records( 'game_queries', array( 'attemptid' => $crossm->id))) {
foreach ($recs as $rec) {
if ($rec->questiontext == '') {
$rec->questiontext = ' ';
}
$key = $this->gethash( $rec->questiontext).'-'.$rec->answertext.'-'.$rec->id;
$questions[ $key] = $rec;
$word = $rec->answertext;
$pos = $crossm->usedcols * ($rec->row - 1) + ($rec->col - 1);
$len = game_strlen( $word);
$found = ($rec->answertext == $rec->studentanswer);
for ($i = 0; $i < $len; $i++) {
$c = ( $found ? '1' : '2');
if (game_substr( $mask, $pos, 1) != '1') {
game_setchar( $mask, $pos, $c);
}
$pos += ($rec->horizontal ? 1 : $crossm->usedcols);
}
if ($found) {
$corrects[ $rec->id] = 1;
}
if ($language == '') {
$language = game_detectlanguage( $rec->answertext);
}
}
ksort( $questions);
}
return $questions;
}
/**
* Calls the setwords of class Cross.
*
* @param string $answers
* @param int $maxcols
* @param array $reps
*
* @return Cross::setwords
*/
public function setwords( $answers, $maxcols, $reps) {
return Cross::setwords( $answers, $maxcols, $reps);
}
/**
* Calls the computedata of class Cross.
*
* @param stdClass $crossm
* @param stdClass $crossd
* @param string $letters
* @param int $minwords
* @param int $maxwords
* @param int $mtimelimit
*/
public function computedata( &$crossm, &$crossd, &$letters, $minwords, $maxwords, $mtimelimit=3) {
if (!cross::computedata( $crossm, $crossd, $letters, $minwords, $maxwords, $mtimelimit)) {
return false;
}
$letters = $this->computeletters( $crossm, $crossd);
return true;
}
}

427
cryptex/play.php

@ -0,0 +1,427 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page plays the cryptex game
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
**/
defined('MOODLE_INTERNAL') || die();
require_once( "cryptexdb_class.php");
/**
* Plays the game cryptex.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $cryptexrec
* @param boolean $endofgame
* @param stdClass $context
*/
function game_cryptex_continue( $id, $game, $attempt, $cryptexrec, $endofgame, $context) {
global $DB, $USER;
if ($endofgame) {
game_updateattempts( $game, $attempt, -1, true);
$endofgame = false;
}
if ($attempt != false and $cryptexrec != false) {
$crossm = $DB->get_record( 'game_cross', array( 'id' => $attempt->id));
return game_cryptex_play( $id, $game, $attempt, $cryptexrec, $crossm, false, false, false, $context);
}
if ($attempt === false) {
$attempt = game_addattempt( $game);
}
$cryptex = new CryptexDB();
$questions = array();
$infos = array();
$answers = array();
$recs = game_questions_shortanswer( $game);
if ($recs == false) {
print_error( get_string( 'no_words', 'game'));
}
$infos = array();
$reps = array();
foreach ($recs as $rec) {
if ($game->param7 == false) {
if (game_strpos( $rec->answertext, ' ')) {
continue; // Spaces not allowed.
}
}
$rec->answertext = game_upper( $rec->answertext);
$answers[ $rec->answertext] = game_repairquestion( $rec->questiontext);
$infos[ $rec->answertext] = array( $game->sourcemodule, $rec->questionid, $rec->glossaryentryid);
$a = array( 'gameid' => $game->id, 'userid' => $USER->id,
'questionid' => $rec->questionid, 'glossaryentryid' => $rec->glossaryentryid);
if (($rec2 = $DB->get_record('game_repetitions', $a, 'id,repetitions AS r')) != false) {
$reps[ $rec->answertext] = $rec2->r;
}
}
$cryptex->setwords( $answers, $game->param1, $reps);
// The game->param4 is minimum words.
// The game->param2 is maximum words.
if ($cryptex->computedata( $crossm, $crossd, $letters, $game->param4, $game->param2, $game->param3)) {
$newcrossd = array();
foreach ($crossd as $rec) {
if (array_key_exists( $rec->answertext, $infos)) {
$info = $infos[ $rec->answertext];
$rec->id = 0;
$rec->sourcemodule = $info[ 0];
$rec->questionid = $info[ 1];
$rec->glossaryentryid = $info[ 2];
}
game_update_queries( $game, $attempt, $rec, 0, '');
$newcrossd[] = $rec;
}
$cryptexrec = $cryptex->savecryptex( $game, $crossm, $newcrossd, $attempt->id, $letters);
}
game_updateattempts( $game, $attempt, 0, 0);
return game_cryptex_play( $id, $game, $attempt, $cryptexrec, $crossm, false, false, false, $context);
}
/**
* Checks if is correct.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $cryptexrec
* @param int $q (The q means game_queries.id).
* @param stdClass $answer
* @param boolean $finishattempt
* @param stdClass $context
*/
function game_cryptex_check( $id, $game, $attempt, $cryptexrec, $q, $answer, $finishattempt, $context) {
global $DB;
if ($finishattempt) {
game_updateattempts( $game, $attempt, -1, true);
game_cryptex_continue( $id, $game, false, false, true, $context);
return;
}
if ($attempt === false) {
game_cryptex_continue( $id, $game, $attempt, $cryptexrec, false, $context);
return;
}
$crossm = $DB->get_record_select( 'game_cross', "id=$attempt->id");
$query = $DB->get_record_select( 'game_queries', "id=$q");
$answer1 = trim( game_upper( $query->answertext));
$answer2 = trim( game_upper( $answer));
$len1 = game_strlen( $answer1);
$len2 = game_strlen( $answer2);
$equal = ( $len1 == $len2);
if ($equal) {
for ($i = 0; $i < $len1; $i++) {
if (game_substr( $answer1, $i, 1) != game_substr( $answer2, $i, 1)) {
$equal = true;
break;
}
}
}
if ($equal == false) {
game_update_queries( $game, $attempt, $query, 0, $answer2, true);
game_cryptex_play( $id, $game, $attempt, $cryptexrec, $crossm, true, false, false, $context);
return;
}
game_update_queries( $game, $attempt, $query, 1, $answer2);
$onlyshow = false;
$showsolution = false;
game_cryptex_play( $id, $game, $attempt, $cryptexrec, $crossm, true, $onlyshow, $showsolution, $context);
}
/**
* Plays the game cryptex.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $cryptexrec
* @param stdClass $crossm
* @param boolean $updateattempt
* @param boolean $onlyshow
* @param boolean $showsolution
* @param stdClass $context
* @param boolean $print
* @param boolean $showhtmlprintbutton
*/
function game_cryptex_play( $id, $game, $attempt, $cryptexrec, $crossm,
$updateattempt = false, $onlyshow = false, $showsolution = false, $context,
$print = false, $showhtmlprintbutton = true) {
global $CFG, $DB;
if ($game->toptext != '') {
echo $game->toptext.'<br>';
}
echo '<br>';
$cryptex = new CryptexDB();
$language = $attempt->language;
$questions = $cryptex->loadcryptex( $crossm, $mask, $corrects, $attempt->language);
if ($language != $attempt->language) {
if (!$DB->set_field( 'game_attempts', 'language', $attempt->language, array( 'id' => $attempt->id))) {
print_error( "game_cross_play: Can't set language");
}
}
if ( $attempt->language != '') {
$wordrtl = game_right_to_left( $attempt->language);
} else {
$wordrtl = right_to_left();
}
$reverseprint = ($wordrtl != right_to_left());
if ($reverseprint) {
$textdir = 'dir="'.($wordrtl ? 'rtl' : 'ltr').'"';
} else {
$textdir = '';
}
$len = game_strlen( $mask);
// The count1 means there is a guested letter.
// The count2 means there is a letter that not guessed.
$count1 = $count2 = 0;
for ($i = 0; $i < $len; $i++) {
$c = game_substr( $mask, $i, 1);
if ($c == '1') {
$count1++;
} else if ($c == '2') {
$count2++;
}
}
if ($count1 + $count2 == 0) {
$gradeattempt = 0;
} else {
$gradeattempt = $count1 / ($count1 + $count2);
}
$finished = ($count2 == 0);
if (($finished === false) && ($game->param8 > 0)) {
$found = false;
foreach ($questions as $q) {
if ($q->tries < $game->param8) {
$found = true;
}
}
if ($found == false) {
$finished = true; // Rich max tries.
}
}
if ($updateattempt) {
game_updateattempts( $game, $attempt, $gradeattempt, $finished);
}
if (($onlyshow == false) and ($showsolution == false)) {
if ($finished) {
game_cryptex_onfinished( $id, $game, $attempt, $cryptexrec);
}
}
?>
<style type="text/css"><!--
.answerboxstyle {
background-color: #FFFAF0;
border-color: #808080;
border-style: solid;
border-width: 1px;
display: block;
padding: .75em;
width: 240pt;
}
--></style>
<?php
$grade = round( 100 * $gradeattempt);
echo get_string( 'grade', 'game').' '.$grade.' %';
echo '<br>';
echo '<table border=0>';
echo '<tr><td>';
$cryptex->displaycryptex( $crossm->usedcols, $crossm->usedrows, $cryptexrec->letters, $mask, $showsolution, $textdir);
?>
</td>
<td width=10%>&nbsp;</td>
<td>
<form method="get" action="<?php echo $CFG->wwwroot?>/mod/game/attempt.php">
<div id="answerbox" class="answerboxstyle" style="display:none;">
<div id="wordclue" name="wordclue" class="cluebox"> </div>
<input id="action" name="action" type="hidden" value="cryptexcheck">
<input id="q" name="q" type="hidden" >
<input id="id" name="id" value="<?php echo $id; ?>" type="hidden">
<div style="margin-top:1em;"><input id="answer" name="answer" type="text" size="24"
style="font-weight: bold; text-transform:uppercase;" autocomplete="off"></div>
<table border="0" cellspacing="0" cellpadding="0" width="100%" style="margin-top:1em;"><tr>
<td align="right">
<button id="okbutton" type="submit" class="button" style="font-weight: bold;">OK</button> &nbsp;
<button id="cancelbutton" type="button" class="button" onclick="DeselectCurrentWord();">Cancel</button>
</td></tr></table>
</form>
</td>
</tr>
</table>
<?php
if ($showhtmlprintbutton) {
echo '<br><button id="finishattemptbutton" type="button" onclick="OnEndGame();" >'.get_string( 'finish', 'game');
echo '</button>';
echo '<button id="printbutton" type="button" onclick="OnPrint();" >'.get_string( 'print', 'game');
echo '</button><br>';
}
if ($showhtmlprintbutton) {
?>
<script>
function PrintHtmlClick() {
document.getElementById("printbutton").style.display = "none";
window.print();
document.getElementById("printbutton").style.display = "block";
}
function OnPrint() {
<?php
global $CFG;
$params = "id=$id&gameid=$game->id";
echo "window.open( \"{$CFG->wwwroot}/mod/game/print.php?$params\");";
?>
}
function OnEndGame() {
<?php
global $CFG;
$params = 'id='.$id.'&action=cryptexcheck&g=&finishattempt=1';
echo "window.location = \"{$CFG->wwwroot}/mod/game/attempt.php?$params\";\r\n";
?>
}
</script>
<?php
}
$i = 0;
$else = '';
$contextglossary = false;
foreach ($questions as $key => $q) {
$i++;
if ($showsolution == false) {
// When I want to show the solution a want to show the questions to.
if (array_key_exists( $q->id, $corrects)) {
continue;
}
}
$question = game_show_query( $game, $q, "$i. ".$q->questiontext, $context);
$question2 = strip_tags($question); // ADDED BY DP (AUG 2009) - fixes " breaking the Answer button for this question.
echo "<script>var msg{$q->id}=".json_encode( $question2).';</script>';
if (($onlyshow == false) and ($showsolution == false)) {
if (($game->param8 == 0) || ($game->param8 > $q->tries)) {
$question .= ' &nbsp;<input type="submit" value="'.
get_string( 'answer').'" onclick="OnCheck( '.$q->id.",msg{$q->id});\" />";
}
}
echo $question;
if ($showsolution) {
echo " &nbsp;&nbsp;&nbsp;$q->answertext<B></b>";
}
echo '<br>';
}
if ($game->bottomtext != '') {
echo '<br><br>'.$game->bottomtext;
}
?>
<script>
function OnCheck( id, question) {
document.getElementById("q").value = id;
document.getElementById("wordclue").innerHTML = question;
// Finally, show the answer box.
document.getElementById("answerbox").style.display = "block";
try {
document.getElementById("answer").focus();
document.getElementById("answer").select();
}
catch (e)
{
}
}
</script>
<?php
if ($print) {
echo '<body onload="window.print()">';
} else {
echo '<body>';
}
}
/**
* On finished.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $cryptexrec
*/
function game_cryptex_onfinished( $id, $game, $attempt, $cryptexrec) {
global $CFG, $DB;
if (! $cm = $DB->get_record( 'course_modules', array( 'id' => $id))) {
print_error( "Course Module ID was incorrect id=$id");
}
echo '<B>'.get_string( 'win', 'game').'</B><br>';
echo '<br>';
echo "<a href=\"{$CFG->wwwroot}/mod/game/attempt.php?id=$id&forcenew=1\">".
get_string( 'nextgame', 'game').'</a> &nbsp; &nbsp; &nbsp; &nbsp; ';
echo "<a href=\"{$CFG->wwwroot}/course/view.php?id=$cm->course\">".get_string( 'finish', 'game').'</a> ';
echo "<br><br>\r\n";
}

118
db/access.php

@ -0,0 +1,118 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Plugin capabilities
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
// Ability to see that the game exists, and the basic information about it, for example the start date and time limit.
'mod/game:view' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'guest' => CAP_ALLOW,
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
// Ability to do the game as a 'student'.
'mod/game:attempt' => array(
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'student' => CAP_ALLOW,
'guest' => CAP_ALLOW
)
),
// Ability for a 'Student' to review their previous attempts. Review by 'Teachers' is controlled by mod/game:viewreports.
'mod/game:reviewmyattempts' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'student' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/game:attempt'
),
// Edit the game settings, add and remove questions.
'mod/game:manage' => array(
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
// Edit the game overrides.
'mod/game:manageoverrides' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
// View the game reports.
'mod/game:viewreports' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
// Delete attempts using the overview report.
'mod/game:deleteattempts' => array(
'riskbitmask' => RISK_DATALOSS,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'mod/game:addinstance' => array(
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/course:manageactivities'
)
);

28
db/createsnakes.php

@ -0,0 +1,28 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Creates the snakes database.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require( "../../../config.php");
require_login();
execute_sql("truncate TABLE {game_snakes_database}");
require( "importsnakes.php");

82
db/importsnakes.php

@ -0,0 +1,82 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Imports the snakes database.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
game_importsnakes();
/**
* Imports the snakes database.
*/
function game_importsnakes() {
global $DB;
if ($DB->count_records( 'game_snakes_database') != 0) {
return;
}
$newrec = new stdClass();
$newrec->name = '8x8 - 4 Snakes - 4 Ladders';
$newrec->usedcols = 8;
$newrec->usedrows = 8;
$newrec->fileboard = 'fidaki.jpg';
$newrec->direction = 1;
$newrec->headerx = 4;
$newrec->headery = 4;
$newrec->footerx = 4;
$newrec->footery = 4;
$newrec->width = 487;
$newrec->height = 487;
$newrec->data = 'L3-18,S5-19,S8-27,L24-39,L29-53,S32-62,S41-58,L48-63';
game_importsnakes_do( $newrec);
$newrec = new stdClass();
$newrec->name = '6x6 - 3 Snakes - 3 Ladders';
$newrec->usedcols = 6;
$newrec->usedrows = 6;
$newrec->fileboard = 'fidaki2.jpg';
$newrec->direction = 1;
$newrec->headerx = 8;
$newrec->headery = 8;
$newrec->footerx = 8;
$newrec->footery = 8;
$newrec->width = 502;
$newrec->height = 436;
$newrec->data = 'L2-25,S4-23,L8-18,S16-20,L19-29,S27-33';
game_importsnakes_do( $newrec);
}
/**
* Insert one board to database
*
* @param stdClass $newrec
*/
function game_importsnakes_do( $newrec) {
global $DB;
if (!$DB->insert_record( 'game_snakes_database', $newrec)) {
print_error( "Can't insert to table game_snakes_database");
}
}

3554
db/importsudoku.php

File diff suppressed because it is too large

358
db/install.xml

@ -0,0 +1,358 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/game/db" VERSION="20160626" COMMENT="XMLDB file for Moodle mod/game"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd">
<TABLES>
<TABLE NAME="game" COMMENT="game">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="sourcemodule" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="timeopen" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timeclose" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="quizid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="glossaryid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="glossarycategoryid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="questioncategoryid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="bookid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="gamekind" TYPE="char" LENGTH="20" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param1" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param2" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param3" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param4" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param5" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param6" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param7" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param8" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param9" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param10" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="shuffle" TYPE="int" LENGTH="2" NOTNULL="false" DEFAULT="1" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="gameinputid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="toptext" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="bottomtext" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="grademethod" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="grade" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="decimalpoints" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="popup" TYPE="int" LENGTH="4" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="review" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="attempts" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="glossaryid2" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="glossarycategoryid2" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="language" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="subcategories" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="maxattempts" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="userlanguage" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="disablesummarize" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="glossaryonlyapproved" TYPE="int" LENGTH="1" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="completionattemptsexhausted" TYPE="int" LENGTH="1" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="completionpass" TYPE="int" LENGTH="1" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_attempts" COMMENT="game_attempts">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="gameid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="timestart" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timefinish" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timelastattempt" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="lastip" TYPE="char" LENGTH="30" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="lastremotehost" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="preview" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="attempt" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="score" TYPE="float" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="attempts" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="language" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="gameiduseridfinished" UNIQUE="false" FIELDS="gameid, userid, timefinish"/>
</INDEXES>
</TABLE>
<TABLE NAME="game_grades" COMMENT="game_grades">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="gameid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="score" TYPE="float" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
<INDEX NAME="gameid" UNIQUE="false" FIELDS="gameid"/>
</INDEXES>
</TABLE>
<TABLE NAME="game_queries" COMMENT="game_queries">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="attemptid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="gamekind" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="gameid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="sourcemodule" TYPE="char" LENGTH="20" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="glossaryentryid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="questiontext" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="score" TYPE="float" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="timelastattempt" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="studentanswer" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="col" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="row" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="horizontal" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="answertext" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="correct" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="attachment" TYPE="char" LENGTH="200" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="answerid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="tries" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="attemptid" UNIQUE="false" FIELDS="attemptid"/>
</INDEXES>
</TABLE>
<TABLE NAME="game_hangman" COMMENT="game_hangman">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="queryid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="letters" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="allletters" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="try" TYPE="int" LENGTH="4" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="maxtries" TYPE="int" LENGTH="4" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="finishedword" TYPE="int" LENGTH="4" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="corrects" TYPE="int" LENGTH="4" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="iscorrect" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_cross" COMMENT="game_cross">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="usedcols" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="usedrows" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="words" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="wordsall" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="createscore" TYPE="float" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="createtries" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="createtimelimit" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="createconnectors" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="createfilleds" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="createspaces" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="triesplay" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_cryptex" COMMENT="game_cryptex">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="letters" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_millionaire" COMMENT="game_millionaire">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="queryid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="state" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="level" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_sudoku" COMMENT="game_sudoku">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="level" TYPE="int" LENGTH="4" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="data" TYPE="char" LENGTH="81" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="opened" TYPE="int" LENGTH="4" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="guess" TYPE="char" LENGTH="81" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_sudoku_database" COMMENT="game_sudoku_database">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="level" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="opened" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="data" TYPE="char" LENGTH="81" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="data" UNIQUE="true" FIELDS="data"/>
</INDEXES>
</TABLE>
<TABLE NAME="game_bookquiz" COMMENT="game_bookquiz">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="lastchapterid" TYPE="char" LENGTH="81" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_bookquiz_chapters" COMMENT="game_bookquiz_chapters">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="attemptid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="chapterid" TYPE="char" LENGTH="81" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="attemptidchapterid" UNIQUE="false" FIELDS="attemptid, chapterid"/>
</INDEXES>
</TABLE>
<TABLE NAME="game_bookquiz_questions" COMMENT="game_bookquiz">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="gameid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="chapterid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="questioncategoryid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="gameidchapterid" UNIQUE="false" FIELDS="gameid, chapterid"/>
</INDEXES>
</TABLE>
<TABLE NAME="game_export_javame" COMMENT="game_export_javame">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="filename" TYPE="char" LENGTH="20" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="icon" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="createdby" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="vendor" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="name" TYPE="char" LENGTH="20" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="description" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="version" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="maxpicturewidth" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="maxpictureheight" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="type" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_export_html" COMMENT="game_export_html">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="filename" TYPE="char" LENGTH="30" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="title" TYPE="char" LENGTH="200" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="checkbutton" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="printbutton" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="inputsize" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="maxpicturewidth" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="maxpictureheight" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="type" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_snakes" COMMENT="game_snakes">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="snakesdatabaseid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="position" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="queryid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="dice" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_snakes_database" COMMENT="game_snakes_database">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="usedcols" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="usedrows" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="data" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="fileboard" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="direction" TYPE="int" LENGTH="2" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="headerx" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="headery" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="footerx" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="footery" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="width" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="height" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_course" COMMENT="game_course">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="messagewin" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="messageloose" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_course_inputs" COMMENT="game_course_inputs">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="sourcemodule" TYPE="char" LENGTH="20" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="ids" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_hiddenpicture" COMMENT="game_hiddenpicture">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="correct" TYPE="int" LENGTH="4" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="wrong" TYPE="int" LENGTH="4" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="found" TYPE="int" LENGTH="4" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="game_repetitions" COMMENT="game_repetitions">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="gameid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="glossaryentryid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="repetitions" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="main" UNIQUE="true" FIELDS="gameid, userid, questionid, glossaryentryid"/>
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>

1728
db/upgrade.php

File diff suppressed because it is too large

BIN
docs/Readme_en.pdf

Binary file not shown.

BIN
docs/database.pdf

Binary file not shown.

1048
docs/database.xmi

File diff suppressed because it is too large

BIN
docs/readme_el.pdf

Binary file not shown.

338
export.php

@ -0,0 +1,338 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page exports a game to another platform e.g. html, jar
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(dirname(__FILE__) . '/../../config.php');
ob_start();
require_once( "headergame.php");
require_login($course->id, false, $cm);
$context = game_get_context_module_instance( $cm->id);
require_capability('mod/game:view', $context);
require_once( $CFG->dirroot.'/lib/formslib.php');
require_login($course->id, false, $cm);
if (!has_capability('mod/game:viewreports', $context)) {
return;
}
$target = optional_param('target', "", PARAM_ALPHANUM); // The target is HTML or JavaMe.
/**
* The mod_game_exporthtml_form show the export form.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_game_exporthtml_form extends moodleform {
/**
* Definition of form.
*/
public function definition() {
global $CFG, $game;
$mform = $this->_form;
$html = $this->_customdata['html'];
$mform->addElement('header', 'general', get_string('general', 'form'));
if ( $game->gamekind == 'hangman') {
$options = array();
$options[ '0'] = 'Hangman with phrases';
$options[ 'hangmanp'] = 'Hangman with pictures';
$mform->addElement('select', 'type', get_string('javame_type', 'game'), $options);
if ( $html->type == 0) {
$mform->setDefault('type', '0');
} else {
$mform->setDefault('type', 'hangmanp');
}
}
// Input the filename.
$mform->addElement('text', 'filename', get_string('javame_filename', 'game'), array('size' => '30'));
$mform->setDefault('filename', $html->filename);
$mform->setType('filename', PARAM_TEXT);
// Input the html title.
$mform->addElement('text', 'title', get_string('html_title', 'game'), array('size' => '80'));
$mform->setDefault('title', $html->title);
$mform->setType('title', PARAM_TEXT);
// Inputs special fields for hangman.
if ($game->gamekind == 'hangman') {
$mform->addElement('text', 'maxpicturewidth', get_string('javame_maxpicturewidth', 'game'), array('size' => '5'));
$mform->setDefault('maxpicturewidth', $html->maxpicturewidth);
$mform->setType('maxpicturewidth', PARAM_INT);
$mform->addElement('text', 'maxpictureheight', get_string('javame_maxpictureheight', 'game'), array('size' => '5'));
$mform->setDefault('maxpictureheight', $html->maxpictureheight);
$mform->setType('maxpictureheight', PARAM_INT);
}
// Input special fields for crossword.
if ( $game->gamekind == 'cross') {
$mform->addElement('selectyesno', 'checkbutton', get_string('html_hascheckbutton', 'game'));
$mform->setDefault('checkbutton', $html->checkbutton);
$mform->addElement('selectyesno', 'printbutton', get_string('html_hasprintbutton', 'game'));
$mform->setDefault('printbutton', $html->printbutton);
}
$mform->addElement('hidden', 'q', $game->id);
$mform->setType('q', PARAM_INT);
$mform->addElement('hidden', 'target', 'html');
$mform->setType('target', PARAM_TEXT);
$mform->addElement('submit', 'submitbutton', get_string( 'export', 'game'));
$mform->closeHeaderBefore('submitbutton');
}
/**
* Validation of form.
*
* @param stdClass $data
* @param stdClass $files
*
* @return errors
*/
public function validation($data, $files) {
global $CFG, $USER, $DB;
$errors = parent::validation($data, $files);
return $errors;
}
/**
* Do the exporting.
*/
public function export() {
global $game, $DB;
$mform = $this->_form;
$html = new stdClass();
$html->id = $this->_customdata['html']->id;
$html->type = optional_param('type', 0, PARAM_ALPHANUM);
$html->filename = $mform->getElementValue('filename');
$html->title = $mform->getElementValue('title');
$html->maxpicturewidth = optional_param('maxpicturewidth', 0, PARAM_INT);
$html->maxpictureheight = optional_param('maxpictureheight', 0, PARAM_INT);
if ( $mform->elementExists( 'checkbutton')) {
$checkbuttonvalue = $mform->getElementValue('checkbutton');
$html->checkbutton = $checkbuttonvalue[ 0];
}
if ( $mform->elementExists( 'printbutton')) {
$printbuttonvalue = $mform->getElementValue('printbutton');
$html->printbutton = $printbuttonvalue[ 0];
}
if (!($DB->update_record( 'game_export_html', $html))) {
print_error("game_export_html: not updated id=$html->id");
}
$cm = get_coursemodule_from_instance('game', $game->id, $game->course);
$context = game_get_context_module_instance( $cm->id);
require_once("export/exporthtml.php");
game_OnExportHTML( $game, $context, $html);
}
}
/**
* The mod_game_exportjavame_form show the export form.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_game_exportjavame_form extends moodleform {
/**
* Definition of form.
*/
public function definition() {
global $CFG, $DB, $game;
$mform = $this->_form;
$javame = $this->_customdata['javame'];
$mform->addElement('header', 'general', get_string('general', 'form'));
if ( $game->gamekind == 'hangman') {
$options = array();
$options[ '0'] = 'Hangman with phrases';
$options[ 'hangmanp'] = 'Hangman with pictures';
$mform->addElement('select', 'type', get_string('javame_type', 'game'), $options);
}
$mform->addElement('text', 'filename', get_string('javame_filename', 'game'), array('size' => '30'));
$mform->setDefault('filename', $javame->filename);
$mform->setType('filename', PARAM_TEXT);
$mform->addElement('text', 'icon', get_string('javame_icon', 'game'));
$mform->setDefault('icon', $javame->icon);
$mform->setType('icon', PARAM_TEXT);
$mform->addElement('text', 'createdby', get_string('javame_createdby', 'game'));
$mform->setDefault('createdby', $javame->createdby);
$mform->setType('createdby', PARAM_TEXT);
$mform->addElement('text', 'vendor', get_string('javame_vendor', 'game'));
$mform->setDefault('vendor', $javame->vendor);
$mform->setType('vendor', PARAM_TEXT);
$mform->addElement('text', 'name', get_string('javame_name', 'game'), array('size' => '80'));
$mform->setDefault('name', $javame->name);
$mform->setType('name', PARAM_TEXT);
$mform->addElement('text', 'description', get_string('javame_description', 'game'), array('size' => '80'));
$mform->setDefault('description', $javame->description);
$mform->setType('description', PARAM_TEXT);
$mform->addElement('text', 'version', get_string('javame_version', 'game'), array('size' => '10'));
$mform->setDefault('version', $javame->version);
$mform->setType('version', PARAM_TEXT);
$mform->addElement('text', 'maxpicturewidth', get_string('javame_maxpicturewidth', 'game'), array('size' => '5'));
$mform->setDefault('maxpicturewidth', $javame->maxpicturewidth);
$mform->setType('maxpicturewidth', PARAM_INT);
$mform->addElement('text', 'maxpictureheight', get_string('javame_maxpictureheight', 'game'), array('size' => '5'));
$mform->setDefault('maxpictureheight', $javame->maxpictureheight);
$mform->setType('maxpictureheight', PARAM_INT);
$mform->addElement('hidden', 'q', $game->id);
$mform->setType('q', PARAM_INT);
$mform->addElement('hidden', 'target', 'javame');
$mform->setType('target', PARAM_TEXT);
$mform->addElement('submit', 'submitbutton', get_string( 'export', 'game'));
$mform->closeHeaderBefore('submitbutton');
}
/**
* Validation of form.
*
* @param stdClass $data
* @param stdClass $files
*
* @return errors
*/
public function validation($data, $files) {
global $CFG, $USER, $DB;
$errors = parent::validation($data, $files);
return $errors;
}
/**
* Do the exporting.
*/
public function export() {
global $game, $DB;
$mform = $this->_form;
$javame = $this->_customdata['javame'];
$javame->type = optional_param('type', 0, PARAM_ALPHANUM);
$javame->filename = $mform->getElementValue('filename');
$javame->icon = $mform->getElementValue('icon');
$javame->createdby = $mform->getElementValue('createdby');
$javame->vendor = $mform->getElementValue('vendor');
$javame->name = $mform->getElementValue('name');
$javame->description = $mform->getElementValue('description');
$javame->version = $mform->getElementValue('version');
$javame->maxpicturewidth = $mform->getElementValue('maxpicturewidth');
$javame->maxpictureheight = $mform->getElementValue('maxpictureheight');
if (!($DB->update_record( 'game_export_javame', $javame))) {
print_error("game_export_javame: not updated id=$javame->id");
}
require_once("export/exportjavame.php");
game_OnExportJavaME( $game, $javame);
}
}
// Creates form and set initial data.
if ($target == 'html') {
$html = $DB->get_record( 'game_export_html', array( 'id' => $game->id));
if ($html == false) {
$html = new stdClass();
$html->id = $game->id;
$html->checkbutton = 1;
$html->printbutton = 1;
game_insert_record( 'game_export_html', $html);
$html = $DB->get_record( 'game_export_html', array( 'id' => $game->id));
}
$html->type = 0;
$mform = new mod_game_exporthtml_form(null, array('id' => $id, 'html' => $html));
} else {
$javame = $DB->get_record( 'game_export_javame', array( 'id' => $game->id));
if ($javame == false) {
$javame = new stdClass();
$javame->id = $game->id;
$javame->filename = $game->gamekind;
game_insert_record( 'game_export_javame', $javame);
$javame = $DB->get_record( 'game_export_javame', array( 'id' => $game->id));
}
$mform = new mod_game_exportjavame_form(null, array('id' => $id, 'javame' => $javame));
}
if ($mform->is_cancelled()) {
ob_end_flush();
if ($id) {
redirect("view.php?id=$cm->id&amp;mode=entry&amp;hook=$id");
} else {
redirect("view.php?id=$cm->id");
}
} else if ($entry = $mform->get_data()) {
$mform->export();
} else {
ob_end_flush();
if (!empty($id)) {
$PAGE->navbar->add(get_string('export', 'game'));
}
$mform->display();
}
echo $OUTPUT->footer();
/**
* Sends via html a file.
*
* @param string $file
*/
function game_send_stored_file($file) {
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
} else {
print_error("export.php: File does not exists ".$file);
}
}

497
export/exporthtml.php

@ -0,0 +1,497 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page export the game to html for games: cross, hangman
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once( "locallib.php");
require_once( "exportjavame.php");
/**
* Exports to html.
*
* @param stdClass $game
* @param stdClass $context
* @param string $html
*/
function game_onexporthtml( $game, $context, $html) {
global $CFG;
$destdir = game_export_createtempdir();
switch( $game->gamekind) {
case 'cross';
game_onexporthtml_cross( $game, $context, $html, $destdir);
break;
case 'hangman':
game_onexporthtml_hangman( $game, $context, $html, $destdir);
break;
case 'snakes':
game_onexporthtml_snakes( $game, $html, $destdir, $context);
break;
case 'millionaire':
game_onexporthtml_millionaire( $game, $context, $html, $destdir);
break;
}
remove_dir( $destdir);
}
/**
* Exports cross to html.
*
* @param stdClass $game
* @param stdClass $context
* @param string $html
* @param string $destdir
*/
function game_onexporthtml_cross( $game, $context, $html, $destdir) {
global $CFG, $DB;
if ( $html->filename == '') {
$html->filename = 'cross';
}
$filename = $html->filename . '.htm';
require( "cross/play.php");
$attempt = game_getattempt( $game, $crossrec, true);
if ( $crossrec == false) {
game_cross_new( $game, $attempt->id, $crossm);
$attempt = game_getattempt( $game, $crossrec);
}
$ret = game_export_printheader( $html->title);
echo "$ret<br>";
ob_start();
game_cross_play( 0, $game, $attempt, $crossrec, '', true, false, false, false,
$html->checkbutton, true, $html->printbutton, false, $context);
$outputstring = ob_get_contents();
ob_end_clean();
$course = $DB->get_record( 'course', array( 'id' => $game->course));
$filename = $html->filename . '.htm';
file_put_contents( $destdir.'/'.$filename, $ret . "\r\n" . $outputstring);
$filename = game_onexporthtml_cross_repair_questions( $game, $context, $filename, $destdir);
game_send_stored_file( $filename);
}
/**
* Repairs questions.
*
* @param stdClass $game
* @param stdClass $context
* @param string $filename
* @param string $destdir
*/
function game_onexporthtml_cross_repair_questions( $game, $context, $filename, $destdir) {
global $CFG, $DB;
$filehandle = fopen( $destdir.'/'.$filename, "rb");
$found = false;
$files = array();
$contextcourse = false;
$linesbefore = array();
$linesafter = array();
while (!feof($filehandle) ) {
$line = fgets( $filehandle);
if ($found) {
if ( strpos( $line, 'new Array')) {
$linesafter[] = $line;
break;
}
$array .= $line;
continue;
}
if (strpos( $line, 'Clue = new Array') === false) {
$linesbefore[] = $line;
continue;
}
$array = $line;
$found = true;
}
while (!feof($filehandle) ) {
$linesafter[] = fgets( $filehandle);
}
fclose($filehandle);
$search = $CFG->wwwroot.'/pluginfile.php';
$pos = 0;
$search = '"'.$CFG->wwwroot.'/pluginfile.php/'.$context->id.'/mod_game/';
$len = strlen( $search);
$start = 0;
$filescopied = false;
for (;;) {
$pos1 = strpos( $array, $search, $start);
if ( $pos1 == false) {
break;
}
$pos2 = strpos( $array, '\"', $pos1 + $len);
if ( $pos2 == false) {
break;
}
// Have to copy the files.
if ($contextcourse === false) {
mkdir( $destdir.'/images');
if (!$contextcourse = get_context_instance(CONTEXT_COURSE, $game->course)) {
print_error('nocontext');
}
$fs = get_file_storage();
}
$inputs = explode( '/', substr( $array, $pos1 + $len, $pos2 - $pos1 - $len));
$filearea = $inputs[ 0];
$id = $inputs[ 1];
$fileimage = urldecode( $inputs[ 2]);
$component = 'question';
$params = array( 'component' => $component, 'filearea' => $filearea,
'itemid' => $id, 'filename' => $fileimage, 'contextid' => $context, 'contextid' => $contextcourse->id);
$rec = $DB->get_record( 'files', $params);
if ( $rec == false) {
break;
}
if (!$file = $fs->get_file_by_hash($rec->pathnamehash) or $file->is_directory()) {
continue;
}
$posext = strrpos( $fileimage, '.');
$filenoext = substr( $fileimage, $posext);
$ext = substr( $fileimage, $posext + 1);
for ($i = 0;; $i++) {
$newfile = $filenoext.$i;
$newfile = md5( $newfile).'.'.$ext;
if (!array_search( $newfile, $files)) {
break;
}
}
$file->copy_content_to( $destdir.'/images/'.$newfile);
$filescopied = true;
$array = substr( $array, 0, $pos1 + 1).'images/'.$newfile.substr( $array, $pos2);
}
if ($filescopied == false) {
return $destdir.'/'.$filename;
}
$linesbefore[] = $array;
foreach ($linesafter as $line) {
$linesbefore [] = $line;
}
file_put_contents( $destdir.'/'.$filename, $linesbefore);
$pos = strrpos( $filename, '.');
if ($pos === false) {
$filezip = $filename.'.zip';
} else {
$filezip = substr( $filename, 0, $pos).'.zip';
}
$filezip = game_create_zip( $destdir, $game->course, $filezip);
return $filezip;
}
/**
* Prints the header.
*
* @param string $title
* @param boolean $showbody
] */
function game_export_printheader( $title, $showbody=true) {
$ret = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n";
$ret .= '<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="el" xml:lang="el">'."\n";
$ret .= "<head>\n";
$ret .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'."\n";
$ret .= '<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">'."\n";
$ret .= "<title>$title</title>\n";
$ret .= "</head>\n";
if ($showbody) {
$ret .= "<body>";
}
return $ret;
}
/**
* Exports to html a hangman game.
*
* @param stdClass $game
* @param stdClass $context
* @param string $html
* @param string $destdir
*/
function game_onexporthtml_hangman( $game, $context, $html, $destdir) {
global $CFG, $DB;
if ($html->filename == '') {
$html->filename = 'hangman';
}
if ($game->param10 <= 0) {
$game->param10 = 6;
}
$filename = $html->filename . '.htm';
$ret = game_export_printheader( $html->title, false);
$ret .= "\r<body onload=\"reset()\">\r";
$exportattachment = ( $html->type == 'hangmanp');
$map = game_exmportjavame_getanswers( $game, $context, $exportattachment, $destdir, $files);
if ($map == false) {
print_error( get_string('no_words', 'game'));
}
ob_start();
// Here is the code of hangman.
require_once( "exporthtml_hangman.php");
$outputstring = ob_get_contents();
ob_end_clean();
$courseid = $game->course;
$course = $DB->get_record( 'course', array( 'id' => $courseid));
$filename = $html->filename . '.htm';
file_put_contents( $destdir.'/'.$filename, $ret . "\r\n" . $outputstring);
if ($html->type != 'hangmanp') {
// Not copy the standard pictures when we use the "Hangman with pictures".
$src = $CFG->dirroot.'/mod/game/pix/hangman/1';
$handle = opendir( $src);
while (false !== ($item = readdir($handle))) {
if ($item != '.' && $item != '..') {
if (!is_dir($src.'/'.$item)) {
$itemdest = $item;
if ( strpos( $item, '.') === false) {
continue;
}
copy( $src.'/'.$item, $destdir.'/'.$itemdest);
}
}
}
}
$filezip = game_create_zip( $destdir, $courseid, $html->filename.'.zip');
game_send_stored_file( $filezip);
}
/**
* Exports to html.
*
* @param stdClass $game
* @param stdClass $context
* @param string $html
* @param string $destdir
*/
function game_onexporthtml_millionaire( $game, $context, $html, $destdir) {
global $CFG, $DB;
if ($html->filename == '') {
$html->filename = 'millionaire';
}
$filename = $html->filename . '.htm';
$ret = game_export_printheader( $html->title, false);
$ret .= "\r<body onload=\"Reset();\">\r";
// Here is the code of millionaire.
require( "exporthtml_millionaire.php");
$questions = game_millionaire_html_getquestions( $game, $context, $maxanswers, $maxquestions, $retfeedback, $destdir, $files);
ob_start();
game_millionaire_html_print( $game, $questions, $maxanswers);
// End of millionaire code.
$outputstring = ob_get_contents();
ob_end_clean();
$courseid = $game->course;
$course = $DB->get_record( 'course', array( 'id' => $courseid));
$filename = $html->filename . '.htm';
file_put_contents( $destdir.'/'.$filename, $ret . "\r\n" . $outputstring);
// Copy the standard pictures of Millionaire.
$src = $CFG->dirroot.'/mod/game/pix/millionaire/1';
$handle = opendir( $src);
while (false !== ($item = readdir($handle))) {
if ($item != '.' && $item != '..') {
if (!is_dir($src.'/'.$item)) {
$itemdest = $item;
if (strpos( $item, '.') === false) {
continue;
}
copy( $src.'/'.$item, $destdir.'/'.$itemdest);
}
}
}
$filezip = game_create_zip( $destdir, $courseid, $html->filename.'.zip');
game_send_stored_file($filezip);
}
/**
* Exports to html a "Snakes and Ladders" game.
*
* @param stdClass $game
* @param string $html
* @param string $destdir
* @param stdClass $context
*/
function game_onexporthtml_snakes( $game, $html, $destdir, $context) {
require_once( "exporthtml_millionaire.php");
global $CFG, $DB;
if ($html->filename == '') {
$html->filename = 'snakes';
}
$filename = $html->filename . '.htm';
$ret = '';
$board = game_snakes_get_board( $game);
if ( ($game->sourcemodule == 'quiz') or ($game->sourcemodule == 'question')) {
$questionsm = game_millionaire_html_getquestions( $game, $context, $maxquestions,
$countofquestionsm, $retfeedback, $destdir, $files);
} else {
$questionsm = array();
$countofquestionsm = 0;
$retfeedback = '';
}
$questionss = game_exmportjavame_getanswers( $game, $context, false, $destdir, $files);
ob_start();
// Here is the code of Snakes and Ladders.
require( "exporthtml_snakes.php");
$outputstring = ob_get_contents();
ob_end_clean();
$courseid = $game->course;
$course = $DB->get_record( 'course', array( 'id' => $courseid));
$filename = $html->filename . '.htm';
file_put_contents( $destdir.'/'.$filename, $ret . "\r\n" . $outputstring);
$src = $CFG->dirroot.'/mod/game/export/html/snakes';
game_copyfiles( $src, $destdir);
mkdir( $destdir .'/css');
$src = $CFG->dirroot.'/mod/game/export/html/snakes/css';
game_copyfiles( $src, $destdir.'/css');
mkdir( $destdir .'/js');
$src = $CFG->dirroot.'/mod/game/export/html/snakes/js';
game_copyfiles( $src, $destdir.'/js');
unzip_file($destdir.'/js/js.zip', $destdir.'/js', false);
unlink( $destdir.'/js/js.zip');
mkdir( $destdir .'/images');
$destfile = $destdir.'/images/'.$board->fileboard;
if ( $game->param3 != 0) {
// Is a standard board.
copy( $board->imagesrc, $destfile);
} else {
$cmg = get_coursemodule_from_instance('game', $game->id, $game->course);
$modcontext = get_context_instance(CONTEXT_MODULE, $cmg->id);
$fs = get_file_storage();
$files = $fs->get_area_files($modcontext->id, 'mod_game', 'snakes_board', $game->id);
foreach ($files as $f) {
if ( $f->is_directory()) {
continue;
}
break;
}
$f->copy_content_to( $destfile);
}
$a = array( 'player1.png', 'dice1.png', 'dice2.png', 'dice3.png', 'dice4.png', 'dice5.png', 'dice6.png', 'numbers.png');
foreach ($a as $file) {
copy( $CFG->dirroot.'/mod/game/snakes/1/'.$file, $destdir.'/images/'.$file);
}
$filezip = game_create_zip( $destdir, $courseid, $html->filename.'.zip');
game_send_stored_file($filezip);
}
/**
* Copy files from source directory to dest directory.
*
* @param string $src
* @param string $destdir
*/
function game_copyfiles( $src, $destdir) {
$handle = opendir( $src);
while (($item = readdir($handle)) !== false) {
if ( $item == '.' or $item == '..') {
continue;
}
if ( strpos( $item, '.') === false) {
continue;
}
if (is_dir($src.'/'.$item)) {
continue;
}
copy( $src.'/'.$item, $destdir.'/'.$item);
}
closedir($handle);
}

373
export/exporthtml_hangman.php

@ -0,0 +1,373 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page export the game hangman to html
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
?>
<script type="text/javascript">
// Hangman for Moodle by Vasilis Daloukas.
// The script is based on HangMan II script- By Chris Fortey (http://www.c-g-f.net/)
var can_play = true;
<?php
$destdir = game_export_createtempdir();
$exportattachment = ( $html->type == 'hangmanp');
$map = game_exmportjavame_getanswers( $game, $context, $exportattachment, $destdir, $files);
if ($map == false) {
print_error( 'No Questions');
}
$questions = '';
$words = '';
$lang = '';
$allletters = '';
$images = '';
foreach ($map as $line) {
$answer = game_upper( $line->answer);
if ($game->param7) {
// Have to delete space.
$answer = str_replace(' ', '', $answer);
}
if ($game->param8) {
// Have to deletε -.
$answer = str_replace('-', '', $answer);
}
if ($lang == '') {
$lang = $game->language;
if ($lang == '') {
$lang = game_detectlanguage( $answer);
}
if ($lang == '') {
$lang = current_language();
}
$allletters = game_getallletters( $answer, $lang);
}
if (game_getallletters( $answer, $lang) != $allletters) {
continue;
}
if ($html->type == 'hangmanp') {
$file = $line->attachment;
$pos = strrpos( $file, '.');
if ($pos == false) {
continue;
}
}
if ($html->type == 'hangmanp') {
$src = $line->attachment;
$pos = strrpos( $file, '.');
if ($pos == false) {
continue;
}
}
if ($questions != '') {
$questions .= ', ';
}
if ($words != '') {
$words .= ', ';
}
$questions .= '"'.base64_encode( $line->question).'"';
$words .= '"'.base64_encode( $line->answer).'"';
if ($html->type == 'hangmanp') {
$file = $line->id.substr( $file, $pos);
game_export_javame_smartcopyimage( $src, $destdir.'/'.$file, $html->maxpicturewidth, $html->maxpictureheight);
if ($images != '') {
$images .= ', ';
}
$images .= '"'.$file.'"';
}
}
if ($game->param7) {
$allletters .= '_';
}
if ($game->param8) {
$allletters .= '-';
}
echo "var questions = new Array($questions);\r";
echo "var words = new Array($words);\r";
if ($html->type == 'hangmanp') {
echo "var images = new Array($images);\r";
}
?>
var to_guess = "";
var display_word = "";
var used_letters = "";
var wrong_guesses = 0;
var used_letters_all = "";
var all_letters = new Array(<?php
$len = game_strlen( $allletters);
for ($i = 0; $i < $len; $i++) {
if ($i > 0) {
echo ',';
}
echo '"'.game_substr( $allletters, $i, 1).'"';
}
?>);
function selectLetter(l)
{
if (can_play == false)
{
}
if (used_letters.indexOf(l) != -1)
{
return;
}
used_letters_all += l;
if( to_guess.indexOf(l) == -1) {
used_letters += l;
document.getElementById('usedLetters').innerHTML = used_letters;
}
if (to_guess.indexOf(l) != -1) {
// correct letter guess
pos = 0;
temp_mask = display_word;
while (to_guess.indexOf(l, pos) != -1) {
pos = to_guess.indexOf(l, pos);
end = pos + 1;
start_text = temp_mask.substring(0, pos);
end_text = temp_mask.substring(end, temp_mask.length);
temp_mask = start_text + l + end_text;
pos = end;
}
display_word = temp_mask;
document.getElementById('displayWord').innerHTML=display_word;
if (display_word.indexOf("#") == -1) {
// won
alert( "<?php echo game_get_string_lang( 'win', 'mod_game', $lang); ?>");
can_play = false;
reset();
}
} else {
wrong_guesses++;
<?php
if ($html->type != 'hangmanp') {
?>eval("document.hm.src=\"hangman_" + wrong_guesses + ".jpg\"");
// Ιncortect letter guess.
eval("document.hm.src=\"hangman_" + wrong_guesses + ".jpg\"");
<?php
}
?>
if (wrong_guesses == <?php echo $game->param10 + 1;?>) {
// lost
alert( "<?php echo strip_tags( game_get_string_lang( 'hangman_loose', 'mod_game', $lang)); ?>");
can_play = false;
reset();
}
}
showallletters();
}
function stripHTML(oldString) {
return oldString.replace(/<&#91;^>&#93;*>/g, "");
}
function reset() {
selectWord();
document.getElementById('usedLetters').innerHTML = "&nbsp;";
used_letters = "";
used_letters_all = "";
wrong_guesses = 0;
showallletters();
<?php
if ($html->type != 'hangmanp') {
echo ' document.hm.src="hangman_0.jpg"'."\r";
}
?>
}
function showallletters() {
var letters = "";
var next = all_letters.length / 4;
var letter = "";
for( i=0; i < all_letters.length; i++) {
if( i > next) {
next += all_letters.length / 4;
letters += " ";
}
letter = all_letters[ i];
if( used_letters_all.length > 0) {
if( used_letters_all.indexOf( letter) > -1) {
continue;
}
}
letters = letters + "<a href=\"javascript:selectLetter('" + letter + "');\">" + letter + "</a>"
}
document.getElementById( "letters").innerHTML = letters;
}
function selectWord() {
can_play = true;
random_number = Math.round(Math.random() * (words.length - 1));
to_guess = Base64.decode( words[random_number]);
to_question = Base64.decode( questions[random_number]);
// Display masked word.
masked_word = createMask(to_guess);
document.getElementById('displayWord').innerHTML=masked_word;
display_word = masked_word;
<?php
if ($html->type == 'hangmanp') {
echo " document.hm.src = images[ random_number];\r";
} else {
echo " document.getElementById('question').innerHTML=to_question;\r";
}
?>
}
function createMask(m)
{
mask = "";
word_lenght = m.length;
for (i = 0; i < word_lenght; i++) {
mask += "#";
}
return mask;
}
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// Private property.
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// Public method for decoding.
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// Private method for UTF-8 decoding.
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
</script>
</head>
<div id="question"></div>
<img src="<?php echo ($html->type == 'hangmanp' ? '' : 'hangman_0.jpg');?>" name="hm">
<a href="javascript:reset();"><?php echo game_get_string_lang( 'html_hangman_new', 'mod_game', $lang); ?></a>
<form name="game">
<div id="displayWord"> </div>
<div id="usedLetters"> </div>
</form>
<div id="letters"></div>
</body>

537
export/exporthtml_millionaire.php

@ -0,0 +1,537 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page export the game millionaire to html
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Exports millionaire.
*
* @param stdClass $game
* @param stdClass $context
* @param int $maxanswers
* @param int $countofquestions
* @param string $retfeedback
* @param string $destdir
* @param array $files
*/
function game_millionaire_html_getquestions( $game, $context, &$maxanswers, &$countofquestions, &$retfeedback, $destdir, &$files) {
global $CFG, $DB, $USER;
$maxanswers = 0;
$countofquestions = 0;
$files = array();
if ( ($game->sourcemodule != 'quiz') and ($game->sourcemodule != 'question')) {
print_error( get_string('millionaire_sourcemodule_must_quiz_question', 'game', get_string( 'modulename', 'quiz')).
' '.get_string( 'modulename', $game->sourcemodule));
}
if ( $game->sourcemodule == 'quiz') {
if ( $game->quizid == 0) {
print_error( get_string( 'must_select_quiz', 'game'));
}
$select = "qtype='multichoice' AND quiz='$game->quizid' ".
" AND qqi.question=q.id";
$table = "{question} q,{quiz_question_instances} qqi";
} else {
if ( $game->questioncategoryid == 0) {
print_error( get_string( 'must_select_questioncategory', 'game'));
}
// Include subcategories.
$select = 'category='.$game->questioncategoryid;
if ( $game->subcategories) {
$cats = question_categorylist( $game->questioncategoryid);
if (strpos( $cats, ',') > 0) {
$select = 'category in ('.$cats.')';
}
}
$select .= " AND qtype='multichoice'";
$table = "{question} q";
}
$select .= " AND q.hidden=0";
$sql = "SELECT q.id as id, q.questiontext FROM $table WHERE $select";
$recs = $DB->get_records_sql( $sql);
$ret = '';
$retfeedback = '';
foreach ($recs as $rec) {
$recs2 = $DB->get_records( 'question_answers', array( 'question' => $rec->id), 'fraction DESC', 'id,answer,feedback');
// Must parse the questiontext and get the name of files.
$line = $rec->questiontext;
$line = game_export_split_files( $game->course, $context, 'questiontext', $rec->id, $rec->questiontext, $destdir, $files);
$linefeedback = '';
foreach ($recs2 as $rec2) {
$line .= '#'.str_replace( array( '"', '#'), array( "'", ' '),
game_export_split_files( $game->course, $context, 'answer', $rec2->id, $rec2->answer, $destdir, $files));
$linefeedback .= '#'.str_replace( array( '"', '#'), array( "'", ' '), $rec2->feedback);
}
if ( $ret != '') {
$ret .= ",\r";
}
$ret .= '"'.base64_encode( $line).'"';
if ( $retfeedback != '') {
$retfeedback .= ",\r";
}
$retfeedback .= '"'.base64_encode( $linefeedback).'"';
if ( count( $recs2) > $maxanswers) {
$maxanswers = count( $recs2);
}
$countofquestions++;
}
return $ret;
}
/**
* Exports to html a "Millionaire" game.
*
* @param stdClass $game
* @param string $questions
* @param int $maxquestions
*/
function game_millionaire_html_print( $game, $questions, $maxquestions) {
$color1 = 'black';
$color2 = 'DarkOrange';
$colorback = "white";
$stylequestion = "background:$colorback;color:$color1";
$stylequestionselected = "background:$colorback;color:$color2";
?>
<body onload="Reset();">
<script type="text/javascript">
// Millionaire for Moodle by Vasilis Daloukas.
<?php echo 'var questions = new Array('.$questions.");\r"; ?>
var current_question = 0;
var level = 0;
var posCorrect = 0;
var infoCorrect = "";
var flag5050 = 0;
var flagTelephone = 0;
var flagPeople = 0;
var countQuestions = 0;
var maxQuestions = <?php echo $maxquestions;?>;
function Highlite( ans) {
document.getElementById( "btAnswer" + ans).style.backgroundColor = '<?php echo $color2;?>';
}
function Restore( ans) {
document.getElementById( "btAnswer" + ans).style.backgroundColor = '<?php echo $colorback;?>';
}
function OnSelectAnswer( ans) {
if ( posCorrect == ans) {
if( level+1 > 15) {
alert( "<?php echo get_string( 'win', 'game');?>");
Reset();
} else {
UpdateLevel( level+1);
SelectNextQuestion();
}
} else {
OnGameOver( ans);
}
}
function OnGameOver( ans) {
document.getElementById( "info").innerHTML = "<?php echo get_string( 'millionaire_info_wrong_answer', 'game');?> " +
document.getElementById( "lblAnswer" + posCorrect).innerHTML;
Highlite( posCorrect);
Restore( ans);
document.getElementById( "lblAnswer" + posCorrect).style.backgroundColor = '<?php echo $color2;?>';
alert( "<?php echo strip_tags( get_string( 'hangman_loose', 'game')); ?>");
Restore( posCorrect);
document.getElementById( "lblAnswer" + posCorrect).style.backgroundColor = '<?php echo $colorback;?>';
Reset();
}
function UpdateLevel( newlevel) {
if ( level > 0) {
document.getElementById( "levela" + level).bgColor = "<?php echo $colorback;?>";
document.getElementById( "levelb" + level).bgColor = "<?php echo $colorback;?>";
document.getElementById( "levelc" + level).bgColor = "<?php echo $colorback;?>";
document.getElementById( "levela" + level).style.color = "<?php echo $color1;?>";
document.getElementById( "levelb" + level).style.color = "<?php echo $color1;?>";
document.getElementById( "levelc" + level).style.color = "<?php echo $color1;?>";
}
level = newlevel;
document.getElementById( "levela" + level).bgColor = "<?php echo $color2;?>";
document.getElementById( "levelb" + level).bgColor = "<?php echo $color2;?>";
document.getElementById( "levelc" + level).bgColor = "<?php echo $color2;?>";
document.getElementById( "levela" + level).style.color = "<?php echo $colorback;?>";
document.getElementById( "levelb" + level).style.color = "<?php echo $colorback;?>";
document.getElementById( "levelc" + level).style.color = "<?php echo $colorback;?>";
}
function OnHelp5050( ans) {
if (flag5050) {
return;
}
document.getElementById( "Help5050").src = "5050x.png";
flag5050 = 1;
for (pos = posCorrect;pos == posCorrect;pos = 1+Math.floor(Math.random()*countQuestions));
for (i=1; i <= countQuestions; i++) {
if( (i != pos) && (i != posCorrect)) {
document.getElementById( "lblAnswer" + i).style.visibility = 'hidden';
document.getElementById( "btAnswer" + i).style.visibility = 'hidden';
}
}
}
function OnHelpTelephone( ans) {
if( flagTelephone) {
return;
}
flagTelephone = 1;
document.getElementById( "HelpTelephone").src = "telephonex.png";
if (countQuestions < 2) {
wrong = posCorrect;
} else {
for(;;) {
wrong = 1 + Math.floor(Math.random() * countQuestions);
if ( wrong != posCorrect) {
break;
}
}
}
// With 80% gives the correct answer.
if (Math.random() <= 0.8) {
pos = posCorrect;
} else {
pos = wrong;
}
info = "<?php echo get_string( 'millionaire_info_telephone', 'game').'<br><b>';?> ";
info += document.getElementById( "lblAnswer" + pos).innerHTML;
document.getElementById( "info").innerHTML = info;
}
function OnHelpPeople( ans) {
if( flagPeople) {
return;
}
flagPeople = 1;
document.getElementById( "HelpPeople").src = "peoplex.png";
sum = 0;
var aPercent = new Array();
for( i = 0; i < countQuestions-1; i++) {
percent = Math.floor(Math.random()*(100-sum));
aPercent[ i] = percent;
sum += percent;
}
aPercent[ countQuestions - 1] = 100 - sum;
if( Math.random() <= 0.8) {
//with percent 80% sets in the correct answer the biggest percent
max_pos = 0;
for( i=1; i < countQuestions; i++) {
if( aPercent[ i] >= aPercent[ max_pos])
max_pos = i;
}
temp = aPercent[ max_pos];
aPercent[ max_pos] = aPercent[ posCorrect-1];
aPercent[ posCorrect-1] = temp;
}
var letters = "<?php echo get_string( 'lettersall', 'game');?>";
info = "<?php echo '<br>'.get_string( 'millionaire_info_people', 'game').':<br>';?>";
for( i=0; i < countQuestions; i++) {
info += "<br>" + letters.charAt( i) + " : " + aPercent[ i] + " %";
}
document.getElementById( "info").innerHTML = info;
}
function OnQuit( ans) {
Reset();
}
function Reset() {
for(i=1; i <= 15; i++) {
document.getElementById( "levela" + i).bgColor = "<?php echo $colorback;?>";
document.getElementById( "levelb" + i).bgColor = "<?php echo $colorback;?>";
document.getElementById( "levelc" + i).bgColor = "<?php echo $colorback;?>";
document.getElementById( "levela" + i).style.color = "<?php echo $color1;?>";
document.getElementById( "levelb" + i).style.color = "<?php echo $color1;?>";
document.getElementById( "levelc" + i).style.color = "<?php echo $color1;?>";
}
flag5050 = 0;
flagTelephone = 0;
flagPeople = 0;
document.getElementById( "Help5050").src = "5050.png";
document.getElementById( "HelpPeople").src = "people.png";
document.getElementById( "HelpTelephone").src = "telephone.png";
document.getElementById( "info").innerHTML = "";
UpdateLevel( 1);
SelectNextQuestion();
}
function RandomizeAnswers( elements) {
posCorrect = 1;
countQuestions = elements.length-1;
for( i=1; i <= countQuestions; i++) {
pos = 1+Math.floor(Math.random()*countQuestions);
if( posCorrect == i) {
posCorrect = pos;
} else if ( posCorrect == pos)
posCorrect = i;
var temp = elements[ i];
elements[ i] = elements[ pos];
elements[ pos] = temp;
}
}
function SelectNextQuestion() {
current_question = Math.floor(Math.random()*questions.length);
question = Base64.decode( questions[ current_question]);
var elements = new Array();
elements = question.split('#');
RandomizeAnswers( elements);
document.getElementById( "question").innerHTML = elements[ 0];
for( i=1; i < elements.length; i++) {
document.getElementById( "lblAnswer" + i).innerHTML = elements[ i];
document.getElementById( "lblAnswer" + i).style.visibility = 'visible';
document.getElementById( "btAnswer" + i).style.visibility = 'visible';
}
for( i=elements.length; i<= maxQuestions; i++) {
document.getElementById( "lblAnswer" + i).style.visibility = 'hidden';
document.getElementById( "btAnswer" + i).style.visibility = 'hidden';
}
document.getElementById( "info").innerHTML = "";
}
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// Private property.
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// Public method for decoding.
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
</script>
<table cellpadding=0 cellspacing=0 border=0>
<tr style='background:#408080'>
<td rowspan=<?php echo 17 + $maxquestions;?>>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td colspan=6>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td rowspan=<?php echo 17 + $maxquestions;?>>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
</tr>
<tr height=10%>
<td style='background:#408080' rowspan=3 colspan=2>
<input type="image" name="Help5050" id="Help5050" Title="50 50" src="5050.png" alt="" border="0" onmousedown=OnHelp5050();>&nbsp;
<input type="image" name="HelpTelephone" id="HelpTelephone" Title="<?php echo get_string( 'millionaire_telephone', 'game');?>"
src="telephone.png" alt="" border="0" onmousedown="OnHelpTelephone();">&nbsp;
<input type="image" name="HelpPeople" id="HelpPeople" Title="<?php echo get_string( 'millionaire_helppeople', 'game');?>"
src="people.png" alt="" border="0" onmousedown="OnHelpPeople();">&nbsp;
<input type="image" name="Quit" id="Quit" Title="<?php echo get_string( 'millionaire_quit', 'game');?>"
src="x.png" alt="" border="0" onmousedown=OnQuit();>&nbsp;
</td>
<td rowspan=<?php echo 16 + $maxquestions;?> style='background:#408080'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td id="levela15" align=right>15</td>
<td id="levelb15">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td id="levelc15" align=right> 150000</td>
</tr>
<tr><td id="levela14" align=right>14</td>
<td id="levelb14"></td><td id="levelc14" align=right> 800000</td>
</tr>
<tr><td id="levela13" align=right>13</td>
<td id="levelb13"></td><td id="levelc13" align=right> 400000</td>
</tr>
<tr><td rowspan=12 colspan=2 valign=top style='background:<?php echo $colorback;?>;color:<?php echo $color1;?>'>
<div id="question">aa</div></td>
<td id="levela12" align=r0ight>12</div></td>
<td id="levelb12"></td><td id="levelc12" align=right> 200000</td>
</tr>
<tr><td id="levela11" align=right>11</td>
<td id="levelb11"></td><td id="levelc11" align=right> 10000</td>
</tr>
<tr><td id="levela10" align=right>10</td>
<td id="levelb10"></td><td id="levelc10" align=right> 5000</td>
</tr>
<tr><td id="levela9" align=right>9</td>
<td id="levelb9"></td><td id="levelc9" align=right> 4000</td>
</tr>
<tr><td id="levela8" align=right>8</td>
<td id="levelb8"></td><td id="levelc8" align=right> 2000</td>
</tr>
<tr><td id="levela7" align=right>7</td>
<td id="levelb7"></td><td id="levelc7" align=right> 1500</td>
</tr>
<tr><td id="levela6" align=right>6</td>
<td id="levelb6"></td><td id="levelc6" align=right> 1000</td>
</tr>
<tr><td id="levela5" align=right>5</td>
<td id="levelb5"></td><td id="levelc5" align=right> 500</td>
</tr>
<tr><td id="levela4" align=right>4</td>
<td id="levelb4"></td><td id="levelc4" align=right> 400</td>
</tr>
<tr><td id="levela3" align=right>3</td>
<td id="levelb3"></td><td id="levelc3" align=right> 300</td>
</tr>
<tr><td id="levela2" align=right>2</td>
<td id="levelb2"></td><td id="levelc2" align=right> 200</td>
</tr>
<tr><td id="levela1" align=right>1</td>
<td id="levelb1"></td><td id="levelc1" align=right> 100</td>
</tr>
<tr style='background:#408080'><td colspan=10>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
</tr>
<?php
$letters = get_string( 'lettersall', 'game');
for ($i = 1; $i <= $maxquestions; $i++) {
$s = game_substr( $letters, $i - 1, 1);
echo "<tr>\n";
echo "<td style='background:$colorback;color:$color1'>";
echo "<input style=\"background:$colorback;color:$color1;\"
type=\"submit\" name=\"btAnswer$i\" value=\"$s\" id=\"btAnswer$i\"";
echo " onmouseover=\"Highlite( $i);\" onmouseout=\"Restore( $i);\" onmousedown=\"OnSelectAnswer( $i);\">";
echo "</td>\n";
echo "<td style=\"background:$colorback;color:$color1;\" width=100%> &nbsp; <span id=lblAnswer$i
style=\"background:$colorback;color:$color1\"
onmouseover=\"Highlite($i);\r \n\" onmouseout=\"Restore( $i);\" onmousedown=\"OnSelectAnswer( $i);\"></span></td>\n";
if ( $i == 1) {
echo "<td style='background:#408080' rowspan=".$maxquestions." colspan=3><div id=\"info\"></div></td>\n";
}
echo "</tr>\n";
}
?>
<tr><td colspan=10 style='background:#408080'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td></tr>
</table>
</body>
</html>
<?php
}

800
export/exporthtml_snakes.php

@ -0,0 +1,800 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page export the game snakes to html
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php echo $html->title;?></title>
<link href="css/game.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="css/subModal.css" />
<script type="text/javascript" src="js/common.js"></script>
<?php
createsubmodaljs();
?>
<style type="text/css">
#pawn
{
position:absolute;
}
img
{
border:hidden
}
body
{
background: #999 url('images/backdropJungle.png') no-repeat fixed left top;
}
.score {
color: #FC3;
font-size: 40px;
}
</style>
</head>
<body>
<script language="JavaScript">
// Snakes for Moodle by Maria Rigkou.
var boards = 1;
var board_images = new Array( boards);
var board_names = new Array( boards);
var pawn_width = new Array(boards);
var pawn_height = new Array(boards);
var board_cols = new Array(boards);
var board_rows = new Array(boards);
var board_contents = new Array (boards);
var board_headerx = new Array(boards);
var board_headery = new Array(boards);
var board_footerx = new Array(boards);
var board_footery = new Array(boards);
var board_width = new Array(boards);
var board_height = new Array(boards);
var board_data = new Array(boards);
var pawn_width = new Array(boards);
var pawn_height = new Array(boards);
var current_board = 0;
var current_position=0;
var current_quest = 0;
var mchoice_count = 0;
var mchoice_positions =new Array( 1);
var quest_text = ""; //Question
var quest_resp = ""; // Answer
var quest_feedb = ""; // feedback
var quest_total = 25; // Count of questions
board_images[ 0] = '<?php echo $board->fileboard; ?>';
board_names[ 0] = "<?php echo $game->name; ?>";
board_cols [0] = <?php echo $board->usedcols; ?>;
board_rows [0] = <?php echo $board->usedrows; ?>;
board_contents [0] = '<?php echo $board->data; ?>';
board_headerx [0] = <?php echo $board->headerx; ?>;
board_headery [0] = <?php echo $board->headery; ?>;
board_footerx [0] = <?php echo $board->footerx; ?>;
board_footery [0] = <?php echo $board->footery; ?>;
board_width [0] = <?php echo $board->width; ?>;
board_height [0] = <?php echo $board->height; ?>;
pawn_width [0] = 40;
pawn_height [0]= 40;
<?php
echo "var countofquestionsM=$countofquestionsm;\r\n";
echo 'var countofquestionsS='.count($questionss).";\r\n";
$questionsm = '';
foreach ($questionss as $line) {
$s = $line->question.'#'.str_replace( array( '"', '#'), array( "'", ' '), $line->answer);
if ($questionsm != '') {
$questionsm .= ",\r";
}
$questionsm .= '"'.base64_encode( game_upper( $s)).'"';
$s = '#'.str_replace( array( '"', '#'), array( "'", ' '), $line->feedback);
if ($retfeedback != '') {
$retfeedback .= ",\r";
}
$retfeedback .= '"'.base64_encode( $s).'"';
}
$rettimesasked = '';
for ($i = 0; $i < $countofquestionsm + count($questionss); $i++) {
$rettimesasked .= ',0';
}
$rettimesasked = substr( $rettimesasked, 1);
echo "var questions=new Array( $questionsm);\r\n";
echo "var feedbacks=new Array( $retfeedback);\r\n";
echo "var quest_times_asked=new Array( $rettimesasked); //How many times is used a question\r\n";
?>
var current_dice=0;
var feedb_correct_S = "<?php print_string( 'html_snakes_correct', 'game'); ?>";
var feedb_wrong_S = "<?php print_string( 'html_snakes_wrong', 'game'); ?>";
var str_score = "<?php print_string( 'score', 'game'); ?>";
var str_check = "<?php print_string( 'html_snakes_check', 'game'); ?>";
var str_no_selection = "<?php print_string( 'html_snakes_no_selection', 'game'); ?>";
var correct_ans = 0; //counter of correct answers
var all_ans = 0; //counter of all answers
var score = 0;
ShowMainForm();
display_quest();
function ShowMainForm()
{
var pawn_x =0;
var pawn_y=0;
var direction=0;
var cols = board_cols[current_board];
var rows = board_rows[current_board];
var col_width = (board_width[current_board]-board_headerx[current_board]-board_footerx[current_board])/cols;
var col_height = (board_height[current_board]-board_headery[current_board]-board_footery[current_board])/rows;
document.write('<img id="boardimage" src="images/' + board_images[ current_board] + '">');
document.write('<div id="dicecont">&nbsp;</div>');
if( current_position >= 0) {
direction=Math.floor((current_position /cols))%2;
if (direction == 1) {
axis_x=(cols-(current_position %cols)-1);
} else {
axis_x=current_position %cols;
}
axis_y=Math.floor((current_position /rows));
pawn_x=board_headerx[current_board]+(axis_x*col_width)+(col_width-pawn_width[current_board])/2;
pawn_y=board_footery[current_board]+pawn_height[current_board]+(axis_y*col_height);
pawn_y += (col_height-pawn_height[current_board])/2;
document.write('<div id="pawn1"><img id="pawn" alt="" src="images/player1.png"></div>');
move_pawn();
}
}
function select_quest() {
var quest_total = countofquestionsM + countofquestionsS;
var quest_candidates= new Array();
var i, q;
for (i=0;i<3;i++) {
quest_candidates[i]=Math.floor((Math.random() * quest_total));
}
current_quest = quest_candidates[0];
for (i=1;i<3;i++) {
if (quest_times_asked[quest_candidates[i]]>quest_times_asked[current_quest])
current_quest=quest_candidates[i];
}
q=Base64decode( questions[ current_quest]);
quest_resp = decode_multiple_choice( q);
quest_text = quest_resp[ 0];
quest_feedb = Base64decode( feedbacks[ current_quest]);
}
function IsMultipleChoiceQuestion() {
return (current_quest < countofquestionsM);
}
function check_answer() {
all_ans=all_ans+1;
if( IsMultipleChoiceQuestion()) {
check_answer_M();
} else {
check_answer_S();
}
move_pawn();
}
function check_answer_M() {
document.getElementById("check_btn").style.display = "none";
var useranswer;
var n=document.snakesform.radio_answer.length;
for(useranswer=0;useranswer < n;useranswer++) {
if( document.snakesform.radio_answer[ useranswer].checked)
break;
}
if( useranswer >= n) {
alert( str_no_selection);
document.getElementById("feedb").innerHTML= "";
document.getElementById("check_btn").style.display = "block";
return;
}
var feedbacks = decode_multiple_choice(quest_feedb);
var j;
for (j=0;j<n;j++) {
document.snakesform.radio_answer[ j].disabled = "true";
}
document.getElementById("feedb").innerHTML= feedbacks[ mchoice_positions[useranswer]];
document.getElementById("feedb").style.display = "block";
if ( mchoice_positions[ useranswer] == 1) {
current_position += current_dice;
correct_ans =correct_ans+1; //calculate new score----
score = Math.round((correct_ans/all_ans)*100);
var s = '<strong>'+str_score+': </strong><strong class="score">' +score+ '</strong>';
document.getElementById("show_score").innerHTML = s;
check_game_over();
check_exists_ladder();
} else {
score = Math.round((correct_ans/all_ans)*100);
var s = '<strong>'+str_score+': </strong><strong class="score">' +score+ '</strong>';
document.getElementById("show_score").innerHTML = s;
check_exists_snake();
}
document.getElementById("OK_btn").style.display = "block";
}
function check_answer_S() {
document.getElementById("answer").disabled = "true";
document.getElementById("check_btn").style.display = "none";
if (document.getElementById("answer").value.toUpperCase() == quest_resp[ 1].toUpperCase()) {
document.getElementById("feedb").style.display = "block";
current_position += current_dice;
correct_ans =correct_ans+1; //calculate new score
score = Math.round((correct_ans/all_ans)*100);
var s = '<strong>'+str_score+': </strong><strong class="score">' +score+ '</strong>';
document.getElementById("show_score").innerHTML = s;
check_game_over();
check_exists_ladder();
} else {
document.getElementById("feedb_wrong").style.display = "block";
score = Math.round((correct_ans/all_ans)*100);
var s = '<strong>'+str_score+': </strong><strong class="score">' +score+ '</strong>';
document.getElementById("show_score").innerHTML = s;
check_exists_snake();
}
document.getElementById("OK_btn").style.display = "block";
}
function check_game_over() {
var out=(board_cols[current_board]*board_rows[current_board]);
if (current_position > out-1) {
current_position=out-1;
showPopWin('modalContent.html', 350, 220, returnRefresh); // modal
}
}
function check_exists_ladder() {
var find = "L" + (current_position+1) + "-";
var pos = board_contents[ current_board].indexOf( find);
if( pos < 0) {
return;
}
var s = board_contents[ current_board].substr( pos+find.length)
pos = s.indexOf( ',');
if (pos >= 0) {
s = s.substr( 0, pos);
}
current_position = s-1;
}
function check_exists_snake() {
var find = "-" + (current_position+1) + ",";
var s= ',' +board_contents[ current_board] + ',';
for(;;) {
var pos = s.indexOf( find);
if (pos < 0) {
return;
}
var pos_start = s.lastIndexOf( ',', pos-1);
var kind = s.substr( pos_start+1, 1);
if ( kind != "S") {
s = s.substr( pos+1);
continue;
}
s = s.substr( pos_start+2);
pos = s.indexOf( '-');
current_position = s.substr( 0, pos)-1;
break;
}
}
function decode_multiple_choice(s) {
var ret = new Array();
var i=0;
for(;;) {
var pos=s.indexOf( '#');
if( pos < 0) {
ret[ i++] = s;
return ret;
}
ret[ i++] = s.substr( 0, pos);
s = s.substr( pos+1);
}
}
function display_quest() {
current_dice = Math.floor((Math.random() * 6)) + 1;
select_quest();
if( IsMultipleChoiceQuestion()) {
display_quest_M();
} else {
display_quest_S();
}
}
function display_quest_M() {
s = '<table width="250px"><tr><td><div id="show_dice"> ';
s = s + '<img src = "images/dice' + current_dice + '.png"> </div> </td>';
s = s + '<td align=right><div id="show_score" style="color: #FFFFFF; font-weight:bold; font-size: 20px;">';
s = s + '<strong>'+str_score+': </strong>';
s = s + '<strong class="score">' +score+ '</strong></div></td></tr></table>';
s = s + '<div id="question_area">' + quest_text+'</div>';
s = s + '<form name="snakesform">';
mchoice_count = quest_resp.length-1;
mchoice_positions = new Array( mchoice_count);
for(i=0; i < mchoice_count ; i++) {
mchoice_positions[ i] = i+1;
}
for(i=0; i < mchoice_count ; i++) {
var j = Math.floor((Math.random() * mchoice_count));
var temp = mchoice_positions[ i];
mchoice_positions[ i] = mchoice_positions[ j];
mchoice_positions[ j] = temp;
}
for(i=0; i < mchoice_count;i++) {
s = s + '<input type="radio" name="radio_answer" id="radio_answer" value="';
s = s + i+'" />'+quest_resp[ mchoice_positions[ i]] + '<br />';
}
s = s + '<br /><input type="button" id="check_btn" value="'+str_check;
s = s + '" onclick="check_answer();"> <br/><div id="feedb_area"> <div id="feedb_wrong" style="display:none; color:yellow;"> ';
s = s + quest_feedb+' </div> <br /><div id="feedb" style="display:none; color:yellow;"> ';
s = s + quest_feedb+'. Θα προχωρήσεις ';
s = s + current_dice+' τετράγωνα μπροστά!</div><br /> <div id="OK_btn"';
s = s + 'style="display:none;"><input type="button" onclick="display_quest();" value="OK"/></div> </div></form>';
document.getElementById("dicecont").innerHTML = s;
document.getElementById("question_area").style.display = "block";
document.getElementById("check_btn").style.display = "block";
}
function display_quest_S() {
var s = "";
s = '<table width="250px"><tr><td><div id="show_dice"> <img src = "images/dice';
s = s + current_dice + '.png"> </div> </td><td align=right>';
s = s + '<div id="show_score" style="color: #FFFFFF; font-weight:bold; font-size: 20px;"><strong>';
s = s + str_score+': </strong><strong class="score">' +score+ '</strong></div></td></tr></table><div id="question_area">';
s = s + quest_text+'</div> <br /><input type="text" id="answer"/><br /><br /> <input type="button" id="check_btn" value="';
s = s + str_check+'" onclick="check_answer();"> <br /> <div id="feedb_area">';
s = s + ' <div id="feedb_wrong" style="display:none; color:yellow;"> ';
s = s + feedb_wrong_S+' </div> <div id="feedb" style="display:none; color:yellow;"> ';
s = s + feedb_correct_S+'</div> <br /><div id="OK_btn" style="display:none;">';
s = s + '<input type="button" onclick="display_quest();" value="OK"/></div> </div>';
document.getElementById("dicecont").innerHTML = s;
document.getElementById("question_area").style.display = "block";
document.getElementById("check_btn").style.display = "block";
}
function move_pawn() {
var pawn_x =0;
var pawn_y=0;
var direction=0;
var cols = board_cols[current_board];
var rows = board_rows[current_board];
var col_width = (board_width[current_board]-board_headerx[current_board]-board_footerx[current_board])/cols;
var col_height = (board_height[current_board]-board_headery[current_board]-board_footery[current_board])/rows;
if( current_position >= 0) {
direction=Math.floor((current_position /cols))%2;
if (direction == 1) {
axis_x=(cols-(current_position %cols)-1);
} else {
axis_x=current_position %cols;
}
axis_y=Math.floor((current_position /rows));
pawn_x=board_headerx[current_board]+(axis_x*col_width)+(col_width-pawn_width[current_board])/2;
pawn_y = board_footery[current_board]+pawn_height[current_board]+(axis_y*col_height);
pawn_y += (col_height-pawn_height[current_board])/2;
document.getElementById("pawn1").style.position='relative';
document.getElementById("pawn1").style.left=pawn_x+'px';
document.getElementById("pawn1").style.bottom=pawn_y+'px';
}
}
function Base64decode(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64_utf8_decode(output);
return output;
};
// Private method for UTF-8 decoding.
function Base64_utf8_decode(utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
</script>
</body>
</html>
<?php
/**
* Javascript code
*/
function createsubmodaljs() {
?>
<script type="text/javascript" src="js/common.js">
var gPopupMask = null;
var gPopupContainer = null;
var gPopFrame = null;
var gReturnFunc;
var gPopupIsShown = false;
var gDefaultPage = "/loading.html";
var gHideSelects = false;
var gReturnVal = null;
var gTabIndexes = new Array();
// Pre-defined list of tags we want to disable/enable tabbing into
var gTabbableTags = new Array("A","BUTTON","TEXTAREA","INPUT","IFRAME");
// If using Mozilla or Firefox, use Tab-key trap.
if (!document.all) {
document.onkeypress = keyDownHandler;
}
/**
* Initializes popup code on load.
*/
function initPopUp() {
// Add the HTML to the body
theBody = document.getElementsByTagName('BODY')[0];
popmask = document.createElement('div');
popmask.id = 'popupMask';
popcont = document.createElement('div');
popcont.id = 'popupContainer';
popcont.innerHTML = '' +
'<div id="popupInner">' +
'<div id="popupTitleBar">' +
'<div id="popupTitle"></div>' +
'<div id="popupControls">' +
'<img src="close.gif" onclick="hidePopWin(false);" id="popCloseBox" />' +
'</div>' +
'</div>' +
'<iframe src="'+ gDefaultPage +'" style="width:100%;height:100%;background-color:transparent;" ' +
' scrolling="auto" frameborder="0" allowtransparency="true" id="popupFrame" name="popupFrame" ' +
' width="100%" height="100%"></iframe>' +
'</div>';
theBody.appendChild(popmask);
theBody.appendChild(popcont);
gPopupMask = document.getElementById("popupMask");
gPopupContainer = document.getElementById("popupContainer");
gPopFrame = document.getElementById("popupFrame");
// check to see if this is IE version 6 or lower. hide select boxes if so
// maybe they'll fix this in version 7?
var brsVersion = parseInt(window.navigator.appVersion.charAt(0), 10);
if (brsVersion <= 6 && window.navigator.userAgent.indexOf("MSIE") > -1) {
gHideSelects = true;
}
// Add onclick handlers to 'a' elements of class submodal or submodal-width-height
var elms = document.getElementsByTagName('a');
for (i = 0; i < elms.length; i++) {
if (elms[i].className.indexOf("submodal") == 0) {
elms[i].onclick = function(){
// default width and height
var width = 400;
var height = 200;
// Parse out optional width and height from className
params = this.className.split('-');
if (params.length == 3) {
width = parseInt(params[1]);
height = parseInt(params[2]);
}
showPopWin(this.href,width,height,null); return false;
}
}
}
}
addEvent(window, "load", initPopUp);
/**
* @argument width - int in pixels
* @argument height - int in pixels
* @argument url - url to display
* @argument returnFunc - function to call when returning true from the window.
* @argument showCloseBox - show the close box - default true
*/
function showPopWin(url, width, height, returnFunc, showCloseBox) {
// show or hide the window close widget
if (showCloseBox == null || showCloseBox == true) {
document.getElementById("popCloseBox").style.display = "block";
} else {
document.getElementById("popCloseBox").style.display = "none";
}
gPopupIsShown = true;
disableTabIndexes();
gPopupMask.style.display = "block";
gPopupContainer.style.display = "block";
// calculate where to place the window on screen
centerPopWin(width, height);
var titleBarHeight = parseInt(document.getElementById("popupTitleBar").offsetHeight, 10);
gPopupContainer.style.width = width + "px";
gPopupContainer.style.height = (height+titleBarHeight) + "px";
setMaskSize();
// need to set the width of the iframe to the title bar width because of the dropshadow
// some oddness was occuring and causing the frame to poke outside the border in IE6
gPopFrame.style.width = parseInt(document.getElementById("popupTitleBar").offsetWidth, 10) + "px";
gPopFrame.style.height = (height) + "px";
// set the url
gPopFrame.src = url;
gReturnFunc = returnFunc;
// for IE
if (gHideSelects == true) {
hideSelectBoxes();
}
}
var gi = 0;
function centerPopWin(width, height) {
if (gPopupIsShown == true) {
if (width == null || isNaN(width)) {
width = gPopupContainer.offsetWidth;
}
if (height == null) {
height = gPopupContainer.offsetHeight;
}
var theBody = document.getElementsByTagName("BODY")[0];
var scTop = parseInt(getScrollTop(),10);
var scLeft = parseInt(theBody.scrollLeft,10);
setMaskSize();
var titleBarHeight = parseInt(document.getElementById("popupTitleBar").offsetHeight, 10);
var fullHeight = getViewportHeight();
var fullWidth = getViewportWidth();
gPopupContainer.style.top = (scTop + ((fullHeight - (height+titleBarHeight)) / 2)) + "px";
gPopupContainer.style.left = (scLeft + ((fullWidth - width) / 2)) + "px";
}
}
addEvent(window, "resize", centerPopWin);
addEvent(window, "scroll", centerPopWin);
window.onscroll = centerPopWin;
/**
* Sets the size of the popup mask.
*
*/
function setMaskSize() {
var theBody = document.getElementsByTagName("BODY")[0];
var fullHeight = getViewportHeight();
var fullWidth = getViewportWidth();
// Determine what's bigger, scrollHeight or fullHeight / width
if (fullHeight > theBody.scrollHeight) {
popHeight = fullHeight;
} else {
popHeight = theBody.scrollHeight;
}
if (fullWidth > theBody.scrollWidth) {
popWidth = fullWidth;
} else {
popWidth = theBody.scrollWidth;
}
gPopupMask.style.height = popHeight + "px";
gPopupMask.style.width = popWidth + "px";
}
/**
* @argument callReturnFunc - bool - determines if we call the return function specified
* @argument returnVal - anything - return value
*/
function hidePopWin(callReturnFunc) {
gPopupIsShown = false;
var theBody = document.getElementsByTagName("BODY")[0];
theBody.style.overflow = "";
restoreTabIndexes();
if (gPopupMask == null) {
return;
}
gPopupMask.style.display = "none";
gPopupContainer.style.display = "none";
if (callReturnFunc == true && gReturnFunc != null) {
// Set the return code to run in a timeout.
// Was having issues using with an Ajax.Request();
gReturnVal = window.frames["popupFrame"].returnVal;
window.setTimeout('gReturnFunc(gReturnVal);', 1);
}
gPopFrame.src = gDefaultPage;
// display all select boxes
if (gHideSelects == true) {
displaySelectBoxes();
}
}
// Tab key trap. iff popup is shown and key was [TAB], suppress it.
// @argument e - event - keyboard event that caused this function to be called.
function keyDownHandler(e) {
if (gPopupIsShown && e.keyCode == 9) return false;
}
// For IE. Go through predefined tags and disable tabbing into them.
function disableTabIndexes() {
if (document.all) {
var i = 0;
for (var j = 0; j < gTabbableTags.length; j++) {
var tagElements = document.getElementsByTagName(gTabbableTags[j]);
for (var k = 0 ; k < tagElements.length; k++) {
gTabIndexes[i] = tagElements[k].tabIndex;
tagElements[k].tabIndex="-1";
i++;
}
}
}
}
function returnRefresh()
{
window.location.reload();
}
// For IE. Restore tab-indexes.
function restoreTabIndexes() {
if (document.all) {
var i = 0;
for (var j = 0; j < gTabbableTags.length; j++) {
var tagElements = document.getElementsByTagName(gTabbableTags[j]);
for (var k = 0 ; k < tagElements.length; k++) {
tagElements[k].tabIndex = gTabIndexes[i];
tagElements[k].tabEnabled = true;
i++;
}
}
}
}
/**
* Hides all drop down form select boxes on the screen so they do not appear above the mask layer.
* IE has a problem with wanted select form tags to always be the topmost z-index or layer
*
* Thanks for the code Scott!
*/
function hideSelectBoxes() {
var x = document.getElementsByTagName("SELECT");
for (i=0;x && i < x.length; i++) {
x[i].style.visibility = "hidden";
}
}
/**
* Makes all drop down form select boxes on the screen visible so they do not
* reappear after the dialog is closed.
*
* IE has a problem with wanting select form tags to always be the
* topmost z-index or layer.
*/
function displaySelectBoxes() {
var x = document.getElementsByTagName("SELECT");
for (i=0;x && i < x.length; i++){
x[i].style.visibility = "visible";
}
}
</script>
<?php
}

510
export/exportjavame.php

@ -0,0 +1,510 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page export the game to javame for mobile phones
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Exports to javame.
*
* @param object $game
* @param object $javame
*/
function game_onexportjavame( $game, $javame) {
global $CFG, $DB;
$courseid = $game->course;
$course = $DB->get_record( 'course', array( 'id' => $courseid));
$destdir = game_export_createtempdir();
if ( $javame->type == 'hangmanp') {
$destmobiledir = 'hangmanp';
} else {
$destmobiledir = 'hangman';
}
$src = $CFG->dirroot.'/mod/game/export/javame/'.$destmobiledir.'/simple';
if ( $javame->filename == '') {
$javame->filename = 'moodle'.$destmobiledir;
}
$handle = opendir( $src);
while (false !== ($item = readdir($handle))) {
if ($item != '.' && $item != '..') {
if (!is_dir($src.'/'.$item)) {
$itemdest = $item;
if (substr( $item, -5) == '.java') {
continue; // Don't copy the java source code files.
}
if (substr( $itemdest, -8) == '-1.class') {
$itemdest = substr( $itemdest, 0, -8).'$1.class';
}
copy( $src.'/'.$item, $destdir.'/'.$itemdest);
}
}
}
mkdir( $destdir.'/META-INF');
game_exportjavame_exportdata( $src, $destmobiledir, $destdir, $game, $javame->maxpicturewidth, $javame->maxpictureheight);
game_create_manifest_mf( $destdir.'/META-INF', $javame, $destmobiledir);
$filejar = game_create_jar( $destdir, $course, $javame);
if ($filejar == '') {
$filezip = game_create_zip( $destdir, $course->id, $javame->filename.'.zip');
} else {
$filezip = '';
}
if ($destdir != '') {
remove_dir( $destdir);
}
if ($filezip != '') {
echo "unzip the $filezip in a directory and when you are in this directory use the command <br><b>jar ".
"cvfm {$javame->filename}.jar META-INF/MANIFEST.MF<br></b> to produce the jar files<br><br>";
}
$file = ($filejar != '' ? $filejar : $filezip);
game_send_stored_file( $file);
}
/**
* Exports data.
*
* @param string $src
* @param string $destmobiledir
* @param string $destdir
* @param stdClass $game
* @param int $maxwidth
* @param int $maxheight
*/
function game_exportjavame_exportdata( $src, $destmobiledir, $destdir, $game, $maxwidth, $maxheight) {
global $CFG;
mkdir( $destdir.'/'.$destmobiledir);
$handle = opendir( $src);
while (false !== ($item = readdir($handle))) {
if ($item != '.' && $item != '..') {
if (!is_dir($src.'/'.$item)) {
if (substr( $item, -4) == '.jpg') {
copy( $src.'/'.$item, $destdir."/$destmobiledir/".$item);
}
}
}
}
$lang = $game->language;
if ($lang == '') {
$lang = current_language();
}
$sourcefile = $src. '/lang/'.$lang.'/language.txt';
if (!file_exists( $sourcefile)) {
$sourcefile = $src. '/lang/'.$lang.'_utf8/language.txt';
}
copy( $sourcefile, $destdir."/$destmobiledir/language.txt");
$exportattachment = ( $destmobiledir == 'hangmanp');
$map = game_exmportjavame_getanswers( $game, $exportattachment, false, $destdir, $files);
if ($map == false) {
print_error( 'No Questions');
}
if ($destmobiledir == 'hangmanp') {
game_exportjavame_exportdata_hangmanp( $src, $destmobiledir, $destdir, $game, $map, $maxwidth, $maxheight);
return;
}
$fp = fopen( $destdir."/$destmobiledir/hangman.txt", "w");
fputs( $fp, "1.txt=$destmobiledir\r\n");
fclose( $fp);
$fp = fopen( $destdir."/$destmobiledir/1.txt", "w");
foreach ($map as $line) {
$s = game_upper( $line->answer) . '=' . $line->question;
fputs( $fp, "$s\r\n");
}
fclose( $fp);
}
/**
* Exports data of hangman with pictures.
*
* @param string $src
* @param string $destmobiledir
* @param string $destdir
* @param stdClass $game
* @param array $map
* @param int $maxwidth
* @param int $maxheight
*/
function game_exportjavame_exportdata_hangmanp( $src, $destmobiledir, $destdir, $game, $map, $maxwidth, $maxheight) {
global $CFG;
$fp = fopen( $destdir."/$destmobiledir/$destmobiledir.txt", "w");
fputs( $fp, "01=01\r\n");
fclose( $fp);
$destdirphoto = $destdir.'/'.$destmobiledir.'/01';
mkdir( $destdirphoto);
$fp = fopen( $destdirphoto.'/photo.txt', "w");
foreach ($map as $line) {
$file = $line->attachment;
$pos = strrpos( $file, '.');
if ($pos != false) {
$file = $line->id.substr( $file, $pos);
$src = $CFG->dataroot.'/'.$game->course.'/moddata/'.$line->attachment;
game_export_javame_smartcopyimage( $src, $destdirphoto.'/'.$file, $maxwidth, $maxheight);
$s = $file . '=' . game_upper( $line->answer);
fputs( $fp, "$s\r\n");
}
}
fclose( $fp);
}
/**
* Exports to javame.
*
* @param stdClas $game
* @param stdClass $context
* @param boolean $exportattachment
* @param string $dest
* @param array $files
*/
function game_exmportjavame_getanswers( $game, $context, $exportattachment, $dest, &$files) {
$map = array();
$files = array();
switch ($game->sourcemodule) {
case 'question':
return game_exmportjavame_getanswers_question( $game, $context, $dest, $files);
case 'glossary':
return game_exmportjavame_getanswers_glossary( $game, $context, $exportattachment, $dest, $files);
case 'quiz':
return game_exmportjavame_getanswers_quiz( $game, $context, $dest, $files);
}
return false;
}
/**
* Exports to javame.
*
* @param stdClass $game
* @param stdClass $context
* @param string $destdir
* @param array $files
*/
function game_exmportjavame_getanswers_question( $game, $context, $destdir, &$files) {
$select = 'hidden = 0 AND category='.$game->questioncategoryid;
$select .= game_showanswers_appendselect( $game);
return game_exmportjavame_getanswers_question_select( $game, $context, 'question',
$select, '*', $game->course, $destdir, $files);
}
/**
* Exports to javame.
*
* @param stdClass $game
* @param stdClass $context
* @param string $destdir
* @param array $files
*/
function game_exmportjavame_getanswers_quiz( $game, $context, $destdir, $files) {
global $CFG;
$select = "quiz='$game->quizid' ".
" AND qqi.question=q.id".
" AND q.hidden=0".
game_showanswers_appendselect( $game);
$table = "{question} q,{quiz_question_instances} qqi";
return game_exmportjavame_getanswers_question_select( $game, $context, $table, $select, "q.*", $game->course, $destdir, $files);
}
/**
* Exports to javame.
*
* @param stdClass $game
* @param stdClass $context
* @param string $table
* @param string $select
* @param string $fields
* @param int $courseid
* @param string $destdir
* @param array $files
*/
function game_exmportjavame_getanswers_question_select( $game, $context, $table, $select, $fields, $courseid, $destdir, &$files) {
global $CFG, $DB;
if (($questions = $DB->get_records_select( $table, $select, null, '', $fields)) === false) {
return;
}
$line = 0;
$map = array();
foreach ($questions as $question) {
unset( $ret);
$ret = new stdClass();
$ret->qtype = $question->qtype;
$ret->question = $question->questiontext;
$ret->question = str_replace( array( '"', '#'), array( "'", ' '),
game_export_split_files( $game->course, $context, 'questiontext',
$question->id, $ret->question, $destdir, $files));
switch ($question->qtype) {
case 'shortanswer':
$rec = $DB->get_record( 'question_answers', array( 'question' => $question->id),
'id,answer,feedback');
$ret->answer = $rec->answer;
$ret->feedback = $rec->feedback;
$map[] = $ret;
break;
default:
break;
}
}
return $map;
}
/**
* Exports to javame.
*
* @param stdClass $game
* @param stdClass $context
* @param boolean $exportattachment
* @param string $destdir
* @param array $files
*/
function game_exmportjavame_getanswers_glossary( $game, $context, $exportattachment, $destdir, &$files) {
global $CFG, $DB;
$table = '{glossary_entries} ge';
$select = "glossaryid={$game->glossaryid}";
if ($game->glossarycategoryid) {
$select .= " AND gec.entryid = ge.id ".
" AND gec.categoryid = {$game->glossarycategoryid}";
$table .= ",{glossary_entries_categories} gec";
}
if ($exportattachment) {
$select .= " AND attachment <> ''";
}
$fields = 'ge.id,definition,concept';
if ($exportattachment) {
$fields .= ',attachment';
}
$sql = "SELECT $fields FROM $table WHERE $select ORDER BY definition";
if (($questions = $DB->get_records_sql( $sql)) === false) {
return false;
}
$fs = get_file_storage();
$map = array();
$cmglossary = false;
foreach ($questions as $question) {
$ret = new stdClass();
$ret->id = $question->id;
$ret->qtype = 'shortanswer';
$ret->question = strip_tags( $question->definition);
$ret->answer = $question->concept;
$ret->feedback = '';
$ret->attachment = '';
// Copies the appropriate files from the file storage to destdir.
if ($exportattachment) {
if ($question->attachment != '') {
if ($cmglossary === false) {
$cmglossary = get_coursemodule_from_instance('glossary', $game->glossaryid, $game->course);
$contextglossary = get_context_instance(CONTEXT_MODULE, $cmglossary->id);
}
$ret->attachment = "glossary/{$game->glossaryid}/$question->id/$question->attachment";
$myfiles = $fs->get_area_files( $contextglossary->id, 'mod_glossary', 'attachment', $ret->id);
$i = 0;
foreach ($myfiles as $f) {
if ($f->is_directory()) {
continue;
}
$filename = $f->get_filename();
$url = "{$CFG->wwwroot}/pluginfile.php/{$f->get_contextid()}/mod_glossary/attachment}";
$fileurl = $url.$f->get_filepath().$f->get_itemid().'/'.$filename;
$pos = strrpos( $filename, '.');
$ext = substr( $filename, $pos);
$destfile = $ret->id;
if ($i > 0) {
$destfile .= '_'.$i;
}
$destfile = $destdir.'/'.$destfile.$ext;
$f->copy_content_to( $destfile);
$ret->attachment = $destfile;
$i++;
$files[] = $destfile;
}
}
}
$map[] = $ret;
}
return $map;
}
/**
* Create manifest mf.
*
* @param string $dir
* @param stdClass $javame
* @param string $destmobiledir
*/
function game_create_manifest_mf( $dir, $javame, $destmobiledir) {
$fp = fopen( $dir.'/MANIFEST.MF', "w");
fputs( $fp, "Manifest-Version: 1.0\r\n");
fputs( $fp, "Ant-Version: Apache Ant 1.7.0\r\n");
fputs( $fp, "Created-By: {$javame->createdby}\r\n");
fputs( $fp, "MIDlet-1: MoodleHangman,,$destmobiledir\r\n");
fputs( $fp, "MIDlet-Vendor: {$javame->vendor}\r\n");
fputs( $fp, "MIDlet-Name: {$javame->vendor}\r\n");
fputs( $fp, "MIDlet-Description: {$javame->description}\r\n");
fputs( $fp, "MIDlet-Version: {$javame->version}\r\n");
fputs( $fp, "MicroEdition-Configuration: CLDC-1.0\r\n");
fputs( $fp, "MicroEdition-Profile: MIDP-1.0\r\n");
fclose( $fp);
}
/**
* Creates a jar file.
*
* @param string $srcdir
* @param stdClass $course
* @param stdClass $javame
*/
function game_create_jar( $srcdir, $course, $javame) {
global $CFG;
$dir = $CFG->dataroot . '/' . $course->id;
$filejar = $dir . "/export/{$javame->filename}.jar";
if (!file_exists( $dir)) {
mkdir( $dir);
}
if (!file_exists( $dir.'/export')) {
mkdir( $dir.'/export');
}
if (file_exists( $filejar)) {
unlink( $filejar);
}
$cmd = "cd $srcdir;jar cvfm $filejar META-INF/MANIFEST.MF *";
exec( $cmd);
return (file_exists( $filejar) ? $filejar : '');
}
/**
* Exports to javame.
*
* @param stdClass $form
*/
function game_showanswers_appendselect( $form) {
switch( $form->gamekind){
case 'hangman':
case 'cross':
case 'crypto':
return " AND qtype='shortanswer'";
case 'millionaire':
return " AND qtype = 'multichoice'";
case 'sudoku':
case 'bookquiz':
case 'snakes':
return " AND qtype in ('shortanswer', 'truefalse', 'multichoice')";
}
return '';
}
/**
* Copy images
*
* @param string $filename
* @param string $dest
* @param int $maxwidth
*/
function game_export_javame_smartcopyimage( $filename, $dest, $maxwidth) {
if ($maxwidth == 0) {
copy( $filename, $dest);
return;
}
$size = getimagesize( $filename);
if ($size == false) {
copy( $filename, $dest);
return;
}
$mul = $maxwidth / $size[ 0];
if ($mul > 1) {
copy( $filename, $dest);
return;
}
$mime = $size[ 'mime'];
switch( $mime) {
case 'image/png':
$srcimage = imagecreatefrompng( $filename);
break;
case 'image/jpeg':
$srcimage = imagecreatefromjpeg( $filename);
break;
case 'image/gif':
$srcimage = imagecreatefromgif( $filename);
break;
default:
die('Aknown mime type $mime');
return false;
}
$dstw = $size[ 0] * $mul;
$dsth = $size[ 1] * $mul;
$dstimage = imagecreatetruecolor( $dstw, $dsth);
imagecopyresampled( $dstimage, $srcimage, 0, 0, 0, 0, $dstw, $dsth, $size[ 0], $size[ 1]);
imagejpeg( $dstimage, $dest);
}

28
export/html/snakes/css/game.css

@ -0,0 +1,28 @@
.nodis {
list-style-type: none;
}
#cont {
position: relative;
display: none;
}
.img1 {
position: absolute;
display: none;
}
#dicecont {
width: 250px;
background-image: url(../images/meter.png);
background-repeat: repeat;
font-family: Arial, Helvetica, sans-serif;
font-weight: normal;
color: #fff;
border: 0.5em solid #333;
top: 30px;
position: absolute;
left: 500px;
font-size: 14px;
padding: 10px;
}

47
export/html/snakes/css/modal.css

@ -0,0 +1,47 @@
@charset "utf-8";
#fade { /*--Transparent background layer--*/
display: none; /*--hidden by default--*/
background: #000;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: .80;
z-index: 9999;
}
.popup_block {
display: none; /*--hidden by default--*/
background: #fff;
padding: 20px;
border: 20px solid #ddd;
float: left;
font-size: 1.2em;
position: fixed;
top: 50%;
left: 50%;
z-index: 99999;
/*--CSS3 Box Shadows--*/
-webkit-box-shadow: 0 0 20px #000;
-moz-box-shadow: 0 0 20px #000;
box-shadow: 0 0 20px #000;
/*--CSS3 Rounded Corners--*/
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
img.btn_close {
float: right;
margin: -55px -55px 0 0;
}
/*--Making IE6 Understand Fixed Positioning--*/
*html #fade {
position: absolute;
}
*html .popup_block {
position: absolute;
}

125
export/html/snakes/css/snakes.css

@ -0,0 +1,125 @@
/*This Code is a sole propritary of
Husain Limdiyawala(MSc IT DA-IICT)
Any Duplication of this code should be avoided*/
.blocks {
font-family: Arial, Helvetica, sans-serif;
margin-left: 5px;
margin-top: 2px;
margin-bottom: 2px;
padding: 0;
float: left;
height: 52px;
width: 52px;
display: block;
position: relative;
background-image: url(../square52.png);
}
.nodis {
list-style-type: none;
}
#cont {
position: relative;
display: none;
}
#diceimg {
display: none;
width: 45px;
height: 44px;
}
.img1 {
position: absolute;
display: none;
}
body {
background: #ccc;
}
#player {
display: none;
z-index: 5;
position: absolute;
}
#players {
margin-top: 0.3em;
margin-bottom: 1em;
}
#dicecont {
float: right;
width: 170px;
background-image: url(../images/meter.png);
background-repeat: repeat;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
color: #fff;
border: 0.5em solid #333;
top: 30px;
position: absolute;
right: 880px;
}
#playbtn {
margin-left: 0.5em;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
color: #000;
background-color: #fc0;
padding: 1em;
}
/*-- from modal window coding --*/
#fade { /*--Transparent background layer--*/
display: none; /*--hidden by default--*/
background: #000;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: .80;
z-index: 9999;
}
.popup_block {
display: none; /*--hidden by default--*/
background: #fff;
padding: 20px;
border: 20px solid #ddd;
float: left;
font-size: 1.2em;
position: fixed;
top: 50%;
left: 50%;
z-index: 99999;
/*--CSS3 Box Shadows--*/
-webkit-box-shadow: 0 0 20px #000;
-moz-box-shadow: 0 0 20px #000;
box-shadow: 0 0 20px #000;
/*--CSS3 Rounded Corners--*/
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
img.btn_close {
float: right;
margin: -55px -55px 0 0;
border: 0;
}
/*--Making IE6 Understand Fixed Positioning--*/
*html #fade {
position: absolute;
}
*html .popup_block {
position: absolute;
}

17
export/html/snakes/css/style.css

@ -0,0 +1,17 @@
body {
background-color: #efefef;
}
body,
html,
input {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
color: #333;
}
.info {
font-style: italic;
font-size: 0.9em;
color: #666;
}

70
export/html/snakes/css/subModal.css

@ -0,0 +1,70 @@
/**
* POPUP CONTAINER STYLES
*/
#popupMask {
position: absolute;
z-index: 200;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: .4;
filter: alpha(opacity=50);
/* this hack is so it works in IE
* I find setting the color in the css gives me more flexibility
* than the PNG solution.
*/
background-color: #333;
/* this hack is for opera support
* you can uncomment the background-image if you don't care about opera.
* this gives you the flexibility to use any bg color that you want, instead of the png
*/
background-image: none;
background-repeat: repeat;
display: none;
}
#popupContainer {
position: absolute;
z-index: 201;
top: 0;
left: 0;
display: none;
padding: 0;
}
#popupInner {
border: 2px solid #000;
background-color: #fff;
}
#popupFrame {
margin: 0;
width: 100%;
height: 100%;
position: relative;
z-index: 202;
}
#popupTitleBar {
background-color: #090;
color: #000;
font-weight: bold;
height: 1.3em;
padding: 5px;
border-bottom: 2px solid #000;
border-top: 1px solid #7878a3f2;
border-left: 1px solid #7878a3f2;
border-right: 1px solid #204095;
position: relative;
z-index: 203;
}
#popupTitle {
float: left;
font-size: 1.1em;
}
#popupControls {
float: right;
cursor: hand;
}

BIN
export/html/snakes/js/js.zip

Binary file not shown.

BIN
export/html/snakes/maskBG.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

18
export/html/snakes/modalContent.html

@ -0,0 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1253" />
<title>ÏëïêëÞñùóç ðáé÷íéäéïý</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="stylesheet" type="text/css" href="css/subModal.css" />
</head>
<body bgcolor="#CCFF66" style="font-family: Arial, Helvetica, sans-serif; font-weight: normal; font-size:13px;">
<h2>Óõã÷áñçôÞñéá! </h2>Ìüëéò ïëïêëÞñùóåò ìå åðéôõ÷ßá ôï ðáé÷íßäé.
<p>Ôï óêïñ óïõ äåß÷íåé ôï <strong>ðïóïóôü % ôùí óùóôþí áðáíôÞóåùí</strong>, óôï óýíïëï ôùí åñùôÞóåùí ðïõ óïõ Ýãéíáí.</p>
<p>Èá Þèåëåò íá îáíáäïêéìÜóåéò;</p>
<button onclick="window.top.hidePopWin(true)">Íáé, èá ðáßîù îáíÜ!</button>
<button onclick="window.top.hidePopWin()">¼÷é, åõ÷áñéóôþ</button>
</body>
</html>

BIN
export/javame/hangman/simple/KeyCanvas.class

Binary file not shown.

537
export/javame/hangman/simple/KeyCanvas.java

@ -0,0 +1,537 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import java.util.Hashtable;
import java.util.Random;
class KeyCanvas extends Canvas {
//private Font mFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
private String mMessage = "";
private String m_letters;
private String m_lastletter;
private String m_answer;
private String m_question;
private String m_allletters;
private String m_guess;
private String m_wrong;
private int m_wrongletters;
private String m_encoding="";
private int m_state=0;
//0=start 1=play 2=next word 3=lose 4=win
private String m_init_letters;
private String m_init_allletters;
private int m_count_games=0;
private int m_count_wins=0;
private String m_filewords;
public Hashtable m_hashLocales;
private int m_keysize = 0;
private int [] m_key;
public KeyCanvas() throws IOException {
m_state = 0;
m_key = new int[ m_keysize+1];
m_key[ 0] = 0;
SelectFileWords();
//LoadEncoding();
LoadLocales();
addCommand(new Command( getlocale( "exit"), Command.EXIT, 0));
}
private String decrypt( String s){
String ret="";
if( m_keysize <=0 ){
return s;
}
int len=s.length();
for(int i=0; i < len; i+=m_keysize){
for(int j=0; j < m_keysize; j++){
int pos=i + m_key[ j];
if( pos < len){
ret = ret + s.charAt( pos);
}
}
}
return ret;
}
private String getlocale( String key){
return (String)m_hashLocales.get( key);
}
private void SelectFileWords() throws IOException{
Class c = this.getClass();
InputStream is = c.getResourceAsStream( "hangman/hangman.txt");
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
int pos = line.indexOf( "=");
if( pos >= 0){
m_filewords = "hangman/" + line.substring( 0, pos);
}
break;
}
reader.close();
}
private String readLine(InputStreamReader reader) throws IOException {
// Test whether the end of file has been reached. If so, return null.
int readChar = reader.read();
if (readChar <= -1) {
return null;
}
StringBuffer string = new StringBuffer();
// Read until end of file or new line
while (readChar > -1 && readChar != '\n') {
// Append the read character to the string. Some operating systems
// such as Microsoft Windows prepend newline character ('\n') with
// carriage return ('\r'). This is part of the newline character and
// therefore an exception that should not be appended to the string.
if (readChar != '\r') {
string.append( (char )readChar);
}
// Read the next character
readChar = reader.read();
}
return string.toString();
}
private void LoadLocales() throws IOException{
m_hashLocales = new Hashtable();
Class c = this.getClass();
InputStream is = c.getResourceAsStream( "hangman/language.txt");
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
String key, data;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
int pos = line.indexOf( "=");
if( pos >= 0){
key = line.substring( 0, pos);
data = line.substring( pos+1);
m_hashLocales.put(key, data);
}
}
reader.close();
}
protected boolean SetCurrentWord( String line) throws IOException{
int pos=line.indexOf( '=');
if( pos == -1){
return false;
}
m_answer = line.substring( 0, pos);
m_question = line.substring( pos+1);
return true;
}
protected int SelectWord( String fname) throws IOException{
Class c = this.getClass();
InputStream is = c.getResourceAsStream( fname);
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
int count=0;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
// Append the read line to the main form with a linefeed ('\n')
count = count + 1;
}
reader.close();
//select randomly one word
Random r = new Random();
int curline = r.nextInt();
curline = curline % count;
if( curline < 0)
curline = curline + count;
InputStreamReader reader2 = new InputStreamReader(
getClass().getResourceAsStream(fname), "UTF-8");
int i = 0;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader2)) != null) {
if( i == curline){
line = decrypt( line);
SetCurrentWord( line);
return 1;
}
i = i + 1;
}
reader.close();
return 0;
}
public void paint(Graphics g) {
switch( m_state){
case 0:
try {
paint_state_start(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
case 1:
try {
paint_state_play( g);
} catch (StringIndexOutOfBoundsException ex) {
ex.printStackTrace();
}
break;
case 2:
try {
paint_state_nextword(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
case 3:
paint_state_lose( g);
break;
case 4:
try {
paint_state_win(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
}
}
private void paint_state_start(Graphics g) throws IOException{
m_init_letters = getlocale( "keyboardletters");
m_init_allletters = m_init_letters;
String sRemove = "1234567890:#";
for(int i=0; i < sRemove.length(); i++){
for(;;){
int pos = m_init_allletters.indexOf( sRemove.charAt(i));
if( pos < 0)
break;
m_init_allletters = m_init_allletters.substring( 0, pos) + m_init_allletters.substring( pos+1);
}
}
m_state = 2;
paint_state_nextword( g);
}
private void paint_state_nextword(Graphics g) throws IOException{
m_letters = m_init_letters;
m_allletters = m_init_allletters;
SelectWord( m_filewords);
m_lastletter = "";
int len = m_answer.length();
m_guess = "";
m_wrong = "";
for(int i=0; i < len; i++){
m_guess = m_guess + "-";
}
m_wrongletters = 0;
m_state = 1; //play
paint_state_play( g);
}
private void paint_state_win(Graphics g) throws IOException{
m_count_games++;
m_count_wins++;
m_state = 2;
paint_state_nextword( g);
}
private void paint_state_lose(Graphics g){
m_count_games++;
//clear the screen
g.setColor(255,255,255);
g.fillRect(0, 0, getWidth(), getHeight());
//set color to black
g.setColor(0,0,0);
//get the font height
int y=10;
int iHeight=g.getFont().getHeight();
String s = m_answer;
if( m_wrong.length() > 0){
s = s + " (" + m_wrong + ")";
}
s = s + " [" + String.valueOf( m_count_wins) + "/" + String.valueOf( m_count_games) + "]";
y = drawtextmultiline( g, s, 0, y);
y = drawtextmultiline( g, m_question, 0, y+iHeight);
m_state = 2;
}
private void paint_state_play(Graphics g){
//clear the screen
g.setColor(255,255,255);
g.fillRect(0, 0, getWidth(), getHeight());
//set color to black
g.setColor(0,0,0);
//get the font height
int y=0;
Font font = g.getFont();
int iHeight=g.getFont().getHeight();
String s = m_guess;
if( m_wrong.compareTo( "") != 0){
s = s + " (" + m_wrong + ")";
}
s = s + " (" + String.valueOf( m_count_wins) + "/" + String.valueOf( m_count_games) + ")";
y = drawtextmultiline( g, s, 0, y);
int x = getWidth() - 3 * font.charWidth( '-');
y = drawtextmultiline( g, mMessage, x, y) + iHeight;
y = drawtextmultiline( g, m_question, 0, y) + iHeight;
Image im = null;
try {
String filename = "/hangman/hangman_" + String.valueOf(m_wrongletters) + ".jpg";
im = Image.createImage( filename);
} catch (IOException ex) {
ex.printStackTrace();
}
int xMul = (100 * getWidth()) / im.getWidth();
int yMul = (100 * (getHeight() - y)) / im.getHeight();
if( yMul < xMul){
xMul = yMul;
}
int cx = (xMul * im.getWidth()) / 100;
int cy = (yMul * im.getHeight()) / 100;
Image resize = resizeImage( im, cx, cy);
g.drawImage(resize, 0, y, Graphics.LEFT | Graphics.TOP);
}
protected int drawtextmultiline(Graphics g, String text, int x, int y){
Font font = g.getFont();
int fontHeight = font.getHeight();
//change string to char data
char[] data = new char[text.length()];
text.getChars(0, text.length(), data, 0);
int width = getWidth();
int lineWidth = 0;
int charWidth = 0;
int xStart = x;
char ch;
for(int ccnt=0; ccnt < data.length; ccnt++)
{
ch = data[ccnt];
//measure the char to draw
charWidth = font.charWidth(ch);
lineWidth = lineWidth + charWidth;
//see if a new line is needed
if (lineWidth > width)
{
y = y + fontHeight;
lineWidth = 0;
x = xStart;
}
//draw the char
g.drawChar(ch, x, y,
Graphics.TOP|Graphics.LEFT);
x = x + charWidth;
}
return y;
}
protected void keyPressed(int keyCode) {
char number;
if( m_state == 2){
repaint();
return;
}
if( (keyCode >= 49) && (keyCode <= 57)){
String numbers = "123456789";
number = numbers.charAt(keyCode - 49);
int pos = m_letters.indexOf( number + ":");
String letters = "";
String letters2 = m_letters.substring( pos+2);
if( pos >= 0){
pos = letters2.indexOf( '#');
if( pos >= 0){
letters = letters2.substring( 0, pos);
//Compute the letters that correspond to the key pressed
if( m_lastletter.compareTo( "") != 0){
pos = letters.indexOf( m_lastletter);
if( pos >= 0){
pos = pos + 1;
if( pos >= letters.length()){
pos = 0;
}
}else{
//different key
pos = 0;
}
}else{
pos = 0;
}
if( (pos < letters.length()) && (pos >= 0)){
m_lastletter = letters.substring( pos, pos+1);
mMessage = m_lastletter;
repaint();
}
return;
}
}
repaint();
return;
}
int gameAction = getGameAction(keyCode);
switch (gameAction) {
case FIRE:
OnFire();
break;
default:
mMessage = String.valueOf( keyCode);
break;
}
}
protected void OnFire() {
int pos = m_guess.indexOf( m_lastletter);
if( pos >= 0){
//Already used
return;
}
char ch = m_lastletter.charAt( 0);
pos = m_answer.indexOf( ch);
if( pos >= 0){
//correct letter
//Maybe there are many letters
for(pos=0; pos < m_guess.length();pos++){
if( m_answer.charAt( pos) == ch){
m_guess = m_guess.substring( 0, pos) + m_lastletter + m_guess.substring( pos+1);
}
}
pos = m_allletters.indexOf( m_lastletter);
if( pos >= 0){
m_allletters = m_allletters.substring( 0, pos) + "." + m_allletters.substring( pos+1);
}
remove_lastletter_from_keyboard();
if( m_guess.indexOf( '-') < 0){
m_state = 4; //state=win;
}
repaint();
return;
}
pos = m_allletters.indexOf( m_lastletter);
if( pos < 0){
return;
}
//wrong letter
m_wrongletters = m_wrongletters + 1;
pos = m_allletters.indexOf( m_lastletter);
if( pos >= 0){
m_allletters = m_allletters.substring( 0, pos) + "." + m_allletters.substring( pos+1);
m_wrong = m_wrong + m_lastletter;
}
remove_lastletter_from_keyboard();
if( m_wrongletters >= 6){
m_state = 3; //state=lose
}
repaint();
}
private void remove_lastletter_from_keyboard(){
int pos = m_letters.indexOf( m_lastletter);
if( pos >= 0){
m_letters = m_letters.substring( 0, pos) + m_letters.substring( pos+1);
}
}
private Image resizeImage(Image src, int cx, int cy) {
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
Image tmp = Image.createImage(cx, srcHeight);
Graphics g = tmp.getGraphics();
int ratio = (srcWidth << 16) / cx;
int pos = ratio/2;
//Horizontal Resize
for (int x = 0; x < cx; x++) {
g.setClip(x, 0, 1, srcHeight);
g.drawImage(src, x - (pos >> 16), 0, Graphics.LEFT | Graphics.TOP);
pos += ratio;
}
Image resizedImage = Image.createImage(cx, cy);
g = resizedImage.getGraphics();
ratio = (srcHeight << 16) / cy;
pos = ratio/2;
//Vertical resize
for (int y = 0; y < cy; y++) {
g.setClip(0, y, cx, 1);
g.drawImage(tmp, 0, y - (pos >> 16), Graphics.LEFT | Graphics.TOP);
pos += ratio;
}
return resizedImage;
}//resize image
}

BIN
export/javame/hangman/simple/hangman-1.class

Binary file not shown.

BIN
export/javame/hangman/simple/hangman.class

Binary file not shown.

566
export/javame/hangman/simple/hangman.java

@ -0,0 +1,566 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.midlet.MIDlet;
import java.util.Hashtable;
import java.util.Random;
public class hangman extends MIDlet {
public void startApp() {
Displayable d = null;
try {
d = new KeyCanvas();
} catch (IOException ex) {
ex.printStackTrace();
}
d.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable s) {
notifyDestroyed();
}
});
Display.getDisplay(this).setCurrent(d);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
class KeyCanvas extends Canvas {
//private Font mFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
private String mMessage = "";
private String m_letters;
private String m_lastletter;
private String m_answer;
private String m_question;
private String m_allletters;
private String m_guess;
private String m_wrong;
private int m_wrongletters;
private String m_encoding="";
private int m_state=0;
//0=start 1=play 2=next word 3=lose 4=win
private String m_init_letters;
private String m_init_allletters;
private int m_count_games=0;
private int m_count_wins=0;
private String m_filewords;
public Hashtable m_hashLocales;
private int m_keysize = 0;
private int [] m_key;
public KeyCanvas() throws IOException {
m_state = 0;
m_key = new int[ m_keysize+1];
m_key[ 0] = 0;
SelectFileWords();
//LoadEncoding();
LoadLocales();
addCommand(new Command( getlocale( "exit"), Command.EXIT, 0));
}
private String decrypt( String s){
String ret="";
if( m_keysize <=0 ){
return s;
}
int len=s.length();
for(int i=0; i < len; i+=m_keysize){
for(int j=0; j < m_keysize; j++){
int pos=i + m_key[ j];
if( pos < len){
ret = ret + s.charAt( pos);
}
}
}
return ret;
}
private String getlocale( String key){
return (String)m_hashLocales.get( key);
}
private void SelectFileWords() throws IOException{
Class c = this.getClass();
InputStream is = c.getResourceAsStream( "hangman/hangman.txt");
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
int pos = line.indexOf( "=");
if( pos >= 0){
m_filewords = "hangman/" + line.substring( 0, pos);
}
break;
}
reader.close();
}
private String readLine(InputStreamReader reader) throws IOException {
// Test whether the end of file has been reached. If so, return null.
int readChar = reader.read();
if (readChar <= -1) {
return null;
}
StringBuffer string = new StringBuffer();
// Read until end of file or new line
while (readChar > -1 && readChar != '\n') {
// Append the read character to the string. Some operating systems
// such as Microsoft Windows prepend newline character ('\n') with
// carriage return ('\r'). This is part of the newline character and
// therefore an exception that should not be appended to the string.
if (readChar != '\r') {
string.append( (char )readChar);
}
// Read the next character
readChar = reader.read();
}
return string.toString();
}
private void LoadLocales() throws IOException{
m_hashLocales = new Hashtable();
Class c = this.getClass();
InputStream is = c.getResourceAsStream( "hangman/language.txt");
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
String key, data;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
int pos = line.indexOf( "=");
if( pos >= 0){
key = line.substring( 0, pos);
data = line.substring( pos+1);
m_hashLocales.put(key, data);
}
}
reader.close();
}
protected boolean SetCurrentWord( String line) throws IOException{
int pos=line.indexOf( '=');
if( pos == -1){
return false;
}
m_answer = line.substring( 0, pos);
m_question = line.substring( pos+1);
return true;
}
protected int SelectWord( String fname) throws IOException{
Class c = this.getClass();
InputStream is = c.getResourceAsStream( fname);
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
int count=0;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
// Append the read line to the main form with a linefeed ('\n')
count = count + 1;
}
reader.close();
//select randomly one word
Random r = new Random();
int curline = r.nextInt();
curline = curline % count;
if( curline < 0)
curline = curline + count;
InputStreamReader reader2 = new InputStreamReader(
getClass().getResourceAsStream(fname), "UTF-8");
int i = 0;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader2)) != null) {
if( i == curline){
line = decrypt( line);
SetCurrentWord( line);
return 1;
}
i = i + 1;
}
reader.close();
return 0;
}
public void paint(Graphics g) {
switch( m_state){
case 0:
try {
paint_state_start(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
case 1:
try {
paint_state_play( g);
} catch (StringIndexOutOfBoundsException ex) {
ex.printStackTrace();
}
break;
case 2:
try {
paint_state_nextword(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
case 3:
paint_state_lose( g);
break;
case 4:
try {
paint_state_win(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
}
}
private void paint_state_start(Graphics g) throws IOException{
m_init_letters = getlocale( "keyboardletters");
m_init_allletters = m_init_letters;
String sRemove = "1234567890:#";
for(int i=0; i < sRemove.length(); i++){
for(;;){
int pos = m_init_allletters.indexOf( sRemove.charAt(i));
if( pos < 0)
break;
m_init_allletters = m_init_allletters.substring( 0, pos) + m_init_allletters.substring( pos+1);
}
}
m_state = 2;
paint_state_nextword( g);
}
private void paint_state_nextword(Graphics g) throws IOException{
m_letters = m_init_letters;
m_allletters = m_init_allletters;
SelectWord( m_filewords);
m_lastletter = "";
int len = m_answer.length();
m_guess = "";
m_wrong = "";
for(int i=0; i < len; i++){
m_guess = m_guess + "-";
}
m_wrongletters = 0;
m_state = 1; //play
paint_state_play( g);
}
private void paint_state_win(Graphics g) throws IOException{
m_count_games++;
m_count_wins++;
m_state = 2;
paint_state_nextword( g);
}
private void paint_state_lose(Graphics g){
m_count_games++;
//clear the screen
g.setColor(255,255,255);
g.fillRect(0, 0, getWidth(), getHeight());
//set color to black
g.setColor(0,0,0);
//get the font height
int y=10;
int iHeight=g.getFont().getHeight();
String s = m_answer;
if( m_wrong.length() > 0){
s = s + " (" + m_wrong + ")";
}
s = s + " [" + String.valueOf( m_count_wins) + "/" + String.valueOf( m_count_games) + "]";
y = drawtextmultiline( g, s, 0, y);
y = drawtextmultiline( g, m_question, 0, y+iHeight);
m_state = 2;
}
private void paint_state_play(Graphics g){
//clear the screen
g.setColor(255,255,255);
g.fillRect(0, 0, getWidth(), getHeight());
//set color to black
g.setColor(0,0,0);
//get the font height
int y=0;
Font font = g.getFont();
int iHeight=g.getFont().getHeight();
String s = m_guess;
if( m_wrong.compareTo( "") != 0){
s = s + " (" + m_wrong + ")";
}
s = s + " (" + String.valueOf( m_count_wins) + "/" + String.valueOf( m_count_games) + ")";
y = drawtextmultiline( g, s, 0, y);
int x = getWidth() - 3 * font.charWidth( '-');
y = drawtextmultiline( g, mMessage, x, y) + iHeight;
y = drawtextmultiline( g, m_question, 0, y) + iHeight;
Image im = null;
try {
String filename = "/hangman/hangman_" + String.valueOf(m_wrongletters) + ".jpg";
im = Image.createImage( filename);
} catch (IOException ex) {
ex.printStackTrace();
}
int xMul = (100 * getWidth()) / im.getWidth();
int yMul = (100 * (getHeight() - y)) / im.getHeight();
if( yMul < xMul){
xMul = yMul;
}
int cx = (xMul * im.getWidth()) / 100;
int cy = (yMul * im.getHeight()) / 100;
Image resize = resizeImage( im, cx, cy);
g.drawImage(resize, 0, y, Graphics.LEFT | Graphics.TOP);
}
protected int drawtextmultiline(Graphics g, String text, int x, int y){
Font font = g.getFont();
int fontHeight = font.getHeight();
//change string to char data
char[] data = new char[text.length()];
text.getChars(0, text.length(), data, 0);
int width = getWidth();
int lineWidth = 0;
int charWidth = 0;
int xStart = x;
char ch;
for(int ccnt=0; ccnt < data.length; ccnt++)
{
ch = data[ccnt];
//measure the char to draw
charWidth = font.charWidth(ch);
lineWidth = lineWidth + charWidth;
//see if a new line is needed
if (lineWidth > width)
{
y = y + fontHeight;
lineWidth = 0;
x = xStart;
}
//draw the char
g.drawChar(ch, x, y,
Graphics.TOP|Graphics.LEFT);
x = x + charWidth;
}
return y;
}
protected void keyPressed(int keyCode) {
char number;
if( m_state == 2){
repaint();
return;
}
if( (keyCode >= 49) && (keyCode <= 57)){
String numbers = "123456789";
number = numbers.charAt(keyCode - 49);
int pos = m_letters.indexOf( number + ":");
String letters = "";
String letters2 = m_letters.substring( pos+2);
if( pos >= 0){
pos = letters2.indexOf( '#');
if( pos >= 0){
letters = letters2.substring( 0, pos);
//Compute the letters that correspond to the key pressed
if( m_lastletter.compareTo( "") != 0){
pos = letters.indexOf( m_lastletter);
if( pos >= 0){
pos = pos + 1;
if( pos >= letters.length()){
pos = 0;
}
}else{
//different key
pos = 0;
}
}else{
pos = 0;
}
if( (pos < letters.length()) && (pos >= 0)){
m_lastletter = letters.substring( pos, pos+1);
mMessage = m_lastletter;
repaint();
}
return;
}
}
repaint();
return;
}
int gameAction = getGameAction(keyCode);
switch (gameAction) {
case FIRE:
OnFire();
break;
default:
mMessage = String.valueOf( keyCode);
break;
}
}
protected void OnFire() {
int pos = m_guess.indexOf( m_lastletter);
if( pos >= 0){
//Already used
return;
}
char ch = m_lastletter.charAt( 0);
pos = m_answer.indexOf( ch);
if( pos >= 0){
//correct letter
//Maybe there are many letters
for(pos=0; pos < m_guess.length();pos++){
if( m_answer.charAt( pos) == ch){
m_guess = m_guess.substring( 0, pos) + m_lastletter + m_guess.substring( pos+1);
}
}
pos = m_allletters.indexOf( m_lastletter);
if( pos >= 0){
m_allletters = m_allletters.substring( 0, pos) + "." + m_allletters.substring( pos+1);
}
remove_lastletter_from_keyboard();
if( m_guess.indexOf( '-') < 0){
m_state = 4; //state=win;
}
repaint();
return;
}
pos = m_allletters.indexOf( m_lastletter);
if( pos < 0){
return;
}
//wrong letter
m_wrongletters = m_wrongletters + 1;
pos = m_allletters.indexOf( m_lastletter);
if( pos >= 0){
m_allletters = m_allletters.substring( 0, pos) + "." + m_allletters.substring( pos+1);
m_wrong = m_wrong + m_lastletter;
}
remove_lastletter_from_keyboard();
if( m_wrongletters >= 6){
m_state = 3; //state=lose
}
repaint();
}
private void remove_lastletter_from_keyboard(){
int pos = m_letters.indexOf( m_lastletter);
if( pos >= 0){
m_letters = m_letters.substring( 0, pos) + m_letters.substring( pos+1);
}
}
private Image resizeImage(Image src, int cx, int cy) {
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
Image tmp = Image.createImage(cx, srcHeight);
Graphics g = tmp.getGraphics();
int ratio = (srcWidth << 16) / cx;
int pos = ratio/2;
//Horizontal Resize
for (int x = 0; x < cx; x++) {
g.setClip(x, 0, 1, srcHeight);
g.drawImage(src, x - (pos >> 16), 0, Graphics.LEFT | Graphics.TOP);
pos += ratio;
}
Image resizedImage = Image.createImage(cx, cy);
g = resizedImage.getGraphics();
ratio = (srcHeight << 16) / cy;
pos = ratio/2;
//Vertical resize
for (int y = 0; y < cy; y++) {
g.setClip(0, y, cx, 1);
g.drawImage(tmp, 0, y - (pos >> 16), Graphics.LEFT | Graphics.TOP);
pos += ratio;
}
return resizedImage;
}//resize image
}

3
export/javame/hangman/simple/lang/el_utf8/language.txt

@ -0,0 +1,3 @@
encoding=el_utf8
exit=Έξοδος
keyboardletters=2:ΑΒΓ#3:ΔΕΖ#4:ΗΘΙ#5:ΚΛΜ#6:ΝΞΟ#7:ΠΡΣ#8:ΤΥΦ#9:ΧΨΩ#

3
export/javame/hangman/simple/lang/en_utf8/language.txt

@ -0,0 +1,3 @@
encoding=en_utf8
exit=Exit
keyboardletters=2:ABC#3:DEF#4:GHI#5:JKL#6:MNO#7:PQRS#8:TUV#9:WXYZ#

3
export/javame/hangman/simple/lang/es_utf8/language.txt

@ -0,0 +1,3 @@
encoding=es_utf8
exit=Salir
keyboardletters=2:ABC2ÁªÀÇ#3:DEF3ÉÈ#4:GHI4ÍÌ#5:JKL5#6:MNÑO6ÓÒº#7:PQRS7#8:TUV8ÚÜÙ#9:WXYZ9#

BIN
export/javame/hangmanp/simple/hangmanp-1.class

Binary file not shown.

BIN
export/javame/hangmanp/simple/hangmanp.class

Binary file not shown.

33
export/javame/hangmanp/simple/hangmanp.java

@ -0,0 +1,33 @@
import java.io.IOException;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;
public class hangmanp extends MIDlet {
public void startApp() {
Displayable d = null;
try {
d = new keycanvasp();
} catch (IOException ex) {
ex.printStackTrace();
}
d.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable s) {
notifyDestroyed();
}
});
Display.getDisplay(this).setCurrent(d);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}

BIN
export/javame/hangmanp/simple/keycanvasp.class

Binary file not shown.

570
export/javame/hangmanp/simple/keycanvasp.java

@ -0,0 +1,570 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import java.util.Hashtable;
import java.util.Random;
class keycanvasp extends Canvas {
//private Font mFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
private String mMessage = "";
private String m_letters;
private String m_lastletter;
private String m_dirphoto;
//read from photo.txt
private String m_file;
private String m_answer;
private String m_info;
//private String m_question;
private String m_allletters;
private String m_guess;
private String m_wrong;
private int m_wrongletters;
private int m_state=0;
//0=start 1=play 2=next word 3=lose 4=win
private String m_init_letters;
private String m_init_allletters;
private int m_count_games=0;
private int m_count_wins=0;
public Hashtable m_hashLocales;
private int m_keysize = 0;
private int [] m_key;
public keycanvasp() throws IOException {
m_state = 0;
m_key = new int[ m_keysize+1];
m_key[ 0] = 0;
SelectFileWords();
LoadLocales();
addCommand(new Command( getlocale( "exit"), Command.EXIT, 0));
}
private String decrypt( String s){
String ret="";
if( m_keysize <=0 ){
return s;
}
int len=s.length();
for(int i=0; i < len; i+=m_keysize){
for(int j=0; j < m_keysize; j++){
int pos=i + m_key[ j];
if( pos < len){
ret = ret + s.charAt( pos);
}
}
}
return ret;
}
private String getlocale( String key){
return (String)m_hashLocales.get( key);
}
private void SelectFileWords() throws IOException{
Class c = this.getClass();
InputStream is = c.getResourceAsStream( "hangmanp/hangmanp.txt");
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
int pos = line.indexOf( "=");
if( pos >= 0){
m_dirphoto = "/hangmanp/" + line.substring( 0, pos);
}
break;
}
reader.close();
}
private String readLine(InputStreamReader reader) throws IOException {
// Test whether the end of file has been reached. If so, return null.
int readChar = reader.read();
if (readChar <= -1) {
return null;
}
StringBuffer string = new StringBuffer();
// Read until end of file or new line
while (readChar > -1 && readChar != '\n') {
// Append the read character to the string. Some operating systems
// such as Microsoft Windows prepend newline character ('\n') with
// carriage return ('\r'). This is part of the newline character and
// therefore an exception that should not be appended to the string.
if (readChar != '\r') {
string.append( (char )readChar);
}
// Read the next character
readChar = reader.read();
}
return string.toString();
}
private void LoadLocales() throws IOException{
m_hashLocales = new Hashtable();
Class c = this.getClass();
InputStream is = c.getResourceAsStream( "hangmanp/language.txt");
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
String key, data;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
int pos = line.indexOf( "=");
if( pos >= 0){
key = line.substring( 0, pos);
data = line.substring( pos+1);
m_hashLocales.put(key, data);
}
}
reader.close();
}
protected boolean SetCurrentWord( String line) throws IOException{
int pos=line.indexOf( '=');
if( pos == -1){
return false;
}
m_file = line.substring( 0, pos);
m_answer = line.substring( pos+1);
pos=m_answer.indexOf( ',');
if( pos == -1){
m_info = "";
}else
{
m_info = line.substring( pos+1);
m_answer = line.substring( 0, pos);
}
return true;
}
protected int SelectWord( String fname) throws IOException{
Class c = this.getClass();
InputStream is = c.getResourceAsStream( fname);
if( is == null)
is = c.getResourceAsStream( fname);
if( is == null)
{
fname = "/hangmanp/01/photo.txt";
is = c.getResourceAsStream( fname);
}
InputStreamReader reader = new InputStreamReader( is, "UTF-8");
String line = null;
int count=0;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader)) != null) {
// Append the read line to the main form with a linefeed ('\n')
count = count + 1;
}
reader.close();
//select randomly one word
Random r = new Random();
int curline = r.nextInt();
curline = curline % count;
if( curline < 0)
curline = curline + count;
is = c.getResourceAsStream( fname);
InputStreamReader reader2 = new InputStreamReader( is, "UTF-8");
int i = 0;
// Read a single line from the file. null represents the EOF.
while ((line = readLine(reader2)) != null) {
if( i == curline){
line = decrypt( line);
SetCurrentWord( line);
return 1;
}
i = i + 1;
}
reader.close();
return 0;
}
public void paint(Graphics g) {
switch( m_state){
case 0:
try {
paint_state_start(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
case 1:
try {
paint_state_play( g);
} catch (StringIndexOutOfBoundsException ex) {
ex.printStackTrace();
}
break;
case 2:
try {
paint_state_nextword(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
case 3:
paint_state_lose( g);
break;
case 4:
try {
paint_state_win(g);
} catch (IOException ex) {
ex.printStackTrace();
}
break;
}
}
private void paint_state_start(Graphics g) throws IOException{
m_init_letters = getlocale( "keyboardletters");
m_init_allletters = m_init_letters;
String sRemove = "1234567890:#";
for(int i=0; i < sRemove.length(); i++){
for(;;){
int pos = m_init_allletters.indexOf( sRemove.charAt(i));
if( pos < 0)
break;
m_init_allletters = m_init_allletters.substring( 0, pos) + m_init_allletters.substring( pos+1);
}
}
m_state = 2;
paint_state_nextword( g);
}
private void paint_state_nextword(Graphics g) throws IOException{
m_letters = m_init_letters;
m_allletters = m_init_allletters;
SelectWord( m_dirphoto + "/photo.txt");
m_lastletter = "";
int len = m_answer.length();
m_guess = "";
m_wrong = "";
for(int i=0; i < len; i++){
m_guess = m_guess + "-";
}
m_wrongletters = 0;
m_state = 1; //play
paint_state_play( g);
}
private void paint_state_win(Graphics g) throws IOException{
m_count_games++;
m_count_wins++;
m_state = 2;
paint_state_nextword( g);
}
private void paint_state_lose(Graphics g){
m_count_games++;
//clear the screen
g.setColor(255,255,255);
g.fillRect(0, 0, getWidth(), getHeight());
//set color to black
g.setColor(0,0,0);
//get the font height
int y=10;
int iHeight=g.getFont().getHeight();
String s = m_answer;
if( m_wrong.length() > 0){
s = s + " (" + m_wrong + ")";
}
s = s + " [" + String.valueOf( m_count_wins) + "/" + String.valueOf( m_count_games) + "]";
y = drawtextmultiline( g, s, 0, y);
y = drawtextmultiline( g, m_info, 0, y+iHeight);
m_state = 2;
}
private void paint_state_play(Graphics g){
//clear the screen
g.setColor(255,255,255);
g.fillRect(0, 0, getWidth(), getHeight());
//set color to black
g.setColor(0,0,0);
//get the font height
int y=0;
Font font = g.getFont();
int iHeight=g.getFont().getHeight();
String s = m_guess;
if( m_wrong.compareTo( "") != 0){
s = s + " (" + m_wrong + ")";
}
s = s + " (" + String.valueOf( m_count_wins) + "/" + String.valueOf( m_count_games) + ")";
y = drawtextmultiline( g, s, 0, y);
int x = getWidth() - 3 * font.charWidth( '-');
y = drawtextmultiline( g, mMessage, x, y) + iHeight;
y = drawtextmultiline( g, m_info, 0, y) + iHeight;
Image im = null;
try {
String filename = m_dirphoto + "/" + m_file;
im = Image.createImage( filename);
} catch (IOException ex) {
ex.printStackTrace();
}
if( im == null)
{
try {
String filename = "/hangmanp/01/";
filename = filename + m_file;
im = Image.createImage(filename);
} catch (IOException ex) {
ex.printStackTrace();
}
}
int xMul = (100 * getWidth()) / im.getWidth();
int yMul = (100 * (getHeight() - y)) / im.getHeight();
if( yMul < xMul){
xMul = yMul;
}
int cx = (xMul * im.getWidth()) / 100;
int cy = (yMul * im.getHeight()) / 100;
Image resize = resizeImage( im, cx, cy);
g.drawImage(resize, 0, y, Graphics.LEFT | Graphics.TOP);
}
protected int drawtextmultiline(Graphics g, String text, int x, int y){
Font font = g.getFont();
int fontHeight = font.getHeight();
//change string to char data
char[] data = new char[text.length()];
text.getChars(0, text.length(), data, 0);
int width = getWidth();
int lineWidth = 0;
int charWidth = 0;
int xStart = x;
char ch;
for(int ccnt=0; ccnt < data.length; ccnt++)
{
ch = data[ccnt];
//measure the char to draw
charWidth = font.charWidth(ch);
lineWidth = lineWidth + charWidth;
//see if a new line is needed
if (lineWidth > width)
{
y = y + fontHeight;
lineWidth = 0;
x = xStart;
}
//draw the char
g.drawChar(ch, x, y,
Graphics.TOP|Graphics.LEFT);
x = x + charWidth;
}
return y;
}
protected void keyPressed(int keyCode) {
char number;
if( m_state == 2){
repaint();
return;
}
if( (keyCode >= 49) && (keyCode <= 57)){
String numbers = "123456789";
number = numbers.charAt(keyCode - 49);
int pos = m_letters.indexOf( number + ":");
String letters = "";
String letters2 = m_letters.substring( pos+2);
if( pos >= 0){
pos = letters2.indexOf( '#');
if( pos >= 0){
letters = letters2.substring( 0, pos);
//Compute the letters that correspond to the key pressed
if( m_lastletter.compareTo( "") != 0){
pos = letters.indexOf( m_lastletter);
if( pos >= 0){
pos = pos + 1;
if( pos >= letters.length()){
pos = 0;
}
}else{
//different key
pos = 0;
}
}else{
pos = 0;
}
if( (pos < letters.length()) && (pos >= 0)){
m_lastletter = letters.substring( pos, pos+1);
mMessage = m_lastletter;
repaint();
}
return;
}
}
repaint();
return;
}
int gameAction = getGameAction(keyCode);
switch (gameAction) {
case FIRE:
OnFire();
break;
default:
mMessage = String.valueOf( keyCode);
break;
}
}
protected void OnFire() {
int pos = m_guess.indexOf( m_lastletter);
if( pos >= 0){
//Already used
return;
}
char ch = m_lastletter.charAt( 0);
pos = m_answer.indexOf( ch);
if( pos >= 0){
//correct letter
//Maybe there are many letters
for(pos=0; pos < m_guess.length();pos++){
if( m_answer.charAt( pos) == ch){
m_guess = m_guess.substring( 0, pos) + m_lastletter + m_guess.substring( pos+1);
}
}
pos = m_allletters.indexOf( m_lastletter);
if( pos >= 0){
m_allletters = m_allletters.substring( 0, pos) + "." + m_allletters.substring( pos+1);
}
remove_lastletter_from_keyboard();
if( m_guess.indexOf( '-') < 0){
m_state = 4; //state=win;
}
repaint();
return;
}
pos = m_allletters.indexOf( m_lastletter);
if( pos < 0){
return;
}
//wrong letter
m_wrongletters = m_wrongletters + 1;
pos = m_allletters.indexOf( m_lastletter);
if( pos >= 0){
m_allletters = m_allletters.substring( 0, pos) + "." + m_allletters.substring( pos+1);
m_wrong = m_wrong + m_lastletter;
}
remove_lastletter_from_keyboard();
if( m_wrongletters >= 6){
m_state = 3; //state=lose
}
repaint();
}
private void remove_lastletter_from_keyboard(){
int pos = m_letters.indexOf( m_lastletter);
if( pos >= 0){
m_letters = m_letters.substring( 0, pos) + m_letters.substring( pos+1);
}
}
private Image resizeImage(Image src, int cx, int cy) {
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
Image tmp = Image.createImage(cx, srcHeight);
Graphics g = tmp.getGraphics();
int ratio = (srcWidth << 16) / cx;
int pos = ratio/2;
//Horizontal Resize
for (int x = 0; x < cx; x++) {
g.setClip(x, 0, 1, srcHeight);
g.drawImage(src, x - (pos >> 16), 0, Graphics.LEFT | Graphics.TOP);
pos += ratio;
}
Image resizedImage = Image.createImage(cx, cy);
g = resizedImage.getGraphics();
ratio = (srcHeight << 16) / cy;
pos = ratio/2;
//Vertical resize
for (int y = 0; y < cy; y++) {
g.setClip(0, y, cx, 1);
g.drawImage(tmp, 0, y - (pos >> 16), Graphics.LEFT | Graphics.TOP);
pos += ratio;
}
return resizedImage;
}//resize image
}

3
export/javame/hangmanp/simple/lang/el_utf8/language.txt

@ -0,0 +1,3 @@
encoding=el_utf8
exit=Έξοδος
keyboardletters=2:ΑΒΓ#3:ΔΕΖ#4:ΗΘΙ#5:ΚΛΜ#6:ΝΞΟ#7:ΠΡΣ#8:ΤΥΦ#9:ΧΨΩ#

3
export/javame/hangmanp/simple/lang/en_utf8/language.txt

@ -0,0 +1,3 @@
encoding=en_utf8
exit=Exit
keyboardletters=2:ABC#3:DEF#4:GHI#5:JKL#6:MNO#7:PQRS#8:TUV#9:WXYZ#

3
export/javame/hangmanp/simple/lang/es_utf8/language.txt

@ -0,0 +1,3 @@
encoding=es_utf8
exit=Salir
keyboardletters=2:ABC2ÁªÀÇ#3:DEF3ÉÈ#4:GHI4ÍÌ#5:JKL5#6:MNÑO6ÓÒº#7:PQRS7#8:TUV8ÚÜÙ#9:WXYZ9#

584
hangman/play.php

@ -0,0 +1,584 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file plays the game hangman.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Plays the game hangman
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hangman
* @param string $newletter
* @param string $action
* @param stdClass $context
*/
function game_hangman_continue( $id, $game, $attempt, $hangman, $newletter, $action, $context) {
global $DB, $USER;
if ($attempt != false and $hangman != false) {
if (($action == 'nextword') and ($hangman->finishedword != 0)) {
// Finish with one word and continue to another.
if (!$DB->set_field( 'game_hangman', 'finishedword', 0, array( 'id' => $hangman->id))) {
error( "game_hangman_continue: Can't update game_hangman");
}
} else {
return game_hangman_play( $id, $game, $attempt, $hangman, false, false, $context);
}
}
$updatehangman = (($attempt != false) and ($hangman != false));
// New game.
srand ((double)microtime() * 1000003);
// I try 10 times to find a new question.
$found = false;
$minnum = 0;
$unchanged = 0;
for ($i = 1; $i <= 10; $i++) {
$rec = game_question_shortanswer( $game, $game->param7, false);
if ($rec === false) {
continue;
}
$answer = game_upper( $rec->answertext, $game->language);
if ($game->language == '') {
$game->language = game_detectlanguage( $answer);
$answer = game_upper( $rec->answertext, $game->language);
}
$answer2 = $answer;
if ($game->param7) {
// Have to delete space.
$answer2 = str_replace( ' ', '', $answer2);
}
if ($game->param8) {
// Have to delete -.
$answer2 = str_replace( '-', '', $answer2);
}
$allletters = game_getallletters( $answer2, $game->language, $game->userlanguage);
if ($allletters == '') {
continue;
}
if ($game->param7) {
$allletters .= '_';
}
if ($game->param8) {
$allletters .= '-';
}
if ($game->param7 == false) {
// I don't allow spaces.
if (strpos( $answer, " ")) {
continue;
}
}
$copy = false;
$select2 = 'gameid=? AND userid=? AND questionid=? AND glossaryentryid=?';
if (($rec2 = $DB->get_record_select( 'game_repetitions', $select2,
array( $game->id, $USER->id, $rec->questionid, $rec->glossaryentryid), 'id,repetitions AS r')) != false) {
if (($rec2->r < $minnum) or ($minnum == 0)) {
$minnum = $rec2->r;
$copy = true;
}
} else {
$minnum = 0;
$copy = true;
}
if ($copy) {
$found = true;
$min = new stdClass();
$min->questionid = $rec->questionid;
$min->glossaryentryid = $rec->glossaryentryid;
$min->attachment = $rec->attachment;
$min->questiontext = $rec->questiontext;
$min->answerid = $rec->answerid;
$min->answer = $answer;
$min->language = $game->language;
$min->allletters = $allletters;
if ($minnum == 0) {
break; // We found an unused word.
}
} else {
$unchanged++;
}
if ($unchanged > 2) {
if ($found) {
break;
}
}
}
if ($found == false) {
print_error( get_string( 'no_words', 'game'));
}
// Found one word for hangman.
if ($attempt == false) {
$attempt = game_addattempt( $game);
}
if (!$DB->set_field( 'game_attempts', 'language', $min->language, array( 'id' => $attempt->id))) {
print_error( "game_hangman_continue: Can't set language");
}
$query = new stdClass();
$query->attemptid = $attempt->id;
$query->gamekind = $game->gamekind;
$query->gameid = $game->id;
$query->userid = $USER->id;
$query->sourcemodule = $game->sourcemodule;
$query->questionid = $min->questionid;
$query->glossaryentryid = $min->glossaryentryid;
$query->attachment = $min->attachment;
$query->questiontext = addslashes( $min->questiontext);
$query->score = 0;
$query->timelastattempt = time();
$query->answertext = $min->answer;
$query->answerid = $min->answerid;
if (!($query->id = $DB->insert_record( 'game_queries', $query))) {
print_error( "game_hangman_continue: Can't insert to table game_queries");
}
$newrec = new stdClass();
$newrec->id = $attempt->id;
$newrec->queryid = $query->id;
if ($updatehangman == false) {
$newrec->maxtries = $game->param4;
if ($newrec->maxtries == 0) {
$newrec->maxtries = 1;
}
$newrec->finishedword = 0;
$newrec->corrects = 0;
}
$newrec->allletters = $min->allletters;
$letters = '';
if ($game->param1) {
$letters .= game_substr( $min->answer, 0, 1);
}
if ($game->param2) {
$letters .= game_substr( $min->answer, -1, 1);
}
$newrec->letters = $letters;
if ($updatehangman == false) {
if (!game_insert_record( 'game_hangman', $newrec)) {
print_error( 'game_hangman_continue: error inserting in game_hangman');
}
} else {
if (!$DB->update_record( 'game_hangman', $newrec)) {
print_error( 'game_hangman_continue: error updating in game_hangman');
}
$newrec = $DB->get_record( 'game_hangman', array( 'id' => $newrec->id));
}
game_update_repetitions( $game->id, $USER->id, $query->questionid, $query->glossaryentryid);
game_hangman_play( $id, $game, $attempt, $newrec, false, false, $context);
}
/**
* On finish game.
*
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hangman
*/
function game_hangman_onfinishgame( $game, $attempt, $hangman) {
global $DB;
$score = $hangman->corrects / $hangman->maxtries;
game_updateattempts( $game, $attempt, $score, true);
if (!$DB->set_field( 'game_hangman', 'finishedword', 0, array( 'id' => $hangman->id))) {
print_error( "game_hangman_onfinishgame: Can't update game_hangman");
}
}
/**
* Plays the hangman game.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hangman
* @param boolean $onlyshow
* @param boolean $showsolution
* @param stdClass $context
*/
function game_hangman_play( $id, $game, $attempt, $hangman, $onlyshow, $showsolution, $context) {
global $CFG, $DB, $OUTPUT;
$query = $DB->get_record( 'game_queries', array( 'id' => $hangman->queryid));
if ($attempt->language != '') {
$wordrtl = game_right_to_left( $attempt->language);
} else {
$wordrtl = right_to_left();
}
$reverseprint = ($wordrtl != right_to_left());
if ($game->toptext != '') {
echo $game->toptext.'<br>';
}
$max = $game->param10; // Maximum number of wrongs.
if ($max <= 0) {
$max = 6;
}
hangman_showpage( $done, $correct, $wrong, $max, $wordline, $wordline2, $links, $game,
$attempt, $hangman, $query, $onlyshow, $showsolution, $context);
if (!$done) {
if ($wrong > $max) {
$wrong = $max;
}
if ($game->param3 == 0) {
$game->param3 = 1;
}
echo "\r\n<br/><img src=\"".game_pix_url('hangman/'.$game->param3.'/hangman_'.$wrong, 'mod_game')."\"";
$message = sprintf( get_string( 'hangman_wrongnum', 'game'), $wrong, $max);
echo ' ALIGN="MIDDLE" BORDER="0" HEIGHT="100" alt="'.$message.'"/>';
if ($wrong >= $max) {
// This word is incorrect. If reach the max number of word I have to finish else continue with next word.
hangman_onincorrect( $id, $wordline, $query->answertext, $game, $attempt, $hangman, $onlyshow, $showsolution);
} else {
$i = $max - $wrong;
if ($i > 1) {
echo ' '.get_string( 'hangman_restletters_many', 'game', $i);
} else {
echo ' '.get_string( 'hangman_restletters_one', 'game');
}
if ($reverseprint) {
echo '<SPAN dir="'.($wordrtl ? 'rtl' : 'ltr').'">';
}
echo "<br/><font size=\"5\">\n$wordline</font>\r\n";
if ($wordline2 != '') {
echo "<br/><font size=\"5\">\n$wordline2</font>\r\n";
}
if ($reverseprint) {
echo "</SPAN>";
}
if ($hangman->finishedword == false) {
echo "<br/><br/><BR/>".get_string( 'hangman_letters', 'game').' '.$links."\r\n";
}
}
} else {
// This word is correct. If reach the max number of word I have to finish else continue with next word.
hangman_oncorrect( $id, $wordline, $game, $attempt, $hangman, $query);
}
echo "<br/><br/>".get_string( 'grade', 'game').' : '.round( $query->percent * 100).' %';
if ($hangman->maxtries > 1) {
$percent = ($correct - $wrong / $max) / game_strlen( $query->answertext);
if ($done) {
$percent = 0;
}
$score = $hangman->corrects / $hangman->maxtries + $percent / $hangman->maxtries;
echo '<br/><br/>'.get_string( 'hangman_gradeinstance', 'game').' : '.
round( $score * 100).' %';
}
if ($game->bottomtext != '') {
echo '<br><br>'.$game->bottomtext;
}
}
/**
* Shows page.
*
* @param boolean $done
* @param boolean $correct
* @param boolean $wrong
* @param int $max
* @param string $wordline
* @param string $wordline2
* @param array $links
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hangman
* @param stdClass $query
* @param boolean $onlyshow
* @param boolean $showsolution
* @param stdClass $context
*/
function hangman_showpage(&$done, &$correct, &$wrong, $max, &$wordline, &$wordline2, &$links,
$game, &$attempt, &$hangman, &$query, $onlyshow, $showsolution, $context) {
global $USER, $CFG, $DB;
$id = optional_param('id', 0, PARAM_INT); // Course Module ID.
$word = $query->answertext;
$newletter = optional_param('newletter', "", PARAM_TEXT);
if ( $newletter == '_') {
$newletter = ' ';
}
$letters = $hangman->letters;
if ($newletter != null) {
if (game_strpos( $letters, $newletter) === false) {
$letters .= $newletter;
}
}
$links = "";
$alpha = $hangman->allletters;
$wrong = 0;
if ($query->questionid) {
$questiontext = str_replace( array("\'", '\"'), array("'", '"'), $query->questiontext);
$query->questiontext = game_filterquestion($questiontext, $query->questionid, $context->id, $game->course);
} else {
$glossary = $DB->get_record_sql( "SELECT id,course FROM {$CFG->prefix}glossary WHERE id={$game->glossaryid}");
$cmglossary = get_coursemodule_from_instance('glossary', $game->glossaryid, $glossary->course);
$contextglossary = game_get_context_module_instance( $cmglossary->id);
$query->questiontext = game_filterglossary(str_replace( '\"', '"',
$query->questiontext), $query->glossaryentryid, $contextglossary->id, $game->course);
}
if ($game->param5) {
$s = trim( game_filtertext( $query->questiontext, $game->course));
if ($s != '.' and $s <> '') {
echo "<br/><b>".$s.'</b>';
}
if ($query->attachment != '') {
$file = "{$CFG->wwwroot}/file.php/$game->course/moddata/$query->attachment";
echo "<img src=\"$file\" />";
}
echo "<br/><br/>";
}
$wordline = $wordline2 = "";
$len = game_strlen( $word);
$done = 1;
$answer = '';
$correct = 0;
for ($x = 0; $x < $len; $x++) {
$char = game_substr( $word, $x, 1);
if ($showsolution) {
$wordline2 .= ( $char == " " ? '&nbsp; ' : $char);
$done = 0;
}
if (game_strpos($letters, $char) === false) {
$wordline .= "_<font size=\"1\">&nbsp;</font>\r\n";
$done = 0;
$answer .= '_';
} else {
$wordline .= ( $char == " " ? '&nbsp; ' : $char);
$answer .= $char;
$correct++;
}
}
$lenalpha = game_strlen( $alpha);
$fontsize = 5;
for ($c = 0; $c < $lenalpha; $c++) {
$char = game_substr( $alpha, $c, 1);
if (game_strpos($letters, $char) === false) {
// User doesn't select this character.
$params = 'id='.$id.'&amp;newletter='.urlencode( $char);
if ($onlyshow or $showsolution) {
$links .= $char;
} else {
$links .= "<font size=\"$fontsize\"><a href=\"attempt.php?$params\">$char</a></font>\r\n";
}
continue;
}
if (game_strpos($word, $char) === false) {
$links .= "\r\n<font size=\"$fontsize\" color=\"red\">$char </font>";
$wrong++;
} else {
$links .= "\r\n<B><font size=\"$fontsize\">$char </font></B> ";
}
}
$finishedword = ($done or $wrong >= $max);
$finished = false;
$updrec = new stdClass();
$updrec->id = $hangman->id;
$updrec->letters = $letters;
if ($finishedword) {
if ($hangman->finishedword == 0) {
// Only one time per word increace the variable try.
$hangman->try = $hangman->try + 1;
if ($hangman->try > $hangman->maxtries) {
$finished = true;
}
if ($done) {
$hangman->corrects = $hangman->corrects + 1;
$updrec->corrects = $hangman->corrects;
}
}
$updrec->try = $hangman->try;
$updrec->finishedword = 1;
}
$query->percent = ($correct - $wrong / $max) / game_strlen( $word);
if ($query->percent < 0) {
$query->percent = 0;
}
if ($onlyshow or $showsolution) {
return;
}
if (!$DB->update_record( 'game_hangman', $updrec)) {
print_error( "hangman_showpage: Can't update game_hangman id=$updrec->id");
}
if ($done) {
$score = 1;
} else if ($wrong >= $max) {
$score = 0;
} else {
$score = -1;
}
if ($hangman->maxtries > 0) {
$percent = ($correct - $wrong / $max) / game_strlen( $word);
$score = $hangman->corrects / $hangman->maxtries + $percent / $hangman->maxtries;
}
game_updateattempts( $game, $attempt, $score, $finished);
game_update_queries( $game, $attempt, $query, $score, $answer);
}
/**
* This word is correct. If reach the max number of words I have to finish else continue with next word.
*
* @param int $id
* @param string $wordline
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hangman
* @param stdClass $query
*/
function hangman_oncorrect( $id, $wordline, $game, $attempt, $hangman, $query) {
global $DB;
echo "<br/><br/><font size=\"5\">\n$wordline</font>\r\n";
echo '<p><br/><font size="5" color="green">'.get_string( 'win', 'game').'</font><BR/><BR/></p>';
if ($query->answerid) {
$feedback = $DB->get_field( 'question_answers', 'feedback', array( 'id' => $query->answerid));
if ($feedback != '') {
echo "$feedback<br>";
}
}
game_hangman_show_nextword( $id, $game, $attempt, $hangman);
}
/**
* On incorrect.
*
* @param int $id
* @param string $wordline
* @param string $word
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hangman
* @param boolean $onlyshow
* @param boolean $showsolution
*/
function hangman_onincorrect( $id, $wordline, $word, $game, $attempt, $hangman, $onlyshow, $showsolution) {
echo "\r\n<br/><br/><font size=\"5\">\n$wordline</font>\r\n";
if ( $onlyshow or $showsolution) {
return;
}
echo '<p><BR/><font size="5" color="red">'.get_string( 'hangman_loose', 'game').'</font><BR/><BR/></p>';
if ($game->param6) {
// Show the correct answer.
if (game_strpos($word, ' ') != false) {
echo '<br/>'.get_string( 'hangman_correct_phrase', 'game');
} else {
echo '<br/>'.get_string( 'hangman_correct_word', 'game');
}
echo '<B>'.$word."</B><BR/><BR/>\r\n";
}
game_hangman_show_nextword( $id, $game, $attempt, $hangman, true);
}
/**
* Shows the next word.
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hangman
*/
function game_hangman_show_nextword( $id, $game, $attempt, $hangman) {
global $CFG, $DB;
echo '<br/>';
if (($hangman->try < $hangman->maxtries) or ($hangman->maxtries == 0)) {
// Continue to next word.
$params = "id=$id&action2=nextword\">".get_string( 'nextword', 'game').'</a> &nbsp; &nbsp; &nbsp; &nbsp;';
echo "<a href=\"{$CFG->wwwroot}/mod/game/attempt.php?$params";
} else {
game_hangman_onfinishgame( $game, $attempt, $hangman);
if (game_can_start_new_attempt( $game)) {
echo "<a href=\"{$CFG->wwwroot}/mod/game/attempt.php?id=$id\">".
get_string( 'nextgame', 'game').'</a> &nbsp; &nbsp; &nbsp; &nbsp; ';
}
}
if (! $cm = $DB->get_record('course_modules', array( 'id' => $id))) {
print_error( "Course Module ID was incorrect id=$id");
}
echo "<a href=\"{$CFG->wwwroot}/course/view.php?id=$cm->course\">".get_string( 'finish', 'game').'</a> ';
}

101
headergame.php

@ -0,0 +1,101 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The header for many .php files.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once(dirname(__FILE__) . '/../../config.php');
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/mod/game/locallib.php');
require_once($CFG->libdir . '/completionlib.php');
$id = optional_param('id', 0, PARAM_INT); // Course Module ID.
$q = optional_param('q', 0, PARAM_INT); // Game ID.
if ($id) {
if (!$cm = get_coursemodule_from_id('game', $id)) {
print_error('invalidcoursemodule');
}
if (! $course = $DB->get_record('course', array('id' => $cm->course))) {
print_error('coursemisconf');
}
if (! $game = $DB->get_record('game', array('id' => $cm->instance))) {
print_error('invalidcoursemodule');
}
} else {
if (! $game = $DB->get_record('game', array('id' => $q))) {
print_error('invalidgameid q='.$q, 'game');
}
if (!$course = $DB->get_record('course', array('id' => $game->course))) {
print_error('invalidcourseid');
}
if (!$cm = get_coursemodule_from_instance('game', $game->id, $course->id)) {
print_error('invalidcoursemodule');
}
}
// Check login and get context.
require_login($course->id, false, $cm);
$context = game_get_context_module_instance( $cm->id);
require_capability('mod/game:view', $context);
// Cache some other capabilites we use several times.
$canattempt = has_capability('mod/game:attempt', $context);
$canreviewmine = has_capability('mod/game:reviewmyattempts', $context);
// Create an object to manage all the other (non-roles) access rules.
$timenow = time();
// Log this request.
if (game_use_events()) {
require( 'classes/event/course_module_viewed.php');
\mod_game\event\course_module_viewed::viewed($game, $context)->trigger();
} else {
add_to_log($course->id, 'game', 'view', "view.php?id=$cm->id", $game->id, $cm->id);
}
// Initialize $PAGE, compute blocks.
$PAGE->set_url('/mod/game/view.php', array('id' => $cm->id));
$edit = optional_param('edit', -1, PARAM_BOOL);
if ($edit != -1 && $PAGE->user_allowed_editing()) {
$USER->editing = $edit;
}
// Note: MDL-19010 there will be further changes to printing header and blocks.
// The code will be much nicer than this eventually.
$title = $course->shortname . ': ' . format_string($game->name);
if ($PAGE->user_allowed_editing() && !empty($CFG->showblocksonmodpages)) {
$buttons = '<table><tr><td><form method="get" action="view.php"><div>'.
'<input type="hidden" name="id" value="'.$cm->id.'" />'.
'<input type="hidden" name="edit" value="'.($PAGE->user_is_editing() ? 'off' : 'on').'" />'.
'<input type="submit" value="'.
get_string($PAGE->user_is_editing() ? 'blockseditoff' : 'blocksediton').
'" /></div></form></td></tr></table>';
$PAGE->set_button($buttons);
}
$PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();

BIN
hiddenpicture/numbers.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

152
hiddenpicture/picture.php

@ -0,0 +1,152 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Creates an image dynamically.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require( '../../../config.php');
require_login();
$id = required_param('id', PARAM_INT); // Course Module ID.
$attemptid = required_param('id2', PARAM_INT); // Course Module ID.
$foundcells = required_param('f', PARAM_SEQUENCE); // CSV.
$cells = required_param('cells', PARAM_SEQUENCE); // CSV.
$filehash = required_param('p', PARAM_PATH);
$cols = required_param('cols', PARAM_INT);
$rows = required_param('rows', PARAM_INT);
$filenamenumbers = required_param('n', PARAM_PATH); // Path to numbers picture.
create_image( $id, $attemptid, $foundcells, $cells, $filehash, $cols, $rows, $filenamenumbers);
/**
* Create an image.
*
* @param int $id
* @param int $attemptid
* @param boolean $foundcells
* @param stdClass $cells
* @param string $filehash
* @param int $cols
* @param int $rows
* @param string $filenamenumbers
*/
function create_image( $id, $attemptid, $foundcells, $cells, $filehash, $cols, $rows, $filenamenumbers) {
global $CFG;
$a = explode( ',', $foundcells);
$found = array();
foreach ($a as $s) {
$found[ $s] = 1;
}
$a = explode( ',', $cells);
$cells = array();
foreach ($a as $s) {
$cells[ $s] = 1;
}
$file = get_file_storage()->get_file_by_hash( $filehash);
$image = $file->get_imageinfo();
if ($image === false) {
die("Aknown filehash $filehash");
return false;
}
$imghandle = imagecreatefromstring($file->get_content());
$mime = $image[ 'mimetype'];
$imgnumbers = imagecreatefrompng( $filenamenumbers);
$sizenumbers = getimagesize ($filenamenumbers);
header("Content-type: $mime");
$color = imagecolorallocate( $imghandle, 100, 100, 100);
$width = $image[ 'width'];
$height = $image[ 'height'];
$pos = 0;
$font = 1;
for ($y = 0; $y < $rows; $y++) {
for ($x = 0; $x < $cols; $x++) {
$pos++;
if (!array_key_exists( $pos, $found)) {
$x1 = $x * $width / $cols;
$y1 = $y * $height / $rows;
imagefilledrectangle( $imghandle, $x1, $y1, $x1 + $width / $cols, $y1 + $height / $rows, $color);
if (array_key_exists( $pos, $cells)) {
shownumber( $imghandle, $imgnumbers, $pos, $x1 , $y1, $width / $cols, $height / $rows, $sizenumbers);
}
}
}
}
switch ($mime) {
case 'image/png':
imagepng ($imghandle);
break;
case 'image/jpeg':
imagejpeg ($imghandle);
break;
case 'image/gif':
imagegif ($imghandle);
break;
default:
die('Aknown mime type $mime');
return false;
}
imagedestroy ($imghandle);
}
/**
* Show number.
*
* @param object $imghandle
* @param object $imgnumbers
* @param int $number
* @param int $x1
* @param int $y1
* @param int $width
* @param int $height
* @param int $sizenumbers
*/
function shownumber( $imghandle, $imgnumbers, $number, $x1 , $y1, $width, $height, $sizenumbers) {
if ($number < 10) {
$widthnumber = $sizenumbers[ 0] / 10;
$dstx = $x1 + $width / 3;
$dsty = $y1 + $height / 3;
$srcx = $number * $sizenumbers[ 0] / 10;
$srcw = $sizenumbers[ 0] / 10;
$srch = $sizenumbers[ 1];
$dstw = $width / 10;
$dsth = $dstw * $srch / $srcw;
imagecopyresized( $imghandle, $imgnumbers, $dstx, $dsty, $srcx, 0, $dstw, $dsth, $srcw, $srch);
} else {
$number1 = floor( $number / 10);
$number2 = $number % 10;
shownumber( $imghandle, $imgnumbers, $number1, $x1 - $width / 20, $y1, $width, $height, $sizenumbers);
shownumber( $imghandle, $imgnumbers, $number2, $x1 + $width / 20, $y1, $width, $height, $sizenumbers);
}
}

510
hiddenpicture/play.php

@ -0,0 +1,510 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file plays the game Hidden Picture.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Plays the game "Hidden picture"
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hiddenpicture
* @param stdClass $context
*/
function game_hiddenpicture_continue( $id, $game, $attempt, $hiddenpicture, $context) {
global $DB, $USER;
if ($attempt != false and $hiddenpicture != false) {
// Continue a previous attempt.
return game_hiddenpicture_play( $id, $game, $attempt, $hiddenpicture, false, $context);
}
if ($attempt == false) {
// Start a new attempt.
$attempt = game_addattempt( $game);
}
$cols = $game->param1;
$rows = $game->param2;
if ($cols == 0) {
print_error( get_string( 'hiddenpicture_nocols', 'game'));
}
if ($rows == 0) {
print_error( get_string( 'hiddenpicture_norows', 'game'));
}
// New attempt.
$n = $game->param1 * $game->param2;
$recs = game_questions_selectrandom( $game, CONST_GAME_TRIES_REPETITION * $n);
$selectedrecs = game_select_from_repetitions( $game, $recs, $n);
$newrec = game_hiddenpicture_selectglossaryentry( $game, $attempt);
if ($recs === false) {
print_error( get_string( 'no_questions', 'game'));
}
$positions = array();
$pos = 1;
for ($col = 0; $col < $cols; $col++) {
for ($row = 0; $row < $rows; $row++) {
$positions[] = $pos++;
}
}
$i = 0;
$field = ($game->sourcemodule == 'glossary' ? 'glossaryentryid' : 'questionid');
foreach ($recs as $rec) {
if ($game->sourcemodule == 'glossary') {
$key = $rec->glossaryentryid;
} else {
$key = $rec->questionid;
}
if (!array_key_exists( $key, $selectedrecs)) {
continue;
}
$query = new stdClass();
$query->attemptid = $newrec->id;
$query->gamekind = $game->gamekind;
$query->gameid = $game->id;
$query->userid = $USER->id;
$pos = array_rand( $positions);
$query->col = $positions[ $pos];
unset( $positions[ $pos]);
$query->sourcemodule = $game->sourcemodule;
$query->questionid = $rec->questionid;
$query->glossaryentryid = $rec->glossaryentryid;
$query->score = 0;
if (($query->id = $DB->insert_record( 'game_queries', $query)) == 0) {
print_error( 'error inserting in game_queries');
}
game_update_repetitions($game->id, $USER->id, $query->questionid, $query->glossaryentryid);
}
// The score is zero.
game_updateattempts( $game, $attempt, 0, 0);
game_hiddenpicture_play( $id, $game, $attempt, $newrec, false, $context);
}
/**
* Create the game_hiddenpicture record.
*
* @param stdClass $game
* @param stdClass $attempt
*/
function game_hiddenpicture_selectglossaryentry( $game, $attempt) {
global $CFG, $DB, $USER;
srand( (double)microtime() * 1000000);
if ($game->glossaryid2 == 0) {
print_error( get_string( 'must_select_glossary', 'game'));
}
$select = "ge.glossaryid={$game->glossaryid2}";
$table = '{glossary_entries} ge';
if ($game->glossarycategoryid2) {
$table .= ",{glossary_entries_categories} gec";
$select .= " AND gec.entryid = ge.id AND gec.categoryid = {$game->glossarycategoryid2}";
}
if ($game->param7 == 0) {
// Allow spaces.
$select .= " AND concept NOT LIKE '% %'";
}
$sql = "SELECT ge.id,attachment FROM $table WHERE $select";
if (($recs = $DB->get_records_sql( $sql)) == false) {
$a->name = "'".$DB->get_field('glossary', 'name', array( 'id' => $game->glossaryid2))."'";
print_error( get_string( 'hiddenpicture_nomainquestion', 'game', $a));
return false;
}
$ids = array();
$keys = array();
$fs = get_file_storage();
$cmg = get_coursemodule_from_instance('glossary', $game->glossaryid2, $game->course);
$context = game_get_context_module_instance( $cmg->id);
foreach ($recs as $rec) {
$files = $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $rec->id, "timemodified", false);
if ($files) {
foreach ($files as $key => $file) {
$s = strtoupper( $file->get_filename());
$s = substr( $s, -4);
if ($s == '.GIF' or $s == '.JPG' or $s == '.PNG') {
$ids[] = $rec->id;
$keys[] = $file->get_pathnamehash();
}
}
}
}
if (count( $ids) == 0) {
$a = new stdClass();
$a->name = "'".$DB->get_field( 'glossary', 'name', array( 'id' => $game->glossaryid2))."'";
print_error( get_string( 'hiddenpicture_nomainquestion', 'game', $a));
return false;
}
// Have to select randomly one glossaryentry.
$poss = array();
for ($i = 0; $i < count($ids); $i++) {
$poss[] = $i;
}
shuffle( $poss);
$minnum = 0;
$attachement = '';
for ($i = 0; $i < count($ids); $i++) {
$pos = $poss[ $i];
$tempid = $ids[ $pos];
$a = array( 'gameid' => $game->id, 'userid' => $USER->id, 'questionid' => 0, 'glossaryentryid' => $tempid);
if (($rec2 = $DB->get_record('game_repetitions', $a, 'id,repetitions r')) != false) {
if (($rec2->r < $minnum) or ($minnum == 0)) {
$minnum = $rec2->r;
$glossaryentryid = $tempid;
$attachement = $keys[ $pos];
}
} else {
$glossaryentryid = $tempid;
$attachement = $keys[ $pos];
break;
}
}
$sql = 'SELECT id, concept as answertext, definition as questiontext,'.
' id as glossaryentryid, 0 as questionid, glossaryid, attachment'.
' FROM {glossary_entries} WHERE id = '.$glossaryentryid;
if (($rec = $DB->get_record_sql( $sql)) == false) {
return false;
}
$query = new stdClass();
$query->attemptid = $attempt->id;
$query->gamekind = $game->gamekind;
$query->gameid = $game->id;
$query->userid = $USER->id;
$query->col = 0;
$query->sourcemodule = 'glossary';
$query->questionid = 0;
$query->glossaryentryid = $rec->glossaryentryid;
$query->attachment = $attachement;
$query->questiontext = $rec->questiontext;
$query->answertext = $rec->answertext;
$query->score = 0;
if (($query->id = $DB->insert_record( 'game_queries', $query)) == 0) {
print_error( 'Error inserting in game_queries');
}
$newrec = new stdClass();
$newrec->id = $attempt->id;
$newrec->correct = 0;
if (!game_insert_record( 'game_hiddenpicture', $newrec)) {
print_error( 'Error inserting in game_hiddenpicture');
}
game_update_repetitions($game->id, $USER->id, $query->questionid, $query->glossaryentryid);
return $newrec;
}
/**
* Plays the game "Hidden picture"
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hiddenpicture
* @param boolean $showsolution
* @param stdClass $context
*/
function game_hiddenpicture_play( $id, $game, $attempt, $hiddenpicture, $showsolution, $context) {
if ($game->toptext != '') {
echo $game->toptext.'<br>';
}
// Show picture.
$offsetquestions = game_sudoku_compute_offsetquestions( $game->sourcemodule, $attempt, $numbers, $correctquestions);
unset( $offsetquestions[ 0]);
game_hiddenpicture_showhiddenpicture( $id, $game, $attempt, $hiddenpicture, $showsolution,
$offsetquestions, $correctquestions, $id, $attempt, $showsolution);
// Show questions.
$onlyshow = false;
$showsolution = false;
switch ($game->sourcemodule) {
case 'quiz':
case 'question':
game_sudoku_showquestions_quiz( $id, $game, $attempt, $hiddenpicture, $offsetquestions,
$numbers, $correctquestions, $onlyshow, $showsolution, $context);
break;
case 'glossary':
game_sudoku_showquestions_glossary( $id, $game, $attempt, $hiddenpicture,
$offsetquestions, $numbers, $correctquestions, $onlyshow, $showsolution);
break;
}
if ($game->bottomtext != '') {
echo '<br><br>'.$game->bottomtext;
}
}
/**
* "Hidden picture" compute score
*
* @param stdClass $game
* @param stdClass $hiddenpicture
*/
function game_hidden_picture_computescore( $game, $hiddenpicture) {
$correct = $hiddenpicture->correct;
if ($hiddenpicture->found) {
$correct++;
}
$remaining = $game->param1 * $game->param2 - $hiddenpicture->correct;
$div2 = $correct + $hiddenpicture->wrong + $remaining;
if ($hiddenpicture->found) {
$percent = ($correct + $remaining) / $div2;
} else {
$percent = $correct / $div2;
}
return $percent;
}
/**
* Show hidden picture
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hiddenpicture
* @param boolean $showsolution
* @param int $offsetquestions
* @param int $correctquestions
*/
function game_hiddenpicture_showhiddenpicture( $id, $game, $attempt, $hiddenpicture, $showsolution,
$offsetquestions, $correctquestions) {
global $DB;
$foundcells = '';
foreach ($correctquestions as $key => $val) {
$foundcells .= ','.$key;
}
$cells = '';
foreach ($offsetquestions as $key => $val) {
if ($key != 0) {
$cells .= ','.$key;
}
}
$query = $DB->get_record_select( 'game_queries', "attemptid=$hiddenpicture->id AND col=0",
null, 'id,glossaryentryid,attachment,questiontext');
// Grade.
echo "<br/>".get_string( 'grade', 'game').' : '.round( $attempt->score * 100).' %';
game_hiddenpicture_showquestion_glossary( $game, $id, $query);
$cells = substr( $cells, 1);
$foundcells = substr( $foundcells, 1);
game_showpicture( $id, $game, $attempt, $query, $cells, $foundcells, true);
}
/**
* hidden picture. show question glossary
*
* @param stdClass $game
* @param int $id
* @param stdClass $query
*/
function game_hiddenpicture_showquestion_glossary( $game, $id, $query) {
global $CFG, $DB;
$entry = $DB->get_record( 'glossary_entries', array( 'id' => $query->glossaryentryid));
// Start the form.
echo '<br>';
echo "<form id=\"responseform\" method=\"post\" ".
"action=\"{$CFG->wwwroot}/mod/game/attempt.php\" onclick=\"this.autocomplete='off'\">\n";
echo "<center><input type=\"submit\" name=\"finishattempt\" ".
"value=\"".get_string('hiddenpicture_mainsubmit', 'game')."\"></center>\n";
// Add a hidden field with the queryid.
echo '<input type="hidden" name="id" value="' . s($id) . "\" />\n";
echo '<input type="hidden" name="action" value="hiddenpicturecheckg" />';
echo '<input type="hidden" name="queryid" value="' . $query->id . "\" />\n";
// Add a hidden field with glossaryentryid.
echo '<input type="hidden" name="glossaryentryid" value="'.$query->glossaryentryid."\" />\n";
$temp = $game->glossaryid;
$game->glossaryid = $game->glossaryid2;
echo game_show_query( $game, $query, $entry->definition);
$game->glossaryid = $temp;
echo get_string( 'answer').': ';
echo "<input type=\"text\" name=\"answer\" size=30 /><br>";
echo "</form><br>\n";
}
/**
* Check main question
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $hiddenpicture
* @param boolean $finishattempt
* @param stdClass $context
*/
function game_hiddenpicture_check_mainquestion( $id, $game, &$attempt, &$hiddenpicture, $finishattempt, $context) {
global $CFG, $DB;
$responses = data_submitted();
$glossaryentryid = $responses->glossaryentryid;
$queryid = $responses->queryid;
// Load the glossary entry.
if (!($entry = $DB->get_record( 'glossary_entries', array( 'id' => $glossaryentryid)))) {
print_error( get_string( 'noglossaryentriesfound', 'game'));
}
$answer = $responses->answer;
$correct = false;
if ($answer != '') {
if (game_upper( $entry->concept) == game_upper( $answer)) {
$correct = true;
}
}
// Load the query.
if (!($query = $DB->get_record( 'game_queries', array( 'id' => $queryid)))) {
print_error( "The query $queryid not found");
}
game_update_queries( $game, $attempt, $query, $correct, $answer);
if ($correct) {
$hiddenpicture->found = 1;
} else {
$hiddenpicture->wrong++;
}
if (!$DB->update_record( 'game_hiddenpicture', $hiddenpicture)) {
print_error( 'game_hiddenpicture_check_mainquestion: error updating in game_hiddenpicture');
}
$score = game_hidden_picture_computescore( $game, $hiddenpicture);
game_updateattempts( $game, $attempt, $score, $correct);
if ($correct == false) {
game_hiddenpicture_play( $id, $game, $attempt, $hiddenpicture, false, $context);
return true;
}
// Finish the game.
$query = $DB->get_record_select( 'game_queries', "attemptid=$hiddenpicture->id AND col=0",
null, 'id,glossaryentryid,attachment,questiontext');
game_showpicture( $id, $game, $attempt, $query, '', '', false);
echo '<p><br/><font size="5" color="green">'.get_string( 'win', 'game').'</font><BR/><BR/></p>';
global $CFG;
echo '<br/>';
echo "<a href=\"$CFG->wwwroot/mod/game/attempt.php?id=$id\">";
echo get_string( 'nextgame', 'game').'</a> &nbsp; &nbsp; &nbsp; &nbsp;';
if (! $cm = $DB->get_record( 'course_modules', array( 'id' => $id))) {
print_error( "Course Module ID was incorrect id=$id");
}
echo "<a href=\"{$CFG->wwwroot}/course/view.php?id=$cm->course\">".get_string( 'finish', 'game').'</a> ';
return false;
}
/**
* Show picture
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $query
* @param object $cells
* @param int $foundcells
* @param boolean $usemap
*/
function game_showpicture( $id, $game, $attempt, $query, $cells, $foundcells, $usemap) {
global $CFG;
$filenamenumbers = str_replace( "\\", '/', $CFG->dirroot)."/mod/game/hiddenpicture/numbers.png";
if ($usemap) {
$cols = $game->param1;
$rows = $game->param2;
} else {
$cols = $rows = 0;
}
$params = "id=$id&id2=$attempt->id&f=$foundcells&cols=$cols&rows=$rows&cells=$cells&p={$query->attachment}&n=$filenamenumbers";
$imagesrc = "hiddenpicture/picture.php?$params";
$fs = get_file_storage();
$file = get_file_storage()->get_file_by_hash( $query->attachment);
$image = $file->get_imageinfo();
if ($game->param4 > 10) {
$width = $game->param4;
$height = $image[ 'height'] * $width / $image[ 'width'];
} else if ( $game->param5 > 10) {
$height = $game->param5;
$width = $image[ 'width'] * $height / $image[ 'height'];
} else {
$width = $image[ 'width'];
$height = $image[ 'height'];
}
echo "<IMG SRC=\"$imagesrc\" width=$width ";
if ($usemap) {
echo " USEMAP=\"#mapname\" ";
}
echo " BORDER=\"1\">\r\n";
if ($usemap) {
echo "<MAP NAME=\"mapname\">\r\n";
$pos = 0;
for ($row = 0; $row < $rows; $row++) {
for ($col = 0; $col < $cols; $col++) {
$pos++;
$x1 = $col * $width / $cols;
$y1 = $row * $height / $rows;
$x2 = $x1 + $width / $cols;
$y2 = $y1 + $height / $rows;
$q = "a$pos";
echo "<AREA SHAPE=\"rect\" COORDS=\"$x1,$y1,$x2,$y2\" HREF=\"#$q\" ALT=\"$pos\">\r\n";
}
}
echo "</MAP>";
}
}

BIN
images/soundplay.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

111
index.php

@ -0,0 +1,111 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page lists all the instances of game module in a particular course
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once("../../config.php");
require_once("lib.php");
require_once("locallib.php");
$id = required_param('id', PARAM_INT); // It stores the courseid.
if (! $course = $DB->get_record( 'course', array( 'id' => $id))) {
print_error( 'Course ID is incorrect');
}
require_login($course->id);
// Get all required strings game.
$strgames = get_string( 'modulenameplural', 'game');
$strgame = get_string('modulename', 'game');
// Print the header.
$PAGE->set_url('/mod/game/index.php', array('id' => $id));
$coursecontext = game_get_context_course_instance( $id);
$PAGE->set_pagelayout('incourse');
if (game_use_events()) {
require( 'classes/event/course_module_instance_list_viewed.php');
\mod_game\event\course_module_instance_list_viewed::create_from_course($course)->trigger();
} else {
add_to_log($course->id, "game", "view all", "index.php?id=$course->id", "");
}
// Print the header.
$strgames = get_string("modulenameplural", "game");
$streditquestions = '';
$editqcontexts = new question_edit_contexts($coursecontext);
$PAGE->navbar->add($strgames);
$PAGE->set_title($strgames);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
// Get all the appropriate data.
if (! $games = get_all_instances_in_course("game", $course)) {
notice("There are no games", "../../course/view.php?id=$course->id");
die;
}
// Print the list of instances (your module will probably extend this).
$timenow = time();
$strname = get_string("name");
$strweek = get_string("week");
$strtopic = get_string("topic");
$table = new html_table();
if ($course->format == "weeks") {
$table->head = array ($strweek, $strname);
$table->align = array ("center", "left");
} else if ($course->format == "topics") {
$table->head = array ($strtopic, $strname);
$table->align = array ("center", "left", "left", "left");
} else {
$table->head = array ($strname);
$table->align = array ("left", "left", "left");
}
foreach ($games as $game) {
if (!$game->visible) {
// Show dimmed if the mod is hidden.
$link = "<a class=\"dimmed\" href=\"view.php?id=$game->coursemodule\">$game->name</a>";
} else {
// Show normal if the mod is visible.
$link = "<a href=\"view.php?id=$game->coursemodule\">$game->name</a>";
}
if ($course->format == "weeks" or $course->format == "topics") {
$table->data[] = array ($game->section, $link);
} else {
$table->data[] = array ($link);
}
}
echo "<br />";
echo html_writer::table($table);
// Finish the page.
echo $OUTPUT->footer($course);

373
lang/en/game.php

@ -0,0 +1,373 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'game', language 'en', branch 'MOODLE_20_STABLE'
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
// File bookquiz/importodt.php.
$string[ 'bookquiz_not_select_book'] = 'You have not select book';
// File bookquiz/play.php.
$string[ 'bookquiz_empty'] = 'The book is empty';
$string[ 'sudoku_submit'] = 'Grade answers';
// File bookquiz/questions.php.
$string[ 'bookquiz_categories'] = 'Categories';
$string[ 'bookquiz_chapters'] = 'Chapters';
$string[ 'bookquiz_numquestions'] = 'Questions';
// Check.php.
$string[ 'common_problems'] = 'Common problems';
$string[ 'millionaire_also_multichoice'] = 'Multichoice answers without single correct answer';
$string[ 'common_problems_allowspaces'] = 'There are words with spaces but in the game, spaces are not allowed';
$string[ 'common_problems_shortanswer_hangman'] = 'Not all characters are in the language of game';
$string[ 'common_problems_crossword_param1'] = "'Maximum number of cols/rows' is too small";
$string[ 'millionaire_no_multichoice_questions'] = 'There are no multichoice questions';
// Classes.
$string[ 'eventgamecreated'] = 'Game created';
$string[ 'eventgamedeleted'] = 'Game deleted';
$string[ 'eventgamesupdated'] = 'Game updated';
$string[ 'eventgameviewed'] = 'Game viewed';
$string[ 'eventgameplayed'] = 'Game played';
// File cross/cross_class.php.
$string[ 'lettersall'] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// File cross/crossdb_class.php.
$string[ 'and'] = 'and';
$string[ 'cross_correct'] = 'corrert character';
$string[ 'cross_corrects'] = 'correct characters';
$string[ 'cross_error'] = 'wrong character';
$string[ 'cross_errors'] = 'wrong characters';
$string[ 'cross_found_many'] = 'Found';
$string[ 'cross_found_one'] = 'Found';
$string[ 'grade'] = 'Grade';
$string[ 'cross_disabletransformuppercase'] = 'Disables text-transform:uppercase in CSS';
// File cross/play.php.
$string[ 'cross_across'] = 'Across';
$string[ 'cross_checkbutton'] = 'Check crossword';
$string[ 'cross_down'] = 'Down';
$string[ 'cross_endofgamebutton'] = 'End of crossword game';
$string[ 'cross_error_containsbadchars'] = 'The word contains illegal characteres';
$string[ 'cross_error_wordlength1'] = 'The correct word contains ';
$string[ 'cross_error_wordlength2'] = ' letters.';
$string[ 'cross_pleasewait'] = 'Please wait while cross is loading';
$string[ 'cross_welcome'] = '<h3>Welcome!</h3><p>Click on a word to begin/continue.</p>';
$string[ 'letter'] = 'letter';
$string[ 'letters'] = 'letters';
$string[ 'nextgame'] = 'New game';
$string[ 'no_words'] = 'There are no words';
$string[ 'print'] = 'Print';
$string[ 'win'] = 'Congratulations !!!';
// File cryptex/play.php.
$string[ 'finish'] = 'End of game';
// File db/access.php.
$string[ 'game:addinstance'] = 'Add a new game';
$string[ 'game:attempt'] = 'Play game';
$string[ 'game:deleteattempts'] = 'Delete attempts';
$string[ 'game:grade'] = 'Grade games manually';
$string[ 'game:manage'] = 'Manage';
$string[ 'game:manageoverrides'] = 'Manage game overrides';
$string[ 'game:preview'] = 'Preview Games';
$string[ 'game:reviewmyattempts'] = 'reviewmyattempts';
$string[ 'game:view'] = 'view';
$string[ 'game:viewreports'] = 'viewreports';
// File hangman/play.php.
$string[ 'hangman_correct_phrase'] = 'The correct phrase was: ';
$string[ 'hangman_correct_word'] = 'The correct word was: ';
$string[ 'hangman_gradeinstance'] = 'Grade in whole game';
$string[ 'hangman_letters'] = 'Letters: ';
$string[ 'hangman_restletters_many'] = 'You have <b>{$a}</b> tries';
$string[ 'hangman_restletters_one'] = 'You have <b>ONLY 1</b> try';
$string[ 'hangman_wrongnum'] = 'Wrong: %d out of %d';
$string[ 'nextword'] = 'Next word';
// File hiddenpicture/play.php.
$string[ 'hiddenpicture_mainsubmit'] = 'Grade main answer';
$string[ 'hiddenpicture_nocols'] = 'Have to specify the number of cols horizontaly';
$string[ 'hiddenpicture_nomainquestion'] = 'There are no glossary entries on glossary {$a->name} with an attached picture';
$string[ 'hiddenpicture_norows'] = 'Have to specify the number of cols verticaly';
$string[ 'must_select_glossary'] = 'You must select a glossary';
$string[ 'no_questions'] = "There are no questions";
$string[ 'noglossaryentriesfound'] = 'No glossary entries found';
// File millionaire/play.php.
$string[ 'millionaire_must_select_questioncategory'] = 'You must select one question category';
$string[ 'millionaire_must_select_quiz'] = 'You must select one quiz';
$string[ 'millionaire_lettersall'] = '-';
// File report/overview/report.php.
$string[ 'allattempts'] = 'Show all tries';
$string[ 'allstudents'] = 'Show all $a';
$string[ 'attemptduration'] = 'Attempt duration';
$string[ 'attemptsonly'] = 'Show only students with attempts';
$string[ 'deleteattemptcheck'] = 'Are you absolutely sure you want to completely delete these attempts?';
$string[ 'displayoptions'] = 'Display options';
$string[ 'downloadods'] = 'Download in ODS format';
$string[ 'feedback'] = 'Feedback';
$string[ 'noattemptsonly'] = 'Show $a with no attempts only';
$string[ 'numattempts'] = '$a->studentnum $a->studentstring have made $a->attemptnum attempts';
$string[ 'pagesize'] = 'Questions per page:';
$string[ 'reportoverview'] = 'Overview';
$string[ 'selectall'] = 'Select all';
$string[ 'selectnone'] = 'Deselect all';
$string[ 'showdetailedmarks'] = 'Show mark details';
$string[ 'startedon'] = 'Started on';
$string[ 'timecompleted'] = 'Completed';
$string[ 'unfinished'] = 'open';
$string[ 'withselected'] = 'With selected';
// File snakes/play.php.
$string[ 'snakes_dice'] = 'Dice, $a spots.';
$string[ 'snakes_player'] = 'Player, position: $a.';
// File sudoku/create.php.
$string[ 'sudoku_create_count'] = 'Number of sudokus that will be created';
$string[ 'sudoku_create_start'] = 'Start creating sudokus';
$string[ 'sudoku_creating'] = 'Creating <b>{$a}</b> sudoku';
// File sudoku/play.php.
$string[ 'sudoku_finishattemptbutton'] = 'End of game';
$string[ 'sudoku_guessnumber'] = 'Guess the correct number';
$string[ 'sudoku_noentriesfound'] = 'No words found in glossary';
// File export.php.
$string[ 'export'] = 'Export';
$string[ 'html_hascheckbutton'] = 'Has check button:';
$string[ 'html_hasprintbutton'] = 'Has print button:';
$string[ 'html_title'] = 'Title of html:';
$string[ 'javame_createdby'] = 'Created by:';
$string[ 'javame_description'] = 'Description:';
$string[ 'javame_filename'] = 'Filename:';
$string[ 'javame_icon'] = 'Icon:';
$string[ 'javame_maxpictureheight'] = 'Max picture height:';
$string[ 'javame_maxpicturewidth'] = 'Max picture width:';
$string[ 'javame_name'] = 'Name:';
$string[ 'javame_type'] = 'Type:';
$string[ 'javame_vendor'] = 'Vendor:';
$string[ 'javame_version'] = 'Version:';
// File exporthtml_hangman.php.
$string[ 'hangman_loose'] = '<BIG><B>Game over</B></BIG>';
$string[ 'html_hangman_new'] = 'New';
// File exporthtml_millionaire.php.
$string[ 'millionaire_helppeople'] = 'Help of people';
$string[ 'millionaire_info_people'] = 'People say';
$string[ 'millionaire_info_telephone'] = 'I think that the correct answer is ';
$string[ 'millionaire_info_wrong_answer'] = 'Your answer is wrong<br>The right answer is:';
$string[ 'millionaire_quit'] = 'Quit';
$string[ 'millionaire_sourcemodule_must_quiz_question'] = 'For the millionaire the source must be {$a} or questions and not';
$string[ 'millionaire_telephone'] = 'Help of telephone';
$string[ 'must_select_questioncategory'] = 'You must select a question category';
$string[ 'must_select_quiz'] = 'You must select a quiz';
// File exporthtml_snakes.php.
$string[ 'html_snakes_check'] = 'Check';
$string[ 'html_snakes_correct'] = 'Correct!';
$string[ 'html_snakes_no_selection'] = 'Have to select something!';
$string[ 'html_snakes_wrong'] = "Your answer isn't correct. Stay on the same seat.";
$string[ 'score'] = 'Score';
// File index.php.
$string[ 'helpbookquiz'] = 'When the student answers correct can go to the next chapter.';
$string[ 'helpcross'] = 'This game takes words from either a Glossary or quiz short answer questions and generates a random crossword puzzle. Teacher can set the maximum number of columns/rows or words that contains. Student can press the button “Check crossword” to check if the answers are correct. Every crossword is dynamic so it is different to every student.';
$string[ 'helpcryptex'] = 'This game is like a crossword but the answers are hidden inside a random cryptex.';
$string[ 'helphangman'] = 'This game takes words from either a Glossary or quiz short answer questions and generates a hangman puzzle. Teacher can set the number of words that each game contains, if shows the first or last letter, or if show the question or the answer at the end.';
$string[ 'helphiddenpicture'] = 'The hidden picture game uncovers each piece of a picture for each question correctly answered by the student. Each number in the hidden picture game displays a question to the student such that when the student answers the question correctly, the number is uncovered to display a piece of the picture.';
$string[ 'helpmillionaire'] = 'A question is displayed to the student which if answered correctly moves up to the next number in the game until the user has completed the questions. If a question is answered incorrectly, the game is over.';
$string[ 'helpsnakes'] = 'A question is displayed to the student which if answered correctly, displays a number on the dice, then game piece moves up the number displayed on the dice.';
$string[ 'helpsudoku'] = 'This game shows a sudoku puzzle to the students with not enough numbers to allow it to be solved. For each question the student correctly answers an additional number is slotted into the puzzle to make it easier to solve.';
$string['modulename'] = 'Game';
$string['modulename_help'] = 'This module contains 8 games: Hangman,Crossword, Cryptex, Millionaire, Sudoku, The hidden picture, Snakes and Ladders and Book with questions';
$string[ 'modulenameplural'] = 'Games';
$string[ 'pluginadministration'] = 'Game administration';
$string[ 'pluginname'] = 'Game';
// File lib.php.
$string[ 'attempt'] = 'Attempt';
$string[ 'bookquiz_questions'] = 'Associate question categories to chapter of book';
$string[ 'export_to_html'] = 'Export to HTML';
$string[ 'export_to_javame'] = 'Export to Javame';
$string[ 'game_bookquiz'] = 'Book with questions';
$string[ 'game_cross'] = 'Crossword';
$string[ 'game_cryptex'] = 'Cryptex';
$string[ 'game_hangman'] = 'Hangman';
$string[ 'game_hiddenpicture'] = 'Hidden Picture';
$string[ 'game_millionaire'] = 'Millionaire';
$string[ 'game_snakes'] = 'Snakes and Ladders';
$string[ 'game_sudoku'] = 'Sudoku';
$string[ 'info'] = 'Info';
$string[ 'noattempts'] = 'No attempts have been made on this game';
$string[ 'percent'] = 'Percent';
$string[ 'reset_game_all'] = 'Delete tries from all games';
$string[ 'reset_game_deleted_course'] = 'Delete tries from deleted courses';
$string[ 'results'] = 'Results';
$string[ 'showanswers'] = 'Show answers';
$string[ 'showattempts'] = 'Show attempts';
// File locallib.php.
$string[ 'attemptfirst'] = 'First attempt';
$string[ 'attemptlast'] = 'Last attempt';
$string[ 'convertfrom'] = '-';
$string[ 'convertto'] = '-';
$string[ 'gradeaverage'] = 'Average grade';
$string[ 'gradehighest'] = 'Highest grade';
// File mod_form.php.
$string[ 'bookquiz_layout'] = 'Layout';
$string[ 'bookquiz_layout0'] = 'Question at the top of the book';
$string[ 'bookquiz_layout1'] = 'Question at the bottom of the book';
$string[ 'bookquiz_options'] = 'Bookquiz options';
$string[ 'bottomtext'] = 'Text at the bottom of page';
$string[ 'cross_layout'] = 'Layout';
$string[ 'cross_layout0'] = 'Phrases on the bottom of cross';
$string[ 'cross_layout1'] = 'Phrases on the right of cross';
$string[ 'cross_maxcols'] = 'Maximum number of cols/rows';
$string[ 'cross_max_attempts'] = 'Maximum number of attempts';
$string[ 'cross_maxcomputetime'] = 'Maximum compute time in seconds';
$string[ 'cross_maxwords'] = 'Maximum number of words';
$string[ 'cross_minwords'] = 'Minimum number of words';
$string[ 'cross_options'] = 'Crossword options';
$string[ 'cryptex_maxtries'] = 'Max tries';
$string[ 'cryptex_options'] = 'Cryptex options';
$string[ 'disablesummarize'] = 'Disable summarize';
$string[ 'gameclose'] = 'Close the game';
$string[ 'gameopen'] = 'Open the game';
$string[ 'gameopenclose'] = 'Open and close dates';
$string[ 'gameopenclose_help'] = 'Students can only start their attempt(s) after the open time and they must complete their attempts before the close time.';
$string[ 'grademethod'] = 'Grading method';
$string[ 'glossary_only_approved'] = "Only approved or teacher's glossary entries";
$string[ 'hangman_allowspaces'] = 'Allow spaces in words';
$string[ 'hangman_allowsub'] = 'Allow the symbol - in words';
$string[ 'hangman_imageset'] = 'Select the images of hangman';
$string[ 'hangman_language'] = 'Language of words';
$string[ 'hangman_maximum_number_of_errors'] = 'Maximum number or errors (have to be images named hangman_0.jpg, hangman_1.jpg, ...)';
$string[ 'hangman_maxtries'] = 'Number of words per game';
$string[ 'hangman_options'] = 'Hangman options';
$string[ 'hangman_showcorrectanswer'] = 'Show the correct answer after the end';
$string[ 'hangman_showfirst'] = 'Show first letter of hangman';
$string[ 'hangman_showlast'] = 'Show last letter of hangman';
$string[ 'hangman_showquestion'] = 'Show the questions ?';
$string[ 'language_user_defined'] = 'User defined language';
$string[ 'hiddenpicture_across'] = 'Cells horizontal';
$string[ 'hiddenpicture_down'] = 'Cells down';
$string[ 'hiddenpicture_height'] = 'Set height of picture to (in pixels)';
$string[ 'hiddenpicture_options'] = '\'Hidden Picture\' options';
$string[ 'hiddenpicture_pictureglossary'] = 'The glossary for main question and picture';
$string[ 'hiddenpicture_width'] = 'Set width of picture to (in pixels)';
$string[ 'millionaire_background'] = 'Background color';
$string[ 'millionaire_options'] = 'Millionaire\' options';
$string[ 'millionaire_shuffle'] = 'Randomize questions';
$string[ 'snakes_background'] = 'Background';
$string[ 'snakes_cols'] = 'Cols';
$string[ 'snakes_data'] = 'Positions of Snakes and Ladders';
$string[ 'snakes_file'] = 'File for background';
$string[ 'snakes_footerx'] = 'Space at bootom left (in pixels)';
$string[ 'snakes_footery'] = 'Space at bottom right (in pixels)';
$string[ 'snakes_headerx'] = 'Space at up left (in pixels)';
$string[ 'snakes_headery'] = 'Space at up right (in pixels)';
$string[ 'snakes_layout0'] = 'Question at the top of the image';
$string[ 'snakes_layout1'] = 'Question at the bottom of the image';
$string[ 'snakes_options'] = '\'Snakes and Ladders\' options';
$string[ 'snakes_rows'] = 'Rows';
$string[ 'sourcemodule'] = 'Source of questions';
$string[ 'sourcemodule_book'] = 'Select a book';
$string[ 'sourcemodule_glossary'] = 'Select glossary';
$string[ 'sourcemodule_glossarycategory'] = 'Select category of glossary';
$string[ 'sourcemodule_include_subcategories'] = 'Include subcategories';
$string[ 'sourcemodule_question'] = 'Questions';
$string[ 'sourcemodule_questioncategory'] = 'Select question category';
$string[ 'sourcemodule_quiz'] = 'Select quiz';
$string[ 'sudoku_maxquestions'] = 'Maximum number of questions';
$string[ 'sudoku_options'] = 'Sudoku options';
$string[ 'toptext'] = 'Text at the top of page';
$string[ 'userdefined'] = 'User defined';
$string[ 'different_glossary_category'] = "The selected category doesn't corespond to selected glossary";
$string[ 'highscore'] = 'Show high score (number of students)';
// File preview.php.
$string[ 'only_teachers'] = 'Only teacher can see this page';
$string[ 'preview'] = 'Preview';
// File review.php.
$string[ 'attempts'] = 'Attempts';
$string[ 'completedon'] = 'Completed on';
$string[ 'outof'] = '{$a->grade} out of a maximum of {$a->maxgrade}';
$string[ 'review'] = 'Review';
$string[ 'reviewofattempt'] = 'Review of Attempt {$a}';
$string[ 'showall'] = 'Show all';
$string[ 'startagain'] = 'Start again';
$string[ 'timetaken'] = 'Time taken';
$string[ 'col_highscores'] = 'High scores';
// File settings.php.
$string[ 'hangmanimagesets'] = 'Number of image sets used by hangman';
$string[ 'hidebookquiz'] = 'Hide the "Book with questions" game';
$string[ 'hidecross'] = 'Hide the Crossword game';
$string[ 'hidecryptex'] = 'Hide the Cryptex game';
$string[ 'hidehangman'] = 'Hide the Hangman game';
$string[ 'hidehiddenpicture'] = 'Hide the "Hidden Picture" game';
$string[ 'hidemillionaire'] = 'Hide the Millionaire game';
$string[ 'hidesnakes'] = 'Hide the "Snakes and Ladders" game';
$string[ 'hidesudoku'] = 'Hide the Sudoku game';
$string[ 'confighangmanimagesets'] = 'Configs how many set of images are used by hangman';
$string[ 'confighidebookquiz'] = 'Configs if the "Book with questions" game is shown to teachers or not';
$string[ 'confighidecross'] = 'Configs if the Crossword game is shown to teachers or not';
$string[ 'confighidecryptex'] = 'Configs if the Cryptex game is shown to teachers or not';
$string[ 'confighidehangman'] = 'Configs if the Hangman game is shown to teachers or not';
$string[ 'confighidehiddenpicture'] = 'Configs if the "Hidden Picture" game is shown to teachers or not';
$string[ 'confighidemillionaire'] = 'Configs if the Millionaire game is shown to teachers or not';
$string[ 'confighidesnakes'] = 'Configs if the "Snakes and Ladders" game is shown to teachers or not';
$string[ 'confighidesudoku'] = 'Configs if the Sudoku game is shown to teachers or not';
// File showanswers.php.
$string[ 'clearrepetitions'] = 'Clear statistics';
$string[ 'computerepetitions'] = 'Compute statistics again';
$string[ 'feedbacks'] = 'Messages correct answer';
$string[ 'repetitions'] = 'Repetitions';
// File showattempts.php.
$string[ 'lastip'] = 'IP student';
$string[ 'showsolution'] = 'solution';
$string[ 'timefinish'] = 'End of game';
$string[ 'timelastattempt'] = 'Last attempt';
$string[ 'timestart'] = 'Start';
// File tabs.php.
// File view.php.
$string[ 'attemptgamenow'] = 'Attempt game now';
$string[ 'comment'] = 'Comment';
$string[ 'continueattemptgame'] = 'Continue a previous attempt of game';
$string[ 'gameclosed'] = 'This game closed on {$a}';
$string[ 'gamecloseson'] = 'This game will close at {$a}';
$string[ 'gamenotavailable'] = 'The game will not be available until {$a}';
$string[ 'gameopenedon'] = 'This game opened at {$a}';
$string[ 'reattemptgame'] = 'Reattempt game';
$string[ 'yourfinalgradeis'] = 'Your final grade for this game is {$a}.';

1487
lib.php

File diff suppressed because it is too large

2573
locallib.php

File diff suppressed because it is too large

766
millionaire/play.php

@ -0,0 +1,766 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file plays the game millionaire.
*
* @package mod_game
* @copyright 2007 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Plays the millionaire
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $millionaire
* @param stdClass $context
*/
function game_millionaire_continue( $id, $game, $attempt, $millionaire, $context) {
// User must select quiz or question as a source module.
if (($game->quizid == 0) and ($game->questioncategoryid == 0)) {
if ($game->sourcemodule == 'quiz') {
print_error( get_string( 'millionaire_must_select_quiz', 'game'));
} else {
print_error( get_string( 'millionaire_must_select_questioncategory', 'game'));
}
}
if ($attempt != false and $millionaire != false) {
// Continue an existing game.
return game_millionaire_play( $id, $game, $attempt, $millionaire, $context);
}
if ($attempt == false) {
$attempt = game_addattempt( $game);
}
$newrec = new stdClass();
$newrec->id = $attempt->id;
$newrec->queryid = 0;
$newrec->level = 0;
$newrec->state = 0;
if (!game_insert_record( 'game_millionaire', $newrec)) {
print_error( 'error inserting in game_millionaire');
}
game_millionaire_play( $id, $game, $attempt, $newrec, $context);
}
/**
* Plays the millionaire
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $millionaire
* @param stdClass $context
*/
function game_millionaire_play( $id, $game, $attempt, $millionaire, $context) {
global $DB;
$buttons = optional_param('buttons', 0, PARAM_INT);
$help5050x = optional_param('Help5050_x', 0, PARAM_INT);
$helptelephonex = optional_param('HelpTelephone_x', 0, PARAM_INT);
$helppeoplex = optional_param('HelpPeople_x', 0, PARAM_INT);
$quitx = optional_param('Quit_x', 0, PARAM_INT);
if ($millionaire->queryid) {
$query = $DB->get_record( 'game_queries', array( 'id' => $millionaire->queryid));
} else {
$query = new StdClass;
}
$found = 0;
for ($i = 1; $i <= $buttons; $i++) {
$name = 'btAnswer'.$i;
$answer = optional_param($name, '', PARAM_RAW);
if (!empty($answer)) {
game_millionaire_OnAnswer( $id, $game, $attempt, $millionaire, $query, $i, $context);
$found = 1;
}
}
if ($found == 1) {
$found = $found; // Nothing.
} else if (!empty($help5050x)) {
game_millionaire_OnHelp5050( $game, $id, $millionaire, $game, $query, $context);
} else if (!empty($helptelephonex)) {
game_millionaire_OnHelpTelephone( $game, $id, $millionaire, $query, $context);
} else if (!empty($helppeoplex)) {
game_millionaire_OnHelpPeople( $game, $id, $millionaire, $query, $context);
} else if (!empty($quitx)) {
game_millionaire_OnQuit( $id, $game, $attempt, $query, $context);
} else {
game_millionaire_ShowNextQuestion( $id, $game, $attempt, $millionaire, $context);
}
}
/**
* Shows the grid
*
* @param stdClass $game
* @param stdClass $millionaire
* @param int $id
* @param stdClass $query
* @param array $aanswer
* @param stdClass $info
* @param stdClass $context
*/
function game_millionaire_showgrid( $game, $millionaire, $id, $query, $aanswer, $info, $context) {
global $CFG, $OUTPUT;
$question = str_replace( array("\'", '\"'), array("'", '"'), $query->questiontext);
if ($game->param8 == '') {
$color = 408080;
} else {
$color = substr( '000000'.base_convert($game->param8, 10, 16), -6);
}
$color1 = 'black';
$color2 = 'DarkOrange';
$colorback = "white";
$stylequestion = "background:$colorback;color:$color1";
$stylequestionselected = "background:$colorback;color:$color2";
$state = $millionaire->state;
$level = $millionaire->level;
$background = "style='background:#$color'";
echo '<form name="Form1" method="post" action="attempt.php" id="Form1">';
echo "<table cellpadding=0 cellspacing=0 border=0>\r\n";
echo "<tr $background>";
echo '<td rowspan='.(17 + count( $aanswer)).'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>';
echo "<td colspan=6>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
echo '<td rowspan='.(17 + count( $aanswer)).'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>';
echo "</tr>\r\n";
echo "<tr height=10%>";
echo "<td $background rowspan=3 colspan=2>";
$dirgif = 'millionaire/1/';
if ($state & 1) {
$gif = "5050x";
$disabled = "disabled=1";
} else {
$gif = "5050";
$disabled = "";
}
$src = game_pix_url($dirgif.$gif, 'mod_game');
echo '<input type="image" '.$disabled.' name="Help5050" id="Help5050" Title="50 50" src="'.$src.'" alt="" border="0">&nbsp;';
if ($state & 2) {
$gif = "telephonex";
$disabled = "disabled=1";
} else {
$gif = "telephone";
$disabled = "";
}
echo '<input type="image" name="HelpTelephone" '.$disabled.
' id="HelpTelephone" Title="'.get_string( 'millionaire_telephone', 'game').
'" src="'.game_pix_url($dirgif.$gif, 'mod_game').'" alt="" border="0">&nbsp;';
if ($state & 4) {
$gif = "peoplex";
$disabled = "disabled=1";
} else {
$gif = "people";
$disabled = "";
}
echo '<input type="image" name="HelpPeople" '.$disabled.' id="HelpPeople" Title="'.
get_string( 'millionaire_helppeople', 'game').'" src="'.
game_pix_url($dirgif.$gif, 'mod_game').'" alt="" border="0">&nbsp;';
echo '<input type="image" name="Quit" id="Quit" Title="'.
get_string( 'millionaire_quit', 'game').'" src="'.
game_pix_url($dirgif.'x', 'mod_game').'" alt="" border="0">&nbsp;';
echo "\r\n";
echo "</td>\r\n";
$styletext = "";
if (strpos( $question, 'color:') == false and strpos( $question, 'background:') == false) {
$styletext = "style='$stylequestion'";
}
$aval = array( 100, 200, 300, 400, 500, 1000, 1500, 2000, 4000, 5000, 10000, 20000, 40000, 80000, 150000);
for ($i = 15; $i >= 1; $i--) {
$btr = false;
switch ($i) {
case 15:
echo "<td rowspan=".(16 + count( $aanswer)).
" $background>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>\r\n";
$btr = true;
break;
case 14:
case 13:
echo "<tr>\n";
$btr = true;
break;
case 12:
$question = game_show_query( $game, $query, $question);
echo "<tr>";
echo "<td rowspan=12 colspan=2 valign=top style=\"$styletext\">$question</td>\r\n";
$btr = true;
break;
case 11:
case 10:
case 9:
case 8:
case 7:
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
echo "<tr>";
$btr = true;
break;
default:
echo "<tr>";
$btr = true;
}
if ($i == $level + 1) {
$style = "background:$color1;color:$color2";
} else {
$style = $stylequestion;
}
echo "<td style='$style' align=right>$i</td>";
if ($i < $level + 1) {
echo "<td style='$style'>&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;</td>";
} else if ($i == 15 and $level <= 1) {
echo "<td style='$style'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
} else {
echo "<td style='$style'></td>";
}
echo "<td style='$style' align=right>".sprintf( "%10d", $aval[ $i - 1])."</td>\r\n";
if ($btr) {
echo "</tr>\r\n";
}
}
echo "<tr $background><td colspan=10>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td></tr>\r\n";
$bfirst = true;
$letters = get_string( 'millionaire_lettersall', 'game');
if (($letters == '') or ($letters == '-')) {
$letters = get_string( 'lettersall', 'game');
}
for ($i = 1; $i <= count( $aanswer); $i++) {
$name = "btAnswer".$i;
$s = game_substr( $letters, $i - 1, 1);
$disabled = ( $state == 15 ? "disabled=1" : "");
$style = $stylequestion;
if ((strpos( $aanswer[ $i - 1], 'color:') != false) or (strpos( $aanswer[ $i - 1], 'background:') != false)) {
$style = '';
}
if ($state == 15 and $i + 1 == $query->correct) {
$style = $stylequestionselected;
}
$button = '<input style="'.$style.'" '.$disabled.'type="submit" name="'.$name.'" value="'.$s.'" id="'.$name."1\"".
" onmouseover=\"this.style.backgroundColor = '$color2';$name.style.backgroundColor = '$color2';\" ".
" onmouseout=\"this.style.backgroundColor = '$colorback';$name.style.backgroundColor = '$colorback';\" >";
$text = game_filtertext($aanswer[ $i - 1], $game->course);
$answer = "<span id=$name style=\"$style\" ".
" onmouseover=\"this.style.backgroundColor = '$color2';{$name}1.style.backgroundColor = '$color2';\" ".
" onmouseout=\"this.style.backgroundColor = '$colorback';{$name}1.style.backgroundColor = '$colorback';\" >".
$text.'</span>';
if ($aanswer[ $i - 1] != "") {
echo "<tr>\n";
echo "<td style='$stylequestion'> $button</td>\n";
echo "<td $style width=100%> &nbsp; $answer</td>";
if ($bfirst) {
$bfirst = false;
$info = game_filtertext($info, $game->course);
echo "<td style=\"$style\" rowspan=".count( $aanswer)." colspan=3>$info</td>";
}
echo "\r\n</tr>\r\n";
}
}
echo "<tr><td colspan=10 $background>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td></tr>\r\n";
echo "<input type=hidden name=state value=\"$state\">\r\n";
echo '<input type=hidden name=id value="'.$id.'">';
echo "<input type=hidden name=buttons value=\"".count( $aanswer)."\">\r\n";
echo "</table>\r\n";
echo "</form>\r\n";
}
/**
* Show next question
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $millionaire
* @param stdClass $context
*/
function game_millionaire_shownextquestion( $id, $game, $attempt, $millionaire, $context) {
game_millionaire_selectquestion( $aanswer, $game, $attempt, $millionaire, $query, $context);
if ($game->toptext != '') {
echo $game->toptext.'<br><br>';
}
game_millionaire_showgrid( $game, $millionaire, $id, $query, $aanswer, "", $context);
if ($game->bottomtext != '') {
echo '<br>'.$game->bottomtext;
}
}
/**
* Updates tables: games_millionaire, game_attempts, game_questions.
*
* @param array $aanswer
* @param stdClass $game
* @param stdClasss $attempt
* @param stdClass $millionaire
* @param stdClass $query
* @param stdClass $context
*/
function game_millionaire_selectquestion( &$aanswer, $game, $attempt, &$millionaire, &$query, $context) {
global $DB, $USER;
if (($game->sourcemodule != 'quiz') and ($game->sourcemodule != 'question')) {
print_error( get_string('millionaire_sourcemodule_must_quiz_question', 'game',
get_string( 'modulename', 'quiz')).' '.get_string( 'modulename', $attempt->sourcemodule));
}
if ($millionaire->queryid != 0) {
game_millionaire_loadquestions( $game, $millionaire, $query, $aanswer, $context);
return;
}
if ($game->sourcemodule == 'quiz') {
if ($game->quizid == 0) {
print_error( get_string( 'must_select_quiz', 'game'));
}
if (game_get_moodle_version() < '02.06') {
$select = "qtype='multichoice' AND quiz='$game->quizid' AND qmo.question=q.id".
" AND qqi.question=q.id";
$table = "{quiz_question_instances} qqi,{question} q, {question_multichoice} qmo";
$order = '';
} else if (game_get_moodle_version() < '02.07') {
$select = "qtype='multichoice' AND quiz='$game->quizid' AND qmo.questionid=q.id".
" AND qqi.question=q.id";
$table = "{quiz_question_instances} qqi,{question} q, {qtype_multichoice_options} qmo";
$order = '';
} else {
$select = "qtype='multichoice' AND qs.quizid='$game->quizid' AND qmo.questionid=q.id".
" AND qs.questionid=q.id";
$table = "{quiz_slots} qs,{question} q, {qtype_multichoice_options} qmo";
$order = 'qs.page,qs.slot';
}
} else {
// Source is questions.
if ($game->questioncategoryid == 0) {
print_error( get_string( 'must_select_questioncategory', 'game'));
}
// Include subcategories.
$select = 'category='.$game->questioncategoryid;
if ($game->subcategories) {
$cats = question_categorylist( $game->questioncategoryid);
if (count( $cats)) {
$select = 'q.category in ('.implode(',', $cats).')';
}
}
if (game_get_moodle_version() < '02.06') {
$select .= " AND qtype='multichoice' AND qmo.single=1 AND qmo.question=q.id";
$table = '{question} q, {question_multichoice} qmo';
} else {
$select .= " AND qtype='multichoice' AND qmo.single=1 AND qmo.questionid=q.id";
$table = '{question} q, {qtype_multichoice_options} qmo';
}
}
$select .= ' AND hidden=0';
if ($game->shuffle or $game->quizid == 0) {
$questionid = game_question_selectrandom( $game, $table, $select, 'q.id as id', true);
} else {
$questionid = game_millionaire_select_serial_question( $game, $table, $select, 'q.id as id', $millionaire->level, $order);
}
if ($questionid == 0) {
print_error( get_string( 'no_questions', 'game'));
}
$q = $DB->get_record( 'question', array( 'id' => $questionid), 'id,questiontext');
$recs = $DB->get_records( 'question_answers', array( 'question' => $questionid));
if ($recs === false) {
print_error( get_string( 'no_questions', 'game'));
}
$correct = 0;
$ids = array();
foreach ($recs as $rec) {
$aanswer[] = game_filterquestion_answer(str_replace( '\"', '"', $rec->answer), $rec->id, $context->id, $game->course);
$ids[] = $rec->id;
if ($rec->fraction == 1) {
$correct = $rec->id;
}
}
$count = count( $aanswer);
for ($i = 1; $i <= $count; $i++) {
$sel = mt_rand(0, $count - 1);
$temp = array_splice( $aanswer, $sel, 1);
$aanswer[ ] = $temp[ 0];
$temp = array_splice( $ids, $sel, 1);
$ids[ ] = $temp[ 0];
}
$query = new StdClass;
$query->attemptid = $attempt->id;
$query->gamekind = $game->gamekind;
$query->gameid = $game->id;
$query->userid = $USER->id;
$query->sourcemodule = $game->sourcemodule;
$query->glossaryentryid = 0;
$query->questionid = $questionid;
$query->questiontext = addslashes( $q->questiontext);
$query->answertext = implode( ',', $ids);
$query->correct = array_search( $correct, $ids) + 1;
if (!$query->id = $DB->insert_record( 'game_queries', $query)) {
print_error( 'error inserting to game_queries');
}
$updrec = new StdClass;
$updrec->id = $millionaire->id;
$updrec->queryid = $query->id;
if (!$newid = $DB->update_record( 'game_millionaire', $updrec)) {
print_error( 'error updating in game_millionaire');
}
$score = $millionaire->level / 15;
game_updateattempts( $game, $attempt, $score, 0);
game_update_queries( $game, $attempt, $query, $score, '');
}
/**
* Select serial question
*
* @param stdClass $game
* @param string $table
* @param string $select
* @param string $idfields
* @param int $level
* @param string $order
*/
function game_millionaire_select_serial_question( $game, $table, $select, $idfields = "id", $level, $order) {
global $DB, $USER;
$sql = "SELECT $idfields,$idfields FROM ".$table." WHERE $select ";
if ($order != '') {
$sql .= " ORDER BY $order";
}
if (($recs = $DB->get_records_sql( $sql)) == false) {
return false;
}
$questions = array();
foreach ($recs as $rec) {
$questions[] = $rec->id;
}
$count = count( $questions);
if ($count == 0) {
return false;
}
$from = round($level * ($count - 1) / 15);
$to = round(max( $from, ($level + 1) * ($count - 1) / 15)) - 1;
if ($to < $from) {
$to = $from;
}
$pos = mt_rand( round( $from), round( $to));
return $questions[ $pos];
}
/**
* Load questions for millionaire
*
* @param stdClass $game
* @param stdClass $millionaire
* @param string $query
* @param array $aanswer
* @param stdClass $context
*/
function game_millionaire_loadquestions( $game, $millionaire, &$query, &$aanswer, $context) {
global $DB;
$query = $DB->get_record( 'game_queries', array( 'id' => $millionaire->queryid),
'id,questiontext,answertext,correct,questionid');
$aids = explode( ',', $query->answertext);
$aanswer = array();
foreach ($aids as $id) {
$rec = $DB->get_record( 'question_answers', array( 'id' => $id), 'id,answer');
$aanswer[] = game_filterquestion_answer(str_replace( '\"', '"', $rec->answer), $id, $context->id, $game->course);
}
}
/**
* Set state. Flag 1 is 5050, 2 is telephone 4 is people.
*
* @param stdClass $millionaire
* @param string $mask
*/
function game_millionaire_setstate( &$millionaire, $mask) {
global $DB;
$millionaire->state |= $mask;
$updrec = new stdClass();
$updrec->id = $millionaire->id;
$updrec->state = $millionaire->state;
if (!$DB->update_record( 'game_millionaire', $updrec)) {
print_error( 'error updating in game_millionaire');
}
}
/**
* One help 50-50
*
* @param stdClass $game
* @param int $id
* @param stdClass $millionaire
* @param string $query
* @param stdClass $context
*/
function game_millionaire_onhelp5050( $game, $id, &$millionaire, $query, $context) {
game_millionaire_loadquestions( $game, $millionaire, $query, $aanswer, $context);
if (($millionaire->state & 1) != 0) {
game_millionaire_showgrid( $game, $millionaire, $id, $query, $aanswer, '', $context);
return;
}
game_millionaire_setstate( $millionaire, 1);
$n = count( $aanswer);
if ($n > 2) {
for (;;) {
$wrong = mt_rand( 1, $n);
if ($wrong != $query->correct) {
break;
}
}
for ($i = 1; $i <= $n; $i++) {
if ($i <> $wrong and $i <> $query->correct) {
$aanswer[ $i - 1] = "";
}
}
}
game_millionaire_showgrid( $game, $millionaire, $id, $query, $aanswer, '', $context);
}
/**
* One help telephone
*
* @param stdClass $game
* @param int $id
* @param stdClass $millionaire
* @param stdClass $query
* @param stdClass $context
*/
function game_millionaire_onhelptelephone( $game, $id, &$millionaire, $query, $context) {
game_millionaire_loadquestions( $game, $millionaire, $query, $aanswer, $context);
if (($millionaire->state & 2) != 0) {
game_millionaire_ShowGrid( $game, $millionaire, $id, $query, $aanswer, '', $context);
return;
}
game_millionaire_setstate( $millionaire, 2);
$n = count( $aanswer);
if ($n < 2) {
$wrong = $query->correct;
} else {
for (;;) {
$wrong = mt_rand( 1, $n);
if ($wrong != $query->correct) {
break;
}
}
}
// With 80% gives the correct answer.
if (mt_rand( 1, 10) <= 8) {
$response = $query->correct;
} else {
$response = $wrong;
}
$info = get_string( 'millionaire_info_telephone', 'game').'<br><b>'.$aanswer[ $response - 1].'</b>';
game_millionaire_showgrid( $game, $millionaire, $id, $query, $aanswer, $info, $context);
}
/**
* One help people
*
* @param stdClass $game
* @param int $id
* @param stdClass $millionaire
* @param stdClass $query
* @param stdClass $context
*/
function game_millionaire_onhelppeople( $game, $id, &$millionaire, $query, $context) {
game_millionaire_loadquestions( $game, $millionaire, $query, $aanswer, $context);
if (($millionaire->state & 4) != 0) {
game_millionaire_showgrid( $game, $millionaire, $id, $query, $aanswer, '', $context);
return;
}
game_millionaire_setstate( $millionaire, 4);
$n = count( $aanswer);
$sum = 0;
$apercent = array();
for ($i = 0; $i + 1 < $n; $i++) {
$percent = mt_rand( 0, 100 - $sum);
$apercent[ $i] = $percent;
$sum += $percent;
}
$apercent[ $n - 1] = 100 - $sum;
if (mt_rand( 1, 100) <= 80) {
// With percent 80% sets in the correct answer the biggest percent.
$maxpos = 0;
for ($i = 1; $i + 1 < $n; $i++) {
if ($apercent[ $i] >= $apercent[ $maxpos]) {
$maxpos = $i;
}
$temp = $apercent[ $maxpos];
$apercent[ $maxpos] = $apercent[ $query->correct - 1];
$apercent[ $query->correct - 1] = $temp;
}
}
$info = '<br>'.get_string( 'millionaire_info_people', 'game').':<br>';
for ($i = 0; $i < $n; $i++) {
$info .= "<br>". game_substr( get_string( 'lettersall', 'game'), $i, 1) ." : ".$apercent[ $i]. ' %';
}
game_millionaire_showgrid( $game, $millionaire, $id, $query, $aanswer, game_substr( $info, 4), $context);
}
/**
* Millionaire on answer
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $millionaire
* @param stdClass $query
* @param string $answer
* @param stdClass $context
*/
function game_millionaire_onanswer( $id, $game, $attempt, &$millionaire, $query, $answer, $context) {
global $DB;
game_millionaire_loadquestions( $game, $millionaire, $query, $aanswer, $context);
if ($answer == $query->correct) {
if ($millionaire->level < 15) {
$millionaire->level++;
}
$finish = ($millionaire->level == 15 ? 1 : 0);
$scorequestion = 1;
} else {
$finish = 1;
$scorequestion = 0;
}
$score = $millionaire->level / 15;
game_update_queries( $game, $attempt, $query, $scorequestion, $answer);
game_updateattempts( $game, $attempt, $score, $finish);
$updrec = new stdClass();
$updrec->id = $millionaire->id;
$updrec->level = $millionaire->level;
$updrec->queryid = 0;
if (!$DB->update_record( 'game_millionaire', $updrec)) {
print_error( 'error updating in game_millionaire');
}
if ($answer == $query->correct) {
// Correct.
if ($finish) {
echo get_string( 'win', 'game');
game_millionaire_OnQuit( $id, $game, $attempt, $query);
} else {
$millionaire->queryid = 0; // So the next function select a new question.
}
game_millionaire_ShowNextQuestion( $id, $game, $attempt, $millionaire, $context);
} else {
// Wrong answer.
$info = get_string( 'millionaire_info_wrong_answer', 'game').
'<br><br><b><center>'.$aanswer[ $query->correct - 1].'</b>';
$millionaire->state = 15;
game_millionaire_ShowGrid( $game, $millionaire, $id, $query, $aanswer, $info, $context);
}
}
/**
* Millionaire on quit
*
* @param int $id
* @param stdClass $game
* @param stdClass $attempt
* @param stdClass $query
*/
function game_millionaire_onquit( $id, $game, $attempt, $query) {
global $CFG, $DB;
game_updateattempts( $game, $attempt, -1, true);
if (! $cm = $DB->get_record( 'course_modules', array( 'id' => $id))) {
print_error( "Course Module ID was incorrect id=$id");
}
echo '<br>';
echo "<a href=\"{$CFG->wwwroot}/mod/game/attempt.php?id=$id\">".
get_string( 'nextgame', 'game').'</a> &nbsp; &nbsp; &nbsp; &nbsp; ';
echo "<a href=\"{$CFG->wwwroot}/course/view.php?id=$cm->course\">".get_string( 'finish', 'game').'</a> ';
}

657
mod_form.php

@ -0,0 +1,657 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Form for creating and modifying a game
*
* @package mod_game
* @author Alastair Munro <alastair@catalyst.net.nz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2007 Vasilis Daloukas
*/
defined('MOODLE_INTERNAL') || die();
require_once( $CFG->dirroot.'/course/moodleform_mod.php');
require( 'locallib.php');
/**
* The class defines the form of game parameters
*
* @package mod_game
* @copyright 2014 Vasilis Daloukas
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_game_mod_form extends moodleform_mod {
/**
* definition
*/
public function definition() {
global $CFG, $DB, $COURSE;
$config = get_config('game');
$mform =& $this->_form;
$id = $this->_instance;
if (!empty($this->_instance)) {
if ($g = $DB->get_record('game', array('id' => $id))) {
$gamekind = $g->gamekind;
} else {
print_error('incorrect game');
}
} else {
$gamekind = required_param('type', PARAM_ALPHA);
}
// Hidden elements.
$mform->addElement('hidden', 'gamekind', $gamekind);
$mform->setDefault('gamekind', $gamekind);
$mform->setType('gamekind', PARAM_ALPHA);
$mform->addElement('hidden', 'type', $gamekind);
$mform->setDefault('type', $gamekind);
$mform->setType('type', PARAM_ALPHA);
$mform->addElement( 'hidden', 'gameversion', game_get_version());
$mform->setType('gameversion', PARAM_INT);
$mform->addElement('header', 'general', get_string('general', 'form'));
$mform->addElement('text', 'name', 'Name', array('size' => '64'));
if (!empty($CFG->formatstringstriptags)) {
$mform->setType('name', PARAM_TEXT);
} else {
$mform->setType('name', PARAM_CLEAN);
}
if (!isset( $g)) {
$mform->setDefault('name', get_string( 'game_'.$gamekind, 'game'));
}
$mform->addRule('name', null, 'required', null, 'client');
$hasglossary = ($gamekind == 'hangman' || $gamekind == 'cross' ||
$gamekind == 'cryptex' || $gamekind == 'sudoku' ||
$gamekind == 'hiddenpicture' || $gamekind == 'snakes');
$questionsourceoptions = array();
if ($hasglossary) {
$questionsourceoptions['glossary'] = get_string('modulename', 'glossary');
}
$questionsourceoptions['question'] = get_string('sourcemodule_question', 'game');
if ($gamekind != 'bookquiz') {
$questionsourceoptions['quiz'] = get_string('modulename', 'quiz');
}
$mform->addElement('select', 'sourcemodule', get_string('sourcemodule', 'game'), $questionsourceoptions);
if ($hasglossary) {
$a = array();
$sql = "SELECT id,name,globalglossary,course FROM {$CFG->prefix}glossary ".
"WHERE course={$COURSE->id} OR globalglossary=1 ORDER BY globalglossary DESC,name";
if ($recs = $DB->get_records_sql($sql)) {
foreach ($recs as $rec) {
if (($rec->globalglossary != 0) and ($rec->course != $COURSE->id)) {
$rec->name = '*'.$rec->name;
}
$a[$rec->id] = $rec->name;
}
}
$mform->addElement('select', 'glossaryid', get_string('sourcemodule_glossary', 'game'), $a);
$mform->disabledIf('glossaryid', 'sourcemodule', 'neq', 'glossary');
$a = $this->get_array_glossary_categories( $a);
$mform->addElement('select', 'glossarycategoryid', get_string('sourcemodule_glossarycategory', 'game'), $a);
$mform->disabledIf('glossarycategoryid', 'sourcemodule', 'neq', 'glossary');
// Only approved.
$mform->addElement('selectyesno', 'glossaryonlyapproved', get_string('glossary_only_approved', 'game'));
$mform->disabledIf('subcategories', 'sourcemodule', 'neq', 'glossary');
}
// Question Category - Short Answer.
if ($gamekind != 'bookquiz') {
$a = $this->get_array_question_categories( $COURSE->id, $gamekind );
$mform->addElement('select', 'questioncategoryid', get_string('sourcemodule_questioncategory', 'game'), $a);
$mform->disabledIf('questioncategoryid', 'sourcemodule', 'neq', 'question');
// Subcategories.
$mform->addElement('selectyesno', 'subcategories', get_string('sourcemodule_include_subcategories', 'game'));
$mform->disabledIf('subcategories', 'sourcemodule', 'neq', 'question');
}
// Quiz Category.
if ($gamekind != 'bookquiz') {
$a = array();
if ($recs = $DB->get_records('quiz', array( 'course' => $COURSE->id), 'id,name')) {
foreach ($recs as $rec) {
$a[$rec->id] = $rec->name;
}
}
$mform->addElement('select', 'quizid', get_string('sourcemodule_quiz', 'game'), $a);
$mform->disabledIf('quizid', 'sourcemodule', 'neq', 'quiz');
}
// Book.
if ( $gamekind == 'bookquiz') {
$a = array();
if ($recs = $DB->get_records('book', array( 'course' => $COURSE->id), 'id,name')) {
foreach ($recs as $rec) {
$a[$rec->id] = $rec->name;
}
}
$mform->addElement('select', 'bookid', get_string('sourcemodule_book', 'game'), $a);
}
// Common settings to all games.
$mform->addElement('text', 'maxattempts', get_string('cross_max_attempts', 'game'));
$mform->setType('maxattempts', PARAM_INT);
// Disable summarize.
$mform->addElement('selectyesno', 'disablesummarize', get_string('disablesummarize', 'game'));
// Enable high score.
$mform->addElement('text', 'highscore', get_string('highscore', 'game'));
$mform->setType('highscore', PARAM_INT);
// Grade options.
$this->standard_grading_coursemodule_elements();
$mform->removeElement('grade');
$mform->addElement('text', 'grade', get_string( 'grademax', 'grades'), array('size' => 4));
$mform->setType('grade', PARAM_INT);
$gradingtypeoptions = array();
$gradingtypeoptions[ GAME_GRADEHIGHEST] = get_string('gradehighest', 'game');
$gradingtypeoptions[ GAME_GRADEAVERAGE] = get_string('gradeaverage', 'game');
$gradingtypeoptions[ GAME_ATTEMPTFIRST] = get_string('attemptfirst', 'game');
$gradingtypeoptions[ GAME_ATTEMPTLAST] = get_string('attemptlast', 'game');
$mform->addElement('select', 'grademethod', get_string('grademethod', 'game'), $gradingtypeoptions);
// Open and close dates.
$mform->addElement('date_time_selector', 'timeopen', get_string('gameopen', 'game'),
array('optional' => true, 'step' => 1));
$mform->addHelpButton('timeopen', 'gameopenclose', 'game');
$mform->addElement('date_time_selector', 'timeclose', get_string('gameclose', 'game'),
array('optional' => true, 'step' => 1));
// Bookquiz options.
if ($gamekind == 'bookquiz') {
$mform->addElement('header', 'bookquiz', get_string( 'bookquiz_options', 'game'));
$bookquizlayoutoptions = array();
$bookquizlayoutoptions[0] = get_string('bookquiz_layout0', 'game');
$bookquizlayoutoptions[1] = get_string('bookquiz_layout1', 'game');
$mform->addElement('select', 'param3',
get_string('bookquiz_layout', 'game'), $bookquizlayoutoptions);
}
// Hangman options.
if ($gamekind == 'hangman') {
$mform->addElement('header', 'hangman', get_string( 'hangman_options', 'game'));
$mform->addElement('text', 'param4', get_string('hangman_maxtries', 'game'), array('size' => 4));
$mform->setType('param4', PARAM_INT);
$mform->addElement('selectyesno', 'param1', get_string('hangman_showfirst', 'game'));
$mform->addElement('selectyesno', 'param2', get_string('hangman_showlast', 'game'));
$mform->addElement('selectyesno', 'param7', get_string('hangman_allowspaces', 'game'));
$mform->addElement('selectyesno', 'param8', get_string('hangman_allowsub', 'game'));
$mform->addElement('text', 'param10', get_string( 'hangman_maximum_number_of_errors', 'game'), array('size' => 4));
$mform->setType('param10', PARAM_INT);
if (!isset( $config->hangmanimagesets)) {
$number = 1;
} else {
$number = $config->hangmanimagesets;
}
if ($number > 1) {
$a = array();
for ($i = 1; $i <= $number; $i++) {
$a[ $i] = $i;
}
$mform->addElement('select', 'param3', get_string('hangman_imageset', 'game'), $a);
}
$mform->addElement('selectyesno', 'param5', get_string('hangman_showquestion', 'game'));
$mform->setDefault('param5', 1);
$mform->addElement('selectyesno', 'param6', get_string('hangman_showcorrectanswer', 'game'));
$a = array();
$a = get_string_manager()->get_list_of_translations();
$a[ ''] = '----------';
$a[ 'user'] = get_string('language_user_defined', 'game');
ksort( $a);
$mform->addElement('select', 'language', get_string('hangman_language', 'game'), $a);
$mform->addElement('text', 'userlanguage', get_string('language_user_defined', 'game'));
$mform->setType('userlanguage', PARAM_TEXT);
$mform->disabledIf('userlanguage', 'language', 'neq', 'user');
}
// Crossword options.
if ($gamekind == 'cross') {
$mform->addElement('header', 'cross', get_string( 'cross_options', 'game'));
$mform->addElement('text', 'param1', get_string('cross_maxcols', 'game'));
$mform->setType('param1', PARAM_INT);
$mform->addElement('text', 'param4', get_string('cross_minwords', 'game'));
$mform->setType('param4', PARAM_INT);
$mform->addElement('text', 'param2', get_string('cross_maxwords', 'game'));
$mform->setType('param2', PARAM_INT);
$mform->addElement('selectyesno', 'param7', get_string('hangman_allowspaces', 'game'));
$crosslayoutoptions = array();
$crosslayoutoptions[0] = get_string('cross_layout0', 'game');
$crosslayoutoptions[1] = get_string('cross_layout1', 'game');
$mform->addElement('select', 'param3', get_string('cross_layout', 'game'), $crosslayoutoptions);
$mform->setType('param5', PARAM_INT);
$mform->addElement('selectyesno', 'param6', get_string('cross_disabletransformuppercase', 'game'));
$mform->addElement('text', 'param8', get_string('cross_maxcomputetime', 'game'));
$mform->setType('param8', PARAM_INT);
}
// Cryptex options.
if ($gamekind == 'cryptex') {
$mform->addElement('header', 'cryptex', get_string( 'cryptex_options', 'game'));
$mform->addElement('text', 'param1', get_string('cross_maxcols', 'game'));
$mform->setType('param1', PARAM_INT);
$mform->addElement('text', 'param4', get_string('cross_minwords', 'game'));
$mform->setType('param4', PARAM_INT);
$mform->addElement('text', 'param2', get_string('cross_maxwords', 'game'));
$mform->setType('param2', PARAM_INT);
$mform->addElement('selectyesno', 'param7', get_string('hangman_allowspaces', 'game'));
$mform->addElement('text', 'param8', get_string('cryptex_maxtries', 'game'));
$mform->setType('param8', PARAM_INT);
$mform->addElement('text', 'param3', get_string('cross_maxcomputetime', 'game'));
$mform->setType('param3', PARAM_INT);
}
// Millionaire options.
if ($gamekind == 'millionaire') {
global $OUTPUT, $PAGE;
$mform->addElement('header', 'millionaire', get_string( 'millionaire_options', 'game'));
$mform->addElement('text', 'param8', get_string('millionaire_background', 'game'));
$mform->setDefault('param8', '#408080');
$mform->setType('param8', PARAM_TEXT);
$mform->addElement('selectyesno', 'shuffle', get_string('millionaire_shuffle', 'game'));
}
// Sudoku options.
if ($gamekind == 'sudoku') {
$mform->addElement('header', 'sudoku', get_string( 'sudoku_options', 'game'));
$mform->addElement('text', 'param2', get_string('sudoku_maxquestions', 'game'));
$mform->setType('param2', PARAM_INT);
}
// Snakes and Ladders options.
if ($gamekind == 'snakes') {
$mform->addElement('header', 'snakes', get_string( 'snakes_options', 'game'));
$snakesandladdersbackground = array();
if ($recs = $DB->get_records( 'game_snakes_database', null, 'id,name')) {
foreach ($recs as $rec) {
$snakesandladdersbackground[$rec->id] = $rec->name;
}
}
$snakeslayoutoptions = array();
$snakeslayoutoptions[0] = get_string('snakes_layout0', 'game');
$snakeslayoutoptions[1] = get_string('snakes_layout1', 'game');
$mform->addElement('select', 'param8', get_string('bookquiz_layout', 'game'), $snakeslayoutoptions);
if (count($snakesandladdersbackground) == 0) {
require("{$CFG->dirroot}/mod/game/db/importsnakes.php");
if ($recs = $DB->get_records('game_snakes_database', null, 'id,name')) {
foreach ($recs as $rec) {
$snakesandladdersbackground[$rec->id] = $rec->name;
}
}
}
$snakesandladdersbackground[ 0] = get_string( 'userdefined', 'game');
ksort( $snakesandladdersbackground);
$mform->addElement('select', 'param3', get_string('snakes_background', 'game'), $snakesandladdersbackground);
// Param3 = background.
// Param4 = itemid for file_storage.
// Param5 (=1 means dirty file and and have to be computed again).
// Param6 = width of autogenerated picture.
// Param7 = height of autogenerated picture.
// Param8 = layout.
$attachmentoptions = array('subdirs' => false, 'maxfiles' => 1);
$mform->addElement('filepicker', 'param4', get_string('snakes_file', 'game'), $attachmentoptions);
$mform->disabledIf('param4', 'param3', 'neq', '0');
$mform->addElement('textarea', 'snakes_data', get_string('snakes_data', 'game'), 'rows="2" cols="70"');
$mform->disabledIf('snakes_data', 'param3', 'neq', '0');
$mform->addElement('text', 'snakes_cols', get_string('snakes_cols', 'game'), array('size' => 4));
$mform->disabledIf('snakes_cols', 'param3', 'neq', '0');
$mform->setType('snakes_cols', PARAM_INT);
$mform->addElement('text', 'snakes_rows', get_string('snakes_rows', 'game'), array('size' => 4));
$mform->disabledIf('snakes_rows', 'param3', 'neq', '0');
$mform->setType('snakes_rows', PARAM_INT);
$mform->addElement('text', 'snakes_headerx', get_string('snakes_headerx', 'game'), array('size' => 4));
$mform->disabledIf('snakes_headerx', 'param3', 'neq', '0');
$mform->setType('snakes_headerx', PARAM_INT);
$mform->addElement('text', 'snakes_headery', get_string('snakes_headery', 'game'), array('size' => 4));
$mform->disabledIf('snakes_headery', 'param3', 'neq', '0');
$mform->setType('snakes_headery', PARAM_INT);
$mform->addElement('text', 'snakes_footerx', get_string('snakes_footerx', 'game'), array('size' => 4));
$mform->disabledIf('snakes_footerx', 'param3', 'neq', '0');
$mform->setType('snakes_footerx', PARAM_INT);
$mform->addElement('text', 'snakes_footery', get_string('snakes_footery', 'game'), array('size' => 4));
$mform->disabledIf('snakes_footery', 'param3', 'neq', '0');
$mform->setType('snakes_footery', PARAM_INT);
$mform->addElement('text', 'snakes_width', get_string('hiddenpicture_width', 'game'), array('size' => 6));
$mform->setType('snakes_width', PARAM_INT);
$mform->addELement('text', 'snakes_height', get_string('hiddenpicture_height', 'game'), array('size' => 6));
$mform->setType('snakes_height', PARAM_INT);
}
// Hidden Picture options.
if ($gamekind == 'hiddenpicture') {
$mform->addElement('header', 'hiddenpicture', get_string( 'hiddenpicture_options', 'game'));
$mform->addElement('text', 'param1', get_string('hiddenpicture_across', 'game'));
$mform->setType('param1', PARAM_INT);
$mform->setDefault('param1', 3);
$mform->addElement('text', 'param2', get_string('hiddenpicture_down', 'game'));
$mform->setType('param2', PARAM_INT);
$mform->setDefault('param2', 3);
$a = array();
if ($recs = $DB->get_records('glossary', array( 'course' => $COURSE->id), 'id,name')) {
foreach ($recs as $rec) {
$cmg = get_coursemodule_from_instance('glossary', $rec->id, $COURSE->id);
$context = game_get_context_module_instance( $cmg->id);
if ($DB->record_exists( 'files', array( 'contextid' => $context->id))) {
$a[$rec->id] = $rec->name;
}
}
}
$mform->addElement('select', 'glossaryid2', get_string('hiddenpicture_pictureglossary', 'game'), $a);
$mform->addElement('text', 'param4', get_string('hiddenpicture_width', 'game'));
$mform->setType('param4', PARAM_INT);
$mform->addELement('text', 'param5', get_string('hiddenpicture_height', 'game'));
$mform->setType('param5', PARAM_INT);
$mform->addElement('selectyesno', 'param7', get_string('hangman_allowspaces', 'game'));
}
// Header/Footer options.
$mform->addElement('header', 'headerfooteroptions', 'Header/Footer Options');
$mform->addElement('htmleditor', 'toptext', get_string('toptext', 'game'));
$mform->addElement('htmleditor', 'bottomtext', get_string('bottomtext', 'game'));
$features = new stdClass;
$this->standard_coursemodule_elements($features);
// Buttons.
$this->add_action_buttons();
}
/**
* Computes the categories of all glossaries of the current course;
*
* @param array $a array of id of glossaries to each name
*
* @return array of glossary categories
*/
public function get_array_glossary_categories( $a) {
global $CFG, $DB;
if (count( $a) == 0) {
$select = 'gc.glossaryid = -1';
} else if (count($a) == 1) {
foreach ($a as $id => $name) {
$select = 'gc.glossaryid = '.$id;
break;
}
} else {
$select = '';
foreach ($a as $id => $name) {
$select .= ','.$id;
}
$select = 'gc.glossaryid IN ('.substr( $select, 1).')';
}
$a = array();
// Fills with the count of entries in each glossary.
$a[ 0] = '';
// Fills with the count of entries in each category.
$sql2 = "SELECT COUNT(*) ".
" FROM {$CFG->prefix}glossary_entries ge, {$CFG->prefix}glossary_entries_categories gec".
" WHERE gec.categoryid=gc.id AND gec.entryid=ge.id";
$sql = "SELECT gc.id,gc.name,g.name as name2,g.globalglossary,g.course, ($sql2) as c ".
" FROM {$CFG->prefix}glossary_categories gc, {$CFG->prefix}glossary g".
" WHERE $select AND gc.glossaryid=g.id".
" ORDER BY g.name, gc.name";
if ($recs = $DB->get_records_sql( $sql)) {
foreach ($recs as $rec) {
$a[$rec->id] = $rec->name2.' -> '.$rec->name.' ('.$rec->c.')';
}
}
return $a;
}
/**
* Computes the categories of all question of the current course;
*
* @param int $courseid
* @param string $gamekind
*
* @return array of question categories
*/
public function get_array_question_categories( $courseid, $gamekind) {
global $CFG, $DB;
$context = game_get_context_course_instance( $courseid);
$a = array();
$table = "{$CFG->prefix}question q";
$select = '';
if ($gamekind == 'millionaire') {
if (game_get_moodle_version() < '02.06') {
$table = "{$CFG->prefix}question q, {$CFG->prefix}question_multichoice qmo";
$select = " AND q.qtype='multichoice' AND qmo.single = 1 AND qmo.question=q.id";
} else {
$table = "{$CFG->prefix}question q, {$CFG->prefix}qtype_multichoice_options qmo";
$select = " AND q.qtype='multichoice' AND qmo.single = 1 AND qmo.questionid=q.id";
}
} else if (($gamekind == 'hangman') or ($gamekind == 'cryptex') or ($gamekind == 'cross')) {
// Single answer questions.
$select = " AND q.qtype='shortanswer'";
}
$sql2 = "SELECT COUNT(*) FROM $table WHERE q.category = qc.id $select";
$sql = "SELECT id,name,($sql2) as c FROM {$CFG->prefix}question_categories qc WHERE contextid = $context->id";
if ($recs = $DB->get_records_sql( $sql)) {
foreach ($recs as $rec) {
$a[$rec->id] = $rec->name.' ('.$rec->c.')';
}
}
return $a;
}
/**
* validation
*
* @param stdClass $data
* @param array $files
*
* @return moodle_url
*/
public function validation($data, $files) {
global $CFG, $DB;
$errors = parent::validation($data, $files);
// Check open and close times are consistent.
if ($data['timeopen'] != 0 && $data['timeclose'] != 0 &&
$data['timeclose'] < $data['timeopen']) {
$errors['timeclose'] = get_string('closebeforeopen', 'quiz');
}
if (array_key_exists( 'glossarycategoryid', $data)) {
if ($data['glossarycategoryid'] != 0) {
$sql = "SELECT glossaryid FROM {$CFG->prefix}glossary_categories ".
" WHERE id=".$data[ 'glossarycategoryid'];
$rec = $DB->get_record_sql( $sql);
if ($rec != false) {
if ($data[ 'glossaryid'] != $rec->glossaryid) {
$s = get_string( 'different_glossary_category', 'game');
$errors['glossaryid'] = $s;
$errors['glossarycategoryid'] = $s;
}
}
}
}
if (array_key_exists('completion', $data) && $data['completion'] == COMPLETION_TRACKING_AUTOMATIC) {
$completionpass = isset($data['completionpass']) ? $data['completionpass'] : $this->current->completionpass;
// Show an error if require passing grade was selected and the grade to pass was set to 0.
if ($completionpass && (empty($data['gradepass']) || grade_floatval($data['gradepass']) == 0)) {
if (isset($data['completionpass'])) {
$errors['completionpassgroup'] = get_string('gradetopassnotset', 'quiz');
} else {
$errors['gradepass'] = get_string('gradetopassmustbeset', 'quiz');
}
}
}
return $errors;
}
/**
* Set data
*
* @param array $defaultvalues
*/
public function set_data($defaultvalues) {
global $DB;
if (isset( $defaultvalues->type)) {
// Default values for every game.
if ($defaultvalues->type == 'hangman') {
$defaultvalues->param10 = 6; // Maximum number of wrongs.
} else if ($defaultvalues->type == 'snakes') {
$defaultvalues->gamekind = $defaultvalues->type;
$defaultvalues->param3 = 1;
$defaultvalues->questioncategoryid = 0;
} else if ($defaultvalues->type == 'millionaire') {
$defaultvalues->shuffle = 1;
}
}
if (isset( $defaultvalues->gamekind)) {
if ($defaultvalues->gamekind == 'hangman') {
if ($defaultvalues->param10 == 0) {
$defaultvalues->param10 = 6;
}
} else if ($defaultvalues->gamekind == 'millionaire') {
if (isset( $defaultvalues->param8)) {
$defaultvalues->param8 = '#'.substr( '000000'.strtoupper( dechex( $defaultvalues->param8)), -6);
}
} else if ($defaultvalues->gamekind == 'cross') {
if ($defaultvalues->param5 == null) {
$defaultvalues->param5 = 1;
}
}
if ($defaultvalues->gamekind == 'snakes') {
if (isset( $defaultvalues->param9)) {
$a = explode( '#', $defaultvalues->param9);
foreach ($a as $s) {
$pos = strpos( $s, ':');
if ($pos) {
$name = substr( $s, 0, $pos);
$defaultvalues->$name = substr( $s, $pos + 1);
}
}
}
}
}
if (!isset( $defaultvalues->gamekind)) {
$defaultvalues->gamekind = $defaultvalues->type;
}
if ($defaultvalues->gamekind == 'snakes') {
if (isset( $defaultvalues->param3)) {
$board = $defaultvalues->param3;
if ($board != 0) {
$rec = $DB->get_record( 'game_snakes_database', array( 'id' => $board));
$defaultvalues->snakes_data = $rec->data;
$defaultvalues->snakes_cols = $rec->usedcols;
$defaultvalues->snakes_rows = $rec->usedrows;
$defaultvalues->snakes_headerx = $rec->headerx;
$defaultvalues->snakes_headery = $rec->headery;
$defaultvalues->snakes_footerx = $rec->footerx;
$defaultvalues->snakes_footery = $rec->footery;
}
}
} else if ($defaultvalues->gamekind == 'cross') {
if (!isset( $defaultvalues->param8)) {
$defaultvalues->param8 = 2;
}
} else if ($defaultvalues->gamekind == 'cryptex') {
if (!isset( $defaultvalues->param3)) {
$defaultvalues->param3 = 2;
}
}
parent::set_data($defaultvalues);
}
/**
* Display module-specific activity completion rules.
* Part of the API defined by moodleform_mod
* @return array Array of string IDs of added items, empty array if none
*/
public function add_completion_rules() {
$mform = $this->_form;
$items = array();
$group = array();
$group[] = $mform->createElement('advcheckbox', 'completionpass', null, get_string('completionpass', 'quiz'),
array('group' => 'cpass'));
$group[] = $mform->createElement('advcheckbox', 'completionattemptsexhausted', null,
get_string('completionattemptsexhausted', 'quiz'),
array('group' => 'cattempts'));
$mform->disabledIf('completionattemptsexhausted', 'completionpass', 'notchecked');
$mform->addGroup($group, 'completionpassgroup', get_string('completionpass', 'quiz'), ' &nbsp; ', false);
$mform->addHelpButton('completionpassgroup', 'completionpass', 'quiz');
$items[] = 'completionpassgroup';
return $items;
}
/**
* Called during validation. Indicates whether a module-specific completion rule is selected.
*
* @param array $data Input data (not yet validated)
* @return bool True if one or more rules is enabled, false if none are.
*/
public function completion_rule_enabled($data) {
return !empty($data['completionattemptsexhausted']) || !empty($data['completionpass']);
}
}

BIN
pix/bookquiz/add.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

BIN
pix/bookquiz/generateimscp.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

BIN
pix/bookquiz/nav_exit.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

BIN
pix/bookquiz/nav_next.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

BIN
pix/bookquiz/nav_prev.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

BIN
pix/bookquiz/nav_prev_dis.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

BIN
pix/bookquiz/nav_sep.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 B

BIN
pix/bookquiz/print_book.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

BIN
pix/bookquiz/print_chapter.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

BIN
pix/hangman/1/hangman_0.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
pix/hangman/1/hangman_1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
pix/hangman/1/hangman_2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
pix/hangman/1/hangman_3.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
pix/hangman/1/hangman_4.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
pix/hangman/1/hangman_5.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
pix/hangman/1/hangman_6.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
pix/icon.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 B

BIN
pix/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

848
pix/icon.svg

@ -0,0 +1,848 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
viewBox="-4.2 -0.3 24 24"
preserveAspectRatio="xMinYMid meet"
overflow="visible"
version="1.1"
id="svg4508"
sodipodi:docname="icon_game.svg"
inkscape:version="0.92.1 r15371"
inkscape:export-filename="C:\Users\ralfe\Desktop\icon.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<metadata
id="metadata4514">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs4512">
<linearGradient
y2="22.326"
x2="7.824"
y1="1"
x1="7.824"
gradientUnits="userSpaceOnUse"
id="marble_green_ground-0">
<stop
style="stop-color:#9af67a;stop-opacity:1"
id="stop4815"
stop-color="#BBE0F7"
offset="0" />
<stop
style="stop-color:#7df454;stop-opacity:1"
offset="0.76148415"
stop-color="#BBE0F7"
id="stop4817" />
<stop
style="stop-color:#257808;stop-opacity:1"
id="stop4819"
stop-color="#82B4FB"
offset="1" />
</linearGradient>
<linearGradient
y2="21.326"
x2="7.824"
y1="2.099"
x1="7.824"
gradientUnits="userSpaceOnUse"
id="marble_green_reflex-1">
<stop
style="stop-color:#fcfeec;stop-opacity:1"
id="stop4808"
stop-color="#95BFF8"
offset="0" />
<stop
style="stop-color:#9af779;stop-opacity:0.70588237"
id="stop4810"
stop-color="#84ADEF"
offset="0.76752627" />
<stop
style="stop-color:#9af779;stop-opacity:0"
id="stop4812"
stop-color="#7CA4EB"
offset="1" />
</linearGradient>
<linearGradient
y2="23.326"
x2="7.824"
x1="7.824"
gradientUnits="userSpaceOnUse"
id="marble_green_backreflex-5">
<stop
style="stop-color:#9af67a;stop-opacity:0"
id="stop4801"
stop-color="#76A1F0"
offset="0" />
<stop
offset="0.58803326"
stop-color="#76A1F0"
id="stop4803"
style="stop-color:#9faf99;stop-opacity:0.70588237" />
<stop
style="stop-color:#9faf99;stop-opacity:1"
id="stop4805"
stop-color="#6B90D5"
offset="1" />
</linearGradient>
<linearGradient
y2="23.326"
x2="7.824"
x1="7.824"
gradientUnits="userSpaceOnUse"
id="linearGradient4799">
<stop
style="stop-color:#7ac0f6;stop-opacity:0"
id="stop4793"
stop-color="#76A1F0"
offset="0" />
<stop
offset="0.58803326"
stop-color="#76A1F0"
id="stop4795"
style="stop-color:#99a5af;stop-opacity:0.70588237" />
<stop
style="stop-color:#99a5af;stop-opacity:1"
id="stop4797"
stop-color="#6B90D5"
offset="1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="board_reflex-9">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4590" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop4592" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4584">
<stop
style="stop-color:#efefef;stop-opacity:1"
offset="0"
id="stop4580" />
<stop
style="stop-color:#000000;stop-opacity:1"
offset="1"
id="stop4582" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4572">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4568" />
<stop
style="stop-color:#a4a4a4;stop-opacity:1"
offset="1"
id="stop4570" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4572"
id="radialGradient4574"
cx="11.877741"
cy="13.771272"
fx="11.877741"
fy="13.771272"
r="11.441406"
gradientTransform="matrix(0.70959075,0.00271411,-3.2874994e-4,0.08595021,3.4539331,19.160126)"
gradientUnits="userSpaceOnUse" />
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter4576"
x="-0.0065157051"
width="1.0130314"
y="-0.075807343"
height="1.1516147">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.062124023"
id="feGaussianBlur4578" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4584"
id="radialGradient4586"
cx="4.6210914"
cy="3.9787023"
fx="4.6210914"
fy="3.9787023"
r="11.456542"
gradientTransform="matrix(1.078582,-0.0118638,0.00670545,0.60961778,2.845712,4.0667088)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#board_reflex-9"
id="radialGradient4596"
cx="7.7654934"
cy="14.414653"
fx="7.7654934"
fy="14.414653"
r="12.840489"
gradientTransform="matrix(0.86677071,0.00411477,-0.00304216,0.64082565,5.3285746,1.7703639)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_ground-4-1"
id="radialGradient4610"
cx="-0.2091489"
cy="12.155626"
fx="-0.2091489"
fy="12.155626"
r="1.6413541"
gradientTransform="matrix(1,0,0,0.94648805,0,0.65047134)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_reflex-6-3"
id="radialGradient4618"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.95317726,1.0954857e-8,0,0.70150181,-0.00979287,3.8824048)"
cx="-0.25522199"
cy="13.405602"
fx="-0.25522199"
fy="13.405602"
r="1.6413541" />
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter4624"
x="-0.02335786"
width="1.0467157"
y="-0.024678445"
height="1.0493569">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.030452837"
id="feGaussianBlur4626" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_backreflex-7-3"
id="radialGradient4677"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.1342104,-0.006908,0.00148695,0.67462293,4.558378,4.8430071)"
cx="-0.18647377"
cy="11.379992"
fx="-0.18647377"
fy="11.379992"
r="1.6413541" />
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter4695"
x="-0.044681648"
width="1.0893633"
y="-0.091301021"
height="1.182602">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.058251954"
id="feGaussianBlur4697" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_ground-4-1"
id="radialGradient4715"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.94648805,0,0.65047134)"
cx="-0.2091489"
cy="12.155626"
fx="-0.2091489"
fy="12.155626"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_reflex-6-3"
id="radialGradient4717"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.95317726,1.0954857e-8,0,0.70150181,-0.00979287,3.8824048)"
cx="-0.25522199"
cy="13.405602"
fx="-0.25522199"
fy="13.405602"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_backreflex-7-3"
id="radialGradient4719"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.1342104,-0.006908,0.00148695,0.67462293,4.558378,4.8430071)"
cx="-0.18647377"
cy="11.379992"
fx="-0.18647377"
fy="11.379992"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_ground-4-1"
id="radialGradient4731"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.94648805,0,0.65047134)"
cx="-0.2091489"
cy="12.155626"
fx="-0.2091489"
fy="12.155626"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_reflex-6-3"
id="radialGradient4733"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.95317726,1.0954857e-8,0,0.70150181,-0.00979287,3.8824048)"
cx="-0.25522199"
cy="13.405602"
fx="-0.25522199"
fy="13.405602"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_backreflex-7-3"
id="radialGradient4735"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.1342104,-0.006908,0.00148695,0.67462293,4.558378,4.8430071)"
cx="-0.18647377"
cy="11.379992"
fx="-0.18647377"
fy="11.379992"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_ground-4-1"
id="radialGradient4747"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.94648805,0,0.65047134)"
cx="-0.2091489"
cy="12.155626"
fx="-0.2091489"
fy="12.155626"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_reflex-6-3"
id="radialGradient4749"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.95317726,1.0954857e-8,0,0.70150181,-0.00979287,3.8824048)"
cx="-0.25522199"
cy="13.405602"
fx="-0.25522199"
fy="13.405602"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_blue_backreflex-7-3"
id="radialGradient4751"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.1342104,-0.006908,0.00148695,0.67462293,4.558378,4.8430071)"
cx="-0.18647377"
cy="11.379992"
fx="-0.18647377"
fy="11.379992"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_ground-0"
id="radialGradient4779"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.94648805,0,0.65047134)"
cx="-0.2091489"
cy="12.155626"
fx="-0.2091489"
fy="12.155626"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_reflex-1"
id="radialGradient4781"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.95317726,1.0954857e-8,0,0.70150181,-0.00979287,3.8824048)"
cx="-0.25522199"
cy="13.405602"
fx="-0.25522199"
fy="13.405602"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_backreflex-5"
id="radialGradient4783"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.1342104,-0.006908,0.00148695,0.67462293,4.558378,4.8430071)"
cx="-0.18647377"
cy="11.379992"
fx="-0.18647377"
fy="11.379992"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_ground-0"
id="radialGradient4832"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.94648805,0,0.65047134)"
cx="-0.2091489"
cy="12.155626"
fx="-0.2091489"
fy="12.155626"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_reflex-1"
id="radialGradient4834"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.95317726,1.0954857e-8,0,0.70150181,-0.00979287,3.8824048)"
cx="-0.25522199"
cy="13.405602"
fx="-0.25522199"
fy="13.405602"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_backreflex-5"
id="radialGradient4836"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.1342104,-0.006908,0.00148695,0.67462293,4.558378,4.8430071)"
cx="-0.18647377"
cy="11.379992"
fx="-0.18647377"
fy="11.379992"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_ground-0"
id="radialGradient4848"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.94648805,0,0.65047134)"
cx="-0.2091489"
cy="12.155626"
fx="-0.2091489"
fy="12.155626"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_reflex-1"
id="radialGradient4850"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.95317726,1.0954857e-8,0,0.70150181,-0.00979287,3.8824048)"
cx="-0.25522199"
cy="13.405602"
fx="-0.25522199"
fy="13.405602"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_backreflex-5"
id="radialGradient4852"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.1342104,-0.006908,0.00148695,0.67462293,4.558378,4.8430071)"
cx="-0.18647377"
cy="11.379992"
fx="-0.18647377"
fy="11.379992"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_ground-0"
id="radialGradient4864"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.94648805,0,0.65047134)"
cx="-0.2091489"
cy="12.155626"
fx="-0.2091489"
fy="12.155626"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_reflex-1"
id="radialGradient4866"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.95317726,1.0954857e-8,0,0.70150181,-0.00979287,3.8824048)"
cx="-0.25522199"
cy="13.405602"
fx="-0.25522199"
fy="13.405602"
r="1.6413541" />
<radialGradient
inkscape:collect="always"
xlink:href="#marble_green_backreflex-5"
id="radialGradient4868"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.1342104,-0.006908,0.00148695,0.67462293,4.558378,4.8430071)"
cx="-0.18647377"
cy="11.379992"
fx="-0.18647377"
fy="11.379992"
r="1.6413541" />
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter4878"
x="-0.093228539"
width="1.1864571"
y="-0.1683406"
height="1.3366812">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.99758339"
id="feGaussianBlur4880" />
</filter>
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2160"
inkscape:window-height="1346"
id="namedview4510"
showgrid="false"
inkscape:zoom="22.770834"
inkscape:cx="19.293444"
inkscape:cy="7.7529993"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg4508" />
<linearGradient
id="marble_blue_backreflex-7-3"
gradientUnits="userSpaceOnUse"
x1="7.824"
x2="7.824"
y2="23.326">
<stop
offset="0"
stop-color="#76A1F0"
id="stop4485"
style="stop-color:#7ac0f6;stop-opacity:0" />
<stop
style="stop-color:#99a5af;stop-opacity:0.70588237"
id="stop4634"
stop-color="#76A1F0"
offset="0.58803326" />
<stop
offset="1"
stop-color="#6B90D5"
id="stop4487"
style="stop-color:#99a5af;stop-opacity:1" />
</linearGradient>
<linearGradient
id="marble_blue_ground-4-1"
gradientUnits="userSpaceOnUse"
x1="7.824"
y1="1"
x2="7.824"
y2="22.326">
<stop
offset="0"
stop-color="#BBE0F7"
id="stop4492"
style="stop-color:#7abff6;stop-opacity:1" />
<stop
id="stop4612"
stop-color="#BBE0F7"
offset="0.76148415"
style="stop-color:#54aef4;stop-opacity:1" />
<stop
offset="1"
stop-color="#82B4FB"
id="stop4494"
style="stop-color:#084878;stop-opacity:1" />
</linearGradient>
<linearGradient
id="marble_blue_reflex-6-3"
gradientUnits="userSpaceOnUse"
x1="7.824"
y1="2.099"
x2="7.824"
y2="21.326">
<stop
offset="0"
stop-color="#95BFF8"
id="stop4499"
style="stop-color:#ecf6fe;stop-opacity:1" />
<stop
offset="0.76752627"
stop-color="#84ADEF"
id="stop4501"
style="stop-color:#79c0f7;stop-opacity:0.70588237" />
<stop
offset="1"
stop-color="#7CA4EB"
id="stop4503"
style="stop-color:#79c0f7;stop-opacity:0" />
</linearGradient>
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4882"
d="m 17.615188,2.0824336 0.94419,16.8636774 -21.47484,-0.04391 0.6916743,-16.8197623 z"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="opacity:0.875;fill:url(#radialGradient4574);fill-opacity:1;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4576)"
d="M 0.56054688 20.013672 L 0.90429688 21.980469 L 23.101562 21.980469 L 23.443359 20.013672 L 0.56054688 20.013672 z "
transform="translate(-4.2,-0.3)"
id="rect4560" />
<path
style="fill:url(#radialGradient4586);fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M -2.8605672,1.5554437 -3.6620311,19.725618 19.251052,19.714639 18.339799,1.5334858 Z"
id="path4556"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 17.615188,2.0824336 0.94419,16.8636774 -21.47484,-0.04391 0.6916743,-16.8197623 z"
id="path4558"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#000000;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="M 1.9765625 2.3828125 L 1.8183594 6.2363281 L 6.6210938 6.2246094 L 6.6914062 2.3828125 L 1.9765625 2.3828125 z M 6.6210938 6.2246094 L 6.5429688 10.386719 L 12.015625 10.380859 L 12.033203 6.2421875 L 6.6210938 6.2246094 z M 12.033203 6.2421875 L 17.539062 6.2421875 L 17.433594 2.3828125 L 12.052734 2.3828125 L 12.033203 6.2421875 z M 17.539062 6.2421875 L 17.660156 10.375 L 22.263672 10.386719 L 22.03125 6.2363281 L 17.539062 6.2421875 z M 17.660156 10.375 L 12.015625 10.380859 L 11.988281 14.810547 L 17.791016 14.826172 L 17.660156 10.375 z M 17.791016 14.826172 L 17.921875 19.236328 L 22.759766 19.246094 L 22.511719 14.826172 L 17.791016 14.826172 z M 11.988281 14.810547 L 6.4726562 14.798828 L 6.4082031 19.212891 L 11.978516 19.224609 L 11.988281 14.810547 z M 6.4726562 14.798828 L 6.5429688 10.386719 L 1.6484375 10.380859 L 1.4667969 14.798828 L 6.4726562 14.798828 z "
transform="translate(-4.2,-0.3)"
id="path4539" />
<path
style="opacity:0.85;fill:url(#radialGradient4596);fill-opacity:1;stroke:none;stroke-width:3.77952756;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4878)"
d="M 22.027344 1.8339844 L 2.3085938 1.8535156 L 2.3066406 1.8535156 A 12.840489 7.1111784 0 0 0 1.3046875 2.6347656 L 0.98632812 9.8535156 A 12.840489 7.1111784 0 0 0 12.1875 13.503906 A 12.840489 7.1111784 0 0 0 22.960938 10.25 L 22.792969 6.8984375 L 22.558594 2.2128906 A 12.840489 7.1111784 0 0 0 22.027344 1.8339844 z "
transform="translate(-4.2,-0.3)"
id="path4588" />
<g
id="g4703">
<g
id="g4675">
<ellipse
style="opacity:1;fill:url(#radialGradient4610);fill-opacity:1;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4602"
cx="-0.2091489"
cy="12.155626"
rx="1.6413541"
ry="1.5535225" />
<ellipse
ry="1.4807823"
rx="1.5645014"
cy="12.155626"
cx="-0.2091489"
id="ellipse4614"
style="opacity:1;fill:url(#radialGradient4618);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4624)" />
</g>
<path
id="ellipse4628"
transform="translate(-4.2,-0.3)"
d="M 3.9902344 10.974609 A 1.5645014 1.4807823 0 0 0 2.4257812 12.455078 A 1.5645014 1.4807823 0 0 0 2.4277344 12.505859 L 5.5527344 12.505859 A 1.5645014 1.4807823 0 0 0 5.5546875 12.455078 A 1.5645014 1.4807823 0 0 0 3.9902344 10.974609 z "
style="opacity:0.75;fill:url(#radialGradient4677);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4695)" />
</g>
<g
id="g4713"
transform="translate(5.105215,4.6331199)">
<g
id="g4709">
<ellipse
ry="1.5535225"
rx="1.6413541"
cy="12.155626"
cx="-0.2091489"
id="ellipse4705"
style="opacity:1;fill:url(#radialGradient4715);fill-opacity:1;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
style="opacity:1;fill:url(#radialGradient4717);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4624)"
id="ellipse4707"
cx="-0.2091489"
cy="12.155626"
rx="1.5645014"
ry="1.4807823" />
</g>
<path
style="opacity:0.75;fill:url(#radialGradient4719);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4695)"
d="m 3.9902344,10.974609 a 1.5645014,1.4807823 0 0 0 -1.5644532,1.480469 1.5645014,1.4807823 0 0 0 0.00195,0.05078 h 3.125 a 1.5645014,1.4807823 0 0 0 0.00195,-0.05078 1.5645014,1.4807823 0 0 0 -1.5644531,-1.480469 z"
transform="translate(-4.2,-0.3)"
id="path4711"
inkscape:connector-curvature="0" />
</g>
<g
transform="translate(10.891125,-0.02195787)"
id="g4729">
<g
id="g4725">
<ellipse
style="opacity:1;fill:url(#radialGradient4731);fill-opacity:1;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse4721"
cx="-0.2091489"
cy="12.155626"
rx="1.6413541"
ry="1.5535225" />
<ellipse
ry="1.4807823"
rx="1.5645014"
cy="12.155626"
cx="-0.2091489"
id="ellipse4723"
style="opacity:1;fill:url(#radialGradient4733);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4624)" />
</g>
<path
inkscape:connector-curvature="0"
id="path4727"
transform="translate(-4.2,-0.3)"
d="m 3.9902344,10.974609 a 1.5645014,1.4807823 0 0 0 -1.5644532,1.480469 1.5645014,1.4807823 0 0 0 0.00195,0.05078 h 3.125 a 1.5645014,1.4807823 0 0 0 0.00195,-0.05078 1.5645014,1.4807823 0 0 0 -1.5644531,-1.480469 z"
style="opacity:0.75;fill:url(#radialGradient4735);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4695)" />
</g>
<g
id="g4745"
transform="translate(16.391582,4.6221409)">
<g
id="g4741">
<ellipse
ry="1.5535225"
rx="1.6413541"
cy="12.155626"
cx="-0.2091489"
id="ellipse4737"
style="opacity:1;fill:url(#radialGradient4747);fill-opacity:1;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
style="opacity:1;fill:url(#radialGradient4749);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4624)"
id="ellipse4739"
cx="-0.2091489"
cy="12.155626"
rx="1.5645014"
ry="1.4807823" />
</g>
<path
style="opacity:0.75;fill:url(#radialGradient4751);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4695)"
d="m 3.9902344,10.974609 a 1.5645014,1.4807823 0 0 0 -1.5644532,1.480469 1.5645014,1.4807823 0 0 0 0.00195,0.05078 h 3.125 a 1.5645014,1.4807823 0 0 0 0.00195,-0.05078 1.5645014,1.4807823 0 0 0 -1.5644531,-1.480469 z"
transform="translate(-4.2,-0.3)"
id="path4743"
inkscape:connector-curvature="0" />
</g>
<g
transform="translate(15.985361,-3.9963404)"
id="g4761">
<g
id="g4757">
<ellipse
style="opacity:1;fill:url(#radialGradient4779);fill-opacity:1.0;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse4753"
cx="-0.2091489"
cy="12.155626"
rx="1.6413541"
ry="1.5535225" />
<ellipse
ry="1.4807823"
rx="1.5645014"
cy="12.155626"
cx="-0.2091489"
id="ellipse4755"
style="opacity:1;fill:url(#radialGradient4781);fill-opacity:1.0;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4624)" />
</g>
<path
inkscape:connector-curvature="0"
id="path4759"
transform="translate(-4.2,-0.3)"
d="m 3.9902344,10.974609 a 1.5645014,1.4807823 0 0 0 -1.5644532,1.480469 1.5645014,1.4807823 0 0 0 0.00195,0.05078 h 3.125 a 1.5645014,1.4807823 0 0 0 0.00195,-0.05078 1.5645014,1.4807823 0 0 0 -1.5644531,-1.480469 z"
style="opacity:0.75;fill:url(#radialGradient4783);fill-opacity:1.0;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4695)" />
</g>
<g
id="g4830"
transform="translate(5.3796885,-3.9524246)">
<g
id="g4826">
<ellipse
ry="1.5535225"
rx="1.6413541"
cy="12.155626"
cx="-0.2091489"
id="ellipse4822"
style="opacity:1;fill:url(#radialGradient4832);fill-opacity:1;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
style="opacity:1;fill:url(#radialGradient4834);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4624)"
id="ellipse4824"
cx="-0.2091489"
cy="12.155626"
rx="1.5645014"
ry="1.4807823" />
</g>
<path
style="opacity:0.75;fill:url(#radialGradient4836);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4695)"
d="m 3.9902344,10.974609 a 1.5645014,1.4807823 0 0 0 -1.5644532,1.480469 1.5645014,1.4807823 0 0 0 0.00195,0.05078 h 3.125 a 1.5645014,1.4807823 0 0 0 0.00195,-0.05078 1.5645014,1.4807823 0 0 0 -1.5644531,-1.480469 z"
transform="translate(-4.2,-0.3)"
id="path4828"
inkscape:connector-curvature="0" />
</g>
<g
transform="translate(0.19762082,-8.2342179)"
id="g4846">
<g
id="g4842">
<ellipse
style="opacity:1;fill:url(#radialGradient4848);fill-opacity:1;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse4838"
cx="-0.2091489"
cy="12.155626"
rx="1.6413541"
ry="1.5535225" />
<ellipse
ry="1.4807823"
rx="1.5645014"
cy="12.155626"
cx="-0.2091489"
id="ellipse4840"
style="opacity:1;fill:url(#radialGradient4850);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4624)" />
</g>
<path
inkscape:connector-curvature="0"
id="path4844"
transform="translate(-4.2,-0.3)"
d="m 3.9902344,10.974609 a 1.5645014,1.4807823 0 0 0 -1.5644532,1.480469 1.5645014,1.4807823 0 0 0 0.00195,0.05078 h 3.125 a 1.5645014,1.4807823 0 0 0 0.00195,-0.05078 1.5645014,1.4807823 0 0 0 -1.5644531,-1.480469 z"
style="opacity:0.75;fill:url(#radialGradient4852);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4695)" />
</g>
<g
id="g4862"
transform="translate(10.825251,-8.1244283)">
<g
id="g4858">
<ellipse
ry="1.5535225"
rx="1.6413541"
cy="12.155626"
cx="-0.2091489"
id="ellipse4854"
style="opacity:1;fill:url(#radialGradient4864);fill-opacity:1;stroke:none;stroke-width:0.03779528;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
style="opacity:1;fill:url(#radialGradient4866);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4624)"
id="ellipse4856"
cx="-0.2091489"
cy="12.155626"
rx="1.5645014"
ry="1.4807823" />
</g>
<path
style="opacity:0.75;fill:url(#radialGradient4868);fill-opacity:1;stroke:none;stroke-width:0.0360256;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4695)"
d="m 3.9902344,10.974609 a 1.5645014,1.4807823 0 0 0 -1.5644532,1.480469 1.5645014,1.4807823 0 0 0 0.00195,0.05078 h 3.125 a 1.5645014,1.4807823 0 0 0 0.00195,-0.05078 1.5645014,1.4807823 0 0 0 -1.5644531,-1.480469 z"
transform="translate(-4.2,-0.3)"
id="path4860"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 32 KiB

BIN
pix/millionaire/1/5050.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1018 B

BIN
pix/millionaire/1/5050x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
pix/millionaire/1/people.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
pix/millionaire/1/peoplex.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
pix/millionaire/1/telephone.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
pix/millionaire/1/telephonex.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
pix/millionaire/1/x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 927 B

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save