├── .gitignore ├── local ├── database.db └── config.php ├── .github └── FUNDING.yml ├── sources ├── Db.php ├── autoload.php └── Engine.php ├── save.php ├── api └── v1 │ └── objects.php ├── CONTRIBUTING.md ├── LICENSE ├── SCHEMA.sql ├── README.md ├── harvestFrom20Q.php ├── index.php ├── TECHNICAL.md └── play.php /.gitignore: -------------------------------------------------------------------------------- 1 | local/config.php 2 | local/database.db 3 | -------------------------------------------------------------------------------- /local/database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fulldecent/19-questions/HEAD/local/database.db -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [fulldecent] 4 | custom: ["https://www.paypal.me/fulldecent", "https://amazon.com/hz/wishlist/ls/EE78A23EEGQB"] 5 | -------------------------------------------------------------------------------- /local/config.php: -------------------------------------------------------------------------------- 1 | false, 13 | \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, 14 | ]; 15 | 16 | try { 17 | parent::__construct(constant('DB_DSN'), '', '', $options); 18 | } catch (\PDOException $e) { 19 | trigger_error($e->getMessage()); 20 | return false; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /save.php: -------------------------------------------------------------------------------- 1 | getObjectByName($_GET['objectname']); 13 | } else { 14 | die('Invalid object'); 15 | } 16 | list($objectName, $objectSubName) = $nq->getObject($objectID); 17 | if (empty($objectName)) die('Object database error'); 18 | //$nq->teach($objectID); 19 | header('Location: index.php?playagain=1'); 20 | 21 | //TODO: use POST to access this page instead of GET -------------------------------------------------------------------------------- /api/v1/objects.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 24 | $statement->execute(['%' . $query . '%']); 25 | 26 | echo json_encode($statement->fetchAll(\PDO::FETCH_OBJ)); 27 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Project scope 4 | 5 | Please see the README to understand what is in project scope and what contributions are likely to be accepted. If you're not sure, just ask! Please feel free to create an issue to discuss changes you would like to see for the project. 6 | 7 | ## Release process 8 | 9 | - [ ] Perform manual user testing to ensure the project is working 10 | * Use PHP 8.1 on latest macOS 11 | * Play a game 12 | * Save results 13 | * Try using the object search on the "I won" page 14 | - [ ] Tag the release and use GitHub releases 15 | - [ ] Follow distribution list (see below) 16 | 17 | ## Promoting / distribution list 18 | 19 | Following are communities that have shown an interest in this project. After each major release or new feature, reach out or post on each of the following: 20 | 21 | - https://news.ycombinator.com/ 22 | - https://www.reddit.com/r/MachineLearning/ 23 | 24 | HELP: need more ideas on how we should promote new releases 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 William Entriken 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SCHEMA.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `questions` ( 2 | `questionid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 3 | `name` TEXT NOT NULL, 4 | `subname` TEXT 5 | ); 6 | CREATE TABLE "logs" ( 7 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 8 | `host` TEXT NOT NULL, 9 | `datetime` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, 10 | `objectid` INTEGER NOT NULL, 11 | `answers` TEXT NOT NULL 12 | ); 13 | CREATE TABLE "objects" ( 14 | `objectid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 15 | `name` TEXT NOT NULL, 16 | `subname` TEXT, 17 | `hits` INTEGER NOT NULL DEFAULT 0, 18 | `visible` INTEGER NOT NULL DEFAULT 0, 19 | `calc_logl` REAL NOT NULL 20 | ); 21 | CREATE TABLE "answers" ( 22 | `objectid` INTEGER NOT NULL, 23 | `questionid` INTEGER NOT NULL, 24 | `yes` INTEGER NOT NULL, 25 | `no` INTEGER NOT NULL, 26 | `skip` INTEGER NOT NULL, 27 | `calc_y3lmin1` REAL NOT NULL, 28 | `calc_n3lmin1` REAL NOT NULL, 29 | `calc_s3lmin1` REAL NOT NULL, 30 | `calc_y3lll` REAL NOT NULL, 31 | `calc_n3lll` REAL NOT NULL, 32 | `calc_s3lll` REAL NOT NULL, 33 | `calc_y3ll` REAL NOT NULL, 34 | `calc_n3ll` REAL NOT NULL, 35 | `calc_s3ll` REAL NOT NULL, 36 | PRIMARY KEY(`objectid`,`questionid`) 37 | ); 38 | CREATE UNIQUE INDEX `questions_name` ON `questions` (`name` ,`subname` ); 39 | CREATE UNIQUE INDEX `objects_name` ON `objects` (`name` ,`subname` ) 40 | -------------------------------------------------------------------------------- /sources/autoload.php: -------------------------------------------------------------------------------- 1 | referrer) . $url; 15 | } 16 | $ch = curl_init(); 17 | curl_setopt($ch, CURLOPT_URL, $url); 18 | curl_setopt($ch, CURLOPT_REFERER, $this->referrer); 19 | curl_setopt($ch, CURLOPT_HEADER, 1); 20 | curl_setopt($ch, CURLOPT_VERBOSE, 1); 21 | if (!empty($post)) { 22 | curl_setopt($ch, CURLOPT_POST, true); 23 | curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 24 | } 25 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 26 | curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'); 27 | $this->referrer = $url; 28 | $this->page = curl_exec($ch); 29 | echo "##\n## LOADED URL {$url}\n##\n{$this->page}\n\n"; 30 | } 31 | 32 | function preg_extract_first($pattern) 33 | { 34 | if (!preg_match($pattern, $this->page, $matches)) return null; 35 | if (count($matches) < 2) return null; 36 | echo "##\n## EXTRACTED: {$pattern}\n## GOT: {$matches[1]}\n##\n\n"; 37 | return $matches[1]; 38 | } 39 | } 40 | 41 | ################################################################################ 42 | ## Now get to work 43 | ################################################################################ 44 | $scraper = new Scraper(); 45 | $scraper->referrer = 'http://y.20q.net/play'; 46 | 47 | // Load login page 48 | $scraper->loadUrl('http://y.20q.net/gsq-en'); 49 | $actionUrl = $scraper->preg_extract_first('/