Merge pull request #48 from RetiredWizard/fruitjampybasic
Some checks failed
Validate Build / validate-build (push) Has been cancelled

Add PyBasic as a built-in app
This commit is contained in:
foamyguy 2025-08-12 14:29:26 -05:00 committed by GitHub
commit 28aba35b8d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 9607 additions and 0 deletions

View file

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View file

@ -0,0 +1,22 @@
Changes made to https://github.com/richpl/PyBasic on 8/6/2025 to support CircuitPython and Fruit-Jam-OS.
1) interpreter.py (modified printing of trapped exceptions for CircuitPython):
Added the following import (line 30):
from traceback import print_exception
Replaced exception print (line 130):
Orig: print(e, file=stderr, flush=True)
New: print_exception(e,e,e.__traceback__ if hasattr(e,'__traceback__') else None)
2) program.py (set the default directory to the same directory a program is loaded from):
Added the following import (line 28):
import os
Added command to set current directory to folder loaded program is loaded from (line 236-239):
if file.rfind('/') == 0:
os.chdir('/')
elif file.rfind('/') != -1:
os.chdir(file[:file.rfind('/')])

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -0,0 +1,7 @@
# Launches the PyBasic interpreter
#
# See the "Pybasic changes.txt" file for a list of difference from
# the original https://github.com/richpl/PyBasic
#
import interpreter
interpreter.main()

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,200 @@
#! /usr/bin/python
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Class to represent a token for the BASIC
programming language. A token consists of
three items:
column Column in which token starts
category Category of the token
lexeme Token in string form
"""
class BASICToken:
"""BASICToken categories"""
EOF = 0 # End of file
LET = 1 # LET keyword
LIST = 2 # LIST command
PRINT = 3 # PRINT command
RUN = 4 # RUN command
FOR = 5 # FOR keyword
NEXT = 6 # NEXT keyword
IF = 7 # IF keyword
THEN = 8 # THEN keyword
ELSE = 9 # ELSE keyword
ASSIGNOP = 10 # '='
LEFTPAREN = 11 # '('
RIGHTPAREN = 12 # ')'
PLUS = 13 # '+'
MINUS = 14 # '-'
TIMES = 15 # '*'
DIVIDE = 16 # '/'
NEWLINE = 17 # End of line
UNSIGNEDINT = 18 # Integer
NAME = 19 # Identifier that is not a keyword
EXIT = 20 # Used to quit the interpreter
DIM = 21 # DIM keyword
GREATER = 22 # '>'
LESSER = 23 # '<'
STEP = 24 # STEP keyword
GOTO = 25 # GOTO keyword
GOSUB = 26 # GOSUB keyword
INPUT = 27 # INPUT keyword
REM = 28 # REM keyword
RETURN = 29 # RETURN keyword
SAVE = 30 # SAVE command
LOAD = 31 # LOAD command
NOTEQUAL = 32 # '<>'
LESSEQUAL = 33 # '<='
GREATEQUAL = 34 # '>='
UNSIGNEDFLOAT = 35 # Floating point number
STRING = 36 # String values
TO = 37 # TO keyword
NEW = 38 # NEW command
EQUAL = 39 # '='
COMMA = 40 # ','
STOP = 41 # STOP keyword
COLON = 42 # ':'
ON = 43 # ON keyword
POW = 44 # Power function
SQR = 45 # Square root function
ABS = 46 # Absolute value function
DIM = 47 # DIM keyword
RANDOMIZE = 48 # RANDOMIZE keyword
RND = 49 # RND keyword
ATN = 50 # Arctangent function
COS = 51 # Cosine function
EXP = 52 # Exponential function
LOG = 53 # Natural logarithm function
SIN = 54 # Sine function
TAN = 55 # Tangent function
DATA = 56 # DATA keyword
READ = 57 # READ keyword
INT = 58 # INT function
CHR = 59 # CHR$ function
ASC = 60 # ASC function
STR = 61 # STR$ function
MID = 62 # MID$ function
MODULO = 63 # MODULO operator
TERNARY = 64 # TERNARY functions
VAL = 65 # VAL function
LEN = 66 # LEN function
UPPER = 67 # UPPER function
LOWER = 68 # LOWER function
ROUND = 69 # ROUND function
MAX = 70 # MAX function
MIN = 71 # MIN function
INSTR = 72 # INSTR function
AND = 73 # AND operator
OR = 74 # OR operator
NOT = 75 # NOT operator
PI = 76 # PI constant
RNDINT = 77 # RNDINT function
OPEN = 78 # OPEN keyword
HASH = 79 # "#"
CLOSE = 80 # CLOSE keyword
FSEEK = 81 # FSEEK keyword
RESTORE = 82 # RESTORE keyword
APPEND = 83 # APPEND keyword
OUTPUT = 84 # OUTPUT keyword
TAB = 85 # TAB function
SEMICOLON = 86 # SEMICOLON
LEFT = 87 # LEFT$ function
RIGHT = 88 # RIGHT$ function
# Displayable names for each token category
catnames = ['EOF', 'LET', 'LIST', 'PRINT', 'RUN',
'FOR', 'NEXT', 'IF', 'THEN', 'ELSE', 'ASSIGNOP',
'LEFTPAREN', 'RIGHTPAREN', 'PLUS', 'MINUS', 'TIMES',
'DIVIDE', 'NEWLINE', 'UNSIGNEDINT', 'NAME', 'EXIT',
'DIM', 'GREATER', 'LESSER', 'STEP', 'GOTO', 'GOSUB',
'INPUT', 'REM', 'RETURN', 'SAVE', 'LOAD',
'NOTEQUAL', 'LESSEQUAL', 'GREATEQUAL',
'UNSIGNEDFLOAT', 'STRING', 'TO', 'NEW', 'EQUAL',
'COMMA', 'STOP', 'COLON', 'ON', 'POW', 'SQR', 'ABS',
'DIM', 'RANDOMIZE', 'RND', 'ATN', 'COS', 'EXP',
'LOG', 'SIN', 'TAN', 'DATA', 'READ', 'INT',
'CHR', 'ASC', 'STR', 'MID', 'MODULO', 'TERNARY',
'VAL', 'LEN', 'UPPER', 'LOWER', 'ROUND',
'MAX', 'MIN', 'INSTR', 'AND', 'OR', 'NOT', 'PI',
'RNDINT', 'OPEN', 'HASH', 'CLOSE', 'FSEEK', 'APPEND',
'OUTPUT', 'RESTORE', 'RNDINT', 'TAB', 'SEMICOLON',
'LEFT', 'RIGHT']
smalltokens = {'=': ASSIGNOP, '(': LEFTPAREN, ')': RIGHTPAREN,
'+': PLUS, '-': MINUS, '*': TIMES, '/': DIVIDE,
'\n': NEWLINE, '<': LESSER,
'>': GREATER, '<>': NOTEQUAL,
'<=': LESSEQUAL, '>=': GREATEQUAL, ',': COMMA,
':': COLON, '%': MODULO, '!=': NOTEQUAL, '#': HASH,
';': SEMICOLON}
# Dictionary of BASIC reserved words
keywords = {'LET': LET, 'LIST': LIST, 'PRINT': PRINT,
'FOR': FOR, 'RUN': RUN, 'NEXT': NEXT,
'IF': IF, 'THEN': THEN, 'ELSE': ELSE,
'EXIT': EXIT, 'DIM': DIM, 'STEP': STEP,
'GOTO': GOTO, 'GOSUB': GOSUB,
'INPUT': INPUT, 'REM': REM, 'RETURN': RETURN,
'SAVE': SAVE, 'LOAD': LOAD, 'NEW': NEW,
'STOP': STOP, 'TO': TO, 'ON':ON, 'POW': POW,
'SQR': SQR, 'ABS': ABS,
'RANDOMIZE': RANDOMIZE, 'RND': RND,
'ATN': ATN, 'COS': COS, 'EXP': EXP,
'LOG': LOG, 'SIN': SIN, 'TAN': TAN,
'DATA': DATA, 'READ': READ, 'INT': INT,
'CHR$': CHR, 'ASC': ASC, 'STR$': STR,
'MID$': MID, 'MOD': MODULO,
'IF$': TERNARY, 'IFF': TERNARY,
'VAL': VAL, 'LEN': LEN,
'UPPER$': UPPER, 'LOWER$': LOWER,
'ROUND': ROUND, 'MAX': MAX, 'MIN': MIN,
'INSTR': INSTR, 'END': STOP,
'AND': AND, 'OR': OR, 'NOT': NOT,
'PI': PI, 'RNDINT': RNDINT, 'OPEN': OPEN,
'CLOSE': CLOSE, 'FSEEK': FSEEK,
'APPEND': APPEND, 'OUTPUT':OUTPUT,
'RESTORE': RESTORE, 'TAB': TAB,
'LEFT$': LEFT, 'RIGHT$': RIGHT}
# Functions
functions = {ABS, ATN, COS, EXP, INT, LOG, POW, RND, SIN, SQR, TAN,
CHR, ASC, MID, TERNARY, STR, VAL, LEN, UPPER, LOWER,
ROUND, MAX, MIN, INSTR, PI, RNDINT, TAB, LEFT, RIGHT}
def __init__(self, column, category, lexeme):
self.column = column # Column in which token starts
self.category = category # Category of the token
self.lexeme = lexeme # Token in string form
def pretty_print(self):
"""Pretty prints the token
"""
print('Column:', self.column,
'Category:', self.catnames[self.category],
'Lexeme:', self.lexeme)
def print_lexeme(self):
print(self.lexeme, end=' ')

View file

@ -0,0 +1,4 @@
from supervisor import reload
import interpreter
interpreter.main()
reload()

View file

@ -0,0 +1,100 @@
You're in the forest.
You're in the forest.
You're in the forest.
You're in the forest.
You're at the hill in the road.
You're at the end of the road again.
You're inside the Building.
You're in the valley.
You're at slit in the streambed.
You're directly above a grate in a dry streambed.
You're below the grate.
You're in the cobble crawl.
You're in the debris room.
You are in an awkward sloping east/west canyon.
You're in the bird chamber.
You're at the top of the small pit.
You're in the Hall of Mists.
You're in the nugget of gold room.
You're on the east bank of the fissure.
You are on the west side of the fissure in the Hall of Mists.
You're at west end of the Hall of Mists.
You're in the Hall of the Mountain King.
You are in the south side chamber.
You are in the west side chamber of the Hall of the Mountain King.
You are at a N/S passage at a hole in the floor.
You're at Y2 .
You're at the window near the pit.
The passage here is blocked by a recent cave-in.
You're at the east end of the Long Hall.
You're at west end of the Long Hall.
You are at a crossover of a high N/S passage and a low E/W one.
Dead end
You are in a dirty broken passage.
You're at the top of the small pit.
You are in a little pit which has a stream flowing through it.
You're in the dusty rock room.
You're at a complex junction.
You're in the anteroom.
You are at Witt's end. Passages lead off in *all* directions.
You're in the shell room.
You're in the arched hall.
You're in a long sloping corridor with ragged sharp walls.
You are in a cul-de-sac about eight feet across. How's your french?
You are in bedquilt, a long east/west passage with holes everywhere.
You're in the swiss cheese room.
You're in the soft room.
You're at the east end of the Twopit room.
You're at the west end of the Twopit room.
You're in the east pit.
You're in the west pit.
You're in the slab room.
You're in the Oriental room.
You are in a large low room.
You're in a sloping corridor.
Dead end crawl.
You're in the misty cavern.
You're in the alcove.
You're in the Plover room.
You're in the dark-room.
You're on the SW side of the chasm.
You're on the NE side of the chasm.
You're in a corridor.
You're at the fork in the path.
You're in the limestone passage.
You're at a junction with warm walls.
You're in the chamber of boulders.
You're at a breath-taking view.
You're in front of the barren room.
You're in the barren room.
You're in a narrow corridor.
You're in the Giant room.
The passage here is blocked by a recent cave-in.
You are at one end of an immense north/south passage.
You're in the cavern with a waterfall
You're at a steep incline above a large room.
You are in a secret N/S canyon above a sizable passage.
You're at the top of the stalactite.
You're at a junction of three secret canyons.
You are in a secret N/S canyon above a large room.
You're in mirror canyon.
You're at a reservoir.
You are in a secret canyon which exits to the north and east.
You're in the secret E/W canyon above a tight canyon.
You are at a wide place in a very tight N/S canyon.
The canyon here becomes too tight to go on.
You are in a tall E/W canyon.
The canyon runs into a mass of boulders -- dead end.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all alike.
You are at a huge orange stalactite in the maze.
You are in a maze of twisty little passages, all alike.
You are at a dead end.

View file

@ -0,0 +1,35 @@
There is a large sparking nugget of gold here!
There are bars of silver here!
There is precious jewelry here!
There are many coins here!
There are several diamonds here!
There is a delicate, precious ming vase here!
To one side lies a glistening Pearl!
There is a nest here, full of golden eggs!
There is a jewel-encrusted trident here!
There is an emerald the size of a plover's egg here!
There is a platinum pyramid here, eight inches on a side!
There is a golden chain here!
There are rare spices here!
There is a valuable persian rug here!
There is a chest here, full of various treasures!
There is a bottle of water here.
There is a small pool of oil here.
There is a brass lantern here.
There is a set of keys here.
There is food here.
There is a glass bottle here.
There is a small wicker cage here.
There is a 3-foot black rod here.
There is an enormous clam here with its shell tightly shut.
There is a recent issue of 'Spelunker Today' here.
There is a bear nearby.
There is a little axe here.
There is a purple velvet pillow here.
There are shards of pottery scattered about.
There is an enormous oyster here with its shell tightly shut.
There is a little bird here.
A burly troll stands in front of you.
A huge fierce green dragon bars the way!
A huge fierce green snake bars the way!
There is a threatening little dwarf in the room with you!

View file

@ -0,0 +1,583 @@
#1
You can't move that way.
#2.1
Nothing happens.
#2.2
Nothing seems to happen.
#2.3
I don't think that had any affect on anything.
#2.4
I don't know how to apply that word here.
#2.5
That had little effect, if any at all.
#3
The mist is quite thick here, and the fissure is too wide to jump.
#4
You are at the bottom of the pit with a broken neck.
#5
The bottle is already filled!
#6
The bear eagerly wolfs down your food, after which he seems to calm
down considerably and even becomes rather friendly. burp
#7
The plant surges upwards, reaching halfway to the hole above you
#8
The plant grows explosively, almost filling the bottom of the pit.
#9
You overwatered the plant, you fool!
#10
The grate is locked.
#11
The grate is unlocked.
#12
The bear is quite ferocious, and will no doubt tear you to
shreds if you approach it!
#13
The chain is unlocked and the bear is free.
#14
A crystal bridge now spans the fissure.
#15
The bridge vanishes.
#16
It is beyond your power to do that.
#17
The clam opens momenntarily, and a glistening pearl falls out
and rolls away. Goodness, this must really have been an oyster.
(I never was any good at identifying bivalves, anyway.)
#18
I can't close that!
#19
The oil has freed up the hinges so that the door will now move,
although it requires some effort.
#20
I can't eat.
#21
How can I drink that?
#22
"Glug, glug, glug, Belch!"
#23
It doesn't want to eat anything (except maybe you!)
#24
You fool! Dwarves only eat coal! Now you've made him
*** REALLY MAD ****!
#25
Trolls are close relatives with the rocks and have skin as tough as
that of a rhinoceros. The troll fends off your blows effortlessly.
#26
The troll deftly catches the axe, examines it carefully, and tosses it
back, declaring, "Good workmanship, but it's not valuable enough."
#27
The troll catches your treasure and scurries away out of sight.
#28
The bear lumbers toward the troll, who lets out a startled shriek and
scurries away. The bear soon gives up the pursuit and wanders back.
#29
You attack a little dwarf, but he dodges out of the way.
#30
You killed a little dwarf. The body vanishes in a cloud of greasy
black smoke.
#31
There is a threatening little dwarf in the room with you!
#32
One sharp nasty knife is thrown at you!
#33
Out from the shadows behind you pounces a bearded pirate! "Har, har,"
he chortles, "I'll just take all this booty and hide it away with me
chest deep in the maze!" he snatches your treasure and vanishes into
the gloom.
#34
There are faint rustling noises from the darkness behind you.
#35
The grate is open.
#36
The grate is locked.
#37
The bird was unafraid when you entered, but as you approach it becomes
disturbed and you cannot catch it.
#38
The dome is unclimbable.
#39
A crystal bridge now spans the fissure.
#40
A huge green fierce snake bars the way! Hisssssss
#41
A hollow voice says "Plugh".
#42
The vase is now resting, delicately, on a velvet pillow.
#43
Crash! Tinkle! The ming vase shatters into worthless crockery.
#44
You fell into a pit and broke every bone in your body!
#45
It is now pitch dark. If you proceed you will likely fall into a pit.
#46
The nest of golden eggs has vanished!
#47
There is a tiny little plant in the pit, murmuring "water, water, ..."
#48
There is a 12-foot-tall beanstalk stretching up out of the pit,
bellowing "WATER!! WATER!!"
#49
There is a gigantic beanstalk stretching all the way up to the hole.
#50
You can't get by the snake. He hates your guts.
#51
The dragon has a rather "volatile" personality, and he will
probably incinerate you if you get any closer.
#52
You have crawled around in some little holes and wound up back in the
main passage.
#53
Something you're carrying won't fit through the tunnel with you.
#54
Your load is too heavy. You'd best take inventory and drop
something first.
#55
A burly troll stands by the bridge and insists you throw him a
treasure before you may cross.
#56
The troll pops from under the bridge and blocks your way.
#57
The way north is barred by a massive, rusty, iron door.
#58
The bear will bite off your hand. Besides, the chain is locked to the wall.
#59
It's rather difficult to move a twenty-ton dragon, considering
he is lying on the rug.
#60
The vase is now resting, delicately, on a velvet pillow.
#61.1
A valliant attempt!
#61.2
Nice try!
#61.3
A valliant attempt, but you're not that strong!
#61.4
Don't be silly!
#61.5
Do you have any idea on how to do that?
#62
A huge green fierce dragon blocks the way. The dragon is lying
on a persian rug!
#63
A burly troll stands beside the bridge, blocking your way.
#64
There is a ferocious cave bear eyeing you from the far end of the room!
#65
The bear is locked to the wall with a golden chain!
#66
There is a calm, friendly bear locked to the wall.
#67
You are being followed by a very large, tame bear.
#68
With what? Your bare hands?
#69
Congratulations! You have just vanquished a dragon with your bare hands
(hard to believe ain't it?).
#70
Attacking it is both dangerous and doesn't work.
#71
There is nothing here to attack.
#72
How can you do that to more than one thing at a time?
#73
Thank you, it was delicious!
#74
I see nothing special about that.
#75
Oh dear, you seem to have gotten yourself killed. I might be able to
help you out, but I've never really done this before. Do you want me
to try to reincarnate you?
#76
All right. But don't blame me if something goes wr......
--- POOF!! ---
You are engulfed in a cloud of orange smoke. Coughing and gasping,
you emerge from the smoke and find....
#77
You clumsy oaf, you've done it again! I don't know how long I can
keep this up. Do you want me to try reincarnating you again?
#78
Now you've really done it! I'm out of orange smoke! You don't expect
me to do a decent reincarnation without any orange smoke, do you?
Better luck next time!
#79
The nest of golden eggs has vanished!
#80
A little dwarf just walked around a corner, saw you, threw a little
axe at you which missed, cursed and ran away.
#81
The nest of golden eggs has re-appeared!
#200
You are in a forest, with trees all around you.
#205
You have walked up a hill, still in the forest. The road slopes back
down the other side of the hill. There is a building in the distance.
#206
You are standing at the end of a road before a small brick building.
Around you is a forest. A small stream flows out of the building and
down a gully.
#207
You are inside a building, a well house for a large spring.
#208
You are in a valley in the forest beside a stream tumbling along a
rocky bed.
#209
At your feet all the water of the stream splashes into a 2-inch slit
in the rock. Downstream the streambed is bare rock.
#210
You are in a 20-foot depression floored with bare dirt. Set into the
dirt is a strong steel grate mounted in concrete. A dry streambed
leads into the depression.
#211
You are in a small chamber beneath a 3x3 steel grate to the surface.
A low crawl over cobbles leads inward to the west.
#212
You are crawling over cobbles in a low passage. There is a dim light
at the east end of the passage.
#213
You are in a debris room filled with stuff washed in from the surface.
A low wide passage with cobbles becomes plugged with mud and debris
here, but an awkward canyon leads upward and west. A note on the wall
says "magic word XYZZY."
#214
You are in an awkward sloping east/west canyon.
#215
You are in a splendid chamber thirty feet high. The walls are frozen
rivers of orange stone. An awkward canyon and a good passage exit
from east and west sides of the chamber.
#216
At your feet is a small pit breathing traces of white mist. An east
passage ends here except for a small crack leading on.
Rough stone steps lead down the pit.
#217
You are at one end of a vast hall stretching forward out of sight to
the west. There are openings to either side. Nearby, a wide stone
staircase leads downward. The hall is filled with wisps of white mist
swaying to and fro almost as if alive. A cold wind blows up the
staircase. There is a passage at the top of a dome behind you.
Rough stone steps lead to the top of the dome.
#218
This is a low room with a crude note on the wall. The note says,
"you can't get it up the steps."
#219
You are on the east bank of a fissure slicing clear across the hall.
The mist is quite thick here, and the fissure is too wide to jump.
#220
You are on the west side of the fissure in the Hall of Mists.
#221
You are at the west end of Hall of Mists. A low wide crawl continues
west and another goes north. To the south is a little passage 6 feet
off the floor.
#222
You are in the Hall of the Mountain King, with passages off in all
directions.
#223
You are in the south side chamber.
#224
You are in the west side chamber of the Hall of the Mountain King.
A passage continues west and up here.
#225
You are in a low N/S passage at a hole in the floor. The hole goes
down to an E/W passage.
#226
You are in a large room, with a passage to the south, a passage to the
west, and a wall of broken rock to the east. There is a large "Y2" on
a rock in the room's center.
#227
You're at a low window overlooking a huge pit, which extends up out of
sight. A floor is indistinctly visible over 50 feet below. Traces of
white mist cover the floor of the pit, becoming thicker to the right.
Marks in the dust around the window would seem to indicate that
someone has been here recently. Directly across the pit from you and
25 feet away there is a similar window looking into a lighted room. A
shadowy figure can be seen there peering back at you.
The shadowy figure seems to be trying to attract your attention.
#228
The passage here is blocked by a recent cave-in.
#229
You are at the east end of a very long hall apparently without side
chambers. To the east a low wide crawl slants up. To the north a
round two foot hole slants down.
#230
You are at the west end of a very long featureless hall. The hall
joins up with a narrow north/south passage.
#231
You are at a crossover of a high N/S passage and a low E/W one.
#232
Dead end
#233
You are in a dirty broken passage. To the east is a crawl. To the
west is a large passage. Above you is a hole to another passage.
#234
You are on the brink of a small clean climbable pit. A crawl leads
west.
#235
You are in the bottom of a small pit with a little stream, which
enters and exits through tiny slits.
#236
You are in a large room full of dusty rocks. There is a big hole in
the floor. There are cracks everywhere, and a passage leading east.
#237
You are at a complex junction. A low hands and knees passage from the
north joins a higher crawl from the east to make a walking passage
going west. There is also a large room above. The air is damp here.
#238
You are in an anteroom leading to a large passage to the east. Small
passages go west and up. The remnants of recent digging are evident.
a sign in midair here says "Cave under construction beyond this point.
proceed at own risk. "[Witt Construction Company]"
#239
You are at Witt's end. Passages lead off in *all* directions.
#240
You're in a large room carved out of sedimentary rock. The floor and
walls are littered with bits of shells embedded in the stone. A
shallow passage proceeds downward, and a somewhat steeper one leads
up. A low hands and knees passage enters from the south.
#241
You are in an arched hall. A coral passage once continued up and east
from here, but is now blocked by debris. The air smells of sea water.
#242
You are in a long sloping corridor with ragged sharp walls.
#243
You are in a cul-de-sac about eight feet across. How's your french?
#244
You are in bedquilt, a long east/west passage with holes everywhere.
To explore at random, select north, south, up or down.
#245
You are in a room whose walls resemble swiss cheese. Obvious passages
go west, east, NE, and NW. Part of the room is occupied by a large
bedrock block.
#246
You are in the soft room. The walls are covered with heavy curtains,
the floor with a thick pile carpet. Moss covers the ceiling.
#247
You are at the east end of the Twopit room. The floor here is
littered with thin rock slabs, which make it easy to descend the pits.
There is a path here bypassing the pits to connect passages from east
and west. There are holes all over, but the only big one is on the
wall directly over the west pit where you can't get to it.
#248
You are at the west end of the Twopit room. There is a large hole in
the wall above the pit at this end of the room.
#249
You are at the bottom of the eastern pit in the Twopit room. There is
a small pool of oil in one corner of the pit.
#250
You are at the bottom of the western pit in the Twopit room. There is
a large hole in the wall about 25 feet above you.
#251
You are in a large low circular chamber whose floor is an immense slab
fallen from the ceiling (slab room). East and west there once were
large passages, but they are now filled with boulders. Low small
passages go north and south, and the south one quickly bends west
around the boulders.
#252
This is the oriental room. Ancient oriental cave drawings cover the
walls. A gently sloping passage leads upward to the north, another
passage leads SE, and a hands and knees crawl leads west.
#253
You are in a large low room. Crawls lead north, SE, and SW.
#254
You are in a long winding corridor sloping out of sight in both
directions.
#255
Dead end crawl.
#256
You are following a wide path around the outer edge of a large cavern.
Far below, through a heavy white mist, strange splashing noises can be
heard. The mist rises up through a fissure in the ceiling. The path
exits to the south and west.
#257
You are in an alcove. A small NW path seems to widen after a short
distance. An extremely tight tunnel leads east. It looks like a very
tight squeeze. An eerie light can be seen at the other end.
#258
You're in a small chamber lit by an eerie green light. An extremely
narrow tunnel exits to the west. A dark corridor leads NE.
#259
You're in the dark-room. A corridor leading south is the only exit.
A massive stone tablet embedded in the wall reads:
"Congratulations on bringing light into the dark-room!"
#260
You are on one side of a large, deep chasm. A heavy white mist rising
up from below obscures all view of the far side. A SW path leads away.
A rickety wooden bridge extends across the chasm, vanishing into the
mist. A sign posted on the bridge reads, "STOP! Pay Troll!"
#261
You are on the far side of the chasm. A NE path leads away from the
chasm on this side.
A rickety wooden bridge extends across the chasm, vanishing into the
gloom. A sign posted on the bridge reads: "Stop! Pay troll!"
#262
You're in a long east/west corridor. A faint rumbling noise can be
heard in the distance.
#263
The path forks here. The left fork leads northeast. A dull rumbling
seems to get louder in that direction. The right fork leads southeast
down a gentle slope. The main corridor enters from the west.
#264
You are walking along a gently sloping north/south passage lined with
oddly shaped limestone formations.
#265
The walls are quite warm here. From the north can be heard a steady
roar, so loud that the entire cave seems to be trembling. Another
passage leads south, and a low crawl goes east.
#266
You are in a small chamber filled with large boulders. The walls are
very warm, causing the air in the room to be almost stifling from the
heat. The only exit is a crawl heading west, through which is coming
a low rumbling.
#267
You are on the edge of a breath-taking view. Far below you is an
active volcano, from which great gouts of molten lava come surging
out, cascading back down into the depths. The glowing rock fills the
farthest reaches of the cavern with a blood-red glare, giving every-
thing an eerie, macabre appearance. The air is filled with flickering
sparks of ash and a heavy smell of brimstone. The walls are hot to
the touch, and the thundering of the volcano drowns out all other
sounds. Embedded in the jagged roof far overhead are myriad twisted
formations composed of pure white alabaster, which scatter the murky
light into sinister apparitions upon the walls. To one side is a deep
gorge, filled with a bizarre chaos of tortured rock which seems to
have been crafted by the devil himself. An immense river of fire
crashes out from the depths of the volcano, burns its way through the
gorge, and plummets into a bottomless pit far off to your left. To
the right, an immense geyser of blistering steam erupts continuously
from a barren island in the center of a sulfurous lake, which bubbles
ominously. The far right wall is aflame with an incandescence of its
own, which lends an additional infernal splendor to the already
hellish scene. A dark, foreboding passage exits to the south.
#268
You are standing at the entrance to a large, barren room. A sign
posted above the entrance reads: "Caution! Bear in room!"
#269
You are inside a barren room. The center of the room is completely
empty except for some dust. Marks in the dust lead away toward the
far end of the room. The only exit is the way you came in.
#270
You are in a long, narrow corridor stretching out of sight to the
west. At the eastern end is a hole through which you can see a
profusion of leaves.
#271
You are in the giant room. The ceiling here is too high up for your
lamp to show it. Cavernous passages lead east, north, and south. On
the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
#272
The passage here is blocked by a recent cavein.
#273
You are at one end of an immense north/south passage.
#274
You are in a magnificent cavern with a rushing stream, which cascades
over a sparkling waterfall into a roaring whirlpool which disappears
through a hole in the floor. Passages exit to the south and west.
#275
You are at the top of a steep incline above a large room. You could
climb down here, but you would not be able to climb up. There is a
passage leading back to the north.
#276
You are in a secret N/S canyon above a sizable passage.
#277
A large stalactite extends from the roof and almost reaches the floor
below. You could climb down it, and jump from it to the floor, but
having done so you would be unable to reach it to climb back up.
The maze continues at this level.
#278
You are in a secret canyon at a junction of three canyons, bearing
north, south, and SE. The north one is as tall as the other two
combined.
#279
You are in a secret N/S canyon above a large room.
#280
You are in a north/south canyon about 25 feet across. The floor is
covered by white mist seeping in from the north. The walls extend
upward for well over 100 feet. Suspended from some unseen point far
above you, an enormous two-sided mirror is hanging parallel to and
midway between the canyon walls. (The mirror is obviously provided
for the use of the dwarves, who as you know, are extremely vain.) A
small window can be seen in either wall, some fifty feet up.
#281
You are at the edge of a large underground reservoir. An opaque cloud
of white mist fills the room and rises rapidly upward. The lake is
fed by a stream, which tumbles out of a hole in the wall about 10 feet
overhead and splashes noisily into the water somewhere within the
mist. The only passage goes back toward the south.
#282
You are in a secret canyon which exits to the north and east.
#283
You're in the secret E/W canyon above a tight canyon.
#284
You are at a wide place in a very tight N/S canyon.
#285
The canyon here becomes too tight to go on.
#286
You are in a tall E/W canyon. A low tight crawl goes 3 feet north and
seems to open up.
#287
The canyon runs into a maze of boulders -- dead end.
#288
You are in a maze of twisty little passages, all alike.
#298
You are near a large pit beside a large stalactite in the maze.
The stalactite is about 30 feet long, allowing you to descend
it. However, due to the smoothness of the stalactite you will
probably be unable to climb back up again.
#299
The threatening little dwarf pulls out a sharp, nasty knife but
suddenly freezes.
The burly troll notices the little dwarf and appears to become very angry.
The little dwarf frantically looks from side to side, the burly troll
takes a sudden step towards the little dwarf.
The little dwarf makes an odd squeal, steps back and trips on an outcropping,
falling with a soft *thud* before scrambling out of sight in a cloud of dust.
#300
Dead end.
#301
Welcome to adventure.! Would you like instructions?
#302
Somewhere nearby is Colossal Cave, where others have found fortunes in
treasure and gold, though it is rumored that some who enter are never
seen again. Magic is said to work in the cave. I will be your eyes
and hands. Direct me with commands such as get, take, or look. Since you
need to move around, you must usually enter compass directions
(N,NE,E,SE,S,SW,W,NW or up or down), although you may sometimes use
more vague verbs with with to move. I know of several objects in this
game, such as a lamp and a bottle. I also know of special objects in the
cave. Some of these objects have side effects, ie there is a rod in the
cave that scares a little bird.
-----------------------------------------------------------------
The object of this game is to gather as many treasures as you can and
put them back in the house. You also run the risk of getting robbed or
killed by some rather unfriendly inhabitants of the cave.
----------------------------------------------------------------
There are some useful commands that you should know about:
--- Brief, Long, and Short - these commands control the amount of
--- detail you get in descriptions.
--- Look (or L) - gives a detailed description of your surroundings.
--- Inventory (or I) tells you what you are carrying.
--- Quit, Stop or End - these are self-explanatory.
--- Save - by typing this, you may save your game and continue it at
--- a later time.
--- Continue - lets you continue an old game.
--- Score - tells you hw well you're doing.
Other helpful functions include:
* multiple commands on one input line, ie:
"Go south, get car, keys, Start car." (example only)
--------------------------------------------------------------
"Adventure" is a version of the game created by Willy Crowther and
Dan Woods at M.I.T.
--------------------------------------------------------------
#303
I'm sorry, but the magazine is written in Dwarvish.
#
#
#

View file

@ -0,0 +1,184 @@
1,0
2,1
3,235
4,307
5,365
6,400
7,531
8,601
9,673
10,715
11,742
12,771
13,864
14,914
15,960
16,987
17,1029
18,1219
19,1245
20,1350
21,1369
22,1397
23,1430
24,1488
25,1570
26,1713
27,1858
28,1928
29,2074
30,2137
31,2224
32,2288
33,2334
34,2564
35,2632
36,2657
37,2684
38,2797
39,2828
40,2874
41,2931
42,2966
43,3029
44,3098
45,3159
46,3236
47,3280
48,3357
49,3456
50,3531
51,3585
52,3699
53,3790
54,3861
55,3944
56,4045
57,4109
58,4171
59,4253
60,4347
61,6
62,4584
63,4672
64,4737
65,4815
66,4873
67,4930
68,4987
69,5022
70,5131
71,5186
72,5225
73,5285
74,5320
75,5360
76,5535
77,5744
78,5880
79,6048
80,6092
81,6213
200,6260
205,6315
206,6464
207,6626
208,6693
209,6779
210,6909
211,7082
212,7210
213,7320
214,7565
215,7620
216,7807
217,7979
218,8377
219,8484
220,8628
221,8697
222,8861
223,8948
224,8990
225,9103
226,9203
227,9383
228,9935
229,9991
230,10168
231,10287
232,10358
233,10374
234,10516
235,10598
236,10708
237,10854
238,11071
239,11344
240,11414
241,11685
242,11834
243,11901
244,11976
245,12108
246,12271
247,12411
248,12753
249,12879
250,13004
251,13133
252,13436
253,13640
254,13708
255,13792
256,13815
257,14066
258,14275
259,14412
260,14597
261,14882
262,15113
263,15212
264,15424
265,15537
266,15730
267,15966
268,17284
269,17418
270,17623
271,17783
272,17999
273,18054
274,18115
275,18330
276,18511
277,18574
278,18823
279,18974
280,19032
281,19514
282,19853
283,19922
284,19983
285,20042
286,20093
287,20190
288,20250
298,20313
299,20554
300,21003
301,21020
302,21080
303,22968
-999,-999
30
54
86
140
189
4410
4438
4456
4512
4536
-999

View file

@ -0,0 +1,100 @@
3,0,6,0,4,0,2,0,0,0
1,0,8,0,2,0,4,0,0,0
2,0,1,0,4,0,7,0,0,0
1,0,3,0,5,0,2,0,0,0
2,0,6,0,4,0,1,0,0,0
2,0,7,0,8,0,5,0,0,0
0,0,0,0,0,0,6,0,0,0
6,0,3,0,9,0,4,0,0,0
8,0,3,0,10,0,4,0,0,0
9,0,0,0,11,0,0,0,0,11
0,0,10,0,0,0,12,0,10,0
0,0,11,0,0,0,13,0,0,0
0,0,12,0,0,0,14,0,14,0
0,0,13,0,0,0,15,0,15,13
0,0,14,0,0,0,16,0,0,0
0,0,15,0,0,0,0,0,0,17
22,0,0,0,18,0,19,0,16,22
17,0,0,0,0,0,0,0,0,0
0,0,17,0,0,0,20,0,0,0
0,0,19,0,0,0,21,0,0,0
20,0,20,0,88,0,29,0,0,0
25,0,17,0,23,83,24,0,17,0
22,0,0,0,0,0,0,0,0,0
0,0,22,0,0,0,31,0,31,0
26,0,0,0,22,0,0,0,0,33
0,0,28,0,25,0,27,0,0,0
0,0,26,0,0,0,0,0,0,0
0,0,0,0,0,26,0,0,0,0
31,0,21,0,0,0,30,0,21,31
31,0,29,0,94,0,0,0,0,0
32,0,24,0,30,0,29,0,0,0
31,0,0,0,0,0,0,0,0,0
0,0,34,0,0,0,36,0,25,0
0,0,0,0,0,0,33,0,0,35
0,0,0,0,0,0,0,0,34,0
0,0,33,0,0,0,0,0,25,37
40,0,38,0,0,0,44,0,36,0
0,0,39,0,0,0,37,0,37,0
255,255,255,255,255,255,255,255,255,255
0,0,0,0,37,0,0,0,41,42
0,0,0,0,0,0,0,0,0,43
0,0,0,0,0,0,0,0,40,43
0,0,0,0,0,0,0,0,42,0
255,0,37,0,255,0,45,0,255,255
0,44,46,0,0,0,47,52,0,0
0,0,0,0,0,0,45,0,0,0
0,0,45,0,0,0,48,0,0,49
0,0,47,0,0,0,51,0,0,50
0,0,0,0,0,0,0,0,47,0
0,0,0,0,0,0,0,0,48,0
44,0,0,0,48,0,0,0,79,0
56,0,0,45,0,0,53,0,0,0
55,0,0,52,0,54,0,0,0,0
0,0,0,0,0,0,0,0,60,53
0,0,0,0,53,0,0,0,0,0
0,0,0,0,52,0,57,0,0,0
0,0,58,0,0,0,0,56,0,0
0,59,0,0,0,0,57,0,0,0
0,0,0,0,58,0,0,0,0,0
0,61,0,0,0,54,0,0,0,54
0,62,0,0,0,60,0,0,0,0
0,0,63,0,0,0,61,0,0,0
0,65,0,64,0,0,62,0,0,0
63,0,0,0,68,0,0,0,0,0
67,0,66,0,63,0,0,0,0,0
0,0,0,0,0,0,65,0,0,0
0,0,0,0,65,0,0,0,0,0
0,0,69,0,0,0,64,0,0,0
0,0,0,0,0,0,68,0,0,0
0,0,50,0,0,0,71,0,0,50
73,0,70,0,72,0,0,0,0,0
0,71,0,0,0,0,0,0,0,0
74,0,0,0,71,0,0,0,0,0
0,0,0,0,73,0,75,0,0,0
74,0,0,0,0,0,0,0,0,53
78,0,0,0,77,0,0,0,0,45
76,0,0,0,0,0,0,0,0,93
27,0,0,44,76,0,0,0,0,0
80,0,0,0,82,0,0,0,0,51
81,0,0,0,79,0,0,0,0,0
0,0,0,0,80,0,0,0,0,0
79,0,83,0,0,0,0,0,0,0
0,0,22,0,0,0,82,0,0,84
86,0,0,0,85,0,0,0,0,0
84,0,0,0,0,0,0,0,0,0
45,0,84,0,0,0,87,0,0,0
0,0,0,86,0,0,0,0,0,0
89,82,91,95,90,83,92,91,95,94
95,96,91,90,89,88,91,95,93,97
92,92,91,93,88,97,88,96,99,87
91,89,94,90,93,95,89,92,0,0
95,97,93,96,94,95,21,92,0,0
90,96,92,94,88,30,92,90,0,0
98,89,90,91,89,93,95,97,0,0
93,94,96,92,97,95,94,92,0,0
92,99,97,96,89,94,90,90,91,92
98,89,92,91,90,93,94,95,96,98
95,90,93,91,94,92,90,99,98,15
88,89,93,97,100,89,96,95,0,0
0,0,0,0,99,0,0,0,0,0

View file

@ -0,0 +1,585 @@
10 REM Pneuma - A space adventure
20 REM ========== backstory and instructions ==========
30 PRINT "********************************" : PRINT
35 PRINT " Pneuma - A space adventure" : PRINT
40 PRINT "********************************": PRINT
45 PRINT "To get instructions, type 'help'"
50 PRINT
60 PRINT "You wake up in your bunk, in the sleeping quarters of the starship Pneuma. You can't"
65 PRINT "remember much. You went to bed feeling sick and after a feverish few hours tossing and"
70 PRINT "turning, feeling like you were burning up, you eventually fell asleep." : PRINT
75 PRINT "Now, your sheets and night clothes are damp with sweat, and you have a raging thirst."
80 PRINT "You have a sore throat and the mother of all headaches, like your brain has been boiling"
85 PRINT "in your skull. In fact, you're no longer sure exactly where you are ... you seem to be"
90 PRINT "suffering from some sort of amnesia ...": PRINT
95 REM set up environment
100 GOSUB 2700
500 REM setup room descriptions
510 GOSUB 3000
520 REM setup up interative descriptions
530 GOSUB 5000
540 REM setup dialogue
550 GOSUB 7000
700 REM ========== main loop ==========
701 IF WPL <> 99 THEN GOSUB 8400 : REM wraith-hound movement
702 REM show room details
703 PRINT "You are in the " ; LO$ ( PL ) : PRINT
705 GOSUB 4010 : REM print room description
706 GOSUB 8000 : REM tracker info if carried
707 IF WPL <> 99 THEN GOSUB 8200 : REM wraith-hound proximity check
709 IF WPL = PL THEN GOSUB 11000 : REM fight wraith-hound
710 INPUT "What now? " ; I$
715 PRINT
716 MOVE = 1
720 IF LEFT$ ( LOWER$ ( I$ ) , 4 ) = "get " THEN MOVE = 0 : GOSUB 1400
730 IF LEFT$ ( LOWER$ ( I$ ) , 5 ) = "take " THEN MOVE = 0 : GOSUB 1700
740 IF LEFT$ ( LOWER$ ( I$ ) , 5 ) = "drop " THEN MOVE = 0 : GOSUB 2000
750 IF LEFT$ ( LOWER$ ( I$ ) , 8 ) = "examine " THEN MOVE = 0 : GOSUB 2300
760 IF LEFT$ ( LOWER$ ( I$ ) , 4 ) = "look" THEN MOVE = 0 : GOSUB 4010
765 IF LEFT$ ( LOWER$ ( I$ ) , 4 ) = "help" THEN MOVE = 0 : GOSUB 4130
767 IF LEFT$ ( LOWER$ ( I$ ) , 4 ) = "use " THEN MOVE = 0 : GOSUB 9000
770 IF LOWER$ ( I$ ) = "i" OR LOWER$ ( I$ ) = "inventory" THEN MOVE = 0 : GOSUB 1000
775 IF LEFT$ ( LOWER$ ( I$ ) , 8 ) = "talk to " THEN MOVE = 0 : GOSUB 2630
780 IF LEFT$ ( LOWER$ ( I$ ) , 1 ) = "q" THEN GOSUB 2600
785 IF LEFT$ ( LOWER$ ( I$ ) , 3 ) = "go " THEN GOSUB 1100
790 IF LOWER$ ( I$ ) = "f" OR LOWER$ ( I$ ) = "forward" THEN GOSUB 1200
800 IF LOWER$ ( I$ ) = "a" OR LOWER$ ( I$ ) = "aft" THEN GOSUB 1200
810 IF LOWER$ ( I$ ) = "p" OR LOWER$ ( I$ ) = "port" THEN GOSUB 1200
820 IF LOWER$ ( I$ ) = "s" OR LOWER$ ( I$ ) = "starboard" THEN GOSUB 1200
830 IF LOWER$ ( I$ ) = "u" OR LOWER$ ( I$ ) = "up" THEN GOSUB 1200
840 IF LOWER$ ( I$ ) = "d" OR LOWER$ ( I$ ) = "down" THEN GOSUB 1200
895 IF MOVE = 1 THEN GOTO 700 ELSE GOTO 710
900 STOP
995 REM ========== actions ==========
1000 REM list the player's inventory
1005 PRINT "You have the following items:" : PRINT
1010 FOR I = 0 TO OC - 1
1020 IF OL ( I ) = 0 THEN PRINT OB$ ( I )
1030 NEXT I
1035 PRINT
1040 RETURN
1100 REM fully written out move (e.g. 'go aft')
1110 D$ = MID$ ( LOWER$(I$) , 4 , 1 )
1120 GOSUB 1300
1130 RETURN
1200 REM abbreviated move (e.g. 'a' or 'aft')
1210 D$ = LOWER$( I$ )
1220 GOSUB 1300
1230 RETURN
1300 REM go to the player's new location (PL)
1310 IF D$ = "f" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 1 , 2 ) )
1320 IF D$ = "a" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 3 , 2 ) )
1330 IF D$ = "p" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 5 , 2 ) )
1340 IF D$ = "s" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 7 , 2 ) )
1345 IF D$ = "u" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 9 , 2 ) )
1350 IF D$ = "d" THEN NPL = VAL ( MID$ ( EX$ ( PL ) , 11 , 2 ) )
1355 IF NPL = 0 THEN PRINT "You can't go that way." : PRINT ELSE PL = NPL
1360 RETURN
1400 REM get command
1405 F=-1: R$=""
1410 R$ = MID$(LOWER$(I$), 5) : REM R$ is the requested object
1420 REM get the object ID
1430 FOR I= 0 TO OC-1
1440 IF OB$(I) = R$ THEN F=I : REM object exists
1450 NEXT I
1460 REM can't find the item?
1470 IF F=-1 THEN PRINT "You can't take that." : PRINT : RETURN
1480 IF OL(F) <> PL THEN PRINT "That item doesn't appear to be around here." : PRINT : RETURN
1490 IF OL(F)=0 THEN PRINT "You already have that item." : PRINT: RETURN
1520 OL(F)=0 : REM add the item to the inventory
1530 PRINT "You've picked up ";OB$(F); "." : PRINT
1540 RETURN
1700 REM take command
1710 F=-1: R$=""
1720 R$ = MID$(LOWER$(I$), 6) : REM R$ is the requested object
1730 GOTO 1420 : REM use the same logic as the get command
2000 REM drop command
2010 F=-1: R$=""
2020 R$ = MID$(LOWER$(I$), 6) : REM R$ is the requested object
2030 FOR I= 0 TO OC-1
2040 IF OB$(I) = R$ THEN F=I : REM object exists
2050 NEXT I
2060 REM can't find it?
2070 IF F=-1 THEN PRINT "You don't have that." : PRINT: RETURN
2080 IF OL(F) <> 0 THEN PRINT "You aren't carrying that." : PRINT: RETURN
2090 OL(F) = PL : PRINT "You've dropped ";OB$(F); ".": PRINT: REM add the item to the current room
2095 IF F = SUIT THEN SUIT_WORN = 0
2110 RETURN
2300 REM examine command
2310 F=-1 : R$=""
2320 R$ = MID$(LOWER$(I$), 9) : REM R$ is the object to examine
2330 FOR I = 0 TO IC-1
2340 IF IO$(I) = R$ THEN F=I : REM object exists
2350 NEXT I
2360 REM can't find it?
2370 IF F=-1 THEN PRINT "You can't examine that." : PRINT : RETURN
2380 IF IL(F) <> PL THEN PRINT "There isn't one of these here." : PRINT : RETURN
2390 GOSUB 6000 : REM print result of examination
2400 RETURN
2600 REM quit command
2610 PRINT "Farewell spacefarer ..."
2620 STOP
2630 REM talk to command
2635 F=-1 : R$ = ""
2640 R$ = MID$(LOWER$(I$), 9) : REM R$ is the person to talk to
2645 FOR I = 0 TO PC-1
2650 IF P$(I) = R$ THEN F=I : REM person exists
2655 NEXT I
2660 REM can't find them?
2665 IF F=-1 THEN PRINT "You've not met them." : PRINT : RETURN
2670 IF PLOC(F) <> PL THEN PRINT "They aren't here." : PRINT : RETURN
2675 GOSUB 7500 : REM print dialogue
2695 RETURN
2700 REM ========== set up environment ===========
2705 RC = 18 : REM room count
2710 DIM LO$ ( RC )
2715 INV = 0 : LO$ ( INV ) = "Inventory"
2720 GAL = 1 : LO$ ( GAL ) = "Galley"
2725 REC = 2 : LO$ ( REC ) = "Recreation/Dining Room"
2730 ARM = 3 : LO$ ( ARM ) = "Armoury"
2735 BDG = 4 : LO$ ( BDG ) = "Bridge"
2740 SLP = 5 : LO$ ( SLP ) = "Sleeping Quarters"
2745 MED = 6 : LO$ ( MED ) = "Medical Centre"
2750 GYM = 7 : LO$ ( GYM ) = "Gymnasium"
2755 LAC = 8 : LO$ ( LAC ) = "Lower Aft Corridor"
2760 ENG = 9 : LO$ ( ENG ) = "Engine Room"
2765 STO = 10 : LO$ ( STO ) = "Storeroom"
2770 MEN = 11 : LO$ ( MEN ) = "Menagerie"
2775 LAB = 12 : LO$ ( LAB ) = "Laboratory"
2780 LFC = 13 : LO$ ( LFC ) = "Lower Forward Corridor"
2785 POD = 14 : LO$ ( POD ) = "Pod Bay"
2790 AMC = 15 : LO$ ( AMC ) = "Aft Main Corridor"
2795 MMC = 16 : LO$ ( MMC ) = "Mid Main Corridor"
2800 FMC = 17 : LO$ ( FMC ) = "Forward Main Corridor"
2805 REM encoded room exits, two digits per direction f, a, p, s, u, d
2810 DIM EX$ ( RC )
2815 EX$ ( GAL ) = "020000150008"
2820 EX$ ( REC ) = "000100160000"
2825 EX$ ( ARM ) = "000000170000"
2830 EX$ ( BDG ) = "001700000000"
2835 EX$ ( SLP ) = "000015000000"
2840 EX$ ( MED ) = "070016000000"
2845 EX$ ( GYM ) = "000617000013"
2850 EX$ ( LAC ) = "100000090100"
2855 EX$ ( ENG ) = "000008000000"
2860 EX$ ( STO ) = "120800110000"
2865 EX$ ( MEN ) = "000010000000"
2870 EX$ ( LAB ) = "001000130000"
2875 EX$ ( LFC ) = "140012000700"
2880 EX$ ( POD ) = "001300000000"
2890 EX$ ( AMC ) = "160001050000"
2895 EX$ ( MMC ) = "171502060000"
2900 EX$ ( FMC ) = "041603070000"
2905 OC = 5 : REM object count
2910 DIM OB$ ( OC )
2915 PULSE = 0 : OB$ ( PULSE ) = "pulse rifle"
2920 SUIT = 1 : OB$ ( SUIT ) = "space suit"
2922 KNIFE = 2 : OB$ ( KNIFE ) = "knife"
2924 TRACKER = 3 : OB$ ( TRACKER ) = "tracker"
2926 SYRINGE = 4 : OB$ ( SYRINGE ) = "syringe"
2930 REM object locations
2932 REM location 0 = player's inventory
2934 DIM OL ( OC )
2936 OL ( PULSE ) = ARM
2937 OL ( SUIT ) = POD
2939 OL ( KNIFE ) = GAL
2940 OL ( TRACKER ) = GYM
2941 OL ( SYRINGE ) = MED
2942 IC = 5 : REM interactive object count
2944 DIM IO$ (IC)
2946 MEDLOG = 0 : IO$ ( MEDLOG ) = "medical log"
2948 PORTHOLE = 1 : IO$ (PORTHOLE) = "porthole"
2950 CONSOLE = 2 : IO$(CONSOLE) = "console"
2952 ENGINE = 3 : IO$(ENGINE)= "engine control"
2954 TERMINAL = 4 : IO$(TERMINAL) = "library terminal"
2960 REM interative object locations
2962 DIM IL ( IC )
2964 IL ( MEDLOG) = MED
2966 IL (PORTHOLE) = POD
2968 IL (CONSOLE) = BDG
2970 IL (ENGINE) = ENG
2971 IL (TERMINAL) = REC
2972 PC = 3 : REM person count
2974 DIM P$ ( PC )
2976 CHEF = 0 : P$ ( CHEF ) = "chef"
2978 RUNNER = 1 : P$ ( RUNNER ) = "runner"
2980 PILOT = 2 : P$ ( PILOT ) = "pilot"
2981 REM person locations
2983 DIM PLOC ( PC )
2985 PLOC ( CHEF ) = GAL
2987 PLOC ( RUNNER ) = GYM
2989 PLOC ( PILOT ) = BDG
2990 PL = SLP : REM initial player location
2992 WPL = MEN : REM wraith-hound initial location
2994 SUIT_WORN = 0 : REM is space suit worn?
2995 SHUTDOWN = 0 : REM are engines shut down?
2999 RETURN
3000 REM ========== room descriptions ==========
3010 DIM RD$ ( RC, 5 )
3015 REM inventory
3020 DATA "", "", "", "", ""
3025 REM galley
3030 DATA "The galley contains gleaming, stainless steel cupboards along the aft wall. A food"
3040 DATA "preparation surface is on the port wall, currently covered in rotting food. A chef"
3050 DATA "stands at the work surface, methodically chopping food even though everything has"
3060 DATA "already been thoroughly diced. There are doors in the starboard and forward walls and"
3070 DATA "a stairway leads downwards in the far corner."
3075 REM recreation room
3080 DATA "Space is clearly at a premium in this ship. The room doubles as both a dining and"
3090 DATA "recreation area. Long tables for dining are located on the port side, while couches"
3100 DATA "and low tables are scattered around the remaining space. A library terminal is switched"
3105 DATA "on in the corner. There are doors in the aft and starboard walls.", ""
3120 REM armoury
3130 DATA "Locked cabinets line the starboard wall. Each cabinet has a prominently displayed"
3140 DATA "notice on its door reading 'Weapons to be removed only when authorised by the Chief"
3150 DATA "Security Officer'. However, the door to one cupboard has been prized open, it is"
3160 DATA "warped and bent. This cupboard appears to be empty. The only exit is a starboard door.", ""
3170 REM bridge
3180 DATA "The bridge is the heart of the ship. A vast array of glowing screens and switches fill"
3190 DATA "every surface. On the screens are complex graphics providing detailed information about"
3200 DATA "the status of every system on the ship. Many of them are showing red warning symbols."
3210 DATA "There is a console directly in front of you, a pilot gripping the throttle."
3220 DATA "An aft exit leads back into the main corridor."
3225 REM sleeping quarters
3230 DATA "The sleeping quarters is filled with bunks, one up, one down. Several of the bunks"
3240 DATA "contain sleeping forms, some gently shoring. The room has a partition to separate"
3250 DATA "male and female bunks. Against the forward wall are two corresponding sets of heads."
3260 DATA "The room is messy, with discarded personal items everywhere ... on bunks, on the floor."
3270 DATA "There is a door in the port wall."
3275 REM medical centre
3280 DATA "The medical centre looks relatively normal, but there is evidence of discarded items"
3290 DATA "lying around the room. Blood filled syringes are scattered on a workbench, as well as"
3300 DATA "some bloodied bandanges. The words 'I'm losing myself' are scrawled messily in blood on"
3310 DATA "one wall. In the corner you can see a terminal. On the terminal screen is a portion"
3320 DATA "of the medical log. Exits lead port and forward."
3325 REM gymnasium
3330 DATA "The gymnasium is full of exercise equipment. A female runner is sprinting furiously on a"
3340 DATA "treadmill. She looks exhausted and emaciated, but she keeps running at top speed, almost at"
3350 DATA "a sprint. Her eyes remain fixed on the treadmill console. There are aft and port exits,"
3360 DATA "as well as a stairwell leading to the lower deck in the far corner.", ""
3370 REM lower aft corridor
3380 DATA "This is a featureless, utilitarian corridor. A stairwell leads upwards. There are also"
3390 DATA "exits leading starboard and forward.", "", "", ""
3400 REM engine room
3430 DATA "The engine room is characterised by a continual rumble, as though incredible energies are"
3440 DATA "barely being contained. There is an engine control in the far corner, festooned with"
3450 DATA "switches and engine readouts. A single exit leads out into the corridor.", "", ""
3460 REM storeroom
3480 DATA "The storeroom is full of crates, most neatly stacked, but with some scattered across the"
3490 DATA "floor, their contents spilling out. Along the port wall is a door marked 'Test specimens'."
3500 DATA "From behind the door, strange animal noises are audible ... snuffling sounds and the"
3510 DATA "occasional primate shriek. A dead man wearing a scuffed and torn lab coat is lying face down"
3520 DATA "in front of the specimen door. Two other exits lead forward and aft."
3525 REM menagerie
3530 DATA "The room is a hellhole. Cages stand open, while various animals roam about: chimpanzees,"
3540 DATA "dogs, and rats. Some of the rats are dead, having been savaged and eviscerated. The floor"
3550 DATA "and walls are smeared with animal faeces, and the smell is almost overpowering. A capsule,"
3552 DATA "its door ajar, is marked 'BIOWEAPON CONTAINMENT'. The capsule is empty."
3555 DATA "A single door to port leads back into the storeroom."
3560 REM laboratory
3570 DATA "The laboratory is full of scientific equipment, chemical glassware, electronic analysers,"
3580 DATA "fume cupboards, and two couches. The place looks disorded, like the rest of the ship, the"
3590 DATA "result of frenetic activity. A number of experiments seem to be in progress, with logbooks"
3600 DATA "and tablets covered in dense calculations and notes. Whatever has been happening in here,"
3610 DATA "it has been done with extreme urgency. Exits lead aft and to starboard."
3615 REM lower forward corridor
3620 DATA "This is a featureless, utilitarian corridor. A stairwell leads upwards. There are also"
3630 DATA "doors leading to port and forward.", "", "", ""
3660 REM pod bay
3670 DATA "You are in a large room, with a row of spacesuits hanging on the port wall. At the forward"
3680 DATA "end of the room is a small, two seater vehicle, capable of operating in space outside the"
3690 DATA "main ship for limited periods. In front of the small ship is the pod bay door, leading out"
3700 DATA "into space. There is a porthole on the far wall. There is a single exit leading aft.", ""
3710 REM aft main corridor
3720 DATA "The main corridor stretches away from you towards the front of the ship. It is featureless"
3730 DATA "and utilitarian. The lighting is dim. You can see doors either side of you, to port and"
3740 DATA "to starboard.", "", ""
3760 REM mid main corridor
3770 DATA "The main corridor stretches away from you both forward and aft. It is featureless"
3780 DATA "and utilitarian. The lighting is dim. You can see doors either side of you, to port and"
3790 DATA "to starboard.", "", ""
3810 REM forward main corridor
3820 DATA "The main corridor stretches away from you towards the rear of the ship. It is featureless"
3830 DATA "and utilitarian. The lighting is dim. You can see doors either side of you, to port and"
3840 DATA "to starboard, as well as a third door leading forward.", "", ""
3860 REM assign to room descriptions
3870 FOR ROOM = 0 to RC-1
3880 FOR I = 0 TO 4
3885 READ DESC$ : RD$ (ROOM, I) = DESC$
3890 NEXT I
3900 NEXT ROOM
4000 RETURN
4010 REM ========== print room description ==========
4020 FOR LINE = 0 TO 4
4030 IF RD$(PL, LINE) <> "" THEN PRINT RD$(PL, LINE)
4040 NEXT LINE
4055 GOSUB 4070
4060 RETURN
4070 REM print objects
4080 FOR I = 0 TO OC-1
4090 IF OL ( I ) = PL THEN PRINT : PRINT "You can see: ";OB$ ( I ); "."
4100 NEXT I
4110 PRINT
4115 IF PL = LAB THEN GOSUB 9700
4120 RETURN
4130 REM ========== print help ==========
4140 PRINT "For movement, try [go] a[ft], f[orward], p[ort], s[tarboard], u[p] or d[own]."
4150 PRINT "For actions, try get, take, drop, examine, look, use, i[nventory], q[uit]."
4155 PRINT "To examine, pick up, use or drop items, refer to them exactly as they are described."
4157 PRINT
4160 RETURN
5000 REM ========== interactive item descriptions ==========
5010 DIM ID$(IC, 20)
5020 REM medical log
5030 DATA "The last few entries of the medical log are still visible on the screen:", " "
5040 DATA "'2142-6-13: Three days since chimpanzee Nova was innoculated with agent #53."
5050 DATA " However, subject Nova showing no signs of adaptation to planetary destination"
5060 DATA " atmosphere. In fact, she appears listless, though punctuated with periods of"
5070 DATA " extreme agression.", " "
5090 DATA " 2142-6-14: This morning, Dr Pearson was bitten by Nova. Very quickly he exhibited"
5100 DATA " signs of a high fever and is now resting in his quarters.", " "
5120 DATA " 2142-6-15: After a brief period of catatonia, Pearson got up on his own, returned"
5130 DATA " to the medical bay and began to compulsively prepare more agent #53 samples. He"
5140 DATA " is otherwise uncommunicative.", " "
5160 DATA " 2142-6-17: Pearson's compulsive behaviour continues unabated. We have a hypothesis"
5170 DATA " for what the virus, which we have now designated HO-1, does to the brain. However,"
5180 DATA " we are struggling to isolate Pearson and may have to seal the medical bay.", " "
5200 DATA " 2142-6-17: Hollow (HO-1) confirmed as airborne, and other cases appearing around the ship."
5210 DATA " Shipwide lockdown declared but crew cohesion and discipline already breaking down.'"
5215 REM porthole
5220 DATA "Looking through the porthole, you seen a spacesuit clad figure floating outside."
5230 DATA "Although he is tethered to an anchor point on the ship's hull, he is otherwise floating"
5240 DATA "freely, his arms and legs splayed out to his sides.", " "
5260 DATA "Peering at the figure more closely, as he slowly rotates, a light from the ship"
5270 DATA "briefly illuminates his face. He's clearly dead, his oxygen ran out some time ago."
5280 DATA "His expression is frozen in a rictus of pain. He was screaming almost until the end ..."
5290 DATA "", "", "", "", "", "", "", "", "", "", "", "", ""
5300 REM console
5310 DATA "The console shows the state of the ship's engines. The pilot"
5320 DATA "appears to have the throttle jammed wide open with his right arm. The muscles in his"
5340 DATA "forearm are taught, there's no way he's going to release the throttle. He left hand"
5350 DATA "works its way around the console switches. After a few moments you realise that he is"
5360 DATA "executing the same sequence of switches over and over again.", " "
5370 DATA "His eyes are glazed, mentally he is somewhere else. He is"
5380 DATA "mumbling to himself but you cannot make out the words, although he appears to be"
5390 DATA "reciting some sort of launch checklist.", " "
5392 DATA "One screen shows the mission parameters:"
5394 DATA " 1. Explore potentially habitable worlds"
5396 DATA " 2. Conduct research to develop gene therapies to aid adaptation to planetary conditions"
5398 DATA " 3. Conduct research to develop custom biologic weapons systems, to protect colonists", " "
5400 DATA "If the engines are online, the ship will be careering through space at maximum"
5410 DATA "speed. Rescue will be impossible unless the engines are offline."
5420 DATA "", "", ""
5430 REM engine control
5440 DATA "The control panel is grubby, smeared with oil and grime. This is clearly"
5450 DATA "the engineering heart of the ship. Most of the readouts mean nothing to you,"
5460 DATA "whatever your duties were on this ship, you were clearly not a warp engineer.", " "
5470 DATA "Many of the lights on the front panel are flashing red. Not all is well with"
5480 DATA "the Pneuma. Even to your untrained eye, it's obvious that the ship's engines appear to"
5490 DATA "be on the point of burnout, having been run at full capacity for many hours.", " "
5500 DATA "To the top left of the panel, a screen reads:", " "
5510 DATA "'WARNING: CORE BREACH IMMINENT'", " "
5520 DATA "Just below the screen is a large red button, shielded by a cover that can be"
5530 DATA "flipped aside.", "", "", "", "", "", ""
5540 REM library terminal
5550 DATA "A ancient text is open in the terminal: 'The Origin of Consciousness in the Breakdown"
5560 DATA "of the Bicameral Mind by Julian Jaynes, 1976.'", "", "", "", "", "", "", "", "", ""
5570 DATA "", "", "", "", "", "", "", "", ""
5940 FOR OBJECT = 0 TO IC-1
5950 FOR I = 0 TO 19
5960 READ DESC$ : ID$ (OBJECT, I) = DESC$
5970 NEXT I
5980 NEXT OBJECT
5990 RETURN
6000 REM ========== print interative object description ==========
6010 FOR LINE = 0 TO 19
6020 IF ID$(F, LINE) <> "" THEN PRINT ID$(F, LINE)
6030 NEXT LINE
6035 PRINT
6040 RETURN
7000 REM ========== character speech ==========
7010 REM chef
7015 DIM PD$(PC, 4)
7020 DATA "Carrots, potatoes, I'm going to make a nice beef stew."
7030 DATA "This stew is going to be delicious."
7060 REM runner
7070 DATA "24:50, that's my new personal best. Not much further to go!"
7080 DATA "24:50, that's my new personal best. Not much further to go!"
7110 REM pilot
7120 DATA "Main engines online, supercruise on my mark."
7130 DATA "Five ... four ... three ... two ... one ... mark!"
7140 FOR PERSON = 0 TO PC-1
7150 FOR I = 0 TO 1
7160 READ DESC$ : PD$ (PERSON, I) = DESC$
7170 NEXT I
7180 PD$(PERSON, 2) = PD$(PERSON, 0)
7190 PD$(PERSON, 3) = PD$(PERSON, 1)
7200 NEXT PERSON
7210 RETURN
7500 REM ========== print character speech ==========
7510 FOR LINE = 0 TO 4
7520 PRINT PD$(F, LINE)
7530 NEXT LINE
7535 PRINT
7550 RETURN
8000 REM ========== wraith-hound tracking ==========
8010 IF OL ( TRACKER ) <> INV THEN RETURN
8015 IF WPL = 99 THEN PRINT "Tracking: Wraith-hound terminated." : GOTO 8030
8020 PRINT "Tracking: Wraith-hound current location is the "; LO$ ( WPL )
8030 PRINT
8040 RETURN
8200 REM ========== wraith-hound proximity check ==========
8210 DIR$ = ""
8220 IF VAL ( MID$ ( EX$ ( PL ) , 1 , 2 ) ) = WPL THEN DIR$ = "forward of you"
8230 IF VAL ( MID$ ( EX$ ( PL ) , 3 , 2 ) ) = WPL THEN DIR$ = "aft of you"
8240 IF VAL ( MID$ ( EX$ ( PL ) , 5 , 2 ) ) = WPL THEN DIR$ = "to port"
8250 IF VAL ( MID$ ( EX$ ( PL ) , 7 , 2 ) ) = WPL THEN DIR$ = "to starboard"
8260 IF VAL ( MID$ ( EX$ ( PL ) , 9 , 2 ) ) = WPL THEN DIR$ = "above you"
8270 IF VAL ( MID$ ( EX$ ( PL ) , 11 , 2 ) ) = WPL THEN DIR$ = "below you"
8280 IF DIR$ <> "" THEN PRINT "You hear a snarling, spitting noise "; DIR$; ". The tracker is pinging ..."
8285 PRINT
8290 RETURN
8400 REM ========== wraith-hound movement ==========
8410 REM decide to move one third of the time
8420 MOVE = RNDINT(1, 3)
8430 IF MOVE <> 1 THEN RETURN
8440 REM randomly determine direction
8450 DIR = RNDINT(1, 6)
8460 IF DIR = 1 THEN INDEX = 1
8470 IF DIR = 2 THEN INDEX = 3
8480 IF DIR = 3 THEN INDEX = 5
8490 IF DIR = 4 THEN INDEX = 7
8500 IF DIR = 5 THEN INDEX = 9
8510 IF DIR = 6 THEN INDEX = 11
8520 NWPL = VAL ( MID$ ( EX$ ( WPL ) , INDEX , 2 ) ) : REM potential next location
8530 IF NWPL = 0 THEN GOTO 8450 : REM can't go that way
8540 WPL = NWPL
8550 RETURN
9000 REM ========== use an item ==========
9010 F=-1: R$=""
9020 R$ = MID$(LOWER$(I$), 5) : REM R$ is the requested object
9025 IF R$ <> "red button" THEN GOTO 9030
9027 GOSUB 9500
9028 RETURN
9030 REM get the object ID
9040 FOR I= 0 TO OC-1
9050 IF OB$(I) = R$ THEN F=I : REM object exists
9060 NEXT I
9070 REM can't find the item?
9080 IF F=-1 THEN PRINT "You haven't seen that item." : PRINT : RETURN
9090 IF OL(F) <> 0 THEN PRINT "You haven't picked up that item." : PRINT : RETURN
9100 REM item exists and is in inventory
9110 IF F <> SYRINGE THEN GOTO 9140
9112 IF OB$( SYRINGE ) = "blood filled syringe" THEN PRINT "The syringe is full." : PRINT : RETURN
9115 IF SUIT_WORN = 1 THEN PRINT "You can't puncture a spacesuit with a syringe!" : PRINT : RETURN
9120 OB$( SYRINGE ) = "blood filled syringe"
9130 PRINT "You use the syringe to take a blood sample from your arm." : PRINT : RETURN
9140 IF F <> TRACKER THEN GOTO 9160
9150 PRINT "The tracker is always on." : PRINT
9160 IF F <> SUIT THEN GOTO 9200
9170 IF OL(F) <> 0 THEN PRINT "You don't have a space suit." : PRINT : RETURN
9175 IF SUIT_WORN = 1 THEN PRINT "You're already wearing the space suit." : PRINT : RETURN
9180 SUIT_WORN = 1
9190 PRINT "You put on the space suit." : PRINT
9400 RETURN
9500 REM special button routine
9510 IF PL <> ENG THEN PRINT "There is no red button here." : PRINT : RETURN
9520 IF SHUTDOWN = 0 THEN GOTO 9540
9525 SHUTDOWN = 0
9530 PRINT "Engine restart initiated ... engines online." : PRINT
9535 ID$ (ENGINE, 10) = "'WARNING: CORE BREACH IMMINENT'" : RETURN
9540 SHUTDOWN = 1
9550 PRINT "Engine shutdown initiated ... engines offline." : PRINT
9555 ID$ (ENGINE, 10) = "'ENGINES OFFLINE'"
9560 RETURN
9700 REM ========== laboratory conversation ==========
9710 PRINT "Dr Lascoe is stood in the laboratory. He is armed. He speaks to you." : PRINT
9720 PRINT "'It's you! You were infected with HO-1, but you seem to be normal."
9730 PRINT " Hollow destroys consciousness, it shuts down all self awareness in the brain."
9740 PRINT " The patient still functions to a degree, but they're an automaton, endlessly"
9750 PRINT " running the same mental subroutines like a piece of clockwork until the body"
9760 PRINT " breaks down.'" : PRINT
9770 PRINT "'I've been hiding in here to avoid contagion. Someone released the wraith-hound"
9780 PRINT " from containment, but I've been able to keep it away with this weapon."
9790 PRINT " But if you're immune, I can develop a vaccine from your blood.'" : PRINT
9800 IF OL(SYRINGE) = 0 AND OB$(SYRINGE) = "blood filled syringe" THEN GOTO 9820
9810 PRINT "'You need to get me a sample of your blood.'" : PRINT : RETURN
9820 PRINT "'Ah, I see you have a blood sample, excellent.'" : PRINT
9830 IF SUIT_WORN = 1 THEN GOTO 9855
9840 PRINT " I still don't want to take the risk that you are contagious. Put on a space"
9850 PRINT " suit and then I'll let you approach me.'" : PRINT: RETURN
9855 PRINT "'Good, you're wearing a suit to avoid contaminating me.'" : PRINT
9860 IF SHUTDOWN = 1 THEN GOTO 9885
9870 PRINT "'Rescue will be impossible while the engines are running out of control."
9880 PRINT " You'll need to take them offline.'": PRINT : RETURN
9885 PRINT "'Good job on taking the engines offline, you've saved us both!"
9890 PRINT " I'll work up the serum and we can wait for rescue.'" : PRINT
9900 GOSUB 10000
9910 RETURN
10000 REM ========== finale ==========
10010 PRINT "Congratulations, you have save Pneuma and helped Dr Lascoe develop"
10020 PRINT "vaccine against HO-1, the Hollow virus."
10030 PRINT : PRINT " THE END" : PRINT
10040 STOP
11000 REM ========== fight ==========
11010 PRINT "The wraith-hound arrives. It is an abomination! A weapon system that"
11020 PRINT "nature would never have created unaided. Everything about it is just"
11030 PRINT "plain wrong on so many levels. One thing is clear, it is designed"
11035 PRINT "purely for hunting and killing." : PRINT
11040 INPUT "Do you r[un] or f[ight]?"; I$
11050 PRINT
11060 IF LOWER$ ( I$ ) = "f" OR LOWER$ ( I$ ) = "fight" THEN GOTO 11190
11065 IF LOWER$ ( I$ ) = "r" OR LOWER$ ( I$ ) = "run" THEN GOTO 11070
11067 PRINT "Command unrecognised, you must fight!" : PRINT : GOTO 11190
11070 REM run away to a random adjoining room
11080 DIR = RNDINT(1, 6)
11090 IF DIR = 1 THEN INDEX = 1
11100 IF DIR = 2 THEN INDEX = 3
11110 IF DIR = 3 THEN INDEX = 5
11120 IF DIR = 4 THEN INDEX = 7
11130 IF DIR = 5 THEN INDEX = 9
11140 IF DIR = 6 THEN INDEX = 11
11150 NPL = VAL ( MID$ ( EX$ ( PL ) , INDEX , 2 ) ) : REM potential next location
11160 IF NPL = 0 THEN GOTO 11080 : REM can't go that way
11170 PL = NPL : PRINT "You are in the " ; LO$ ( PL ) : PRINT
11175 GOSUB 4010
11180 RETURN
11190 REM fight
11200 FEROCITY = 60 : REM ferocity factor for wraith-hound
11205 STAMINA = 50 : REM your stamina
11210 IF OL(PULSE) <> INV AND OL(KNIFE) <> INV THEN PRINT "You have no weapons, and must fight bare handed." : PRINT : GOTO 11280
11220 IF OL(PULSE) = INV AND OL(KNIFE) <> INV THEN PRINT "Luckily, you have a pulse rifle." : PRINT: FEROCITY=50 : GOTO 11280
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
11240 INPUT "Which weapon do you choose? 1 - Pulse rifle, 2 - Knife: "; WPN
11245 PRINT
11250 IF WPN<1 OR WPN>2 THEN GOTO 11240
11260 IF WPN=1 THEN FEROCITY = 50
11270 IF WPN=2 THEN FEROCITY = 55
11280 REM the battle
11290 IF RND(1)>0.5 THEN PRINT "The wraith-hound attacks!" ELSE PRINT "You attack!"
11300 PRINT
11305 GOSUB 11430
11310 IF RND(1)>0.5 THEN PRINT "You wound the creature." : PRINT: FEROCITY = FEROCITY-5 : GOTO 11330
11320 PRINT "The wraith-hound wounds you." : PRINT : STAMINA = STAMINA-5
11330 GOSUB 11430
11340 IF FEROCITY > 0 THEN GOTO 11390
11350 PRINT "You slayed the wraith-hound!" : PRINT
11360 REM remove creature from the game
11370 WPL = 99 : REM inaccessible location
11380 RETURN
11390 IF STAMINA > 0 THEN GOTO 11420
11400 PRINT "You were slayed by the wraith-hound! You have failed to save the Pneuma." : PRINT
11410 STOP
11420 GOTO 11280 : REM next round of the battle
11430 REM ========== delay loop ==========
11440 FOR T = 1 TO 80000
11450 NEXT T
11460 RETURN

View file

@ -0,0 +1,682 @@
520 REM
530 REM
540 REM **** **** STAR TREK **** ****
550 REM **** Simulation of a mission of the starship ENTERPRISE
560 REM **** as seen on the Star Trek tv show
570 REM **** Original program in Creative Computing
580 REM **** Basic Computer Games by Dave Ahl
590 REM **** Modifications by Bob Fritz and Sharon Fritz
600 REM **** for the IBM Personal Computer, October-November 1981
610 REM **** Bob Fritz, 9915 Caninito Cuadro, San Diego, Ca., 92129
620 REM **** (714) 484-2955
630 REM ****
640 PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT:PRINT
650 E1$= " ,-----------------, _"
660 E2$= " `---------- ----',-----/ \----,"
670 E3$= " | | '- --------'"
680 E4$= " ,--' '------/ /--,"
690 E5$= " '-----------------'"
691 PRINT
700 E6$= " THE USS ENTERPRISE --- NCC-1701"
720 PRINT E1$
730 PRINT E2$
740 PRINT E3$
750 PRINT E4$
760 PRINT E5$
770 PRINT
780 PRINT E6$
790 PRINT:PRINT: PRINT:PRINT:PRINT:PRINT:PRINT
811 RANDOMIZE
960 dim D(8)
961 dim C(9,2)
962 dim K(3,3)
963 dim N(3)
965 DIM G(8,8)
966 DIM Z(8,8)
970 T=INT(RND(1)*20+20)*100:T0=T:T9=25+INT(RND(1)*10):D0=0:E=3000:E0=E
980 P=10:P0=P:S9=200:S=0:B9=0:K9=0:X$="":X0$=" is "
990 rem DEF FND(D)=SQR((K(I,1)-S1)^2+(K(I,2)-S2)^2)
1000 rem DEF FNR(R)=INT(RND(1)(R)*7.98+1.01)
1010 REM initialize enterprise's position
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)
1030 FOR I=1 TO 9
1031 C(I,1)=0:C(I,2)=0
1032 NEXT I
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
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
1060 FOR I=1 TO 8
1061 D(I)=0
1062 NEXT I
1070 A1$="NAVSRSLRSPHATORSHIDAMCOMRES"
1080 REM set up what exists in galaxy
1090 REM k3=#klingons b3=#starbases s3=#stars
1100 FOR I=1 TO 8
1101 FOR J=1 TO 8
1102 K3=0:Z(I,J)=0:R1=RND(1)
1110 IF R1<=0.9799999 THEN goto 1120
1111 K3=3:K9=K9+3: GOTO 1140
1120 IF R1<=0.95 THEN goto 1130
1121 K3=2:K9=K9+2: GOTO 1140
1130 IF R1<=0.8 THEN goto 1140
1131 K3=1:K9=K9+1
1140 B3=0:IF RND(1)<=0.96 THEN goto 1150
1141 B3=1:B9=B9+1
1150 G(I,J)=K3*100+B3*10+INT(RND(1)*7.98+1.01)
1151 NEXT J
1152 NEXT I
1153 IF K9<=T9 THEN goto 1160
1154 T9=K9+1
1160 IF B9<>0 THEN 1190
1170 IF G(Q1,Q2)>=200 THEN 1180
1171 G(Q1,Q2)=G(Q1,Q2)+100:K9=K9+1
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)
1190 K7=K9:IF B9=1 THEN 1200
1191 X$="s":X0$=" are "
1200 PRINT" Your orders are as follows: "
1210 PRINT" Destroy the ";K9;" Klingon warships which have invaded"
1220 PRINT" the galaxy before they can attack Federation headquarters"
1230 PRINT" on stardate ";T0+T9;". This gives you ";T9;" days. there";X0$
1240 PRINT" ";B9;" starbase";X$;" in the galaxy for resupplying your ship"
1261 PRINT:INPUT"hit return when ready to accept command";i$
1270 REM here any time new quadrant entered
1280 Z4=Q1:Z5=Q2:K3=0:B3=0:S3=0:G5=0:D4=0.5*RND(1):Z(Q1,Q2)=G(Q1,Q2)
1290 IF Q1<1 OR Q1>8 OR Q2<1 OR Q2>8 THEN 1410
1300 GOSUB 5040
1301 PRINT:IF T0 <>T THEN 1330
1310 PRINT"Your mission begins with your starship located"
1320 PRINT"in the galactic quadrant, '";G2$;"'.":GOTO 1340
1330 PRINT"Now entering ";G2$;" quadrant. . ."
1340 PRINT:K3=INT(G(Q1,Q2)*0.01):B3=INT(G(Q1,Q2)*0.1)-10*K3
1350 S3=G(Q1,Q2)-100*K3-10*B3:IF K3=0 THEN 1400
1360 PRINT "COMBAT AREA!! Condition";
1370 PRINT " RED "; : PRINT
1380 GOSUB 5290
1381 IF S>200 THEN 1400
1390 PRINT" SHIELDS DANGEROUSLY LOW"; : PRINT
1400 FOR I=1 TO 3
1401 K(I,1)=0:K(I,2)=0
1402 NEXT I
1410 FOR I=1 TO 3
1411 K(I,3)=0
1412 NEXT I
1413 Q$=" "*192
1420 REM position enterprise in quadrant, then place "k3" klingons,&
1430 REM "b3" starbases & "s3" stars elsewhere.
1440 A$="\e/":Z1=S1:Z2=S2
1441 GOSUB 4830
1442 IF K3<1 THEN 1470
1450 FOR I=1 TO K3
1451 GOSUB 4800
1452 A$=chr$(187)+"K"+chr$(171):Z1=R1:Z2=R2
1460 GOSUB 4830
1461 K(I,1)=R1:K(I,2)=R2:K(I,3)=S9*(0.5+RND(1))
1462 NEXT I
1470 IF B3<1 THEN 1500
1480 GOSUB 4800
1481 A$="("+chr$(174)+")":Z1=R1:B4=R1:Z2=R2:B5=R2
1490 GOSUB 4830
1500 FOR I=1 TO S3
1501 GOSUB 4800
1502 A$=" * ":Z1=R1:Z2=R2
1503 GOSUB 4830
1504 NEXT I
1510 GOSUB 3720
1520 IF S+E<=10 THEN 1530
1521 IF E>10 OR D(7)>=0 THEN 1580
1530 PRINT"*** FATAL ERROR ***";
1531 GOSUB 5290
1540 PRINT"You've just stranded your ship in "
1550 PRINT"space":PRINT"You have insufficient maneuvering energy,";
1560 PRINT" and shield control":PRINT"is presently incapable of cross";
1570 PRINT"-circuiting to engine room!!":GOTO 3480
1580 INPUT"command ";A$
1590 FOR I=1 TO 9
1591 IF MID$(A$,1,3)<> MID$(A1$,3*I-2,3) THEN 1610
1600 ON I GOTO 1720,1510,2440,2530,2750,3090,3180,3980,3510
1610 NEXT I
1611 PRINT"Enter one of the following:"
1620 PRINT" NAV (to set course)"
1630 PRINT" SRS (for short range sensor scan)"
1640 PRINT" LRS (for long range sensor scan)"
1650 PRINT" PHA (to fire phasers)"
1660 PRINT" TOR (to fire photon torpedoes)"
1670 PRINT" SHI (to raise or lower shields)"
1680 PRINT" DAM (for damage control reports)"
1690 PRINT" COM (to call on library-computer)"
1700 PRINT" RES (to resign your command)":PRINT:GOTO 1520
1710 REM course control begins here
1720 INPUT"Course (1-9) ";C2$:C1=VAL(C2$):IF C1<>9 THEN 1730
1721 C1=1
1730 IF C1>=1 AND C1<9 THEN 1750
1740 PRINT" Lt. Sulu reports, 'Incorrect course data, sir!'":GOTO 1520
1750 X$="8":IF D(1)>=0 THEN 1760
1751 X$="0.2"
1760 PRINT"Warp factor(0-";X$;") ";:INPUT C2$:W1=VAL(C2$):IF D(1)<0 AND W1>0.2 THEN 1810
1770 IF W1>0 AND W1<8 THEN 1820
1780 IF W1=0 THEN 1520
1790 PRINT" Chief Engineer Scott reports 'The engines won't take";
1800 PRINT" warp ";W1;"!":GOTO 1520
1810 PRINT"Warp engines are damaged. Maximum speed = warp 0.2":GOTO 1520
1820 N1=INT(W1*8+0.5):IF E-N1>=0 THEN 1900
1830 PRINT"Engineering reports 'Insufficient energy available"
1840 PRINT" for maneuvering at warp ";W1;"!'"
1850 IF S<N1-E OR D(7)<0 THEN 1520
1860 PRINT"Deflector control room acknowledges ";S;" units of energy"
1870 PRINT" presently deployed to shields."
1880 GOTO 1520
1890 REM klingons move/fire on moving starship . . .
1900 FOR I=1 TO K3
1901 IF K(I,3)=0 THEN 1930
1910 A$=" ":Z1=K(I,1):Z2=K(I,2)
1911 GOSUB 4830
1912 GOSUB 4800
1920 K(I,1)=Z1:K(I,2)=Z2:A$=chr$(187)+"K"+chr$(171)
1921 GOSUB 4830
1930 NEXT I
1931 REM GOSUB 4810
1932 D1=0:D6=W1:IF W1<1 THEN 1940
1933 D6=1
1940 FOR I=1 TO 8
1941 IF D(I)>=0 THEN 1990
1950 D(I)=min(0,D(I)+D6):IF D(I)<=-0.1 or D(I)>=0 THEN 1960
1951 D(I)=-0.1
1952 GOTO 1990
1960 IF D(I)<0 THEN 1990
1970 IF D1=1 THEN 1980
1971 D1=1:PRINT"DAMAGE CONTROL REPORT: ";
1980 PRINT TAB(8);:R1=I
1981 GOSUB 4890
1982 PRINT G2$;" Repair completed."
1990 NEXT I
1991 IF RND(1)>0.2 THEN 2070
2000 R1=INT(RND(1)*7.98+1.01):IF RND(1)>=0.6 THEN 2040
2010 IF K3=0 THEN 2070
2020 D(R1)=D(R1)-(RND(1)*5+1):PRINT"DAMAGE CONTROL REPORT: ";
2030 GOSUB 4890
2031 PRINT G2$;" damaged":PRINT:GOTO 2070
2040 D(R1)=min(0,D(R1)+RND(1)*3+1):PRINT"DAMAGE CONTROL REPORT: ";
2050 GOSUB 4890
2051 PRINT G2$;" State of repair improved":PRINT
2060 REM begin moving starship
2070 A$=" " :Z1=INT(S1):Z2=INT(S2)
2071 GOSUB 4830
2079 Z1=INT(C1):C1=C1-Z1
2080 X1=C(Z1,1)+(C(Z1+1,1)-C(Z1,1))*C1:X=S1:Y=S2
2090 X2=C(Z1,2)+(C(Z1+1,2)-C(Z1,2))*C1:Q4=Q1:Q5=Q2
2100 FOR I=1 TO N1
2101 S1=S1+X1:S2=S2+X2:IF S1<1 OR S1>=9 OR S2<1 OR S2>=9 THEN 2220
2110 S8=INT(S1)*24+INT(S2)*3-26:IF MID$(Q$,S8+1,2)=" " THEN 2140
2120 S1=INT(S1-X1):S2=INT(S2-X2):PRINT"Warp engines shut down at ";
2130 PRINT "sector ";S1;",";S2;" due to bad navigation.":GOTO 2150
2140 NEXT I
2141 S1=INT(S1):S2=INT(S2)
2150 A$="\e/"
2160 Z1=INT(S1):Z2=INT(S2)
2161 GOSUB 4830
2162 GOSUB 2390
2163 T8=1
2170 IF W1>=1 THEN 2180
2171 T8=0.1*INT(10*W1)
2180 T=T+T8:IF T>T0+T9 THEN 3480
2190 REM see if docked then get command
2200 GOTO 1510
2210 REM exceeded quadrant limits
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)
2230 S2=INT(Y-Q2*8):IF S1<>0 THEN 2240
2231 Q1=Q1-1:S1=8
2240 IF S2<>0 THEN 2250
2241 Q2=Q2-1:S2=8
2250 X5=0:IF Q1>=1 THEN 2260
2251 X5=1:Q1=1:S1=1
2260 IF Q1<=8 THEN 2270
2261 X5=1:Q1=8:S1=8
2270 IF Q2>=1 THEN 2280
2271 X5=1:Q2=1:S2=1
2280 IF Q2<=8 THEN 2290
2281 X5=1:Q2=8:S2=8
2290 IF X5=0 THEN 2360
2300 PRINT"Lt. Uhura reports message from Starfleet Command:"
2310 PRINT" 'Permission to attempt crossing of galactic perimeter"
2320 PRINT" is hereby *DENIED*. Shut down your engines.'"
2330 PRINT"Chief Engineer Scott reports 'Warp engines shut down"
2340 PRINT" at sector ";S1;",";S2;" of quadrant ";Q1;",";Q2".'"
2350 IF T>T0 THEN 3480
2360 IF 8*Q1+Q2=8*Q4+Q5 THEN 2150
2370 T=T+1
2371 GOSUB 2390
2372 GOTO 1280
2380 REM maneuver energy s/r **
2390 E=E-N1-10:IF E<=0 THEN 2400
2391 RETURN
2400 PRINT"Shield control supplies energy to complete the maneuver."
2410 S=S+E:E=0:IF S<=0 THEN 2420
2411 S=0
2420 RETURN
2430 REM long range sensor scan code
2440 IF D(3)>=0 THEN 2450
2441 PRINT"Long Range Sensors are inoperable":GOTO 1520
2450 PRINT"Long Range Scan for quadrant ";Q1;",";Q2
2460 PRINT "-"*19
2470 FOR I=Q1-1 TO Q1+1
2471 N(1)=-1:N(2)=-2:N(3)=-3
2472 FOR J=Q2-1 TO Q2+1
2480 IF I<=0 or I>=9 or J<=0 or J>=9 THEN 2490
2481 N(J-Q2+2)=G(I,J)
2482 REM added so long range sensor scans are added to computer database
2483 z(i,j)=g(i,j)
2490 NEXT J
2491 FOR L=1 TO 3
2492 PRINT"| ";
2493 IF N(L)>=0 THEN 2500
2494 PRINT"*** ";:GOTO 2510
2500 PRINT MID$(STR$(N(L)+1000),2,3);" ";
2510 NEXT L
2511 PRINT"|"
2512 PRINT "-"*19
2513 NEXT I
2514 GOTO 1520
2520 REM phaser control code begins here
2530 IF D(4)>=0 THEN 2540
2531 PRINT"Phasers Inoperative":GOTO 1520
2540 IF K3>0 THEN 2570
2550 PRINT"Science Officer Spock reports 'Sensors show no enemy ships"
2560 PRINT" in this quadrant'":GOTO 1520
2570 IF D(8)>=0 THEN 2580
2571 PRINT"Computer failure hampers accuracy"
2580 PRINT"Phasers locked on target ";
2590 PRINT"Energy available = ";E;" units"
2600 INPUT"Numbers of units to fire ";X:IF X<=0 THEN 1520
2610 IF E-X<0 THEN 2590
2620 E=E-X
2621 GOSUB 5420
2622 IF D(7)<0 THEN 2630
2623 X=X*RND(1)
2630 H1=INT(X/K3)
2631 FOR I=1 TO 3
2632 IF K(I,3)<=0 THEN 2730
2640 KSQ1 = (K(I,1)-S1)*(K(I,1)-S1)
2641 KSQ2 = (K(I,2)-S2)*(K(I,2)-S2)
2642 H= SQR( KSQ1 + KSQ2 )
2646 H = H1 / H
2647 H = INT(H * (RND(1)+2))
2648 IF H>0.15*K(I,3) THEN 2660
2650 PRINT"Sensors show no damage to enemy at ";K(I,1);",";K(I,2):GOTO 2730
2660 K(I,3)=K(I,3)-H:PRINT H;"Unit hit on Klingon at sector ";K(I,1);",";
2670 PRINT K(I,2):IF K(I,3)> 0 THEN GOTO 2700
2680 PRINT "**** KLINGON DESTROYED ****"
2690 GOTO 2710
2700 PRINT" (Sensors show ";K(I,3);" units remaining)":GOTO 2730
2710 K3=K3-1:K9=K9-1:Z1=K(I,1):Z2=K(I,2):A$=" "
2711 GOSUB 4830
2720 K(I,3)=0:G(Q1,Q2)=G(Q1,Q2)-100:Z(Q1,Q2)=G(Q1,Q2):IF K9<=0 THEN 3680
2730 NEXT I
2731 GOSUB 3350
2732 GOTO 1520
2740 REM photon torpedo code begins here
2750 IF P>0 THEN 2760
2751 PRINT"All photon torpedoes expended":GOTO 1520
2760 IF D(5)>=0 THEN 2770
2761 PRINT"Photon tubes are not operational":GOTO 1520
2770 INPUT"Photon torpedo course (1-9) ";C2$:C1=VAL(C2$):IF C1<>9 THEN 2780
2771 C1=1
2780 IF C1>=1 AND C1<9 THEN 2810
2790 PRINT"Ensign Chekov reports, 'Incorrect course data, sir!'"
2800 GOTO 1520
2810 Z1=INT(C1):C1=C1-Z1
2811 X1=C(Z1,1)+(C(Z1+1,1)-C(Z1,1))*C1:E=E-2:P=P-1
2820 X2=C(Z1,2)+(C(Z1+1,2)-C(Z1,2))*C1:X=S1:Y=S2
2821 GOSUB 5360
2830 PRINT"Torpedo track:"
2840 X=X+X1:Y=Y+X2:X3=INT(X+0.5):Y3=INT(Y+0.5)
2850 IF X3<1 OR X3>8 OR Y3<1 OR Y3>8 THEN 3070
2860 PRINT" ";X3;",";Y3:A$=" ":Z1=X:Z2=Y
2861 GOSUB 4990
2870 IF Z3<>0 THEN 2840
2880 A$=chr$(187)+"K"+chr$(171):Z1=X:Z2=Y
2881 GOSUB 4990
2882 IF Z3=0 THEN 2940
2890 PRINT"**** KLINGON DESTROYED ****"
2900 K3=K3-1:K9=K9-1:IF K9<=0 THEN 3680
2910 FOR I=1 TO 3
2911 IF X3=K(I,1) AND Y3=K(I,2) THEN 2930
2920 NEXT I
2921 I=3
2930 K(I,3)=0:GOTO 3050
2940 A$=" * ":Z1=X:Z2=Y
2941 GOSUB 4990
2942 IF Z3=0 THEN 2960
2950 PRINT"Star at ";X3;",";Y3;" absorbed torpedo energy."
2951 GOSUB 3350
2952 GOTO 1520
2960 A$="("+chr$(174)+")":Z1=X:Z2=Y
2961 GOSUB 4990
2962 IF Z3<>0 THEN 2970
2963 PRINT "Torpedo absorbed by unknown object at ";x3;",";y3
2964 goto 1520
2970 PRINT"*** STARBASE DESTROYED ***"
2980 B3=B3-1 : B9=B9-1
2990 IF B9>0 OR K9>T-T0-T9 THEN 3030
3000 PRINT"THAT DOES IT, CAPTAIN!! You are hereby relieved of command"
3010 PRINT"and sentenced to 99 stardates of hard labor on CYGNUS 12!!"
3020 GOTO 3510
3030 PRINT"Starfleet reviewing your record to consider"
3040 PRINT"court martial!":D0=0
3050 Z1=X:Z2=Y:A$=" "
3051 GOSUB 4830
3060 G(Q1,Q2)=K3*100+B3*10+S3:Z(Q1,Q2)=G(Q1,Q2)
3061 GOSUB 3350
3062 GOTO 1520
3070 PRINT"Torpedo missed"
3071 GOSUB 3350
3072 GOTO 1520
3080 REM shield control
3090 IF D(7)>=0 THEN 3100
3091 PRINT"Shield control inoperable":GOTO 1520
3100 PRINT"Energy available = ";E+S :INPUT "Number of units to shields? ";X
3110 IF X>=0 and S<>X THEN 3120
3111 PRINT"<shields unchanged>":GOTO 1520
3120 IF X<E+S THEN 3150
3130 PRINT"Shield Control reports: This is not the federation treasury."
3140 PRINT"<shields unchanged>":goto 1990
3150 E=E+S-X:S=X:PRINT"Deflector Control Room report:"
3160 PRINT" 'Shields now at ";INT(S);" units per your command.'":GOTO 1520
3170 REM damage control
3180 IF D(6)>=0 THEN 3290
3190 PRINT"Damage control report not available":IF D0=0 THEN 1520
3200 D3=0:FOR I=1 TO 8
3201 IF D(I)>=0 THEN 3210
3202 D3=D3+1
3210 NEXT I
3211 IF D3=0 THEN 1520
3220 PRINT:D3=D3+D4:IF D3<1 THEN 3230
3221 D3=0.9
3230 PRINT"Technicians standing by to effect repairs to your ship;"
3240 PRINT"estimated time to repair: ";0.01*INT(100*D3);" stardates"
3250 INPUT"Will you authorize the repair order (Y/N)? ";A$
3260 IF A$<>"y" AND A$<> "Y" THEN 1520
3270 FOR I=1 TO 8
3271 IF D(I)>=0 THEN 3280
3272 D(I)=0
3280 NEXT I
3281 T=T+D3+0.1
3290 PRINT:PRINT"Device state of repair"
3291 FOR R1=1 TO 8
3300 GOSUB 4890
3301 PRINT G2$;tab(25);
3310 GG2=INT(D(R1)*100)*0.01:PRINT GG2
3320 NEXT R1
3321 PRINT:IF D0<>0 THEN 3200
3330 GOTO 1520
3340 REM klingons shooting
3350 IF K3>0 THEN 3360
3351 RETURN
3360 IF D0=0 THEN 3370
3361 PRINT"Starbase shields protect the ENTERPRISE"
3362 RETURN
3370 FOR I=1 TO 3
3371 IF K(I,3)<=0 THEN 3460
3380 ksq1 = (K(I,1)-S1)*(K(I,1)-S1)
3381 ksq2 = (K(I,2)-S2)*(K(I,2)-S2)
3382 H=( K(I,3) / SQR( ksq1 + ksq2 ) )*(2+RND(1))
3383 h = int(h)
3384 S=S-H:K(I,3)=K(I,3)/(3+RND(1))
3390 PRINT "ENTERPRISE HIT!"
3400 GOSUB 5480
3401 PRINT H;" Unit hit on ENTERPRISE from sector ";K(I,1);",";K(I,2)
3410 IF S<=0 THEN 3490
3420 PRINT" <shields down to ";S;" units>":IF H<20 THEN 3460
3430 IF RND(1)>0.6 OR H/S<=0.02 THEN 3460
3440 R1=INT(RND(1)*7.98+1.01):D(R1)=D(R1)-H/S-0.5*RND(1)
3441 GOSUB 4890
3450 PRINT"Damage control reports '";G2$;" damaged by the hit'"
3460 NEXT I
3461 RETURN
3470 REM end of game
3480 PRINT"It is stardate";T:GOTO 3510
3490 PRINT:PRINT"the ENTERPRISE has been destroyed. The Federation ";
3500 PRINT"will be conquered":GOTO 3480
3510 PRINT"There were ";K9;" Klingon battle cruisers left at"
3520 PRINT"the end of your mission"
3530 PRINT:PRINT:IF B9=0 THEN 3670
3540 PRINT"The Federation is in need of a new starship commander"
3550 PRINT"for a similar mission -- if there is a volunteer,"
3560 INPUT"let him or her step forward and enter 'AYE' ";X$:IF X$="AYE" THEN 520
3670 END
3680 PRINT"Congratulations, Captain! the last Klingon battle cruiser"
3690 PRINT"menacing the Federation has been destroyed.":PRINT
3700 PRINT"Your efficiency rating is ";:cc1 = k7/(t-t0):PRINT 1000*cc1*cc1:GOTO 3530
3710 REM short range sensor scan & startup subroutine
3720 A$="("+chr$(174)+")":Z3=0
3721 FOR I=S1-1 TO S1+1
3722 FOR J=S2-1 TO S2+1
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
3750 Z1=I:Z2=J
3751 GOSUB 4990
3760 NEXT J
3761 NEXT I
3762 IF Z3=1 THEN 3770
3763 D0=0:GOTO 3790
3770 D0=1:C$="docked":E=E0:P=P0
3780 PRINT"Shields dropped for docking purposes":S=0:GOTO 3810
3790 IF K3<=0 THEN 3800
3791 C$="*red*":GOTO 3810
3800 C$="GREEN":IF E>=E0*0.1 THEN 3810
3801 C$="YELLOW"
3810 IF D(2)>=0 THEN 3830
3820 PRINT:PRINT"*** Short Range Sensors are out ***":PRINT
3821 RETURN
3830 PRINT "-"*33
3832 FOR I=1 TO 8
3840 FOR J=(I-1)*24 TO (I-1)*24+21 STEP 3
3850 IF MID$(Q$,J+1,3)<>" " THEN 3860
3851 PRINT " . ";:GOTO 3861
3860 PRINT " ";MID$(Q$,J+1,3);
3861 NEXT J
3870 ON I GOTO 3880,3900,3910,3920,3930,3940,3950,3960
3880 PRINT" Stardate ";
3890 TT= T*10 : TT=INT(TT)*0.1:PRINT TT :GOTO 3970
3900 PRINT" Condition ";C$:GOTO 3970
3910 PRINT" Quadrant ";Q1;",";Q2:GOTO 3970
3920 PRINT" Sector ";S1;",";S2:GOTO 3970
3930 PRINT" Photon torpedoes ";INT(P):GOTO 3970
3940 PRINT" Total energy ";INT(E+S):GOTO 3970
3950 PRINT" Shields ";INT(S):GOTO 3970
3960 PRINT" Klingons remaining ";INT(K9)
3970 NEXT I
3971 PRINT "-"*33
3972 RETURN
3980 REM library computer code
3990 CM1$="GALSTATORBASDIRREG"
4000 IF D(8)>=0 THEN 4010
4001 PRINT"Computer Disabled":GOTO 1520
4010 rem KEY 1, "GAL RCD"+CHR$(13)
4020 rem KEY 2, "STATUS"+CHR$(13)
4030 rem KEY 3, "TOR DATA"+CHR$(13)
4040 rem KEY 4, "BASE NAV"+CHR$(13)
4050 rem KEY 5, "DIR/DIST"+CHR$(13)
4060 rem KEY 6, "REG MAP"+CHR$(13)
4070 rem KEY 7,CHR$(13):KEY 8,CHR$(13):KEY 9,CHR$(13):KEY 10,CHR$(13)
4071 gosub 4130
4080 INPUT"Computer active and awaiting command ";CM$:H8=1
4090 FOR K1= 1 TO 6
4100 IF MID$(CM$,1,3)<>MID$(CM1$,3*K1-2,3) THEN 4120
4110 ON K1 GOTO 4250,4400,4490,4750,4550,4210
4120 NEXT K1
4121 gosub 4130
4122 goto 4080
4130 PRINT"Functions available from library-computer:"
4140 PRINT" GAL = Cumulative galactic record"
4150 PRINT" STA = Status report"
4160 PRINT" TOR = Photon torpedo data"
4170 PRINT" BAS = Starbase nav data"
4180 PRINT" DIR = Direction/distance calculator"
4190 PRINT" REG = Galaxy 'region name' map":PRINT
4191 return
4200 REM setup to change cum gal record to galaxy map
4210 H8=0:G5=1:PRINT" the galaxy":GOTO 4290
4250 PRINT:PRINT" ";
4270 PRINT "Computer record of galaxy for quadrant ";Q1;",";Q2
4280 PRINT
4290 PRINT" 1 2 3 4 5 6 7 8"
4300 O1$=" ----- ----- ----- ----- ----- ----- ----- -----"
4310 PRINT O1$
4311 FOR I=1 TO 8
4312 PRINT I;" ";:IF H8=0 THEN 4350
4320 FOR J=1 TO 8
4321 PRINT" ";:IF Z(I,J)<>0 THEN 4330
4322 PRINT"***";:GOTO 4340
4330 ZLEN = len(str$(z(i,j)+1000)
4331 PRINT MID$(STR$(Z(I,J)+1000),zlen-2,3);
4340 NEXT J
4341 GOTO 4370
4350 Z4=I:Z5=1
4351 GOSUB 5040
4352 J0=INT(15-0.5*LEN(G2$)):PRINT TAB(J0);G2$;
4360 Z5=5
4361 GOSUB 5040
4362 J0=INT(40-0.5*LEN(G2$)):PRINT TAB(J0);G2$;
4370 PRINT:PRINT O1$
4371 NEXT I
4372 PRINT
4373 rem 'POKE 1229,0 POKE 1237,1
4380 GOTO 1520
4390 REM status report
4400 PRINT" Status Report":X$="":IF K9<=1 THEN 4410
4402 X$="s"
4410 PRINT"Klingon";X$;" left: ";K9
4420 PRINT"Mission must be completed in ";0.1*INT((T0+T9-T)*10);" stardates"
4430 X$="s":IF B9>=2 THEN 4440
4431 X$="":IF B9<1 THEN 4460
4440 PRINT"The federation is maintaining ";B9;" starbase";X$;" in the galaxy"
4450 GOTO 3180
4460 PRINT"Your stupidity has left you on your own in"
4470 PRINT" the galaxy -- you have no starbases left!":GOTO 3180
4480 REM torpedo, base nav, d/d calculator
4490 IF K3<=0 THEN 2550
4500 X$="":IF K3<=1 THEN 4510
4501 X$="s"
4510 PRINT"From ENTERPRISE to Klingon battle cruiser";X$
4520 H8=0:FOR I=1 TO 3
4521 IF K(I,3)<=0 THEN 4740
4530 W1=K(I,1):X=K(I,2)
4540 C1=S1:A=S2:GOTO 4590
4550 PRINT"Direction/Distance Calculator:"
4560 PRINT"You are at quadrant ";Q1;",";Q2;" sector ";S1;",";S2
4570 PRINT"Please enter ":INPUT" initial coordinates (x,y) ";C1,A
4580 INPUT" Final coordinates (x,y) ";W1,X
4590 X=X-A:A=C1-W1:aa=abs(a):ax=abs(x):IF X<0 THEN 4670
4600 IF A<0 THEN 4690
4610 IF X>0 THEN 4630
4620 IF A<>0 THEN 4630
4621 C1=5:GOTO 4640
4630 C1=1
4640 IF AA<=AX THEN 4660
4650 PRINT"Direction1 = ";:cc1=(AA-AX+AA)/AA:PRINT c1+cc1:GOTO 4730
4660 PRINT"Direction2 = ";:cc1=C1+(AA/AX):PRINT cc1:GOTO 4730
4670 IF A<=0 THEN 4680
4671 C1=3:GOTO 4700
4680 IF X=0 THEN 4690
4681 C1=5:GOTO 4640
4690 C1=7
4700 IF AA>=AX THEN 4720
4710 PRINT"Direction3 = ";:cc1=(AX-AA+AX)/AX:PRINT c1+cc1:GOTO 4730
4720 PRINT"Direction4 = ";:CC1=C1+(AX/AA):PRINT CC1
4730 PRINT"Distance = ";:cc1=SQR(x*X+A*A):PRINT cc1:IF H8=1 THEN 1520
4740 NEXT I
4741 GOTO 1520
4750 IF B3=0 THEN 4770
4752 PRINT"From ENTERPRISE to Starbase:":W1=B4:X=B5
4760 GOTO 4540
4770 PRINT"Mr. Spock reports, 'Sensors show no starbases in this";
4780 PRINT"quadrant.'":GOTO 1520
4790 REM find empty place in quadrant (for things)
4800 R1=INT(RND(1)*7.98+1.01):R2=INT(RND(1)*7.98+1.01):A$=" ":Z1=R1:Z2=R2
4801 GOSUB 4990
4802 IF Z3=0 THEN 4800
4810 RETURN
4820 REM insert in string array for quadrant
4830 S8=INT(Z2-0.5)*3+INT(Z1-0.5)*24+1
4840 IF LEN(A$)=3 THEN 4850
4841 PRINT"ERROR":STOP
4850 IF S8<>1 THEN 4860
4851 Q$=A$+MID$(Q$,4,189):RETURN
4860 IF S8<>190 THEN 4870
4861 Q$=MID$(Q$,1,189)+A$:RETURN
4870 Q$=MID$(Q$,1,S8-1)+A$+MID$(Q$,s8+3,192-s8-2):RETURN
4880 REM prints device name
4890 ON R1 GOTO 4900,4910,4920,4930,4940,4950,4960,4970
4900 G2$="Warp Engines":RETURN
4910 G2$="Short Range Sensors":RETURN
4920 G2$="Long Range Sensors":RETURN
4930 G2$="Phaser Control":RETURN
4940 G2$="Photon Tubes":RETURN
4950 G2$="Damage Control":RETURN
4960 G2$="Shield Control":RETURN
4970 G2$="Library-Computer":RETURN
4980 REM string comparison in quadrant array
4990 Z1=INT(Z1+0.5):Z2=INT(Z2+0.5):S8=(Z2-1)*3+(Z1-1)*24:Z3=0
5000 IF MID$(Q$,S8+1,3)=A$ THEN 5010
5001 RETURN
5010 Z3=1:RETURN
5020 REM quadrant name in g2$ from z4,z5 (=q1,q2)
5030 REM call with g5=1 to get region name only
5040 IF Z5<=4 THEN 5140
5041 ON Z4 GOTO 5060,5070,5080,5090,5100,5110,5120,5130
5050 GOTO 5140
5060 G2$="Antares":GOTO 5230
5070 G2$="Rigel":GOTO 5230
5080 G2$="Procyon":GOTO 5230
5090 G2$="Vega":GOTO 5230
5100 G2$="Canopus":GOTO 5230
5110 G2$="Altair":GOTO 5230
5120 G2$="Sagittarius":GOTO 5230
5130 G2$="Pollux":GOTO 5230
5140 ON Z4 GOTO 5150,5160,5170,5180,5180,5200,5210,5220
5150 G2$="Sirius":GOTO 5230
5160 G2$="Deneb":GOTO 5230
5170 G2$="Capella":GOTO 5230
5180 G2$="Betelgeuse":GOTO 5230
5190 G2$="Aldebaran":GOTO 5230
5200 G2$="Regulus":GOTO 5230
5210 G2$="Arcturus":GOTO 5230
5220 G2$="Spica"
5230 IF G5=1 THEN 5240
5231 ON Z5 GOTO 5250,5260,5270,5280,5250,5260,5270,5280
5240 RETURN
5250 G2$=G2$+" i":RETURN
5260 G2$=G2$+" ii":RETURN
5270 G2$=G2$+" iii":RETURN
5280 G2$=G2$+" iv":RETURN
5290 rem red alert sound
5291 return
5300 FOR J= 1 TO 4
5310 FOR K=1000 TO 2000 STEP 20
5320 rem SOUND K,0.01*18.2
5330 NEXT K
5340 NEXT J
5350 RETURN
5360 rem torpedo sound
5361 return
5370 FOR J = 1500 TO 100 STEP -20
5380 rem SOUND J,0.01*18.2
5390 rem SOUND 3600-J,.01*18.2
5400 NEXT J
5410 RETURN
5420 rem phaser sound
5421 return
5430 FOR J= 1 TO 40
5440 rem SOUND 800,.01*18.2
5450 rem SOUND 2500,.008*18.2
5460 NEXT J
5470 RETURN
5480 rem alarm sound
5481 return
5490 FOR SI = 1 TO 3
5500 FOR J= 800 TO 1500 STEP 20
5510 rem SOUND J,.01 *18.2
5520 NEXT J
5530 FOR K = 1500 TO 800 STEP -20
5540 rem SOUND K, .01 *18.2
5550 NEXT K
5560 NEXT SI
5570 RETURN

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,83 @@
5 PRINT TAB(33);"BAGELS"
10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY":PRINT:PRINT
15 REM *** BAGLES NUMBER GUESSING GAME
20 REM *** ORIGINAL SOURCE UNKNOWN BUT SUSPECTED TO BE
25 REM *** LAWRENCE HALL OF SCIENCE UC BERKELY
30 DIM A1(6),A(3),B(3)
40 Y=0:T=255
50 PRINT:PRINT:PRINT
70 INPUT "WOULD YOU LIKE THE RULES (YES OR NO)";A$
90 IF LEFT$(A$,1)="N" THEN 150
100 PRINT:PRINT "I AM THINKING OF A THREE-DIGIT NUMBER. TRY TO GUESS"
110 PRINT "MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:"
120 PRINT " PICO - ONE DIGIT CORRECT BUT IN THE WRONG POSITION"
130 PRINT " FERMI - ONE DIGIT CORRECT AND IN THE RIGHT POSITION"
140 PRINT " BAGELS - NO DIGITS CORRECT"
150 FOR I=1 TO 3
160 A(I)=INT(10*RND(1))
165 IF I-1=0 THEN 200
170 FOR J=1 TO I-1
180 IF A(I)=A(J) THEN 160
190 NEXT J
200 NEXT I
210 PRINT:PRINT "O.K. I HAVE A NUMBER IN MIND."
220 FOR I=1 TO 20
230 PRINT "GUESS #";I
240 INPUT A$
245 IF LEN(A$)<>3 THEN 630
250 FOR Z=1 TO 3
251 A1(Z)=ASC(MID$(A$,Z,1))
252 NEXT Z
260 FOR J=1 TO 3
270 IF A1(J)<48 THEN 300
280 IF A1(J)>57 THEN 300
285 B(J)=A1(J)-48
290 NEXT J
295 GOTO 320
300 PRINT "WHAT?"
310 GOTO 230
320 IF B(1)=B(2) THEN 650
330 IF B(2)=B(3) THEN 650
340 IF B(3)=B(1) THEN 650
350 C=0:D=0
360 FOR J=1 TO 2
370 IF A(J)<>B(J+1) THEN 390
380 C=C+1
390 IF A(J+1)<>B(J) THEN 410
400 C=C+1
410 NEXT J
420 IF A(1)<>B(3) THEN 440
430 C=C+1
440 IF A(3)<>B(1) THEN 460
450 C=C+1
460 FOR J=1 TO 3
470 IF A(J)<>B(J) THEN 490
480 D=D+1
490 NEXT J
500 IF D=3 THEN 680
505 IF C=0 THEN 545
520 FOR J=1 TO C
530 PRINT "PICO ";
540 NEXT J
545 IF D=0 THEN 580
550 FOR J=1 TO D
560 PRINT "FERMI ";
570 NEXT J
580 IF C+D<>0 THEN 600
590 PRINT "BAGELS";
600 PRINT
605 NEXT I
610 PRINT "OH WELL."
615 PRINT "THAT'S TWNETY GUESSES. MY NUMBER WAS";100*A(1)+10*A(2)+A(3)
620 GOTO 700
630 PRINT "TRY GUESSING A THREE-DIGIT NUMBER.":GOTO 230
650 PRINT "OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND"
660 PRINT "HAS NO TWO DIGITS THE SAME.":GOTO 230
680 PRINT "YOU GOT IT!!!":PRINT
690 Y=Y+1
700 INPUT "PLAY AGAIN (YES OR NO)";A$
720 IF LEFT$(A$,1)="YES" THEN 150
730 IF Y=0 THEN 750
740 PRINT:PRINT "A";Y;"POINT BAGELS BUFF!!"
750 PRINT "HOPE YOU HAD FUN. BYE."
999 END

View file

@ -0,0 +1,234 @@
5 PRINT TAB ( 16 ) ; "**************************"
10 PRINT TAB ( 26 ) ; "ELIZA"
20 PRINT TAB ( 20 ) ; "CREATIVE COMPUTING"
30 PRINT TAB ( 18 ) ; "MORRISTOWN, NEW JERSEY" : PRINT
40 PRINT TAB ( 19 ) ; "ADAPTED FOR IBM PC BY"
50 PRINT TAB ( 12 ) ; "PATRICIA DANIELSON AND PAUL HASHFIELD"
53 PRINT : PRINT TAB ( 6 ) ; "PLEASE DON'T USE COMMAS OR PERIODS IN YOUR INPUTS" : PRINT
55 PRINT TAB ( 16 ) ; "*************************"
60 PRINT : PRINT : PRINT
80 REM*****INITIALIZATION**********
100 DIM S ( 36 ) , R ( 36 ) , N ( 36 )
105 DIM KEYWORD$ ( 36 ) , WORDIN$ ( 7 ) , WORDOUT$ ( 7 ) , REPLIES$ ( 112 )
107 REM NEED TO PRE-DECLARE BEFORE USE
108 P$ = "NULL"
110 N1 = 36 : N2 = 14 : N3 = 112
112 FOR X = 1 TO N1
113 READ TEMP$: KEYWORD$ ( X ) = TEMP$
114 NEXT X
115 FOR X = 1 TO N2 / 2
116 READ TEMP$: WORDIN$ ( X ) = TEMP$ : READ TEMP$: WORDOUT$ ( X ) = TEMP$
117 NEXT X
118 FOR X = 1 TO N3
119 READ TEMP$: REPLIES$ ( X ) = TEMP$
120 NEXT X
130 FOR X = 1 TO N1
140 READ TEMP: S ( X ) = TEMP: READ TEMP: L = TEMP
142 R ( X ) = S ( X ) : N ( X ) = S ( X ) + L - 1
150 NEXT X
160 PRINT "HI! I'M ELIZA. WHAT'S YOUR PROBLEM?"
170 REM ***********************************
180 REM *******USER INPUT SECTION**********
190 REM ***********************************
200 INPUT I$
201 I$ = " " + I$ + " "
210 REM GET RID OF APOSTROPHES
220 FOR L = 1 TO LEN ( I$ )
230 REM IF MID$(I$,L,1)="'"THEN I$=LEFT$(I$,L-1)+RIGHT$(I$,LEN(I$)-L):GOTO 230
240 IF L + 4 > LEN ( I$ ) THEN 250
241 IF MID$ ( I$ , L , 4 ) <> "SHUT" THEN 250
242 PRINT "O.K. IF YOU FEEL THAT WAY I'LL SHUT UP...."
243 END
250 NEXT L
255 IF I$ = P$ THEN 256 ELSE 260
256 PRINT "PLEASE DON'T REPEAT YOURSELF!": GOTO 170
260 REM ***********************************
270 REM ********FIND KEYWORD IN I$*********
280 REM ***********************************
300 FOR K = 1 TO N1
320 FOR L = 1 TO LEN ( I$ ) - LEN ( KEYWORD$ ( K ) ) + 1
340 IF MID$ ( I$ , L , LEN ( KEYWORD$ ( K ) ) ) <> KEYWORD$ ( K ) THEN 350
341 IF K <> 13 THEN 349
342 IF MID$ ( I$ , L , LEN ( KEYWORD$ ( 29 ) ) ) = KEYWORD$ ( 29 ) THEN 343 ELSE 349
343 K = 29
349 F$ = KEYWORD$ ( K ) : GOTO 390
350 NEXT L
360 NEXT K
370 K = 36 : GOTO 570 : REM WE DIDN'T FIND ANY KEYWORDS
380 REM ******************************************
390 REM **TAKE PART OF STRING AND CONJUGATE IT****
400 REM **USING THE LIST OF STRINGS TO BE SWAPPED*
410 REM ******************************************
430 C$ = " " + RIGHT$ ( I$ , LEN ( I$ ) - LEN ( F$ ) - L + 1 ) + " "
440 FOR X = 1 TO N2 / 2
460 FOR L = 1 TO LEN ( C$ )
470 IF L + LEN ( WORDIN$ ( X ) ) > LEN ( C$ ) THEN 510
480 IF MID$ ( C$ , L , LEN ( WORDIN$ ( X ) ) ) <> WORDIN$ ( X ) THEN 510
490 C$ = LEFT$ ( C$ , L - 1 ) + WORDOUT$ ( X ) + RIGHT$ ( C$ , LEN ( C$ ) - L - LEN ( WORDIN$ ( X ) ) + 1 )
495 L = L + LEN ( WORDOUT$ ( X ) )
500 GOTO 540
510 IF L + LEN ( WORDOUT$ ( X ) ) > LEN ( C$ ) THEN 540
520 IF MID$ ( C$ , L , LEN ( WORDOUT$ ( X ) ) ) <> WORDOUT$ ( X ) THEN 540
530 C$ = LEFT$ ( C$ , L - 1 ) + WORDIN$ ( X ) + RIGHT$ ( C$ , LEN ( C$ ) - L - LEN ( WORDOUT$ ( X ) ) + 1 )
535 L = L + LEN ( WORDIN$ ( X ) )
540 NEXT L
550 NEXT X
551 IF MID$ ( C$ , 2 , 1 ) = " " THEN 552 ELSE 555
552 C$ = RIGHT$ ( C$ , LEN ( C$ ) - 1 ) : REM ONLY 1 SPACE
555 FOR L = 1 TO LEN ( C$ )
556 IF MID$ ( C$ , L , 1 ) = "!" THEN 557 ELSE 558
557 C$ = LEFT$ ( C$ , L - 1 ) + RIGHT$ ( C$ , LEN ( C$ ) - L ) : GOTO 556
558 NEXT L
560 REM **********************************************
570 REM **NOW USING THE KEYWORD NUMBER (K) GET REPLY**
580 REM **********************************************
600 F$ = REPLIES$ ( R ( K ) )
610 R ( K ) = R ( K ) + 1
615 IF R ( K ) > N ( K ) THEN 617 ELSE 620
617 R ( K ) = S ( K )
620 IF RIGHT$ ( F$ , 1 ) <> "*" THEN 621 ELSE 625
621 PRINT F$ : P$ = I$ : GOTO 170
625 IF C$ <> " " THEN 630
626 PRINT "YOU WILL HAVE TO ELABORATE MORE FOR ME TO HELP YOU"
627 GOTO 170
630 PRINT LEFT$ ( F$ , LEN ( F$ ) - 1 ) ; C$
640 P$ = I$ : GOTO 170
1000 REM *******************************
1010 REM *****PROGRAM DATA FOLLOWS******
1020 REM *******************************
1030 REM *********KEYWORDS**************
1049 REM *******************************
1050 DATA "CAN YOU " , "CAN I " , "YOU ARE " , "YOU'RE " , "I DON'T " , "I FEEL "
1060 DATA "WHY DON'T YOU " , "WHY CAN'T I " , "ARE YOU " , "I CAN'T " , "I AM " , "I'M "
1070 DATA "YOU " , "I WANT " , "WHAT " , "HOW " , "WHO " , "WHERE " , "WHEN " , "WHY "
1080 DATA "NAME " , "CAUSE " , "SORRY " , "DREAM " , "HELLO " , "HI " , "MAYBE "
1090 DATA "NO" , "YOUR " , "ALWAYS " , "THINK " , "ALIKE " , "YES " , "FRIEND "
1100 DATA "COMPUTER" , "NOKEYFOUND"
1200 REM *********************************
1210 REM ***STRING DATA FOR CONJUGATIONS**
1220 REM *********************************
1230 DATA " ARE " , " AM " , " WERE " , " WAS " , " YOU " , " I " , " YOUR" , " MY "
1235 DATA " I'VE " , " YOU'VE " , " I'M " , " YOU'RE "
1240 DATA " ME " , " YOU "
1300 REM ******************************
1310 REM *********REPLIES**************
1320 REM ******************************
1330 DATA "DON'T YOU BELIEVE THAT I CAN*"
1340 DATA "PERHAPS YOU WOULD LIKE TO BE LIKE ME*"
1350 DATA "YOU WANT ME TO BE ABLE TO*"
1360 DATA "PERHAPS YOU DON'T WANT TO*"
1365 DATA "DO YOU WANT TO BE ABLE TO*"
1370 DATA "WHAT MAKES YOU THINK I AM*"
1380 DATA "DOES IT PLEASE YOU TO BELIEVE I AM*"
1390 DATA "PERHAPS YOU WOULD LIKE TO BE*"
1400 DATA "DO YOU SOMETIMES WISH YOU WERE*"
1410 DATA "DON'T YOU REALLY*"
1420 DATA "WHY DON'T YOU*"
1430 DATA "DO YOU WISH TO BE ABLE TO*"
1440 DATA "DOES THAT TROUBLE YOU*"
1450 DATA "DO YOU OFTEN FEEL*"
1460 DATA "DO YOU OFTEN FEEL*"
1470 DATA "DO YOU ENJOY FEELING*"
1480 DATA "DO YOU REALLY BELIEVE I DON'T*"
1490 DATA "PERHAPS IN GOOD TIME I WILL*"
1500 DATA "DO YOU WANT ME TO*"
1510 DATA "DO YOU THINK YOU SHOULD BE ABLE TO*"
1520 DATA "WHY CAN'T YOU*"
1530 DATA "WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*"
1540 DATA "WOULD YOU PREFER IF I WERE NOT*"
1550 DATA "PERHAPS IN YOUR FANTASIES I AM*"
1560 DATA "HOW DO YOU KNOW YOU CAN'T*"
1570 DATA "HAVE YOU TRIED?"
1580 DATA "PERHAPS YOU CAN NOW*"
1590 DATA "DID YOU COME TO ME BECAUSE YOU ARE*"
1600 DATA "HOW LONG HAVE YOU BEEN*"
1610 DATA "DO YOU BELIEVE IT IS NORMAL TO BE*"
1620 DATA "DO YOU ENJOY BEING*"
1630 DATA "WE WERE DISCUSSING YOU--NOT ME."
1640 DATA "OH, I*"
1650 DATA "YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?"
1660 DATA "WHAT WOULD IT MEAN TO YOU IF YOU GOT*"
1670 DATA "WHY DO YOU WANT*"
1680 DATA "SUPPOSE YOU SOON GOT*"
1690 DATA "WHAT IF YOU NEVER GOT*"
1700 DATA "I SOMETIMES ALSO WANT*"
1710 DATA "WHY DO YOU ASK?"
1720 DATA "DOES THAT QUESTION INTEREST YOU?"
1730 DATA "WHAT ANSWER WOULD PLEASE YOU THE MOST?"
1740 DATA "WHAT DO YOU THINK?"
1750 DATA "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?"
1760 DATA "WHAT IS IT THAT YOU REALLY WANT TO KNOW?"
1770 DATA "HAVE YOU ASKED ANYONE ELSE?"
1780 DATA "HAVE YOU ASKED SUCH QUESTIONS BEFORE?"
1790 DATA "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"
1800 DATA "NAMES DON'T INTEREST ME."
1810 DATA "I DON'T CARE ABOUT NAMES --PLEASE GO ON."
1820 DATA "IS THAT THE REAL REASON?"
1830 DATA "DON'T ANY OTHER REASONS COME TO MIND?"
1840 DATA "DOES THAT REASON EXPLAIN ANYTHING ELSE?"
1850 DATA "WHAT OTHER REASONS MIGHT THERE BE?"
1860 DATA "PLEASE DON'T APOLOGIZE!"
1870 DATA "APOLOGIES ARE NOT NECESSARY."
1880 DATA "WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?"
1890 DATA "DON'T BE SO DEFENSIVE!"
1900 DATA "WHAT DOES THAT DREAM SUGGEST TO YOU?"
1910 DATA "DO YOU DREAM OFTEN?"
1920 DATA "WHAT PERSONS APPEAR IN YOUR DREAMS?"
1930 DATA "ARE YOU DISTURBED BY YOUR DREAMS?"
1940 DATA "HOW DO YOU DO ...PLEASE STATE YOUR PROBLEM."
1950 DATA "YOU DON'T SEEM QUITE CERTAIN."
1960 DATA "WHY THE UNCERTAIN TONE?"
1970 DATA "CAN'T YOU BE MORE POSITIVE?"
1980 DATA "YOU AREN'T SURE?"
1990 DATA "DON'T YOU KNOW?"
2000 DATA "ARE YOU SAYING NO JUST TO BE NEGATIVE?"
2010 DATA "YOU ARE BEING A BIT NEGATIVE."
2020 DATA "WHY NOT?"
2030 DATA "ARE YOU SURE?"
2040 DATA "WHY NO?"
2050 DATA "WHY ARE YOU CONCERNED ABOUT MY*"
2060 DATA "WHAT ABOUT YOUR OWN*"
2070 DATA "CAN YOU THINK OF A SPECIFIC EXAMPLE?"
2080 DATA "WHEN?"
2090 DATA "WHAT ARE YOU THINKING OF?"
2100 DATA "REALLY, ALWAYS?"
2110 DATA "DO YOU REALLY THINK SO?"
2120 DATA "BUT YOU ARE NOT SURE YOU*"
2130 DATA "DO YOU DOUBT YOU*"
2140 DATA "IN WHAT WAY?"
2150 DATA "WHAT RESEMBLANCE DO YOU SEE?"
2160 DATA "WHAT DOES THE SIMILARITY SUGGEST TO YOU?"
2170 DATA "WHAT OTHER CONNECTIONS DO YOU SEE?"
2180 DATA "COULD THERE REALLY BE SOME CONNECTION?"
2190 DATA "HOW?"
2200 DATA "YOU SEEM QUITE POSITIVE."
2210 DATA "ARE YOU SURE?"
2220 DATA "I SEE."
2230 DATA "I UNDERSTAND."
2240 DATA "WHY DO YOU BRING UP THE TOPIC OF FRIENDS?"
2250 DATA "DO YOUR FRIENDS WORRY YOU?"
2260 DATA "DO YOUR FRIENDS PICK ON YOU?"
2270 DATA "ARE YOU SURE YOU HAVE ANY FRIENDS?"
2280 DATA "DO YOU IMPOSE ON YOUR FRIENDS?"
2290 DATA "PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU."
2300 DATA "DO COMPUTERS WORRY YOU?"
2310 DATA "ARE YOU TALKING ABOUT ME IN PARTICULAR?"
2320 DATA "ARE YOU FRIGHTENED BY MACHINES?"
2330 DATA "WHY DO YOU MENTION COMPUTERS?"
2340 DATA "WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?"
2350 DATA "DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?"
2360 DATA "WHAT IS IT ABOUT MACHINES THAT WORRIES YOU?"
2370 DATA "SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS?"
2380 DATA "WHAT DOES THAT SUGGEST TO YOU?"
2390 DATA "I SEE."
2400 DATA "I'M NOT SURE I UNDERSTAND YOU FULLY."
2410 DATA "COME COME ELUCIDATE YOUR THOUGHTS."
2420 DATA "CAN YOU ELABORATE ON THAT?"
2430 DATA "THAT IS QUITE INTERESTING."
2500 REM *************************
2510 REM *****DATA FOR FINDING RIGHT REPLIES
2520 REM *************************
2530 DATA 1 , 3 , 4 , 2 , 6 , 4 , 6 , 4 , 10 , 4 , 14 , 3 , 17 , 3 , 20 , 2 , 22 , 3 , 25 , 3
2540 DATA 28 , 4 , 28 , 4 , 32 , 3 , 35 , 5 , 40 , 9 , 40 , 9 , 40 , 9 , 40 , 9 , 40 , 9 , 40 , 9
2550 DATA 49 , 2 , 51 , 4 , 55 , 4 , 59 , 4 , 63 , 1 , 63 , 1 , 64 , 5 , 69 , 5 , 74 , 2 , 76 , 4
2560 DATA 80 , 3 , 83 , 7 , 90 , 3 , 93 , 6 , 99 , 7 , 106 , 6

View file

@ -0,0 +1,9 @@
10 REM A SHORT PROGRAM TO CALCULATE FACTORIAL OF
20 REM SUPPLIED NUMBER N
30 INPUT "Please provide N: "; N
35 REM OUTPUT IS NOW A RESERVED KEYWORD
40 OUTPUTVAL = 1
50 FOR I = 1 TO N
60 OUTPUTVAL = OUTPUTVAL * I
70 NEXT I
80 PRINT "Factorial of N is "; OUTPUTVAL

View file

@ -0,0 +1,94 @@
2 PRINT TAB(34);"LIFE"
4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN NEW JERSEY"
6 PRINT: PRINT: PRINT
8 PRINT "ENTER YOUR PATTERN, AS A SERIES OF SPACES"
9 PRINT "AND STARS, LINE BY LINE. FINISH BY TYPING"
10 PRINT "'DONE' ON THE FINAL LINE:"
11 X1=1: Y1=1: X2=24: Y2=70: G=0: P=0
12 DIM A(24, 70): DIM B$(24)
15 I9=1
20 C=1
30 INPUT TEMP$
35 B$(C) = TEMP$
40 IF B$(C)="DONE" THEN 45 ELSE 50
45 B$(C)="": GOTO 80
46 REM ORIGINAL VERSION REQUIRED USER TO WRITE
47 REM DOTS INSTEAD OF SPACES, WHICH WOULD THEN BE
48 REM CONVERTED TO SPACES
50 REM IF LEFT$(B$(C), 1)="." THEN 55 ELSE 60
55 REM B$(C)=" "+RIGHT$(B$(C), LEN(B$(C))-1)
60 C=C+1
70 GOTO 30
80 C=C-1: L=0
90 FOR X=1 TO C-1
100 IF LEN(B$(X))>L THEN 105 ELSE 110
105 L=LEN(B$(X))
110 NEXT X
120 X1=INT(11-C/2)
130 Y1=INT(33-L/2)
135 REM TRANSCRIBE INPUT PATTERN INTO ARRAY
140 FOR X=1 TO C
150 FOR Y=1 TO LEN(B$(X))
160 IF MID$(B$(X), Y, 1)<>" " THEN 165 ELSE 170
165 A(X1+X, Y1+Y)=1: P=P+1
170 NEXT Y
180 NEXT X
200 PRINT: PRINT: PRINT
210 PRINT "GENERATION: "; G; " POPULATION: "; P;
212 IF I9=0 THEN 213 ELSE 215
213 PRINT " INVALID!";
215 X3=24: Y3=70: X4=1: Y4=1: P=0
220 G=G+1
230 FOR X=X1 TO X2
240 PRINT
250 FOR Y=Y1 TO Y2
253 IF A(X, Y)=2 THEN 254 ELSE 256
254 A(X, Y)=0: GOTO 270
256 IF A(X, Y)=3 THEN 258 ELSE 260
258 A(X, Y)=1: GOTO 261
260 IF A(X, Y)<>1 THEN 270
261 PRINT TAB(Y);"*";
262 IF X<X3 THEN 263 ELSE 264
263 X3=X
264 IF X>X4 THEN 265 ELSE 266
265 X4=X
266 IF Y<Y3 THEN 267 ELSE 268
267 Y3=Y
268 IF Y>Y4 THEN 269 ELSE 270
269 Y4=Y
270 NEXT Y
290 NEXT X
295 FOR X=X2+1 TO 24
296 PRINT
297 NEXT X
299 X1=X3: X2=X4: Y1=Y3: Y2=Y4
301 IF X1<3 THEN 302 ELSE 303
302 X1=3: I9=-1
303 IF X2>22 THEN 304 ELSE 305
304 X2=22: I9=-1
305 IF Y1<3 THEN 306 ELSE 307
306 Y1=3: I9=-1
307 IF Y2>68 THEN 308 ELSE 309
308 Y2=68: I9=-1
309 P=0
500 FOR X=X1-1 TO X2+1
510 FOR Y=Y1-1 TO Y2+1
520 C=0
530 FOR I=X-1 TO X+1
540 FOR J=Y-1 TO Y+1
550 IF A(I, J)=1 OR A(I, J)=2 THEN 555 ELSE 560
555 C=C+1
560 NEXT J
570 NEXT I
580 IF A(X, Y)=0 THEN 610
590 IF C<3 or C>4 THEN 592 ELSE 595
592 A(X, Y)=2: GOTO 600
595 P=P+1
600 GOTO 620
610 IF C=3 THEN 615 ELSE 620
615 A(X, Y)=3: P=P+1
620 NEXT Y
630 NEXT X
635 X1=X1-1: Y1=Y1-1: X2=X2+1: Y2=Y2+1
640 GOTO 210
650 END

View file

@ -0,0 +1,720 @@
10 REM PROGRAM NAME - OREGON VERSION:01/01/78
20 REM ORIGINAL PROGRAMMING BY BILL HEINEMANN - 1971
30 REM SUPPORT RESEARCH AND MATERIALS BY DON RAVITSCH,
40 REM MINNESOTA EDUCATIONAL COMPUTING CONSORTIUM STAFF
50 REM CDC CYBER 70/73-26 BASIC 3.1
60 REM DOCUMENTATION BOOKLET 'OREGON' AVAILABLE FROM
61 REM MECC SUPPORT SERVICES
62 REM 2520 BROADWAY DRIVE
63 REM ST. PAUL MN 55113
80 REM
150 REM *FOR THE MEANING OF THE VARIABLES USED, LIST LINES 6470-6790*
155 REM
160 PRINT "DO YOU NEED INSTRUCTIONS (YES/NO)" ;
165 REM PYBASIC CAN'T DO STRING OPERATIONS ON ARRAYS
170 REM DIM C$(5)
180 REM RANDOMIZE REMOVED
190 INPUT C$
200 IF C$ = "NO" THEN 690
210 PRINT
220 PRINT
230 REM ***INSTRUCTIONS***
240 PRINT "THIS PROGRAM SIMULATES A TRIP OVER THE OREGON TRAIL FROM"
250 PRINT "INDEPENDENCE, MISSOURI TO OREGON CITY, OREGON IN 1847."
260 PRINT "YOUR FAMILY OF FIVE WILL COVER THE 2040 MILE OREGON TRAIL"
270 PRINT "IN 5-6 MONTHS --- IF YOU MAKE IT ALIVE."
280 PRINT
290 PRINT "YOU HAD SAVED $900 TO SPEND FOR THE TRIP, AND YOU'VE JUST"
300 PRINT " PAID $200 FOR A WAGON."
310 PRINT "YOU WILL NEED TO SPEND THE REST OF YOUR MONEY ON THE"
320 PRINT " FOLLOWING ITEMS:"
330 PRINT
340 PRINT " OXEN - YOU CAN SPEND $200-$300 ON YOUR TEAM"
350 PRINT " THE MORE YOU SPEND, THE FASTER YOU'LL GO"
360 PRINT " BECAUSE YOU'LL HAVE BETTER ANIMALS"
370 PRINT
380 PRINT " FOOD - THE MORE YOU HAVE, THE LESS CHANCE THERE"
390 PRINT " IS OF GETTING SICK"
400 PRINT
410 PRINT " AMMUNITION - $1 BUYS A BELT OF 50 BULLETS"
420 PRINT " YOU WILL NEED BULLETS FOR ATTACKS BY ANIMALS"
430 PRINT " AND BANDITS, AND FOR HUNTING FOOD"
440 PRINT
450 PRINT " CLOTHING - THIS IS ESPECIALLY IMPORTANT FOR THE COLD"
460 PRINT " WEATHER YOU WILL ENCOUNTER WHEN CROSSING"
470 PRINT " THE MOUNTAINS"
480 PRINT
490 PRINT " MISCELLANEOUS SUPPLIES - THIS INCLUDES MEDICINE AND"
500 PRINT " OTHER THINGS YOU WILL NEED FOR SICKNESS"
510 PRINT " AND EMERGENCY REPAIRS"
520 PRINT
530 PRINT
540 PRINT "YOU CAN SPEND ALL YOUR MONEY BEFORE YOU START YOUR TRIP -"
550 PRINT "OR YOU CAN SAVE SOME OF YOUR CASH TO SPEND AT FORTS ALONG"
560 PRINT "THE WAY WHEN YOU RUN LOW. HOWEVER, ITEMS COST MORE AT"
570 PRINT "THE FORTS. YOU CAN ALSO GO HUNTING ALONG THE WAY TO GET"
580 PRINT "MORE FOOD."
590 PRINT "WHENEVER YOU HAVE TO USE YOUR TRUSTY RIFLE ALONG THE WAY,"
600 PRINT "YOU WILL BE TOLD TO TYPE IN A WORD (ONE THAT SOUNDS LIKE A "
610 PRINT "GUN SHOT). THE FASTER YOU TYPE IN THAT WORD AND HIT THE"
620 PRINT "" "RETURN" " KEY, THE BETTER LUCK YOU'LL HAVE WITH YOUR GUN."
630 PRINT
640 PRINT "AT EACH TURN, ALL ITEMS ARE SHOWN IN DOLLAR AMOUNTS"
650 PRINT "EXCEPT BULLETS"
660 PRINT "WHEN ASKED TO ENTER MONEY AMOUNTS, DON'T USE A " "$" "."
670 PRINT
680 PRINT "GOOD LUCK!!!"
690 PRINT
700 PRINT
710 PRINT "HOW GOOD A SHOT ARE YOU WITH YOUR RIFLE?"
720 PRINT " (1) ACE MARKSMAN, (2) GOOD SHOT, (3) FAIR TO MIDDLIN'"
730 PRINT " (4) NEED MORE PRACTICE, (5) SHAKY KNEES"
740 PRINT "ENTER ONE OF THE ABOVE -- THE BETTER YOU CLAIM YOU ARE, THE"
750 PRINT "FASTER YOU'LL HAVE TO BE WITH YOUR GUN TO BE SUCCESSFUL."
760 INPUT D9
770 IF D9 > 5 THEN 790
780 GOTO 810
790 D9 = 0
800 REM ***INITIAL PURCHASES***
810 X1 = - 1
820 REM LINES 820-829 MODIFIED BY CHRISTOPHER PEDERSEN (AUG 10, 2018)
821 REM FOR COMPATIBILITY WITH THE CHIPMUNK BASIC INTERPRETER
822 REM CHIPMUNK BASIC: http://www.nicholson.com/rhn/basic/
823 D3 = 0
824 M9 = 0
825 M = 0
826 F2 = 0
827 F1 = 0
828 S4 = 0
829 K8 = 0
830 PRINT
840 PRINT
850 PRINT "HOW MUCH DO YOU WANT TO SPEND ON YOUR OXEN TEAM" ;
860 INPUT A
870 IF A >= 200 THEN 900
880 PRINT "NOT ENOUGH"
890 GOTO 850
900 IF A <= 300 THEN 930
910 PRINT "TOO MUCH"
920 GOTO 850
930 PRINT "HOW MUCH DO YOU WANT TO SPEND ON FOOD" ;
940 INPUT F
950 IF F >= 0 THEN 980
960 PRINT "IMPOSSIBLE"
970 GOTO 930
980 PRINT "HOW MUCH DO YOU WANT TO SPEND ON AMMUNITION" ;
990 INPUT B
1000 IF B >= 0 THEN 1030
1010 PRINT "IMPOSSIBLE"
1020 GOTO 980
1030 PRINT "HOW MUCH DO YOU WANT TO SPEND ON CLOTHING" ;
1040 INPUT C
1050 IF C >= 0 THEN 1080
1060 PRINT "IMPOSSIBLE"
1070 GOTO 1030
1080 PRINT "HOW MUCH DO YOU WANT TO SPEND ON MISCELLANEOUS SUPPLIES" ;
1090 INPUT M1
1100 IF M1 >= 0 THEN 1130
1110 PRINT "IMPOSSIBLE"
1120 GOTO 1080
1130 T = 700 - A - F - B - C - M1
1140 IF T >= 0 THEN 1170
1150 PRINT "YOU OVERSPENT--YOU ONLY HAD $700 TO SPEND. BUY AGAIN"
1160 GOTO 830
1170 B = 50 * B
1180 PRINT "AFTER ALL YOUR PURCHASES. YOU NOW HAVE " ; T ; " DOLLARS LEFT"
1190 PRINT
1200 PRINT "MONDAY MARCH 29 1847"
1210 PRINT
1220 GOTO 1750
1230 IF M >= 2040 THEN 5430
1240 REM ***SETTING DATE***
1250 D3 = D3 + 1
1260 PRINT
1270 PRINT "MONDAY " ;
1280 IF D3 > 10 THEN 1300
1290 ON D3 GOTO 1310 , 1330 , 1350 , 1370 , 1390 , 1410 , 1430 , 1450 , 1470 , 1490
1300 ON D3 - 10 GOTO 1510 , 1530 , 1550 , 1570 , 1590 , 1610 , 1630 , 1650 , 1670 , 1690
1310 PRINT "APRIL 12 " ;
1320 GOTO 1720
1330 PRINT "APRIL 26 " ;
1340 GOTO 1720
1350 PRINT "MAY 10 " ;
1360 GOTO 1720
1370 PRINT "MAY 24 " ;
1380 GOTO 1720
1390 PRINT "JUNE 7 " ;
1400 GOTO 1720
1410 PRINT "JUNE 21 " ;
1420 GOTO 1720
1430 PRINT "JULY 5 " ;
1440 GOTO 1720
1450 PRINT "JULY 19 " ;
1460 GOTO 1720
1470 PRINT "AUGUST 2 " ;
1480 GOTO 1720
1490 PRINT "AUGUST 16 " ;
1500 GOTO 1720
1510 PRINT "AUGUST 31 " ;
1520 GOTO 1720
1530 PRINT "SEPTEMBER 13 " ;
1540 GOTO 1720
1550 PRINT "SEPTEMBER 27 " ;
1560 GOTO 1720
1570 PRINT "OCTOBER 11 " ;
1580 GOTO 1720
1590 PRINT "OCTOBER 25 " ;
1600 GOTO 1720
1610 PRINT "NOVEMBER 8 " ;
1620 GOTO 1720
1630 PRINT "NOVEMBER 22 " ;
1640 GOTO 1720
1650 PRINT "DECEMBER 6 " ;
1660 GOTO 1720
1670 PRINT "DECEMBER 20 " ;
1680 GOTO 1720
1690 PRINT "YOU HAVE BEEN ON THE TRAIL TOO LONG ------"
1700 PRINT "YOUR FAMILY DIES IN THE FIRST BLIZZARD OF WINTER"
1710 GOTO 5170
1720 PRINT "1847"
1730 PRINT
1740 REM ***BEGINNING EACH TURN***
1750 IF F >= 0 THEN 1770
1760 F = 0
1770 IF B >= 0 THEN 1790
1780 B = 0
1790 IF C >= 0 THEN 1810
1800 C = 0
1810 IF M1 >= 0 THEN 1830
1820 M1 = 0
1830 IF F >= 13 THEN 1850
1840 PRINT "YOU'D BETTER DO SOME HUNTING OR BUY FOOD AND SOON!!!!"
1850 F = INT ( F )
1860 B = INT ( B )
1870 C = INT ( C )
1880 M1 = INT ( M1 )
1890 T = INT ( T )
1900 M = INT ( M )
1910 M2 = M
1920 IF S4 = 1 THEN 1950
1930 IF K8 = 1 THEN 1950
1940 GOTO 1990
1950 T = T - 20
1960 IF T < 0 THEN 5080
1970 PRINT "DOCTOR'S BILL IS $20"
1980 REM LINES 1980-1982 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH MODERN BASIC
1981 LET S4 = 0
1982 LET K8 = S4
1990 IF M9 = 1 THEN 2020
2000 PRINT "TOTAL MILEAGE: " ; M
2010 GOTO 2040
2020 PRINT "TOTAL MILEAGE: 950"
2030 M9 = 0
2040 REM LINES 2040-2050 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH MODERN BASIC
2041 PRINT "FOOD: " ; F
2042 PRINT "BULLETS: " ; B
2043 PRINT "CLOTHING: " ; C
2044 PRINT "MISC. SUPPLIES: " ; M1
2050 PRINT "CASH: $" ; T
2060 IF X1 = - 1 THEN 2170
2070 X1 = X1 * ( - 1 )
2080 PRINT "DO YOU WANT TO (1) STOP AT THE NEXT FORT, (2) HUNT, " ;
2090 PRINT "OR (3) CONTINUE"
2100 INPUT X
2110 REM IF X>2 THEN 2150
2120 REM IF X<1 THEN 2150
2130 REM LET X=INT(X)
2140 GOTO 2270
2150 LET X = 3
2160 GOTO 2270
2170 PRINT "DO YOU WANT TO (1) HUNT, OR (2) CONTINUE"
2180 INPUT X
2190 IF X = 1 THEN 2210
2200 LET X = 2
2210 LET X = X + 1
2220 IF X = 3 THEN 2260
2230 IF B > 39 THEN 2260
2240 PRINT "TOUGH---YOU NEED MORE BULLETS TO GO HUNTING"
2250 GOTO 2170
2260 X1 = X1 * ( - 1 )
2270 ON X GOTO 2290 , 2540 , 2720
2280 REM ***STOPPING AT FORT***
2290 PRINT "ENTER WHAT YOU WISH TO SPEND ON THE FOLLOWING"
2300 PRINT "FOOD" ;
2310 GOSUB 2330
2320 GOTO 2410
2330 INPUT P
2340 IF P < 0 THEN 2400
2350 T = T - P
2360 IF T >= 0 THEN 2400
2370 PRINT "YOU DON'T HAVE THAT MUCH--KEEP YOUR SPENDING DOWN"
2380 T = T + P
2390 P = 0
2400 RETURN
2410 F = F + 2 / 3 * P
2420 PRINT "AMMUNITION" ;
2430 GOSUB 2330
2440 LET B = INT ( B + 2 / 3 * P * 50 )
2450 PRINT "CLOTHING" ;
2460 GOSUB 2330
2470 C = C + 2 / 3 * P
2480 PRINT "MISCELLANEOUS SUPPLIES" ;
2490 GOSUB 2330
2500 M1 = M1 + 2 / 3 * P
2510 M = M - 45
2520 GOTO 2720
2530 REM ***HUNTING***
2540 IF B > 39 THEN 2570
2550 PRINT "TOUGH---YOU NEED MORE BULLETS TO GO HUNTING"
2560 GOTO 2080
2570 M = M - 45
2580 GOSUB 6140
2590 IF B1 <= 1 THEN 2660
2600 IF 100 + RND ( 1 ) < 13 * B1 THEN 2710
2610 F = F + 48 - 2 * B1
2620 PRINT "NICE SHOT--RIGHT ON TARGET--GOOD EATIN' TONIGHT!!"
2630 B = B - 10 - 3 * B1
2640 GOTO 2720
2650 REM **BELLS IN LINE 2660**
2660 PRINT "RIGHT BETWEEN THE EYES---YOU GOT A BIG ONE!!!!"
2670 PRINT "FULL BELLIES TONIGHT!"
2680 F = F + 52 + RND ( 1 ) * 6
2690 B = B - 10 - RND ( 1 ) * 4
2700 GOTO 2720
2710 PRINT "YOU MISSED---AND YOUR DINNER GOT AWAY....."
2720 IF F >= 13 THEN 2750
2730 GOTO 5060
2740 REM ***EATING***
2750 PRINT "DO YOU WANT TO EAT (1) POORLY (2) MODERATELY"
2760 PRINT "OR (3) WELL" ;
2770 INPUT E
2780 IF E > 3 THEN 2750
2790 IF E < 1 THEN 2750
2800 LET E = INT ( E )
2810 LET F = F - 8 - 5 * E
2820 IF F >= 0 THEN 2860
2830 F = F + 8 + 5 * E
2840 PRINT "YOU CAN'T EAT THAT WELL"
2850 GOTO 2750
2860 LET M = M + 200 + ( A - 220 ) / 5 + 10 * RND ( 1 )
2870 REM LINES 2870-2872 MODIFIED BY C.D.P. FOR COMPATIBILITY W/ CHIPMUNK BASIC
2871 C1 = 0
2872 L1 = C1
2880 REM ***RIDERS ATTACK***
2889 REM LINE 2890 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH CHIPMUNK BASIC
2900 PRINT "RIDERS AHEAD. THEY " ;
2910 S5 = 0
2919 REM ALL RND(-1) FUNCTION CALLS HAVE BEEN CHANGED TO RND(1) BY C.D.P.
2930 PRINT "DON'T " ;
2940 S5 = 1
2950 PRINT "LOOK HOSTILE"
2960 PRINT "TACTICS"
2970 PRINT "(1) RUN (2) ATTACK (3) CONTINUE (4) CIRCLE WAGONS"
2990 S5 = 1 - S5
3000 INPUT T1
3010 IF T1 < 1 THEN 2970
3020 IF T1 > 4 THEN 2970
3030 T1 = INT ( T1 )
3040 IF S5 = 1 THEN 3330
3050 IF T1 > 1 THEN 3110
3060 M = M + 20
3070 M1 = M1 - 15
3080 B = B - 150
3090 A = A - 40
3100 GOTO 3470
3110 IF T1 > 2 THEN 3240
3120 GOSUB 6140
3130 B = B - B1 * 40 - 80
3140 IF B1 > 1 THEN 3170
3150 PRINT "NICE SHOOTING---YOU DROVE THEM OFF"
3160 GOTO 3470
3170 IF B1 <= 4 THEN 3220
3180 PRINT "LOUSY SHOT---YOU GOT KNIFED"
3190 K8 = 1
3200 PRINT "YOU HAVE TO SEE OL' DOC BLANCHARD"
3210 GOTO 3470
3220 PRINT "KINDA SLOW WITH YOUR COLT .45"
3230 GOTO 3470
3240 IF T1 > 3 THEN 3290
3260 LET B = B - 150
3270 M1 = M1 - 15
3280 GOTO 3470
3290 GOSUB 6140
3300 B = B - B1 * 30 - 80
3310 M = M - 25
3320 GOTO 3140
3330 IF T1 > 1 THEN 3370
3340 M = M + 15
3350 A = A - 10
3360 GOTO 3470
3370 IF T1 > 2 THEN 3410
3380 M = M - 5
3390 B = B - 100
3400 GOTO 3470
3410 IF T1 > 3 THEN 3430
3420 GOTO 3470
3430 M = M - 20
3440 GOTO 3470
3450 PRINT "THEY DID NOT ATTACK"
3460 GOTO 3550
3470 IF S5 = 0 THEN 3500
3480 PRINT "RIDERS WERE FRIENDLY, BUT CHECK FOR POSSIBLE LOSSES"
3490 GOTO 3550
3500 PRINT "RIDERS WERE HOSTILE--CHECK FOR LOSES"
3510 IF B >= 0 THEN 3550
3520 PRINT "YOU RAN OUT OF BULLETS AND GOT MASSACRED BY THE RIDERS"
3530 GOTO 5170
3540 REM ***SELECTION OF EVENTS***
3550 LET D1 = 0
3560 RESTORE 3620
3570 R1 = 100 * RND ( 1 )
3580 LET D1 = D1 + 1
3590 IF D1 = 16 THEN 4670
3600 READ D
3610 IF R1 > D THEN 3580
3620 DATA 6 , 11 , 13 , 15 , 17 , 22 , 32 , 35 , 37 , 42 , 44 , 54 , 64 , 69 , 95
3630 IF D1 > 10 THEN 3650
3640 ON D1 GOTO 3660 , 3700 , 3740 , 3790 , 3820 , 3850 , 3880 , 3960 , 4130 , 4190
3650 ON D1 - 10 GOTO 4220 , 4290 , 4340 , 4560 , 4610 , 4670
3660 PRINT "WAGON BREAKS DOWN--LOSE TIME AND SUPPLIES FIXING IT"
3670 LET M = M - 15 - 5 * RND ( 1 )
3680 LET M1 = M1 - 8
3690 GOTO 4710
3700 PRINT "0X INJURES LEG---SLOWS YOU DOWN REST OF TRIP"
3710 LET M = M - 25
3720 LET A = A - 20
3730 GOTO 4710
3740 PRINT "BACK LUCK---YOUR DAUGHTER BROKE HER ARM"
3750 PRINT "YOU HAD TO STOP AND USE SUPPLIES TO MAKE A SLING"
3760 M = M - 5 - 4 * RND ( 1 )
3770 M1 = M1 - 2 - 3 * RND ( 1 )
3780 GOTO 4710
3790 PRINT "OX WANDERS OFF---SPEND TIME LOOKING FOR IT"
3800 M = M - 17
3810 GOTO 4710
3820 PRINT "YOUR SON GETS LOST---SPEND HALF THE DAY LOOKING FOR HIM"
3830 M = M - 10
3840 GOTO 4710
3850 PRINT "UNSAFE WATER--LOSE TIME LOOKING FOR CLEAN SPRING"
3860 LET M = M - 10 * RND ( 1 ) - 2
3870 GOTO 4710
3880 IF M > 950 THEN 4490
3890 PRINT "HEAVY RAINS---TIME AND SUPPLIES LOST"
3910 F = F - 10
3920 B = B - 500
3930 M1 = M1 - 15
3940 M = M - 10 * RND ( 1 ) - 5
3950 GOTO 4710
3960 PRINT "BANDITS ATTACK"
3970 GOSUB 6140
3980 B = B - 20 * B1
3990 IF B >= 0 THEN 4030
4000 PRINT "YOU RAN OUT OF BULLETS---THEY GET LOTS OF CASH"
4010 T = T / 3
4020 GOTO 4040
4030 IF B1 <= 1 THEN 4100
4040 PRINT "YOU GOT SHOT IN THE LEG AND THEY TOOK ONE OF YOUR OXEN"
4050 K8 = 1
4060 PRINT "BETTER HAVE A DOC LOOK AT YOUR WOUND"
4070 M1 = M1 - 5
4080 A = A - 20
4090 GOTO 4710
4100 PRINT "QUICKEST DRAW OUTSIDE OF DODGE CITY!!!"
4110 PRINT "YOU GOT 'EM!"
4120 GOTO 4710
4130 PRINT "THERE WAS A FIRE IN YOUR WAGON--FOOD AND SUPPLIES DAMAGE!"
4140 F = F - 40
4150 B = B - 400
4160 LET M1 = M1 - RND ( 1 ) * 8 - 3
4170 M = M - 15
4180 GOTO 4710
4190 PRINT "LOSE YOUR WAY IN HEAVY FOG---TIME IS LOST"
4200 M = M - 10 - 5 * RND ( 1 )
4210 GOTO 4710
4220 PRINT "YOU KILLED A POISONOUS SNAKE AFTER IT BIT YOU"
4230 B = B - 10
4240 M1 = M1 - 5
4250 IF M1 >= 0 THEN 4280
4260 PRINT "YOU DIE OF SNAKEBITE SINCE YOU HAVE NO MEDICINE"
4270 GOTO 5170
4280 GOTO 4710
4290 PRINT "WAGON GETS SWAMPED FORDING RIVER--LOSE FOOD AND CLOTHES"
4300 F = F - 30
4310 C = C - 20
4320 M = M - 20 - 20 * RND ( 1 )
4330 GOTO 4710
4340 PRINT "WILD ANIMALS ATTACK!"
4350 GOSUB 6140
4360 IF B > 39 THEN 4410
4370 PRINT "YOU WERE TOO LOW ON BULLETS--"
4380 PRINT "THE WOLVES OVERPOWERED YOU"
4390 K8 = 1
4400 GOTO 5120
4410 IF B1 > 2 THEN 4440
4420 PRINT "NICE SHOOTIN' PARTNER---THEY DIDN'T GET MUCH"
4430 GOTO 4450
4440 PRINT "SLOW ON THE DRAW---THEY GOT AT YOUR FOOD AND CLOTHES"
4450 B = B - 20 * B1
4460 C = C - B1 * 4
4470 F = F - B1 * 8
4480 GOTO 4710
4490 PRINT "COLD WEATHER---BRRRRRRR!---YOU " ;
4500 IF C > 22 + 4 * RND ( 1 ) THEN 4530
4510 PRINT "DON'T " ;
4520 C1 = 1
4530 PRINT "HAVE ENOUGH CLOTHING TO KEEP YOU WARM"
4540 IF C1 = 0 THEN 4710
4550 GOTO 6300
4560 PRINT "HAIL STORM---SUPPLIES DAMAGED"
4570 M = M - 5 - RND ( 1 ) * 10
4580 B = B - 200
4590 M1 = M1 - 4 - RND ( 1 ) * 3
4600 GOTO 4710
4610 IF E = 1 THEN 6300
4620 IF E = 3 THEN 4650
4630 IF RND(1) > 0.25 THEN 6300
4640 GOTO 4710
4650 IF RND(1) < 0.5 THEN 6300
4660 GOTO 4720
4670 PRINT "HELPFUL INDIANS SHOW YOU WHERE TO FIND MORE FOOD"
4680 F = F + 14
4690 GOTO 4710
4700 REM ***MOUNTAINS***
4710 IF M <= 950 THEN 1230
4719 REM LINE 4720 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH CHIPMUNK BASIC
4720 IF RND(1)*10 > 9-(POW((M/100-15),2)+72)/(POW((M/100-15),2)+12) THEN 4860
4730 PRINT "RUGGED MOUNTAINS"
4740 IF RND(1) > 0.1 THEN 4780
4750 PRINT "YOU GOT LOST---LOSE VALUABLE TIME TRYING TO FIND TRAIL!"
4760 M = M - 60
4770 GOTO 4860
4780 IF RND(1) > 0.11 THEN 4840
4790 PRINT "WAGON DAMAGED!---LOSE TIME AND SUPPLIES"
4800 M1 = M1 - 5
4810 B = B - 200
4820 M = M - 20 - 30 * RND ( 1 )
4830 GOTO 4860
4840 PRINT "THE GOING GETS SLOW"
4850 M = M - 45 - RND(1) / 0.02
4860 IF F1 = 1 THEN 4900
4870 F1 = 1
4880 IF RND(1) < 0.8 THEN 4970
4890 PRINT "YOU MADE IT SAFELY THROUGH SOUTH PASS--NO SNOW"
4900 IF M < 1700 THEN 4940
4910 IF F2 = 1 THEN 4940
4920 F2 = 1
4930 IF RND(1) < 0.7 THEN 4970
4940 IF M > 950 THEN 1230
4950 M9 = 1
4960 GOTO 1230
4970 PRINT "BLIZZARD IN MOUNTAIN PASS--TIME AND SUPPLIES LOST"
4980 L1 = 1
4990 F = F - 25
5000 M1 = M1 - 10
5010 B = B - 300
5020 M = M - 30 - 40 * RND ( 1 )
5030 IF C < 18 + 2 * RND ( 1 ) THEN 6300
5040 GOTO 4940
5050 REM ***DYING***
5060 PRINT "YOU RAN OUT OF FOOD AND STARVED TO DEATH"
5070 GOTO 5170
5080 LET T = 0
5090 PRINT "YOU CAN'T AFFORD A DOCTOR"
5100 GOTO 5120
5110 PRINT "YOU RAN OUT OF MEDICAL SUPPLIES"
5120 PRINT "YOU DIED OF " ;
5130 IF K8 = 1 THEN 5160
5140 PRINT "PNEUMONIA"
5150 GOTO 5170
5160 PRINT "INJURIES"
5170 PRINT
5180 PRINT "DUE TO YOUR UNFORTUNATE SITUATION, THERE ARE A FEW"
5190 PRINT "FORMALITIES WE MUST GO THROUGH"
5200 PRINT
5210 PRINT "WOULD YOU LIKE A MINISTER?"
5220 INPUT C$
5230 PRINT "WOULD YOU LIKE A FANCY FUNERAL?"
5240 INPUT C$
5250 PRINT "WOULD YOU LIKE US TO INFORM YOUR NEXT OF KIN?"
5260 INPUT C$
5270 IF C$ = "YES" THEN 5310
5280 PRINT "BUT YOUR AUNT SADIE IN ST. LOUIS IS REALLY WORRIED ABOUT YOU"
5290 PRINT
5300 GOTO 5330
5310 PRINT "THAT WILL BE $4.50 FOR THE TELEGRAPH CHARGE."
5320 PRINT
5330 PRINT "WE THANK YOU FOR THIS INFORMATION AND WE ARE SORRY YOU"
5340 PRINT "DIDN'T MAKE IT TO THE GREAT TERRITORY OF OREGON"
5350 PRINT "BETTER LUCK NEXT TIME"
5360 PRINT
5370 PRINT
5380 PRINT TAB ( 30 ) ; "SINCERELY"
5390 PRINT
5400 PRINT TAB ( 17 ) ; "THE OREGON CITY CHAMBER OF COMMERCE"
5409 REM 'STOP' COMMAND BELOW CHANGED TO 'END' BY C.D.P.
5410 END
5420 REM ***FINAL TURN***
5430 F9 = ( 2040 - M2 ) / ( M - M2 )
5440 F = F + ( 1 - F9 ) * ( 8 + 5 * E )
5450 PRINT
5460 REM **BELLS IN LINES 5470,5480**
5470 PRINT "YOU FINALLY ARRIVED AT OREGON CITY"
5480 PRINT "AFTER 2040 LONG MILES---HOORAY!!!!!"
5490 PRINT "A REAL PIONEER!"
5500 PRINT
5510 F9 = INT ( F9 * 14 )
5520 D3 = D3 * 14 + F9
5530 F9 = F9 + 1
5540 IF F9 < 8 THEN 5560
5550 F9 = F9 - 7
5560 ON F9 GOTO 5570 , 5590 , 5610 , 5630 , 5650 , 5670 , 5690
5570 PRINT "MONDAY " ;
5580 GOTO 5700
5590 PRINT "TUESDAY " ;
5600 GOTO 5700
5610 PRINT "WEDNESDAY " ;
5620 GOTO 5700
5630 PRINT "THURSDAY " ;
5640 GOTO 5700
5650 PRINT "FRIDAY " ;
5660 GOTO 5700
5670 PRINT "SATURDAY " ;
5680 GOTO 5700
5690 PRINT "SUNDAY " ;
5700 IF D3 > 124 THEN 5740
5710 D3 = D3 - 93
5720 PRINT "JULY " ; D3 ; " 1847"
5730 GOTO 5920
5740 IF D3 > 155 THEN 5780
5750 D3 = D3 - 124
5760 PRINT "AUGUST " ; D3 ; " 1847"
5770 GOTO 5920
5780 IF D3 > 185 THEN 5820
5790 D3 = D3 - 155
5800 PRINT "SEPTEMBER " ; D3 ; " 1847"
5810 GOTO 5920
5820 IF D3 > 216 THEN 5860
5830 D3 = D3 - 185
5840 PRINT "OCTOBER " ; D3 ; " 1847"
5850 GOTO 5920
5860 IF D3 > 246 THEN 5900
5870 D3 = D3 - 216
5880 PRINT "NOVEMBER " ; D3 ; " 1847"
5890 GOTO 5920
5900 D3 = D3 - 246
5910 PRINT "DECEMBER " ; D3 ; " 1847"
5920 PRINT
5930 REM LINE 5930 REMOVED BY C.D.P. FOR COMPATIBILITY WITH MODERN BASIC
5940 IF B > 0 THEN 5960
5950 LET B = 0
5960 IF C > 0 THEN 5980
5970 LET C = 0
5980 IF M1 > 0 THEN 6000
5990 LET M1 = 0
6000 IF T > 0 THEN 6020
6010 LET T = 0
6020 IF F > 0 THEN 6040
6030 LET F = 0
6040 REM LINES 6040-6045 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH MODERN BASIC
6041 PRINT "FOOD: " ; F
6042 PRINT "BULLETS: " ; B
6043 PRINT "CLOTHING: " ; C
6044 PRINT "MISC. SUPP.: " ; M1
6045 PRINT "CASH: " ; T
6050 PRINT
6060 PRINT TAB ( 11 ) ; "PRESIDENT JAMES K. POLK SENDS YOU HIS"
6070 PRINT TAB ( 17 ) ; "HEARTIEST CONGRATULATIONS"
6080 PRINT
6090 PRINT TAB ( 11 ) ; "AND WISHES YOU A PROSPEROUS LIFE AHEAD"
6100 PRINT
6110 PRINT TAB ( 22 ) ; "AT YOUR NEW HOME"
6119 REM 'STOP' COMMAND BELOW CHANGED TO 'END' BY C.D.P.
6120 END
6130 REM ***SHOOTING SUB-ROUTINE***
6131 REM THE METHOD OF TIMING THE SHOOTING (LINES 6210-6240)
6132 REM WILL VARY FROM SYSTEM TO SYSTEM. FOR EXAMPLE, H-P
6133 REM USERS WILL PROBABLY PREFER TO USE THE 'ENTER' STATEMENT.
6134 REM IF TIMING ON THE USER'S SYSTEM IS HIGHLY SUSCEPTIBLE
6135 REM TO SYSTEM RESPONSE TIME, THE FORMULA IN LINE 6240 CAN
6136 REM BE TAILORED TO ACCOMMODATE THIS BY EITHER INCREASING
6137 REM OR DECREASING THE 'SHOOTING' TIME RECORDED BY THE SYSTEM
6140 DIM S$ ( 5 )
6150 S$ ( 1 ) = "BANG"
6160 S$ ( 2 ) = "BLAM"
6170 S$ ( 3 ) = "POW"
6180 S$ ( 4 ) = "WHAM"
6190 S6 = INT ( RND ( 1 ) * 4 + 1 )
6200 PRINT "TYPE " ; S$ ( S6 )
6201 REM NO TIMER FUNCTION IN PYBASIC, SO RANDOM ELEMENT INTRODUCED
6202 REM I'M AWARE THAT THIS CHANGES THE ELEMENT OF 'SKILL' TO
6203 REM ONE OF LUCK FOR HUNTING
6206 REM 'CLK(0)' FUNCTION CHANGED TO 'TIMER' BY C.D.P. FOR COMPATIBILITY
6207 REM B3 = TIMER changed to B3 = TIMER + 2 BY C.D.P. TO MAKE HUNTING...
6208 REM ...EASIER ON MODERN COMPUTERS. SEE NOTES FROM ORIGINAL AUTHOR ON
6209 REM ... ON TWEAKING HUNTING DIFFICULTY
6210 REM B3 = TIMER + 2
6220 INPUT C$
6229 REM 'CLK(0)' FUNCTION CHANGED TO 'TIMER' BY C.D.P. FOR COMPATIBILITY
6230 REM B1 = TIMER
6240 REM B1 = ( ( B1 - B3 ) * 3600 ) - ( D9 - 1 )
6244 REM IT'S A PYBASIC BODGE, BUT GENERATE RANDOM B1
6245 B1 = INT(RND(1)*9)+1
6250 PRINT
6255 IF B1 > 0 THEN 6260
6257 B1 = 0
6260 IF C$ = S$ ( S6 ) THEN 6280
6270 B1 = 9
6280 RETURN
6290 REM ***ILLNESS SUB-ROUTINE***
6300 IF 100 * RND ( 1 ) < 10 + 35 * ( E - 1 ) THEN 6370
6309 REM LINE 6310 MODIFIED BY C.D.P. FOR COMPATIBILITY WITH CHIPMUNK BASIC
6310 IF 100*RND(1)<100-POW(40/4,E-1) THEN 6410
6320 PRINT "SERIOUS ILLNESS---"
6330 PRINT "YOU MUST STOP FOR MEDICAL ATTENTION"
6340 M1 = M1 - 10
6350 S4 = 1
6360 GOTO 6440
6370 PRINT "WILD ILLNESS---MEDICINE USED"
6380 M = M - 5
6390 M1 = M1 - 2
6400 GOTO 6440
6410 PRINT "BAD ILLNESS---MEDICINE USED"
6420 M = M - 5
6430 M1 = M1 - 5
6440 IF M1 < 0 THEN 5110
6450 IF L1 = 1 THEN 4940
6460 GOTO 4710
6470 REM ***IDENTIFICATION OF VARIABLES IN THE PROGRAM***
6480 REM A = AMOUNT SPENT ON ANIMALS
6490 REM B = AMOUNT SPENT ON AMMUNITION
6500 REM B1 = ACTUAL RESPONSE TIME FOR INPUTTING "BANG"
6510 REM B3 = CLOCK TIME AT START OF INPUTTING "BANG"
6520 REM C = AMOUNT SPENT ON CLOTHING
6530 REM C1 = FLAG FOR INSUFFICIENT CLOTHING IN COLD WEATHER
6540 REM C$ = YES/N0 RESPONSE TO QUESTIONS
6550 REM D1 = COUNTER IN GENERATING EVENTS
6560 REM D3 = TURN NUMBER FOR SETTING DATE
6570 REM D4 = CURRENT DATE
6580 REM D9 = CHOICE OF SHOOTING EXPERTISE LEVEL
6590 REM E = CHOICE OF EATING
6600 REM F = AMOUNT SPENT ON FOOD
6610 REM F1 = FLAG FOR CLEARING SOUTH PASS
6620 REM F2 = FLAG FOR CLEARING BLUE MOUNTAINS
6630 REM F9 = FRACTION OF 2 WEEKS TRAVELED ON FINAL TURN
6640 REM K8 = FLAG FOR INJURY
6650 REM L1 = FLAG FOR BLIZZARD
6660 REM M = TOTAL MILEAGE WHOLE TRIP
6670 REM M1 = AMOUNT SPENT ON MISCELLANEOUS SUPPLIES
6680 REM M2 = TOTAL MILEAGE UP THROUGH PREVIOUS TURN
6690 REM M9 = FLAG FOR CLEARING SOUTH PASS IN SETTING MILEAGE
6700 REM P = AMOUNT SPENT ON ITEMS AT FORT
6710 REM R1 = RANDOM NUMBER IN CHOOSING EVENTS
6720 REM S4 = FLAG FOR ILLNESS
6730 REM S5 = ""HOSTILITY OF RIDERS"" FACTOR
6740 REM S6 = SHOOTING WORD SELECTOR
6750 REM S$ = VARIATIONS OF SHOOTING WORD
6760 REM T = CASH LEFT OVER AFTER INITIAL PURCHASES
6770 REM T1 = CHOICE OF TACTICS WHEN ATTACKED
6780 REM X = CHOICE OF ACTION FOR EACH TURN
6790 REM X1 = FLAG FOR FORT OPTION
6800 END

View file

@ -0,0 +1,159 @@
10 REM A BASIC PROGRAM THAT CAN BE USED FOR REGRESSION TESTING
20 REM OF ALL INTERPRETER FUNCTIONALITY
30 PRINT "*** Testing basic arithmetic functions and multiple statements ***"
40 LET I = 100: LET J = 200
60 PRINT "Expecting the sum to be 300:"
70 PRINT I + J
80 PRINT "Expecting the product to be 20000:"
90 PRINT I * J
100 PRINT "Expecting the sum to be 20100:"
110 PRINT 100 + I * J
120 PRINT "Expecting sum to be 40000"
130 PRINT (100 + I) * J
140 IF I > J THEN 150 ELSE 180
150 PRINT "Should not print the smaller value of I which is "; I
160 PRINT I
170 GOTO 180
180 PRINT "Should print the larger value of J which is "; J
190 PRINT J
200 GOTO 220
210 PRINT "Should not print this line"
220 PRINT "*** Testing subroutine behaviour ***"
230 PRINT "Calling subroutine"
240 GOSUB 1630
250 PRINT "Exited subroutine"
260 PRINT "Now testing nested subroutines"
270 GOSUB 1660
280 PRINT "*** Testing loops ***"
290 PRINT "This loop should count to 5 in increments of 1:"
300 FOR I = 1 TO 5
310 PRINT I
320 NEXT I
330 PRINT "This loop should count back from 10 to 1 in decrements of 2:"
340 FOR I = 10 TO 1 STEP -2
350 PRINT I
360 NEXT I
370 PRINT "These nested loops should print 11, 12, 13, 21, 22, 23:"
380 FOR I = 1 TO 2
390 FOR J = 1 TO 3
400 PRINT I; J
410 NEXT J
420 NEXT I
430 PRINT "*** Testing arrays ***"
440 DIM A(3, 3)
450 FOR I = 0 TO 2
460 FOR J = 0 TO 2
470 LET A(I, J) = 5
480 NEXT J
490 NEXT I
500 PRINT "This should print 555"
510 PRINT A(0, 0); A(1, 1); A(2, 2)
520 PRINT "*** Testing file i/o ***"
530 OPEN "REGRESSION.TXT" FOR OUTPUT AS #1
540 PRINT #1,"0123456789Hello World!"
545 PRINT #1,"This is second line for testing"
550 CLOSE #1
560 OPEN "REGRESSION.TXT" FOR INPUT AS #2
570 PRINT "The next line should say 'Hello World!'"
580 FSEEK #2,10
590 INPUT #2,A$
595 PRINT A$
600 CLOSE #2
601 OPEN "REGRESSION.TXT" FOR APPEND AS #2
602 PRINT "3 text lines starting with 0,T,S and ending with !,g,e should follow:"
603 PRINT #2,"Should be a seperate line"
604 CLOSE #2
605 OPEN "REGRESSION.TXT" FOR INPUT AS #2
606 FOR I = 1 TO 2
607 INPUT #2,A$:PRINT A$
608 NEXT I
609 INPUT #2,A$
610 FOR I = 1 TO 25
611 PRINT MID$(A$,I,1);
612 NEXT I
613 PRINT:CLOSE #2
614 OPEN "NOFILE.X7Z" FOR INPUT AS #2 ELSE 620
615 PRINT "***This Message should NOT be Displayed***"
620 N = 0
630 I = 7
640 PRINT "This loop should count to 5 in increments of 1 twice:"
650 FOR I = 1 TO 10
660 PRINT I
670 IF I = 5 THEN GOTO 690
680 NEXT I
690 N = N + 1
700 IF N < 2 THEN GOTO 650
810 PRINT "The loop variable I should be equal to 5, I=";I
815 DATA "DATA Statement tests..."
820 READ A$
825 PRINT "The next line should read: DATA Statement tests..."
830 PRINT A$
840 DATA 1 , 2 , 3
850 DATA 4 , 5 , 6
855 DATA 1.5 , 2 , "test"
858 PRINT "The next three lines should be: 12 34 56"
860 FOR I = 1 TO 3
870 READ J , K
880 PRINT J ; K
890 NEXT I
900 RESTORE 840
910 READ I , J , K
920 PRINT "the next line should print 123"
930 PRINT I ; J ; K
970 RESTORE 855
980 READ A1 , B , C$
990 PRINT "Float: " ; A1 ; " Int: " ; B ; " String: " ; C$
1000 RESTORE 850
1010 READ I , J , K , L
1020 PRINT "the next line should print 4561.5:"
1030 PRINT I; J ; K ; L
1040 PRINT "The next lines should print: 'Hello World' and then 'AGAIN' under the word 'World'"
1050 PRINT "Hel" ; : PRINT "lo" ; TAB ( 7 ) ; "World" ; TAB ( 7 ) ; "AGAIN"
1060 PRINT "This loop should count from 1 to 10"
1070 FOR I = 1 TO 10
1080 FOR J = 1 TO 3
1090 PRINT I
1100 GOTO 1130
1120 NEXT J
1130 NEXT I
1140 INPUT "Enter T for the THEN blocks to execute, E for the ELSE (T/E): " ; ANS$
1150 ANS$ = UPPER$ ( ANS$ )
1160 IF ANS$ = "T" THEN 1190
1170 PRINT "1170: Did not enter T"
1180 GOTO 1200
1190 PRINT "1190: Entered T"
1200 IF ANS$ = "T" THEN GOTO 1230
1210 PRINT "1210: Did not enter T"
1220 GOTO 1240
1230 PRINT "1230: Entered T"
1240 IF ANS$ = "T" THEN 1280 ELSE 1260
1250 PRINT "ERROR - Should not be at line 1250"
1260 PRINT "1260: Did not enter T"
1270 GOTO 1290
1280 PRINT "1280: Entered T"
1290 IF ANS$ = "T" THEN GOTO 1330 ELSE GOTO 1310
1300 PRINT "ERROR - Should not be at line 1300"
1310 PRINT "1310: Did not enter T"
1320 GOTO 1340
1330 PRINT "1330: Entered T"
1340 IF ANS$ = "T" THEN PRINT "1340: Entered T"
1350 IF ANS$ <> "T" THEN PRINT "1350: Did not enter T"
1360 IF ANS$ = "T" THEN PRINT "1360: Entered T" ELSE PRINT "1360: Did not enter T"
1370 IF ANS$ = "T" THEN PRINT "1370: Entered T" : GOTO 1390
1380 IF ANS$ <> "T" THEN PRINT "1380: Did not enter T"
1390 IF ANS$ = "T" THEN PRINT "1390: Entered " ; : PRINT "T" ELSE PRINT "1390: Did " ; : PRINT "not enter T"
1400 IF ANS$ = "T" THEN PRINT "1400: Entered T" ELSE PRINT "1400: Did " ; : PRINT "not enter T"
1410 IF ANS$ = "T" THEN PRINT "1410: Entered " ; : PRINT "T" ELSE PRINT "1410: Did not enter T"
1420 PRINT "Compound Stmt w/conditionals ";:IF ANS$ = "T" THEN PRINT "1420: Entered " ; : PRINT "T" ELSE PRINT "1420: Did " ; : PRINT "not enter T"
1610 PRINT "*** Finished ***"
1620 STOP
1630 REM A SUBROUTINE TEST
1640 PRINT "Executing the subroutine"
1650 RETURN
1660 REM AN OUTER SUBROUTINE
1670 GOSUB 1700
1680 PRINT "This should be printed second"
1690 RETURN
1700 REM A NESTED SUBROUTINE
1710 PRINT "This should be printed first"
1720 RETURN

View file

@ -0,0 +1,63 @@
10 REM ROCK, SCISSORS, PAPER AGAINST
20 REM THE COMPUTER
30 RANDOMIZE
40 MYSCORE = 0
50 YOURSCORE = 0
60 PRINT "Let's play rock-scissors-paper!"
70 INPUT "(R)ock, (S)cissors, (P)aper or e(X)it: "; YOURGUESS$
75 IF YOURGUESS$ = "X" THEN 160
80 RANDOM = RND(1)
90 GOSUB 190
100 PRINT "Your guess: "; YOURGUESS$; ", My guess: "; MYGUESS$
110 REM ON YOURGUESS$ = "R" GOSUB 300
120 REM ON YOURGUESS$ = "S" GOSUB 500
130 REM ON YOURGUESS$ = "P" GOSUB 700
135 ON INSTR("RSP",YOURGUESS$) GOSUB 300,500,700
150 GOTO 70
160 PRINT "My score: "; MYSCORE; " Your score: "; YOURSCORE
170 STOP
190 REM RANDOMLY ASSIGN MYGUESS$
200 IF RANDOM < 0.3 THEN 210 ELSE 230
210 MYGUESS$ = "R"
220 RETURN
230 IF RANDOM < 0.6 THEN 240 ELSE 260
240 MYGUESS$ = "S"
250 RETURN
260 MYGUESS$ = "P"
270 RETURN
300 REM ROCK
310 IF MYGUESS$ = "R" THEN 320 ELSE 340
320 PRINT "A draw!"
330 RETURN
340 IF MYGUESS$ = "S" THEN 350 ELSE 380
350 PRINT "I lost!"
360 YOURSCORE = YOURSCORE + 1
370 RETURN
380 IF MYGUESS$ = "P" THEN 390 ELSE 410
390 PRINT "I won!"
400 MYSCORE = MYSCORE + 1
410 RETURN
500 REM SCISSORS
510 IF MYGUESS$ = "S" THEN 520 ELSE 540
520 PRINT "A draw!"
530 RETURN
540 IF MYGUESS$ = "P" THEN 550 ELSE 580
550 PRINT "I lost!"
560 YOURSCORE = YOURSCORE + 1
570 RETURN
580 IF MYGUESS$ = "R" THEN 390 ELSE 410
590 PRINT "I won!"
600 MYSCORE = MYSCORE + 1
610 RETURN
700 REM PAPER
710 IF MYGUESS$ = "P" THEN 720 ELSE 740
720 PRINT "A draw!"
730 RETURN
740 IF MYGUESS$ = "R" THEN 750 ELSE 780
750 PRINT "I lost!"
760 YOURSCORE = YOURSCORE + 1
770 RETURN
780 IF MYGUESS$ = "S" THEN 790 ELSE 810
790 PRINT "I won!"
800 MYSCORE = MYSCORE + 1
810 RETURN

View file

@ -0,0 +1,95 @@
2 PRINT TAB ( 34 ) ; "LIFE"
4 PRINT TAB ( 15 ) ; "CREATIVE COMPUTING MORRISTOWN NEW JERSEY"
6 PRINT : PRINT : PRINT
8 PRINT "ENTER YOUR PATTERN, AS A SERIES OF SPACES"
9 PRINT "AND STARS, LINE BY LINE. FINISH BY TYPING"
10 PRINT "'DONE' ON THE FINAL LINE:"
11 X1 = 1 : Y1 = 1 : X2 = 24 : Y2 = 70 : G = 0 : P = 0
12 DIM A ( 24 , 70 ) : DIM B$ ( 24 )
15 I9 = 1
20 C = 1
30 INPUT TEMP$
35 B$ ( C ) = TEMP$
40 IF B$ ( C ) = "DONE" THEN 45 ELSE 50
45 B$ ( C ) = "" : GOTO 80
46 REM ORIGINAL VERSION REQUIRED USER TO WRITE
47 REM DOTS INSTEAD OF SPACES, WHICH WOULD THEN BE
48 REM CONVERTED TO SPACES
50 REM IF LEFT$(B$(C), 1)="." THEN 55 ELSE 60
55 REM B$(C)=" "+RIGHT$(B$(C), LEN(B$(C))-1)
60 C = C + 1
70 GOTO 30
80 C = C - 1 : L = 0
90 FOR X = 1 TO C - 1
100 IF LEN ( B$ ( X ) ) > L THEN 105 ELSE 110
105 L = LEN ( B$ ( X ) )
110 NEXT X
120 X1 = INT ( 11 - C / 2 )
130 Y1 = INT ( 33 - L / 2 )
135 REM TRANSCRIBE INPUT PATTERN INTO ARRAY
140 FOR X = 1 TO C
150 FOR Y = 1 TO LEN ( B$ ( X ) )
160 IF MID$ ( B$ ( X ) , Y , 1 ) <> " " THEN 165 ELSE 170
165 A ( X1 + X , Y1 + Y ) = 1 : P = P + 1
170 NEXT Y
180 NEXT X
200 PRINT CHR$ ( 27 ) + "[2J"
210 PRINT CHR$ ( 27 ) + "[2;1HGENERATION: " ; G ; " POPULATION: " ; P ; CHR$ ( 27 ) + "[K" ;
212 IF I9 = 0 THEN 213 ELSE 215
213 PRINT " INVALID!" ; CHR$ ( 27 ) + "[K" ;
215 X3 = 24 : Y3 = 70 : X4 = 1 : Y4 = 1 : P = 0
220 G = G + 1
230 FOR X = X1 TO X2
240 IF X-X1+1 < 17 THEN PRINT CHR$ ( 27 ) + "[K"
250 FOR Y = Y1 TO Y2
253 IF A ( X , Y ) = 2 THEN 254 ELSE 256
254 A ( X , Y ) = 0 : GOTO 270
256 IF A ( X , Y ) = 3 THEN 258 ELSE 260
258 A ( X , Y ) = 1 : GOTO 261
260 IF A ( X , Y ) <> 1 THEN 270
261 IF X-X1+1 < 17 THEN PRINT TAB ( Y ) ; "*" ;
262 IF X < X3 THEN 263 ELSE 264
263 X3 = X
264 IF X > X4 THEN 265 ELSE 266
265 X4 = X
266 IF Y < Y3 THEN 267 ELSE 268
267 Y3 = Y
268 IF Y > Y4 THEN 269 ELSE 270
269 Y4 = Y
270 NEXT Y
290 NEXT X
293 PRINT
295 FOR X = X2 + 1 TO 24
296 IF X-X1+1 < 17 THEN PRINT " "*71
297 NEXT X
299 X1 = X3 : X2 = X4 : Y1 = Y3 : Y2 = Y4
301 IF X1 < 3 THEN 302 ELSE 303
302 X1 = 3 : I9 = - 1
303 IF X2 > 22 THEN 304 ELSE 305
304 X2 = 22 : I9 = - 1
305 IF Y1 < 3 THEN 306 ELSE 307
306 Y1 = 3 : I9 = - 1
307 IF Y2 > 68 THEN 308 ELSE 309
308 Y2 = 68 : I9 = - 1
309 P = 0
500 FOR X = X1 - 1 TO X2 + 1
510 FOR Y = Y1 - 1 TO Y2 + 1
520 C = 0
530 FOR I = X - 1 TO X + 1
540 FOR J = Y - 1 TO Y + 1
550 IF A ( I , J ) = 1 OR A ( I , J ) = 2 THEN 555 ELSE 560
555 C = C + 1
560 NEXT J
570 NEXT I
580 IF A ( X , Y ) = 0 THEN 610
590 IF C < 3 OR C > 4 THEN 592 ELSE 595
592 A ( X , Y ) = 2 : GOTO 600
595 P = P + 1
600 GOTO 620
610 IF C = 3 THEN 615 ELSE 620
615 A ( X , Y ) = 3 : P = P + 1
620 NEXT Y
630 NEXT X
635 X1 = X1 - 1 : Y1 = Y1 - 1 : X2 = X2 + 1 : Y2 = Y2 + 1
640 GOTO 210
650 END

View file

@ -0,0 +1,110 @@
#! /usr/bin/python
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""This class defines an object that can be returned by the BASICParser to
indicate the need for a control flow branch. The information within the
object tells the Program the nature of the jump and therefore whether a
return address need to be added to the return stack.
>>> flowsignal = FlowSignal(ftype=FlowSignal.RETURN)
>>> print(flowsignal.ftarget)
-1
>>> flowsignal = FlowSignal(ftarget=100, ftype=FlowSignal.SIMPLE_JUMP)
>>> print(flowsignal.ftarget)
100
>>> print(flowsignal.ftype)
0
"""
class FlowSignal:
# Jump categories
# Indicates a simple jump as the result
# of a GOTO or conditional branch. The
# ftarget value should be the jump target, i.e.
# the line number being jumped to
SIMPLE_JUMP = 0
# Indicates a subroutine call where the
# return address must be the line number of the instruction
# of the following the call.
# The ftarget value should be the line number of the first line
# of the subroutine
GOSUB = 1
# Indicates the start of a FOR loop where loop
# variable has not reached the end value, and therefore the loop
# must be repeated. There should be therefore be
# no ftarget value associated with it
LOOP_BEGIN = 2
# An indication from a processed NEXT statement that the loop is to
# be repeated. Since the return address is already on the stack,
# there does not need to be an ftarget value associated with the signal.
LOOP_REPEAT = 3
# An indication from a FOR statement that the loop should be skipped because
# loop variable has reached its end value. The ftarget should be
# the loop variable to look for in the terminating NEXT statement
LOOP_SKIP = 4
# Indicates a subroutine return has been processed, where the return
# address is on the return stack. There should be therefore
# be no ftarget value specified
RETURN = 5
# Indicates that execution should cease because a stop statement has
# been processed. There should be therefore be no ftarget value specified
STOP = 6
# Indicates that a conditional result block should be executed
EXECUTE = 7
def __init__(self, ftarget=None, ftype=SIMPLE_JUMP, floop_var=None):
"""Creates a new FlowSignal for a branch. If the jump
target is supplied, then the branch is assumed to be
either a GOTO or conditional branch and the type is assigned as
SIMPLE_JUMP. If no jump_target is supplied, then a jump_type must be
supplied, which must either be GOSUB, RETURN, LOOP_BEGIN,
LOOP_REPEAT, LOOP_SKIP or STOP. In the latter cases
the jump target is assigned an arbitrary value of None.
:param ftarget: The associated value
:param ftype: Either GOSUB, SIMPLE_JUMP, RETURN, LOOP_BEGIN,
LOOP_SKIP or STOP
:param floop_var: The loop variable of a FOR/NEXT loop
"""
if ftype not in [self.GOSUB, self.SIMPLE_JUMP, self.LOOP_BEGIN,
self.LOOP_REPEAT, self.RETURN,
self.LOOP_SKIP, self.STOP, self.EXECUTE]:
raise TypeError("Invalid flow signal type supplied: " + str(ftype))
if ftarget == None and \
ftype in [self.SIMPLE_JUMP, self.GOSUB, self.LOOP_SKIP]:
raise TypeError("Invalid jump target supplied for flow signal type: " + str(ftarget))
if ftarget != None and \
ftype in [self.RETURN, self.LOOP_BEGIN, self.LOOP_REPEAT,
self.STOP, self.EXECUTE]:
raise TypeError("Target wrongly supplied for flow signal " + str(ftype))
self.ftype = ftype
self.ftarget = ftarget
self.floop_var = floop_var

