diff --git a/pacman/.gitignore b/pacman/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f35f60a357424aa265b3a6c1933c26af537c57ad --- /dev/null +++ b/pacman/.gitignore @@ -0,0 +1,62 @@ +# Mac file finder metadata +.DS_Store +# Windows file metadata +._* +# Thumbnail image caches +Thumbs.db +ethumbs.db +# MS Office temporary file +~* +# Emacs backup file +*~ + +# Common +[Bb]in/ +[Bb]uild/ +[Oo]bj/ +[Oo]ut/ +[Tt]mp/ +[Xx]86/ +[Ii][Aa]32/ +[Xx]64/ +[Xx]86_64/ +[Xx]86-64/ +[Aa]rm +[Aa]32 +[Tt]32 +[Aa]64 +*.tmp +*.bak +*.bk +*.swp + +# Java files +*.class +javadoc/ + +# Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + +# JetBrains (IntelliJ IDEA, PyCharm, etc) files +.idea/ +cmake-build-*/ +*.iml +*.iws +*.ipr + +# Eclipse files +.settings/ +.project +.classpath +.buildpath +.loadpath +.factorypath +local.properties diff --git a/pacman/LICENSE b/pacman/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2 --- /dev/null +++ b/pacman/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://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 <http://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 +<http://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 +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/pacman/README.md b/pacman/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cc1b05fa0ee99bc3f62fdcf6476a7085028b4ef9 --- /dev/null +++ b/pacman/README.md @@ -0,0 +1,5 @@ +This code is a modification of ["Intelligent Java Pacman"](https://sourceforge.net/projects/javaipacman/) by +[Junyang Gu](https://sourceforge.net/u/mikejyg/profile/). + +"Intelligent Java Pacman" is free software released under the GNU General Public +License version 3.0 (GPLv3); see LICENSE for details. diff --git a/pacman/documentation/ghost-specification.txt b/pacman/documentation/ghost-specification.txt new file mode 100644 index 0000000000000000000000000000000000000000..5443911dc9bbb7f566f311b6322ca6b560004e67 --- /dev/null +++ b/pacman/documentation/ghost-specification.txt @@ -0,0 +1,47 @@ +Maze Layout +=========== + +The maze's X coordinates go from 0 (left) to 20 (right). + +The maze's Y coordinates go from 0 (top) to 15 (bottom). + +The maze has no dead ends. + +Ghost Behavior (as implemented in the turn method of edu.unl.cse.soft160.pacman.Ghost) +====================================================================================== + +A ghost may never go into a wall. + +A ghost may never reverse direction; it can only go straight, turn left, or turn right. + +If a ghost is: + in the center box ("caged") and + able to move in the same direction as the player, +it should: + move in the same direction as the player. + +If a ghost is: + in the center box ("caged") and + not able to move in the same direction as the player, +it should: + move in the first available direction from the list [north, east, west, south]. + +If a ghost is: + outside the center box and inedible ("hunting"), +it should: + choose the highest rated legal move, where the rating of a move is the sum of: + the number of squares from the ghost to the player in that direction and + a ten-point bonus if the player is moving in the same direction. + +If a ghost is: + outside the center box and edible ("edible"), +it should: + choose the highest rated legal move, where the rating of a move is: + the number of squares from the ghost to the player in the opposite direction. + +If a ghost is: + outside the center box and recovering from being eaten ("eaten"), +it should: + choose the highest rated legal move, where the rating of a move is the sum of: + the number of squares from the ghost to the player in the opposite direction and + a ten-point bonus if the player is moving in the same direction. diff --git a/pacman/pom.xml b/pacman/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..a743a77164da681927b0ce3e7ee7e73e4b1cff34 --- /dev/null +++ b/pacman/pom.xml @@ -0,0 +1,36 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>edu.unl.cse.soft160.pacman</groupId> + <artifactId>pacman</artifactId> + <packaging>jar</packaging> + <version>1.0-SNAPSHOT</version> + <name>pacman</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.8.1</version> + <configuration> + <source>8</source> + <target>8</target> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13</version> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/Constants.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Constants.java new file mode 100644 index 0000000000000000000000000000000000000000..cd08ed8755b3d678cba9aff49fcd1f2c42f96c6c --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Constants.java @@ -0,0 +1,72 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +/** + * the tables are used to speed up computation + */ +public class Constants { + // for direction computation + public static final int[] DIRECTION_X_COMPONENTS = {1, 0, -1, 0}; + public static final int[] DIRECTION_Y_COMPONENTS = {0, -1, 0, 1}; + public static final int[] iDirection = {-1, // 0: + 1, // 1: x=0, y=-1 + -1, // 2: + -1, // 3: + 2, // 4: x=-1, y=0 + -1, // 5: + 0, // 6: x=1, y=0 + -1, // 7 + -1, // 8 + 3 // 9: x=0, y=1 + }; + + // backward direction + public static final int[] iBack = {2, 3, 0, 1}; + + // direction code + public enum Direction { + EAST, + NORTH, + WEST, + SOUTH, + } + + // the maze definition string + public static final String[] MazeDefine = { + "XXXXXXXXXXXXXXXXXXXXX", // 1 + "X.........X.........X", // 2 + "XOXXX.XXX.X.XXX.XXXOX", // 3 + "X......X..X.........X", // 4 + "XXX.XX.X.XXX.XX.X.X.X", // 5 + "X....X..........X.X.X", // 6 + "X.XX.X.XXXXX-X.XX.X.X", // 7 + "X.XX.X.X X......X", // 8 + "X.XX...X X.XXXX.X", // 9 + "X.XX.X.XXXXXXX.XXXX.X", // 10 + "X....X.... .........X", // 11 + "XXX.XX.XXXXXXX.X.X.XX", // 12 + "X.........X....X....X", // 13 + "XOXXXXXXX.X.XXXXXXXOX", // 14 + "X...................X", // 15 + "XXXXXXXXXXXXXXXXXXXXX", // 16 + }; + +} diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/Ghost.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Ghost.java new file mode 100644 index 0000000000000000000000000000000000000000..f93a03fdb8194f276ca76de43b07f084024f5bc2 --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Ghost.java @@ -0,0 +1,284 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +import static edu.unl.cse.soft160.pacman.Constants.Direction; +import java.awt.*; + +public class Ghost { + public enum Status { + CAGED, HUNTING, EDIBLE, EATEN, + }; + + private final int[] STEPS = { 7, 7, 1, 1 }; // indexed by status + private final int[] FRAMES = { 8, 8, 2, 1 }; // indexed by status + + private final int MAXIMUM_EDIBILITY_DURATION = 600; // frames + private int edibilityDuration; // frames + + private Speed speed = new Speed(); + + private Status status; + private int edibilityRemaining; + private boolean blinking; + private Direction direction; + private int x, y; + + // the applet this object is associated to + private Window applet; + private Graphics graphics; + + // the maze the ghosts knows + private Maze maze; + + // the ghost images + java.awt.Image imageGhost; + java.awt.Image imageEdible; + java.awt.Image imageEye; + + Ghost(Window applet, Graphics graphics, Maze maze, Color color) { + this.applet = applet; + this.graphics = graphics; + this.maze = maze; + + imageGhost = applet.createImage(18, 18); + Image.drawGhost(imageGhost, 0, color); + imageEdible = applet.createImage(18, 18); + Image.drawGhost(imageEdible, 1, Color.white); + imageEye = applet.createImage(18, 18); + Image.drawGhost(imageEye, 2, Color.lightGray); + } + + public void start(int initialPosition, int round) { + x = (8 + initialPosition + (initialPosition >= 2 ? 1 : 0)) * 16; + y = 8 * 16; + direction = Direction.NORTH; + status = Status.CAGED; + edibilityDuration = MAXIMUM_EDIBILITY_DURATION / ((round + 1) / 2); + speed.start(STEPS[status.ordinal()], FRAMES[status.ordinal()]); + } + + public void draw() { + maze.DrawDot(x / 16, y / 16); + maze.DrawDot(x / 16 + (x % 16 > 0 ? 1 : 0), y / 16 + (y % 16 > 0 ? 1 : 0)); + if (status == Status.EDIBLE && blinking && edibilityRemaining % 32 < 16) { + graphics.drawImage(imageGhost, x - 1, y - 1, applet); + } else if (status == Status.HUNTING || status == Status.CAGED) { + graphics.drawImage(imageGhost, x - 1, y - 1, applet); + } else if (status == Status.EDIBLE) { + graphics.drawImage(imageEdible, x - 1, y - 1, applet); + } else { + graphics.drawImage(imageEye, x - 1, y - 1, applet); + } + } + + public static Direction turn(Status status, int gridX, int gridY, Direction direction, int playerGridX, int playerGridY, + Direction playerDirection, boolean eastBlocked, boolean northBlocked, boolean westBlocked, boolean southBlocked) { + int reverse = (direction.ordinal() + 2) % 4; + int dx = playerGridX - gridX; + int dy = playerGridY - gridY; + boolean[] blocked = { eastBlocked, northBlocked, westBlocked, southBlocked }; + Direction candidate; + candidate = Direction.EAST; + int eastScore = 0; + if (status == Status.CAGED && candidate == playerDirection) { + eastScore = 1; + } else { + int towardsPlayer = Math.max( + dx * Constants.DIRECTION_X_COMPONENTS[candidate.ordinal()] + dy * Constants.DIRECTION_Y_COMPONENTS[candidate.ordinal()], + 0); + if (status == Status.HUNTING) { + eastScore += towardsPlayer; + } else { + eastScore -= towardsPlayer; + } + } + if (status != Status.EDIBLE && candidate == playerDirection) { + eastScore += 10; + } + if (candidate.ordinal() == reverse || blocked[candidate.ordinal()]) { + eastScore = Integer.MIN_VALUE; + } + candidate = Direction.NORTH; + int northScore = 0; + if (status == Status.CAGED && candidate == playerDirection) { + northScore = 1; + } else { + int towardsPlayer = Math.max( + dx * Constants.DIRECTION_X_COMPONENTS[candidate.ordinal()] + dy * Constants.DIRECTION_Y_COMPONENTS[candidate.ordinal()], + 0); + if (status == Status.HUNTING) { + northScore += towardsPlayer; + } else { + northScore -= towardsPlayer; + } + } + if (status != Status.EDIBLE && candidate == playerDirection) { + northScore += 10; + } + if (candidate.ordinal() == reverse || blocked[candidate.ordinal()]) { + northScore = Integer.MIN_VALUE; + } + candidate = Direction.WEST; + int westScore = 0; + if (status == Status.CAGED && candidate == playerDirection) { + westScore = 1; + } else { + int towardsPlayer = Math.max( + dx * Constants.DIRECTION_X_COMPONENTS[candidate.ordinal()] + dy * Constants.DIRECTION_Y_COMPONENTS[candidate.ordinal()], + 0); + if (status == Status.HUNTING) { + westScore += towardsPlayer; + } else { + westScore -= towardsPlayer; + } + } + if (status != Status.EDIBLE && candidate == playerDirection) { + westScore += 10; + } + if (candidate.ordinal() == reverse || blocked[candidate.ordinal()]) { + westScore = Integer.MIN_VALUE; + } + candidate = Direction.SOUTH; + int southScore = 0; + if (status == Status.CAGED && candidate == playerDirection) { + southScore = 1; + } else { + int towardsPlayer = Math.max( + dx * Constants.DIRECTION_X_COMPONENTS[candidate.ordinal()] + dy * Constants.DIRECTION_Y_COMPONENTS[candidate.ordinal()], + 0); + if (status == Status.HUNTING) { + southScore += towardsPlayer; + } else { + southScore -= towardsPlayer; + } + } + if (status != Status.EDIBLE && candidate == playerDirection) { + southScore += 10; + } + if (candidate.ordinal() == reverse || blocked[candidate.ordinal()]) { + southScore = Integer.MIN_VALUE; + } + if (status == Status.CAGED) { + ++northScore; + } + Direction result = direction; + int score = Integer.MIN_VALUE; + if (eastScore > score) { + result = Direction.EAST; + score = eastScore; + } + if (northScore > score) { + result = Direction.NORTH; + score = northScore; + } + if (westScore > score) { + result = Direction.WEST; + score = westScore; + } + if (southScore > score) { + result = Direction.SOUTH; + score = southScore; + } + return result; + } + + private boolean isDoor(int gridX, int gridY) { + int square = maze.grid[gridY][gridX]; + return square == Maze.DOOR; + } + + private boolean isBlocked(int gridX, int gridY) { + int square = maze.grid[gridY][gridX]; + return square == Maze.WALL || square == Maze.DOOR && status != Status.CAGED; + } + + private void move(int playerX, int playerY, Direction playerDirection) { + if (x % 16 == 0 && y % 16 == 0) { + int gridX = x / 16; + int gridY = y / 16; + if (status == Status.CAGED && isDoor(gridX, gridY)) { + status = Status.HUNTING; + } + direction = turn(status, gridX, gridY, direction, playerX / 16, playerY / 16, playerDirection, + isBlocked(gridX + 1, gridY), isBlocked(gridX, gridY - 1), isBlocked(gridX - 1, gridY), + isBlocked(gridX, gridY + 1)); + } + int travelRate = (status == Status.EATEN) ? 2 : 1; + x += travelRate * Constants.DIRECTION_X_COMPONENTS[direction.ordinal()]; + y += travelRate * Constants.DIRECTION_Y_COMPONENTS[direction.ordinal()]; + + } + + public void tick(int playerX, int playerY, int playerDirection) { + if (status == Status.EDIBLE || status == Status.EATEN) { + --edibilityRemaining; + if (edibilityRemaining == 0) { + status = Status.HUNTING; + } + } + if (status == Status.EDIBLE) { + blinking = edibilityRemaining < edibilityDuration / 3; + } + if (speed.isMove() && (status != Status.EDIBLE || edibilityRemaining % 2 == 0)) { + move(playerX, playerY, Direction.values()[playerDirection]); + } + } + + public void makeEdible() { + if (status == Status.EDIBLE || status == Status.HUNTING) { + status = Status.EDIBLE; + edibilityRemaining = edibilityDuration; + blinking = false; + // reverse + if (x % 16 != 0 || y % 16 != 0) { + direction = Direction.values()[Constants.iBack[direction.ordinal()]]; + // a special condition: + // when ghost is leaving home, it can not go back + // while becoming edible + int square; + square = maze.grid[y / 16 + Constants.DIRECTION_Y_COMPONENTS[direction.ordinal()]][x / 16 + + Constants.DIRECTION_X_COMPONENTS[direction.ordinal()]]; + if (square == Maze.DOOR) + direction = Direction.values()[Constants.iBack[direction.ordinal()]]; + } + } + } + + // return 1 if caught the pac! + // return 2 if being caught by pac + public int testCollision(int playerX, int playerY) { + if (x <= playerX + 2 && x >= playerX - 2 && y <= playerY + 2 && y >= playerY - 2) { + switch (status) { + case HUNTING: + return 1; + case EDIBLE: + status = Status.EATEN; + x = x / 4 * 4; + y = y / 4 * 4; + return 2; + default: + break; + } + } + // nothing + return 0; + } +} diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/Image.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Image.java new file mode 100644 index 0000000000000000000000000000000000000000..37dca017b4f1db3dc0b31d5af6cc976d19c5e6ff --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Image.java @@ -0,0 +1,192 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +import java.awt.*; + +public class Image { + public static void drawDot(java.awt.Image img) { + Graphics g = img.getGraphics(); + g.setColor(Color.yellow); + g.drawRect(0, 0, 2, 2); + g.dispose(); + } + + public static void drawPowerDot(java.awt.Image img) { + Graphics g = img.getGraphics(); + g.setColor(Color.black); + g.fillRect(0, 0, 16, 16); + g.setColor(Color.yellow); + int iCounter = 0; + short mask = 0x01; + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j++) { + if ((power_bits[iCounter] & mask) != 0) + g.fillRect(j, i, 1, 1); + mask <<= 1; + if ((mask & 0xff) == 0) { + mask = 0x01; + iCounter++; + } + } + g.dispose(); + } + + public static void drawPac(java.awt.Image img, int dir, int step) { + Graphics g = img.getGraphics(); + g.setColor(Color.black); + g.fillRect(0, 0, 18, 18); + g.setColor(Color.yellow); + int iCounter = 0; + short mask = 0x01; + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j++) { + if ((pac_bits[dir][step][iCounter] & mask) != 0) + g.fillRect(j + 1, i + 1, 1, 1); + mask <<= 1; + if ((mask & 0xff) == 0) { + mask = 0x01; + iCounter++; + } + } + g.dispose(); + } + + public static void drawGhost(java.awt.Image img, int number, Color color) { + Graphics g = img.getGraphics(); + g.setColor(Color.black); + g.fillRect(0, 0, 18, 18); + g.setColor(color); + int iCounter = 0; + short mask = 0x01; + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j++) { + if ((ghost_bits[number][iCounter] & mask) != 0) + g.fillRect(j + 1, i + 1, 1, 1); + mask <<= 1; + if ((mask & 0xff) == 0) { + mask = 0x01; + iCounter++; + } + } + g.dispose(); + } + + // ////////////////////////////////////////////////////////////////////////////// + // image arrays + // ////////////////////////////////////////////////////////////////////////////// + + static final short[][][] pac_bits = { // [4][4][32] + // right + { + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x0f, 0xfe, 0x07, 0xfe, + 0x03, 0xff, 0x01, 0xff, 0x00, 0x7f, 0x00, 0x7f, + 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x03, 0xfe, + 0x07, 0xfc, 0x0f, 0xf8, 0x1f, 0xe0, 0x07}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x3f, 0xff, 0x0f, 0xff, 0x03, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x03, 0xff, 0x0f, 0xfe, 0x3f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x01, 0xff, + 0x01, 0xff, 0x1f, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07},}, + // up + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x06, + 0x60, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}, + {0x00, 0x00, 0x08, 0x10, 0x1c, 0x38, 0x1e, 0x78, 0x3e, + 0x7c, 0x3f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfe, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}, + {0x20, 0x04, 0x38, 0x1c, 0x3c, 0x3c, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7f, 0xfe, 0x7f, 0xfe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}}, + // left + { + {0xe0, 0x07, 0xf8, 0x1f, 0xf0, 0x3f, 0xe0, 0x7f, 0xc0, + 0x7f, 0x80, 0xff, 0x00, 0xff, 0x00, 0xfe, 0x00, + 0xfe, 0x00, 0xff, 0x80, 0xff, 0xc0, 0x7f, 0xe0, + 0x7f, 0xf0, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfc, + 0x7f, 0xf0, 0xff, 0xc0, 0xff, 0x00, 0xff, 0x00, + 0xff, 0xc0, 0xff, 0xf0, 0xff, 0xfc, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xf8, 0xff, 0x80, 0xff, 0x80, + 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}}, + // down + { + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0x3f, + 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x06, 0x60, 0x02, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xfe, 0x7f, 0xfe, 0x3f, 0xfc, 0x3e, 0x7c, 0x1e, + 0x78, 0x1c, 0x38, 0x08, 0x10, 0x00, 0x00}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0xfe, 0x7f, 0xfe, 0x7e, 0x7e, 0x7e, + 0x7e, 0x3c, 0x3c, 0x38, 0x1c, 0x20, 0x04}, + {0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07}}}; + + static final short[][] ghost_bits = { // [3][32] + {0xe0, 0x07, 0xf8, 0x1f, 0xcc, 0x33, 0xbc, 0x3d, 0xfe, 0x7f, 0xde, + 0x7b, 0x8e, 0x71, 0x9e, 0x79, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, + 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0x76, 0x6e, 0x76, 0x6e, 0x24, + 0x24}, + {0xe0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x04, 0x20, 0x32, 0x4c, 0x4a, + 0x52, 0x8a, 0x51, 0x8a, 0x51, 0x72, 0x4e, 0x02, 0x40, 0x02, + 0x40, 0x02, 0x40, 0x8a, 0x51, 0x56, 0x6a, 0x52, 0x4a, 0x24, + 0x24}, + // blind + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x48, + 0x12, 0x88, 0x11, 0x88, 0x11, 0x70, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}}; + + static final short[] power_bits = + // [32] + // show + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, + 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x0f, 0xe0, + 0x07, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +} diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/Interface.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Interface.java new file mode 100644 index 0000000000000000000000000000000000000000..937331f9b8b6f59bbb5de51654954732c4717456 --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Interface.java @@ -0,0 +1,142 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +import java.awt.*; + +public class Interface { + // frames to wait after eaten a dot + final int DOT_WAIT = 4; + + int iDotWait; + + // current position + int iX, iY; + // current direction + int iDir; + + // the applet this object is associated to + Window applet; + Graphics graphics; + + // the pac image + java.awt.Image[][] imagePac; + + // the knowledge of the maze + Maze maze; + + // the knowledge of the power dots + PowerDot powerDot; + + Interface(Window a, Graphics g, Maze m, PowerDot p) { + applet = a; + graphics = g; + maze = m; + powerDot = p; + + // initialize pac and pac image + imagePac = new java.awt.Image[4][4]; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) { + imagePac[i][j] = applet.createImage(18, 18); + Image.drawPac(imagePac[i][j], i, j); + } + } + + public void start() { + iX = 10 * 16; + iY = 10 * 16; + iDir = 1; // downward, illegal and won't move + iDotWait = 0; + } + + public void draw() { + maze.DrawDot(iX / 16, iY / 16); + maze.DrawDot(iX / 16 + (iX % 16 > 0 ? 1 : 0), iY / 16 + + (iY % 16 > 0 ? 1 : 0)); + + int iImageStep = (iX % 16 + iY % 16) / 2; // determine shape of PAc + if (iImageStep < 4) + iImageStep = 3 - iImageStep; + else + iImageStep -= 4; + graphics.drawImage(imagePac[iDir][iImageStep], iX - 1, iY - 1, applet); + } + + // return 1 if eat a dot + // return 2 if eat power dot + public int move(int iNextDir) { + int eaten = 0; + + // iNextDir=cAuto.GetNextDir(); + + if (iNextDir != -1 && iNextDir != iDir) // not set or same + // change direction + { + if (iX % 16 != 0 || iY % 16 != 0) { + // only check go back + if (iNextDir % 2 == iDir % 2) + iDir = iNextDir; + } else // need to see whether ahead block is OK + { + if (mazeOK( + iX / 16 + Constants.DIRECTION_X_COMPONENTS[iNextDir], + iY / 16 + Constants.DIRECTION_Y_COMPONENTS[iNextDir])) { + iDir = iNextDir; + iNextDir = -1; + } + } + } + if (iX % 16 == 0 && iY % 16 == 0) { + + // see whether has eaten something + switch (maze.grid[iY / 16][iX / 16]) { + case Maze.DOT : + eaten = 1; + maze.grid[iY / 16][iX / 16] = Maze.BLANK; // eat dot + maze.iTotalDotcount--; + iDotWait = DOT_WAIT; + break; + case Maze.POWER_DOT : + eaten = 2; + powerDot.eat(iX / 16, iY / 16); + maze.grid[iY / 16][iX / 16] = Maze.BLANK; + break; + } + + if (maze.grid[iY / 16 + Constants.DIRECTION_Y_COMPONENTS[iDir]][iX + / 16 + Constants.DIRECTION_X_COMPONENTS[iDir]] == 1) { + return (eaten); // not valid move + } + } + if (iDotWait == 0) { + iX += Constants.DIRECTION_X_COMPONENTS[iDir]; + iY += Constants.DIRECTION_Y_COMPONENTS[iDir]; + } else + iDotWait--; + return (eaten); + } + + boolean mazeOK(int iRow, int icol) { + if ((maze.grid[icol][iRow] & (Maze.WALL | Maze.DOOR)) == 0) + return (true); + return (false); + } +} diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/Maze.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Maze.java new file mode 100644 index 0000000000000000000000000000000000000000..09d1dcfda0c906d603053339fa959d4fd83f822d --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Maze.java @@ -0,0 +1,309 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +import static edu.unl.cse.soft160.pacman.Constants.Direction; +import java.awt.*; + +/* define the maze */ +public class Maze { + // constant definitions + static final int BLANK = 0; + static final int WALL = 1; + static final int DOOR = 2; + static final int DOT = 4; + static final int POWER_DOT = 8; + + static final int HEIGHT = 16; + static final int WIDTH = 21; + + static final int height = HEIGHT * 16; + static final int width = WIDTH * 16; + + // the applet the object associate with + Window applet; + // the graphics it will be using + Graphics graphics; + + // the maze image + java.awt.Image imageMaze; + + // the dot image + java.awt.Image imageDot; + + // total dots left + int iTotalDotcount; + + // the status of maze + int[][] grid; + + // initialize the maze + Maze(Window a, Graphics g) { + // setup associations + applet = a; + graphics = g; + + imageMaze = applet.createImage(width, height); + imageDot = applet.createImage(2, 2); + + // create data + grid = new int[HEIGHT][WIDTH]; + } + + public void start() { + int i, j, k; + iTotalDotcount = 0; + for (i = 0; i < HEIGHT; i++) + for (j = 0; j < WIDTH; j++) { + switch (Constants.MazeDefine[i].charAt(j)) { + case ' ' : + k = BLANK; + break; + case 'X' : + k = WALL; + break; + case '.' : + k = DOT; + iTotalDotcount++; + break; + case 'O' : + k = POWER_DOT; + break; + case '-' : + k = DOOR; + break; + default : + k = DOT; + iTotalDotcount++; + break; + } + grid[i][j] = k; + } + // create initial maze image + createImage(); + } + + public void draw() { + graphics.drawImage(imageMaze, 0, 0, applet); + drawDots(); + } + + void drawDots() // on the offscreen + { + int i, j; + + for (i = 0; i < HEIGHT; i++) + for (j = 0; j < WIDTH; j++) { + if (grid[i][j] == DOT) + graphics.drawImage(imageDot, j * 16 + 7, i * 16 + 7, applet); + } + } + + void createImage() { + // create the image of a dot + Image.drawDot(imageDot); + + // create the image of the maze + Graphics gmaze = imageMaze.getGraphics(); + + // background + gmaze.setColor(Color.black); + gmaze.fillRect(0, 0, width, height); + + DrawWall(gmaze); + } + + public void DrawDot(int icol, int iRow) { + if (grid[iRow][icol] == DOT) + graphics.drawImage(imageDot, icol * 16 + 7, iRow * 16 + 7, applet); + } + + void DrawWall(Graphics g) { + int i, j; + int iDir; + + g.setColor(Color.green); + + for (i = 0; i < HEIGHT; i++) { + for (j = 0; j < WIDTH; j++) { + for (iDir = Direction.EAST.ordinal(); iDir <= Direction.SOUTH.ordinal(); iDir++) { + if (grid[i][j] == DOOR) { + g.drawLine(j * 16, i * 16 + 8, j * 16 + 16, i * 16 + 8); + continue; + } + if (grid[i][j] != WALL) + continue; + switch (Direction.values()[iDir]) { + case NORTH : + if (i == 0) + break; + if (grid[i - 1][j] == WALL) + break; + DrawBoundary(g, j, i - 1, Direction.SOUTH.ordinal()); + break; + case EAST : + if (j == WIDTH - 1) + break; + if (grid[i][j + 1] == WALL) + break; + DrawBoundary(g, j + 1, i, Direction.WEST.ordinal()); + break; + case SOUTH : + if (i == HEIGHT - 1) + break; + if (grid[i + 1][j] == WALL) + break; + DrawBoundary(g, j, i + 1, Direction.NORTH.ordinal()); + break; + case WEST : + if (j == 0) + break; + if (grid[i][j - 1] == WALL) + break; + DrawBoundary(g, j - 1, i, Direction.EAST.ordinal()); + break; + default : + } + } + } + } + } + + void DrawBoundary(Graphics g, int col, int row, int iDir) { + int x, y; + + x = col * 16; + y = row * 16; + + switch (Direction.values()[iDir]) { + case WEST : + // draw lower half segment + if (grid[row + 1][col] != WALL) + // down empty + if (grid[row + 1][col - 1] != WALL) + // left-down empty + { + g.drawArc(x - 8 - 6, y + 8 - 6, 12, 12, 270, 100); + } else { + g.drawLine(x - 2, y + 8, x - 2, y + 16); + } + else { + g.drawLine(x - 2, y + 8, x - 2, y + 17); + g.drawLine(x - 2, y + 17, x + 7, y + 17); + } + + // Draw upper half segment + if (grid[row - 1][col] != WALL) + // upper empty + if (grid[row - 1][col - 1] != WALL) + // upper-left empty + { + g.drawArc(x - 8 - 6, y + 7 - 6, 12, 12, 0, 100); + } else { + g.drawLine(x - 2, y, x - 2, y + 7); + } + else { + g.drawLine(x - 2, y - 2, x - 2, y + 7); + g.drawLine(x - 2, y - 2, x + 7, y - 2); + } + break; + + case EAST : + // draw lower half segment + if (grid[row + 1][col] != WALL) + // down empty + if (grid[row + 1][col + 1] != WALL) + // down-right empty + { + g.drawArc(x + 16 + 7 - 6, y + 8 - 6, 12, 12, 180, 100); + } else { + g.drawLine(x + 17, y + 8, x + 17, y + 15); + } + else { + g.drawLine(x + 8, y + 17, x + 17, y + 17); + g.drawLine(x + 17, y + 8, x + 17, y + 17); + } + // Draw upper half segment + if (grid[row - 1][col] != WALL) + // upper empty + if (grid[row - 1][col + 1] != WALL) + // upper-right empty + { + g.drawArc(x + 16 + 7 - 6, y + 7 - 6, 12, 12, 90, 100); + } else { + g.drawLine(x + 17, y, x + 17, y + 7); + } + else { + g.drawLine(x + 8, y - 2, x + 17, y - 2); + g.drawLine(x + 17, y - 2, x + 17, y + 7); + } + break; + + case NORTH : + // draw left half segment + if (grid[row][col - 1] != WALL) + // left empty + if (grid[row - 1][col - 1] != WALL) + // left-upper empty + { + g.drawArc(x + 7 - 6, y - 8 - 6, 12, 12, 180, 100); + } else { + g.drawLine(x, y - 2, x + 7, y - 2); + } + + // Draw right half segment + if (grid[row][col + 1] != WALL) + // right empty + if (grid[row - 1][col + 1] != WALL) + // right-upper empty + { + g.drawArc(x + 8 - 6, y - 8 - 6, 12, 12, 270, 100); + } else { + g.drawLine(x + 8, y - 2, x + 16, y - 2); + } + break; + + case SOUTH : + // draw left half segment + if (grid[row][col - 1] != WALL) + // left empty + if (grid[row + 1][col - 1] != WALL) + // left-down empty + { + g.drawArc(x + 7 - 6, y + 16 + 7 - 6, 12, 12, 90, 100); + } else { + g.drawLine(x, y + 17, x + 7, y + 17); + } + + // Draw right half segment + if (grid[row][col + 1] != WALL) + // right empty + if (grid[row + 1][col + 1] != WALL) + // right-down empty + { + g.drawArc(x + 8 - 6, y + 16 + 7 - 6, 12, 12, 0, 100); + } else { + g.drawLine(x + 8, y + 17, x + 15, y + 17); + } + break; + } + } + +} diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/PacMan.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/PacMan.java new file mode 100644 index 0000000000000000000000000000000000000000..30b5b4735547b5fc18a3a23a210bee10c388d965 --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/PacMan.java @@ -0,0 +1,534 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +import static edu.unl.cse.soft160.pacman.Constants.Direction; +import java.awt.*; +import java.awt.event.*; + +/** + * the main class of the pacman game + */ +public class PacMan extends Frame + implements + Runnable, + KeyListener, + WindowListener { + private static final long serialVersionUID = 3582431359568375379L; + // the timer + Thread timer; + int timerPeriod = 12; // in miliseconds + + // the timer will increment this variable to signal a frame + int signalMove = 0; + + // for graphics + final int canvasWidth = 368; + final int canvasHeight = 288 + 1; + + // the canvas starting point within the frame + int topOffset; + int leftOffset; + + // the draw point of maze within the canvas + final int iMazeX = 16; + final int iMazeY = 16; + + // the off screen canvas for the maze + java.awt.Image offScreen; + Graphics offScreenG; + + // the objects + Maze maze; + Interface pac; + PowerDot powerDot; + Ghost[] ghosts; + + // game counters + final int PAcLIVE = 3; + int pacRemain; + int changePacRemain; // to signal redraw remaining pac + + // score + int score; + int hiScore; + int scoreGhost; // score of eat ghost, doubles every time + int changeScore; // signal score change + int changeHiScore; // signal change of hi score + + // score images + java.awt.Image imgScore; + Graphics imgScoreG; + java.awt.Image imgHiScore; + Graphics imgHiScoreG; + + // game status + final int INITIMAGE = 100; // need to wait before paint anything + final int STARTWAIT = 0; // wait before running + final int RUNNING = 1; + final int DEADWAIT = 2; // wait after dead + final int SUSPENDED = 3; // suspended during game + int gameState; + + final int WAITCOUNT = 100; // 100 frames for wait states + int wait; // the counter + + // rounds + int round; // the round of current game; + + // whether it is played in a new maze + boolean newMaze; + + // the direction specified by key + int pacKeyDir; + int key = 0; + final int NONE = 0; + final int SUSPEND = 1; // stop/start + final int BOSS = 2; // boss + + // ////////////////////////////////////////////// + // initialize the object + // only called once at the beginning + // ////////////////////////////////////////////// + public PacMan() { + super("PacMan"); + + // init variables + hiScore = 0; + + gameState = INITIMAGE; + + initGUI(); + + addWindowListener(this); + + addKeyListener(this); + + setSize(canvasWidth, canvasHeight); + + setVisible(true); + } + + void initGUI() { + addNotify(); // for updated inset information + } + + public void initImages() { + // initialize off screen drawing canvas + offScreen = createImage(Maze.width, Maze.height); + if (offScreen == null) + System.out.println("createImage failed"); + offScreenG = offScreen.getGraphics(); + + // initialize maze object + maze = new Maze(this, offScreenG); + + // initialize ghosts object + // 4 ghosts + ghosts = new Ghost[4]; + for (int i = 0; i < 4; i++) { + Color color; + if (i == 0) + color = Color.red; + else if (i == 1) + color = Color.blue; + else if (i == 2) + color = Color.white; + else + color = Color.orange; + ghosts[i] = new Ghost(this, offScreenG, maze, color); + } + + // initialize power dot object + powerDot = new PowerDot(this, offScreenG, ghosts); + + // initialize pac object + pac = new Interface(this, offScreenG, maze, powerDot); + + // initialize the score images + imgScore = createImage(150, 16); + imgScoreG = imgScore.getGraphics(); + imgHiScore = createImage(150, 16); + imgHiScoreG = imgHiScore.getGraphics(); + + imgHiScoreG.setColor(Color.black); + imgHiScoreG.fillRect(0, 0, 150, 16); + imgHiScoreG.setColor(Color.red); + imgHiScoreG.setFont(new Font("Helvetica", Font.BOLD, 12)); + imgHiScoreG.drawString("HI SCORE", 0, 14); + + imgScoreG.setColor(Color.black); + imgScoreG.fillRect(0, 0, 150, 16); + imgScoreG.setColor(Color.green); + imgScoreG.setFont(new Font("Helvetica", Font.BOLD, 12)); + imgScoreG.drawString("SCORE", 0, 14); + } + + void startTimer() { + // start the timer + timer = new Thread(this); + timer.start(); + } + + void startGame() { + pacRemain = PAcLIVE; + changePacRemain = 1; + + score = 0; + changeScore = 1; + + newMaze = true; + + round = 1; + + startRound(); + } + + void startRound() { + // new round for maze? + if (newMaze == true) { + maze.start(); + powerDot.start(); + newMaze = false; + } + + maze.draw(); // draw maze in off screen buffer + + pac.start(); + pacKeyDir = Direction.SOUTH.ordinal(); + for (int i = 0; i < 4; i++) + ghosts[i].start(i, round); + + gameState = STARTWAIT; + wait = WAITCOUNT; + } + + // ///////////////////////////////////////// + // paint everything + // ///////////////////////////////////////// + public void paint(Graphics g) { + if (gameState == INITIMAGE) { + // System.out.println("first paint(...)..."); + + // init images, must be done after show() because of Graphics + initImages(); + + // set the proper size of canvas + Insets insets = getInsets(); + + topOffset = insets.top; + leftOffset = insets.left; + + setSize(canvasWidth + insets.left + insets.right, canvasHeight + + insets.top + insets.bottom); + + setResizable(false); + + // now we can start timer + startGame(); + + startTimer(); + + } + + g.setColor(Color.black); + g.fillRect(leftOffset, topOffset, canvasWidth, canvasHeight); + + changeScore = 1; + changeHiScore = 1; + changePacRemain = 1; + + paintUpdate(g); + } + + void paintUpdate(Graphics g) { + // updating the frame + + powerDot.draw(); + + for (int i = 0; i < 4; i++) + ghosts[i].draw(); + + pac.draw(); + + // display the offscreen + g.drawImage(offScreen, iMazeX + leftOffset, iMazeY + topOffset, this); + + // display extra information + if (changeHiScore == 1) { + imgHiScoreG.setColor(Color.black); + imgHiScoreG.fillRect(70, 0, 80, 16); + imgHiScoreG.setColor(Color.red); + imgHiScoreG.drawString(Integer.toString(hiScore), 70, 14); + g.drawImage(imgHiScore, 8 + leftOffset, 0 + topOffset, this); + + changeHiScore = 0; + } + + if (changeScore == 1) { + imgScoreG.setColor(Color.black); + imgScoreG.fillRect(70, 0, 80, 16); + imgScoreG.setColor(Color.green); + imgScoreG.drawString(Integer.toString(score), 70, 14); + g.drawImage(imgScore, 158 + leftOffset, 0 + topOffset, this); + + changeScore = 0; + } + + // update pac life info + if (changePacRemain == 1) { + int i; + for (i = 1; i < pacRemain; i++) { + g.drawImage(pac.imagePac[0][0], 16 * i + leftOffset, + canvasHeight - 18 + topOffset, this); + } + g.drawImage(powerDot.imageBlank, 16 * i + leftOffset, canvasHeight + - 17 + topOffset, this); + + changePacRemain = 0; + } + } + + // ////////////////////////////////////////////////////////// + // controls moves + // this is the routine running at the background of drawings + // ////////////////////////////////////////////////////////// + void move() { + int k; + + int oldScore = score; + + for (int i = 0; i < 4; i++) + ghosts[i].tick(pac.iX, pac.iY, pac.iDir); + + k = pac.move(pacKeyDir); + + if (k == 1) // eaten a dot + { + changeScore = 1; + score += 10 * ((round + 1) / 2); + } else if (k == 2) // eaten a powerDot + { + scoreGhost = 200; + } + + if (maze.iTotalDotcount == 0) { + gameState = DEADWAIT; + wait = WAITCOUNT; + newMaze = true; + round++; + return; + } + + for (int i = 0; i < 4; i++) { + k = ghosts[i].testCollision(pac.iX, pac.iY); + if (k == 1) // kill pac + { + pacRemain--; + changePacRemain = 1; + gameState = DEADWAIT; // stop the game + wait = WAITCOUNT; + return; + } else if (k == 2) // caught by pac + { + score += scoreGhost * ((round + 1) / 2); + changeScore = 1; + scoreGhost *= 2; + } + } + + if (score > hiScore) { + hiScore = score; + changeHiScore = 1; + } + + if (changeScore == 1) { + if (score / 10000 - oldScore / 10000 > 0) { + pacRemain++; // bonus + changePacRemain = 1; + } + } + } + + // ///////////////////////////////////////// + // this is the routine draw each frames + // ///////////////////////////////////////// + public void update(Graphics g) { + // System.out.println("update called"); + if (gameState == INITIMAGE) + return; + + // seperate the timer from update + if (signalMove != 0) { + signalMove = 0; + + if (wait != 0) { + wait--; + return; + } + + switch (gameState) { + case STARTWAIT : + gameState = RUNNING; + break; + case RUNNING : + if (key == SUSPEND) + gameState = SUSPENDED; + else + move(); + break; + case DEADWAIT : + if (pacRemain > 0) + startRound(); + else + startGame(); + gameState = STARTWAIT; + wait = WAITCOUNT; + pacKeyDir = Direction.SOUTH.ordinal(); + break; + case SUSPENDED : + if (key == SUSPEND) + gameState = RUNNING; + break; + } + key = NONE; + } + + paintUpdate(g); + } + + // ///////////////////////////////////// + // process key input + // ///////////////////////////////////// + public void keyPressed(KeyEvent e) { + switch (e.getKeyCode()) { + case KeyEvent.VK_RIGHT : + case KeyEvent.VK_L : + pacKeyDir = Direction.EAST.ordinal(); + break; + case KeyEvent.VK_UP : + pacKeyDir = Direction.NORTH.ordinal(); + break; + case KeyEvent.VK_LEFT : + pacKeyDir = Direction.WEST.ordinal(); + break; + case KeyEvent.VK_DOWN : + pacKeyDir = Direction.SOUTH.ordinal(); + break; + case KeyEvent.VK_S : + key = SUSPEND; + break; + case KeyEvent.VK_B : + key = BOSS; + break; + } + } + + public void keyTyped(KeyEvent e) { + } + public void keyReleased(KeyEvent e) { + } + + // ///////////////////////////////////////////////// + // handles window event + // ///////////////////////////////////////////////// + public void windowOpened(WindowEvent e) { + } + + public void windowClosing(WindowEvent e) { + dispose(); + } + + public void windowClosed(WindowEvent e) { + } + + public void windowIconified(WindowEvent e) { + } + + public void windowDeiconified(WindowEvent e) { + } + + public void windowActivated(WindowEvent e) { + } + + public void windowDeactivated(WindowEvent e) { + } + + // /////////////////////////////////////////////// + // the timer + // /////////////////////////////////////////////// + public void run() { + while (true) { + try { + Thread.sleep(timerPeriod); + } catch (InterruptedException e) { + return; + } + + signalMove++; + repaint(); + } + } + + // for applet the check state + boolean finalized = false; + + public void dispose() { + // kill the thread + timer.interrupt(); + + // the off screen canvas + // java.awt.Image offScreen=null; + offScreenG.dispose(); + offScreenG = null; + + // the objects + maze = null; + pac = null; + powerDot = null; + for (int i = 0; i < 4; i++) + ghosts[i] = null; + ghosts = null; + + // score images + imgScore = null; + imgHiScore = null; + imgScoreG.dispose(); + imgScoreG = null; + imgHiScoreG.dispose(); + imgHiScoreG = null; + + super.dispose(); + + finalized = true; + } + + public boolean isFinalized() { + return finalized; + } + + public void setFinalized(boolean finalized) { + this.finalized = finalized; + } + + public static void main(String... arguments) { + new PacMan(); + } +} diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/PowerDot.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/PowerDot.java new file mode 100644 index 0000000000000000000000000000000000000000..79d1b2bc67bd616ee7a2d61af99e4cdae8fcb18a --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/PowerDot.java @@ -0,0 +1,109 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +import java.awt.*; + +public class PowerDot { + final int iX[] = {1, 19, 1, 19}; + final int iY[] = {2, 2, 13, 13}; + + final int iShowCount = 32; + final int iHideCount = 16; + + int frameCount; + int showStatus; + + int iValid[]; + + // the applet this object is associated to + Window applet; + Graphics graphics; + + // the ghosts it controls + Ghost[] ghosts; + + // the power dot image + java.awt.Image imagePowerDot; + + // the blank image + java.awt.Image imageBlank; + + PowerDot(Window a, Graphics g, Ghost[] gh) { + applet = a; + graphics = g; + ghosts = gh; + + // initialize power dot and image + iValid = new int[4]; + + imagePowerDot = applet.createImage(16, 16); + Image.drawPowerDot(imagePowerDot); + + imageBlank = applet.createImage(16, 16); + Graphics imageG = imageBlank.getGraphics(); + imageG.setColor(Color.black); + imageG.fillRect(0, 0, 16, 16); + + frameCount = iShowCount; + showStatus = 1; // show + } + + public void start() { + // all power dots available + for (int i = 0; i < 4; i++) + iValid[i] = 1; + } + + void clear(int dot) { + graphics.drawImage(imageBlank, iX[dot] * 16, iY[dot] * 16, applet); + } + + void eat(int iCol, int iRow) { + for (int i = 0; i < 4; i++) { + if (iX[i] == iCol && iY[i] == iRow) { + iValid[i] = 0; + clear(i); + } + } + for (int i = 0; i < 4; i++) + ghosts[i].makeEdible(); + } + + public void draw() { + frameCount--; + if (frameCount == 0) { + if (showStatus == 1) { + showStatus = 0; + frameCount = iHideCount; + } else { + showStatus = 1; + frameCount = iShowCount; + } + } + for (int i = 0; i < 4; i++) { + if (iValid[i] == 1 && showStatus == 1) + graphics.drawImage(imagePowerDot, iX[i] * 16, iY[i] * 16, + applet); + else + graphics.drawImage(imageBlank, iX[i] * 16, iY[i] * 16, applet); + } + } +} diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/Speed.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Speed.java new file mode 100644 index 0000000000000000000000000000000000000000..d5358cc30b5e64d59986422ac5c6045e13ed4171 --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Speed.java @@ -0,0 +1,70 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +/** + * speed control + * + * use init(s,f) to set the frame/step ratio NOTE: s must <= f call start() to + * reset counters call isMove per frame to see if step are to be taken + */ +public class Speed { + // move steps per frames + int steps; + int frames; + + int frameCount; + int stepCount; + + float frameStepRatio; + + Speed() { + start(1, 1); + } + + public void start(int s, int f) throws Error { + if (f < s) + throw new Error("Speed.init(...): frame must >= step"); + + steps = s; + frames = f; + frameStepRatio = (float) frames / (float) steps; + + stepCount = steps; + frameCount = frames; + } + + public boolean isMove() { + frameCount--; + + float ratio = (float) frameCount / (float) stepCount; + + if (frameCount == 0) + frameCount = frames; + + if (ratio < frameStepRatio) { + stepCount--; + if (stepCount == 0) + stepCount = steps; + return true; + } + return false; + } +} diff --git a/pacman/src/main/java/edu/unl/cse/soft160/pacman/Utility.java b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Utility.java new file mode 100644 index 0000000000000000000000000000000000000000..c70ebb8a50a1184e51a1edaee93cedf941a926ab --- /dev/null +++ b/pacman/src/main/java/edu/unl/cse/soft160/pacman/Utility.java @@ -0,0 +1,50 @@ +/** + * Copyright (C) 1997-2010 Junyang Gu <mikejyg@gmail.com> + * + * This file is part of javaiPacman. + * + * javaiPacman 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. + * + * javaiPacman 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 javaiPacman. If not, see <http://www.gnu.org/licenses/>. + */ + +package edu.unl.cse.soft160.pacman; + +/** + * provide some global public utility functions + */ +public class Utility { + public static int RandDo(int iOdds) + // see if it happens within a probability of 1/odds + { + if (Math.random() * iOdds < 1) + return (1); + return (0); + } + + // return a random number within [0..iTotal) + public static int RandSelect(int iTotal) { + double a; + a = Math.random(); + a = a * iTotal; + return ((int) a); + } + + public static int IntSign(int iD) { + if (iD == 0) + return (0); + if (iD > 0) + return (1); + else + return (-1); + } +} diff --git a/pacman/src/test/java/edu/unl/cse/soft160/pacman/.gitkeep b/pacman/src/test/java/edu/unl/cse/soft160/pacman/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391