├── .gitignore ├── LICENSE ├── README.md ├── basicparser.py ├── basictoken.py ├── examples ├── ADESCRIP ├── AITEMS ├── AMESSAGE ├── AMOVING ├── Pneuma.bas ├── PyBStartrek.bas ├── adventure.bas ├── bagels.bas ├── eliza.bas ├── factorial.bas ├── life.bas ├── oregon.bas ├── regression.bas └── rock_scissors_paper.bas ├── flowsignal.py ├── interpreter.py ├── lexer.py └── program.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/* 2 | *.swp 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /basictoken.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """Class to represent a token for the BASIC 19 | programming language. A token consists of 20 | three items: 21 | 22 | column Column in which token starts 23 | category Category of the token 24 | lexeme Token in string form 25 | 26 | """ 27 | 28 | 29 | class BASICToken: 30 | 31 | """BASICToken categories""" 32 | 33 | EOF = 0 # End of file 34 | LET = 1 # LET keyword 35 | LIST = 2 # LIST command 36 | PRINT = 3 # PRINT command 37 | RUN = 4 # RUN command 38 | FOR = 5 # FOR keyword 39 | NEXT = 6 # NEXT keyword 40 | IF = 7 # IF keyword 41 | THEN = 8 # THEN keyword 42 | ELSE = 9 # ELSE keyword 43 | ASSIGNOP = 10 # '=' 44 | LEFTPAREN = 11 # '(' 45 | RIGHTPAREN = 12 # ')' 46 | PLUS = 13 # '+' 47 | MINUS = 14 # '-' 48 | TIMES = 15 # '*' 49 | DIVIDE = 16 # '/' 50 | NEWLINE = 17 # End of line 51 | UNSIGNEDINT = 18 # Integer 52 | NAME = 19 # Identifier that is not a keyword 53 | EXIT = 20 # Used to quit the interpreter 54 | DIM = 21 # DIM keyword 55 | GREATER = 22 # '>' 56 | LESSER = 23 # '<' 57 | STEP = 24 # STEP keyword 58 | GOTO = 25 # GOTO keyword 59 | GOSUB = 26 # GOSUB keyword 60 | INPUT = 27 # INPUT keyword 61 | REM = 28 # REM keyword 62 | RETURN = 29 # RETURN keyword 63 | SAVE = 30 # SAVE command 64 | LOAD = 31 # LOAD command 65 | NOTEQUAL = 32 # '<>' 66 | LESSEQUAL = 33 # '<=' 67 | GREATEQUAL = 34 # '>=' 68 | UNSIGNEDFLOAT = 35 # Floating point number 69 | STRING = 36 # String values 70 | TO = 37 # TO keyword 71 | NEW = 38 # NEW command 72 | EQUAL = 39 # '=' 73 | COMMA = 40 # ',' 74 | STOP = 41 # STOP keyword 75 | COLON = 42 # ':' 76 | ON = 43 # ON keyword 77 | POW = 44 # Power function 78 | SQR = 45 # Square root function 79 | ABS = 46 # Absolute value function 80 | DIM = 47 # DIM keyword 81 | RANDOMIZE = 48 # RANDOMIZE keyword 82 | RND = 49 # RND keyword 83 | ATN = 50 # Arctangent function 84 | COS = 51 # Cosine function 85 | EXP = 52 # Exponential function 86 | LOG = 53 # Natural logarithm function 87 | SIN = 54 # Sine function 88 | TAN = 55 # Tangent function 89 | DATA = 56 # DATA keyword 90 | READ = 57 # READ keyword 91 | INT = 58 # INT function 92 | CHR = 59 # CHR$ function 93 | ASC = 60 # ASC function 94 | STR = 61 # STR$ function 95 | MID = 62 # MID$ function 96 | MODULO = 63 # MODULO operator 97 | TERNARY = 64 # TERNARY functions 98 | VAL = 65 # VAL function 99 | LEN = 66 # LEN function 100 | UPPER = 67 # UPPER function 101 | LOWER = 68 # LOWER function 102 | ROUND = 69 # ROUND function 103 | MAX = 70 # MAX function 104 | MIN = 71 # MIN function 105 | INSTR = 72 # INSTR function 106 | AND = 73 # AND operator 107 | OR = 74 # OR operator 108 | NOT = 75 # NOT operator 109 | PI = 76 # PI constant 110 | RNDINT = 77 # RNDINT function 111 | OPEN = 78 # OPEN keyword 112 | HASH = 79 # "#" 113 | CLOSE = 80 # CLOSE keyword 114 | FSEEK = 81 # FSEEK keyword 115 | RESTORE = 82 # RESTORE keyword 116 | APPEND = 83 # APPEND keyword 117 | OUTPUT = 84 # OUTPUT keyword 118 | TAB = 85 # TAB function 119 | SEMICOLON = 86 # SEMICOLON 120 | LEFT = 87 # LEFT$ function 121 | RIGHT = 88 # RIGHT$ function 122 | 123 | # Displayable names for each token category 124 | catnames = ['EOF', 'LET', 'LIST', 'PRINT', 'RUN', 125 | 'FOR', 'NEXT', 'IF', 'THEN', 'ELSE', 'ASSIGNOP', 126 | 'LEFTPAREN', 'RIGHTPAREN', 'PLUS', 'MINUS', 'TIMES', 127 | 'DIVIDE', 'NEWLINE', 'UNSIGNEDINT', 'NAME', 'EXIT', 128 | 'DIM', 'GREATER', 'LESSER', 'STEP', 'GOTO', 'GOSUB', 129 | 'INPUT', 'REM', 'RETURN', 'SAVE', 'LOAD', 130 | 'NOTEQUAL', 'LESSEQUAL', 'GREATEQUAL', 131 | 'UNSIGNEDFLOAT', 'STRING', 'TO', 'NEW', 'EQUAL', 132 | 'COMMA', 'STOP', 'COLON', 'ON', 'POW', 'SQR', 'ABS', 133 | 'DIM', 'RANDOMIZE', 'RND', 'ATN', 'COS', 'EXP', 134 | 'LOG', 'SIN', 'TAN', 'DATA', 'READ', 'INT', 135 | 'CHR', 'ASC', 'STR', 'MID', 'MODULO', 'TERNARY', 136 | 'VAL', 'LEN', 'UPPER', 'LOWER', 'ROUND', 137 | 'MAX', 'MIN', 'INSTR', 'AND', 'OR', 'NOT', 'PI', 138 | 'RNDINT', 'OPEN', 'HASH', 'CLOSE', 'FSEEK', 'APPEND', 139 | 'OUTPUT', 'RESTORE', 'RNDINT', 'TAB', 'SEMICOLON', 140 | 'LEFT', 'RIGHT'] 141 | 142 | smalltokens = {'=': ASSIGNOP, '(': LEFTPAREN, ')': RIGHTPAREN, 143 | '+': PLUS, '-': MINUS, '*': TIMES, '/': DIVIDE, 144 | '\n': NEWLINE, '<': LESSER, 145 | '>': GREATER, '<>': NOTEQUAL, 146 | '<=': LESSEQUAL, '>=': GREATEQUAL, ',': COMMA, 147 | ':': COLON, '%': MODULO, '!=': NOTEQUAL, '#': HASH, 148 | ';': SEMICOLON} 149 | 150 | 151 | # Dictionary of BASIC reserved words 152 | keywords = {'LET': LET, 'LIST': LIST, 'PRINT': PRINT, 153 | 'FOR': FOR, 'RUN': RUN, 'NEXT': NEXT, 154 | 'IF': IF, 'THEN': THEN, 'ELSE': ELSE, 155 | 'EXIT': EXIT, 'DIM': DIM, 'STEP': STEP, 156 | 'GOTO': GOTO, 'GOSUB': GOSUB, 157 | 'INPUT': INPUT, 'REM': REM, 'RETURN': RETURN, 158 | 'SAVE': SAVE, 'LOAD': LOAD, 'NEW': NEW, 159 | 'STOP': STOP, 'TO': TO, 'ON':ON, 'POW': POW, 160 | 'SQR': SQR, 'ABS': ABS, 161 | 'RANDOMIZE': RANDOMIZE, 'RND': RND, 162 | 'ATN': ATN, 'COS': COS, 'EXP': EXP, 163 | 'LOG': LOG, 'SIN': SIN, 'TAN': TAN, 164 | 'DATA': DATA, 'READ': READ, 'INT': INT, 165 | 'CHR$': CHR, 'ASC': ASC, 'STR$': STR, 166 | 'MID$': MID, 'MOD': MODULO, 167 | 'IF$': TERNARY, 'IFF': TERNARY, 168 | 'VAL': VAL, 'LEN': LEN, 169 | 'UPPER$': UPPER, 'LOWER$': LOWER, 170 | 'ROUND': ROUND, 'MAX': MAX, 'MIN': MIN, 171 | 'INSTR': INSTR, 'END': STOP, 172 | 'AND': AND, 'OR': OR, 'NOT': NOT, 173 | 'PI': PI, 'RNDINT': RNDINT, 'OPEN': OPEN, 174 | 'CLOSE': CLOSE, 'FSEEK': FSEEK, 175 | 'APPEND': APPEND, 'OUTPUT':OUTPUT, 176 | 'RESTORE': RESTORE, 'TAB': TAB, 177 | 'LEFT$': LEFT, 'RIGHT$': RIGHT} 178 | 179 | 180 | # Functions 181 | functions = {ABS, ATN, COS, EXP, INT, LOG, POW, RND, SIN, SQR, TAN, 182 | CHR, ASC, MID, TERNARY, STR, VAL, LEN, UPPER, LOWER, 183 | ROUND, MAX, MIN, INSTR, PI, RNDINT, TAB, LEFT, RIGHT} 184 | 185 | def __init__(self, column, category, lexeme): 186 | 187 | self.column = column # Column in which token starts 188 | self.category = category # Category of the token 189 | self.lexeme = lexeme # Token in string form 190 | 191 | def pretty_print(self): 192 | """Pretty prints the token 193 | 194 | """ 195 | print('Column:', self.column, 196 | 'Category:', self.catnames[self.category], 197 | 'Lexeme:', self.lexeme) 198 | 199 | def print_lexeme(self): 200 | print(self.lexeme, end=' ') 201 | -------------------------------------------------------------------------------- /examples/ADESCRIP: -------------------------------------------------------------------------------- 1 | You're in the forest. 2 | You're in the forest. 3 | You're in the forest. 4 | You're in the forest. 5 | You're at the hill in the road. 6 | You're at the end of the road again. 7 | You're inside the Building. 8 | You're in the valley. 9 | You're at slit in the streambed. 10 | You're directly above a grate in a dry streambed. 11 | You're below the grate. 12 | You're in the cobble crawl. 13 | You're in the debris room. 14 | You are in an awkward sloping east/west canyon. 15 | You're in the bird chamber. 16 | You're at the top of the small pit. 17 | You're in the Hall of Mists. 18 | You're in the nugget of gold room. 19 | You're on the east bank of the fissure. 20 | You are on the west side of the fissure in the Hall of Mists. 21 | You're at west end of the Hall of Mists. 22 | You're in the Hall of the Mountain King. 23 | You are in the south side chamber. 24 | You are in the west side chamber of the Hall of the Mountain King. 25 | You are at a N/S passage at a hole in the floor. 26 | You're at Y2 . 27 | You're at the window near the pit. 28 | The passage here is blocked by a recent cave-in. 29 | You're at the east end of the Long Hall. 30 | You're at west end of the Long Hall. 31 | You are at a crossover of a high N/S passage and a low E/W one. 32 | Dead end 33 | You are in a dirty broken passage. 34 | You're at the top of the small pit. 35 | You are in a little pit which has a stream flowing through it. 36 | You're in the dusty rock room. 37 | You're at a complex junction. 38 | You're in the anteroom. 39 | You are at Witt's end. Passages lead off in *all* directions. 40 | You're in the shell room. 41 | You're in the arched hall. 42 | You're in a long sloping corridor with ragged sharp walls. 43 | You are in a cul-de-sac about eight feet across. How's your french? 44 | You are in bedquilt, a long east/west passage with holes everywhere. 45 | You're in the swiss cheese room. 46 | You're in the soft room. 47 | You're at the east end of the Twopit room. 48 | You're at the west end of the Twopit room. 49 | You're in the east pit. 50 | You're in the west pit. 51 | You're in the slab room. 52 | You're in the Oriental room. 53 | You are in a large low room. 54 | You're in a sloping corridor. 55 | Dead end crawl. 56 | You're in the misty cavern. 57 | You're in the alcove. 58 | You're in the Plover room. 59 | You're in the dark-room. 60 | You're on the SW side of the chasm. 61 | You're on the NE side of the chasm. 62 | You're in a corridor. 63 | You're at the fork in the path. 64 | You're in the limestone passage. 65 | You're at a junction with warm walls. 66 | You're in the chamber of boulders. 67 | You're at a breath-taking view. 68 | You're in front of the barren room. 69 | You're in the barren room. 70 | You're in a narrow corridor. 71 | You're in the Giant room. 72 | The passage here is blocked by a recent cave-in. 73 | You are at one end of an immense north/south passage. 74 | You're in the cavern with a waterfall 75 | You're at a steep incline above a large room. 76 | You are in a secret N/S canyon above a sizable passage. 77 | You're at the top of the stalactite. 78 | You're at a junction of three secret canyons. 79 | You are in a secret N/S canyon above a large room. 80 | You're in mirror canyon. 81 | You're at a reservoir. 82 | You are in a secret canyon which exits to the north and east. 83 | You're in the secret E/W canyon above a tight canyon. 84 | You are at a wide place in a very tight N/S canyon. 85 | The canyon here becomes too tight to go on. 86 | You are in a tall E/W canyon. 87 | The canyon runs into a mass of boulders -- dead end. 88 | You are in a maze of twisty little passages, all alike. 89 | You are in a maze of twisty little passages, all alike. 90 | You are in a maze of twisty little passages, all alike. 91 | You are in a maze of twisty little passages, all alike. 92 | You are in a maze of twisty little passages, all alike. 93 | You are in a maze of twisty little passages, all alike. 94 | You are in a maze of twisty little passages, all alike. 95 | You are in a maze of twisty little passages, all alike. 96 | You are in a maze of twisty little passages, all alike. 97 | You are in a maze of twisty little passages, all alike. 98 | You are at a huge orange stalactite in the maze. 99 | You are in a maze of twisty little passages, all alike. 100 | You are at a dead end. -------------------------------------------------------------------------------- /examples/AITEMS: -------------------------------------------------------------------------------- 1 | There is a large sparking nugget of gold here! 2 | There are bars of silver here! 3 | There is precious jewelry here! 4 | There are many coins here! 5 | There are several diamonds here! 6 | There is a delicate, precious ming vase here! 7 | To one side lies a glistening Pearl! 8 | There is a nest here, full of golden eggs! 9 | There is a jewel-encrusted trident here! 10 | There is an emerald the size of a plover's egg here! 11 | There is a platinum pyramid here, eight inches on a side! 12 | There is a golden chain here! 13 | There are rare spices here! 14 | There is a valuable persian rug here! 15 | There is a chest here, full of various treasures! 16 | There is a bottle of water here. 17 | There is a small pool of oil here. 18 | There is a brass lantern here. 19 | There is a set of keys here. 20 | There is food here. 21 | There is a glass bottle here. 22 | There is a small wicker cage here. 23 | There is a 3-foot black rod here. 24 | There is an enormous clam here with its shell tightly shut. 25 | There is a recent issue of 'Spelunker Today' here. 26 | There is a bear nearby. 27 | There is a little axe here. 28 | There is a purple velvet pillow here. 29 | There are shards of pottery scattered about. 30 | There is an enormous oyster here with its shell tightly shut. 31 | There is a little bird here. 32 | A burly troll stands in front of you. 33 | A huge fierce green dragon bars the way! 34 | A huge fierce green snake bars the way! 35 | There is a threatening little dwarf in the room with you! -------------------------------------------------------------------------------- /examples/AMESSAGE: -------------------------------------------------------------------------------- 1 | #1 2 | You can't move that way. 3 | #2.1 4 | Nothing happens. 5 | #2.2 6 | Nothing seems to happen. 7 | #2.3 8 | I don't think that had any affect on anything. 9 | #2.4 10 | I don't know how to apply that word here. 11 | #2.5 12 | That had little effect, if any at all. 13 | #3 14 | The mist is quite thick here, and the fissure is too wide to jump. 15 | #4 16 | You are at the bottom of the pit with a broken neck. 17 | #5 18 | The bottle is already filled! 19 | #6 20 | The bear eagerly wolfs down your food, after which he seems to calm 21 | down considerably and even becomes rather friendly. burp 22 | #7 23 | The plant surges upwards, reaching halfway to the hole above you 24 | #8 25 | The plant grows explosively, almost filling the bottom of the pit. 26 | #9 27 | You overwatered the plant, you fool! 28 | #10 29 | The grate is locked. 30 | #11 31 | The grate is unlocked. 32 | #12 33 | The bear is quite ferocious, and will no doubt tear you to 34 | shreds if you approach it! 35 | #13 36 | The chain is unlocked and the bear is free. 37 | #14 38 | A crystal bridge now spans the fissure. 39 | #15 40 | The bridge vanishes. 41 | #16 42 | It is beyond your power to do that. 43 | #17 44 | The clam opens momenntarily, and a glistening pearl falls out 45 | and rolls away. Goodness, this must really have been an oyster. 46 | (I never was any good at identifying bivalves, anyway.) 47 | #18 48 | I can't close that! 49 | #19 50 | The oil has freed up the hinges so that the door will now move, 51 | although it requires some effort. 52 | #20 53 | I can't eat. 54 | #21 55 | How can I drink that? 56 | #22 57 | "Glug, glug, glug, Belch!" 58 | #23 59 | It doesn't want to eat anything (except maybe you!) 60 | #24 61 | You fool! Dwarves only eat coal! Now you've made him 62 | *** REALLY MAD ****! 63 | #25 64 | Trolls are close relatives with the rocks and have skin as tough as 65 | that of a rhinoceros. The troll fends off your blows effortlessly. 66 | #26 67 | The troll deftly catches the axe, examines it carefully, and tosses it 68 | back, declaring, "Good workmanship, but it's not valuable enough." 69 | #27 70 | The troll catches your treasure and scurries away out of sight. 71 | #28 72 | The bear lumbers toward the troll, who lets out a startled shriek and 73 | scurries away. The bear soon gives up the pursuit and wanders back. 74 | #29 75 | You attack a little dwarf, but he dodges out of the way. 76 | #30 77 | You killed a little dwarf. The body vanishes in a cloud of greasy 78 | black smoke. 79 | #31 80 | There is a threatening little dwarf in the room with you! 81 | #32 82 | One sharp nasty knife is thrown at you! 83 | #33 84 | Out from the shadows behind you pounces a bearded pirate! "Har, har," 85 | he chortles, "I'll just take all this booty and hide it away with me 86 | chest deep in the maze!" he snatches your treasure and vanishes into 87 | the gloom. 88 | #34 89 | There are faint rustling noises from the darkness behind you. 90 | #35 91 | The grate is open. 92 | #36 93 | The grate is locked. 94 | #37 95 | The bird was unafraid when you entered, but as you approach it becomes 96 | disturbed and you cannot catch it. 97 | #38 98 | The dome is unclimbable. 99 | #39 100 | A crystal bridge now spans the fissure. 101 | #40 102 | A huge green fierce snake bars the way! Hisssssss 103 | #41 104 | A hollow voice says "Plugh". 105 | #42 106 | The vase is now resting, delicately, on a velvet pillow. 107 | #43 108 | Crash! Tinkle! The ming vase shatters into worthless crockery. 109 | #44 110 | You fell into a pit and broke every bone in your body! 111 | #45 112 | It is now pitch dark. If you proceed you will likely fall into a pit. 113 | #46 114 | The nest of golden eggs has vanished! 115 | #47 116 | There is a tiny little plant in the pit, murmuring "water, water, ..." 117 | #48 118 | There is a 12-foot-tall beanstalk stretching up out of the pit, 119 | bellowing "WATER!! WATER!!" 120 | #49 121 | There is a gigantic beanstalk stretching all the way up to the hole. 122 | #50 123 | You can't get by the snake. He hates your guts. 124 | #51 125 | The dragon has a rather "volatile" personality, and he will 126 | probably incinerate you if you get any closer. 127 | #52 128 | You have crawled around in some little holes and wound up back in the 129 | main passage. 130 | #53 131 | Something you're carrying won't fit through the tunnel with you. 132 | #54 133 | Your load is too heavy. You'd best take inventory and drop 134 | something first. 135 | #55 136 | A burly troll stands by the bridge and insists you throw him a 137 | treasure before you may cross. 138 | #56 139 | The troll pops from under the bridge and blocks your way. 140 | #57 141 | The way north is barred by a massive, rusty, iron door. 142 | #58 143 | The bear will bite off your hand. Besides, the chain is locked to the wall. 144 | #59 145 | It's rather difficult to move a twenty-ton dragon, considering 146 | he is lying on the rug. 147 | #60 148 | The vase is now resting, delicately, on a velvet pillow. 149 | #61.1 150 | A valliant attempt! 151 | #61.2 152 | Nice try! 153 | #61.3 154 | A valliant attempt, but you're not that strong! 155 | #61.4 156 | Don't be silly! 157 | #61.5 158 | Do you have any idea on how to do that? 159 | #62 160 | A huge green fierce dragon blocks the way. The dragon is lying 161 | on a persian rug! 162 | #63 163 | A burly troll stands beside the bridge, blocking your way. 164 | #64 165 | There is a ferocious cave bear eyeing you from the far end of the room! 166 | #65 167 | The bear is locked to the wall with a golden chain! 168 | #66 169 | There is a calm, friendly bear locked to the wall. 170 | #67 171 | You are being followed by a very large, tame bear. 172 | #68 173 | With what? Your bare hands? 174 | #69 175 | Congratulations! You have just vanquished a dragon with your bare hands 176 | (hard to believe ain't it?). 177 | #70 178 | Attacking it is both dangerous and doesn't work. 179 | #71 180 | There is nothing here to attack. 181 | #72 182 | How can you do that to more than one thing at a time? 183 | #73 184 | Thank you, it was delicious! 185 | #74 186 | I see nothing special about that. 187 | #75 188 | Oh dear, you seem to have gotten yourself killed. I might be able to 189 | help you out, but I've never really done this before. Do you want me 190 | to try to reincarnate you? 191 | #76 192 | All right. But don't blame me if something goes wr...... 193 | --- POOF!! --- 194 | You are engulfed in a cloud of orange smoke. Coughing and gasping, 195 | you emerge from the smoke and find.... 196 | #77 197 | You clumsy oaf, you've done it again! I don't know how long I can 198 | keep this up. Do you want me to try reincarnating you again? 199 | #78 200 | Now you've really done it! I'm out of orange smoke! You don't expect 201 | me to do a decent reincarnation without any orange smoke, do you? 202 | Better luck next time! 203 | #79 204 | The nest of golden eggs has vanished! 205 | #80 206 | A little dwarf just walked around a corner, saw you, threw a little 207 | axe at you which missed, cursed and ran away. 208 | #81 209 | The nest of golden eggs has re-appeared! 210 | #200 211 | You are in a forest, with trees all around you. 212 | #205 213 | You have walked up a hill, still in the forest. The road slopes back 214 | down the other side of the hill. There is a building in the distance. 215 | #206 216 | You are standing at the end of a road before a small brick building. 217 | Around you is a forest. A small stream flows out of the building and 218 | down a gully. 219 | #207 220 | You are inside a building, a well house for a large spring. 221 | #208 222 | You are in a valley in the forest beside a stream tumbling along a 223 | rocky bed. 224 | #209 225 | At your feet all the water of the stream splashes into a 2-inch slit 226 | in the rock. Downstream the streambed is bare rock. 227 | #210 228 | You are in a 20-foot depression floored with bare dirt. Set into the 229 | dirt is a strong steel grate mounted in concrete. A dry streambed 230 | leads into the depression. 231 | #211 232 | You are in a small chamber beneath a 3x3 steel grate to the surface. 233 | A low crawl over cobbles leads inward to the west. 234 | #212 235 | You are crawling over cobbles in a low passage. There is a dim light 236 | at the east end of the passage. 237 | #213 238 | You are in a debris room filled with stuff washed in from the surface. 239 | A low wide passage with cobbles becomes plugged with mud and debris 240 | here, but an awkward canyon leads upward and west. A note on the wall 241 | says "magic word XYZZY." 242 | #214 243 | You are in an awkward sloping east/west canyon. 244 | #215 245 | You are in a splendid chamber thirty feet high. The walls are frozen 246 | rivers of orange stone. An awkward canyon and a good passage exit 247 | from east and west sides of the chamber. 248 | #216 249 | At your feet is a small pit breathing traces of white mist. An east 250 | passage ends here except for a small crack leading on. 251 | 252 | Rough stone steps lead down the pit. 253 | #217 254 | You are at one end of a vast hall stretching forward out of sight to 255 | the west. There are openings to either side. Nearby, a wide stone 256 | staircase leads downward. The hall is filled with wisps of white mist 257 | swaying to and fro almost as if alive. A cold wind blows up the 258 | staircase. There is a passage at the top of a dome behind you. 259 | 260 | Rough stone steps lead to the top of the dome. 261 | #218 262 | This is a low room with a crude note on the wall. The note says, 263 | "you can't get it up the steps." 264 | #219 265 | You are on the east bank of a fissure slicing clear across the hall. 266 | The mist is quite thick here, and the fissure is too wide to jump. 267 | #220 268 | You are on the west side of the fissure in the Hall of Mists. 269 | #221 270 | You are at the west end of Hall of Mists. A low wide crawl continues 271 | west and another goes north. To the south is a little passage 6 feet 272 | off the floor. 273 | #222 274 | You are in the Hall of the Mountain King, with passages off in all 275 | directions. 276 | #223 277 | You are in the south side chamber. 278 | #224 279 | You are in the west side chamber of the Hall of the Mountain King. 280 | A passage continues west and up here. 281 | #225 282 | You are in a low N/S passage at a hole in the floor. The hole goes 283 | down to an E/W passage. 284 | #226 285 | You are in a large room, with a passage to the south, a passage to the 286 | west, and a wall of broken rock to the east. There is a large "Y2" on 287 | a rock in the room's center. 288 | #227 289 | You're at a low window overlooking a huge pit, which extends up out of 290 | sight. A floor is indistinctly visible over 50 feet below. Traces of 291 | white mist cover the floor of the pit, becoming thicker to the right. 292 | Marks in the dust around the window would seem to indicate that 293 | someone has been here recently. Directly across the pit from you and 294 | 25 feet away there is a similar window looking into a lighted room. A 295 | shadowy figure can be seen there peering back at you. 296 | 297 | The shadowy figure seems to be trying to attract your attention. 298 | #228 299 | The passage here is blocked by a recent cave-in. 300 | #229 301 | You are at the east end of a very long hall apparently without side 302 | chambers. To the east a low wide crawl slants up. To the north a 303 | round two foot hole slants down. 304 | #230 305 | You are at the west end of a very long featureless hall. The hall 306 | joins up with a narrow north/south passage. 307 | #231 308 | You are at a crossover of a high N/S passage and a low E/W one. 309 | #232 310 | Dead end 311 | #233 312 | You are in a dirty broken passage. To the east is a crawl. To the 313 | west is a large passage. Above you is a hole to another passage. 314 | #234 315 | You are on the brink of a small clean climbable pit. A crawl leads 316 | west. 317 | #235 318 | You are in the bottom of a small pit with a little stream, which 319 | enters and exits through tiny slits. 320 | #236 321 | You are in a large room full of dusty rocks. There is a big hole in 322 | the floor. There are cracks everywhere, and a passage leading east. 323 | #237 324 | You are at a complex junction. A low hands and knees passage from the 325 | north joins a higher crawl from the east to make a walking passage 326 | going west. There is also a large room above. The air is damp here. 327 | #238 328 | You are in an anteroom leading to a large passage to the east. Small 329 | passages go west and up. The remnants of recent digging are evident. 330 | a sign in midair here says "Cave under construction beyond this point. 331 | proceed at own risk. "[Witt Construction Company]" 332 | #239 333 | You are at Witt's end. Passages lead off in *all* directions. 334 | #240 335 | You're in a large room carved out of sedimentary rock. The floor and 336 | walls are littered with bits of shells embedded in the stone. A 337 | shallow passage proceeds downward, and a somewhat steeper one leads 338 | up. A low hands and knees passage enters from the south. 339 | #241 340 | You are in an arched hall. A coral passage once continued up and east 341 | from here, but is now blocked by debris. The air smells of sea water. 342 | #242 343 | You are in a long sloping corridor with ragged sharp walls. 344 | #243 345 | You are in a cul-de-sac about eight feet across. How's your french? 346 | #244 347 | You are in bedquilt, a long east/west passage with holes everywhere. 348 | To explore at random, select north, south, up or down. 349 | #245 350 | You are in a room whose walls resemble swiss cheese. Obvious passages 351 | go west, east, NE, and NW. Part of the room is occupied by a large 352 | bedrock block. 353 | #246 354 | You are in the soft room. The walls are covered with heavy curtains, 355 | the floor with a thick pile carpet. Moss covers the ceiling. 356 | #247 357 | You are at the east end of the Twopit room. The floor here is 358 | littered with thin rock slabs, which make it easy to descend the pits. 359 | There is a path here bypassing the pits to connect passages from east 360 | and west. There are holes all over, but the only big one is on the 361 | wall directly over the west pit where you can't get to it. 362 | #248 363 | You are at the west end of the Twopit room. There is a large hole in 364 | the wall above the pit at this end of the room. 365 | #249 366 | You are at the bottom of the eastern pit in the Twopit room. There is 367 | a small pool of oil in one corner of the pit. 368 | #250 369 | You are at the bottom of the western pit in the Twopit room. There is 370 | a large hole in the wall about 25 feet above you. 371 | #251 372 | You are in a large low circular chamber whose floor is an immense slab 373 | fallen from the ceiling (slab room). East and west there once were 374 | large passages, but they are now filled with boulders. Low small 375 | passages go north and south, and the south one quickly bends west 376 | around the boulders. 377 | #252 378 | This is the oriental room. Ancient oriental cave drawings cover the 379 | walls. A gently sloping passage leads upward to the north, another 380 | passage leads SE, and a hands and knees crawl leads west. 381 | #253 382 | You are in a large low room. Crawls lead north, SE, and SW. 383 | #254 384 | You are in a long winding corridor sloping out of sight in both 385 | directions. 386 | #255 387 | Dead end crawl. 388 | #256 389 | You are following a wide path around the outer edge of a large cavern. 390 | Far below, through a heavy white mist, strange splashing noises can be 391 | heard. The mist rises up through a fissure in the ceiling. The path 392 | exits to the south and west. 393 | #257 394 | You are in an alcove. A small NW path seems to widen after a short 395 | distance. An extremely tight tunnel leads east. It looks like a very 396 | tight squeeze. An eerie light can be seen at the other end. 397 | #258 398 | You're in a small chamber lit by an eerie green light. An extremely 399 | narrow tunnel exits to the west. A dark corridor leads NE. 400 | #259 401 | You're in the dark-room. A corridor leading south is the only exit. 402 | A massive stone tablet embedded in the wall reads: 403 | "Congratulations on bringing light into the dark-room!" 404 | #260 405 | You are on one side of a large, deep chasm. A heavy white mist rising 406 | up from below obscures all view of the far side. A SW path leads away. 407 | 408 | A rickety wooden bridge extends across the chasm, vanishing into the 409 | mist. A sign posted on the bridge reads, "STOP! Pay Troll!" 410 | #261 411 | You are on the far side of the chasm. A NE path leads away from the 412 | chasm on this side. 413 | 414 | A rickety wooden bridge extends across the chasm, vanishing into the 415 | gloom. A sign posted on the bridge reads: "Stop! Pay troll!" 416 | #262 417 | You're in a long east/west corridor. A faint rumbling noise can be 418 | heard in the distance. 419 | #263 420 | The path forks here. The left fork leads northeast. A dull rumbling 421 | seems to get louder in that direction. The right fork leads southeast 422 | down a gentle slope. The main corridor enters from the west. 423 | #264 424 | You are walking along a gently sloping north/south passage lined with 425 | oddly shaped limestone formations. 426 | #265 427 | The walls are quite warm here. From the north can be heard a steady 428 | roar, so loud that the entire cave seems to be trembling. Another 429 | passage leads south, and a low crawl goes east. 430 | #266 431 | You are in a small chamber filled with large boulders. The walls are 432 | very warm, causing the air in the room to be almost stifling from the 433 | heat. The only exit is a crawl heading west, through which is coming 434 | a low rumbling. 435 | #267 436 | You are on the edge of a breath-taking view. Far below you is an 437 | active volcano, from which great gouts of molten lava come surging 438 | out, cascading back down into the depths. The glowing rock fills the 439 | farthest reaches of the cavern with a blood-red glare, giving every- 440 | thing an eerie, macabre appearance. The air is filled with flickering 441 | sparks of ash and a heavy smell of brimstone. The walls are hot to 442 | the touch, and the thundering of the volcano drowns out all other 443 | sounds. Embedded in the jagged roof far overhead are myriad twisted 444 | formations composed of pure white alabaster, which scatter the murky 445 | light into sinister apparitions upon the walls. To one side is a deep 446 | gorge, filled with a bizarre chaos of tortured rock which seems to 447 | have been crafted by the devil himself. An immense river of fire 448 | crashes out from the depths of the volcano, burns its way through the 449 | gorge, and plummets into a bottomless pit far off to your left. To 450 | the right, an immense geyser of blistering steam erupts continuously 451 | from a barren island in the center of a sulfurous lake, which bubbles 452 | ominously. The far right wall is aflame with an incandescence of its 453 | own, which lends an additional infernal splendor to the already 454 | hellish scene. A dark, foreboding passage exits to the south. 455 | #268 456 | You are standing at the entrance to a large, barren room. A sign 457 | posted above the entrance reads: "Caution! Bear in room!" 458 | #269 459 | You are inside a barren room. The center of the room is completely 460 | empty except for some dust. Marks in the dust lead away toward the 461 | far end of the room. The only exit is the way you came in. 462 | #270 463 | You are in a long, narrow corridor stretching out of sight to the 464 | west. At the eastern end is a hole through which you can see a 465 | profusion of leaves. 466 | #271 467 | You are in the giant room. The ceiling here is too high up for your 468 | lamp to show it. Cavernous passages lead east, north, and south. On 469 | the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic]. 470 | #272 471 | The passage here is blocked by a recent cavein. 472 | #273 473 | You are at one end of an immense north/south passage. 474 | #274 475 | You are in a magnificent cavern with a rushing stream, which cascades 476 | over a sparkling waterfall into a roaring whirlpool which disappears 477 | through a hole in the floor. Passages exit to the south and west. 478 | #275 479 | You are at the top of a steep incline above a large room. You could 480 | climb down here, but you would not be able to climb up. There is a 481 | passage leading back to the north. 482 | #276 483 | You are in a secret N/S canyon above a sizable passage. 484 | #277 485 | A large stalactite extends from the roof and almost reaches the floor 486 | below. You could climb down it, and jump from it to the floor, but 487 | having done so you would be unable to reach it to climb back up. 488 | 489 | The maze continues at this level. 490 | #278 491 | You are in a secret canyon at a junction of three canyons, bearing 492 | north, south, and SE. The north one is as tall as the other two 493 | combined. 494 | #279 495 | You are in a secret N/S canyon above a large room. 496 | #280 497 | You are in a north/south canyon about 25 feet across. The floor is 498 | covered by white mist seeping in from the north. The walls extend 499 | upward for well over 100 feet. Suspended from some unseen point far 500 | above you, an enormous two-sided mirror is hanging parallel to and 501 | midway between the canyon walls. (The mirror is obviously provided 502 | for the use of the dwarves, who as you know, are extremely vain.) A 503 | small window can be seen in either wall, some fifty feet up. 504 | #281 505 | You are at the edge of a large underground reservoir. An opaque cloud 506 | of white mist fills the room and rises rapidly upward. The lake is 507 | fed by a stream, which tumbles out of a hole in the wall about 10 feet 508 | overhead and splashes noisily into the water somewhere within the 509 | mist. The only passage goes back toward the south. 510 | #282 511 | You are in a secret canyon which exits to the north and east. 512 | #283 513 | You're in the secret E/W canyon above a tight canyon. 514 | #284 515 | You are at a wide place in a very tight N/S canyon. 516 | #285 517 | The canyon here becomes too tight to go on. 518 | #286 519 | You are in a tall E/W canyon. A low tight crawl goes 3 feet north and 520 | seems to open up. 521 | #287 522 | The canyon runs into a maze of boulders -- dead end. 523 | #288 524 | You are in a maze of twisty little passages, all alike. 525 | #298 526 | You are near a large pit beside a large stalactite in the maze. 527 | The stalactite is about 30 feet long, allowing you to descend 528 | it. However, due to the smoothness of the stalactite you will 529 | probably be unable to climb back up again. 530 | #299 531 | The threatening little dwarf pulls out a sharp, nasty knife but 532 | suddenly freezes. 533 | 534 | The burly troll notices the little dwarf and appears to become very angry. 535 | 536 | The little dwarf frantically looks from side to side, the burly troll 537 | takes a sudden step towards the little dwarf. 538 | 539 | The little dwarf makes an odd squeal, steps back and trips on an outcropping, 540 | falling with a soft *thud* before scrambling out of sight in a cloud of dust. 541 | #300 542 | Dead end. 543 | #301 544 | Welcome to adventure.! Would you like instructions? 545 | #302 546 | Somewhere nearby is Colossal Cave, where others have found fortunes in 547 | treasure and gold, though it is rumored that some who enter are never 548 | seen again. Magic is said to work in the cave. I will be your eyes 549 | and hands. Direct me with commands such as get, take, or look. Since you 550 | need to move around, you must usually enter compass directions 551 | (N,NE,E,SE,S,SW,W,NW or up or down), although you may sometimes use 552 | more vague verbs with with to move. I know of several objects in this 553 | game, such as a lamp and a bottle. I also know of special objects in the 554 | cave. Some of these objects have side effects, ie there is a rod in the 555 | cave that scares a little bird. 556 | ----------------------------------------------------------------- 557 | The object of this game is to gather as many treasures as you can and 558 | put them back in the house. You also run the risk of getting robbed or 559 | killed by some rather unfriendly inhabitants of the cave. 560 | ---------------------------------------------------------------- 561 | There are some useful commands that you should know about: 562 | --- Brief, Long, and Short - these commands control the amount of 563 | --- detail you get in descriptions. 564 | --- Look (or L) - gives a detailed description of your surroundings. 565 | --- Inventory (or I) tells you what you are carrying. 566 | --- Quit, Stop or End - these are self-explanatory. 567 | --- Save - by typing this, you may save your game and continue it at 568 | --- a later time. 569 | --- Continue - lets you continue an old game. 570 | --- Score - tells you hw well you're doing. 571 | 572 | Other helpful functions include: 573 | * multiple commands on one input line, ie: 574 | "Go south, get car, keys, Start car." (example only) 575 | -------------------------------------------------------------- 576 | "Adventure" is a version of the game created by Willy Crowther and 577 | Dan Woods at M.I.T. 578 | -------------------------------------------------------------- 579 | #303 580 | I'm sorry, but the magazine is written in Dwarvish. 581 | # 582 | # 583 | # -------------------------------------------------------------------------------- /examples/AMOVING: -------------------------------------------------------------------------------- 1 | 3,0,6,0,4,0,2,0,0,0 2 | 1,0,8,0,2,0,4,0,0,0 3 | 2,0,1,0,4,0,7,0,0,0 4 | 1,0,3,0,5,0,2,0,0,0 5 | 2,0,6,0,4,0,1,0,0,0 6 | 2,0,7,0,8,0,5,0,0,0 7 | 0,0,0,0,0,0,6,0,0,0 8 | 6,0,3,0,9,0,4,0,0,0 9 | 8,0,3,0,10,0,4,0,0,0 10 | 9,0,0,0,11,0,0,0,0,11 11 | 0,0,10,0,0,0,12,0,10,0 12 | 0,0,11,0,0,0,13,0,0,0 13 | 0,0,12,0,0,0,14,0,14,0 14 | 0,0,13,0,0,0,15,0,15,13 15 | 0,0,14,0,0,0,16,0,0,0 16 | 0,0,15,0,0,0,0,0,0,17 17 | 22,0,0,0,18,0,19,0,16,22 18 | 17,0,0,0,0,0,0,0,0,0 19 | 0,0,17,0,0,0,20,0,0,0 20 | 0,0,19,0,0,0,21,0,0,0 21 | 20,0,20,0,88,0,29,0,0,0 22 | 25,0,17,0,23,83,24,0,17,0 23 | 22,0,0,0,0,0,0,0,0,0 24 | 0,0,22,0,0,0,31,0,31,0 25 | 26,0,0,0,22,0,0,0,0,33 26 | 0,0,28,0,25,0,27,0,0,0 27 | 0,0,26,0,0,0,0,0,0,0 28 | 0,0,0,0,0,26,0,0,0,0 29 | 31,0,21,0,0,0,30,0,21,31 30 | 31,0,29,0,94,0,0,0,0,0 31 | 32,0,24,0,30,0,29,0,0,0 32 | 31,0,0,0,0,0,0,0,0,0 33 | 0,0,34,0,0,0,36,0,25,0 34 | 0,0,0,0,0,0,33,0,0,35 35 | 0,0,0,0,0,0,0,0,34,0 36 | 0,0,33,0,0,0,0,0,25,37 37 | 40,0,38,0,0,0,44,0,36,0 38 | 0,0,39,0,0,0,37,0,37,0 39 | 255,255,255,255,255,255,255,255,255,255 40 | 0,0,0,0,37,0,0,0,41,42 41 | 0,0,0,0,0,0,0,0,0,43 42 | 0,0,0,0,0,0,0,0,40,43 43 | 0,0,0,0,0,0,0,0,42,0 44 | 255,0,37,0,255,0,45,0,255,255 45 | 0,44,46,0,0,0,47,52,0,0 46 | 0,0,0,0,0,0,45,0,0,0 47 | 0,0,45,0,0,0,48,0,0,49 48 | 0,0,47,0,0,0,51,0,0,50 49 | 0,0,0,0,0,0,0,0,47,0 50 | 0,0,0,0,0,0,0,0,48,0 51 | 44,0,0,0,48,0,0,0,79,0 52 | 56,0,0,45,0,0,53,0,0,0 53 | 55,0,0,52,0,54,0,0,0,0 54 | 0,0,0,0,0,0,0,0,60,53 55 | 0,0,0,0,53,0,0,0,0,0 56 | 0,0,0,0,52,0,57,0,0,0 57 | 0,0,58,0,0,0,0,56,0,0 58 | 0,59,0,0,0,0,57,0,0,0 59 | 0,0,0,0,58,0,0,0,0,0 60 | 0,61,0,0,0,54,0,0,0,54 61 | 0,62,0,0,0,60,0,0,0,0 62 | 0,0,63,0,0,0,61,0,0,0 63 | 0,65,0,64,0,0,62,0,0,0 64 | 63,0,0,0,68,0,0,0,0,0 65 | 67,0,66,0,63,0,0,0,0,0 66 | 0,0,0,0,0,0,65,0,0,0 67 | 0,0,0,0,65,0,0,0,0,0 68 | 0,0,69,0,0,0,64,0,0,0 69 | 0,0,0,0,0,0,68,0,0,0 70 | 0,0,50,0,0,0,71,0,0,50 71 | 73,0,70,0,72,0,0,0,0,0 72 | 0,71,0,0,0,0,0,0,0,0 73 | 74,0,0,0,71,0,0,0,0,0 74 | 0,0,0,0,73,0,75,0,0,0 75 | 74,0,0,0,0,0,0,0,0,53 76 | 78,0,0,0,77,0,0,0,0,45 77 | 76,0,0,0,0,0,0,0,0,93 78 | 27,0,0,44,76,0,0,0,0,0 79 | 80,0,0,0,82,0,0,0,0,51 80 | 81,0,0,0,79,0,0,0,0,0 81 | 0,0,0,0,80,0,0,0,0,0 82 | 79,0,83,0,0,0,0,0,0,0 83 | 0,0,22,0,0,0,82,0,0,84 84 | 86,0,0,0,85,0,0,0,0,0 85 | 84,0,0,0,0,0,0,0,0,0 86 | 45,0,84,0,0,0,87,0,0,0 87 | 0,0,0,86,0,0,0,0,0,0 88 | 89,82,91,95,90,83,92,91,95,94 89 | 95,96,91,90,89,88,91,95,93,97 90 | 92,92,91,93,88,97,88,96,99,87 91 | 91,89,94,90,93,95,89,92,0,0 92 | 95,97,93,96,94,95,21,92,0,0 93 | 90,96,92,94,88,30,92,90,0,0 94 | 98,89,90,91,89,93,95,97,0,0 95 | 93,94,96,92,97,95,94,92,0,0 96 | 92,99,97,96,89,94,90,90,91,92 97 | 98,89,92,91,90,93,94,95,96,98 98 | 95,90,93,91,94,92,90,99,98,15 99 | 88,89,93,97,100,89,96,95,0,0 100 | 0,0,0,0,99,0,0,0,0,0 101 | -------------------------------------------------------------------------------- /examples/Pneuma.bas: -------------------------------------------------------------------------------- 1 | 10 REM Pneuma - A space adventure 2 | 20 REM ========== backstory and instructions ========== 3 | 30 PRINT "********************************" : PRINT 4 | 35 PRINT " Pneuma - A space adventure" : PRINT 5 | 40 PRINT "********************************": PRINT 6 | 45 PRINT "To get instructions, type 'help'" 7 | 50 PRINT 8 | 60 PRINT "You wake up in your bunk, in the sleeping quarters of the starship Pneuma. You can't" 9 | 65 PRINT "remember much. You went to bed feeling sick and after a feverish few hours tossing and" 10 | 70 PRINT "turning, feeling like you were burning up, you eventually fell asleep." : PRINT 11 | 75 PRINT "Now, your sheets and night clothes are damp with sweat, and you have a raging thirst." 12 | 80 PRINT "You have a sore throat and the mother of all headaches, like your brain has been boiling" 13 | 85 PRINT "in your skull. In fact, you're no longer sure exactly where you are ... you seem to be" 14 | 90 PRINT "suffering from some sort of amnesia ...": PRINT 15 | 95 REM set up environment 16 | 100 GOSUB 2700 17 | 500 REM setup room descriptions 18 | 510 GOSUB 3000 19 | 520 REM setup up interative descriptions 20 | 530 GOSUB 5000 21 | 540 REM setup dialogue 22 | 550 GOSUB 7000 23 | 700 REM ========== main loop ========== 24 | 701 IF WPL <> 99 THEN GOSUB 8400 : REM wraith-hound movement 25 | 702 REM show room details 26 | 703 PRINT "You are in the " ; LO$ ( PL ) : PRINT 27 | 705 GOSUB 4010 : REM print room description 28 | 706 GOSUB 8000 : REM tracker info if carried 29 | 707 IF WPL <> 99 THEN GOSUB 8200 : REM wraith-hound proximity check 30 | 709 IF WPL = PL THEN GOSUB 11000 : REM fight wraith-hound 31 | 710 INPUT "What now? " ; I$ 32 | 715 PRINT 33 | 716 MOVE = 1 34 | 720 IF LEFT$ ( LOWER$ ( I$ ) , 4 ) = "get " THEN MOVE = 0 : GOSUB 1400 35 | 730 IF LEFT$ ( LOWER$ ( I$ ) , 5 ) = "take " THEN MOVE = 0 : GOSUB 1700 36 | 740 IF LEFT$ ( LOWER$ ( I$ ) , 5 ) = "drop " THEN MOVE = 0 : GOSUB 2000 37 | 750 IF LEFT$ ( LOWER$ ( I$ ) , 8 ) = "examine " THEN MOVE = 0 : GOSUB 2300 38 | 760 IF LEFT$ ( LOWER$ ( I$ ) , 4 ) = "look" THEN MOVE = 0 : GOSUB 4010 39 | 765 IF LEFT$ ( LOWER$ ( I$ ) , 4 ) = "help" THEN MOVE = 0 : GOSUB 4130 40 | 767 IF LEFT$ ( LOWER$ ( I$ ) , 4 ) = "use " THEN MOVE = 0 : GOSUB 9000 41 | 770 IF LOWER$ ( I$ ) = "i" OR LOWER$ ( I$ ) = "inventory" THEN MOVE = 0 : GOSUB 1000 42 | 775 IF LEFT$ ( LOWER$ ( I$ ) , 8 ) = "talk to " THEN MOVE = 0 : GOSUB 2630 43 | 780 IF LEFT$ ( LOWER$ ( I$ ) , 1 ) = "q" THEN GOSUB 2600 44 | 785 IF LEFT$ ( LOWER$ ( I$ ) , 3 ) = "go " THEN GOSUB 1100 45 | 790 IF LOWER$ ( I$ ) = "f" OR LOWER$ ( I$ ) = "forward" THEN GOSUB 1200 46 | 800 IF LOWER$ ( I$ ) = "a" OR LOWER$ ( I$ ) = "aft" THEN GOSUB 1200 47 | 810 IF LOWER$ ( I$ ) = "p" OR LOWER$ ( I$ ) = "port" THEN GOSUB 1200 48 | 820 IF LOWER$ ( I$ ) = "s" OR LOWER$ ( I$ ) = "starboard" THEN GOSUB 1200 49 | 830 IF LOWER$ ( I$ ) = "u" OR LOWER$ ( I$ ) = "up" THEN GOSUB 1200 50 | 840 IF LOWER$ ( I$ ) = "d" OR LOWER$ ( I$ ) = "down" THEN GOSUB 1200 51 | 895 IF MOVE = 1 THEN GOTO 700 ELSE GOTO 710 52 | 900 STOP 53 | 995 REM ========== actions ========== 54 | 1000 REM list the player's inventory 55 | 1005 PRINT "You have the following items:" : PRINT 56 | 1010 FOR I = 0 TO OC - 1 57 | 1020 IF OL ( I ) = 0 THEN PRINT OB$ ( I ) 58 | 1030 NEXT I 59 | 1035 PRINT 60 | 1040 RETURN 61 | 1100 REM fully written out move (e.g. 'go aft') 62 | 1110 D$ = MID$ ( LOWER$(I$) , 4 , 1 ) 63 | 1120 GOSUB 1300 64 | 1130 RETURN 65 | 1200 REM abbreviated move (e.g. 'a' or 'aft') 66 | 1210 D$ = LOWER$( I$ ) 67 | 1220 GOSUB 1300 68 | 1230 RETURN 69 | 1300 REM go to the player's new location (PL) 70 | 1310 IF D$ = "f" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 1 , 2 ) ) 71 | 1320 IF D$ = "a" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 3 , 2 ) ) 72 | 1330 IF D$ = "p" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 5 , 2 ) ) 73 | 1340 IF D$ = "s" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 7 , 2 ) ) 74 | 1345 IF D$ = "u" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 9 , 2 ) ) 75 | 1350 IF D$ = "d" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 11 , 2 ) ) 76 | 1355 IF NPL = 0 THEN PRINT "You can't go that way." : PRINT ELSE PL = NPL 77 | 1360 RETURN 78 | 1400 REM get command 79 | 1405 F=-1: R$="" 80 | 1410 R$ = MID$(LOWER$(I$), 5) : REM R$ is the requested object 81 | 1420 REM get the object ID 82 | 1430 FOR I= 0 TO OC-1 83 | 1440 IF OB$(I) = R$ THEN F=I : REM object exists 84 | 1450 NEXT I 85 | 1460 REM can't find the item? 86 | 1470 IF F=-1 THEN PRINT "You can't take that." : PRINT : RETURN 87 | 1480 IF OL(F) <> PL THEN PRINT "That item doesn't appear to be around here." : PRINT : RETURN 88 | 1490 IF OL(F)=0 THEN PRINT "You already have that item." : PRINT: RETURN 89 | 1520 OL(F)=0 : REM add the item to the inventory 90 | 1530 PRINT "You've picked up ";OB$(F); "." : PRINT 91 | 1540 RETURN 92 | 1700 REM take command 93 | 1710 F=-1: R$="" 94 | 1720 R$ = MID$(LOWER$(I$), 6) : REM R$ is the requested object 95 | 1730 GOTO 1420 : REM use the same logic as the get command 96 | 2000 REM drop command 97 | 2010 F=-1: R$="" 98 | 2020 R$ = MID$(LOWER$(I$), 6) : REM R$ is the requested object 99 | 2030 FOR I= 0 TO OC-1 100 | 2040 IF OB$(I) = R$ THEN F=I : REM object exists 101 | 2050 NEXT I 102 | 2060 REM can't find it? 103 | 2070 IF F=-1 THEN PRINT "You don't have that." : PRINT: RETURN 104 | 2080 IF OL(F) <> 0 THEN PRINT "You aren't carrying that." : PRINT: RETURN 105 | 2090 OL(F) = PL : PRINT "You've dropped ";OB$(F); ".": PRINT: REM add the item to the current room 106 | 2095 IF F = SUIT THEN SUIT_WORN = 0 107 | 2110 RETURN 108 | 2300 REM examine command 109 | 2310 F=-1 : R$="" 110 | 2320 R$ = MID$(LOWER$(I$), 9) : REM R$ is the object to examine 111 | 2330 FOR I = 0 TO IC-1 112 | 2340 IF IO$(I) = R$ THEN F=I : REM object exists 113 | 2350 NEXT I 114 | 2360 REM can't find it? 115 | 2370 IF F=-1 THEN PRINT "You can't examine that." : PRINT : RETURN 116 | 2380 IF IL(F) <> PL THEN PRINT "There isn't one of these here." : PRINT : RETURN 117 | 2390 GOSUB 6000 : REM print result of examination 118 | 2400 RETURN 119 | 2600 REM quit command 120 | 2610 PRINT "Farewell spacefarer ..." 121 | 2620 STOP 122 | 2630 REM talk to command 123 | 2635 F=-1 : R$ = "" 124 | 2640 R$ = MID$(LOWER$(I$), 9) : REM R$ is the person to talk to 125 | 2645 FOR I = 0 TO PC-1 126 | 2650 IF P$(I) = R$ THEN F=I : REM person exists 127 | 2655 NEXT I 128 | 2660 REM can't find them? 129 | 2665 IF F=-1 THEN PRINT "You've not met them." : PRINT : RETURN 130 | 2670 IF PLOC(F) <> PL THEN PRINT "They aren't here." : PRINT : RETURN 131 | 2675 GOSUB 7500 : REM print dialogue 132 | 2695 RETURN 133 | 2700 REM ========== set up environment =========== 134 | 2705 RC = 18 : REM room count 135 | 2710 DIM LO$ ( RC ) 136 | 2715 INV = 0 : LO$ ( INV ) = "Inventory" 137 | 2720 GAL = 1 : LO$ ( GAL ) = "Galley" 138 | 2725 REC = 2 : LO$ ( REC ) = "Recreation/Dining Room" 139 | 2730 ARM = 3 : LO$ ( ARM ) = "Armoury" 140 | 2735 BDG = 4 : LO$ ( BDG ) = "Bridge" 141 | 2740 SLP = 5 : LO$ ( SLP ) = "Sleeping Quarters" 142 | 2745 MED = 6 : LO$ ( MED ) = "Medical Centre" 143 | 2750 GYM = 7 : LO$ ( GYM ) = "Gymnasium" 144 | 2755 LAC = 8 : LO$ ( LAC ) = "Lower Aft Corridor" 145 | 2760 ENG = 9 : LO$ ( ENG ) = "Engine Room" 146 | 2765 STO = 10 : LO$ ( STO ) = "Storeroom" 147 | 2770 MEN = 11 : LO$ ( MEN ) = "Menagerie" 148 | 2775 LAB = 12 : LO$ ( LAB ) = "Laboratory" 149 | 2780 LFC = 13 : LO$ ( LFC ) = "Lower Forward Corridor" 150 | 2785 POD = 14 : LO$ ( POD ) = "Pod Bay" 151 | 2790 AMC = 15 : LO$ ( AMC ) = "Aft Main Corridor" 152 | 2795 MMC = 16 : LO$ ( MMC ) = "Mid Main Corridor" 153 | 2800 FMC = 17 : LO$ ( FMC ) = "Forward Main Corridor" 154 | 2805 REM encoded room exits, two digits per direction f, a, p, s, u, d 155 | 2810 DIM EX$ ( RC ) 156 | 2815 EX$ ( GAL ) = "020000150008" 157 | 2820 EX$ ( REC ) = "000100160000" 158 | 2825 EX$ ( ARM ) = "000000170000" 159 | 2830 EX$ ( BDG ) = "001700000000" 160 | 2835 EX$ ( SLP ) = "000015000000" 161 | 2840 EX$ ( MED ) = "070016000000" 162 | 2845 EX$ ( GYM ) = "000617000013" 163 | 2850 EX$ ( LAC ) = "100000090100" 164 | 2855 EX$ ( ENG ) = "000008000000" 165 | 2860 EX$ ( STO ) = "120800110000" 166 | 2865 EX$ ( MEN ) = "000010000000" 167 | 2870 EX$ ( LAB ) = "001000130000" 168 | 2875 EX$ ( LFC ) = "140012000700" 169 | 2880 EX$ ( POD ) = "001300000000" 170 | 2890 EX$ ( AMC ) = "160001050000" 171 | 2895 EX$ ( MMC ) = "171502060000" 172 | 2900 EX$ ( FMC ) = "041603070000" 173 | 2905 OC = 5 : REM object count 174 | 2910 DIM OB$ ( OC ) 175 | 2915 PULSE = 0 : OB$ ( PULSE ) = "pulse rifle" 176 | 2920 SUIT = 1 : OB$ ( SUIT ) = "space suit" 177 | 2922 KNIFE = 2 : OB$ ( KNIFE ) = "knife" 178 | 2924 TRACKER = 3 : OB$ ( TRACKER ) = "tracker" 179 | 2926 SYRINGE = 4 : OB$ ( SYRINGE ) = "syringe" 180 | 2930 REM object locations 181 | 2932 REM location 0 = player's inventory 182 | 2934 DIM OL ( OC ) 183 | 2936 OL ( PULSE ) = ARM 184 | 2937 OL ( SUIT ) = POD 185 | 2939 OL ( KNIFE ) = GAL 186 | 2940 OL ( TRACKER ) = GYM 187 | 2941 OL ( SYRINGE ) = MED 188 | 2942 IC = 5 : REM interactive object count 189 | 2944 DIM IO$ (IC) 190 | 2946 MEDLOG = 0 : IO$ ( MEDLOG ) = "medical log" 191 | 2948 PORTHOLE = 1 : IO$ (PORTHOLE) = "porthole" 192 | 2950 CONSOLE = 2 : IO$(CONSOLE) = "console" 193 | 2952 ENGINE = 3 : IO$(ENGINE)= "engine control" 194 | 2954 TERMINAL = 4 : IO$(TERMINAL) = "library terminal" 195 | 2960 REM interative object locations 196 | 2962 DIM IL ( IC ) 197 | 2964 IL ( MEDLOG) = MED 198 | 2966 IL (PORTHOLE) = POD 199 | 2968 IL (CONSOLE) = BDG 200 | 2970 IL (ENGINE) = ENG 201 | 2971 IL (TERMINAL) = REC 202 | 2972 PC = 3 : REM person count 203 | 2974 DIM P$ ( PC ) 204 | 2976 CHEF = 0 : P$ ( CHEF ) = "chef" 205 | 2978 RUNNER = 1 : P$ ( RUNNER ) = "runner" 206 | 2980 PILOT = 2 : P$ ( PILOT ) = "pilot" 207 | 2981 REM person locations 208 | 2983 DIM PLOC ( PC ) 209 | 2985 PLOC ( CHEF ) = GAL 210 | 2987 PLOC ( RUNNER ) = GYM 211 | 2989 PLOC ( PILOT ) = BDG 212 | 2990 PL = SLP : REM initial player location 213 | 2992 WPL = MEN : REM wraith-hound initial location 214 | 2994 SUIT_WORN = 0 : REM is space suit worn? 215 | 2995 SHUTDOWN = 0 : REM are engines shut down? 216 | 2999 RETURN 217 | 3000 REM ========== room descriptions ========== 218 | 3010 DIM RD$ ( RC, 5 ) 219 | 3015 REM inventory 220 | 3020 DATA "", "", "", "", "" 221 | 3025 REM galley 222 | 3030 DATA "The galley contains gleaming, stainless steel cupboards along the aft wall. A food" 223 | 3040 DATA "preparation surface is on the port wall, currently covered in rotting food. A chef" 224 | 3050 DATA "stands at the work surface, methodically chopping food even though everything has" 225 | 3060 DATA "already been thoroughly diced. There are doors in the starboard and forward walls and" 226 | 3070 DATA "a stairway leads downwards in the far corner." 227 | 3075 REM recreation room 228 | 3080 DATA "Space is clearly at a premium in this ship. The room doubles as both a dining and" 229 | 3090 DATA "recreation area. Long tables for dining are located on the port side, while couches" 230 | 3100 DATA "and low tables are scattered around the remaining space. A library terminal is switched" 231 | 3105 DATA "on in the corner. There are doors in the aft and starboard walls.", "" 232 | 3120 REM armoury 233 | 3130 DATA "Locked cabinets line the starboard wall. Each cabinet has a prominently displayed" 234 | 3140 DATA "notice on its door reading 'Weapons to be removed only when authorised by the Chief" 235 | 3150 DATA "Security Officer'. However, the door to one cupboard has been prized open, it is" 236 | 3160 DATA "warped and bent. This cupboard appears to be empty. The only exit is a starboard door.", "" 237 | 3170 REM bridge 238 | 3180 DATA "The bridge is the heart of the ship. A vast array of glowing screens and switches fill" 239 | 3190 DATA "every surface. On the screens are complex graphics providing detailed information about" 240 | 3200 DATA "the status of every system on the ship. Many of them are showing red warning symbols." 241 | 3210 DATA "There is a console directly in front of you, a pilot gripping the throttle." 242 | 3220 DATA "An aft exit leads back into the main corridor." 243 | 3225 REM sleeping quarters 244 | 3230 DATA "The sleeping quarters is filled with bunks, one up, one down. Several of the bunks" 245 | 3240 DATA "contain sleeping forms, some gently shoring. The room has a partition to separate" 246 | 3250 DATA "male and female bunks. Against the forward wall are two corresponding sets of heads." 247 | 3260 DATA "The room is messy, with discarded personal items everywhere ... on bunks, on the floor." 248 | 3270 DATA "There is a door in the port wall." 249 | 3275 REM medical centre 250 | 3280 DATA "The medical centre looks relatively normal, but there is evidence of discarded items" 251 | 3290 DATA "lying around the room. Blood filled syringes are scattered on a workbench, as well as" 252 | 3300 DATA "some bloodied bandanges. The words 'I'm losing myself' are scrawled messily in blood on" 253 | 3310 DATA "one wall. In the corner you can see a terminal. On the terminal screen is a portion" 254 | 3320 DATA "of the medical log. Exits lead port and forward." 255 | 3325 REM gymnasium 256 | 3330 DATA "The gymnasium is full of exercise equipment. A female runner is sprinting furiously on a" 257 | 3340 DATA "treadmill. She looks exhausted and emaciated, but she keeps running at top speed, almost at" 258 | 3350 DATA "a sprint. Her eyes remain fixed on the treadmill console. There are aft and port exits," 259 | 3360 DATA "as well as a stairwell leading to the lower deck in the far corner.", "" 260 | 3370 REM lower aft corridor 261 | 3380 DATA "This is a featureless, utilitarian corridor. A stairwell leads upwards. There are also" 262 | 3390 DATA "exits leading starboard and forward.", "", "", "" 263 | 3400 REM engine room 264 | 3430 DATA "The engine room is characterised by a continual rumble, as though incredible energies are" 265 | 3440 DATA "barely being contained. There is an engine control in the far corner, festooned with" 266 | 3450 DATA "switches and engine readouts. A single exit leads out into the corridor.", "", "" 267 | 3460 REM storeroom 268 | 3480 DATA "The storeroom is full of crates, most neatly stacked, but with some scattered across the" 269 | 3490 DATA "floor, their contents spilling out. Along the port wall is a door marked 'Test specimens'." 270 | 3500 DATA "From behind the door, strange animal noises are audible ... snuffling sounds and the" 271 | 3510 DATA "occasional primate shriek. A dead man wearing a scuffed and torn lab coat is lying face down" 272 | 3520 DATA "in front of the specimen door. Two other exits lead forward and aft." 273 | 3525 REM menagerie 274 | 3530 DATA "The room is a hellhole. Cages stand open, while various animals roam about: chimpanzees," 275 | 3540 DATA "dogs, and rats. Some of the rats are dead, having been savaged and eviscerated. The floor" 276 | 3550 DATA "and walls are smeared with animal faeces, and the smell is almost overpowering. A capsule," 277 | 3552 DATA "its door ajar, is marked 'BIOWEAPON CONTAINMENT'. The capsule is empty." 278 | 3555 DATA "A single door to port leads back into the storeroom." 279 | 3560 REM laboratory 280 | 3570 DATA "The laboratory is full of scientific equipment, chemical glassware, electronic analysers," 281 | 3580 DATA "fume cupboards, and two couches. The place looks disorded, like the rest of the ship, the" 282 | 3590 DATA "result of frenetic activity. A number of experiments seem to be in progress, with logbooks" 283 | 3600 DATA "and tablets covered in dense calculations and notes. Whatever has been happening in here," 284 | 3610 DATA "it has been done with extreme urgency. Exits lead aft and to starboard." 285 | 3615 REM lower forward corridor 286 | 3620 DATA "This is a featureless, utilitarian corridor. A stairwell leads upwards. There are also" 287 | 3630 DATA "doors leading to port and forward.", "", "", "" 288 | 3660 REM pod bay 289 | 3670 DATA "You are in a large room, with a row of spacesuits hanging on the port wall. At the forward" 290 | 3680 DATA "end of the room is a small, two seater vehicle, capable of operating in space outside the" 291 | 3690 DATA "main ship for limited periods. In front of the small ship is the pod bay door, leading out" 292 | 3700 DATA "into space. There is a porthole on the far wall. There is a single exit leading aft.", "" 293 | 3710 REM aft main corridor 294 | 3720 DATA "The main corridor stretches away from you towards the front of the ship. It is featureless" 295 | 3730 DATA "and utilitarian. The lighting is dim. You can see doors either side of you, to port and" 296 | 3740 DATA "to starboard.", "", "" 297 | 3760 REM mid main corridor 298 | 3770 DATA "The main corridor stretches away from you both forward and aft. It is featureless" 299 | 3780 DATA "and utilitarian. The lighting is dim. You can see doors either side of you, to port and" 300 | 3790 DATA "to starboard.", "", "" 301 | 3810 REM forward main corridor 302 | 3820 DATA "The main corridor stretches away from you towards the rear of the ship. It is featureless" 303 | 3830 DATA "and utilitarian. The lighting is dim. You can see doors either side of you, to port and" 304 | 3840 DATA "to starboard, as well as a third door leading forward.", "", "" 305 | 3860 REM assign to room descriptions 306 | 3870 FOR ROOM = 0 to RC-1 307 | 3880 FOR I = 0 TO 4 308 | 3885 READ DESC$ : RD$ (ROOM, I) = DESC$ 309 | 3890 NEXT I 310 | 3900 NEXT ROOM 311 | 4000 RETURN 312 | 4010 REM ========== print room description ========== 313 | 4020 FOR LINE = 0 TO 4 314 | 4030 IF RD$(PL, LINE) <> "" THEN PRINT RD$(PL, LINE) 315 | 4040 NEXT LINE 316 | 4055 GOSUB 4070 317 | 4060 RETURN 318 | 4070 REM print objects 319 | 4080 FOR I = 0 TO OC-1 320 | 4090 IF OL ( I ) = PL THEN PRINT : PRINT "You can see: ";OB$ ( I ); "." 321 | 4100 NEXT I 322 | 4110 PRINT 323 | 4115 IF PL = LAB THEN GOSUB 9700 324 | 4120 RETURN 325 | 4130 REM ========== print help ========== 326 | 4140 PRINT "For movement, try [go] a[ft], f[orward], p[ort], s[tarboard], u[p] or d[own]." 327 | 4150 PRINT "For actions, try get, take, drop, examine, look, use, i[nventory], q[uit]." 328 | 4155 PRINT "To examine, pick up, use or drop items, refer to them exactly as they are described." 329 | 4157 PRINT 330 | 4160 RETURN 331 | 5000 REM ========== interactive item descriptions ========== 332 | 5010 DIM ID$(IC, 20) 333 | 5020 REM medical log 334 | 5030 DATA "The last few entries of the medical log are still visible on the screen:", " " 335 | 5040 DATA "'2142-6-13: Three days since chimpanzee Nova was innoculated with agent #53." 336 | 5050 DATA " However, subject Nova showing no signs of adaptation to planetary destination" 337 | 5060 DATA " atmosphere. In fact, she appears listless, though punctuated with periods of" 338 | 5070 DATA " extreme agression.", " " 339 | 5090 DATA " 2142-6-14: This morning, Dr Pearson was bitten by Nova. Very quickly he exhibited" 340 | 5100 DATA " signs of a high fever and is now resting in his quarters.", " " 341 | 5120 DATA " 2142-6-15: After a brief period of catatonia, Pearson got up on his own, returned" 342 | 5130 DATA " to the medical bay and began to compulsively prepare more agent #53 samples. He" 343 | 5140 DATA " is otherwise uncommunicative.", " " 344 | 5160 DATA " 2142-6-17: Pearson's compulsive behaviour continues unabated. We have a hypothesis" 345 | 5170 DATA " for what the virus, which we have now designated HO-1, does to the brain. However," 346 | 5180 DATA " we are struggling to isolate Pearson and may have to seal the medical bay.", " " 347 | 5200 DATA " 2142-6-17: Hollow (HO-1) confirmed as airborne, and other cases appearing around the ship." 348 | 5210 DATA " Shipwide lockdown declared but crew cohesion and discipline already breaking down.'" 349 | 5215 REM porthole 350 | 5220 DATA "Looking through the porthole, you seen a spacesuit clad figure floating outside." 351 | 5230 DATA "Although he is tethered to an anchor point on the ship's hull, he is otherwise floating" 352 | 5240 DATA "freely, his arms and legs splayed out to his sides.", " " 353 | 5260 DATA "Peering at the figure more closely, as he slowly rotates, a light from the ship" 354 | 5270 DATA "briefly illuminates his face. He's clearly dead, his oxygen ran out some time ago." 355 | 5280 DATA "His expression is frozen in a rictus of pain. He was screaming almost until the end ..." 356 | 5290 DATA "", "", "", "", "", "", "", "", "", "", "", "", "" 357 | 5300 REM console 358 | 5310 DATA "The console shows the state of the ship's engines. The pilot" 359 | 5320 DATA "appears to have the throttle jammed wide open with his right arm. The muscles in his" 360 | 5340 DATA "forearm are taught, there's no way he's going to release the throttle. He left hand" 361 | 5350 DATA "works its way around the console switches. After a few moments you realise that he is" 362 | 5360 DATA "executing the same sequence of switches over and over again.", " " 363 | 5370 DATA "His eyes are glazed, mentally he is somewhere else. He is" 364 | 5380 DATA "mumbling to himself but you cannot make out the words, although he appears to be" 365 | 5390 DATA "reciting some sort of launch checklist.", " " 366 | 5392 DATA "One screen shows the mission parameters:" 367 | 5394 DATA " 1. Explore potentially habitable worlds" 368 | 5396 DATA " 2. Conduct research to develop gene therapies to aid adaptation to planetary conditions" 369 | 5398 DATA " 3. Conduct research to develop custom biologic weapons systems, to protect colonists", " " 370 | 5400 DATA "If the engines are online, the ship will be careering through space at maximum" 371 | 5410 DATA "speed. Rescue will be impossible unless the engines are offline." 372 | 5420 DATA "", "", "" 373 | 5430 REM engine control 374 | 5440 DATA "The control panel is grubby, smeared with oil and grime. This is clearly" 375 | 5450 DATA "the engineering heart of the ship. Most of the readouts mean nothing to you," 376 | 5460 DATA "whatever your duties were on this ship, you were clearly not a warp engineer.", " " 377 | 5470 DATA "Many of the lights on the front panel are flashing red. Not all is well with" 378 | 5480 DATA "the Pneuma. Even to your untrained eye, it's obvious that the ship's engines appear to" 379 | 5490 DATA "be on the point of burnout, having been run at full capacity for many hours.", " " 380 | 5500 DATA "To the top left of the panel, a screen reads:", " " 381 | 5510 DATA "'WARNING: CORE BREACH IMMINENT'", " " 382 | 5520 DATA "Just below the screen is a large red button, shielded by a cover that can be" 383 | 5530 DATA "flipped aside.", "", "", "", "", "", "" 384 | 5540 REM library terminal 385 | 5550 DATA "A ancient text is open in the terminal: 'The Origin of Consciousness in the Breakdown" 386 | 5560 DATA "of the Bicameral Mind by Julian Jaynes, 1976.'", "", "", "", "", "", "", "", "", "" 387 | 5570 DATA "", "", "", "", "", "", "", "", "" 388 | 5940 FOR OBJECT = 0 TO IC-1 389 | 5950 FOR I = 0 TO 19 390 | 5960 READ DESC$ : ID$ (OBJECT, I) = DESC$ 391 | 5970 NEXT I 392 | 5980 NEXT OBJECT 393 | 5990 RETURN 394 | 6000 REM ========== print interative object description ========== 395 | 6010 FOR LINE = 0 TO 19 396 | 6020 IF ID$(F, LINE) <> "" THEN PRINT ID$(F, LINE) 397 | 6030 NEXT LINE 398 | 6035 PRINT 399 | 6040 RETURN 400 | 7000 REM ========== character speech ========== 401 | 7010 REM chef 402 | 7015 DIM PD$(PC, 4) 403 | 7020 DATA "Carrots, potatoes, I'm going to make a nice beef stew." 404 | 7030 DATA "This stew is going to be delicious." 405 | 7060 REM runner 406 | 7070 DATA "24:50, that's my new personal best. Not much further to go!" 407 | 7080 DATA "24:50, that's my new personal best. Not much further to go!" 408 | 7110 REM pilot 409 | 7120 DATA "Main engines online, supercruise on my mark." 410 | 7130 DATA "Five ... four ... three ... two ... one ... mark!" 411 | 7140 FOR PERSON = 0 TO PC-1 412 | 7150 FOR I = 0 TO 1 413 | 7160 READ DESC$ : PD$ (PERSON, I) = DESC$ 414 | 7170 NEXT I 415 | 7180 PD$(PERSON, 2) = PD$(PERSON, 0) 416 | 7190 PD$(PERSON, 3) = PD$(PERSON, 1) 417 | 7200 NEXT PERSON 418 | 7210 RETURN 419 | 7500 REM ========== print character speech ========== 420 | 7510 FOR LINE = 0 TO 4 421 | 7520 PRINT PD$(F, LINE) 422 | 7530 NEXT LINE 423 | 7535 PRINT 424 | 7550 RETURN 425 | 8000 REM ========== wraith-hound tracking ========== 426 | 8010 IF OL ( TRACKER ) <> INV THEN RETURN 427 | 8015 IF WPL = 99 THEN PRINT "Tracking: Wraith-hound terminated." : GOTO 8030 428 | 8020 PRINT "Tracking: Wraith-hound current location is the "; LO$ ( WPL ) 429 | 8030 PRINT 430 | 8040 RETURN 431 | 8200 REM ========== wraith-hound proximity check ========== 432 | 8210 DIR$ = "" 433 | 8220 IF VAL ( MID$ ( EX$ ( PL ) , 1 , 2 ) ) = WPL THEN DIR$ = "forward of you" 434 | 8230 IF VAL ( MID$ ( EX$ ( PL ) , 3 , 2 ) ) = WPL THEN DIR$ = "aft of you" 435 | 8240 IF VAL ( MID$ ( EX$ ( PL ) , 5 , 2 ) ) = WPL THEN DIR$ = "to port" 436 | 8250 IF VAL ( MID$ ( EX$ ( PL ) , 7 , 2 ) ) = WPL THEN DIR$ = "to starboard" 437 | 8260 IF VAL ( MID$ ( EX$ ( PL ) , 9 , 2 ) ) = WPL THEN DIR$ = "above you" 438 | 8270 IF VAL ( MID$ ( EX$ ( PL ) , 11 , 2 ) ) = WPL THEN DIR$ = "below you" 439 | 8280 IF DIR$ <> "" THEN PRINT "You hear a snarling, spitting noise "; DIR$; ". The tracker is pinging ..." 440 | 8285 PRINT 441 | 8290 RETURN 442 | 8400 REM ========== wraith-hound movement ========== 443 | 8410 REM decide to move one third of the time 444 | 8420 MOVE = RNDINT(1, 3) 445 | 8430 IF MOVE <> 1 THEN RETURN 446 | 8440 REM randomly determine direction 447 | 8450 DIR = RNDINT(1, 6) 448 | 8460 IF DIR = 1 THEN INDEX = 1 449 | 8470 IF DIR = 2 THEN INDEX = 3 450 | 8480 IF DIR = 3 THEN INDEX = 5 451 | 8490 IF DIR = 4 THEN INDEX = 7 452 | 8500 IF DIR = 5 THEN INDEX = 9 453 | 8510 IF DIR = 6 THEN INDEX = 11 454 | 8520 NWPL = VAL ( MID$ ( EX$ ( WPL ) , INDEX , 2 ) ) : REM potential next location 455 | 8530 IF NWPL = 0 THEN GOTO 8450 : REM can't go that way 456 | 8540 WPL = NWPL 457 | 8550 RETURN 458 | 9000 REM ========== use an item ========== 459 | 9010 F=-1: R$="" 460 | 9020 R$ = MID$(LOWER$(I$), 5) : REM R$ is the requested object 461 | 9025 IF R$ <> "red button" THEN GOTO 9030 462 | 9027 GOSUB 9500 463 | 9028 RETURN 464 | 9030 REM get the object ID 465 | 9040 FOR I= 0 TO OC-1 466 | 9050 IF OB$(I) = R$ THEN F=I : REM object exists 467 | 9060 NEXT I 468 | 9070 REM can't find the item? 469 | 9080 IF F=-1 THEN PRINT "You haven't seen that item." : PRINT : RETURN 470 | 9090 IF OL(F) <> 0 THEN PRINT "You haven't picked up that item." : PRINT : RETURN 471 | 9100 REM item exists and is in inventory 472 | 9110 IF F <> SYRINGE THEN GOTO 9140 473 | 9112 IF OB$( SYRINGE ) = "blood filled syringe" THEN PRINT "The syringe is full." : PRINT : RETURN 474 | 9115 IF SUIT_WORN = 1 THEN PRINT "You can't puncture a spacesuit with a syringe!" : PRINT : RETURN 475 | 9120 OB$( SYRINGE ) = "blood filled syringe" 476 | 9130 PRINT "You use the syringe to take a blood sample from your arm." : PRINT : RETURN 477 | 9140 IF F <> TRACKER THEN GOTO 9160 478 | 9150 PRINT "The tracker is always on." : PRINT 479 | 9160 IF F <> SUIT THEN GOTO 9200 480 | 9170 IF OL(F) <> 0 THEN PRINT "You don't have a space suit." : PRINT : RETURN 481 | 9175 IF SUIT_WORN = 1 THEN PRINT "You're already wearing the space suit." : PRINT : RETURN 482 | 9180 SUIT_WORN = 1 483 | 9190 PRINT "You put on the space suit." : PRINT 484 | 9400 RETURN 485 | 9500 REM special button routine 486 | 9510 IF PL <> ENG THEN PRINT "There is no red button here." : PRINT : RETURN 487 | 9520 IF SHUTDOWN = 0 THEN GOTO 9540 488 | 9525 SHUTDOWN = 0 489 | 9530 PRINT "Engine restart initiated ... engines online." : PRINT 490 | 9535 ID$ (ENGINE, 10) = "'WARNING: CORE BREACH IMMINENT'" : RETURN 491 | 9540 SHUTDOWN = 1 492 | 9550 PRINT "Engine shutdown initiated ... engines offline." : PRINT 493 | 9555 ID$ (ENGINE, 10) = "'ENGINES OFFLINE'" 494 | 9560 RETURN 495 | 9700 REM ========== laboratory conversation ========== 496 | 9710 PRINT "Dr Lascoe is stood in the laboratory. He is armed. He speaks to you." : PRINT 497 | 9720 PRINT "'It's you! You were infected with HO-1, but you seem to be normal." 498 | 9730 PRINT " Hollow destroys consciousness, it shuts down all self awareness in the brain." 499 | 9740 PRINT " The patient still functions to a degree, but they're an automaton, endlessly" 500 | 9750 PRINT " running the same mental subroutines like a piece of clockwork until the body" 501 | 9760 PRINT " breaks down.'" : PRINT 502 | 9770 PRINT "'I've been hiding in here to avoid contagion. Someone released the wraith-hound" 503 | 9780 PRINT " from containment, but I've been able to keep it away with this weapon." 504 | 9790 PRINT " But if you're immune, I can develop a vaccine from your blood.'" : PRINT 505 | 9800 IF OL(SYRINGE) = 0 AND OB$(SYRINGE) = "blood filled syringe" THEN GOTO 9820 506 | 9810 PRINT "'You need to get me a sample of your blood.'" : PRINT : RETURN 507 | 9820 PRINT "'Ah, I see you have a blood sample, excellent.'" : PRINT 508 | 9830 IF SUIT_WORN = 1 THEN GOTO 9855 509 | 9840 PRINT " I still don't want to take the risk that you are contagious. Put on a space" 510 | 9850 PRINT " suit and then I'll let you approach me.'" : PRINT: RETURN 511 | 9855 PRINT "'Good, you're wearing a suit to avoid contaminating me.'" : PRINT 512 | 9860 IF SHUTDOWN = 1 THEN GOTO 9885 513 | 9870 PRINT "'Rescue will be impossible while the engines are running out of control." 514 | 9880 PRINT " You'll need to take them offline.'": PRINT : RETURN 515 | 9885 PRINT "'Good job on taking the engines offline, you've saved us both!" 516 | 9890 PRINT " I'll work up the serum and we can wait for rescue.'" : PRINT 517 | 9900 GOSUB 10000 518 | 9910 RETURN 519 | 10000 REM ========== finale ========== 520 | 10010 PRINT "Congratulations, you have save Pneuma and helped Dr Lascoe develop" 521 | 10020 PRINT "vaccine against HO-1, the Hollow virus." 522 | 10030 PRINT : PRINT " THE END" : PRINT 523 | 10040 STOP 524 | 11000 REM ========== fight ========== 525 | 11010 PRINT "The wraith-hound arrives. It is an abomination! A weapon system that" 526 | 11020 PRINT "nature would never have created unaided. Everything about it is just" 527 | 11030 PRINT "plain wrong on so many levels. One thing is clear, it is designed" 528 | 11035 PRINT "purely for hunting and killing." : PRINT 529 | 11040 INPUT "Do you r[un] or f[ight]?"; I$ 530 | 11050 PRINT 531 | 11060 IF LOWER$ ( I$ ) = "f" OR LOWER$ ( I$ ) = "fight" THEN GOTO 11190 532 | 11065 IF LOWER$ ( I$ ) = "r" OR LOWER$ ( I$ ) = "run" THEN GOTO 11070 533 | 11067 PRINT "Command unrecognised, you must fight!" : PRINT : GOTO 11190 534 | 11070 REM run away to a random adjoining room 535 | 11080 DIR = RNDINT(1, 6) 536 | 11090 IF DIR = 1 THEN INDEX = 1 537 | 11100 IF DIR = 2 THEN INDEX = 3 538 | 11110 IF DIR = 3 THEN INDEX = 5 539 | 11120 IF DIR = 4 THEN INDEX = 7 540 | 11130 IF DIR = 5 THEN INDEX = 9 541 | 11140 IF DIR = 6 THEN INDEX = 11 542 | 11150 NPL = VAL ( MID$ ( EX$ ( PL ) , INDEX , 2 ) ) : REM potential next location 543 | 11160 IF NPL = 0 THEN GOTO 11080 : REM can't go that way 544 | 11170 PL = NPL : PRINT "You are in the " ; LO$ ( PL ) : PRINT 545 | 11175 GOSUB 4010 546 | 11180 RETURN 547 | 11190 REM fight 548 | 11200 FEROCITY = 60 : REM ferocity factor for wraith-hound 549 | 11205 STAMINA = 50 : REM your stamina 550 | 11210 IF OL(PULSE) <> INV AND OL(KNIFE) <> INV THEN PRINT "You have no weapons, and must fight bare handed." : PRINT : GOTO 11280 551 | 11220 IF OL(PULSE) = INV AND OL(KNIFE) <> INV THEN PRINT "Luckily, you have a pulse rifle." : PRINT: FEROCITY=50 : GOTO 11280 552 | 11230 IF OL(PULSE) <> INV AND OL(KNIFE) = INV THEN PRINT "You only have a knife with which to fight." : PRINT : FEROCITY = 55 : GOTO 11280 553 | 11240 INPUT "Which weapon do you choose? 1 - Pulse rifle, 2 - Knife: "; WPN 554 | 11245 PRINT 555 | 11250 IF WPN<1 OR WPN>2 THEN GOTO 11240 556 | 11260 IF WPN=1 THEN FEROCITY = 50 557 | 11270 IF WPN=2 THEN FEROCITY = 55 558 | 11280 REM the battle 559 | 11290 IF RND(1)>0.5 THEN PRINT "The wraith-hound attacks!" ELSE PRINT "You attack!" 560 | 11300 PRINT 561 | 11305 GOSUB 11430 562 | 11310 IF RND(1)>0.5 THEN PRINT "You wound the creature." : PRINT: FEROCITY = FEROCITY-5 : GOTO 11330 563 | 11320 PRINT "The wraith-hound wounds you." : PRINT : STAMINA = STAMINA-5 564 | 11330 GOSUB 11430 565 | 11340 IF FEROCITY > 0 THEN GOTO 11390 566 | 11350 PRINT "You slayed the wraith-hound!" : PRINT 567 | 11360 REM remove creature from the game 568 | 11370 WPL = 99 : REM inaccessible location 569 | 11380 RETURN 570 | 11390 IF STAMINA > 0 THEN GOTO 11420 571 | 11400 PRINT "You were slayed by the wraith-hound! You have failed to save the Pneuma." : PRINT 572 | 11410 STOP 573 | 11420 GOTO 11280 : REM next round of the battle 574 | 11430 REM ========== delay loop ========== 575 | 11440 FOR T = 1 TO 80000 576 | 11450 NEXT T 577 | 11460 RETURN 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | -------------------------------------------------------------------------------- /examples/PyBStartrek.bas: -------------------------------------------------------------------------------- 1 | 520 REM 2 | 530 REM 3 | 540 REM **** **** STAR TREK **** **** 4 | 550 REM **** Simulation of a mission of the starship ENTERPRISE 5 | 560 REM **** as seen on the Star Trek tv show 6 | 570 REM **** Original program in Creative Computing 7 | 580 REM **** Basic Computer Games by Dave Ahl 8 | 590 REM **** Modifications by Bob Fritz and Sharon Fritz 9 | 600 REM **** for the IBM Personal Computer, October-November 1981 10 | 610 REM **** Bob Fritz, 9915 Caninito Cuadro, San Diego, Ca., 92129 11 | 620 REM **** (714) 484-2955 12 | 630 REM **** 13 | 640 PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT 14 | 650 E1$= " ,-----------------, _" 15 | 660 E2$= " `---------- ----',-----/ \----," 16 | 670 E3$= " | | '- --------'" 17 | 680 E4$= " ,--' '------/ /--," 18 | 690 E5$= " '-----------------'" 19 | 691 PRINT 20 | 700 E6$= " THE USS ENTERPRISE --- NCC-1701" 21 | 720 PRINT E1$ 22 | 730 PRINT E2$ 23 | 740 PRINT E3$ 24 | 750 PRINT E4$ 25 | 760 PRINT E5$ 26 | 770 PRINT 27 | 780 PRINT E6$ 28 | 790 PRINT:PRINT: PRINT:PRINT:PRINT:PRINT:PRINT 29 | 811 RANDOMIZE 30 | 960 dim D(8) 31 | 961 dim C(9,2) 32 | 962 dim K(3,3) 33 | 963 dim N(3) 34 | 965 DIM G(8,8) 35 | 966 DIM Z(8,8) 36 | 970 T=INT(RND(1)*20+20)*100:T0=T:T9=25+INT(RND(1)*10):D0=0:E=3000:E0=E 37 | 980 P=10:P0=P:S9=200:S=0:B9=0:K9=0:X$="":X0$=" is " 38 | 990 rem DEF FND(D)=SQR((K(I,1)-S1)^2+(K(I,2)-S2)^2) 39 | 1000 rem DEF FNR(R)=INT(RND(1)(R)*7.98+1.01) 40 | 1010 REM initialize enterprise's position 41 | 1020 Q1=INT(RND(1)*7.98+1.01):Q2=INT(RND(1)*7.98+1.01):S1=INT(RND(1)*7.98+1.01):S2=INT(RND(1)*7.98+1.01) 42 | 1030 FOR I=1 TO 9 43 | 1031 C(I,1)=0:C(I,2)=0 44 | 1032 NEXT I 45 | 1040 C(3,1)=-1:C(2,1)=-1:C(4,1)=-1:C(4,2)=-1:C(5,2)=-1:C(6,2)=-1 46 | 1050 C(1,2)=1:C(2,2)=1:C(6,1)=1:C(7,1)=1:C(8,1)=1:C(8,2)=1:C(9,2)=1 47 | 1060 FOR I=1 TO 8 48 | 1061 D(I)=0 49 | 1062 NEXT I 50 | 1070 A1$="NAVSRSLRSPHATORSHIDAMCOMRES" 51 | 1080 REM set up what exists in galaxy 52 | 1090 REM k3=#klingons b3=#starbases s3=#stars 53 | 1100 FOR I=1 TO 8 54 | 1101 FOR J=1 TO 8 55 | 1102 K3=0:Z(I,J)=0:R1=RND(1) 56 | 1110 IF R1<=0.9799999 THEN goto 1120 57 | 1111 K3=3:K9=K9+3: GOTO 1140 58 | 1120 IF R1<=0.95 THEN goto 1130 59 | 1121 K3=2:K9=K9+2: GOTO 1140 60 | 1130 IF R1<=0.8 THEN goto 1140 61 | 1131 K3=1:K9=K9+1 62 | 1140 B3=0:IF RND(1)<=0.96 THEN goto 1150 63 | 1141 B3=1:B9=B9+1 64 | 1150 G(I,J)=K3*100+B3*10+INT(RND(1)*7.98+1.01) 65 | 1151 NEXT J 66 | 1152 NEXT I 67 | 1153 IF K9<=T9 THEN goto 1160 68 | 1154 T9=K9+1 69 | 1160 IF B9<>0 THEN 1190 70 | 1170 IF G(Q1,Q2)>=200 THEN 1180 71 | 1171 G(Q1,Q2)=G(Q1,Q2)+100:K9=K9+1 72 | 1180 B9=1:G(Q1,Q2)=G(Q1,Q2)+10:Q1=INT(RND(1)*7.98+1.01):Q2=INT(RND(1)*7.98+1.01) 73 | 1190 K7=K9:IF B9=1 THEN 1200 74 | 1191 X$="s":X0$=" are " 75 | 1200 PRINT" Your orders are as follows: " 76 | 1210 PRINT" Destroy the ";K9;" Klingon warships which have invaded" 77 | 1220 PRINT" the galaxy before they can attack Federation headquarters" 78 | 1230 PRINT" on stardate ";T0+T9;". This gives you ";T9;" days. there";X0$ 79 | 1240 PRINT" ";B9;" starbase";X$;" in the galaxy for resupplying your ship" 80 | 1261 PRINT:INPUT"hit return when ready to accept command";i$ 81 | 1270 REM here any time new quadrant entered 82 | 1280 Z4=Q1:Z5=Q2:K3=0:B3=0:S3=0:G5=0:D4=0.5*RND(1):Z(Q1,Q2)=G(Q1,Q2) 83 | 1290 IF Q1<1 OR Q1>8 OR Q2<1 OR Q2>8 THEN 1410 84 | 1300 GOSUB 5040 85 | 1301 PRINT:IF T0 <>T THEN 1330 86 | 1310 PRINT"Your mission begins with your starship located" 87 | 1320 PRINT"in the galactic quadrant, '";G2$;"'.":GOTO 1340 88 | 1330 PRINT"Now entering ";G2$;" quadrant. . ." 89 | 1340 PRINT:K3=INT(G(Q1,Q2)*0.01):B3=INT(G(Q1,Q2)*0.1)-10*K3 90 | 1350 S3=G(Q1,Q2)-100*K3-10*B3:IF K3=0 THEN 1400 91 | 1360 PRINT "COMBAT AREA!! Condition"; 92 | 1370 PRINT " RED "; : PRINT 93 | 1380 GOSUB 5290 94 | 1381 IF S>200 THEN 1400 95 | 1390 PRINT" SHIELDS DANGEROUSLY LOW"; : PRINT 96 | 1400 FOR I=1 TO 3 97 | 1401 K(I,1)=0:K(I,2)=0 98 | 1402 NEXT I 99 | 1410 FOR I=1 TO 3 100 | 1411 K(I,3)=0 101 | 1412 NEXT I 102 | 1413 Q$=" "*192 103 | 1420 REM position enterprise in quadrant, then place "k3" klingons,& 104 | 1430 REM "b3" starbases & "s3" stars elsewhere. 105 | 1440 A$="\e/":Z1=S1:Z2=S2 106 | 1441 GOSUB 4830 107 | 1442 IF K3<1 THEN 1470 108 | 1450 FOR I=1 TO K3 109 | 1451 GOSUB 4800 110 | 1452 A$=chr$(187)+"K"+chr$(171):Z1=R1:Z2=R2 111 | 1460 GOSUB 4830 112 | 1461 K(I,1)=R1:K(I,2)=R2:K(I,3)=S9*(0.5+RND(1)) 113 | 1462 NEXT I 114 | 1470 IF B3<1 THEN 1500 115 | 1480 GOSUB 4800 116 | 1481 A$="("+chr$(174)+")":Z1=R1:B4=R1:Z2=R2:B5=R2 117 | 1490 GOSUB 4830 118 | 1500 FOR I=1 TO S3 119 | 1501 GOSUB 4800 120 | 1502 A$=" * ":Z1=R1:Z2=R2 121 | 1503 GOSUB 4830 122 | 1504 NEXT I 123 | 1510 GOSUB 3720 124 | 1520 IF S+E<=10 THEN 1530 125 | 1521 IF E>10 OR D(7)>=0 THEN 1580 126 | 1530 PRINT"*** FATAL ERROR ***"; 127 | 1531 GOSUB 5290 128 | 1540 PRINT"You've just stranded your ship in " 129 | 1550 PRINT"space":PRINT"You have insufficient maneuvering energy,"; 130 | 1560 PRINT" and shield control":PRINT"is presently incapable of cross"; 131 | 1570 PRINT"-circuiting to engine room!!":GOTO 3480 132 | 1580 INPUT"command ";A$ 133 | 1590 FOR I=1 TO 9 134 | 1591 IF MID$(A$,1,3)<> MID$(A1$,3*I-2,3) THEN 1610 135 | 1600 ON I GOTO 1720,1510,2440,2530,2750,3090,3180,3980,3510 136 | 1610 NEXT I 137 | 1611 PRINT"Enter one of the following:" 138 | 1620 PRINT" NAV (to set course)" 139 | 1630 PRINT" SRS (for short range sensor scan)" 140 | 1640 PRINT" LRS (for long range sensor scan)" 141 | 1650 PRINT" PHA (to fire phasers)" 142 | 1660 PRINT" TOR (to fire photon torpedoes)" 143 | 1670 PRINT" SHI (to raise or lower shields)" 144 | 1680 PRINT" DAM (for damage control reports)" 145 | 1690 PRINT" COM (to call on library-computer)" 146 | 1700 PRINT" RES (to resign your command)":PRINT:GOTO 1520 147 | 1710 REM course control begins here 148 | 1720 INPUT"Course (1-9) ";C2$:C1=VAL(C2$):IF C1<>9 THEN 1730 149 | 1721 C1=1 150 | 1730 IF C1>=1 AND C1<9 THEN 1750 151 | 1740 PRINT" Lt. Sulu reports, 'Incorrect course data, sir!'":GOTO 1520 152 | 1750 X$="8":IF D(1)>=0 THEN 1760 153 | 1751 X$="0.2" 154 | 1760 PRINT"Warp factor(0-";X$;") ";:INPUT C2$:W1=VAL(C2$):IF D(1)<0 AND W1>0.2 THEN 1810 155 | 1770 IF W1>0 AND W1<8 THEN 1820 156 | 1780 IF W1=0 THEN 1520 157 | 1790 PRINT" Chief Engineer Scott reports 'The engines won't take"; 158 | 1800 PRINT" warp ";W1;"!":GOTO 1520 159 | 1810 PRINT"Warp engines are damaged. Maximum speed = warp 0.2":GOTO 1520 160 | 1820 N1=INT(W1*8+0.5):IF E-N1>=0 THEN 1900 161 | 1830 PRINT"Engineering reports 'Insufficient energy available" 162 | 1840 PRINT" for maneuvering at warp ";W1;"!'" 163 | 1850 IF S=0 THEN 1990 181 | 1950 D(I)=min(0,D(I)+D6):IF D(I)<=-0.1 or D(I)>=0 THEN 1960 182 | 1951 D(I)=-0.1 183 | 1952 GOTO 1990 184 | 1960 IF D(I)<0 THEN 1990 185 | 1970 IF D1=1 THEN 1980 186 | 1971 D1=1:PRINT"DAMAGE CONTROL REPORT: "; 187 | 1980 PRINT TAB(8);:R1=I 188 | 1981 GOSUB 4890 189 | 1982 PRINT G2$;" Repair completed." 190 | 1990 NEXT I 191 | 1991 IF RND(1)>0.2 THEN 2070 192 | 2000 R1=INT(RND(1)*7.98+1.01):IF RND(1)>=0.6 THEN 2040 193 | 2010 IF K3=0 THEN 2070 194 | 2020 D(R1)=D(R1)-(RND(1)*5+1):PRINT"DAMAGE CONTROL REPORT: "; 195 | 2030 GOSUB 4890 196 | 2031 PRINT G2$;" damaged":PRINT:GOTO 2070 197 | 2040 D(R1)=min(0,D(R1)+RND(1)*3+1):PRINT"DAMAGE CONTROL REPORT: "; 198 | 2050 GOSUB 4890 199 | 2051 PRINT G2$;" State of repair improved":PRINT 200 | 2060 REM begin moving starship 201 | 2070 A$=" " :Z1=INT(S1):Z2=INT(S2) 202 | 2071 GOSUB 4830 203 | 2079 Z1=INT(C1):C1=C1-Z1 204 | 2080 X1=C(Z1,1)+(C(Z1+1,1)-C(Z1,1))*C1:X=S1:Y=S2 205 | 2090 X2=C(Z1,2)+(C(Z1+1,2)-C(Z1,2))*C1:Q4=Q1:Q5=Q2 206 | 2100 FOR I=1 TO N1 207 | 2101 S1=S1+X1:S2=S2+X2:IF S1<1 OR S1>=9 OR S2<1 OR S2>=9 THEN 2220 208 | 2110 S8=INT(S1)*24+INT(S2)*3-26:IF MID$(Q$,S8+1,2)=" " THEN 2140 209 | 2120 S1=INT(S1-X1):S2=INT(S2-X2):PRINT"Warp engines shut down at "; 210 | 2130 PRINT "sector ";S1;",";S2;" due to bad navigation.":GOTO 2150 211 | 2140 NEXT I 212 | 2141 S1=INT(S1):S2=INT(S2) 213 | 2150 A$="\e/" 214 | 2160 Z1=INT(S1):Z2=INT(S2) 215 | 2161 GOSUB 4830 216 | 2162 GOSUB 2390 217 | 2163 T8=1 218 | 2170 IF W1>=1 THEN 2180 219 | 2171 T8=0.1*INT(10*W1) 220 | 2180 T=T+T8:IF T>T0+T9 THEN 3480 221 | 2190 REM see if docked then get command 222 | 2200 GOTO 1510 223 | 2210 REM exceeded quadrant limits 224 | 2220 X=8*Q1+X+N1*X1:Y=8*Q2+Y+N1*X2:Q1=INT(X/8):Q2=INT(Y/8):S1=INT(X-Q1*8) 225 | 2230 S2=INT(Y-Q2*8):IF S1<>0 THEN 2240 226 | 2231 Q1=Q1-1:S1=8 227 | 2240 IF S2<>0 THEN 2250 228 | 2241 Q2=Q2-1:S2=8 229 | 2250 X5=0:IF Q1>=1 THEN 2260 230 | 2251 X5=1:Q1=1:S1=1 231 | 2260 IF Q1<=8 THEN 2270 232 | 2261 X5=1:Q1=8:S1=8 233 | 2270 IF Q2>=1 THEN 2280 234 | 2271 X5=1:Q2=1:S2=1 235 | 2280 IF Q2<=8 THEN 2290 236 | 2281 X5=1:Q2=8:S2=8 237 | 2290 IF X5=0 THEN 2360 238 | 2300 PRINT"Lt. Uhura reports message from Starfleet Command:" 239 | 2310 PRINT" 'Permission to attempt crossing of galactic perimeter" 240 | 2320 PRINT" is hereby *DENIED*. Shut down your engines.'" 241 | 2330 PRINT"Chief Engineer Scott reports 'Warp engines shut down" 242 | 2340 PRINT" at sector ";S1;",";S2;" of quadrant ";Q1;",";Q2".'" 243 | 2350 IF T>T0 THEN 3480 244 | 2360 IF 8*Q1+Q2=8*Q4+Q5 THEN 2150 245 | 2370 T=T+1 246 | 2371 GOSUB 2390 247 | 2372 GOTO 1280 248 | 2380 REM maneuver energy s/r ** 249 | 2390 E=E-N1-10:IF E<=0 THEN 2400 250 | 2391 RETURN 251 | 2400 PRINT"Shield control supplies energy to complete the maneuver." 252 | 2410 S=S+E:E=0:IF S<=0 THEN 2420 253 | 2411 S=0 254 | 2420 RETURN 255 | 2430 REM long range sensor scan code 256 | 2440 IF D(3)>=0 THEN 2450 257 | 2441 PRINT"Long Range Sensors are inoperable":GOTO 1520 258 | 2450 PRINT"Long Range Scan for quadrant ";Q1;",";Q2 259 | 2460 PRINT "-"*19 260 | 2470 FOR I=Q1-1 TO Q1+1 261 | 2471 N(1)=-1:N(2)=-2:N(3)=-3 262 | 2472 FOR J=Q2-1 TO Q2+1 263 | 2480 IF I<=0 or I>=9 or J<=0 or J>=9 THEN 2490 264 | 2481 N(J-Q2+2)=G(I,J) 265 | 2482 REM added so long range sensor scans are added to computer database 266 | 2483 z(i,j)=g(i,j) 267 | 2490 NEXT J 268 | 2491 FOR L=1 TO 3 269 | 2492 PRINT"| "; 270 | 2493 IF N(L)>=0 THEN 2500 271 | 2494 PRINT"*** ";:GOTO 2510 272 | 2500 PRINT MID$(STR$(N(L)+1000),2,3);" "; 273 | 2510 NEXT L 274 | 2511 PRINT"|" 275 | 2512 PRINT "-"*19 276 | 2513 NEXT I 277 | 2514 GOTO 1520 278 | 2520 REM phaser control code begins here 279 | 2530 IF D(4)>=0 THEN 2540 280 | 2531 PRINT"Phasers Inoperative":GOTO 1520 281 | 2540 IF K3>0 THEN 2570 282 | 2550 PRINT"Science Officer Spock reports 'Sensors show no enemy ships" 283 | 2560 PRINT" in this quadrant'":GOTO 1520 284 | 2570 IF D(8)>=0 THEN 2580 285 | 2571 PRINT"Computer failure hampers accuracy" 286 | 2580 PRINT"Phasers locked on target "; 287 | 2590 PRINT"Energy available = ";E;" units" 288 | 2600 INPUT"Numbers of units to fire ";X:IF X<=0 THEN 1520 289 | 2610 IF E-X<0 THEN 2590 290 | 2620 E=E-X 291 | 2621 GOSUB 5420 292 | 2622 IF D(7)<0 THEN 2630 293 | 2623 X=X*RND(1) 294 | 2630 H1=INT(X/K3) 295 | 2631 FOR I=1 TO 3 296 | 2632 IF K(I,3)<=0 THEN 2730 297 | 2640 KSQ1 = (K(I,1)-S1)*(K(I,1)-S1) 298 | 2641 KSQ2 = (K(I,2)-S2)*(K(I,2)-S2) 299 | 2642 H= SQR( KSQ1 + KSQ2 ) 300 | 2646 H = H1 / H 301 | 2647 H = INT(H * (RND(1)+2)) 302 | 2648 IF H>0.15*K(I,3) THEN 2660 303 | 2650 PRINT"Sensors show no damage to enemy at ";K(I,1);",";K(I,2):GOTO 2730 304 | 2660 K(I,3)=K(I,3)-H:PRINT H;"Unit hit on Klingon at sector ";K(I,1);","; 305 | 2670 PRINT K(I,2):IF K(I,3)> 0 THEN GOTO 2700 306 | 2680 PRINT "**** KLINGON DESTROYED ****" 307 | 2690 GOTO 2710 308 | 2700 PRINT" (Sensors show ";K(I,3);" units remaining)":GOTO 2730 309 | 2710 K3=K3-1:K9=K9-1:Z1=K(I,1):Z2=K(I,2):A$=" " 310 | 2711 GOSUB 4830 311 | 2720 K(I,3)=0:G(Q1,Q2)=G(Q1,Q2)-100:Z(Q1,Q2)=G(Q1,Q2):IF K9<=0 THEN 3680 312 | 2730 NEXT I 313 | 2731 GOSUB 3350 314 | 2732 GOTO 1520 315 | 2740 REM photon torpedo code begins here 316 | 2750 IF P>0 THEN 2760 317 | 2751 PRINT"All photon torpedoes expended":GOTO 1520 318 | 2760 IF D(5)>=0 THEN 2770 319 | 2761 PRINT"Photon tubes are not operational":GOTO 1520 320 | 2770 INPUT"Photon torpedo course (1-9) ";C2$:C1=VAL(C2$):IF C1<>9 THEN 2780 321 | 2771 C1=1 322 | 2780 IF C1>=1 AND C1<9 THEN 2810 323 | 2790 PRINT"Ensign Chekov reports, 'Incorrect course data, sir!'" 324 | 2800 GOTO 1520 325 | 2810 Z1=INT(C1):C1=C1-Z1 326 | 2811 X1=C(Z1,1)+(C(Z1+1,1)-C(Z1,1))*C1:E=E-2:P=P-1 327 | 2820 X2=C(Z1,2)+(C(Z1+1,2)-C(Z1,2))*C1:X=S1:Y=S2 328 | 2821 GOSUB 5360 329 | 2830 PRINT"Torpedo track:" 330 | 2840 X=X+X1:Y=Y+X2:X3=INT(X+0.5):Y3=INT(Y+0.5) 331 | 2850 IF X3<1 OR X3>8 OR Y3<1 OR Y3>8 THEN 3070 332 | 2860 PRINT" ";X3;",";Y3:A$=" ":Z1=X:Z2=Y 333 | 2861 GOSUB 4990 334 | 2870 IF Z3<>0 THEN 2840 335 | 2880 A$=chr$(187)+"K"+chr$(171):Z1=X:Z2=Y 336 | 2881 GOSUB 4990 337 | 2882 IF Z3=0 THEN 2940 338 | 2890 PRINT"**** KLINGON DESTROYED ****" 339 | 2900 K3=K3-1:K9=K9-1:IF K9<=0 THEN 3680 340 | 2910 FOR I=1 TO 3 341 | 2911 IF X3=K(I,1) AND Y3=K(I,2) THEN 2930 342 | 2920 NEXT I 343 | 2921 I=3 344 | 2930 K(I,3)=0:GOTO 3050 345 | 2940 A$=" * ":Z1=X:Z2=Y 346 | 2941 GOSUB 4990 347 | 2942 IF Z3=0 THEN 2960 348 | 2950 PRINT"Star at ";X3;",";Y3;" absorbed torpedo energy." 349 | 2951 GOSUB 3350 350 | 2952 GOTO 1520 351 | 2960 A$="("+chr$(174)+")":Z1=X:Z2=Y 352 | 2961 GOSUB 4990 353 | 2962 IF Z3<>0 THEN 2970 354 | 2963 PRINT "Torpedo absorbed by unknown object at ";x3;",";y3 355 | 2964 goto 1520 356 | 2970 PRINT"*** STARBASE DESTROYED ***" 357 | 2980 B3=B3-1 : B9=B9-1 358 | 2990 IF B9>0 OR K9>T-T0-T9 THEN 3030 359 | 3000 PRINT"THAT DOES IT, CAPTAIN!! You are hereby relieved of command" 360 | 3010 PRINT"and sentenced to 99 stardates of hard labor on CYGNUS 12!!" 361 | 3020 GOTO 3510 362 | 3030 PRINT"Starfleet reviewing your record to consider" 363 | 3040 PRINT"court martial!":D0=0 364 | 3050 Z1=X:Z2=Y:A$=" " 365 | 3051 GOSUB 4830 366 | 3060 G(Q1,Q2)=K3*100+B3*10+S3:Z(Q1,Q2)=G(Q1,Q2) 367 | 3061 GOSUB 3350 368 | 3062 GOTO 1520 369 | 3070 PRINT"Torpedo missed" 370 | 3071 GOSUB 3350 371 | 3072 GOTO 1520 372 | 3080 REM shield control 373 | 3090 IF D(7)>=0 THEN 3100 374 | 3091 PRINT"Shield control inoperable":GOTO 1520 375 | 3100 PRINT"Energy available = ";E+S :INPUT "Number of units to shields? ";X 376 | 3110 IF X>=0 and S<>X THEN 3120 377 | 3111 PRINT"":GOTO 1520 378 | 3120 IF X":goto 1990 381 | 3150 E=E+S-X:S=X:PRINT"Deflector Control Room report:" 382 | 3160 PRINT" 'Shields now at ";INT(S);" units per your command.'":GOTO 1520 383 | 3170 REM damage control 384 | 3180 IF D(6)>=0 THEN 3290 385 | 3190 PRINT"Damage control report not available":IF D0=0 THEN 1520 386 | 3200 D3=0:FOR I=1 TO 8 387 | 3201 IF D(I)>=0 THEN 3210 388 | 3202 D3=D3+1 389 | 3210 NEXT I 390 | 3211 IF D3=0 THEN 1520 391 | 3220 PRINT:D3=D3+D4:IF D3<1 THEN 3230 392 | 3221 D3=0.9 393 | 3230 PRINT"Technicians standing by to effect repairs to your ship;" 394 | 3240 PRINT"estimated time to repair: ";0.01*INT(100*D3);" stardates" 395 | 3250 INPUT"Will you authorize the repair order (Y/N)? ";A$ 396 | 3260 IF A$<>"y" AND A$<> "Y" THEN 1520 397 | 3270 FOR I=1 TO 8 398 | 3271 IF D(I)>=0 THEN 3280 399 | 3272 D(I)=0 400 | 3280 NEXT I 401 | 3281 T=T+D3+0.1 402 | 3290 PRINT:PRINT"Device state of repair" 403 | 3291 FOR R1=1 TO 8 404 | 3300 GOSUB 4890 405 | 3301 PRINT G2$;tab(25); 406 | 3310 GG2=INT(D(R1)*100)*0.01:PRINT GG2 407 | 3320 NEXT R1 408 | 3321 PRINT:IF D0<>0 THEN 3200 409 | 3330 GOTO 1520 410 | 3340 REM klingons shooting 411 | 3350 IF K3>0 THEN 3360 412 | 3351 RETURN 413 | 3360 IF D0=0 THEN 3370 414 | 3361 PRINT"Starbase shields protect the ENTERPRISE" 415 | 3362 RETURN 416 | 3370 FOR I=1 TO 3 417 | 3371 IF K(I,3)<=0 THEN 3460 418 | 3380 ksq1 = (K(I,1)-S1)*(K(I,1)-S1) 419 | 3381 ksq2 = (K(I,2)-S2)*(K(I,2)-S2) 420 | 3382 H=( K(I,3) / SQR( ksq1 + ksq2 ) )*(2+RND(1)) 421 | 3383 h = int(h) 422 | 3384 S=S-H:K(I,3)=K(I,3)/(3+RND(1)) 423 | 3390 PRINT "ENTERPRISE HIT!" 424 | 3400 GOSUB 5480 425 | 3401 PRINT H;" Unit hit on ENTERPRISE from sector ";K(I,1);",";K(I,2) 426 | 3410 IF S<=0 THEN 3490 427 | 3420 PRINT" ":IF H<20 THEN 3460 428 | 3430 IF RND(1)>0.6 OR H/S<=0.02 THEN 3460 429 | 3440 R1=INT(RND(1)*7.98+1.01):D(R1)=D(R1)-H/S-0.5*RND(1) 430 | 3441 GOSUB 4890 431 | 3450 PRINT"Damage control reports '";G2$;" damaged by the hit'" 432 | 3460 NEXT I 433 | 3461 RETURN 434 | 3470 REM end of game 435 | 3480 PRINT"It is stardate";T:GOTO 3510 436 | 3490 PRINT:PRINT"the ENTERPRISE has been destroyed. The Federation "; 437 | 3500 PRINT"will be conquered":GOTO 3480 438 | 3510 PRINT"There were ";K9;" Klingon battle cruisers left at" 439 | 3520 PRINT"the end of your mission" 440 | 3530 PRINT:PRINT:IF B9=0 THEN 3670 441 | 3540 PRINT"The Federation is in need of a new starship commander" 442 | 3550 PRINT"for a similar mission -- if there is a volunteer," 443 | 3560 INPUT"let him or her step forward and enter 'AYE' ";X$:IF X$="AYE" THEN 520 444 | 3670 END 445 | 3680 PRINT"Congratulations, Captain! the last Klingon battle cruiser" 446 | 3690 PRINT"menacing the Federation has been destroyed.":PRINT 447 | 3700 PRINT"Your efficiency rating is ";:cc1 = k7/(t-t0):PRINT 1000*cc1*cc1:GOTO 3530 448 | 3710 REM short range sensor scan & startup subroutine 449 | 3720 A$="("+chr$(174)+")":Z3=0 450 | 3721 FOR I=S1-1 TO S1+1 451 | 3722 FOR J=S2-1 TO S2+1 452 | 3730 IF INT(I+0.5)<1 OR INT(I+0.5)>8 OR INT(J+0.5)<1 OR INT(J+0.5)>8 or Z3=1 THEN 3760 453 | 3750 Z1=I:Z2=J 454 | 3751 GOSUB 4990 455 | 3760 NEXT J 456 | 3761 NEXT I 457 | 3762 IF Z3=1 THEN 3770 458 | 3763 D0=0:GOTO 3790 459 | 3770 D0=1:C$="docked":E=E0:P=P0 460 | 3780 PRINT"Shields dropped for docking purposes":S=0:GOTO 3810 461 | 3790 IF K3<=0 THEN 3800 462 | 3791 C$="*red*":GOTO 3810 463 | 3800 C$="GREEN":IF E>=E0*0.1 THEN 3810 464 | 3801 C$="YELLOW" 465 | 3810 IF D(2)>=0 THEN 3830 466 | 3820 PRINT:PRINT"*** Short Range Sensors are out ***":PRINT 467 | 3821 RETURN 468 | 3830 PRINT "-"*33 469 | 3832 FOR I=1 TO 8 470 | 3840 FOR J=(I-1)*24 TO (I-1)*24+21 STEP 3 471 | 3850 IF MID$(Q$,J+1,3)<>" " THEN 3860 472 | 3851 PRINT " . ";:GOTO 3861 473 | 3860 PRINT " ";MID$(Q$,J+1,3); 474 | 3861 NEXT J 475 | 3870 ON I GOTO 3880,3900,3910,3920,3930,3940,3950,3960 476 | 3880 PRINT" Stardate "; 477 | 3890 TT= T*10 : TT=INT(TT)*0.1:PRINT TT :GOTO 3970 478 | 3900 PRINT" Condition ";C$:GOTO 3970 479 | 3910 PRINT" Quadrant ";Q1;",";Q2:GOTO 3970 480 | 3920 PRINT" Sector ";S1;",";S2:GOTO 3970 481 | 3930 PRINT" Photon torpedoes ";INT(P):GOTO 3970 482 | 3940 PRINT" Total energy ";INT(E+S):GOTO 3970 483 | 3950 PRINT" Shields ";INT(S):GOTO 3970 484 | 3960 PRINT" Klingons remaining ";INT(K9) 485 | 3970 NEXT I 486 | 3971 PRINT "-"*33 487 | 3972 RETURN 488 | 3980 REM library computer code 489 | 3990 CM1$="GALSTATORBASDIRREG" 490 | 4000 IF D(8)>=0 THEN 4010 491 | 4001 PRINT"Computer Disabled":GOTO 1520 492 | 4010 rem KEY 1, "GAL RCD"+CHR$(13) 493 | 4020 rem KEY 2, "STATUS"+CHR$(13) 494 | 4030 rem KEY 3, "TOR DATA"+CHR$(13) 495 | 4040 rem KEY 4, "BASE NAV"+CHR$(13) 496 | 4050 rem KEY 5, "DIR/DIST"+CHR$(13) 497 | 4060 rem KEY 6, "REG MAP"+CHR$(13) 498 | 4070 rem KEY 7,CHR$(13):KEY 8,CHR$(13):KEY 9,CHR$(13):KEY 10,CHR$(13) 499 | 4071 gosub 4130 500 | 4080 INPUT"Computer active and awaiting command ";CM$:H8=1 501 | 4090 FOR K1= 1 TO 6 502 | 4100 IF MID$(CM$,1,3)<>MID$(CM1$,3*K1-2,3) THEN 4120 503 | 4110 ON K1 GOTO 4250,4400,4490,4750,4550,4210 504 | 4120 NEXT K1 505 | 4121 gosub 4130 506 | 4122 goto 4080 507 | 4130 PRINT"Functions available from library-computer:" 508 | 4140 PRINT" GAL = Cumulative galactic record" 509 | 4150 PRINT" STA = Status report" 510 | 4160 PRINT" TOR = Photon torpedo data" 511 | 4170 PRINT" BAS = Starbase nav data" 512 | 4180 PRINT" DIR = Direction/distance calculator" 513 | 4190 PRINT" REG = Galaxy 'region name' map":PRINT 514 | 4191 return 515 | 4200 REM setup to change cum gal record to galaxy map 516 | 4210 H8=0:G5=1:PRINT" the galaxy":GOTO 4290 517 | 4250 PRINT:PRINT" "; 518 | 4270 PRINT "Computer record of galaxy for quadrant ";Q1;",";Q2 519 | 4280 PRINT 520 | 4290 PRINT" 1 2 3 4 5 6 7 8" 521 | 4300 O1$=" ----- ----- ----- ----- ----- ----- ----- -----" 522 | 4310 PRINT O1$ 523 | 4311 FOR I=1 TO 8 524 | 4312 PRINT I;" ";:IF H8=0 THEN 4350 525 | 4320 FOR J=1 TO 8 526 | 4321 PRINT" ";:IF Z(I,J)<>0 THEN 4330 527 | 4322 PRINT"***";:GOTO 4340 528 | 4330 ZLEN = len(str$(z(i,j)+1000) 529 | 4331 PRINT MID$(STR$(Z(I,J)+1000),zlen-2,3); 530 | 4340 NEXT J 531 | 4341 GOTO 4370 532 | 4350 Z4=I:Z5=1 533 | 4351 GOSUB 5040 534 | 4352 J0=INT(15-0.5*LEN(G2$)):PRINT TAB(J0);G2$; 535 | 4360 Z5=5 536 | 4361 GOSUB 5040 537 | 4362 J0=INT(40-0.5*LEN(G2$)):PRINT TAB(J0);G2$; 538 | 4370 PRINT:PRINT O1$ 539 | 4371 NEXT I 540 | 4372 PRINT 541 | 4373 rem 'POKE 1229,0 POKE 1237,1 542 | 4380 GOTO 1520 543 | 4390 REM status report 544 | 4400 PRINT" Status Report":X$="":IF K9<=1 THEN 4410 545 | 4402 X$="s" 546 | 4410 PRINT"Klingon";X$;" left: ";K9 547 | 4420 PRINT"Mission must be completed in ";0.1*INT((T0+T9-T)*10);" stardates" 548 | 4430 X$="s":IF B9>=2 THEN 4440 549 | 4431 X$="":IF B9<1 THEN 4460 550 | 4440 PRINT"The federation is maintaining ";B9;" starbase";X$;" in the galaxy" 551 | 4450 GOTO 3180 552 | 4460 PRINT"Your stupidity has left you on your own in" 553 | 4470 PRINT" the galaxy -- you have no starbases left!":GOTO 3180 554 | 4480 REM torpedo, base nav, d/d calculator 555 | 4490 IF K3<=0 THEN 2550 556 | 4500 X$="":IF K3<=1 THEN 4510 557 | 4501 X$="s" 558 | 4510 PRINT"From ENTERPRISE to Klingon battle cruiser";X$ 559 | 4520 H8=0:FOR I=1 TO 3 560 | 4521 IF K(I,3)<=0 THEN 4740 561 | 4530 W1=K(I,1):X=K(I,2) 562 | 4540 C1=S1:A=S2:GOTO 4590 563 | 4550 PRINT"Direction/Distance Calculator:" 564 | 4560 PRINT"You are at quadrant ";Q1;",";Q2;" sector ";S1;",";S2 565 | 4570 PRINT"Please enter ":INPUT" initial coordinates (x,y) ";C1,A 566 | 4580 INPUT" Final coordinates (x,y) ";W1,X 567 | 4590 X=X-A:A=C1-W1:aa=abs(a):ax=abs(x):IF X<0 THEN 4670 568 | 4600 IF A<0 THEN 4690 569 | 4610 IF X>0 THEN 4630 570 | 4620 IF A<>0 THEN 4630 571 | 4621 C1=5:GOTO 4640 572 | 4630 C1=1 573 | 4640 IF AA<=AX THEN 4660 574 | 4650 PRINT"Direction1 = ";:cc1=(AA-AX+AA)/AA:PRINT c1+cc1:GOTO 4730 575 | 4660 PRINT"Direction2 = ";:cc1=C1+(AA/AX):PRINT cc1:GOTO 4730 576 | 4670 IF A<=0 THEN 4680 577 | 4671 C1=3:GOTO 4700 578 | 4680 IF X=0 THEN 4690 579 | 4681 C1=5:GOTO 4640 580 | 4690 C1=7 581 | 4700 IF AA>=AX THEN 4720 582 | 4710 PRINT"Direction3 = ";:cc1=(AX-AA+AX)/AX:PRINT c1+cc1:GOTO 4730 583 | 4720 PRINT"Direction4 = ";:CC1=C1+(AX/AA):PRINT CC1 584 | 4730 PRINT"Distance = ";:cc1=SQR(x*X+A*A):PRINT cc1:IF H8=1 THEN 1520 585 | 4740 NEXT I 586 | 4741 GOTO 1520 587 | 4750 IF B3=0 THEN 4770 588 | 4752 PRINT"From ENTERPRISE to Starbase:":W1=B4:X=B5 589 | 4760 GOTO 4540 590 | 4770 PRINT"Mr. Spock reports, 'Sensors show no starbases in this"; 591 | 4780 PRINT"quadrant.'":GOTO 1520 592 | 4790 REM find empty place in quadrant (for things) 593 | 4800 R1=INT(RND(1)*7.98+1.01):R2=INT(RND(1)*7.98+1.01):A$=" ":Z1=R1:Z2=R2 594 | 4801 GOSUB 4990 595 | 4802 IF Z3=0 THEN 4800 596 | 4810 RETURN 597 | 4820 REM insert in string array for quadrant 598 | 4830 S8=INT(Z2-0.5)*3+INT(Z1-0.5)*24+1 599 | 4840 IF LEN(A$)=3 THEN 4850 600 | 4841 PRINT"ERROR":STOP 601 | 4850 IF S8<>1 THEN 4860 602 | 4851 Q$=A$+MID$(Q$,4,189):RETURN 603 | 4860 IF S8<>190 THEN 4870 604 | 4861 Q$=MID$(Q$,1,189)+A$:RETURN 605 | 4870 Q$=MID$(Q$,1,S8-1)+A$+MID$(Q$,s8+3,192-s8-2):RETURN 606 | 4880 REM prints device name 607 | 4890 ON R1 GOTO 4900,4910,4920,4930,4940,4950,4960,4970 608 | 4900 G2$="Warp Engines":RETURN 609 | 4910 G2$="Short Range Sensors":RETURN 610 | 4920 G2$="Long Range Sensors":RETURN 611 | 4930 G2$="Phaser Control":RETURN 612 | 4940 G2$="Photon Tubes":RETURN 613 | 4950 G2$="Damage Control":RETURN 614 | 4960 G2$="Shield Control":RETURN 615 | 4970 G2$="Library-Computer":RETURN 616 | 4980 REM string comparison in quadrant array 617 | 4990 Z1=INT(Z1+0.5):Z2=INT(Z2+0.5):S8=(Z2-1)*3+(Z1-1)*24:Z3=0 618 | 5000 IF MID$(Q$,S8+1,3)=A$ THEN 5010 619 | 5001 RETURN 620 | 5010 Z3=1:RETURN 621 | 5020 REM quadrant name in g2$ from z4,z5 (=q1,q2) 622 | 5030 REM call with g5=1 to get region name only 623 | 5040 IF Z5<=4 THEN 5140 624 | 5041 ON Z4 GOTO 5060,5070,5080,5090,5100,5110,5120,5130 625 | 5050 GOTO 5140 626 | 5060 G2$="Antares":GOTO 5230 627 | 5070 G2$="Rigel":GOTO 5230 628 | 5080 G2$="Procyon":GOTO 5230 629 | 5090 G2$="Vega":GOTO 5230 630 | 5100 G2$="Canopus":GOTO 5230 631 | 5110 G2$="Altair":GOTO 5230 632 | 5120 G2$="Sagittarius":GOTO 5230 633 | 5130 G2$="Pollux":GOTO 5230 634 | 5140 ON Z4 GOTO 5150,5160,5170,5180,5180,5200,5210,5220 635 | 5150 G2$="Sirius":GOTO 5230 636 | 5160 G2$="Deneb":GOTO 5230 637 | 5170 G2$="Capella":GOTO 5230 638 | 5180 G2$="Betelgeuse":GOTO 5230 639 | 5190 G2$="Aldebaran":GOTO 5230 640 | 5200 G2$="Regulus":GOTO 5230 641 | 5210 G2$="Arcturus":GOTO 5230 642 | 5220 G2$="Spica" 643 | 5230 IF G5=1 THEN 5240 644 | 5231 ON Z5 GOTO 5250,5260,5270,5280,5250,5260,5270,5280 645 | 5240 RETURN 646 | 5250 G2$=G2$+" i":RETURN 647 | 5260 G2$=G2$+" ii":RETURN 648 | 5270 G2$=G2$+" iii":RETURN 649 | 5280 G2$=G2$+" iv":RETURN 650 | 5290 rem red alert sound 651 | 5291 return 652 | 5300 FOR J= 1 TO 4 653 | 5310 FOR K=1000 TO 2000 STEP 20 654 | 5320 rem SOUND K,0.01*18.2 655 | 5330 NEXT K 656 | 5340 NEXT J 657 | 5350 RETURN 658 | 5360 rem torpedo sound 659 | 5361 return 660 | 5370 FOR J = 1500 TO 100 STEP -20 661 | 5380 rem SOUND J,0.01*18.2 662 | 5390 rem SOUND 3600-J,.01*18.2 663 | 5400 NEXT J 664 | 5410 RETURN 665 | 5420 rem phaser sound 666 | 5421 return 667 | 5430 FOR J= 1 TO 40 668 | 5440 rem SOUND 800,.01*18.2 669 | 5450 rem SOUND 2500,.008*18.2 670 | 5460 NEXT J 671 | 5470 RETURN 672 | 5480 rem alarm sound 673 | 5481 return 674 | 5490 FOR SI = 1 TO 3 675 | 5500 FOR J= 800 TO 1500 STEP 20 676 | 5510 rem SOUND J,.01 *18.2 677 | 5520 NEXT J 678 | 5530 FOR K = 1500 TO 800 STEP -20 679 | 5540 rem SOUND K, .01 *18.2 680 | 5550 NEXT K 681 | 5560 NEXT SI 682 | 5570 RETURN 683 | -------------------------------------------------------------------------------- /examples/bagels.bas: -------------------------------------------------------------------------------- 1 | 5 PRINT TAB(33);"BAGELS" 2 | 10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY":PRINT:PRINT 3 | 15 REM *** BAGLES NUMBER GUESSING GAME 4 | 20 REM *** ORIGINAL SOURCE UNKNOWN BUT SUSPECTED TO BE 5 | 25 REM *** LAWRENCE HALL OF SCIENCE UC BERKELY 6 | 30 DIM A1(6),A(3),B(3) 7 | 40 Y=0:T=255 8 | 50 PRINT:PRINT:PRINT 9 | 70 INPUT "WOULD YOU LIKE THE RULES (YES OR NO)";A$ 10 | 90 IF LEFT$(A$,1)="N" THEN 150 11 | 100 PRINT:PRINT "I AM THINKING OF A THREE-DIGIT NUMBER. TRY TO GUESS" 12 | 110 PRINT "MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:" 13 | 120 PRINT " PICO - ONE DIGIT CORRECT BUT IN THE WRONG POSITION" 14 | 130 PRINT " FERMI - ONE DIGIT CORRECT AND IN THE RIGHT POSITION" 15 | 140 PRINT " BAGELS - NO DIGITS CORRECT" 16 | 150 FOR I=1 TO 3 17 | 160 A(I)=INT(10*RND(1)) 18 | 165 IF I-1=0 THEN 200 19 | 170 FOR J=1 TO I-1 20 | 180 IF A(I)=A(J) THEN 160 21 | 190 NEXT J 22 | 200 NEXT I 23 | 210 PRINT:PRINT "O.K. I HAVE A NUMBER IN MIND." 24 | 220 FOR I=1 TO 20 25 | 230 PRINT "GUESS #";I 26 | 240 INPUT A$ 27 | 245 IF LEN(A$)<>3 THEN 630 28 | 250 FOR Z=1 TO 3 29 | 251 A1(Z)=ASC(MID$(A$,Z,1)) 30 | 252 NEXT Z 31 | 260 FOR J=1 TO 3 32 | 270 IF A1(J)<48 THEN 300 33 | 280 IF A1(J)>57 THEN 300 34 | 285 B(J)=A1(J)-48 35 | 290 NEXT J 36 | 295 GOTO 320 37 | 300 PRINT "WHAT?" 38 | 310 GOTO 230 39 | 320 IF B(1)=B(2) THEN 650 40 | 330 IF B(2)=B(3) THEN 650 41 | 340 IF B(3)=B(1) THEN 650 42 | 350 C=0:D=0 43 | 360 FOR J=1 TO 2 44 | 370 IF A(J)<>B(J+1) THEN 390 45 | 380 C=C+1 46 | 390 IF A(J+1)<>B(J) THEN 410 47 | 400 C=C+1 48 | 410 NEXT J 49 | 420 IF A(1)<>B(3) THEN 440 50 | 430 C=C+1 51 | 440 IF A(3)<>B(1) THEN 460 52 | 450 C=C+1 53 | 460 FOR J=1 TO 3 54 | 470 IF A(J)<>B(J) THEN 490 55 | 480 D=D+1 56 | 490 NEXT J 57 | 500 IF D=3 THEN 680 58 | 505 IF C=0 THEN 545 59 | 520 FOR J=1 TO C 60 | 530 PRINT "PICO "; 61 | 540 NEXT J 62 | 545 IF D=0 THEN 580 63 | 550 FOR J=1 TO D 64 | 560 PRINT "FERMI "; 65 | 570 NEXT J 66 | 580 IF C+D<>0 THEN 600 67 | 590 PRINT "BAGELS"; 68 | 600 PRINT 69 | 605 NEXT I 70 | 610 PRINT "OH WELL." 71 | 615 PRINT "THAT'S TWNETY GUESSES. MY NUMBER WAS";100*A(1)+10*A(2)+A(3) 72 | 620 GOTO 700 73 | 630 PRINT "TRY GUESSING A THREE-DIGIT NUMBER.":GOTO 230 74 | 650 PRINT "OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND" 75 | 660 PRINT "HAS NO TWO DIGITS THE SAME.":GOTO 230 76 | 680 PRINT "YOU GOT IT!!!":PRINT 77 | 690 Y=Y+1 78 | 700 INPUT "PLAY AGAIN (YES OR NO)";A$ 79 | 720 IF LEFT$(A$,1)="YES" THEN 150 80 | 730 IF Y=0 THEN 750 81 | 740 PRINT:PRINT "A";Y;"POINT BAGELS BUFF!!" 82 | 750 PRINT "HOPE YOU HAD FUN. BYE." 83 | 999 END 84 | -------------------------------------------------------------------------------- /examples/eliza.bas: -------------------------------------------------------------------------------- 1 | 5 PRINT TAB ( 16 ) ; "**************************" 2 | 10 PRINT TAB ( 26 ) ; "ELIZA" 3 | 20 PRINT TAB ( 20 ) ; "CREATIVE COMPUTING" 4 | 30 PRINT TAB ( 18 ) ; "MORRISTOWN, NEW JERSEY" : PRINT 5 | 40 PRINT TAB ( 19 ) ; "ADAPTED FOR IBM PC BY" 6 | 50 PRINT TAB ( 12 ) ; "PATRICIA DANIELSON AND PAUL HASHFIELD" 7 | 53 PRINT : PRINT TAB ( 6 ) ; "PLEASE DON'T USE COMMAS OR PERIODS IN YOUR INPUTS" : PRINT 8 | 55 PRINT TAB ( 16 ) ; "*************************" 9 | 60 PRINT : PRINT : PRINT 10 | 80 REM*****INITIALIZATION********** 11 | 100 DIM S ( 36 ) , R ( 36 ) , N ( 36 ) 12 | 105 DIM KEYWORD$ ( 36 ) , WORDIN$ ( 7 ) , WORDOUT$ ( 7 ) , REPLIES$ ( 112 ) 13 | 107 REM NEED TO PRE-DECLARE BEFORE USE 14 | 108 P$ = "NULL" 15 | 110 N1 = 36 : N2 = 14 : N3 = 112 16 | 112 FOR X = 1 TO N1 17 | 113 READ TEMP$: KEYWORD$ ( X ) = TEMP$ 18 | 114 NEXT X 19 | 115 FOR X = 1 TO N2 / 2 20 | 116 READ TEMP$: WORDIN$ ( X ) = TEMP$ : READ TEMP$: WORDOUT$ ( X ) = TEMP$ 21 | 117 NEXT X 22 | 118 FOR X = 1 TO N3 23 | 119 READ TEMP$: REPLIES$ ( X ) = TEMP$ 24 | 120 NEXT X 25 | 130 FOR X = 1 TO N1 26 | 140 READ TEMP: S ( X ) = TEMP: READ TEMP: L = TEMP 27 | 142 R ( X ) = S ( X ) : N ( X ) = S ( X ) + L - 1 28 | 150 NEXT X 29 | 160 PRINT "HI! I'M ELIZA. WHAT'S YOUR PROBLEM?" 30 | 170 REM *********************************** 31 | 180 REM *******USER INPUT SECTION********** 32 | 190 REM *********************************** 33 | 200 INPUT I$ 34 | 201 I$ = " " + I$ + " " 35 | 210 REM GET RID OF APOSTROPHES 36 | 220 FOR L = 1 TO LEN ( I$ ) 37 | 230 REM IF MID$(I$,L,1)="'"THEN I$=LEFT$(I$,L-1)+RIGHT$(I$,LEN(I$)-L):GOTO 230 38 | 240 IF L + 4 > LEN ( I$ ) THEN 250 39 | 241 IF MID$ ( I$ , L , 4 ) <> "SHUT" THEN 250 40 | 242 PRINT "O.K. IF YOU FEEL THAT WAY I'LL SHUT UP...." 41 | 243 END 42 | 250 NEXT L 43 | 255 IF I$ = P$ THEN 256 ELSE 260 44 | 256 PRINT "PLEASE DON'T REPEAT YOURSELF!": GOTO 170 45 | 260 REM *********************************** 46 | 270 REM ********FIND KEYWORD IN I$********* 47 | 280 REM *********************************** 48 | 300 FOR K = 1 TO N1 49 | 320 FOR L = 1 TO LEN ( I$ ) - LEN ( KEYWORD$ ( K ) ) + 1 50 | 340 IF MID$ ( I$ , L , LEN ( KEYWORD$ ( K ) ) ) <> KEYWORD$ ( K ) THEN 350 51 | 341 IF K <> 13 THEN 349 52 | 342 IF MID$ ( I$ , L , LEN ( KEYWORD$ ( 29 ) ) ) = KEYWORD$ ( 29 ) THEN 343 ELSE 349 53 | 343 K = 29 54 | 349 F$ = KEYWORD$ ( K ) : GOTO 390 55 | 350 NEXT L 56 | 360 NEXT K 57 | 370 K = 36 : GOTO 570 : REM WE DIDN'T FIND ANY KEYWORDS 58 | 380 REM ****************************************** 59 | 390 REM **TAKE PART OF STRING AND CONJUGATE IT**** 60 | 400 REM **USING THE LIST OF STRINGS TO BE SWAPPED* 61 | 410 REM ****************************************** 62 | 430 C$ = " " + RIGHT$ ( I$ , LEN ( I$ ) - LEN ( F$ ) - L + 1 ) + " " 63 | 440 FOR X = 1 TO N2 / 2 64 | 460 FOR L = 1 TO LEN ( C$ ) 65 | 470 IF L + LEN ( WORDIN$ ( X ) ) > LEN ( C$ ) THEN 510 66 | 480 IF MID$ ( C$ , L , LEN ( WORDIN$ ( X ) ) ) <> WORDIN$ ( X ) THEN 510 67 | 490 C$ = LEFT$ ( C$ , L - 1 ) + WORDOUT$ ( X ) + RIGHT$ ( C$ , LEN ( C$ ) - L - LEN ( WORDIN$ ( X ) ) + 1 ) 68 | 495 L = L + LEN ( WORDOUT$ ( X ) ) 69 | 500 GOTO 540 70 | 510 IF L + LEN ( WORDOUT$ ( X ) ) > LEN ( C$ ) THEN 540 71 | 520 IF MID$ ( C$ , L , LEN ( WORDOUT$ ( X ) ) ) <> WORDOUT$ ( X ) THEN 540 72 | 530 C$ = LEFT$ ( C$ , L - 1 ) + WORDIN$ ( X ) + RIGHT$ ( C$ , LEN ( C$ ) - L - LEN ( WORDOUT$ ( X ) ) + 1 ) 73 | 535 L = L + LEN ( WORDIN$ ( X ) ) 74 | 540 NEXT L 75 | 550 NEXT X 76 | 551 IF MID$ ( C$ , 2 , 1 ) = " " THEN 552 ELSE 555 77 | 552 C$ = RIGHT$ ( C$ , LEN ( C$ ) - 1 ) : REM ONLY 1 SPACE 78 | 555 FOR L = 1 TO LEN ( C$ ) 79 | 556 IF MID$ ( C$ , L , 1 ) = "!" THEN 557 ELSE 558 80 | 557 C$ = LEFT$ ( C$ , L - 1 ) + RIGHT$ ( C$ , LEN ( C$ ) - L ) : GOTO 556 81 | 558 NEXT L 82 | 560 REM ********************************************** 83 | 570 REM **NOW USING THE KEYWORD NUMBER (K) GET REPLY** 84 | 580 REM ********************************************** 85 | 600 F$ = REPLIES$ ( R ( K ) ) 86 | 610 R ( K ) = R ( K ) + 1 87 | 615 IF R ( K ) > N ( K ) THEN 617 ELSE 620 88 | 617 R ( K ) = S ( K ) 89 | 620 IF RIGHT$ ( F$ , 1 ) <> "*" THEN 621 ELSE 625 90 | 621 PRINT F$ : P$ = I$ : GOTO 170 91 | 625 IF C$ <> " " THEN 630 92 | 626 PRINT "YOU WILL HAVE TO ELABORATE MORE FOR ME TO HELP YOU" 93 | 627 GOTO 170 94 | 630 PRINT LEFT$ ( F$ , LEN ( F$ ) - 1 ) ; C$ 95 | 640 P$ = I$ : GOTO 170 96 | 1000 REM ******************************* 97 | 1010 REM *****PROGRAM DATA FOLLOWS****** 98 | 1020 REM ******************************* 99 | 1030 REM *********KEYWORDS************** 100 | 1049 REM ******************************* 101 | 1050 DATA "CAN YOU " , "CAN I " , "YOU ARE " , "YOU'RE " , "I DON'T " , "I FEEL " 102 | 1060 DATA "WHY DON'T YOU " , "WHY CAN'T I " , "ARE YOU " , "I CAN'T " , "I AM " , "I'M " 103 | 1070 DATA "YOU " , "I WANT " , "WHAT " , "HOW " , "WHO " , "WHERE " , "WHEN " , "WHY " 104 | 1080 DATA "NAME " , "CAUSE " , "SORRY " , "DREAM " , "HELLO " , "HI " , "MAYBE " 105 | 1090 DATA "NO" , "YOUR " , "ALWAYS " , "THINK " , "ALIKE " , "YES " , "FRIEND " 106 | 1100 DATA "COMPUTER" , "NOKEYFOUND" 107 | 1200 REM ********************************* 108 | 1210 REM ***STRING DATA FOR CONJUGATIONS** 109 | 1220 REM ********************************* 110 | 1230 DATA " ARE " , " AM " , " WERE " , " WAS " , " YOU " , " I " , " YOUR" , " MY " 111 | 1235 DATA " I'VE " , " YOU'VE " , " I'M " , " YOU'RE " 112 | 1240 DATA " ME " , " YOU " 113 | 1300 REM ****************************** 114 | 1310 REM *********REPLIES************** 115 | 1320 REM ****************************** 116 | 1330 DATA "DON'T YOU BELIEVE THAT I CAN*" 117 | 1340 DATA "PERHAPS YOU WOULD LIKE TO BE LIKE ME*" 118 | 1350 DATA "YOU WANT ME TO BE ABLE TO*" 119 | 1360 DATA "PERHAPS YOU DON'T WANT TO*" 120 | 1365 DATA "DO YOU WANT TO BE ABLE TO*" 121 | 1370 DATA "WHAT MAKES YOU THINK I AM*" 122 | 1380 DATA "DOES IT PLEASE YOU TO BELIEVE I AM*" 123 | 1390 DATA "PERHAPS YOU WOULD LIKE TO BE*" 124 | 1400 DATA "DO YOU SOMETIMES WISH YOU WERE*" 125 | 1410 DATA "DON'T YOU REALLY*" 126 | 1420 DATA "WHY DON'T YOU*" 127 | 1430 DATA "DO YOU WISH TO BE ABLE TO*" 128 | 1440 DATA "DOES THAT TROUBLE YOU*" 129 | 1450 DATA "DO YOU OFTEN FEEL*" 130 | 1460 DATA "DO YOU OFTEN FEEL*" 131 | 1470 DATA "DO YOU ENJOY FEELING*" 132 | 1480 DATA "DO YOU REALLY BELIEVE I DON'T*" 133 | 1490 DATA "PERHAPS IN GOOD TIME I WILL*" 134 | 1500 DATA "DO YOU WANT ME TO*" 135 | 1510 DATA "DO YOU THINK YOU SHOULD BE ABLE TO*" 136 | 1520 DATA "WHY CAN'T YOU*" 137 | 1530 DATA "WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*" 138 | 1540 DATA "WOULD YOU PREFER IF I WERE NOT*" 139 | 1550 DATA "PERHAPS IN YOUR FANTASIES I AM*" 140 | 1560 DATA "HOW DO YOU KNOW YOU CAN'T*" 141 | 1570 DATA "HAVE YOU TRIED?" 142 | 1580 DATA "PERHAPS YOU CAN NOW*" 143 | 1590 DATA "DID YOU COME TO ME BECAUSE YOU ARE*" 144 | 1600 DATA "HOW LONG HAVE YOU BEEN*" 145 | 1610 DATA "DO YOU BELIEVE IT IS NORMAL TO BE*" 146 | 1620 DATA "DO YOU ENJOY BEING*" 147 | 1630 DATA "WE WERE DISCUSSING YOU--NOT ME." 148 | 1640 DATA "OH, I*" 149 | 1650 DATA "YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?" 150 | 1660 DATA "WHAT WOULD IT MEAN TO YOU IF YOU GOT*" 151 | 1670 DATA "WHY DO YOU WANT*" 152 | 1680 DATA "SUPPOSE YOU SOON GOT*" 153 | 1690 DATA "WHAT IF YOU NEVER GOT*" 154 | 1700 DATA "I SOMETIMES ALSO WANT*" 155 | 1710 DATA "WHY DO YOU ASK?" 156 | 1720 DATA "DOES THAT QUESTION INTEREST YOU?" 157 | 1730 DATA "WHAT ANSWER WOULD PLEASE YOU THE MOST?" 158 | 1740 DATA "WHAT DO YOU THINK?" 159 | 1750 DATA "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?" 160 | 1760 DATA "WHAT IS IT THAT YOU REALLY WANT TO KNOW?" 161 | 1770 DATA "HAVE YOU ASKED ANYONE ELSE?" 162 | 1780 DATA "HAVE YOU ASKED SUCH QUESTIONS BEFORE?" 163 | 1790 DATA "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?" 164 | 1800 DATA "NAMES DON'T INTEREST ME." 165 | 1810 DATA "I DON'T CARE ABOUT NAMES --PLEASE GO ON." 166 | 1820 DATA "IS THAT THE REAL REASON?" 167 | 1830 DATA "DON'T ANY OTHER REASONS COME TO MIND?" 168 | 1840 DATA "DOES THAT REASON EXPLAIN ANYTHING ELSE?" 169 | 1850 DATA "WHAT OTHER REASONS MIGHT THERE BE?" 170 | 1860 DATA "PLEASE DON'T APOLOGIZE!" 171 | 1870 DATA "APOLOGIES ARE NOT NECESSARY." 172 | 1880 DATA "WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?" 173 | 1890 DATA "DON'T BE SO DEFENSIVE!" 174 | 1900 DATA "WHAT DOES THAT DREAM SUGGEST TO YOU?" 175 | 1910 DATA "DO YOU DREAM OFTEN?" 176 | 1920 DATA "WHAT PERSONS APPEAR IN YOUR DREAMS?" 177 | 1930 DATA "ARE YOU DISTURBED BY YOUR DREAMS?" 178 | 1940 DATA "HOW DO YOU DO ...PLEASE STATE YOUR PROBLEM." 179 | 1950 DATA "YOU DON'T SEEM QUITE CERTAIN." 180 | 1960 DATA "WHY THE UNCERTAIN TONE?" 181 | 1970 DATA "CAN'T YOU BE MORE POSITIVE?" 182 | 1980 DATA "YOU AREN'T SURE?" 183 | 1990 DATA "DON'T YOU KNOW?" 184 | 2000 DATA "ARE YOU SAYING NO JUST TO BE NEGATIVE?" 185 | 2010 DATA "YOU ARE BEING A BIT NEGATIVE." 186 | 2020 DATA "WHY NOT?" 187 | 2030 DATA "ARE YOU SURE?" 188 | 2040 DATA "WHY NO?" 189 | 2050 DATA "WHY ARE YOU CONCERNED ABOUT MY*" 190 | 2060 DATA "WHAT ABOUT YOUR OWN*" 191 | 2070 DATA "CAN YOU THINK OF A SPECIFIC EXAMPLE?" 192 | 2080 DATA "WHEN?" 193 | 2090 DATA "WHAT ARE YOU THINKING OF?" 194 | 2100 DATA "REALLY, ALWAYS?" 195 | 2110 DATA "DO YOU REALLY THINK SO?" 196 | 2120 DATA "BUT YOU ARE NOT SURE YOU*" 197 | 2130 DATA "DO YOU DOUBT YOU*" 198 | 2140 DATA "IN WHAT WAY?" 199 | 2150 DATA "WHAT RESEMBLANCE DO YOU SEE?" 200 | 2160 DATA "WHAT DOES THE SIMILARITY SUGGEST TO YOU?" 201 | 2170 DATA "WHAT OTHER CONNECTIONS DO YOU SEE?" 202 | 2180 DATA "COULD THERE REALLY BE SOME CONNECTION?" 203 | 2190 DATA "HOW?" 204 | 2200 DATA "YOU SEEM QUITE POSITIVE." 205 | 2210 DATA "ARE YOU SURE?" 206 | 2220 DATA "I SEE." 207 | 2230 DATA "I UNDERSTAND." 208 | 2240 DATA "WHY DO YOU BRING UP THE TOPIC OF FRIENDS?" 209 | 2250 DATA "DO YOUR FRIENDS WORRY YOU?" 210 | 2260 DATA "DO YOUR FRIENDS PICK ON YOU?" 211 | 2270 DATA "ARE YOU SURE YOU HAVE ANY FRIENDS?" 212 | 2280 DATA "DO YOU IMPOSE ON YOUR FRIENDS?" 213 | 2290 DATA "PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU." 214 | 2300 DATA "DO COMPUTERS WORRY YOU?" 215 | 2310 DATA "ARE YOU TALKING ABOUT ME IN PARTICULAR?" 216 | 2320 DATA "ARE YOU FRIGHTENED BY MACHINES?" 217 | 2330 DATA "WHY DO YOU MENTION COMPUTERS?" 218 | 2340 DATA "WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?" 219 | 2350 DATA "DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?" 220 | 2360 DATA "WHAT IS IT ABOUT MACHINES THAT WORRIES YOU?" 221 | 2370 DATA "SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS?" 222 | 2380 DATA "WHAT DOES THAT SUGGEST TO YOU?" 223 | 2390 DATA "I SEE." 224 | 2400 DATA "I'M NOT SURE I UNDERSTAND YOU FULLY." 225 | 2410 DATA "COME COME ELUCIDATE YOUR THOUGHTS." 226 | 2420 DATA "CAN YOU ELABORATE ON THAT?" 227 | 2430 DATA "THAT IS QUITE INTERESTING." 228 | 2500 REM ************************* 229 | 2510 REM *****DATA FOR FINDING RIGHT REPLIES 230 | 2520 REM ************************* 231 | 2530 DATA 1 , 3 , 4 , 2 , 6 , 4 , 6 , 4 , 10 , 4 , 14 , 3 , 17 , 3 , 20 , 2 , 22 , 3 , 25 , 3 232 | 2540 DATA 28 , 4 , 28 , 4 , 32 , 3 , 35 , 5 , 40 , 9 , 40 , 9 , 40 , 9 , 40 , 9 , 40 , 9 , 40 , 9 233 | 2550 DATA 49 , 2 , 51 , 4 , 55 , 4 , 59 , 4 , 63 , 1 , 63 , 1 , 64 , 5 , 69 , 5 , 74 , 2 , 76 , 4 234 | 2560 DATA 80 , 3 , 83 , 7 , 90 , 3 , 93 , 6 , 99 , 7 , 106 , 6 -------------------------------------------------------------------------------- /examples/factorial.bas: -------------------------------------------------------------------------------- 1 | 10 REM A SHORT PROGRAM TO CALCULATE FACTORIAL OF 2 | 20 REM SUPPLIED NUMBER N 3 | 30 INPUT "Please provide N: "; N 4 | 35 REM OUTPUT IS NOW A RESERVED KEYWORD 5 | 40 OUTPUTVAL = 1 6 | 50 FOR I = 1 TO N 7 | 60 OUTPUTVAL = OUTPUTVAL * I 8 | 70 NEXT I 9 | 80 PRINT "Factorial of N is "; OUTPUTVAL 10 | -------------------------------------------------------------------------------- /examples/life.bas: -------------------------------------------------------------------------------- 1 | 2 PRINT TAB(34);"LIFE" 2 | 4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN NEW JERSEY" 3 | 6 PRINT: PRINT: PRINT 4 | 8 PRINT "ENTER YOUR PATTERN, AS A SERIES OF SPACES" 5 | 9 PRINT "AND STARS, LINE BY LINE. FINISH BY TYPING" 6 | 10 PRINT "'DONE' ON THE FINAL LINE:" 7 | 11 X1=1: Y1=1: X2=24: Y2=70: G=0: P=0 8 | 12 DIM A(24, 70): DIM B$(24) 9 | 15 I9=1 10 | 20 C=1 11 | 30 INPUT TEMP$ 12 | 35 B$(C) = TEMP$ 13 | 40 IF B$(C)="DONE" THEN 45 ELSE 50 14 | 45 B$(C)="": GOTO 80 15 | 46 REM ORIGINAL VERSION REQUIRED USER TO WRITE 16 | 47 REM DOTS INSTEAD OF SPACES, WHICH WOULD THEN BE 17 | 48 REM CONVERTED TO SPACES 18 | 50 REM IF LEFT$(B$(C), 1)="." THEN 55 ELSE 60 19 | 55 REM B$(C)=" "+RIGHT$(B$(C), LEN(B$(C))-1) 20 | 60 C=C+1 21 | 70 GOTO 30 22 | 80 C=C-1: L=0 23 | 90 FOR X=1 TO C-1 24 | 100 IF LEN(B$(X))>L THEN 105 ELSE 110 25 | 105 L=LEN(B$(X)) 26 | 110 NEXT X 27 | 120 X1=INT(11-C/2) 28 | 130 Y1=INT(33-L/2) 29 | 135 REM TRANSCRIBE INPUT PATTERN INTO ARRAY 30 | 140 FOR X=1 TO C 31 | 150 FOR Y=1 TO LEN(B$(X)) 32 | 160 IF MID$(B$(X), Y, 1)<>" " THEN 165 ELSE 170 33 | 165 A(X1+X, Y1+Y)=1: P=P+1 34 | 170 NEXT Y 35 | 180 NEXT X 36 | 200 PRINT: PRINT: PRINT 37 | 210 PRINT "GENERATION: "; G; " POPULATION: "; P; 38 | 212 IF I9=0 THEN 213 ELSE 215 39 | 213 PRINT " INVALID!"; 40 | 215 X3=24: Y3=70: X4=1: Y4=1: P=0 41 | 220 G=G+1 42 | 230 FOR X=X1 TO X2 43 | 240 PRINT 44 | 250 FOR Y=Y1 TO Y2 45 | 253 IF A(X, Y)=2 THEN 254 ELSE 256 46 | 254 A(X, Y)=0: GOTO 270 47 | 256 IF A(X, Y)=3 THEN 258 ELSE 260 48 | 258 A(X, Y)=1: GOTO 261 49 | 260 IF A(X, Y)<>1 THEN 270 50 | 261 PRINT TAB(Y);"*"; 51 | 262 IF XX4 THEN 265 ELSE 266 54 | 265 X4=X 55 | 266 IF YY4 THEN 269 ELSE 270 58 | 269 Y4=Y 59 | 270 NEXT Y 60 | 290 NEXT X 61 | 295 FOR X=X2+1 TO 24 62 | 296 PRINT 63 | 297 NEXT X 64 | 299 X1=X3: X2=X4: Y1=Y3: Y2=Y4 65 | 301 IF X1<3 THEN 302 ELSE 303 66 | 302 X1=3: I9=-1 67 | 303 IF X2>22 THEN 304 ELSE 305 68 | 304 X2=22: I9=-1 69 | 305 IF Y1<3 THEN 306 ELSE 307 70 | 306 Y1=3: I9=-1 71 | 307 IF Y2>68 THEN 308 ELSE 309 72 | 308 Y2=68: I9=-1 73 | 309 P=0 74 | 500 FOR X=X1-1 TO X2+1 75 | 510 FOR Y=Y1-1 TO Y2+1 76 | 520 C=0 77 | 530 FOR I=X-1 TO X+1 78 | 540 FOR J=Y-1 TO Y+1 79 | 550 IF A(I, J)=1 OR A(I, J)=2 THEN 555 ELSE 560 80 | 555 C=C+1 81 | 560 NEXT J 82 | 570 NEXT I 83 | 580 IF A(X, Y)=0 THEN 610 84 | 590 IF C<3 or C>4 THEN 592 ELSE 595 85 | 592 A(X, Y)=2: GOTO 600 86 | 595 P=P+1 87 | 600 GOTO 620 88 | 610 IF C=3 THEN 615 ELSE 620 89 | 615 A(X, Y)=3: P=P+1 90 | 620 NEXT Y 91 | 630 NEXT X 92 | 635 X1=X1-1: Y1=Y1-1: X2=X2+1: Y2=Y2+1 93 | 640 GOTO 210 94 | 650 END -------------------------------------------------------------------------------- /examples/oregon.bas: -------------------------------------------------------------------------------- 1 | 10 REM PROGRAM NAME - OREGON VERSION:01/01/78 2 | 20 REM ORIGINAL PROGRAMMING BY BILL HEINEMANN - 1971 3 | 30 REM SUPPORT RESEARCH AND MATERIALS BY DON RAVITSCH, 4 | 40 REM MINNESOTA EDUCATIONAL COMPUTING CONSORTIUM STAFF 5 | 50 REM CDC CYBER 70/73-26 BASIC 3.1 6 | 60 REM DOCUMENTATION BOOKLET 'OREGON' AVAILABLE FROM 7 | 61 REM MECC SUPPORT SERVICES 8 | 62 REM 2520 BROADWAY DRIVE 9 | 63 REM ST. PAUL MN 55113 10 | 80 REM 11 | 150 REM *FOR THE MEANING OF THE VARIABLES USED, LIST LINES 6470-6790* 12 | 155 REM 13 | 160 PRINT "DO YOU NEED INSTRUCTIONS (YES/NO)" ; 14 | 165 REM PYBASIC CAN'T DO STRING OPERATIONS ON ARRAYS 15 | 170 REM DIM C$(5) 16 | 180 REM RANDOMIZE REMOVED 17 | 190 INPUT C$ 18 | 200 IF C$ = "NO" THEN 690 19 | 210 PRINT 20 | 220 PRINT 21 | 230 REM ***INSTRUCTIONS*** 22 | 240 PRINT "THIS PROGRAM SIMULATES A TRIP OVER THE OREGON TRAIL FROM" 23 | 250 PRINT "INDEPENDENCE, MISSOURI TO OREGON CITY, OREGON IN 1847." 24 | 260 PRINT "YOUR FAMILY OF FIVE WILL COVER THE 2040 MILE OREGON TRAIL" 25 | 270 PRINT "IN 5-6 MONTHS --- IF YOU MAKE IT ALIVE." 26 | 280 PRINT 27 | 290 PRINT "YOU HAD SAVED $900 TO SPEND FOR THE TRIP, AND YOU'VE JUST" 28 | 300 PRINT " PAID $200 FOR A WAGON." 29 | 310 PRINT "YOU WILL NEED TO SPEND THE REST OF YOUR MONEY ON THE" 30 | 320 PRINT " FOLLOWING ITEMS:" 31 | 330 PRINT 32 | 340 PRINT " OXEN - YOU CAN SPEND $200-$300 ON YOUR TEAM" 33 | 350 PRINT " THE MORE YOU SPEND, THE FASTER YOU'LL GO" 34 | 360 PRINT " BECAUSE YOU'LL HAVE BETTER ANIMALS" 35 | 370 PRINT 36 | 380 PRINT " FOOD - THE MORE YOU HAVE, THE LESS CHANCE THERE" 37 | 390 PRINT " IS OF GETTING SICK" 38 | 400 PRINT 39 | 410 PRINT " AMMUNITION - $1 BUYS A BELT OF 50 BULLETS" 40 | 420 PRINT " YOU WILL NEED BULLETS FOR ATTACKS BY ANIMALS" 41 | 430 PRINT " AND BANDITS, AND FOR HUNTING FOOD" 42 | 440 PRINT 43 | 450 PRINT " CLOTHING - THIS IS ESPECIALLY IMPORTANT FOR THE COLD" 44 | 460 PRINT " WEATHER YOU WILL ENCOUNTER WHEN CROSSING" 45 | 470 PRINT " THE MOUNTAINS" 46 | 480 PRINT 47 | 490 PRINT " MISCELLANEOUS SUPPLIES - THIS INCLUDES MEDICINE AND" 48 | 500 PRINT " OTHER THINGS YOU WILL NEED FOR SICKNESS" 49 | 510 PRINT " AND EMERGENCY REPAIRS" 50 | 520 PRINT 51 | 530 PRINT 52 | 540 PRINT "YOU CAN SPEND ALL YOUR MONEY BEFORE YOU START YOUR TRIP -" 53 | 550 PRINT "OR YOU CAN SAVE SOME OF YOUR CASH TO SPEND AT FORTS ALONG" 54 | 560 PRINT "THE WAY WHEN YOU RUN LOW. HOWEVER, ITEMS COST MORE AT" 55 | 570 PRINT "THE FORTS. YOU CAN ALSO GO HUNTING ALONG THE WAY TO GET" 56 | 580 PRINT "MORE FOOD." 57 | 590 PRINT "WHENEVER YOU HAVE TO USE YOUR TRUSTY RIFLE ALONG THE WAY," 58 | 600 PRINT "YOU WILL BE TOLD TO TYPE IN A WORD (ONE THAT SOUNDS LIKE A " 59 | 610 PRINT "GUN SHOT). THE FASTER YOU TYPE IN THAT WORD AND HIT THE" 60 | 620 PRINT "" "RETURN" " KEY, THE BETTER LUCK YOU'LL HAVE WITH YOUR GUN." 61 | 630 PRINT 62 | 640 PRINT "AT EACH TURN, ALL ITEMS ARE SHOWN IN DOLLAR AMOUNTS" 63 | 650 PRINT "EXCEPT BULLETS" 64 | 660 PRINT "WHEN ASKED TO ENTER MONEY AMOUNTS, DON'T USE A " "$" "." 65 | 670 PRINT 66 | 680 PRINT "GOOD LUCK!!!" 67 | 690 PRINT 68 | 700 PRINT 69 | 710 PRINT "HOW GOOD A SHOT ARE YOU WITH YOUR RIFLE?" 70 | 720 PRINT " (1) ACE MARKSMAN, (2) GOOD SHOT, (3) FAIR TO MIDDLIN'" 71 | 730 PRINT " (4) NEED MORE PRACTICE, (5) SHAKY KNEES" 72 | 740 PRINT "ENTER ONE OF THE ABOVE -- THE BETTER YOU CLAIM YOU ARE, THE" 73 | 750 PRINT "FASTER YOU'LL HAVE TO BE WITH YOUR GUN TO BE SUCCESSFUL." 74 | 760 INPUT D9 75 | 770 IF D9 > 5 THEN 790 76 | 780 GOTO 810 77 | 790 D9 = 0 78 | 800 REM ***INITIAL PURCHASES*** 79 | 810 X1 = - 1 80 | 820 REM LINES 820-829 MODIFIED BY CHRISTOPHER PEDERSEN (AUG 10, 2018) 81 | 821 REM FOR COMPATIBILITY WITH THE CHIPMUNK BASIC INTERPRETER 82 | 822 REM CHIPMUNK BASIC: http://www.nicholson.com/rhn/basic/ 83 | 823 D3 = 0 84 | 824 M9 = 0 85 | 825 M = 0 86 | 826 F2 = 0 87 | 827 F1 = 0 88 | 828 S4 = 0 89 | 829 K8 = 0 90 | 830 PRINT 91 | 840 PRINT 92 | 850 PRINT "HOW MUCH DO YOU WANT TO SPEND ON YOUR OXEN TEAM" ; 93 | 860 INPUT A 94 | 870 IF A >= 200 THEN 900 95 | 880 PRINT "NOT ENOUGH" 96 | 890 GOTO 850 97 | 900 IF A <= 300 THEN 930 98 | 910 PRINT "TOO MUCH" 99 | 920 GOTO 850 100 | 930 PRINT "HOW MUCH DO YOU WANT TO SPEND ON FOOD" ; 101 | 940 INPUT F 102 | 950 IF F >= 0 THEN 980 103 | 960 PRINT "IMPOSSIBLE" 104 | 970 GOTO 930 105 | 980 PRINT "HOW MUCH DO YOU WANT TO SPEND ON AMMUNITION" ; 106 | 990 INPUT B 107 | 1000 IF B >= 0 THEN 1030 108 | 1010 PRINT "IMPOSSIBLE" 109 | 1020 GOTO 980 110 | 1030 PRINT "HOW MUCH DO YOU WANT TO SPEND ON CLOTHING" ; 111 | 1040 INPUT C 112 | 1050 IF C >= 0 THEN 1080 113 | 1060 PRINT "IMPOSSIBLE" 114 | 1070 GOTO 1030 115 | 1080 PRINT "HOW MUCH DO YOU WANT TO SPEND ON MISCELLANEOUS SUPPLIES" ; 116 | 1090 INPUT M1 117 | 1100 IF M1 >= 0 THEN 1130 118 | 1110 PRINT "IMPOSSIBLE" 119 | 1120 GOTO 1080 120 | 1130 T = 700 - A - F - B - C - M1 121 | 1140 IF T >= 0 THEN 1170 122 | 1150 PRINT "YOU OVERSPENT--YOU ONLY HAD $700 TO SPEND. BUY AGAIN" 123 | 1160 GOTO 830 124 | 1170 B = 50 * B 125 | 1180 PRINT "AFTER ALL YOUR PURCHASES. YOU NOW HAVE " ; T ; " DOLLARS LEFT" 126 | 1190 PRINT 127 | 1200 PRINT "MONDAY MARCH 29 1847" 128 | 1210 PRINT 129 | 1220 GOTO 1750 130 | 1230 IF M >= 2040 THEN 5430 131 | 1240 REM ***SETTING DATE*** 132 | 1250 D3 = D3 + 1 133 | 1260 PRINT 134 | 1270 PRINT "MONDAY " ; 135 | 1280 IF D3 > 10 THEN 1300 136 | 1290 ON D3 GOTO 1310 , 1330 , 1350 , 1370 , 1390 , 1410 , 1430 , 1450 , 1470 , 1490 137 | 1300 ON D3 - 10 GOTO 1510 , 1530 , 1550 , 1570 , 1590 , 1610 , 1630 , 1650 , 1670 , 1690 138 | 1310 PRINT "APRIL 12 " ; 139 | 1320 GOTO 1720 140 | 1330 PRINT "APRIL 26 " ; 141 | 1340 GOTO 1720 142 | 1350 PRINT "MAY 10 " ; 143 | 1360 GOTO 1720 144 | 1370 PRINT "MAY 24 " ; 145 | 1380 GOTO 1720 146 | 1390 PRINT "JUNE 7 " ; 147 | 1400 GOTO 1720 148 | 1410 PRINT "JUNE 21 " ; 149 | 1420 GOTO 1720 150 | 1430 PRINT "JULY 5 " ; 151 | 1440 GOTO 1720 152 | 1450 PRINT "JULY 19 " ; 153 | 1460 GOTO 1720 154 | 1470 PRINT "AUGUST 2 " ; 155 | 1480 GOTO 1720 156 | 1490 PRINT "AUGUST 16 " ; 157 | 1500 GOTO 1720 158 | 1510 PRINT "AUGUST 31 " ; 159 | 1520 GOTO 1720 160 | 1530 PRINT "SEPTEMBER 13 " ; 161 | 1540 GOTO 1720 162 | 1550 PRINT "SEPTEMBER 27 " ; 163 | 1560 GOTO 1720 164 | 1570 PRINT "OCTOBER 11 " ; 165 | 1580 GOTO 1720 166 | 1590 PRINT "OCTOBER 25 " ; 167 | 1600 GOTO 1720 168 | 1610 PRINT "NOVEMBER 8 " ; 169 | 1620 GOTO 1720 170 | 1630 PRINT "NOVEMBER 22 " ; 171 | 1640 GOTO 1720 172 | 1650 PRINT "DECEMBER 6 " ; 173 | 1660 GOTO 1720 174 | 1670 PRINT "DECEMBER 20 " ; 175 | 1680 GOTO 1720 176 | 1690 PRINT "YOU HAVE BEEN ON THE TRAIL TOO LONG ------" 177 | 1700 PRINT "YOUR FAMILY DIES IN THE FIRST BLIZZARD OF WINTER" 178 | 1710 GOTO 5170 179 | 1720 PRINT "1847" 180 | 1730 PRINT 181 | 1740 REM ***BEGINNING EACH TURN*** 182 | 1750 IF F >= 0 THEN 1770 183 | 1760 F = 0 184 | 1770 IF B >= 0 THEN 1790 185 | 1780 B = 0 186 | 1790 IF C >= 0 THEN 1810 187 | 1800 C = 0 188 | 1810 IF M1 >= 0 THEN 1830 189 | 1820 M1 = 0 190 | 1830 IF F >= 13 THEN 1850 191 | 1840 PRINT "YOU'D BETTER DO SOME HUNTING OR BUY FOOD AND SOON!!!!" 192 | 1850 F = INT ( F ) 193 | 1860 B = INT ( B ) 194 | 1870 C = INT ( C ) 195 | 1880 M1 = INT ( M1 ) 196 | 1890 T = INT ( T ) 197 | 1900 M = INT ( M ) 198 | 1910 M2 = M 199 | 1920 IF S4 = 1 THEN 1950 200 | 1930 IF K8 = 1 THEN 1950 201 | 1940 GOTO 1990 202 | 1950 T = T - 20 203 | 1960 IF T < 0 THEN 5080 204 | 1970 PRINT "DOCTOR'S BILL IS $20" 205 | 1980 REM LINES 1980-1982 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH MODERN BASIC 206 | 1981 LET S4 = 0 207 | 1982 LET K8 = S4 208 | 1990 IF M9 = 1 THEN 2020 209 | 2000 PRINT "TOTAL MILEAGE: " ; M 210 | 2010 GOTO 2040 211 | 2020 PRINT "TOTAL MILEAGE: 950" 212 | 2030 M9 = 0 213 | 2040 REM LINES 2040-2050 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH MODERN BASIC 214 | 2041 PRINT "FOOD: " ; F 215 | 2042 PRINT "BULLETS: " ; B 216 | 2043 PRINT "CLOTHING: " ; C 217 | 2044 PRINT "MISC. SUPPLIES: " ; M1 218 | 2050 PRINT "CASH: $" ; T 219 | 2060 IF X1 = - 1 THEN 2170 220 | 2070 X1 = X1 * ( - 1 ) 221 | 2080 PRINT "DO YOU WANT TO (1) STOP AT THE NEXT FORT, (2) HUNT, " ; 222 | 2090 PRINT "OR (3) CONTINUE" 223 | 2100 INPUT X 224 | 2110 REM IF X>2 THEN 2150 225 | 2120 REM IF X<1 THEN 2150 226 | 2130 REM LET X=INT(X) 227 | 2140 GOTO 2270 228 | 2150 LET X = 3 229 | 2160 GOTO 2270 230 | 2170 PRINT "DO YOU WANT TO (1) HUNT, OR (2) CONTINUE" 231 | 2180 INPUT X 232 | 2190 IF X = 1 THEN 2210 233 | 2200 LET X = 2 234 | 2210 LET X = X + 1 235 | 2220 IF X = 3 THEN 2260 236 | 2230 IF B > 39 THEN 2260 237 | 2240 PRINT "TOUGH---YOU NEED MORE BULLETS TO GO HUNTING" 238 | 2250 GOTO 2170 239 | 2260 X1 = X1 * ( - 1 ) 240 | 2270 ON X GOTO 2290 , 2540 , 2720 241 | 2280 REM ***STOPPING AT FORT*** 242 | 2290 PRINT "ENTER WHAT YOU WISH TO SPEND ON THE FOLLOWING" 243 | 2300 PRINT "FOOD" ; 244 | 2310 GOSUB 2330 245 | 2320 GOTO 2410 246 | 2330 INPUT P 247 | 2340 IF P < 0 THEN 2400 248 | 2350 T = T - P 249 | 2360 IF T >= 0 THEN 2400 250 | 2370 PRINT "YOU DON'T HAVE THAT MUCH--KEEP YOUR SPENDING DOWN" 251 | 2380 T = T + P 252 | 2390 P = 0 253 | 2400 RETURN 254 | 2410 F = F + 2 / 3 * P 255 | 2420 PRINT "AMMUNITION" ; 256 | 2430 GOSUB 2330 257 | 2440 LET B = INT ( B + 2 / 3 * P * 50 ) 258 | 2450 PRINT "CLOTHING" ; 259 | 2460 GOSUB 2330 260 | 2470 C = C + 2 / 3 * P 261 | 2480 PRINT "MISCELLANEOUS SUPPLIES" ; 262 | 2490 GOSUB 2330 263 | 2500 M1 = M1 + 2 / 3 * P 264 | 2510 M = M - 45 265 | 2520 GOTO 2720 266 | 2530 REM ***HUNTING*** 267 | 2540 IF B > 39 THEN 2570 268 | 2550 PRINT "TOUGH---YOU NEED MORE BULLETS TO GO HUNTING" 269 | 2560 GOTO 2080 270 | 2570 M = M - 45 271 | 2580 GOSUB 6140 272 | 2590 IF B1 <= 1 THEN 2660 273 | 2600 IF 100 + RND ( 1 ) < 13 * B1 THEN 2710 274 | 2610 F = F + 48 - 2 * B1 275 | 2620 PRINT "NICE SHOT--RIGHT ON TARGET--GOOD EATIN' TONIGHT!!" 276 | 2630 B = B - 10 - 3 * B1 277 | 2640 GOTO 2720 278 | 2650 REM **BELLS IN LINE 2660** 279 | 2660 PRINT "RIGHT BETWEEN THE EYES---YOU GOT A BIG ONE!!!!" 280 | 2670 PRINT "FULL BELLIES TONIGHT!" 281 | 2680 F = F + 52 + RND ( 1 ) * 6 282 | 2690 B = B - 10 - RND ( 1 ) * 4 283 | 2700 GOTO 2720 284 | 2710 PRINT "YOU MISSED---AND YOUR DINNER GOT AWAY....." 285 | 2720 IF F >= 13 THEN 2750 286 | 2730 GOTO 5060 287 | 2740 REM ***EATING*** 288 | 2750 PRINT "DO YOU WANT TO EAT (1) POORLY (2) MODERATELY" 289 | 2760 PRINT "OR (3) WELL" ; 290 | 2770 INPUT E 291 | 2780 IF E > 3 THEN 2750 292 | 2790 IF E < 1 THEN 2750 293 | 2800 LET E = INT ( E ) 294 | 2810 LET F = F - 8 - 5 * E 295 | 2820 IF F >= 0 THEN 2860 296 | 2830 F = F + 8 + 5 * E 297 | 2840 PRINT "YOU CAN'T EAT THAT WELL" 298 | 2850 GOTO 2750 299 | 2860 LET M = M + 200 + ( A - 220 ) / 5 + 10 * RND ( 1 ) 300 | 2870 REM LINES 2870-2872 MODIFIED BY C.D.P. FOR COMPATIBILITY W/ CHIPMUNK BASIC 301 | 2871 C1 = 0 302 | 2872 L1 = C1 303 | 2880 REM ***RIDERS ATTACK*** 304 | 2889 REM LINE 2890 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH CHIPMUNK BASIC 305 | 2900 PRINT "RIDERS AHEAD. THEY " ; 306 | 2910 S5 = 0 307 | 2919 REM ALL RND(-1) FUNCTION CALLS HAVE BEEN CHANGED TO RND(1) BY C.D.P. 308 | 2930 PRINT "DON'T " ; 309 | 2940 S5 = 1 310 | 2950 PRINT "LOOK HOSTILE" 311 | 2960 PRINT "TACTICS" 312 | 2970 PRINT "(1) RUN (2) ATTACK (3) CONTINUE (4) CIRCLE WAGONS" 313 | 2990 S5 = 1 - S5 314 | 3000 INPUT T1 315 | 3010 IF T1 < 1 THEN 2970 316 | 3020 IF T1 > 4 THEN 2970 317 | 3030 T1 = INT ( T1 ) 318 | 3040 IF S5 = 1 THEN 3330 319 | 3050 IF T1 > 1 THEN 3110 320 | 3060 M = M + 20 321 | 3070 M1 = M1 - 15 322 | 3080 B = B - 150 323 | 3090 A = A - 40 324 | 3100 GOTO 3470 325 | 3110 IF T1 > 2 THEN 3240 326 | 3120 GOSUB 6140 327 | 3130 B = B - B1 * 40 - 80 328 | 3140 IF B1 > 1 THEN 3170 329 | 3150 PRINT "NICE SHOOTING---YOU DROVE THEM OFF" 330 | 3160 GOTO 3470 331 | 3170 IF B1 <= 4 THEN 3220 332 | 3180 PRINT "LOUSY SHOT---YOU GOT KNIFED" 333 | 3190 K8 = 1 334 | 3200 PRINT "YOU HAVE TO SEE OL' DOC BLANCHARD" 335 | 3210 GOTO 3470 336 | 3220 PRINT "KINDA SLOW WITH YOUR COLT .45" 337 | 3230 GOTO 3470 338 | 3240 IF T1 > 3 THEN 3290 339 | 3260 LET B = B - 150 340 | 3270 M1 = M1 - 15 341 | 3280 GOTO 3470 342 | 3290 GOSUB 6140 343 | 3300 B = B - B1 * 30 - 80 344 | 3310 M = M - 25 345 | 3320 GOTO 3140 346 | 3330 IF T1 > 1 THEN 3370 347 | 3340 M = M + 15 348 | 3350 A = A - 10 349 | 3360 GOTO 3470 350 | 3370 IF T1 > 2 THEN 3410 351 | 3380 M = M - 5 352 | 3390 B = B - 100 353 | 3400 GOTO 3470 354 | 3410 IF T1 > 3 THEN 3430 355 | 3420 GOTO 3470 356 | 3430 M = M - 20 357 | 3440 GOTO 3470 358 | 3450 PRINT "THEY DID NOT ATTACK" 359 | 3460 GOTO 3550 360 | 3470 IF S5 = 0 THEN 3500 361 | 3480 PRINT "RIDERS WERE FRIENDLY, BUT CHECK FOR POSSIBLE LOSSES" 362 | 3490 GOTO 3550 363 | 3500 PRINT "RIDERS WERE HOSTILE--CHECK FOR LOSES" 364 | 3510 IF B >= 0 THEN 3550 365 | 3520 PRINT "YOU RAN OUT OF BULLETS AND GOT MASSACRED BY THE RIDERS" 366 | 3530 GOTO 5170 367 | 3540 REM ***SELECTION OF EVENTS*** 368 | 3550 LET D1 = 0 369 | 3560 RESTORE 3620 370 | 3570 R1 = 100 * RND ( 1 ) 371 | 3580 LET D1 = D1 + 1 372 | 3590 IF D1 = 16 THEN 4670 373 | 3600 READ D 374 | 3610 IF R1 > D THEN 3580 375 | 3620 DATA 6 , 11 , 13 , 15 , 17 , 22 , 32 , 35 , 37 , 42 , 44 , 54 , 64 , 69 , 95 376 | 3630 IF D1 > 10 THEN 3650 377 | 3640 ON D1 GOTO 3660 , 3700 , 3740 , 3790 , 3820 , 3850 , 3880 , 3960 , 4130 , 4190 378 | 3650 ON D1 - 10 GOTO 4220 , 4290 , 4340 , 4560 , 4610 , 4670 379 | 3660 PRINT "WAGON BREAKS DOWN--LOSE TIME AND SUPPLIES FIXING IT" 380 | 3670 LET M = M - 15 - 5 * RND ( 1 ) 381 | 3680 LET M1 = M1 - 8 382 | 3690 GOTO 4710 383 | 3700 PRINT "0X INJURES LEG---SLOWS YOU DOWN REST OF TRIP" 384 | 3710 LET M = M - 25 385 | 3720 LET A = A - 20 386 | 3730 GOTO 4710 387 | 3740 PRINT "BACK LUCK---YOUR DAUGHTER BROKE HER ARM" 388 | 3750 PRINT "YOU HAD TO STOP AND USE SUPPLIES TO MAKE A SLING" 389 | 3760 M = M - 5 - 4 * RND ( 1 ) 390 | 3770 M1 = M1 - 2 - 3 * RND ( 1 ) 391 | 3780 GOTO 4710 392 | 3790 PRINT "OX WANDERS OFF---SPEND TIME LOOKING FOR IT" 393 | 3800 M = M - 17 394 | 3810 GOTO 4710 395 | 3820 PRINT "YOUR SON GETS LOST---SPEND HALF THE DAY LOOKING FOR HIM" 396 | 3830 M = M - 10 397 | 3840 GOTO 4710 398 | 3850 PRINT "UNSAFE WATER--LOSE TIME LOOKING FOR CLEAN SPRING" 399 | 3860 LET M = M - 10 * RND ( 1 ) - 2 400 | 3870 GOTO 4710 401 | 3880 IF M > 950 THEN 4490 402 | 3890 PRINT "HEAVY RAINS---TIME AND SUPPLIES LOST" 403 | 3910 F = F - 10 404 | 3920 B = B - 500 405 | 3930 M1 = M1 - 15 406 | 3940 M = M - 10 * RND ( 1 ) - 5 407 | 3950 GOTO 4710 408 | 3960 PRINT "BANDITS ATTACK" 409 | 3970 GOSUB 6140 410 | 3980 B = B - 20 * B1 411 | 3990 IF B >= 0 THEN 4030 412 | 4000 PRINT "YOU RAN OUT OF BULLETS---THEY GET LOTS OF CASH" 413 | 4010 T = T / 3 414 | 4020 GOTO 4040 415 | 4030 IF B1 <= 1 THEN 4100 416 | 4040 PRINT "YOU GOT SHOT IN THE LEG AND THEY TOOK ONE OF YOUR OXEN" 417 | 4050 K8 = 1 418 | 4060 PRINT "BETTER HAVE A DOC LOOK AT YOUR WOUND" 419 | 4070 M1 = M1 - 5 420 | 4080 A = A - 20 421 | 4090 GOTO 4710 422 | 4100 PRINT "QUICKEST DRAW OUTSIDE OF DODGE CITY!!!" 423 | 4110 PRINT "YOU GOT 'EM!" 424 | 4120 GOTO 4710 425 | 4130 PRINT "THERE WAS A FIRE IN YOUR WAGON--FOOD AND SUPPLIES DAMAGE!" 426 | 4140 F = F - 40 427 | 4150 B = B - 400 428 | 4160 LET M1 = M1 - RND ( 1 ) * 8 - 3 429 | 4170 M = M - 15 430 | 4180 GOTO 4710 431 | 4190 PRINT "LOSE YOUR WAY IN HEAVY FOG---TIME IS LOST" 432 | 4200 M = M - 10 - 5 * RND ( 1 ) 433 | 4210 GOTO 4710 434 | 4220 PRINT "YOU KILLED A POISONOUS SNAKE AFTER IT BIT YOU" 435 | 4230 B = B - 10 436 | 4240 M1 = M1 - 5 437 | 4250 IF M1 >= 0 THEN 4280 438 | 4260 PRINT "YOU DIE OF SNAKEBITE SINCE YOU HAVE NO MEDICINE" 439 | 4270 GOTO 5170 440 | 4280 GOTO 4710 441 | 4290 PRINT "WAGON GETS SWAMPED FORDING RIVER--LOSE FOOD AND CLOTHES" 442 | 4300 F = F - 30 443 | 4310 C = C - 20 444 | 4320 M = M - 20 - 20 * RND ( 1 ) 445 | 4330 GOTO 4710 446 | 4340 PRINT "WILD ANIMALS ATTACK!" 447 | 4350 GOSUB 6140 448 | 4360 IF B > 39 THEN 4410 449 | 4370 PRINT "YOU WERE TOO LOW ON BULLETS--" 450 | 4380 PRINT "THE WOLVES OVERPOWERED YOU" 451 | 4390 K8 = 1 452 | 4400 GOTO 5120 453 | 4410 IF B1 > 2 THEN 4440 454 | 4420 PRINT "NICE SHOOTIN' PARTNER---THEY DIDN'T GET MUCH" 455 | 4430 GOTO 4450 456 | 4440 PRINT "SLOW ON THE DRAW---THEY GOT AT YOUR FOOD AND CLOTHES" 457 | 4450 B = B - 20 * B1 458 | 4460 C = C - B1 * 4 459 | 4470 F = F - B1 * 8 460 | 4480 GOTO 4710 461 | 4490 PRINT "COLD WEATHER---BRRRRRRR!---YOU " ; 462 | 4500 IF C > 22 + 4 * RND ( 1 ) THEN 4530 463 | 4510 PRINT "DON'T " ; 464 | 4520 C1 = 1 465 | 4530 PRINT "HAVE ENOUGH CLOTHING TO KEEP YOU WARM" 466 | 4540 IF C1 = 0 THEN 4710 467 | 4550 GOTO 6300 468 | 4560 PRINT "HAIL STORM---SUPPLIES DAMAGED" 469 | 4570 M = M - 5 - RND ( 1 ) * 10 470 | 4580 B = B - 200 471 | 4590 M1 = M1 - 4 - RND ( 1 ) * 3 472 | 4600 GOTO 4710 473 | 4610 IF E = 1 THEN 6300 474 | 4620 IF E = 3 THEN 4650 475 | 4630 IF RND(1) > 0.25 THEN 6300 476 | 4640 GOTO 4710 477 | 4650 IF RND(1) < 0.5 THEN 6300 478 | 4660 GOTO 4720 479 | 4670 PRINT "HELPFUL INDIANS SHOW YOU WHERE TO FIND MORE FOOD" 480 | 4680 F = F + 14 481 | 4690 GOTO 4710 482 | 4700 REM ***MOUNTAINS*** 483 | 4710 IF M <= 950 THEN 1230 484 | 4719 REM LINE 4720 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH CHIPMUNK BASIC 485 | 4720 IF RND(1)*10 > 9-(POW((M/100-15),2)+72)/(POW((M/100-15),2)+12) THEN 4860 486 | 4730 PRINT "RUGGED MOUNTAINS" 487 | 4740 IF RND(1) > 0.1 THEN 4780 488 | 4750 PRINT "YOU GOT LOST---LOSE VALUABLE TIME TRYING TO FIND TRAIL!" 489 | 4760 M = M - 60 490 | 4770 GOTO 4860 491 | 4780 IF RND(1) > 0.11 THEN 4840 492 | 4790 PRINT "WAGON DAMAGED!---LOSE TIME AND SUPPLIES" 493 | 4800 M1 = M1 - 5 494 | 4810 B = B - 200 495 | 4820 M = M - 20 - 30 * RND ( 1 ) 496 | 4830 GOTO 4860 497 | 4840 PRINT "THE GOING GETS SLOW" 498 | 4850 M = M - 45 - RND(1) / 0.02 499 | 4860 IF F1 = 1 THEN 4900 500 | 4870 F1 = 1 501 | 4880 IF RND(1) < 0.8 THEN 4970 502 | 4890 PRINT "YOU MADE IT SAFELY THROUGH SOUTH PASS--NO SNOW" 503 | 4900 IF M < 1700 THEN 4940 504 | 4910 IF F2 = 1 THEN 4940 505 | 4920 F2 = 1 506 | 4930 IF RND(1) < 0.7 THEN 4970 507 | 4940 IF M > 950 THEN 1230 508 | 4950 M9 = 1 509 | 4960 GOTO 1230 510 | 4970 PRINT "BLIZZARD IN MOUNTAIN PASS--TIME AND SUPPLIES LOST" 511 | 4980 L1 = 1 512 | 4990 F = F - 25 513 | 5000 M1 = M1 - 10 514 | 5010 B = B - 300 515 | 5020 M = M - 30 - 40 * RND ( 1 ) 516 | 5030 IF C < 18 + 2 * RND ( 1 ) THEN 6300 517 | 5040 GOTO 4940 518 | 5050 REM ***DYING*** 519 | 5060 PRINT "YOU RAN OUT OF FOOD AND STARVED TO DEATH" 520 | 5070 GOTO 5170 521 | 5080 LET T = 0 522 | 5090 PRINT "YOU CAN'T AFFORD A DOCTOR" 523 | 5100 GOTO 5120 524 | 5110 PRINT "YOU RAN OUT OF MEDICAL SUPPLIES" 525 | 5120 PRINT "YOU DIED OF " ; 526 | 5130 IF K8 = 1 THEN 5160 527 | 5140 PRINT "PNEUMONIA" 528 | 5150 GOTO 5170 529 | 5160 PRINT "INJURIES" 530 | 5170 PRINT 531 | 5180 PRINT "DUE TO YOUR UNFORTUNATE SITUATION, THERE ARE A FEW" 532 | 5190 PRINT "FORMALITIES WE MUST GO THROUGH" 533 | 5200 PRINT 534 | 5210 PRINT "WOULD YOU LIKE A MINISTER?" 535 | 5220 INPUT C$ 536 | 5230 PRINT "WOULD YOU LIKE A FANCY FUNERAL?" 537 | 5240 INPUT C$ 538 | 5250 PRINT "WOULD YOU LIKE US TO INFORM YOUR NEXT OF KIN?" 539 | 5260 INPUT C$ 540 | 5270 IF C$ = "YES" THEN 5310 541 | 5280 PRINT "BUT YOUR AUNT SADIE IN ST. LOUIS IS REALLY WORRIED ABOUT YOU" 542 | 5290 PRINT 543 | 5300 GOTO 5330 544 | 5310 PRINT "THAT WILL BE $4.50 FOR THE TELEGRAPH CHARGE." 545 | 5320 PRINT 546 | 5330 PRINT "WE THANK YOU FOR THIS INFORMATION AND WE ARE SORRY YOU" 547 | 5340 PRINT "DIDN'T MAKE IT TO THE GREAT TERRITORY OF OREGON" 548 | 5350 PRINT "BETTER LUCK NEXT TIME" 549 | 5360 PRINT 550 | 5370 PRINT 551 | 5380 PRINT TAB ( 30 ) ; "SINCERELY" 552 | 5390 PRINT 553 | 5400 PRINT TAB ( 17 ) ; "THE OREGON CITY CHAMBER OF COMMERCE" 554 | 5409 REM 'STOP' COMMAND BELOW CHANGED TO 'END' BY C.D.P. 555 | 5410 END 556 | 5420 REM ***FINAL TURN*** 557 | 5430 F9 = ( 2040 - M2 ) / ( M - M2 ) 558 | 5440 F = F + ( 1 - F9 ) * ( 8 + 5 * E ) 559 | 5450 PRINT 560 | 5460 REM **BELLS IN LINES 5470,5480** 561 | 5470 PRINT "YOU FINALLY ARRIVED AT OREGON CITY" 562 | 5480 PRINT "AFTER 2040 LONG MILES---HOORAY!!!!!" 563 | 5490 PRINT "A REAL PIONEER!" 564 | 5500 PRINT 565 | 5510 F9 = INT ( F9 * 14 ) 566 | 5520 D3 = D3 * 14 + F9 567 | 5530 F9 = F9 + 1 568 | 5540 IF F9 < 8 THEN 5560 569 | 5550 F9 = F9 - 7 570 | 5560 ON F9 GOTO 5570 , 5590 , 5610 , 5630 , 5650 , 5670 , 5690 571 | 5570 PRINT "MONDAY " ; 572 | 5580 GOTO 5700 573 | 5590 PRINT "TUESDAY " ; 574 | 5600 GOTO 5700 575 | 5610 PRINT "WEDNESDAY " ; 576 | 5620 GOTO 5700 577 | 5630 PRINT "THURSDAY " ; 578 | 5640 GOTO 5700 579 | 5650 PRINT "FRIDAY " ; 580 | 5660 GOTO 5700 581 | 5670 PRINT "SATURDAY " ; 582 | 5680 GOTO 5700 583 | 5690 PRINT "SUNDAY " ; 584 | 5700 IF D3 > 124 THEN 5740 585 | 5710 D3 = D3 - 93 586 | 5720 PRINT "JULY " ; D3 ; " 1847" 587 | 5730 GOTO 5920 588 | 5740 IF D3 > 155 THEN 5780 589 | 5750 D3 = D3 - 124 590 | 5760 PRINT "AUGUST " ; D3 ; " 1847" 591 | 5770 GOTO 5920 592 | 5780 IF D3 > 185 THEN 5820 593 | 5790 D3 = D3 - 155 594 | 5800 PRINT "SEPTEMBER " ; D3 ; " 1847" 595 | 5810 GOTO 5920 596 | 5820 IF D3 > 216 THEN 5860 597 | 5830 D3 = D3 - 185 598 | 5840 PRINT "OCTOBER " ; D3 ; " 1847" 599 | 5850 GOTO 5920 600 | 5860 IF D3 > 246 THEN 5900 601 | 5870 D3 = D3 - 216 602 | 5880 PRINT "NOVEMBER " ; D3 ; " 1847" 603 | 5890 GOTO 5920 604 | 5900 D3 = D3 - 246 605 | 5910 PRINT "DECEMBER " ; D3 ; " 1847" 606 | 5920 PRINT 607 | 5930 REM LINE 5930 REMOVED BY C.D.P. FOR COMPATIBILITY WITH MODERN BASIC 608 | 5940 IF B > 0 THEN 5960 609 | 5950 LET B = 0 610 | 5960 IF C > 0 THEN 5980 611 | 5970 LET C = 0 612 | 5980 IF M1 > 0 THEN 6000 613 | 5990 LET M1 = 0 614 | 6000 IF T > 0 THEN 6020 615 | 6010 LET T = 0 616 | 6020 IF F > 0 THEN 6040 617 | 6030 LET F = 0 618 | 6040 REM LINES 6040-6045 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH MODERN BASIC 619 | 6041 PRINT "FOOD: " ; F 620 | 6042 PRINT "BULLETS: " ; B 621 | 6043 PRINT "CLOTHING: " ; C 622 | 6044 PRINT "MISC. SUPP.: " ; M1 623 | 6045 PRINT "CASH: " ; T 624 | 6050 PRINT 625 | 6060 PRINT TAB ( 11 ) ; "PRESIDENT JAMES K. POLK SENDS YOU HIS" 626 | 6070 PRINT TAB ( 17 ) ; "HEARTIEST CONGRATULATIONS" 627 | 6080 PRINT 628 | 6090 PRINT TAB ( 11 ) ; "AND WISHES YOU A PROSPEROUS LIFE AHEAD" 629 | 6100 PRINT 630 | 6110 PRINT TAB ( 22 ) ; "AT YOUR NEW HOME" 631 | 6119 REM 'STOP' COMMAND BELOW CHANGED TO 'END' BY C.D.P. 632 | 6120 END 633 | 6130 REM ***SHOOTING SUB-ROUTINE*** 634 | 6131 REM THE METHOD OF TIMING THE SHOOTING (LINES 6210-6240) 635 | 6132 REM WILL VARY FROM SYSTEM TO SYSTEM. FOR EXAMPLE, H-P 636 | 6133 REM USERS WILL PROBABLY PREFER TO USE THE 'ENTER' STATEMENT. 637 | 6134 REM IF TIMING ON THE USER'S SYSTEM IS HIGHLY SUSCEPTIBLE 638 | 6135 REM TO SYSTEM RESPONSE TIME, THE FORMULA IN LINE 6240 CAN 639 | 6136 REM BE TAILORED TO ACCOMMODATE THIS BY EITHER INCREASING 640 | 6137 REM OR DECREASING THE 'SHOOTING' TIME RECORDED BY THE SYSTEM 641 | 6140 DIM S$ ( 5 ) 642 | 6150 S$ ( 1 ) = "BANG" 643 | 6160 S$ ( 2 ) = "BLAM" 644 | 6170 S$ ( 3 ) = "POW" 645 | 6180 S$ ( 4 ) = "WHAM" 646 | 6190 S6 = INT ( RND ( 1 ) * 4 + 1 ) 647 | 6200 PRINT "TYPE " ; S$ ( S6 ) 648 | 6201 REM NO TIMER FUNCTION IN PYBASIC, SO RANDOM ELEMENT INTRODUCED 649 | 6202 REM I'M AWARE THAT THIS CHANGES THE ELEMENT OF 'SKILL' TO 650 | 6203 REM ONE OF LUCK FOR HUNTING 651 | 6206 REM 'CLK(0)' FUNCTION CHANGED TO 'TIMER' BY C.D.P. FOR COMPATIBILITY 652 | 6207 REM B3 = TIMER changed to B3 = TIMER + 2 BY C.D.P. TO MAKE HUNTING... 653 | 6208 REM ...EASIER ON MODERN COMPUTERS. SEE NOTES FROM ORIGINAL AUTHOR ON 654 | 6209 REM ... ON TWEAKING HUNTING DIFFICULTY 655 | 6210 REM B3 = TIMER + 2 656 | 6220 INPUT C$ 657 | 6229 REM 'CLK(0)' FUNCTION CHANGED TO 'TIMER' BY C.D.P. FOR COMPATIBILITY 658 | 6230 REM B1 = TIMER 659 | 6240 REM B1 = ( ( B1 - B3 ) * 3600 ) - ( D9 - 1 ) 660 | 6244 REM IT'S A PYBASIC BODGE, BUT GENERATE RANDOM B1 661 | 6245 B1 = INT(RND(1)*9)+1 662 | 6250 PRINT 663 | 6255 IF B1 > 0 THEN 6260 664 | 6257 B1 = 0 665 | 6260 IF C$ = S$ ( S6 ) THEN 6280 666 | 6270 B1 = 9 667 | 6280 RETURN 668 | 6290 REM ***ILLNESS SUB-ROUTINE*** 669 | 6300 IF 100 * RND ( 1 ) < 10 + 35 * ( E - 1 ) THEN 6370 670 | 6309 REM LINE 6310 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH CHIPMUNK BASIC 671 | 6310 IF 100*RND(1)<100-POW(40/4,E-1) THEN 6410 672 | 6320 PRINT "SERIOUS ILLNESS---" 673 | 6330 PRINT "YOU MUST STOP FOR MEDICAL ATTENTION" 674 | 6340 M1 = M1 - 10 675 | 6350 S4 = 1 676 | 6360 GOTO 6440 677 | 6370 PRINT "WILD ILLNESS---MEDICINE USED" 678 | 6380 M = M - 5 679 | 6390 M1 = M1 - 2 680 | 6400 GOTO 6440 681 | 6410 PRINT "BAD ILLNESS---MEDICINE USED" 682 | 6420 M = M - 5 683 | 6430 M1 = M1 - 5 684 | 6440 IF M1 < 0 THEN 5110 685 | 6450 IF L1 = 1 THEN 4940 686 | 6460 GOTO 4710 687 | 6470 REM ***IDENTIFICATION OF VARIABLES IN THE PROGRAM*** 688 | 6480 REM A = AMOUNT SPENT ON ANIMALS 689 | 6490 REM B = AMOUNT SPENT ON AMMUNITION 690 | 6500 REM B1 = ACTUAL RESPONSE TIME FOR INPUTTING "BANG" 691 | 6510 REM B3 = CLOCK TIME AT START OF INPUTTING "BANG" 692 | 6520 REM C = AMOUNT SPENT ON CLOTHING 693 | 6530 REM C1 = FLAG FOR INSUFFICIENT CLOTHING IN COLD WEATHER 694 | 6540 REM C$ = YES/N0 RESPONSE TO QUESTIONS 695 | 6550 REM D1 = COUNTER IN GENERATING EVENTS 696 | 6560 REM D3 = TURN NUMBER FOR SETTING DATE 697 | 6570 REM D4 = CURRENT DATE 698 | 6580 REM D9 = CHOICE OF SHOOTING EXPERTISE LEVEL 699 | 6590 REM E = CHOICE OF EATING 700 | 6600 REM F = AMOUNT SPENT ON FOOD 701 | 6610 REM F1 = FLAG FOR CLEARING SOUTH PASS 702 | 6620 REM F2 = FLAG FOR CLEARING BLUE MOUNTAINS 703 | 6630 REM F9 = FRACTION OF 2 WEEKS TRAVELED ON FINAL TURN 704 | 6640 REM K8 = FLAG FOR INJURY 705 | 6650 REM L1 = FLAG FOR BLIZZARD 706 | 6660 REM M = TOTAL MILEAGE WHOLE TRIP 707 | 6670 REM M1 = AMOUNT SPENT ON MISCELLANEOUS SUPPLIES 708 | 6680 REM M2 = TOTAL MILEAGE UP THROUGH PREVIOUS TURN 709 | 6690 REM M9 = FLAG FOR CLEARING SOUTH PASS IN SETTING MILEAGE 710 | 6700 REM P = AMOUNT SPENT ON ITEMS AT FORT 711 | 6710 REM R1 = RANDOM NUMBER IN CHOOSING EVENTS 712 | 6720 REM S4 = FLAG FOR ILLNESS 713 | 6730 REM S5 = ""HOSTILITY OF RIDERS"" FACTOR 714 | 6740 REM S6 = SHOOTING WORD SELECTOR 715 | 6750 REM S$ = VARIATIONS OF SHOOTING WORD 716 | 6760 REM T = CASH LEFT OVER AFTER INITIAL PURCHASES 717 | 6770 REM T1 = CHOICE OF TACTICS WHEN ATTACKED 718 | 6780 REM X = CHOICE OF ACTION FOR EACH TURN 719 | 6790 REM X1 = FLAG FOR FORT OPTION 720 | 6800 END 721 | -------------------------------------------------------------------------------- /examples/regression.bas: -------------------------------------------------------------------------------- 1 | 10 REM A BASIC PROGRAM THAT CAN BE USED FOR REGRESSION TESTING 2 | 20 REM OF ALL INTERPRETER FUNCTIONALITY 3 | 30 PRINT "*** Testing basic arithmetic functions and multiple statements ***" 4 | 40 LET I = 100: LET J = 200 5 | 60 PRINT "Expecting the sum to be 300:" 6 | 70 PRINT I + J 7 | 80 PRINT "Expecting the product to be 20000:" 8 | 90 PRINT I * J 9 | 100 PRINT "Expecting the sum to be 20100:" 10 | 110 PRINT 100 + I * J 11 | 120 PRINT "Expecting sum to be 40000" 12 | 130 PRINT (100 + I) * J 13 | 140 IF I > J THEN 150 ELSE 180 14 | 150 PRINT "Should not print the smaller value of I which is "; I 15 | 160 PRINT I 16 | 170 GOTO 180 17 | 180 PRINT "Should print the larger value of J which is "; J 18 | 190 PRINT J 19 | 200 GOTO 220 20 | 210 PRINT "Should not print this line" 21 | 220 PRINT "*** Testing subroutine behaviour ***" 22 | 230 PRINT "Calling subroutine" 23 | 240 GOSUB 1630 24 | 250 PRINT "Exited subroutine" 25 | 260 PRINT "Now testing nested subroutines" 26 | 270 GOSUB 1660 27 | 280 PRINT "*** Testing loops ***" 28 | 290 PRINT "This loop should count to 5 in increments of 1:" 29 | 300 FOR I = 1 TO 5 30 | 310 PRINT I 31 | 320 NEXT I 32 | 330 PRINT "This loop should count back from 10 to 1 in decrements of 2:" 33 | 340 FOR I = 10 TO 1 STEP -2 34 | 350 PRINT I 35 | 360 NEXT I 36 | 370 PRINT "These nested loops should print 11, 12, 13, 21, 22, 23:" 37 | 380 FOR I = 1 TO 2 38 | 390 FOR J = 1 TO 3 39 | 400 PRINT I; J 40 | 410 NEXT J 41 | 420 NEXT I 42 | 430 PRINT "*** Testing arrays ***" 43 | 440 DIM A(3, 3) 44 | 450 FOR I = 0 TO 2 45 | 460 FOR J = 0 TO 2 46 | 470 LET A(I, J) = 5 47 | 480 NEXT J 48 | 490 NEXT I 49 | 500 PRINT "This should print 555" 50 | 510 PRINT A(0, 0); A(1, 1); A(2, 2) 51 | 520 PRINT "*** Testing file i/o ***" 52 | 530 OPEN "REGRESSION.TXT" FOR OUTPUT AS #1 53 | 540 PRINT #1,"0123456789Hello World!" 54 | 545 PRINT #1,"This is second line for testing" 55 | 550 CLOSE #1 56 | 560 OPEN "REGRESSION.TXT" FOR INPUT AS #2 57 | 570 PRINT "The next line should say 'Hello World!'" 58 | 580 FSEEK #2,10 59 | 590 INPUT #2,A$ 60 | 595 PRINT A$ 61 | 600 CLOSE #2 62 | 601 OPEN "REGRESSION.TXT" FOR APPEND AS #2 63 | 602 PRINT "3 text lines starting with 0,T,S and ending with !,g,e should follow:" 64 | 603 PRINT #2,"Should be a seperate line" 65 | 604 CLOSE #2 66 | 605 OPEN "REGRESSION.TXT" FOR INPUT AS #2 67 | 606 FOR I = 1 TO 2 68 | 607 INPUT #2,A$:PRINT A$ 69 | 608 NEXT I 70 | 609 INPUT #2,A$ 71 | 610 FOR I = 1 TO 25 72 | 611 PRINT MID$(A$,I,1); 73 | 612 NEXT I 74 | 613 PRINT:CLOSE #2 75 | 614 OPEN "NOFILE.X7Z" FOR INPUT AS #2 ELSE 620 76 | 615 PRINT "***This Message should NOT be Displayed***" 77 | 620 N = 0 78 | 630 I = 7 79 | 640 PRINT "This loop should count to 5 in increments of 1 twice:" 80 | 650 FOR I = 1 TO 10 81 | 660 PRINT I 82 | 670 IF I = 5 THEN GOTO 690 83 | 680 NEXT I 84 | 690 N = N + 1 85 | 700 IF N < 2 THEN GOTO 650 86 | 810 PRINT "The loop variable I should be equal to 5, I=";I 87 | 815 DATA "DATA Statement tests..." 88 | 820 READ A$ 89 | 825 PRINT "The next line should read: DATA Statement tests..." 90 | 830 PRINT A$ 91 | 840 DATA 1 , 2 , 3 92 | 850 DATA 4 , 5 , 6 93 | 855 DATA 1.5 , 2 , "test" 94 | 858 PRINT "The next three lines should be: 12 34 56" 95 | 860 FOR I = 1 TO 3 96 | 870 READ J , K 97 | 880 PRINT J ; K 98 | 890 NEXT I 99 | 900 RESTORE 840 100 | 910 READ I , J , K 101 | 920 PRINT "the next line should print 123" 102 | 930 PRINT I ; J ; K 103 | 970 RESTORE 855 104 | 980 READ A1 , B , C$ 105 | 990 PRINT "Float: " ; A1 ; " Int: " ; B ; " String: " ; C$ 106 | 1000 RESTORE 850 107 | 1010 READ I , J , K , L 108 | 1020 PRINT "the next line should print 4561.5:" 109 | 1030 PRINT I; J ; K ; L 110 | 1040 PRINT "The next lines should print: 'Hello World' and then 'AGAIN' under the word 'World'" 111 | 1050 PRINT "Hel" ; : PRINT "lo" ; TAB ( 7 ) ; "World" ; TAB ( 7 ) ; "AGAIN" 112 | 1060 PRINT "This loop should count from 1 to 10" 113 | 1070 FOR I = 1 TO 10 114 | 1080 FOR J = 1 TO 3 115 | 1090 PRINT I 116 | 1100 GOTO 1130 117 | 1120 NEXT J 118 | 1130 NEXT I 119 | 1140 INPUT "Enter T for the THEN blocks to execute, E for the ELSE (T/E): " ; ANS$ 120 | 1150 ANS$ = UPPER$ ( ANS$ ) 121 | 1160 IF ANS$ = "T" THEN 1190 122 | 1170 PRINT "1170: Did not enter T" 123 | 1180 GOTO 1200 124 | 1190 PRINT "1190: Entered T" 125 | 1200 IF ANS$ = "T" THEN GOTO 1230 126 | 1210 PRINT "1210: Did not enter T" 127 | 1220 GOTO 1240 128 | 1230 PRINT "1230: Entered T" 129 | 1240 IF ANS$ = "T" THEN 1280 ELSE 1260 130 | 1250 PRINT "ERROR - Should not be at line 1250" 131 | 1260 PRINT "1260: Did not enter T" 132 | 1270 GOTO 1290 133 | 1280 PRINT "1280: Entered T" 134 | 1290 IF ANS$ = "T" THEN GOTO 1330 ELSE GOTO 1310 135 | 1300 PRINT "ERROR - Should not be at line 1300" 136 | 1310 PRINT "1310: Did not enter T" 137 | 1320 GOTO 1340 138 | 1330 PRINT "1330: Entered T" 139 | 1340 IF ANS$ = "T" THEN PRINT "1340: Entered T" 140 | 1350 IF ANS$ <> "T" THEN PRINT "1350: Did not enter T" 141 | 1360 IF ANS$ = "T" THEN PRINT "1360: Entered T" ELSE PRINT "1360: Did not enter T" 142 | 1370 IF ANS$ = "T" THEN PRINT "1370: Entered T" : GOTO 1390 143 | 1380 IF ANS$ <> "T" THEN PRINT "1380: Did not enter T" 144 | 1390 IF ANS$ = "T" THEN PRINT "1390: Entered " ; : PRINT "T" ELSE PRINT "1390: Did " ; : PRINT "not enter T" 145 | 1400 IF ANS$ = "T" THEN PRINT "1400: Entered T" ELSE PRINT "1400: Did " ; : PRINT "not enter T" 146 | 1410 IF ANS$ = "T" THEN PRINT "1410: Entered " ; : PRINT "T" ELSE PRINT "1410: Did not enter T" 147 | 1420 PRINT "Compound Stmt w/conditionals ";:IF ANS$ = "T" THEN PRINT "1420: Entered " ; : PRINT "T" ELSE PRINT "1420: Did " ; : PRINT "not enter T" 148 | 1610 PRINT "*** Finished ***" 149 | 1620 STOP 150 | 1630 REM A SUBROUTINE TEST 151 | 1640 PRINT "Executing the subroutine" 152 | 1650 RETURN 153 | 1660 REM AN OUTER SUBROUTINE 154 | 1670 GOSUB 1700 155 | 1680 PRINT "This should be printed second" 156 | 1690 RETURN 157 | 1700 REM A NESTED SUBROUTINE 158 | 1710 PRINT "This should be printed first" 159 | 1720 RETURN 160 | -------------------------------------------------------------------------------- /examples/rock_scissors_paper.bas: -------------------------------------------------------------------------------- 1 | 10 REM ROCK, SCISSORS, PAPER AGAINST 2 | 20 REM THE COMPUTER 3 | 30 RANDOMIZE 4 | 40 MYSCORE = 0 5 | 50 YOURSCORE = 0 6 | 60 PRINT "Let's play rock-scissors-paper!" 7 | 70 INPUT "(R)ock, (S)cissors, (P)aper or e(X)it: "; YOURGUESS$ 8 | 75 IF YOURGUESS$ = "X" THEN 160 9 | 80 RANDOM = RND(1) 10 | 90 GOSUB 190 11 | 100 PRINT "Your guess: "; YOURGUESS$; ", My guess: "; MYGUESS$ 12 | 110 REM ON YOURGUESS$ = "R" GOSUB 300 13 | 120 REM ON YOURGUESS$ = "S" GOSUB 500 14 | 130 REM ON YOURGUESS$ = "P" GOSUB 700 15 | 135 ON INSTR("RSP",YOURGUESS$) GOSUB 300,500,700 16 | 150 GOTO 70 17 | 160 PRINT "My score: "; MYSCORE; " Your score: "; YOURSCORE 18 | 170 STOP 19 | 190 REM RANDOMLY ASSIGN MYGUESS$ 20 | 200 IF RANDOM < 0.3 THEN 210 ELSE 230 21 | 210 MYGUESS$ = "R" 22 | 220 RETURN 23 | 230 IF RANDOM < 0.6 THEN 240 ELSE 260 24 | 240 MYGUESS$ = "S" 25 | 250 RETURN 26 | 260 MYGUESS$ = "P" 27 | 270 RETURN 28 | 300 REM ROCK 29 | 310 IF MYGUESS$ = "R" THEN 320 ELSE 340 30 | 320 PRINT "A draw!" 31 | 330 RETURN 32 | 340 IF MYGUESS$ = "S" THEN 350 ELSE 380 33 | 350 PRINT "I lost!" 34 | 360 YOURSCORE = YOURSCORE + 1 35 | 370 RETURN 36 | 380 IF MYGUESS$ = "P" THEN 390 ELSE 410 37 | 390 PRINT "I won!" 38 | 400 MYSCORE = MYSCORE + 1 39 | 410 RETURN 40 | 500 REM SCISSORS 41 | 510 IF MYGUESS$ = "S" THEN 520 ELSE 540 42 | 520 PRINT "A draw!" 43 | 530 RETURN 44 | 540 IF MYGUESS$ = "P" THEN 550 ELSE 580 45 | 550 PRINT "I lost!" 46 | 560 YOURSCORE = YOURSCORE + 1 47 | 570 RETURN 48 | 580 IF MYGUESS$ = "R" THEN 390 ELSE 410 49 | 590 PRINT "I won!" 50 | 600 MYSCORE = MYSCORE + 1 51 | 610 RETURN 52 | 700 REM PAPER 53 | 710 IF MYGUESS$ = "P" THEN 720 ELSE 740 54 | 720 PRINT "A draw!" 55 | 730 RETURN 56 | 740 IF MYGUESS$ = "R" THEN 750 ELSE 780 57 | 750 PRINT "I lost!" 58 | 760 YOURSCORE = YOURSCORE + 1 59 | 770 RETURN 60 | 780 IF MYGUESS$ = "S" THEN 790 ELSE 810 61 | 790 PRINT "I won!" 62 | 800 MYSCORE = MYSCORE + 1 63 | 810 RETURN 64 | -------------------------------------------------------------------------------- /flowsignal.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """This class defines an object that can be returned by the BASICParser to 19 | indicate the need for a control flow branch. The information within the 20 | object tells the Program the nature of the jump and therefore whether a 21 | return address need to be added to the return stack. 22 | 23 | >>> flowsignal = FlowSignal(ftype=FlowSignal.RETURN) 24 | >>> print(flowsignal.ftarget) 25 | -1 26 | >>> flowsignal = FlowSignal(ftarget=100, ftype=FlowSignal.SIMPLE_JUMP) 27 | >>> print(flowsignal.ftarget) 28 | 100 29 | >>> print(flowsignal.ftype) 30 | 0 31 | """ 32 | 33 | 34 | class FlowSignal: 35 | 36 | # Jump categories 37 | 38 | # Indicates a simple jump as the result 39 | # of a GOTO or conditional branch. The 40 | # ftarget value should be the jump target, i.e. 41 | # the line number being jumped to 42 | SIMPLE_JUMP = 0 43 | 44 | # Indicates a subroutine call where the 45 | # return address must be the line number of the instruction 46 | # of the following the call. 47 | # The ftarget value should be the line number of the first line 48 | # of the subroutine 49 | GOSUB = 1 50 | 51 | # Indicates the start of a FOR loop where loop 52 | # variable has not reached the end value, and therefore the loop 53 | # must be repeated. There should be therefore be 54 | # no ftarget value associated with it 55 | LOOP_BEGIN = 2 56 | 57 | # An indication from a processed NEXT statement that the loop is to 58 | # be repeated. Since the return address is already on the stack, 59 | # there does not need to be an ftarget value associated with the signal. 60 | LOOP_REPEAT = 3 61 | 62 | # An indication from a FOR statement that the loop should be skipped because 63 | # loop variable has reached its end value. The ftarget should be 64 | # the loop variable to look for in the terminating NEXT statement 65 | LOOP_SKIP = 4 66 | 67 | # Indicates a subroutine return has been processed, where the return 68 | # address is on the return stack. There should be therefore 69 | # be no ftarget value specified 70 | RETURN = 5 71 | 72 | # Indicates that execution should cease because a stop statement has 73 | # been processed. There should be therefore be no ftarget value specified 74 | STOP = 6 75 | 76 | # Indicates that a conditional result block should be executed 77 | EXECUTE = 7 78 | 79 | def __init__(self, ftarget=None, ftype=SIMPLE_JUMP, floop_var=None): 80 | """Creates a new FlowSignal for a branch. If the jump 81 | target is supplied, then the branch is assumed to be 82 | either a GOTO or conditional branch and the type is assigned as 83 | SIMPLE_JUMP. If no jump_target is supplied, then a jump_type must be 84 | supplied, which must either be GOSUB, RETURN, LOOP_BEGIN, 85 | LOOP_REPEAT, LOOP_SKIP or STOP. In the latter cases 86 | the jump target is assigned an arbitrary value of None. 87 | 88 | :param ftarget: The associated value 89 | :param ftype: Either GOSUB, SIMPLE_JUMP, RETURN, LOOP_BEGIN, 90 | LOOP_SKIP or STOP 91 | :param floop_var: The loop variable of a FOR/NEXT loop 92 | """ 93 | 94 | if ftype not in [self.GOSUB, self.SIMPLE_JUMP, self.LOOP_BEGIN, 95 | self.LOOP_REPEAT, self.RETURN, 96 | self.LOOP_SKIP, self.STOP, self.EXECUTE]: 97 | raise TypeError("Invalid flow signal type supplied: " + str(ftype)) 98 | 99 | if ftarget == None and \ 100 | ftype in [self.SIMPLE_JUMP, self.GOSUB, self.LOOP_SKIP]: 101 | raise TypeError("Invalid jump target supplied for flow signal type: " + str(ftarget)) 102 | 103 | if ftarget != None and \ 104 | ftype in [self.RETURN, self.LOOP_BEGIN, self.LOOP_REPEAT, 105 | self.STOP, self.EXECUTE]: 106 | raise TypeError("Target wrongly supplied for flow signal " + str(ftype)) 107 | 108 | self.ftype = ftype 109 | self.ftarget = ftarget 110 | self.floop_var = floop_var -------------------------------------------------------------------------------- /interpreter.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """This class implements a BASIC interpreter that 19 | presents a prompt to the user. The user may input 20 | program statements, list them and run the program. 21 | The program may also be saved to disk and loaded 22 | again. 23 | 24 | """ 25 | 26 | from basictoken import BASICToken as Token 27 | from lexer import Lexer 28 | from program import Program 29 | from sys import stderr 30 | 31 | 32 | def main(): 33 | 34 | banner = (r""" 35 | ._____________ ___________. ___ ___________ ______ 36 | | _ .__ \ / ___ _ \ / \ / | / | 37 | | |_) | \ \/ / | |_) | / ^ \ | (----`| | | ,----' 38 | | ___/ \_ _/ | _ < / /_\ \ \ \ | | | | 39 | | | | | | |_) \/ _____ \----) | | | | `----. 40 | | _| |__| |___________/ \_________/ |____________| 41 | """) 42 | 43 | print(banner) 44 | 45 | lexer = Lexer() 46 | program = Program() 47 | 48 | # Continuously accept user input and act on it until 49 | # the user enters 'EXIT' 50 | while True: 51 | 52 | stmt = input('> ') 53 | 54 | try: 55 | tokenlist = lexer.tokenize(stmt) 56 | 57 | # Execute commands directly, otherwise 58 | # add program statements to the stored 59 | # BASIC program 60 | 61 | if len(tokenlist) > 0: 62 | 63 | # Exit the interpreter 64 | if tokenlist[0].category == Token.EXIT: 65 | break 66 | 67 | # Add a new program statement, beginning 68 | # a line number 69 | elif tokenlist[0].category == Token.UNSIGNEDINT\ 70 | and len(tokenlist) > 1: 71 | program.add_stmt(tokenlist) 72 | 73 | # Delete a statement from the program 74 | elif tokenlist[0].category == Token.UNSIGNEDINT \ 75 | and len(tokenlist) == 1: 76 | program.delete_statement(int(tokenlist[0].lexeme)) 77 | 78 | # Execute the program 79 | elif tokenlist[0].category == Token.RUN: 80 | try: 81 | program.execute() 82 | 83 | except KeyboardInterrupt: 84 | print("Program terminated") 85 | 86 | # List the program 87 | elif tokenlist[0].category == Token.LIST: 88 | if len(tokenlist) == 2: 89 | program.list(int(tokenlist[1].lexeme),int(tokenlist[1].lexeme)) 90 | elif len(tokenlist) == 3: 91 | # if we have 3 tokens, it might be LIST x y for a range 92 | # or LIST -y or list x- for a start to y, or x to end 93 | if tokenlist[1].lexeme == "-": 94 | program.list(None, int(tokenlist[2].lexeme)) 95 | elif tokenlist[2].lexeme == "-": 96 | program.list(int(tokenlist[1].lexeme), None) 97 | else: 98 | program.list(int(tokenlist[1].lexeme),int(tokenlist[2].lexeme)) 99 | elif len(tokenlist) == 4: 100 | # if we have 4, assume LIST x-y or some other 101 | # delimiter for a range 102 | program.list(int(tokenlist[1].lexeme),int(tokenlist[3].lexeme)) 103 | else: 104 | program.list() 105 | 106 | # Save the program to disk 107 | elif tokenlist[0].category == Token.SAVE: 108 | program.save(tokenlist[1].lexeme) 109 | print("Program written to file") 110 | 111 | # Load the program from disk 112 | elif tokenlist[0].category == Token.LOAD: 113 | program.load(tokenlist[1].lexeme) 114 | print("Program read from file") 115 | 116 | # Delete the program from memory 117 | elif tokenlist[0].category == Token.NEW: 118 | program.delete() 119 | 120 | # Unrecognised input 121 | else: 122 | print("Unrecognised input", file=stderr) 123 | for token in tokenlist: 124 | token.print_lexeme() 125 | print(flush=True) 126 | 127 | # Trap all exceptions so that interpreter 128 | # keeps running 129 | except Exception as e: 130 | print(e, file=stderr, flush=True) 131 | 132 | 133 | if __name__ == "__main__": 134 | main() 135 | -------------------------------------------------------------------------------- /lexer.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """This class implements a lexical analyser capable 19 | of consuming BASIC statements and commands and returning 20 | a corresponding list of tokens. 21 | 22 | >>> lexer = Lexer() 23 | >>> tokenlist = lexer.tokenize('100 LET I = 10') 24 | >>> tokenlist[0].pretty_print() 25 | Column: 0 Category: UNSIGNEDINT Lexeme: 100 26 | >>> tokenlist = lexer.tokenize('100 IF I <> 10') 27 | >>> tokenlist[3].pretty_print() 28 | Column: 9 Category: NOTEQUAL Lexeme: <> 29 | >>> tokenlist = lexer.tokenize('100 LET I = 3.45') 30 | >>> tokenlist[4].pretty_print() 31 | Column: 12 Category: UNSIGNEDFLOAT Lexeme: 3.45 32 | >>> tokenlist = lexer.tokenize('100 LET I = "HELLO"') 33 | >>> tokenlist[4].pretty_print() 34 | Column: 12 Category: STRING Lexeme: HELLO 35 | """ 36 | 37 | from basictoken import BASICToken as Token 38 | 39 | 40 | class Lexer: 41 | 42 | def __init__(self): 43 | 44 | self.__column = 0 # Current column number 45 | self.__stmt = '' # Statement string being processed 46 | 47 | def tokenize(self, stmt): 48 | """Returns a list of tokens obtained by 49 | lexical analysis of the specified 50 | statement. 51 | 52 | """ 53 | self.__stmt = stmt 54 | self.__column = 0 55 | 56 | # Establish a list of tokens to be 57 | # derived from the statement 58 | tokenlist = [] 59 | 60 | # Process every character until we 61 | # reach the end of the statement string 62 | c = self.__get_next_char() 63 | while c != '': 64 | 65 | # Skip any preceding whitespace 66 | while c.isspace(): 67 | c = self.__get_next_char() 68 | 69 | # Construct a token, column count already 70 | # incremented 71 | token = Token(self.__column - 1, None, '') 72 | 73 | # Process strings 74 | if c == '"': 75 | token.category = Token.STRING 76 | 77 | # Consume all of the characters 78 | # until we reach the terminating 79 | # quote. Do not store the quotes 80 | # in the lexeme 81 | c = self.__get_next_char() # Advance past opening quote 82 | 83 | # We explicitly support empty strings 84 | if c == '"': 85 | # String is empty, leave lexeme as '' 86 | # and advance past terminating quote 87 | c = self.__get_next_char() 88 | 89 | else: 90 | while True: 91 | token.lexeme += c # Append the current char to the lexeme 92 | c = self.__get_next_char() 93 | 94 | if c == '': 95 | raise SyntaxError("Mismatched quotes") 96 | 97 | if c == '"': 98 | c = self.__get_next_char() # Advance past terminating quote 99 | break 100 | 101 | # Process numbers 102 | elif c.isdigit() or c == '.': 103 | token.category = Token.UNSIGNEDINT 104 | found_point = False 105 | if c == '.': 106 | token.category = Token.UNSIGNEDFLOAT 107 | found_point = True 108 | 109 | # Consume all of the digits, including any decimal point 110 | while True: 111 | token.lexeme += c # Append the current char to the lexeme 112 | c = self.__get_next_char() 113 | 114 | # Break if next character is not a digit 115 | # and this is not the first decimal point 116 | if not c.isdigit(): 117 | if c == '.': 118 | if found_point is False: 119 | found_point = True 120 | token.category = Token.UNSIGNEDFLOAT 121 | 122 | else: 123 | # Another decimal point found 124 | break 125 | 126 | else: 127 | break 128 | 129 | # Process keywords and names 130 | elif c.isalpha(): 131 | # Consume all of the letters 132 | while True: 133 | token.lexeme += c # append the current char to the lexeme 134 | c = self.__get_next_char() 135 | 136 | # Break if not a letter or a dollar symbol 137 | # (the latter is used for string variable names) 138 | if not ((c.isalpha() or c.isdigit()) or c == '_' or c == '$'): 139 | break 140 | 141 | # Normalise keywords and names to upper case 142 | token.lexeme = token.lexeme.upper() 143 | 144 | # Determine if the lexeme is a variable name or a 145 | # reserved word 146 | if token.lexeme in Token.keywords: 147 | token.category = Token.keywords[token.lexeme] 148 | 149 | else: 150 | token.category = Token.NAME 151 | 152 | # Remark Statements - process rest of statement without checks 153 | if token.lexeme == "REM": 154 | while c!= '': 155 | token.lexeme += c # Append the current char to the lexeme 156 | c = self.__get_next_char() 157 | 158 | # Process operator symbols 159 | elif c in Token.smalltokens: 160 | save = c 161 | c = self.__get_next_char() # c might be '' (end of stmt) 162 | twochar = save + c 163 | 164 | if twochar in Token.smalltokens: 165 | token.category = Token.smalltokens[twochar] 166 | token.lexeme = twochar 167 | c = self.__get_next_char() # Move past end of token 168 | 169 | else: 170 | # One char token 171 | token.category = Token.smalltokens[save] 172 | token.lexeme = save 173 | 174 | # We do not recognise this token 175 | elif c != '': 176 | raise SyntaxError('Syntax error') 177 | 178 | # Append the new token to the list 179 | tokenlist.append(token) 180 | 181 | return tokenlist 182 | 183 | def __get_next_char(self): 184 | """Returns the next character in the 185 | statement, unless the last character has already 186 | been processed, in which case, the empty string is 187 | returned. 188 | 189 | """ 190 | if self.__column < len(self.__stmt): 191 | next_char = self.__stmt[self.__column] 192 | self.__column = self.__column + 1 193 | 194 | return next_char 195 | 196 | else: 197 | return '' 198 | 199 | 200 | if __name__ == "__main__": 201 | import doctest 202 | doctest.testmod() -------------------------------------------------------------------------------- /program.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | # SPDX-License-Identifier: GPL-3.0-or-later 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """Class representing a BASIC program. 19 | This is a list of statements, ordered by 20 | line number. 21 | 22 | """ 23 | 24 | from basictoken import BASICToken as Token 25 | from basicparser import BASICParser 26 | from flowsignal import FlowSignal 27 | from lexer import Lexer 28 | 29 | 30 | class BASICData: 31 | 32 | def __init__(self): 33 | # array of line numbers to represent data statements 34 | self.__datastmts = {} 35 | 36 | # Data pointer 37 | self.__next_data = 0 38 | 39 | 40 | def delete(self): 41 | self.__datastmts.clear() 42 | self.__next_data = 0 43 | 44 | def delData(self,line_number): 45 | if self.__datastmts.get(line_number) != None: 46 | del self.__datastmts[line_number] 47 | 48 | def addData(self,line_number,tokenlist): 49 | """ 50 | Adds the supplied token list 51 | to the program's DATA store. If a token list with the 52 | same line number already exists, this is 53 | replaced. 54 | 55 | line_number: Basic program line number of DATA statement 56 | 57 | """ 58 | 59 | try: 60 | self.__datastmts[line_number] = tokenlist 61 | 62 | except TypeError as err: 63 | raise TypeError("Invalid line number: " + str(err)) 64 | 65 | 66 | def getTokens(self,line_number): 67 | """ 68 | returns the tokens from the program DATA statement 69 | 70 | line_number: Basic program line number of DATA statement 71 | 72 | """ 73 | 74 | return self.__datastmts.get(line_number) 75 | 76 | def readData(self,read_line_number): 77 | 78 | if len(self.__datastmts) == 0: 79 | raise RuntimeError('No DATA statements available to READ ' + 80 | 'in line ' + str(read_line_number)) 81 | 82 | data_values = [] 83 | 84 | line_numbers = list(self.__datastmts.keys()) 85 | line_numbers.sort() 86 | 87 | if self.__next_data == 0: 88 | self.__next_data = line_numbers[0] 89 | elif line_numbers.index(self.__next_data) < len(line_numbers)-1: 90 | self.__next_data = line_numbers[line_numbers.index(self.__next_data)+1] 91 | else: 92 | raise RuntimeError('No DATA statements available to READ ' + 93 | 'in line ' + str(read_line_number)) 94 | 95 | tokenlist = self.__datastmts[self.__next_data] 96 | 97 | sign = 1 98 | for token in tokenlist[1:]: 99 | if token.category != Token.COMMA: 100 | #data_values.append(token.lexeme) 101 | 102 | if token.category == Token.STRING: 103 | data_values.append(token.lexeme) 104 | elif token.category == Token.UNSIGNEDINT: 105 | data_values.append(sign*int(token.lexeme)) 106 | elif token.category == Token.UNSIGNEDFLOAT: 107 | data_values.append(sign*eval(token.lexeme)) 108 | elif token.category == Token.MINUS: 109 | sign = -1 110 | #else: 111 | #data_values.append(token.lexeme) 112 | else: 113 | sign = 1 114 | 115 | 116 | return data_values 117 | 118 | def restore(self,restoreLineNo): 119 | if restoreLineNo == 0 or restoreLineNo in self.__datastmts: 120 | 121 | if restoreLineNo == 0: 122 | self.__next_data = restoreLineNo 123 | else: 124 | 125 | line_numbers = list(self.__datastmts.keys()) 126 | line_numbers.sort() 127 | 128 | indexln = line_numbers.index(restoreLineNo) 129 | 130 | if indexln == 0: 131 | self.__next_data = 0 132 | else: 133 | self.__next_data = line_numbers[indexln-1] 134 | else: 135 | raise RuntimeError('Attempt to RESTORE but no DATA ' + 136 | 'statement at line ' + str(restoreLineNo)) 137 | 138 | 139 | class Program: 140 | 141 | def __init__(self): 142 | # Dictionary to represent program 143 | # statements, keyed by line number 144 | self.__program = {} 145 | 146 | # Program counter 147 | self.__next_stmt = 0 148 | 149 | # Initialise return stack for subroutine returns 150 | self.__return_stack = [] 151 | 152 | # return dictionary for loop returns 153 | self.__return_loop = {} 154 | 155 | # Setup DATA object 156 | self.__data = BASICData() 157 | 158 | def __str__(self): 159 | 160 | program_text = "" 161 | line_numbers = self.line_numbers() 162 | 163 | for line_number in line_numbers: 164 | program_text += self.str_statement(line_number) 165 | 166 | return program_text 167 | 168 | def str_statement(self, line_number): 169 | line_text = str(line_number) + " " 170 | 171 | statement = self.__program[line_number] 172 | if statement[0].category == Token.DATA: 173 | statement = self.__data.getTokens(line_number) 174 | for token in statement: 175 | # Add in quotes for strings 176 | if token.category == Token.STRING: 177 | line_text += '"' + token.lexeme + '" ' 178 | 179 | else: 180 | line_text += token.lexeme + " " 181 | line_text += "\n" 182 | return line_text 183 | 184 | def list(self, start_line=None, end_line=None): 185 | """Lists the program""" 186 | line_numbers = self.line_numbers() 187 | if not start_line: 188 | start_line = int(line_numbers[0]) 189 | 190 | if not end_line: 191 | end_line = int(line_numbers[-1]) 192 | 193 | for line_number in line_numbers: 194 | if int(line_number) >= start_line and int(line_number) <= end_line: 195 | print(self.str_statement(line_number), end="") 196 | 197 | def save(self, file): 198 | """Save the program 199 | 200 | :param file: The name and path of the save file, .bas is 201 | appended 202 | 203 | """ 204 | if not file.lower().endswith(".bas"): 205 | file += ".bas" 206 | try: 207 | with open(file, "w") as outfile: 208 | outfile.write(str(self)) 209 | except OSError: 210 | raise OSError("Could not save to file") 211 | 212 | def load(self, file): 213 | """Load the program 214 | 215 | :param file: The name and path of the file to be loaded, .bas is 216 | appended 217 | 218 | """ 219 | 220 | # New out the program 221 | self.delete() 222 | if not file.lower().endswith(".bas"): 223 | file += ".bas" 224 | try: 225 | lexer = Lexer() 226 | with open(file, "r") as infile: 227 | for line in infile: 228 | line = line.replace("\r", "").replace("\n", "").strip() 229 | tokenlist = lexer.tokenize(line) 230 | self.add_stmt(tokenlist) 231 | 232 | except OSError: 233 | raise OSError("Could not read file") 234 | 235 | def add_stmt(self, tokenlist): 236 | """ 237 | Adds the supplied token list 238 | to the program. The first token should 239 | be the line number. If a token list with the 240 | same line number already exists, this is 241 | replaced. 242 | 243 | :param tokenlist: List of BTokens representing a 244 | numbered program statement 245 | 246 | """ 247 | if len(tokenlist) > 0: 248 | try: 249 | line_number = int(tokenlist[0].lexeme) 250 | if tokenlist[1].lexeme == "DATA": 251 | self.__data.addData(line_number,tokenlist[1:]) 252 | self.__program[line_number] = [tokenlist[1],] 253 | else: 254 | self.__program[line_number] = tokenlist[1:] 255 | 256 | except TypeError as err: 257 | raise TypeError("Invalid line number: " + 258 | str(err)) 259 | 260 | def line_numbers(self): 261 | """Returns a list of all the 262 | line numbers for the program, 263 | sorted 264 | 265 | :return: A sorted list of 266 | program line numbers 267 | """ 268 | line_numbers = list(self.__program.keys()) 269 | line_numbers.sort() 270 | 271 | return line_numbers 272 | 273 | def __execute(self, line_number): 274 | """Execute the statement with the 275 | specified line number 276 | 277 | :param line_number: The line number 278 | 279 | :return: The FlowSignal to indicate to the program 280 | how to branch if necessary, None otherwise 281 | 282 | """ 283 | if line_number not in self.__program.keys(): 284 | raise RuntimeError("Line number " + line_number + 285 | " does not exist") 286 | 287 | statement = self.__program[line_number] 288 | 289 | try: 290 | return self.__parser.parse(statement, line_number) 291 | 292 | except RuntimeError as err: 293 | raise RuntimeError(str(err)) 294 | 295 | def execute(self): 296 | """Execute the program""" 297 | 298 | self.__parser = BASICParser(self.__data) 299 | self.__data.restore(0) # reset data pointer 300 | 301 | line_numbers = self.line_numbers() 302 | 303 | if len(line_numbers) > 0: 304 | # Set up an index into the ordered list 305 | # of line numbers that can be used for 306 | # sequential statement execution. The index 307 | # will be incremented by one, unless modified by 308 | # a jump 309 | index = 0 310 | self.set_next_line_number(line_numbers[index]) 311 | 312 | # Run through the program until the 313 | # has line number has been reached 314 | while True: 315 | flowsignal = self.__execute(self.get_next_line_number()) 316 | self.__parser.last_flowsignal = flowsignal 317 | 318 | if flowsignal: 319 | if flowsignal.ftype == FlowSignal.SIMPLE_JUMP: 320 | # GOTO or conditional branch encountered 321 | try: 322 | index = line_numbers.index(flowsignal.ftarget) 323 | 324 | except ValueError: 325 | raise RuntimeError("Invalid line number supplied in GOTO or conditional branch: " 326 | + str(flowsignal.ftarget)) 327 | 328 | self.set_next_line_number(flowsignal.ftarget) 329 | 330 | elif flowsignal.ftype == FlowSignal.GOSUB: 331 | # Subroutine call encountered 332 | # Add line number of next instruction to 333 | # the return stack 334 | if index + 1 < len(line_numbers): 335 | self.__return_stack.append(line_numbers[index + 1]) 336 | 337 | else: 338 | raise RuntimeError("GOSUB at end of program, nowhere to return") 339 | 340 | # Set the index to be the subroutine start line 341 | # number 342 | try: 343 | index = line_numbers.index(flowsignal.ftarget) 344 | 345 | except ValueError: 346 | raise RuntimeError("Invalid line number supplied in subroutine call: " 347 | + str(flowsignal.ftarget)) 348 | 349 | self.set_next_line_number(flowsignal.ftarget) 350 | 351 | elif flowsignal.ftype == FlowSignal.RETURN: 352 | # Subroutine return encountered 353 | # Pop return address from the stack 354 | try: 355 | index = line_numbers.index(self.__return_stack.pop()) 356 | 357 | except ValueError: 358 | raise RuntimeError("Invalid subroutine return in line " + 359 | str(self.get_next_line_number())) 360 | 361 | except IndexError: 362 | raise RuntimeError("RETURN encountered without corresponding " + 363 | "subroutine call in line " + str(self.get_next_line_number())) 364 | 365 | self.set_next_line_number(line_numbers[index]) 366 | 367 | elif flowsignal.ftype == FlowSignal.STOP: 368 | break 369 | 370 | elif flowsignal.ftype == FlowSignal.LOOP_BEGIN: 371 | # Loop start encountered 372 | # Put loop line number on the stack so 373 | # that it can be returned to when the loop 374 | # repeats 375 | self.__return_loop[flowsignal.floop_var] = line_numbers[index] 376 | 377 | # Continue to the next statement in the loop 378 | index = index + 1 379 | 380 | if index < len(line_numbers): 381 | self.set_next_line_number(line_numbers[index]) 382 | 383 | else: 384 | # Reached end of program 385 | raise RuntimeError("Program terminated within a loop") 386 | 387 | elif flowsignal.ftype == FlowSignal.LOOP_SKIP: 388 | # Loop variable has reached end value, so ignore 389 | # all statements within loop and move past the corresponding 390 | # NEXT statement 391 | index = index + 1 392 | while index < len(line_numbers): 393 | next_line_number = line_numbers[index] 394 | temp_tokenlist = self.__program[next_line_number] 395 | 396 | if temp_tokenlist[0].category == Token.NEXT and \ 397 | len(temp_tokenlist) > 1: 398 | # Check the loop variable to ensure we have not found 399 | # the NEXT statement for a nested loop 400 | if temp_tokenlist[1].lexeme == flowsignal.ftarget: 401 | # Move the statement after this NEXT, if there 402 | # is one 403 | index = index + 1 404 | if index < len(line_numbers): 405 | next_line_number = line_numbers[index] # Statement after the NEXT 406 | self.set_next_line_number(next_line_number) 407 | break 408 | 409 | index = index + 1 410 | 411 | # Check we have not reached end of program 412 | if index >= len(line_numbers): 413 | # Terminate the program 414 | break 415 | 416 | elif flowsignal.ftype == FlowSignal.LOOP_REPEAT: 417 | # Loop repeat encountered 418 | # Pop the loop start address from the stack 419 | try: 420 | index = line_numbers.index(self.__return_loop.pop(flowsignal.floop_var)) 421 | 422 | except ValueError: 423 | raise RuntimeError("Invalid loop exit in line " + 424 | str(self.get_next_line_number())) 425 | 426 | except KeyError: 427 | raise RuntimeError("NEXT encountered without corresponding " + 428 | "FOR loop in line " + str(self.get_next_line_number())) 429 | 430 | self.set_next_line_number(line_numbers[index]) 431 | 432 | else: 433 | index = index + 1 434 | 435 | if index < len(line_numbers): 436 | self.set_next_line_number(line_numbers[index]) 437 | 438 | else: 439 | # Reached end of program 440 | break 441 | 442 | else: 443 | raise RuntimeError("No statements to execute") 444 | 445 | def delete(self): 446 | """Deletes the program by emptying the dictionary""" 447 | self.__program.clear() 448 | self.__data.delete() 449 | 450 | def delete_statement(self, line_number): 451 | """Deletes a statement from the program with 452 | the specified line number, if it exists 453 | 454 | :param line_number: The line number to be deleted 455 | 456 | """ 457 | self.__data.delData(line_number) 458 | try: 459 | del self.__program[line_number] 460 | 461 | except KeyError: 462 | raise KeyError("Line number does not exist") 463 | 464 | def get_next_line_number(self): 465 | """Returns the line number of the next statement 466 | to be executed 467 | 468 | :return: The line number 469 | 470 | """ 471 | 472 | return self.__next_stmt 473 | 474 | def set_next_line_number(self, line_number): 475 | """Sets the line number of the next 476 | statement to be executed 477 | 478 | :param line_number: The new line number 479 | 480 | """ 481 | self.__next_stmt = line_number 482 | --------------------------------------------------------------------------------