View file

@ -0,0 +1,135 @@
#! /usr/bin/python
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""This class implements a BASIC interpreter that
presents a prompt to the user. The user may input
program statements, list them and run the program.
The program may also be saved to disk and loaded
again.
"""
from basictoken import BASICToken as Token
from lexer import Lexer
from program import Program
from sys import stderr
from traceback import print_exception
def main():
banner = (r"""
._____________ ___________. ___ ___________ ______
| _ .__ \ / ___ _ \ / \ / | / |
| |_) | \ \/ / | |_) | / ^ \ | (----`| | | ,----'
| ___/ \_ _/ | _ < / /_\ \ \ \ | | | |
| | | | | |_) \/ _____ \----) | | | | `----.
| _| |__| |___________/ \_________/ |____________|
""")
print(banner)
lexer = Lexer()
program = Program()
# Continuously accept user input and act on it until
# the user enters 'EXIT'
while True:
stmt = input('> ')
try:
tokenlist = lexer.tokenize(stmt)
# Execute commands directly, otherwise
# add program statements to the stored
# BASIC program
if len(tokenlist) > 0:
# Exit the interpreter
if tokenlist[0].category == Token.EXIT:
break
# Add a new program statement, beginning
# a line number
elif tokenlist[0].category == Token.UNSIGNEDINT\
and len(tokenlist) > 1:
program.add_stmt(tokenlist)
# Delete a statement from the program
elif tokenlist[0].category == Token.UNSIGNEDINT \
and len(tokenlist) == 1:
program.delete_statement(int(tokenlist[0].lexeme))
# Execute the program
elif tokenlist[0].category == Token.RUN:
try:
program.execute()
except KeyboardInterrupt:
print("Program terminated")
# List the program
elif tokenlist[0].category == Token.LIST:
if len(tokenlist) == 2:
program.list(int(tokenlist[1].lexeme),int(tokenlist[1].lexeme))
elif len(tokenlist) == 3:
# if we have 3 tokens, it might be LIST x y for a range
# or LIST -y or list x- for a start to y, or x to end
if tokenlist[1].lexeme == "-":
program.list(None, int(tokenlist[2].lexeme))
elif tokenlist[2].lexeme == "-":
program.list(int(tokenlist[1].lexeme), None)
else:
program.list(int(tokenlist[1].lexeme),int(tokenlist[2].lexeme))
elif len(tokenlist) == 4:
# if we have 4, assume LIST x-y or some other
# delimiter for a range
program.list(int(tokenlist[1].lexeme),int(tokenlist[3].lexeme))
else:
program.list()
# Save the program to disk
elif tokenlist[0].category == Token.SAVE:
program.save(tokenlist[1].lexeme)
print("Program written to file")
# Load the program from disk
elif tokenlist[0].category == Token.LOAD:
program.load(tokenlist[1].lexeme)
print("Program read from file")
# Delete the program from memory
elif tokenlist[0].category == Token.NEW:
program.delete()
# Unrecognised input
else:
print("Unrecognised input", file=stderr)
for token in tokenlist:
token.print_lexeme()
print(flush=True)
# Trap all exceptions so that interpreter
# keeps running
except Exception as e:
print_exception(e,e, \
e.__traceback__ if hasattr(e,'__traceback__') else None)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,202 @@
#! /usr/bin/python
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""This class implements a lexical analyser capable
of consuming BASIC statements and commands and returning
a corresponding list of tokens.
>>> lexer = Lexer()
>>> tokenlist = lexer.tokenize('100 LET I = 10')
>>> tokenlist[0].pretty_print()
Column: 0 Category: UNSIGNEDINT Lexeme: 100
>>> tokenlist = lexer.tokenize('100 IF I <> 10')
>>> tokenlist[3].pretty_print()
Column: 9 Category: NOTEQUAL Lexeme: <>
>>> tokenlist = lexer.tokenize('100 LET I = 3.45')
>>> tokenlist[4].pretty_print()
Column: 12 Category: UNSIGNEDFLOAT Lexeme: 3.45
>>> tokenlist = lexer.tokenize('100 LET I = "HELLO"')
>>> tokenlist[4].pretty_print()
Column: 12 Category: STRING Lexeme: HELLO
"""
from basictoken import BASICToken as Token
class Lexer:
def __init__(self):
self.__column = 0 # Current column number
self.__stmt = '' # Statement string being processed
def tokenize(self, stmt):
"""Returns a list of tokens obtained by
lexical analysis of the specified
statement.
"""
self.__stmt = stmt
self.__column = 0
# Establish a list of tokens to be
# derived from the statement
tokenlist = []
# Process every character until we
# reach the end of the statement string
c = self.__get_next_char()
while c != '':
# Skip any preceding whitespace
while c.isspace():
c = self.__get_next_char()
# Construct a token, column count already
# incremented
token = Token(self.__column - 1, None, '')
# Process strings
if c == '"':
token.category = Token.STRING
# Consume all of the characters
# until we reach the terminating
# quote. Do not store the quotes
# in the lexeme
c = self.__get_next_char() # Advance past opening quote
# We explicitly support empty strings
if c == '"':
# String is empty, leave lexeme as ''
# and advance past terminating quote
c = self.__get_next_char()
else:
while True:
token.lexeme += c # Append the current char to the lexeme
c = self.__get_next_char()
if c == '':
raise SyntaxError("Mismatched quotes")
if c == '"':
c = self.__get_next_char() # Advance past terminating quote
break
# Process numbers
elif c.isdigit() or c == '.':
token.category = Token.UNSIGNEDINT
found_point = False
if c == '.':
token.category = Token.UNSIGNEDFLOAT
found_point = True
# Consume all of the digits, including any decimal point
while True:
token.lexeme += c # Append the current char to the lexeme
c = self.__get_next_char()
# Break if next character is not a digit
# and this is not the first decimal point
if not c.isdigit():
if c == '.':
if found_point is False:
found_point = True
token.category = Token.UNSIGNEDFLOAT
else:
# Another decimal point found
break
else:
break
# Process keywords and names
elif c.isalpha():
# Consume all of the letters
while True:
token.lexeme += c # append the current char to the lexeme
c = self.__get_next_char()
# Break if not a letter or a dollar symbol
# (the latter is used for string variable names)
if not ((c.isalpha() or c.isdigit()) or c == '_' or c == '$'):
break
# Normalise keywords and names to upper case
token.lexeme = token.lexeme.upper()
# Determine if the lexeme is a variable name or a
# reserved word
if token.lexeme in Token.keywords:
token.category = Token.keywords[token.lexeme]
else:
token.category = Token.NAME
# Remark Statements - process rest of statement without checks
if token.lexeme == "REM":
while c!= '':
token.lexeme += c # Append the current char to the lexeme
c = self.__get_next_char()
# Process operator symbols
elif c in Token.smalltokens:
save = c
c = self.__get_next_char() # c might be '' (end of stmt)
twochar = save + c
if twochar in Token.smalltokens:
token.category = Token.smalltokens[twochar]
token.lexeme = twochar
c = self.__get_next_char() # Move past end of token
else:
# One char token
token.category = Token.smalltokens[save]
token.lexeme = save
# We do not recognise this token
elif c != '':
raise SyntaxError('Syntax error')
# Append the new token to the list
tokenlist.append(token)
return tokenlist
def __get_next_char(self):
"""Returns the next character in the
statement, unless the last character has already
been processed, in which case, the empty string is
returned.
"""
if self.__column < len(self.__stmt):
next_char = self.__stmt[self.__column]
self.__column = self.__column + 1
return next_char
else:
return ''
if __name__ == "__main__":
import doctest
doctest.testmod()

View file

@ -0,0 +1,4 @@
{
"title": "PyBasic",
"icon": "PyBasic.bmp"
}

View file

@ -0,0 +1,487 @@
#! /usr/bin/python
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Class representing a BASIC program.
This is a list of statements, ordered by
line number.
"""
from basictoken import BASICToken as Token
from basicparser import BASICParser
from flowsignal import FlowSignal
from lexer import Lexer
import os
class BASICData:
def __init__(self):
# array of line numbers to represent data statements
self.__datastmts = {}
# Data pointer
self.__next_data = 0
def delete(self):
self.__datastmts.clear()
self.__next_data = 0
def delData(self,line_number):
if self.__datastmts.get(line_number) != None:
del self.__datastmts[line_number]
def addData(self,line_number,tokenlist):
"""
Adds the supplied token list
to the program's DATA store. If a token list with the
same line number already exists, this is
replaced.
line_number: Basic program line number of DATA statement
"""
try:
self.__datastmts[line_number] = tokenlist
except TypeError as err:
raise TypeError("Invalid line number: " + str(err))
def getTokens(self,line_number):
"""
returns the tokens from the program DATA statement
line_number: Basic program line number of DATA statement
"""
return self.__datastmts.get(line_number)
def readData(self,read_line_number):
if len(self.__datastmts) == 0:
raise RuntimeError('No DATA statements available to READ ' +
'in line ' + str(read_line_number))
data_values = []
line_numbers = list(self.__datastmts.keys())
line_numbers.sort()
if self.__next_data == 0:
self.__next_data = line_numbers[0]
elif line_numbers.index(self.__next_data) < len(line_numbers)-1:
self.__next_data = line_numbers[line_numbers.index(self.__next_data)+1]
else:
raise RuntimeError('No DATA statements available to READ ' +
'in line ' + str(read_line_number))
tokenlist = self.__datastmts[self.__next_data]
sign = 1
for token in tokenlist[1:]:
if token.category != Token.COMMA:
#data_values.append(token.lexeme)
if token.category == Token.STRING:
data_values.append(token.lexeme)
elif token.category == Token.UNSIGNEDINT:
data_values.append(sign*int(token.lexeme))
elif token.category == Token.UNSIGNEDFLOAT:
data_values.append(sign*eval(token.lexeme))
elif token.category == Token.MINUS:
sign = -1
#else:
#data_values.append(token.lexeme)
else:
sign = 1
return data_values
def restore(self,restoreLineNo):
if restoreLineNo == 0 or restoreLineNo in self.__datastmts:
if restoreLineNo == 0:
self.__next_data = restoreLineNo
else:
line_numbers = list(self.__datastmts.keys())
line_numbers.sort()
indexln = line_numbers.index(restoreLineNo)
if indexln == 0:
self.__next_data = 0
else:
self.__next_data = line_numbers[indexln-1]
else:
raise RuntimeError('Attempt to RESTORE but no DATA ' +
'statement at line ' + str(restoreLineNo))
class Program:
def __init__(self):
# Dictionary to represent program
# statements, keyed by line number
self.__program = {}
# Program counter
self.__next_stmt = 0
# Initialise return stack for subroutine returns
self.__return_stack = []
# return dictionary for loop returns
self.__return_loop = {}
# Setup DATA object
self.__data = BASICData()
def __str__(self):
program_text = ""
line_numbers = self.line_numbers()
for line_number in line_numbers:
program_text += self.str_statement(line_number)
return program_text
def str_statement(self, line_number):
line_text = str(line_number) + " "
statement = self.__program[line_number]
if statement[0].category == Token.DATA:
statement = self.__data.getTokens(line_number)
for token in statement:
# Add in quotes for strings
if token.category == Token.STRING:
line_text += '"' + token.lexeme + '" '
else:
line_text += token.lexeme + " "
line_text += "\n"
return line_text
def list(self, start_line=None, end_line=None):
"""Lists the program"""
line_numbers = self.line_numbers()
if not start_line:
start_line = int(line_numbers[0])
if not end_line:
end_line = int(line_numbers[-1])
for line_number in line_numbers:
if int(line_number) >= start_line and int(line_number) <= end_line:
print(self.str_statement(line_number), end="")
def save(self, file):
"""Save the program
:param file: The name and path of the save file, .bas is
appended
"""
if not file.lower().endswith(".bas"):
file += ".bas"
try:
with open(file, "w") as outfile:
outfile.write(str(self))
except OSError:
raise OSError("Could not save to file")
def load(self, file):
"""Load the program
:param file: The name and path of the file to be loaded, .bas is
appended
"""
# New out the program
self.delete()
if not file.lower().endswith(".bas"):
file += ".bas"
try:
lexer = Lexer()
with open(file, "r") as infile:
for line in infile:
line = line.replace("\r", "").replace("\n", "").strip()
tokenlist = lexer.tokenize(line)
self.add_stmt(tokenlist)
except OSError:
raise OSError("Could not read file")
if file.rfind('/') == 0:
os.chdir("/")
elif file.rfind('/') != -1:
os.chdir(file[:file.rfind('/')])
def add_stmt(self, tokenlist):
"""
Adds the supplied token list
to the program. The first token should
be the line number. If a token list with the
same line number already exists, this is
replaced.
:param tokenlist: List of BTokens representing a
numbered program statement
"""
if len(tokenlist) > 0:
try:
line_number = int(tokenlist[0].lexeme)
if tokenlist[1].lexeme == "DATA":
self.__data.addData(line_number,tokenlist[1:])
self.__program[line_number] = [tokenlist[1],]
else:
self.__program[line_number] = tokenlist[1:]
except TypeError as err:
raise TypeError("Invalid line number: " +
str(err))
def line_numbers(self):
"""Returns a list of all the
line numbers for the program,
sorted
:return: A sorted list of
program line numbers
"""
line_numbers = list(self.__program.keys())
line_numbers.sort()
return line_numbers
def __execute(self, line_number):
"""Execute the statement with the
specified line number
:param line_number: The line number
:return: The FlowSignal to indicate to the program
how to branch if necessary, None otherwise
"""
if line_number not in self.__program.keys():
raise RuntimeError("Line number " + line_number +
" does not exist")
statement = self.__program[line_number]
try:
return self.__parser.parse(statement, line_number)
except RuntimeError as err:
raise RuntimeError(str(err))
def execute(self):
"""Execute the program"""
self.__parser = BASICParser(self.__data)
self.__data.restore(0) # reset data pointer
line_numbers = self.line_numbers()
if len(line_numbers) > 0:
# Set up an index into the ordered list
# of line numbers that can be used for
# sequential statement execution. The index
# will be incremented by one, unless modified by
# a jump
index = 0
self.set_next_line_number(line_numbers[index])
# Run through the program until the
# has line number has been reached
while True:
flowsignal = self.__execute(self.get_next_line_number())
self.__parser.last_flowsignal = flowsignal
if flowsignal:
if flowsignal.ftype == FlowSignal.SIMPLE_JUMP:
# GOTO or conditional branch encountered
try:
index = line_numbers.index(flowsignal.ftarget)
except ValueError:
raise RuntimeError("Invalid line number supplied in GOTO or conditional branch: "
+ str(flowsignal.ftarget))
self.set_next_line_number(flowsignal.ftarget)
elif flowsignal.ftype == FlowSignal.GOSUB:
# Subroutine call encountered
# Add line number of next instruction to
# the return stack
if index + 1 < len(line_numbers):
self.__return_stack.append(line_numbers[index + 1])
else:
raise RuntimeError("GOSUB at end of program, nowhere to return")
# Set the index to be the subroutine start line
# number
try:
index = line_numbers.index(flowsignal.ftarget)
except ValueError:
raise RuntimeError("Invalid line number supplied in subroutine call: "
+ str(flowsignal.ftarget))
self.set_next_line_number(flowsignal.ftarget)
elif flowsignal.ftype == FlowSignal.RETURN:
# Subroutine return encountered
# Pop return address from the stack
try:
index = line_numbers.index(self.__return_stack.pop())
except ValueError:
raise RuntimeError("Invalid subroutine return in line " +
str(self.get_next_line_number()))
except IndexError:
raise RuntimeError("RETURN encountered without corresponding " +
"subroutine call in line " + str(self.get_next_line_number()))
self.set_next_line_number(line_numbers[index])
elif flowsignal.ftype == FlowSignal.STOP:
break
elif flowsignal.ftype == FlowSignal.LOOP_BEGIN:
# Loop start encountered
# Put loop line number on the stack so
# that it can be returned to when the loop
# repeats
self.__return_loop[flowsignal.floop_var] = line_numbers[index]
# Continue to the next statement in the loop
index = index + 1
if index < len(line_numbers):
self.set_next_line_number(line_numbers[index])
else:
# Reached end of program
raise RuntimeError("Program terminated within a loop")
elif flowsignal.ftype == FlowSignal.LOOP_SKIP:
# Loop variable has reached end value, so ignore
# all statements within loop and move past the corresponding
# NEXT statement
index = index + 1
while index < len(line_numbers):
next_line_number = line_numbers[index]
temp_tokenlist = self.__program[next_line_number]
if temp_tokenlist[0].category == Token.NEXT and \
len(temp_tokenlist) > 1:
# Check the loop variable to ensure we have not found
# the NEXT statement for a nested loop
if temp_tokenlist[1].lexeme == flowsignal.ftarget:
# Move the statement after this NEXT, if there
# is one
index = index + 1
if index < len(line_numbers):
next_line_number = line_numbers[index] # Statement after the NEXT
self.set_next_line_number(next_line_number)
break
index = index + 1
# Check we have not reached end of program
if index >= len(line_numbers):
# Terminate the program
break
elif flowsignal.ftype == FlowSignal.LOOP_REPEAT:
# Loop repeat encountered
# Pop the loop start address from the stack
try:
index = line_numbers.index(self.__return_loop.pop(flowsignal.floop_var))
except ValueError:
raise RuntimeError("Invalid loop exit in line " +
str(self.get_next_line_number()))
except KeyError:
raise RuntimeError("NEXT encountered without corresponding " +
"FOR loop in line " + str(self.get_next_line_number()))
self.set_next_line_number(line_numbers[index])
else:
index = index + 1
if index < len(line_numbers):
self.set_next_line_number(line_numbers[index])
else:
# Reached end of program
break
else:
raise RuntimeError("No statements to execute")
def delete(self):
"""Deletes the program by emptying the dictionary"""
self.__program.clear()
self.__data.delete()
def delete_statement(self, line_number):
"""Deletes a statement from the program with
the specified line number, if it exists
:param line_number: The line number to be deleted
"""
self.__data.delData(line_number)
try:
del self.__program[line_number]
except KeyError:
raise KeyError("Line number does not exist")
def get_next_line_number(self):
"""Returns the line number of the next statement
to be executed
:return: The line number
"""
return self.__next_stmt
def set_next_line_number(self, line_number):
"""Sets the line number of the next
statement to be executed
:param line_number: The new line number
"""
self.__next_stmt = line_number