summaryrefslogtreecommitdiffstats
path: root/kbattleship
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitc90c389a8a8d9d8661e9772ec4144c5cf2039f23 (patch)
tree6d8391395bce9eaea4ad78958617edb20c6a7573 /kbattleship
downloadtdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.tar.gz
tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegames@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kbattleship')
-rw-r--r--kbattleship/AUTHORS4
-rw-r--r--kbattleship/CLIENTS13
-rw-r--r--kbattleship/COPYING341
-rw-r--r--kbattleship/ChangeLog1
-rw-r--r--kbattleship/INSTALL167
-rw-r--r--kbattleship/Makefile.am1
-rw-r--r--kbattleship/NEWS45
-rw-r--r--kbattleship/README23
-rw-r--r--kbattleship/TODO22
-rw-r--r--kbattleship/VERSION1
-rw-r--r--kbattleship/configure.in.in2
-rw-r--r--kbattleship/kbattleship/Makefile.am39
-rw-r--r--kbattleship/kbattleship/_kbattleship._tcp4
-rw-r--r--kbattleship/kbattleship/dialogs/Makefile.am14
-rw-r--r--kbattleship/kbattleship/dialogs/chatDlg.ui91
-rw-r--r--kbattleship/kbattleship/dialogs/connectDlg.ui183
-rw-r--r--kbattleship/kbattleship/dialogs/infoDlg.ui248
-rw-r--r--kbattleship/kbattleship/dialogs/serverDlg.ui132
-rw-r--r--kbattleship/kbattleship/dialogs/statDlg.ui465
-rw-r--r--kbattleship/kbattleship/eventsrc475
-rw-r--r--kbattleship/kbattleship/kbaiplayer.cpp107
-rw-r--r--kbattleship/kbattleship/kbaiplayer.h59
-rw-r--r--kbattleship/kbattleship/kbattlefield.cpp233
-rw-r--r--kbattleship/kbattleship/kbattlefield.h82
-rw-r--r--kbattleship/kbattleship/kbattleship.cpp1352
-rw-r--r--kbattleship/kbattleship/kbattleship.desktop76
-rw-r--r--kbattleship/kbattleship/kbattleship.h162
-rw-r--r--kbattleship/kbattleship/kbattleshipclient.cpp84
-rw-r--r--kbattleship/kbattleship/kbattleshipclient.h49
-rw-r--r--kbattleship/kbattleship/kbattleshipserver.cpp124
-rw-r--r--kbattleship/kbattleship/kbattleshipserver.h60
-rw-r--r--kbattleship/kbattleship/kbattleshipui.rc17
-rw-r--r--kbattleship/kbattleship/kbattleshipview.cpp295
-rw-r--r--kbattleship/kbattleship/kbattleshipview.h72
-rw-r--r--kbattleship/kbattleship/kbchooserstrategy.cpp139
-rw-r--r--kbattleship/kbattleship/kbchooserstrategy.h46
-rw-r--r--kbattleship/kbattleship/kbdestroyshipstrategy.cpp390
-rw-r--r--kbattleship/kbattleship/kbdestroyshipstrategy.h55
-rw-r--r--kbattleship/kbattleship/kbdiagonalshotstrategy.cpp110
-rw-r--r--kbattleship/kbattleship/kbdiagonalshotstrategy.h43
-rw-r--r--kbattleship/kbattleship/kbdiagonalwrapstrategy.cpp320
-rw-r--r--kbattleship/kbattleship/kbdiagonalwrapstrategy.h53
-rw-r--r--kbattleship/kbattleship/kbhorizontalstepstrategy.cpp210
-rw-r--r--kbattleship/kbattleship/kbhorizontalstepstrategy.h48
-rw-r--r--kbattleship/kbattleship/kbrandomshotstrategy.cpp102
-rw-r--r--kbattleship/kbattleship/kbrandomshotstrategy.h47
-rw-r--r--kbattleship/kbattleship/kbstrategy.cpp108
-rw-r--r--kbattleship/kbattleship/kbstrategy.h52
-rw-r--r--kbattleship/kbattleship/kbverticalstepstrategy.cpp214
-rw-r--r--kbattleship/kbattleship/kbverticalstepstrategy.h49
-rw-r--r--kbattleship/kbattleship/kchatwidget.cpp83
-rw-r--r--kbattleship/kbattleship/kchatwidget.h53
-rw-r--r--kbattleship/kbattleship/kclientdialog.cpp140
-rw-r--r--kbattleship/kbattleship/kclientdialog.h61
-rw-r--r--kbattleship/kbattleship/kgridwidget.cpp416
-rw-r--r--kbattleship/kbattleship/kgridwidget.h66
-rw-r--r--kbattleship/kbattleship/kmessage.cpp101
-rw-r--r--kbattleship/kbattleship/kmessage.h49
-rw-r--r--kbattleship/kbattleship/konnectionhandling.cpp246
-rw-r--r--kbattleship/kbattleship/konnectionhandling.h73
-rw-r--r--kbattleship/kbattleship/kserverdialog.cpp67
-rw-r--r--kbattleship/kbattleship/kserverdialog.h49
-rw-r--r--kbattleship/kbattleship/kship.cpp105
-rw-r--r--kbattleship/kbattleship/kship.h46
-rw-r--r--kbattleship/kbattleship/kshiplist.cpp175
-rw-r--r--kbattleship/kbattleship/kshiplist.h58
-rw-r--r--kbattleship/kbattleship/kstatdialog.cpp92
-rw-r--r--kbattleship/kbattleship/kstatdialog.h48
-rw-r--r--kbattleship/kbattleship/main.cpp70
-rw-r--r--kbattleship/kbattleship/pictures/Makefile.am30
-rw-r--r--kbattleship/kbattleship/pictures/border.pngbin0 -> 735 bytes
-rw-r--r--kbattleship/kbattleship/pictures/death.pngbin0 -> 2690 bytes
-rw-r--r--kbattleship/kbattleship/pictures/hi128-app-kbattleship.pngbin0 -> 10105 bytes
-rw-r--r--kbattleship/kbattleship/pictures/hi16-app-kbattleship.pngbin0 -> 515 bytes
-rw-r--r--kbattleship/kbattleship/pictures/hi22-app-kbattleship.pngbin0 -> 3489 bytes
-rw-r--r--kbattleship/kbattleship/pictures/hi32-app-kbattleship.pngbin0 -> 1334 bytes
-rw-r--r--kbattleship/kbattleship/pictures/hi48-app-kbattleship.pngbin0 -> 2591 bytes
-rw-r--r--kbattleship/kbattleship/pictures/hi64-app-kbattleship.pngbin0 -> 3848 bytes
-rw-r--r--kbattleship/kbattleship/pictures/hit.pngbin0 -> 2130 bytes
-rw-r--r--kbattleship/kbattleship/pictures/sea.pngbin0 -> 1695 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship1-1-r.pngbin0 -> 812 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship1-1.pngbin0 -> 879 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship1-view.pngbin0 -> 812 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship2-1-r.pngbin0 -> 636 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship2-1.pngbin0 -> 823 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship2-2-r.pngbin0 -> 732 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship2-2.pngbin0 -> 938 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship2-view.pngbin0 -> 1171 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship3-1-r.pngbin0 -> 872 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship3-1.pngbin0 -> 800 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship3-2-r.pngbin0 -> 932 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship3-2.pngbin0 -> 963 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship3-3-r.pngbin0 -> 923 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship3-3.pngbin0 -> 922 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship3-view.pngbin0 -> 879 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-1-r.pngbin0 -> 627 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-1.pngbin0 -> 607 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-2-r.pngbin0 -> 575 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-2.pngbin0 -> 594 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-3-r.pngbin0 -> 657 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-3.pngbin0 -> 645 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-4-r.pngbin0 -> 971 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-4.pngbin0 -> 895 bytes
-rw-r--r--kbattleship/kbattleship/pictures/ship4-view.pngbin0 -> 969 bytes
-rw-r--r--kbattleship/kbattleship/pictures/water.pngbin0 -> 2808 bytes
-rw-r--r--kbattleship/kbattleship/sounds/Makefile.am5
-rw-r--r--kbattleship/kbattleship/sounds/ship-player-shoot-water.oggbin0 -> 37703 bytes
-rw-r--r--kbattleship/kbattleship/sounds/ship-player1-shoot.oggbin0 -> 55778 bytes
-rw-r--r--kbattleship/kbattleship/sounds/ship-player2-shoot.oggbin0 -> 55778 bytes
-rw-r--r--kbattleship/kbattleship/sounds/ship-sink.oggbin0 -> 22344 bytes
110 files changed, 9062 insertions, 0 deletions
diff --git a/kbattleship/AUTHORS b/kbattleship/AUTHORS
new file mode 100644
index 00000000..cfa61d99
--- /dev/null
+++ b/kbattleship/AUTHORS
@@ -0,0 +1,4 @@
+Nikolas Zimmermann <wildfox@kde.org>
+Daniel Molkentin <molkentin@kde.org>
+Kevin Krammer <kevin.krammer@gmx.at>
+Albert Astals Cid <tsdgeos@terra.es>
diff --git a/kbattleship/CLIENTS b/kbattleship/CLIENTS
new file mode 100644
index 00000000..393dda40
--- /dev/null
+++ b/kbattleship/CLIENTS
@@ -0,0 +1,13 @@
+Information about other KBattleship-compatible clients:
+
+Client OS Status Homepage/Screenshots
+
+KBattleship Linux/KDE 100% http://games.kde.org/kbattleship
+Mac KBattleship Mac OS + Mac OS X 100% http://www.sebek.de/
+
+Wishes:
+gBattleship
+WinBattleship
+
+Nikolas Zimmermann
+<wildfox@kde.org>
diff --git a/kbattleship/COPYING b/kbattleship/COPYING
new file mode 100644
index 00000000..54754ab4
--- /dev/null
+++ b/kbattleship/COPYING
@@ -0,0 +1,341 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) 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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. 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.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+ 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
+convey 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) 19yy <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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This 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 Library General
+Public License instead of this License.
diff --git a/kbattleship/ChangeLog b/kbattleship/ChangeLog
new file mode 100644
index 00000000..39adbf93
--- /dev/null
+++ b/kbattleship/ChangeLog
@@ -0,0 +1 @@
+See NEWS
diff --git a/kbattleship/INSTALL b/kbattleship/INSTALL
new file mode 100644
index 00000000..02a4a074
--- /dev/null
+++ b/kbattleship/INSTALL
@@ -0,0 +1,167 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes a while. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 4. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/kbattleship/Makefile.am b/kbattleship/Makefile.am
new file mode 100644
index 00000000..409a1b7d
--- /dev/null
+++ b/kbattleship/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = kbattleship
diff --git a/kbattleship/NEWS b/kbattleship/NEWS
new file mode 100644
index 00000000..579e06db
--- /dev/null
+++ b/kbattleship/NEWS
@@ -0,0 +1,45 @@
+Sun Jul 29 14:17:55 CEST 2001
+ o 0.9 -> 1.0 version (WildFox)
+ (AI enhancements)
+
+Mon Apr 30 10:09:31 CEST 2001
+ o 0.8 -> 0.9 version (WildFox)
+ (AlphaBlending added + bigger battlefield)
+
+Tue Apr 17 23:34:45 CEST 2001
+ o 0.7 -> 0.8 version (WildFox)
+ (Rewrote network handling)
+
+Sat Apr 14 20:41:42 CEST 2001
+ o 0.6 -> 0.7 version (WildFox)
+ (AI working + added)
+
+Sat Apr 14 10:56:20 CEST 2001
+ o 0.5 -> 0.6 version (WildFox)
+ (ship-placing preview working)
+
+Tue Mar 26 22:57:08 CEST 2001
+ o Moved into kdegames (WildFox)
+ (paaarty :)
+
+Sat Mar 24 01:57:31 CET 2001
+ o 0.4 -> 0.5 version (WildFox)
+ (much has been changed)
+
+Fri Mar 16 23:55:16 CET 2001
+ o Beta2 -> 0.4 version (WildFox)
+ (yiippie...beta state is over)
+
+Wed Dec 27 00:22:55 CET 2000
+ o Beta -> Beta2 version (WildFox)
+ (only 2 really important TODO things left)
+
+Sun Dec 24 01:50:47 CET 2000
+ o Alpha -> Beta version (WildFox)
+
+Sat Nov 4 18:23:27 UTC 2000
+ o Checked in into KDE CVS (WildFox)
+ (module: kdenonbeta)
+
+Fri Nov 01 16:06:52 CET 2000
+ o Initial creation (WildFox)
diff --git a/kbattleship/README b/kbattleship/README
new file mode 100644
index 00000000..e2e0ad30
--- /dev/null
+++ b/kbattleship/README
@@ -0,0 +1,23 @@
+KBattleship 1.0
+-----------------------------------
+
+KBatteship is a KDE implentation of the
+popular game "Battleship".
+
+In the current version, you can play it
+with two computers in a TCP/IP based
+network and (as of version 0.7) with the
+computer.
+
+KBattleship uses an XML based protocol,
+meaning you can write a compatible application
+in almost every programming or scripting
+language (Would be nice to hear of a
+GNOME port)
+
+If you have ideas or want to get involved,
+simple contanct the authors (see AUTHORS).
+
+Have a lot of fun!
+
+The KBattleship Team
diff --git a/kbattleship/TODO b/kbattleship/TODO
new file mode 100644
index 00000000..6b14a6b4
--- /dev/null
+++ b/kbattleship/TODO
@@ -0,0 +1,22 @@
+KBattleship TODO List:
+
+p = partially
+x = ready
+a = assigned task
+? = really necessary
+
+KB Team:
+ READY :)
+
+User ideas:
+ READY :)
+
+Competiton:
+ http://batnav.sourceforge.net/batnav-en.html (tronical)
+
+as discussed with danimo:
+- there should be at least 2 sets of ships. Like 2 different navys
+- one should be able to choose between different sets of maps:
+ - maps with or without land/island or whatever
+ - maps of differnt size (bigger maps with more ships)
+
diff --git a/kbattleship/VERSION b/kbattleship/VERSION
new file mode 100644
index 00000000..66c8f8d2
--- /dev/null
+++ b/kbattleship/VERSION
@@ -0,0 +1 @@
+KBattleship 1.0 \ No newline at end of file
diff --git a/kbattleship/configure.in.in b/kbattleship/configure.in.in
new file mode 100644
index 00000000..35f58a6e
--- /dev/null
+++ b/kbattleship/configure.in.in
@@ -0,0 +1,2 @@
+
+AC_CHECK_HEADERS(sys/filio.h stropts.h)
diff --git a/kbattleship/kbattleship/Makefile.am b/kbattleship/kbattleship/Makefile.am
new file mode 100644
index 00000000..6c59ddd5
--- /dev/null
+++ b/kbattleship/kbattleship/Makefile.am
@@ -0,0 +1,39 @@
+SUBDIRS = dialogs . pictures sounds
+
+INCLUDES = -I$(top_srcdir)/libkdegames -I$(top_srcdir)/libkdegames/highscore $(all_includes)
+METASOURCES = AUTO
+
+bin_PROGRAMS = kbattleship
+kbattleship_SOURCES = kbaiplayer.cpp kbstrategy.cpp kbverticalstepstrategy.cpp\
+ kbdestroyshipstrategy.cpp kbhorizontalstepstrategy.cpp \
+ kbrandomshotstrategy.cpp kbdiagonalwrapstrategy.cpp \
+ kmessage.cpp kbattleshipserver.cpp kbattleshipclient.cpp \
+ kbattleshipview.cpp kgridwidget.cpp kbattlefield.cpp \
+ kchatwidget.cpp kserverdialog.cpp kclientdialog.cpp \
+ kstatdialog.cpp kbdiagonalshotstrategy.cpp \
+ konnectionhandling.cpp kship.cpp kshiplist.cpp \
+ kbchooserstrategy.cpp kbattleship.cpp main.cpp
+kbattleship_LDADD = $(LIB_KDEGAMES) ./dialogs/libkbattleshipdialogs.la $(LIB_KFILE) $(LIB_KDNSSD)
+kbattleship_COMPILE_FIRST = dialogs/infoDlg.h dialogs/chatDlg.h dialogs/connectDlg.h dialogs/serverDlg.h dialogs/statDlg.h
+kbattleship_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kbattleship_DEPENDENCIES = $(LIB_KDEGAMES_DEP)
+
+services_DATA = _kbattleship._tcp
+servicesdir = $(kde_datadir)/zeroconf
+
+xdg_apps_DATA = kbattleship.desktop
+
+rcdir = $(kde_datadir)/kbattleship
+rc_DATA = kbattleshipui.rc eventsrc
+
+messages: rc.cpp
+ $(EXTRACTRC) */*.ui >> rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kbattleship.pot
+
+kbattleship.o: dialogs/infoDlg.h dialogs/chatDlg.h dialogs/connectDlg.h dialogs/serverDlg.h dialogs/statDlg.h
+kbattleshipview.o: dialogs/infoDlg.h dialogs/chatDlg.h dialogs/connectDlg.h dialogs/serverDlg.h dialogs/statDlg.h
+kchatwidget.o: dialogs/chatDlg.h
+kclientdialog.o: dialogs/connectDlg.h
+kserverdialog.o: dialogs/serverDlg.h
+kstatdialog.o: dialogs/statDlg.h
+
diff --git a/kbattleship/kbattleship/_kbattleship._tcp b/kbattleship/kbattleship/_kbattleship._tcp
new file mode 100644
index 00000000..7044f950
--- /dev/null
+++ b/kbattleship/kbattleship/_kbattleship._tcp
@@ -0,0 +1,4 @@
+Name=KBattleship games
+Type=_kbattleship._tcp
+Exec=kbattleship %u
+Icon=kbattleship
diff --git a/kbattleship/kbattleship/dialogs/Makefile.am b/kbattleship/kbattleship/dialogs/Makefile.am
new file mode 100644
index 00000000..6f7fa1ab
--- /dev/null
+++ b/kbattleship/kbattleship/dialogs/Makefile.am
@@ -0,0 +1,14 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libkbattleshipdialogs.la
+libkbattleshipdialogs_la_SOURCES = dummy.cpp connectDlg.ui serverDlg.ui \
+ chatDlg.ui statDlg.ui infoDlg.ui
+libkbattleshipdialogs_la_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+libkbattleshipdialogs_la_LIBADD = $(LIB_KDEUI)
+
+dummy.cpp:
+ echo > dummy.cpp
+
+DISTCLEANFILES = dummy.cpp
+
diff --git a/kbattleship/kbattleship/dialogs/chatDlg.ui b/kbattleship/kbattleship/dialogs/chatDlg.ui
new file mode 100644
index 00000000..40ffdbf3
--- /dev/null
+++ b/kbattleship/kbattleship/dialogs/chatDlg.ui
@@ -0,0 +1,91 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>chatDlg</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>chatDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>252</width>
+ <height>236</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Chat Widget</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layouter</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLineEdit" row="2" column="0">
+ <property name="name">
+ <cstring>commentEdit</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Enter a message here</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>sendBtn</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Send</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Press here to send the message</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QMultiLineEdit" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>chatView</cstring>
+ </property>
+ <property name="wordWrap">
+ <enum>WidgetWidth</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>chatLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Chat dialog:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </hbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbattleship/kbattleship/dialogs/connectDlg.ui b/kbattleship/kbattleship/dialogs/connectDlg.ui
new file mode 100644
index 00000000..1a5b53de
--- /dev/null
+++ b/kbattleship/kbattleship/dialogs/connectDlg.ui
@@ -0,0 +1,183 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>clientConnectDlg</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>clientConnectDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>332</width>
+ <height>148</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Connect to Server</string>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>nicknameLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Nick name:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>nicknameEdit</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>nicknameEdit</cstring>
+ </property>
+ <property name="maxLength">
+ <number>10</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter a name that identifies you in the game</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>serverLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Server:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>serverEdit</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>lanLabel</cstring>
+ </property>
+ <property name="text">
+ <string>LAN games:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lanBox</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="1">
+ <property name="name">
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="KHistoryCombo">
+ <property name="name">
+ <cstring>serverEdit</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>portLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Port:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>portEdit</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>portEdit</cstring>
+ </property>
+ <property name="maxValue">
+ <number>65000</number>
+ </property>
+ <property name="value">
+ <number>54321</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Choose a port to connect to</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="KComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>lanBox</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<includes>
+ <include location="global" impldecl="in implementation">kcombobox.h</include>
+</includes>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcombobox.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kcombobox.h</includehint>
+</includehints>
+</UI>
diff --git a/kbattleship/kbattleship/dialogs/infoDlg.ui b/kbattleship/kbattleship/dialogs/infoDlg.ui
new file mode 100644
index 00000000..3c66d854
--- /dev/null
+++ b/kbattleship/kbattleship/dialogs/infoDlg.ui
@@ -0,0 +1,248 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>KInfoDialog</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>KInfoDialog</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>254</width>
+ <height>197</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Enemy Client Information</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>Frame8</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout6</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>lbl_clientIdentfierLabel</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Client identifier:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>lbl_ClientInformationLabel</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="frameShape">
+ <enum>MShape</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>MShadow</enum>
+ </property>
+ <property name="text">
+ <string>Client information:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>lbl_clientVersion</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>CV</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>lbl_clientVersionLabel</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Client version:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>lbl_ProtocolVersionLabel</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Protocol version:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>lbl_ProtocolVersion</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>PV</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>lbl_ClientInformation</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>CI</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>lbl_clientIdentfier</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>CI</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer13_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>PushButton7</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer13</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>PushButton7</sender>
+ <signal>clicked()</signal>
+ <receiver>KInfoDialog</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbattleship/kbattleship/dialogs/serverDlg.ui b/kbattleship/kbattleship/dialogs/serverDlg.ui
new file mode 100644
index 00000000..f16216b5
--- /dev/null
+++ b/kbattleship/kbattleship/dialogs/serverDlg.ui
@@ -0,0 +1,132 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>serverStartDlg</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>serverStartDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>247</width>
+ <height>138</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Start Server</string>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>gamenameLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Game name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>gamenameEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>portEdit</cstring>
+ </property>
+ <property name="maxValue">
+ <number>65000</number>
+ </property>
+ <property name="value">
+ <number>54321</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Choose a port where the server listens on</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>portLabel_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Port:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>portEdit</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>nicknameLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>MShape</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>MShadow</enum>
+ </property>
+ <property name="text">
+ <string>&amp;Nick name:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>nicknameEdit</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>gamenameEdit</cstring>
+ </property>
+ <property name="maxLength">
+ <number>100</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter a name that identifies you in the game</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>nicknameEdit</cstring>
+ </property>
+ <property name="maxLength">
+ <number>100</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter a name that identifies you in the game</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbattleship/kbattleship/dialogs/statDlg.ui b/kbattleship/kbattleship/dialogs/statDlg.ui
new file mode 100644
index 00000000..7ff2c202
--- /dev/null
+++ b/kbattleship/kbattleship/dialogs/statDlg.ui
@@ -0,0 +1,465 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>statDlg</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>statDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>144</width>
+ <height>338</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer20_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer18_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>OwnLabel</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>19</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>19</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>EnemyLabel</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>19</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer18</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer20</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>gbShots</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="title">
+ <string>Shots</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout17</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pShots_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer9_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>ShotLCD</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="smallDecimalPoint">
+ <bool>false</bool>
+ </property>
+ <property name="numDigits">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Shows all shots</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>gbHits</cstring>
+ </property>
+ <property name="title">
+ <string>Hits</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout15</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pHits_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer9_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>HitLCD</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="numDigits">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Shows all hit ships</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>gbWater</cstring>
+ </property>
+ <property name="title">
+ <string>Water</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout18</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pWater_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image2</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>WaterLCD</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="numDigits">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Shows all water shots</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer20_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<images>
+ <image name="image0">
+ <data format="PNG" length="831">89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af40000030649444154789ced9531681c5710863f8535ccc209de820dbb2081b67071450a77c1b8ba2a3e3b019d9322526564bb31a9845358c685e154048e5422453029020a84dc059c7855283e55569360a7307663d840047b60831edcc10e64e1523ce94987e390a45173af5916dece7cf3cf3fb3338f771f7392e79d13cd3e0598024c01a60040f06f2eb5efb6c7c76f96554924115ae9e4bb2a6bf7d666fe0bc0ccf155dc59ef8cb55287551d254be753ecc82281608716131a08404b855360c460d562c49017396110faf2d66eff339007e8ac77c62631e848d152915382a2482000482034de6f604243efc71e5460871609052a10910970dc67d8c2a2958bb37a7bf50d180fd05e6f8fcdac61e993251f48878a558b20c8acd05cfa88ecbbefa184ece70c0055a758e34203803889e9fdd0f3eda1c2c7b3430b15acdd3d52c59b5070156c7ebbc9d35f9e32f863407a36e5dcbbe7a8d7ebf477faf47b3f615f596456687dd072df89d0b8d0209d4f8993983008b9f9e94da79c82d4c4ab129f89899398f67a7bfc0680a2fe62fe7b8e56cac6571b68a544a79de1545d558362e0ed7bdc88d76e5cc3c40680d6620b630c12887b8a38a8c081b4ef3908ef6d4126fabd902ef0e4b727d417eabe872272d4bc03d8e474e22b7f983de4ca8757e83ee892cea584b5100984642ea1ac4a4242f647fb586b7d984905c499a779b1891d5aeedcbae393fbe900e2f91802884c84d4846c3bc3c40641e83ee872a97989ce971d072c4e1d1da94b3eb2e479cecaf59599490f0482202c2f2e43004994f0fce5735e3c7bc1eeafbb2c2f2e73f9e265d2f9142ad8d9def1b28612b2f9f526f95e8e20b43e6ed1dfea3b238f14fbdaa223a5d82b28f60a563f3b9a06df02ad94b016d2ddeabaa572e8890307975af28847945549b69511d522440455259d4b290605d976e6a56d2e36b9ffcd7dcebf77de8df49f3a91f8f04c2ea2cf3b631339c378e9554917d2c9193f50ec703911b84ab552f65fef3bc396ce9c7f97f4ad006f3b1b5f6c8ca5e6608e8f1538a8c384e68c61e5eacaff5fc527714efc6f380598024c01a6007f0170086155964fc7580000000049454e44ae426082</data>
+ </image>
+ <image name="image1">
+ <data format="XPM.GZ" length="10577">789c4dd9577332bb9606e0fbfd2bbedaba3b35a5436ce89a9a0b8213c9c6018ca7e6425a92b04d70001c989aff3e42eb5d3aa7becdc68f5ba99752abfdcf7ffc79bc19fff9c73fffdaedcdfe85fed0b3f9fcf30f77d86c7efffb7ffeeb7ffffabb5efb13ff6bd66a7f6a7fffc75f7f87a73ff447d5ab756ad59307c965a3021fb26df2add834922bd994dc871bc8dfc9e6fc4331d2dfc16d5cef9ddca8e6fcdd6cbede12a3feaf6c2eaf80db9cdff7b239ff4ecce9cd354c4d73b2ab8839bdcbd7dba93c7b64372b458adfd2271b297f19c45cbefb81519ebf1773796e22b6e97edc96dd44bc692846fa1b31a73753b8c9eda19698d3878f6cbe9f8d98f387f76c97daafe092d3077372b326fde1155bdae367b0d4f799cdf9dfc45c3e6de112f15c64f3fd8ec4dc3edfcf4ef9cd0dec8ad45ff6498cfacec49cdea7f1d53cc59febfb654b7acbf7638a2af26fc488c7524ccd54ff1c6e72fd612b46fe5f71c9fdf30ae37ebd3eb9c8f7474db6d46fbb30fad35e65737d5e8cf4468cf65dc2258f6723e5957cff6e2de6fc6622e6f6aa05ecd09f293e8591f16e1cbb28e16636d7f70d3baecfccb2b9bd5a8cfa3762c4eb458cfe2676abcaf9555dcced33a36c2ebf23e6f8aa463697b71553b26dc34d943f15a3fc75365faf88d1de9598e31f72798e7d0f97f0f8e4563daf577b18ebc5d288313f576c99efae849b886f9f2de3c33fc125e23d80d11ff682ddaa36aa29ff39dce4f1a2e662ce6f0a18e3d7b4c4656aafaa89793d26b4af85fe3646ccf9d5319bafe7f41c4f3ab0dbe85ffacce6f985f6b69b885f1a2f2d2bf10bcf62ac1f1b9878bc869118ebf3af18f391efd74abcad65cbf8f40f62f44f939dc7570d96f1f403a33fd4af18f15cc2aec1f17f10235e3d31c7dba27d121fa3b2b9bfbfc598cfefd9293f4d608c6fda67737fdc89915fca6f72ffaa2d2cebc78398d3878518fd81fa4aec372e5d6fd7637ff07af62a463c976c89bfafc0586fc2373bc77f9dcdfbcb869dfbe30946fc4d1596f568c89678aa7d365f6fc0129f67b8e4fed22b31ae1fc5581feec5bc3e2823763ec5a30b633ed0bb98f3eb7c9df37b6297e8df7001973e95e7f9feac3c0f84c09678f82d8cf5caf561c487be6089cf588cfd9ac43c9ec28f98cb23cd9678299427f1501f625e7fd5272ce5bf66a7fcfa458c7834c43c1e75919ddaa33bec1c1f9bcdeb5536a7571b31dab3869b9cdebf89f9ba47fb4bac7f24d7713f01ed8bdd9bfa233cb08dc43bc5b36c349bcdd43fbe0e3b5e7fed0fbb25fb1fd2b7f1fcb1b4d9dcde6b18e3cfae60895f9b5dcafcd5d91cafb118eb9d83f1bca05662c42f5f47fc8762ceaf6bd9a97d7a0663bca89198f3fb39db54d92ecdd7385970bef0255c72bcec1bbbc07e45b7b03c0fb6d8323ecd153baf971d18f76f2b62dcff038c78aa4731ce0b6f623c5fa0bd6df457388a79bf27d45fcaf34280cb7a99aebf8ab9bdba22e6f1a3af6194afd11e89971a6673fe252cf737870dd6e34b76dcc0783d49cf3be6341ef9f9a1c52e106fb563b7509e5f8811af4b18cf7fdec3e88f70c56e5779bdb31f30f61fdd8425be3d18f3393831d6cf6e363fbf6dd832df6d15c6f80b62e78b94bf604bfc6805637ed8001bb48fc4886f4f8ce78506ec71dd8b313e70ffb686f39a860bf692c421a4f6d660c3a6b4df19cacfdb962dfde1de615cb777629ebfc4fd17c73ff6df4e36af2f6d31c793c438af995b31d6f70b589edfced825ca3703318f2f7b80d15e7523467caa621e1f3485e57c7493cded7b8631bf692cc6fec6e325ce078c97168cfa0dda23fda32fb3793ca17c5be3fd4fefc548bf1373f9fa072e38bf0ab081cf611fd2f85b72ff13d530ffd278b68d461bfbb566cbfeed9beca2caf39114ecf8bafa664b7fd2078cfe536f62c4a32346ffec60399f7e8ad1ff0d31f6af2a8cf9e87ad929bd437dd21f74cd36689f6d8a715e1d8ad19e1296f68fc548ff9ecdd72f61999f67ecdc3f688f2d38bdbe12737dea0e36bc1eab6731d6db0f31ea7b813dda83f8510de9bfc48877339bdf273818f3dda5f1695ddedf385eae85fe371531d6f32d5b9ee74d1d96e7438e8f2b25be8f30e2e58eb03c7fddc298cf6a26c67a3165e7fefa81d11ffe1c46bcec9718eb33da97e7574dccd7cdaf18fddf675b5f4bfde1d2f8a6661eff812deb9dabb3db553c3f8d608c5f7560cb7aa408c67aa38fb0c4e315c6fe6d2ed806e76d752fe6fdc27c89110f03e3fef4488cfd1ce55b8c073511737d7a91cde9f375debff4209bafcf618c6fd517e37d036573fa3b36a17fc20ddb798cc7b4fe9393f3968765bdf1b76c79dfe2348cf70f96dbebe4f9df217d89fdd69ec34d9e6fc6c3384fd947b6ac076691cded2f61192f2f6c5bc3fcaf8a119fba98d75f5ac3888f6e8911dfa76c3e4f59d820fdbfccd7cf600fa7f5d235653efb6b7651e5fbf37b18f7eb6aec16c697dfc178fea13376bb8af8dec3d81fed275bf64bd5661b8c6f8bfae27ce47879b695e7956731daffc8268c3f3510e3f9c967737c038cf891a437ec308531bec29cedf17ce3d3f398f3395e1dd8f1f8b09cdf174dc4eb15c6fb12ba64cbfe6567ec529e57ea6c996f760de37eed924d059e0ff6628c0707e37ef46f36c7a7643b8caf700dcbfda5fef54581f39e1bb25b309db3e5fc402fecbc3e9cb149d68f4f31d7a7fbd9a93e75c176e81fb51423fd7b764aaf0f7081ebdfb0c17ce1f6fb16c69f53b0f40f97e7e57c4f5c9fcfe795299ba47c939deab77c7f317ef5f43e529f8bd1be0b58d2f760c3fb835e8b91fe06463c96cfec80eb36ad47a190f7e36ec596f5cbdfc0f2fef2832df1359f6c295fa33c8ff686193b884b589ee7d3fa11421ecf23b8e4f7b1ee0cc6f8b6dc9ed0c2fee7d762fc3de908233ffd8831de5e6087f176c76e233f1931febe24d7b13ed12f2cf3cd89f1f7262fc6fbc43ebb94f1f22846f97358ce9b1762de2f7c80e57e2a62b4b72ac6fb81158cfb73cf62ec5713b6c1fb58ba873de2d1cbe6f69eb36d0dfe12637c2ce102fd31860dde473c89393d9118f737803de2331363bd477f12ea73056cf0f748f41779dcdf6536bf8f7c60cbfc719f7081fd6524c6fedc800de2f721c679e0578c781f60d4e7afc4188f3f628c870edbd7709ede8ad1be265ce0feac18e3e5418cf74d4a8cf984f879c3eb8fbbcfe6f3f18518e7fd6e365f1f88b15e6dc458bfd1ff7185e3f1f328c6fb1aa90feb81c77c0b35d4f790cdef4f5ec578bedec3781fe09662fc3de9518c7821de41da1fc4382f2fc4389f1dc4d89fead9dcde211c50bfcbe6f3f4b318e5edb2f93c4162bcef9a67f3f3c4b798f74fe7b3f9fdf7a598db37dd6707b656f8186d3569a7bd0e7aa99ff58b7ed52bbdd69b7f4bf3ef9fede93bf5d19b7ed71ffa53efe267af0ffa4b7feb1ffd1b4b39ea8eeeea9eeeebb378ed439fc7b417fa32faf4f355f2792a63a0877aa4c77aa2aff58d9eea5b7da7eff543fc79a6e7fa512fe2f5275dd1555dd375ddd04d5d440f754bb775a974da8b9532ca2a524e7915d4523deb837a89edf951af6aa58f6aad366aabded4bbfa509f6aa7f6eaa0bed4b7fa51bfeaa83aa98caeeaa9be2675a6ced585ba8c255ca9811a6aab466aac576aa2aed58d9aaa5b75a7eed5839aa9b97a540bf5a42aaaaaf89d415d35e2bd7faba65eab22b6a3a5dab194d2e818dd9551f12c1d8fbbaa6ee253b60966699ecd8b79352bb38edf1bb34dfbe09b9a9a77f3613ecdceeccdc17c996ff3a397e6d71c4dc7744dcff4cd99daeba6393717e6d25cc5dc03f56e866664c66692cab83637666a6ecd9db9370ff1be8f6666e6e6518dccc23c998aa99a9a9a9b7aece96e2cf5f48eae302dd336a58db76b797fb46a61e9745eb4c12eedb37db1afe6ccaeecda6eecd6bed977fb613fedceee63845fd5c81ef48b9ae88efdb2dff6c7fea6328eb663bbb667fbf62c7eceed85bdb4577660877664c77662afed8d9dda5b7b67efed839dd9798cd7ca3eea9969d8857d4a6554d4d15663b9b5f8a9db868d272edbb26d5b92563352f1bc6589c891a7404b7aa6177a55135ad13a2e541b4a31556b7aa377fa88390bfaa45dfcece34f3b3ad0177dd30ffdd2913ad4a51ef5e98ccee9822ee98a062af60c0d6994e6df9826f1b3a7ebf87d63148dd5034d632937744b77744f0f34a3393dd2829ea812cbac528dead4a0753c1316d44afd62629d13f5aa67d48e43a1a09276a7f79d7470da2967e2a31d39179f71835bba67f7e25edd4a3f9a7bb7761bb7a5616ac7944af716e35d4b751fa227b14def3476efeec37dba9ddb4ff7ee904ad9b92fba73df7109fe71bff14e0a2e23c561e28e31578c83ebd044af5cd7f55cdf9db973b77717b1043a7ddca5bb7203377423377613774d43b77537a98c669c51e3d85bb53837c66a6b9bb18c69fcdcba3b771fefc44ff7fffae71edccccddda35bb827f74385aba4b9df7155dac77562651a3449ad6ad397abb9ba6bc493cddceda67b9ae3b388ad896771d7726d577aed15c7d49b382e9a6a150f1ee4de62ff8ce309d3c587fae097319697ff6a837f7697fec5bffa955ffb0d1576e1b73cc674c7bfe9957ff71f3e96e03fd536c6a5e1777eef0ffe2bc6c0f96f174ebdeb76fec7ffc6128ebee3bbbe1763daf2fd148fafd3d857237f16579bb1ebd2752cf1dcdef90b7fe92efc55cc35f0c358dec88ffdc45ffb1b3ff5b7fe2e9e87eefd839ff13855af7eee1fe3aa77f414e7a6f10bffe42bbeea6bbeee1bbee90bdff26d5f061d94bf0b26f6498586fededdc4ffcfb85f820d71258ceb45195c88bb27b54efd1e96ae129ee3eef4e27ec2abbb8ebe0e2b77ed1fe2b5754cb3f133dad845da3bb66eeb676113b67641adf046f13b46ab1f530d63eaf7f8f9b08b106797fd4dbf1f86cf98eefd942bd6b24bfbe13e1cc257fcec7d2fec7c4fc65ff8c6671d6bf8b64fa7391a7ec26f389e72864eccd73da54f65c49f422fe63f7df7e3b54e2cb1ef4fbf49bf4fdffd78b51fcec279b80897e12ade5d2f0cc2f0f4fb54c6574c358a9faf980e6d09e358d2e97b7ffa8ea94f759ed21dc3245c879b30b54fe1f6d4f67097ca18a43abed2f780db70726a413f95d065876e8cc37d7808b3300f8f6111cb7f0a69acc73a631da7fb43abf97b80b645a756e3fe634caaf1a4530ff5e93e3442330c5219456a4327a66ec5cf21b76590ee8ebf0b6e5bfcf9f4af1de20c08e574bfd4cbb467a7bac72945d7fd22b2e353ce531fc53286a92da7b6759626d6510983a55d12cfa1a5433c3a5cf7d2fbde32a43e487d13bac912af4e90b6c4b62d97a7b62c9fa7fbbfffef3ffffa7fb85958cf</data>
+ </image>
+ <image name="image2">
+ <data format="XPM.GZ" length="6001">789c3d98d9522b460e86efcf53504777a7a614e3dd959a0bc060035e31669b9a0bb51730c678df989a77cfef96d421247ca8b5fc92ba7d92bffe9cbd749a677ffefab5dec86632381b7cc8eaeccf703b9b1dfff3df7fffefd7ef5ce60c7f670bd9b3ecef7ffdfa1d32678333cae0af522ef29d71def8d2b86cfc9038447e331e987d9d58ed7de7b2dadbcae719b5d3dcd9ecf7c679655a189795799f38faf393f140996e94b319b31f8df3957c8cff9c7810b96a3c50e60be55cc6ec1abfec7ab8a79cea6767ab6f636cf5f3dad8ea0fb789355e30b6fef020b1da0fcaae275c39ab1e1e1bbbbe4262d533342eab9dae13abfdc3d8f487aeb2ebe76767d1f87963ef5fd6d9ece7c665657e3cf1799a273f18fb3cb789a3beeec6d8f5af945dbf8871deec7d67ebc7c2d8f4f22cb1eaf9311e987d9258ed2367ab7fa99cfaf1eeac7609c6a69fbb89b53f7563ef4727b1da73c69eef32b1da5f94f31965a6c8691f588c4dbfd48c7dbf76ce66a7c4311e358dad1f524dacf637e59ced1bb5136b3d5367ad9f5ac6b61f5475b6fd38248e76c9185b7fe822b1eaef197b7f3e136b7cd3effd09afce41cf5f19fb3c5ace6aa7983f9bf6452ac6de8f5162cdf7a29cde8799b3d5ff6cecf7efdbd9ec2563dfc7b9b3f587126bbeacb1e9a75e62ed9fc71fa81ea92be7bd9e65628d977336fd0563eb0f579dad7f2de3b29d7f30f67c711fb215d7136ace763fae8cbd7f4767d37b9358ed3fca5e3f7f2556bd0767cb3f36f67d1a385bfd569fd72f6f8987d1ee6c7ac23e71b493cea352f07d7a491ced12fb933bcff9fbfa6a6c7a65e66cf36828bbbeb04dacfd5b199b1eba74b6fedf1bfb7e1c9cadfea5b1f7b3e36cfef9c4aaef56b9e0f98fcea6b796389e0f4de382d96f126b3fe27ee5d2fce4d6d8eb3d37f6fdbd76b6fa878935de93b2d7270fcea6a79858cf4f8dbdbe4662d53b741e14e2f90be38a9dbf4eacfb5171b6f31de3a1e5ff4eacf9e3e7511ef3b2f96f8c5d6f4139f5bbe16cfbb932b6fa696fecf5349db59e3032f67a2689f57cddd9ce4f958be776be9658ebbf71b6f38fc6de2fcd2f5e5fb830b6fae4ced8ea916c62dd9f0f678b1f94bd1ef94aacf3da3a5bfefbc46a777fab8fc689d5de35f6f9c5fd2f640b05dbcf86b2e70b3fce16af6c6c7ae53db19eff74363d8bc4da0f67eb0fad9cf53ce7126bbcb9b1efd3d1d9cebf26567b4fb9e4fd89f32a88d71b06ce66ff34f6793d3b5bfdef89d5be36f67a76ce564f39b1da4bce43eddf9d72c9f76be26cfeb789d53e7436ff91b1f733be87c5acdbb9686c76ce38ab5d96c6a68f7689751e5fce966f6d6c7ac2d859ed21def762aa3fec8cbdbfe7c63edfbbc45affd6d9f23d195b3fe923b19eef3adbf94fe5b2efffccd9f4c679947229de5439d98bc6deaf92b3d95f138fa2ffc0d8ea0df1fd2b8574fec7d8f55c258efef2616c7ae8d1d9e2c5fee38f7b43cbf7ae5cf1f91612477bb8761e15238bb1d5132689357ffcefb372a8b8de7b67b3bf386b3cda185bfdd47756bbec8dadde10cf57f26ea78ab1e9e37367b57336b1fab3b2b8def83e550662fa649e58eba91b8bdabb1b26160e3ce0218f78cceffcc113fee429fef9c5337c7ff39c17bc846582af39af78cd1bde763731df8677bce7031ff9872ff892afb8cad77cc335aef32dbeeef89e1bdce4167ed386adc35d9c7ee01e3f44ff47eec3ff899f91b3c52ffcca6f9ce173ce728ef35ce02297f05319bf7be50ae2bee0dc1bef88cd7f83cafba8eb8a88845b14b844031ad288c6f44e1f34e137fa44ee6b6ed094be6846df88d2e715cdd59f167ca4254edcd08ad6b4a12ded28d09e0e74a41fe86dd305f7e91267eafc4a57885425a12a8fa3ff135dd30db886c8759aa1ca3addd21ddd53951ad4a4166a5b529bdac8dfa13d7297a94b0fd4e369f43ff57dc22fa8f791fa34e25b7aa2677aa1577aa30c9df39cb298d152274039cad3150dd1c9776a47ff211f68498553975073910aa0364fa94465aa0843fb2b1d857823c27d0950b34505797451f52ff92003be95217ed7a4aa8c507755c6f22e1ff42113f99429ede44b66f48c492fe59b6b72ea89f02afaa343b482e62f78f7a014ded496057dd2a32c29c80adf4b59d34a3694e505f5309b2ff4d0f2a3331df438275bc4cc4125b64b76b2e73b643dc8024adb3493a3fcc8858ce15fe51bb9c446d4e839eef79554e51a14d09b3636b3cf5f31f717a69fc50cdb98213443c10dcfa52675e8bcc5e97b5e46ff5bb9433fa6728fcaaad8a6be4c658f0dda4a439ad2a21769c3a3814daed1443ab8050dd94a97afa51af52fe8809343587bf07d40b706d2931d8d642d8fd297963c207f40bc23b7e409353c23ff0a3bacf39fa3b217799537c9a0febe9c43f71e9dcf626a39c11f74a881c91631a1a21cb14fd82129a19b2b91e83f96326ac3ecf95b3252917a60da7109678b98c4919e0261b773320912023ab20c03dc8a3cf2af63ff73d4912e5d85217fa303cf61848c35dc8470ea12badf44e426faf1888a3e70977a50b285da0bf5c75635b077537c8454b14b1bec721ffbbfc2366fd1f11aedc3587ab486f7845af09a8577dcc9a2d47911ebefe35e35691d3ee880fdeaf3166fd14c1ec204a74af0df05fc1bb3dc63b3dbb8b53dd83ee50691ecff4fe1a56ae34e8c30a34fd4b0a6676cef17b47e4a8f9bf2c1af612a0ff406db842e90ad717a63907f1ffd2788dae67af8a229269b0933d480b72f7ccb2eccd1c53db41c51f951821cb81d16e8de90af4fbb12fd0f889943059f88104e5b80aeb730d53195b16b3dec47239ceeffe95435ac30bd4beae2055986b5ea87822a5ebe06ee652e6c4eb700b358e06b0eef1dfcaaa77b2b6fd4099f611b7698247a110eda7fbc9c630c768f19d730f52ee2bf862366dec6bd20285923f712513be107fe1738d5c01b7d7a95a27fb80c57f0afe2b737785f6fa1af18f05606dc16fe0eb530c44f5fb0e28e40770df716d5867ab8d5fe87bb704f0bbc8105bc22d7786df0e663f7bba7379f0ea181cc43dc864e68483634d1834bbe0c2da87e228efeb7618daf76b8c21b56c31d29a136dde82ddefc1c174307113ba78d42f62a7ad8c50eddd33ce8fbbf0e0fb408f7bc878a1eb6fa0dd3bcc6e7c07778c4cf3778d1d7127f4fe8c9e9f303afd03ef4a13bfa87a7987f8d78cfdcc1fb38c73754e27daba2ceabd00a2fd0fb125e4f1cead073dddd40f53af463fe157e7a0b99b0c64b7efaf43cbde647be4435e7211bb2e8d765c885163e217a218fd8b81fe13eb45173e1f7fffffef50feb776dab</data>
+ </image>
+</images>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kbattleship/kbattleship/eventsrc b/kbattleship/kbattleship/eventsrc
new file mode 100644
index 00000000..c2c8fe7e
--- /dev/null
+++ b/kbattleship/kbattleship/eventsrc
@@ -0,0 +1,475 @@
+[!Global!]
+IconName=kbattleship
+Comment=KBattleship
+Comment[ar]=لعبة سفينة الحرب (KBattleship)
+Comment[be]=Марскі бой
+Comment[bn]=কে-ব্যাটেলশীপ
+Comment[cs]=Souboj lodí
+Comment[de]=Schiffe versenken (KBattleship)
+Comment[eo]=Batalŝipo
+Comment[hi]=के-बैटलशिप
+Comment[hr]=KPotapanje brodova
+Comment[is]=KSjóorrusta
+Comment[nds]=Scheep versenken (KBattleship)
+Comment[ne]=केडीई ब्याटलसीप
+Comment[pa]=ਕੇ-ਜੰਗੀ ਜਹਾਜ਼
+Comment[ro]=Bătălie navală
+Comment[sl]=KBojnaLadja
+Comment[sv]=Sänka fartyg
+Comment[ta]=கேபோர்க்கப்பல்
+Comment[tg]=KҶанги Киштиҳо
+Comment[tr]=Amiral Battı
+Comment[zh_TW]=KBattleship 戰艦
+
+[shoot_water]
+Name=Shot at water
+Name[ar]=إصابة في الماء
+Name[be]=Стрэл у ваду
+Name[bg]=Пропуск (стрелба във водата)
+Name[bn]=পানিতে কামান চালান
+Name[bs]=Pucanj u vodu
+Name[ca]=Tir a l'aigua
+Name[cs]=Střela do vody
+Name[cy]=Saethu i'r dŵr
+Name[da]=Skudt på vand
+Name[de]=Schuss ins Wasser
+Name[el]=Πυροβολισμός στο νερό
+Name[eo]=Pafo al akvo
+Name[es]=Disparo al agua
+Name[et]=Lask vette
+Name[eu]=Tiroa uretara
+Name[fa]=شلیک کردن در آب
+Name[fi]=Ammus veteen
+Name[fr]=Tirer dans l'eau
+Name[gl]=Disparo á auga
+Name[he]=ירייה במים
+Name[hi]=पानी पर गोली चलाएँ
+Name[hr]=Pucanj u vodu
+Name[hu]=Mellé ment lövés
+Name[is]=Skot í sjóinn
+Name[it]=Colpo in acqua
+Name[ja]=水面を撃つ
+Name[km]=បាញ់​ត្រូវ​ទឹក
+Name[lt]=Šūvis į vandenį
+Name[lv]=Trāpīts ūdenī
+Name[mk]=Истрел во вода
+Name[nb]=Skutt til sjøs
+Name[nds]=Schööt in't Water
+Name[ne]=पानीमा गोली
+Name[nl]=Schot in het water
+Name[nn]=Skot i sjøen
+Name[pa]=ਪਾਣੀ ਉੱਤੇ ਗੋਲਾਬਾਰੀ
+Name[pl]=Pudło
+Name[pt]=Disparo na água
+Name[pt_BR]=Tiro na água
+Name[ro]=A tras în apă
+Name[ru]=Промах
+Name[se]=Bávkkáhus mearas
+Name[sk]=Zásah vody
+Name[sl]=Ustreli proti vodi
+Name[sr]=Пуцањ у воду
+Name[sr@Latn]=Pucanj u vodu
+Name[sv]=Skott i vattnet
+Name[ta]=நீரில் எரி
+Name[tg]=Тирпарронӣ дар Об
+Name[tr]=Yara aldı
+Name[uk]=Постріл у воду
+Name[wa]=Côp dins l' aiwe
+Name[zh_CN]=向水中射击
+Name[zh_TW]=水面射擊
+Comment=Someone has shot at the water
+Comment[ar]=لقد رمى أحدهم على الماء
+Comment[be]=Хтосьці зрабіў стрэл у ваду
+Comment[bg]=Пропуск (стрелба във водата)
+Comment[bn]=কোনো একজন পানিতে গোলা ছুড়েছে
+Comment[bs]=Neko je pucao u vodu
+Comment[ca]=Algú dispara a l'aigua
+Comment[cs]=Někdo vystřelil do vody
+Comment[cy]=Mae rhywun wedi saethu i'r dŵr
+Comment[da]=Nogen har skudt på vandet
+Comment[de]=Da hat jemand ins Wasser geschossen
+Comment[el]=Κάποιος πυροβόλησε στο νερό
+Comment[eo]=Iu pafis al la akvo
+Comment[es]=Alguien ha disparado al agua
+Comment[et]=Keegi tulistas vette
+Comment[eu]=Norbaitek urari tiro egin dio
+Comment[fa]=شخصی در آب شلیک کرده است
+Comment[fi]=Joku on ampunut veteen
+Comment[fr]=Quelqu'un a tiré dans l'eau
+Comment[gl]=Alguén disparou á auga
+Comment[he]=מישהו ירה במים
+Comment[hi]=किसी ने पानी पर गोली चलाई
+Comment[hr]=Neko je pucao u vodu
+Comment[hu]=Az egyik játékos lövése nem talált
+Comment[is]=Einhver skaut í vatnið
+Comment[it]=Qualcuno ha sparato nell'acqua
+Comment[ja]=誰かが水面を撃った
+Comment[km]=មាន​មនុស្ស​បាន​បាញ់​ត្រូវ​ទឹក
+Comment[lt]=Kažkas šovė į vandenį
+Comment[lv]=Kāds trāpija ūdenī
+Comment[mk]=Некој стрелаше во вода
+Comment[nb]=Noen har skutt på vannet
+Comment[nds]=Een hett in't Water schaten
+Comment[ne]=केसैले पानीमा गोली हानेको छ
+Comment[nl]=Iemand heeft in het water geschoten
+Comment[nn]=Nokon har skote på vatnet
+Comment[pa]=ਕਿਸੇ ਨੇ ਪਾਣੀ ਉੱਤੇ ਗੋਲਾਬਾਰੀ ਕੀਤੀ
+Comment[pl]=Ktoś spudłował
+Comment[pt]=Alguém disparou para a água
+Comment[pt_BR]=Alguém atirou na água
+Comment[ro]=Cineva a tras în apă
+Comment[ru]=Кто-то промазал
+Comment[se]=Giinu lea bávkkihan bombba
+Comment[sk]=Niekto trafil vodu
+Comment[sl]=Nekdo je ustrelil v vodo
+Comment[sr]=Неко је пуцао у воду
+Comment[sr@Latn]=Neko je pucao u vodu
+Comment[sv]=Någon har skjutit i vattnet
+Comment[ta]=யாரோ தண்ணீரை நோக்கி சுட்டுவிட்டார்
+Comment[tg]=Касе дар об тир паронд
+Comment[tr]=Birileri biri suya ateş etti
+Comment[uk]=Хтось попав у воду
+Comment[zh_CN]=有人向水中射击
+Comment[zh_TW]=某人已進行水面射擊
+default_sound=ship-player-shoot-water.ogg
+default_presentation=1
+
+[shoot_hit_1]
+Name=Player 1 shot
+Name[ar]=رمية اللاعب 1
+Name[be]=Стрэл першага гульнёўцы
+Name[bg]=Изстрел на играч 1
+Name[bn]=প্রথম খেলোয়াড় গোলা ছুড়েছে
+Name[bs]=Pucanj igrača 1
+Name[ca]=Tir del jugador 1
+Name[cs]=Hráč 1 vystřelil
+Name[cy]=Saethu Chwaraewr 1
+Name[da]=1. spillers skud
+Name[de]=Schuss von Spieler 1
+Name[el]=Παίκτης 1 πυροβόλησε
+Name[eo]=Ludanto 1 pafis
+Name[es]=Disparo del jugador 1
+Name[et]=Mängija 1 lask
+Name[eu]=1. jokalariak tiro egin du
+Name[fa]=شلیک بازیکن ۱
+Name[fi]=Pelaaja 1 ampui
+Name[fr]=Le joueur 1 a tiré
+Name[gl]=Disparo do xogador 1
+Name[he]=יריית שחקן 1
+Name[hi]=खिलाड़ी 1 ने गोली चलाई
+Name[hr]=Puca igrač 1
+Name[hu]=Az 1. játékos egyik hajója találatot kapott
+Name[is]=Leikmaður 1 skaut
+Name[it]=Spara il giocatore n. 1
+Name[ja]=プレイヤー 1 発射
+Name[km]=អ្នក​លេង ១ បាន​បាញ់
+Name[lt]=I Žaidėjo šūvis
+Name[lv]=Pirmā spēlētāja šāviens
+Name[mk]=Истрел на играчот 1
+Name[nb]=Spiller 1 skutt
+Name[nds]=Schööt vun Speler 1
+Name[ne]=खेलाडी १ गोली
+Name[nl]=Schot van speler 1
+Name[nn]=Spelar 1 skote
+Name[pa]=ਖਿਡਾਰੀ 1 ਗੋਲੀ ਚਲਾਈ
+Name[pl]=Strzela Gracz 1
+Name[pt]=Jogador 1 disparou
+Name[pt_BR]=Jogador 1 atira
+Name[ro]=Jucătorul 1 a tras
+Name[ru]=Ход первого игрока
+Name[se]=Speallár 1 lea bávkkihan bombba
+Name[sk]=Hráč 1 vystrelil
+Name[sl]=Strel igralca 1
+Name[sr]=Пуца играч 1
+Name[sr@Latn]=Puca igrač 1
+Name[sv]=Skott från första spelaren
+Name[ta]=விளையாடுபவர் 1 எரிதல்
+Name[tg]=Тирпарронии бозингари 1
+Name[tr]=Oyunu 1 atış
+Name[uk]=Постріл першого гравця
+Name[zh_CN]=Player 1 射击
+Name[zh_TW]=玩家 1 射擊
+Comment=Player 1 takes a shot
+Comment[ar]=اللاعب 1 ي رم
+Comment[be]=Першы гульнёўца страляе
+Comment[bg]=Изстрел на играч 1
+Comment[bn]=প্রথম খেলোয়াড় গোলা ছুড়ছে
+Comment[bs]=Igrač 1 je na potezu
+Comment[ca]=El jugador 1 dispara
+Comment[cs]=Hráč 1 vystřelil
+Comment[cy]=Chwaraewr 1 yn saethu
+Comment[da]=Spiller 1 skyder
+Comment[de]=Spieler 1 schießt
+Comment[el]=Ο παίκτης 1 πυροβολεί
+Comment[eo]=Ludanto 1 pafas
+Comment[es]=El jugador 1 hace un disparo
+Comment[et]=Mängija 1 tulistas
+Comment[eu]=1. jokalariak tiro egin du
+Comment[fa]=بازیکن ۱، یک گلوله می‌خورد
+Comment[fi]=Pelaaja 1 ampuu
+Comment[fr]=Le joueur 1 a subi un tir
+Comment[gl]=O xogador 1 fai un disparo
+Comment[he]=שחקן 1 יורה
+Comment[hi]=खिलाड़ी 1 ने गोली चलाना लिया
+Comment[hr]=Igrač 1 upravo puca
+Comment[hu]=Az 1. játékos lő
+Comment[is]=Leikmaður 1 skýtur
+Comment[it]=Il giocatore 1 prende un colpo
+Comment[ja]=プレイヤー 1 が発射
+Comment[km]=អ្នក​លេង​១ បាន​បាញ់
+Comment[lt]=I Žaidėjas šauna
+Comment[lv]=Šauj pirmais spēlētājs
+Comment[mk]=Играчот 1 истрела
+Comment[nb]=Spiller 1 er truffet
+Comment[nds]=Speler 1 schütt
+Comment[ne]=खेलाडी १ ले गोली लियो
+Comment[nl]=Speler 1 schiet raak
+Comment[nn]=Spelar 1 er truffen
+Comment[pl]=Gracz 1 został trafiony
+Comment[pt]=Jogador 1 dispara
+Comment[pt_BR]=Jogador 1 leva um tiro
+Comment[ro]=Jucătorul 1 a primit o lovitură
+Comment[ru]=Ход первого игрока
+Comment[se]=Speallár 1 lea deaivvahallan
+Comment[sk]=Hráč 1 zasiahnutý
+Comment[sl]=Igralec 1 je dobil strel
+Comment[sr]=Играч 1 управо пуца
+Comment[sr@Latn]=Igrač 1 upravo puca
+Comment[sv]=Första spelaren skjuter
+Comment[ta]=விளையாட்டாளர் 1 விளையாட துவங்குகிறார்
+Comment[tg]=Бозингари 1 тир паронд
+Comment[tr]=Oyuncu 1 atış attı
+Comment[uk]=Перший гравець стріляє
+Comment[zh_CN]=Player 1 射击
+Comment[zh_TW]=玩家 1 進行了一次射擊
+default_sound=ship-player1-shoot.ogg
+default_presentation=1
+
+[shoot_hit_2]
+Name=Player 2 shot
+Name[ar]=رمية اللاعب 2
+Name[be]=Стрэл другога гульнёўцы
+Name[bg]=Изстрел на играч 2
+Name[bn]=দ্বিতীয় খেলোয়াড় গোলা ছুড়েছে
+Name[bs]=Pucanj igrača 2
+Name[ca]=Tir del jugador 2
+Name[cs]=Hráč 2 vystřelil
+Name[cy]=Saethu Chwaraewr 2
+Name[da]=2. spillers skud
+Name[de]=Schuss von Spieler 2
+Name[el]=Παίκτης 2 πυροβόλησε
+Name[eo]=Ludanto 2 pafis
+Name[es]=Disparo del jugador 2
+Name[et]=Mängija 2 lask
+Name[eu]=2. jokalariak tiro egin du
+Name[fa]=شلیک بازیکن ۲
+Name[fi]=Pelaaja 2 ampui
+Name[fr]=Le joueur 2 a tiré
+Name[gl]=Disparo do xogador 2
+Name[he]=יריית שחקן 2
+Name[hi]=खिलाड़ी 2 ने गोली चलाई
+Name[hr]=Puca igrač 2
+Name[hu]=A 2. játékos egyik hajója találatot kapott
+Name[is]=Leikmaður 2 skaut
+Name[it]=Spara il giocatore n. 2
+Name[ja]=プレイヤー 2 発射
+Name[km]=អ្នក​លេង ២ បាន​បាញ់
+Name[lt]=II Žaidėjo šūvis
+Name[lv]=Otrā spēlētāja šāviens
+Name[mk]=Истрел на играчот 2
+Name[nb]=Spiller 2 skutt
+Name[nds]=Schööt vun Speler 2
+Name[ne]=खेलाडी २ गोली
+Name[nl]=Schot van speler 2
+Name[nn]=Spelar 2 skote
+Name[pa]=ਖਿਡਾਰੀ 2 ਨੇ ਗੋਲੀ ਚਲਾਈ
+Name[pl]=Strzela Gracz 2
+Name[pt]=Jogador 2 disparou
+Name[pt_BR]=Jogador 2 atira
+Name[ro]=Jucătorul 2 a tras
+Name[ru]=Ход второго игрока
+Name[se]=Speallár 2 lea deaivvahallan
+Name[sk]=Hráč 2 vystrelil
+Name[sl]=Strel igralca 2
+Name[sr]=Пуца играч 2
+Name[sr@Latn]=Puca igrač 2
+Name[sv]=Skott från andra spelaren
+Name[ta]=விளையாடுபவர் 2 எரிதல்
+Name[tg]=Тирпарронии бозингари 2
+Name[tr]=Oyuncu 2 atış
+Name[uk]=Постріл другого гравця
+Name[zh_CN]=Player 2 射击
+Name[zh_TW]=玩家 2 射擊
+Comment=Player 2 takes a shot
+Comment[ar]=اللاعب 2 يرمى
+Comment[be]=Другі гульнёўца старляе
+Comment[bg]=Изстрел на играч 2
+Comment[bn]=দ্বিতীয় খেলোয়াড় গোলা ছুড়ছে
+Comment[bs]=Igrač 2 je na potezu
+Comment[ca]=El jugador 2 dispara
+Comment[cs]=Hráč 2 vystřelil
+Comment[cy]=Chwaraewr 2 yn saethu
+Comment[da]=Spiller 2 skyder
+Comment[de]=Spieler 2 schießt
+Comment[el]=Ο παίκτης 2 πυροβολεί
+Comment[eo]=Ludanto 2 pafas
+Comment[es]=El jugador 2 hace un disparo
+Comment[et]=Mängija 2 tulistas
+Comment[eu]=2. jokalariak tiro egin du
+Comment[fa]=بازیکن ۲، یک گلوله می‌خورد
+Comment[fi]=Pelaaja 2 ampuu
+Comment[fr]=Le joueur 2 a subi un tir
+Comment[gl]=O xogador 2 fai un disparo
+Comment[he]=שחקן 2 יורה
+Comment[hi]=खिलाड़ी 2 ने गोली चलाना लिया
+Comment[hr]=Igrač 2 upravo puca
+Comment[hu]=A 2. játékos lő
+Comment[is]=Leikmaður 2 skýtur
+Comment[it]=Il giocatore 2 prende un colpo
+Comment[ja]=プレイヤー 2 が発射
+Comment[km]=អ្នក​លេង ២ បាន​បាញ់
+Comment[lt]=II Žaidėjas šauna
+Comment[lv]=Šauj otrais spēlētājs
+Comment[mk]=Играчот 2 истрела
+Comment[nb]=Spiller 2 er truffet
+Comment[nds]=Speler 2 schütt
+Comment[ne]=खेलाडी २ ले गोली लियो
+Comment[nl]=Speler 2 schiet raak
+Comment[nn]=Spelar 2 er truffen
+Comment[pl]=Gracz 2 został trafiony
+Comment[pt]=Jogador 2 dispara
+Comment[pt_BR]=Jogador 2 leva um tiro
+Comment[ro]=Jucătorul 2 a primit o lovitură
+Comment[ru]=Ход второго игрока
+Comment[se]=Speallár 2 lea deaivvahallan
+Comment[sk]=Hráč 2 zasiahnutý
+Comment[sl]=Igralec 2 je dobil strel
+Comment[sr]=Играч 2 управо пуца
+Comment[sr@Latn]=Igrač 2 upravo puca
+Comment[sv]=Andra spelaren skjuter
+Comment[ta]=விளையாட்டாளர் 2 விளையாட துவங்குகிறார்
+Comment[tg]=Бозингари 2 тир паронд
+Comment[tr]=Oyuncu 2 atış attı
+Comment[uk]=Другий гравець стріляє
+Comment[zh_CN]=Player 2 射击
+Comment[zh_TW]=玩家 2 進行了一次射擊
+default_sound=ship-player2-shoot.ogg
+default_presentation=1
+
+[shoot_sink]
+Name=Sunk ship
+Name[ar]=سفينة مغرقة
+Name[be]=Карабель пайшоў на дно
+Name[bg]=Потопен е кораб
+Name[bn]=ডুবে যাওয়া জাহাজ
+Name[br]=Lestr kaset d'ar strad
+Name[bs]=Potopljen brod
+Name[ca]=Vaixell enfonsat
+Name[cs]=Loď potopena
+Name[cy]=Suddo llong
+Name[da]=Sunket skib
+Name[de]=Schiff versenkt
+Name[el]=Βουλιαγμένο πλοίο
+Name[eo]=Sinkita ŝipo
+Name[es]=Barco hundido
+Name[et]=Laev uputatud
+Name[eu]=Urperatutako ontzia
+Name[fa]=کشتی غرق‌‌‌شده
+Name[fi]=Laiva upposi
+Name[fr]=Bateau coulé
+Name[ga]=Long curtha chun tóin farraige
+Name[gl]=Barco afundido
+Name[he]=ספינה טבועה
+Name[hi]=जहाज डुबाएँ
+Name[hr]=Brod je potopljen
+Name[hu]=Elsüllyedt egy hajó
+Name[is]=Sökkti skipi
+Name[it]=Nave affondata
+Name[ja]=沈んだ船
+Name[km]=នាវា​លិច
+Name[lt]=Nuskendes laivas
+Name[lv]=Nogrimis kuģis
+Name[mk]=Потопи брод
+Name[nb]=Senket skip
+Name[nds]=Schipp afbuddelt
+Name[ne]=पानीजहाज डुब्यो
+Name[nl]=Gezonken schip
+Name[nn]=Senka skip
+Name[pa]=ਡੁੱਬਦਾ ਜਹਾਜ਼
+Name[pl]=Zatopiony okręt
+Name[pt]=Navio afundado
+Name[pt_BR]=Navio afundado
+Name[ro]=Nava se scunfundă
+Name[ru]=Корабль потоплен
+Name[se]=Skiipa vuojui
+Name[sk]=Potopenie lode
+Name[sl]=Potopljena ladja
+Name[sr]=Брод је потопљен
+Name[sr@Latn]=Brod je potopljen
+Name[sv]=Sänkt skepp
+Name[ta]=மூழ்கும் கப்பல்
+Name[tg]=Киштии ғарқшуда
+Name[tr]=Batık gemi
+Name[uk]=Потопив корабель
+Name[wa]=Batea coulé
+Name[zh_CN]=击沉军舰
+Name[zh_TW]= 沉船
+Comment=A ship has been sunk
+Comment[ar]=لقد أغرقت سفينة
+Comment[be]=Карабель пайшоў на дно
+Comment[bg]=Потопен е кораб
+Comment[bn]=একটি জাহাজ ডুবে গিয়েছে
+Comment[br]=Kaset d'ar strad eo ul lestr
+Comment[bs]=Brod je potopljen
+Comment[ca]=S'ha enfonsat un vaixell
+Comment[cs]=Loď byla potopena
+Comment[cy]=Mae llong wedi ei suddo
+Comment[da]=Et skib er blevet sænket
+Comment[de]=Ein Schiff wurde versenkt
+Comment[el]=Ένα πλοίο βυθίστηκε
+Comment[es]=Se ha hundido un barco
+Comment[et]=Laev uputati
+Comment[eu]=Ontzi bat urperatu dute
+Comment[fa]=یک کشتی غرق شده است
+Comment[fi]=Laiva on upotettu
+Comment[fr]=Un bateau a été coulé
+Comment[gl]=Afundiuse un barco
+Comment[he]=ספינה הוטבעה
+Comment[hi]=एक जहाज डूबा
+Comment[hr]=Brod je upravo potopljen
+Comment[hu]=Elsüllyedt egy hajó
+Comment[is]=Skipi hefur verið sökkt
+Comment[it]=Una nave è stata affondata
+Comment[ja]=船は沈没しました
+Comment[km]=នាវា​ត្រូវ​បាន​លិច
+Comment[lt]=Laivas nuskandintas
+Comment[lv]=Kugis ir nogrimis
+Comment[mk]=Потопен е брод
+Comment[nb]=Et skip er senket
+Comment[nds]=En Schipp is afbuddelt
+Comment[ne]=पानीजहाज डुबेको छ
+Comment[nl]=Er is een schip gezonken
+Comment[nn]=Eit skip er senka
+Comment[pa]=ਇੱਕ ਜਹਾਜ਼ ਡੁੱਬ ਗਿਆ
+Comment[pl]=Okręt został zatopiony
+Comment[pt]=Foi afundado um navio
+Comment[pt_BR]=Um navio acabou de afundar
+Comment[ro]=O navă s-a scufundat
+Comment[ru]=Корабль потоплен
+Comment[se]=Skiipa vuojui
+Comment[sk]=Potopenie lode
+Comment[sl]=Ladja je bila potopljena
+Comment[sr]=Брод је управо потопљен
+Comment[sr@Latn]=Brod je upravo potopljen
+Comment[sv]=Ett skepp har sänkts
+Comment[ta]=கப்பல் மூழ்கிவிட்டது
+Comment[tg]=Киштӣ ғарқ гардид
+Comment[tr]=Bir gemi batırıldı
+Comment[uk]=Корабель було потоплено
+Comment[uz]=Kema choʻktirildi
+Comment[uz@cyrillic]=Кема чўктирилди
+Comment[wa]=On batea a stî coulé
+Comment[zh_CN]=击沉了一艘军舰
+Comment[zh_TW]= 有一艘傳沉沒了
+default_sound=ship-sink.ogg
+default_presentation=1
diff --git a/kbattleship/kbattleship/kbaiplayer.cpp b/kbattleship/kbattleship/kbaiplayer.cpp
new file mode 100644
index 00000000..ca95c2da
--- /dev/null
+++ b/kbattleship/kbattleship/kbaiplayer.cpp
@@ -0,0 +1,107 @@
+/***************************************************************************
+ kbaiplayer.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+ (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kapplication.h>
+#include <kdebug.h>
+
+#include "kbchooserstrategy.h"
+
+#include "kbaiplayer.moc"
+
+#define MAX_SHIP_LEN 4
+
+KBAIPlayer::KBAIPlayer()
+{
+ m_ownShipList = 0;
+ m_battleField = 0;
+ m_masterStrategy = 0;
+ m_randomSeq = new KRandomSequence(KApplication::random());
+}
+
+KBAIPlayer::~KBAIPlayer()
+{
+ delete m_masterStrategy;
+ delete m_randomSeq;
+}
+
+void KBAIPlayer::init(KBattleField *battle_field, KShipList *ai_shiplist)
+{
+ m_battleField = battle_field;
+ m_ownShipList = ai_shiplist;
+
+ if(m_battleField != 0)
+ {
+ QRect rect = m_battleField->enemyRect();
+ int grid = m_battleField->gridSize();
+ m_fieldRect = QRect(0, 0, (rect.width() / grid), (rect.height() / grid));
+ }
+}
+
+void KBAIPlayer::slotRestart()
+{
+ if(m_randomSeq == 0 || m_ownShipList == 0 || m_battleField == 0)
+ return;
+
+ addShips();
+ chooseStrategy();
+ emit sigReady();
+}
+
+void KBAIPlayer::addShips()
+{
+ m_ownShipList->clear();
+
+ for(int shiplen = MAX_SHIP_LEN; shiplen >= 1; shiplen--)
+ {
+ int x, y;
+ bool vertical;
+
+ do
+ {
+ x = (int) m_randomSeq->getLong(m_fieldRect.width());
+ y = (int) m_randomSeq->getLong(m_fieldRect.height());
+ vertical = m_randomSeq->getBool();
+ }
+ while(!shipPlaced(shiplen, x, y, vertical));
+ }
+}
+
+void KBAIPlayer::chooseStrategy()
+{
+ delete m_masterStrategy;
+
+ m_masterStrategy = new KBChooserStrategy();
+ m_masterStrategy->init(m_battleField, m_fieldRect);
+}
+
+bool KBAIPlayer::slotRequestShot()
+{
+ if(m_masterStrategy != 0 && m_masterStrategy->hasMoreShots())
+ {
+ QPoint pos = m_masterStrategy->nextShot();
+ emit sigShootAt(pos);
+ m_masterStrategy->shotAt(pos);
+ return true;
+ }
+ return false;
+}
+
+bool KBAIPlayer::shipPlaced(int shiplen, int x, int y, bool vertical)
+{
+ QRect ship = vertical ? QRect(x, y, 1, shiplen) : QRect(x, y, shiplen, 1);
+ return m_ownShipList->addNewShip(vertical, ship.x(), ship.y());
+}
diff --git a/kbattleship/kbattleship/kbaiplayer.h b/kbattleship/kbattleship/kbaiplayer.h
new file mode 100644
index 00000000..aebb149d
--- /dev/null
+++ b/kbattleship/kbattleship/kbaiplayer.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ kbaiplayer.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+ (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBAIPLAYER_H
+#define KBAIPLAYER_H
+
+#include <qobject.h>
+
+#include <krandomsequence.h>
+
+#include "kbstrategy.h"
+#include "kbattlefield.h"
+#include "kshiplist.h"
+
+class KBAIPlayer : public QObject
+{
+ Q_OBJECT
+public:
+ KBAIPlayer();
+ ~KBAIPlayer();
+
+ void init(KBattleField *battle_field, KShipList *ai_shiplist);
+
+public slots:
+ void slotRestart();
+ bool slotRequestShot();
+ bool shipPlaced(int shiplen, int x, int y, bool vertical);
+
+signals:
+ void sigShootAt(const QPoint pos);
+ void sigReady();
+
+private:
+ void chooseStrategy();
+ void addShips();
+
+ KBStrategy *m_masterStrategy;
+ KShipList *m_ownShipList;
+ KBattleField *m_battleField;
+ KRandomSequence *m_randomSeq;
+
+ QRect m_fieldRect;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbattlefield.cpp b/kbattleship/kbattleship/kbattlefield.cpp
new file mode 100644
index 00000000..0467ae28
--- /dev/null
+++ b/kbattleship/kbattleship/kbattlefield.cpp
@@ -0,0 +1,233 @@
+/***************************************************************************
+ kbattlefield.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kbattleship.h"
+#include "kship.h"
+
+#include "kbattlefield.h"
+
+KBattleField::KBattleField(QWidget *parent, bool grid) : KGridWidget(parent, grid)
+{
+ m_parent = parent;
+ m_width = parent->width();
+ m_canDraw = true;
+
+ m_ownfieldx = 10;
+ m_ownfieldy = 10;
+ m_enemyfieldx = 10;
+ m_enemyfieldy = 10;
+
+ clearOwnField();
+ clearEnemyField();
+ clearPreviewField();
+ drawField();
+}
+
+void KBattleField::clearOwnField()
+{
+ for(int i = 0; i != m_ownfieldx; i++)
+ {
+ for(int j = 0; j != m_ownfieldy; j++)
+ {
+ m_ownfield[i][j] = KBattleField::FREE;
+ }
+ }
+}
+
+void KBattleField::clearEnemyField()
+{
+ for(int i = 0; i != m_enemyfieldx; i++)
+ {
+ for(int j = 0; j != m_enemyfieldy; j++)
+ {
+ m_enemyfield[i][j] = KBattleField::FREE;
+ }
+ }
+}
+
+void KBattleField::clearPreviewField()
+{
+ for(int i = 0; i != m_ownfieldx; i++)
+ {
+ for(int j = 0; j != m_ownfieldy; j++)
+ {
+ m_newfield[i][j] = KBattleField::FREE;
+ m_newdata[i][j] = false;
+ }
+ }
+}
+
+void KBattleField::setPreviewState(int fieldx, int fieldy, int type, bool rotate)
+{
+ m_newfield[fieldx][fieldy] = type;
+ m_newdata[fieldx][fieldy] = true;
+ m_rotatedata[fieldx][fieldy] = rotate;
+}
+
+void KBattleField::drawField()
+{
+ drawOwnField();
+ drawEnemyField();
+ clearPreviewField();
+ finished();
+}
+
+void KBattleField::drawOwnField()
+{
+ if(!m_canDraw)
+ return;
+
+ KBattleshipWindow *window = static_cast<KBattleshipWindow *>(m_parent->parent()->parent());
+ KShip *ship = 0;
+ int data;
+
+ for(int i = 0; i != m_ownfieldx; i++)
+ {
+ for(int j = 0; j != m_ownfieldy; j++)
+ {
+ setValues(((i * gridSize()) + ownXPosition()), ((j * gridSize()) + ownYPosition()), gridSize());
+ if(!m_newdata[i][j])
+ data = m_ownfield[i][j];
+ else
+ data = m_newfield[i][j];
+ switch(data)
+ {
+ case KBattleField::FREE:
+ drawSquare();
+ break;
+
+ case KBattleField::WATER:
+ drawSquare();
+ drawWaterIcon();
+ break;
+
+ case KBattleField::HIT:
+ drawSquare();
+ ship = window->shipAt(i, j);
+ if(ship->placedLeft())
+ drawShipIcon((ship->shiptype() + 1), (ship->shipxstop() - i + 1), true, true);
+ else
+ drawShipIcon((ship->shiptype() + 1), (j - ship->shipystart() + 1), false, true);
+ break;
+
+ case KBattleField::DEATH:
+ drawSquare();
+ drawDeathIcon();
+ break;
+
+ default:
+ ship = window->shipAt(i, j);
+ if(ship)
+ {
+ drawSquare();
+ if(m_newdata[i][j])
+ data = m_ownfield[i][j];
+ drawShipIcon(data, ship->placedLeft());
+ }
+ else if(!ship)
+ drawShipIcon(data, !m_rotatedata[i][j], false, true);
+ break;
+ }
+ }
+ }
+}
+
+void KBattleField::drawEnemyField()
+{
+ if(!m_canDraw)
+ return;
+
+ KBattleshipWindow *window = static_cast<KBattleshipWindow *>(m_parent->parent()->parent());
+
+ for(int i = 0; i != m_enemyfieldx; i++)
+ {
+ for(int j = 0; j != m_enemyfieldy; j++)
+ {
+ setValues(((i * gridSize()) + enemyXPosition()), ((j * gridSize()) + enemyYPosition()), gridSize());
+ switch(m_enemyfield[i][j])
+ {
+ case KBattleField::FREE:
+ drawSquare();
+ break;
+
+ case KBattleField::WATER:
+ drawSquare();
+ drawWaterIcon();
+ break;
+
+ case KBattleField::HIT:
+ drawSquare();
+ drawHitIcon();
+ break;
+
+ case KBattleField::BORDER:
+ drawSquare();
+ drawDeathBorder();
+ break;
+
+ case KBattleField::DEATH:
+ drawSquare();
+ drawDeathIcon();
+ break;
+
+ default:
+ drawSquare();
+ KShip *ship = window->enemyShipAt(i, j);
+ if(ship->placedLeft())
+ drawShipIcon(m_enemyfield[i][j], true);
+ else
+ drawShipIcon(m_enemyfield[i][j]);
+ break;
+ }
+ }
+ }
+}
+
+int KBattleField::ownXPosition()
+{
+ return 10;
+}
+
+int KBattleField::ownYPosition()
+{
+ return 10;
+}
+
+int KBattleField::enemyXPosition()
+{
+ return (m_width / 2) + 10;
+}
+
+int KBattleField::enemyYPosition()
+{
+ return 10;
+}
+
+int KBattleField::rectX()
+{
+ return 10;
+}
+
+QRect KBattleField::ownRect()
+{
+ return QRect(ownXPosition(), ownYPosition(), m_ownfieldx * gridSize(), m_ownfieldy * gridSize());
+}
+
+QRect KBattleField::enemyRect()
+{
+ return QRect(enemyXPosition(), enemyYPosition(), m_enemyfieldx * gridSize(), m_enemyfieldy * gridSize());
+}
diff --git a/kbattleship/kbattleship/kbattlefield.h b/kbattleship/kbattleship/kbattlefield.h
new file mode 100644
index 00000000..d1e62b3f
--- /dev/null
+++ b/kbattleship/kbattleship/kbattlefield.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ kbattlefield.h
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBATTLEFIELD_H
+#define KBATTLEFIELD_H
+
+#include <qpainter.h>
+#include <qwidget.h>
+
+#include "kgridwidget.h"
+
+class KBattleField : public KGridWidget
+{
+public:
+ enum{FREE, WATER, HIT, DEATH, BORDER, SHIP1P1, SHIP2P1, SHIP2P2, SHIP3P1, SHIP3P2, SHIP3P3, SHIP4P1, SHIP4P2, SHIP4P3, SHIP4P4};
+ KBattleField(QWidget *parent, bool grid);
+
+ void clearOwnField();
+ void clearEnemyField();
+ void clearPreviewField();
+
+ void drawField();
+ void setDrawField(bool draw) { m_canDraw = draw; }
+
+ void setOwnState(int fieldx, int fieldy, int type) { m_ownfield[fieldx][fieldy] = type; }
+ int ownState(int fieldx, int fieldy) { return m_ownfield[fieldx][fieldy]; }
+
+ void setEnemyState(int fieldx, int fieldy, int type) { m_enemyfield[fieldx][fieldy] = type; }
+ int enemyState(int fieldx, int fieldy) { return m_enemyfield[fieldx][fieldy]; }
+
+ void setPreviewState(int fieldx, int fieldy, int type, bool rotate);
+
+ QRect ownRect();
+ QRect enemyRect();
+
+ int gridSize() { return 32; }
+
+private:
+ void drawOwnField();
+ void drawEnemyField();
+
+ int ownXPosition();
+ int ownYPosition();
+ int enemyXPosition();
+ int enemyYPosition();
+
+ int rectX();
+
+ int m_ownfield[15][15];
+ int m_enemyfield[15][15];
+
+ int m_newfield[15][15];
+ bool m_newdata[15][15];
+ bool m_rotatedata[15][15];
+
+ int m_ownfieldx;
+ int m_ownfieldy;
+ int m_enemyfieldx;
+ int m_enemyfieldy;
+
+ int m_width;
+
+ bool m_canDraw;
+
+ QWidget *m_parent;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbattleship.cpp b/kbattleship/kbattleship/kbattleship.cpp
new file mode 100644
index 00000000..b7d38891
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleship.cpp
@@ -0,0 +1,1352 @@
+/***************************************************************************
+ kbattleship.cpp
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qlayout.h>
+#include <qtimer.h>
+
+#include <kgamemisc.h>
+#include <kinputdialog.h>
+#include <knotifyclient.h>
+#include <knotifydialog.h>
+#include <kstandarddirs.h>
+#include <kstatusbar.h>
+#include <kstdgameaction.h>
+#include <kcmdlineargs.h>
+#include <kmessagebox.h>
+#include <kuser.h>
+
+#include <kscoredialog.h>
+
+
+#include "kbattleship.moc"
+
+extern const char *clientVersion;
+
+KBattleshipWindow::KBattleshipWindow() : KMainWindow()
+{
+ shift = false;
+ m_connection = 0;
+ m_lost = 0;
+ m_config = 0;
+ m_client = 0;
+ m_server = 0;
+ m_aiPlayer = 0;
+ m_aiHits = 0;
+
+ init();
+}
+
+KBattleshipWindow::~KBattleshipWindow()
+{
+ if(m_config != 0)
+ saveOptions();
+ delete m_aiPlayer;
+ delete m_ownshiplist;
+ delete m_enemyshiplist;
+}
+
+void KBattleshipWindow::init()
+{
+ m_aiPlaying = false;
+ m_placeable = false;
+ m_shootable = false;
+ m_serverHasClient = false;
+ m_config = kapp->config();
+ initStatusBar();
+ initActions();
+ readOptions();
+ initView();
+ initChat();
+ initShipPlacing();
+ parseCommandLine();
+}
+
+void KBattleshipWindow::slotConfigureNotifications()
+{
+ KNotifyDialog::configure(this);
+}
+
+void KBattleshipWindow::initStatusBar()
+{
+ m_ownNickname = "-";
+ m_enemyNickname = "-";
+ statusBar()->insertItem(i18n(" Player 1: %1 ").arg(m_ownNickname), ID_PLAYER_OWN, 0, true);
+ statusBar()->insertItem(i18n(" Player 2: %1 ").arg(m_enemyNickname), ID_PLAYER_ENEMY, 0, true);
+ statusBar()->insertItem(i18n("Ready"), ID_STATUS_MSG, 1);
+ statusBar()->setItemAlignment(ID_STATUS_MSG, AlignLeft);
+}
+
+void KBattleshipWindow::initActions()
+{
+ KStdAction::configureNotifications(this, SLOT(slotConfigureNotifications()), actionCollection());
+ m_gameServerConnect = new KAction(i18n("&Connect to Server..."), "connect_no", Key_F2, this, SLOT(slotServerConnect()), actionCollection(), "game_serverconnect");
+ m_gameNewServer = new KAction(i18n("&Start Server..."), "network", Key_F3, this, SLOT(slotNewServer()), actionCollection(), "game_newserver");
+ m_gameSingle = new KAction(i18n("S&ingle Player..."), "gear", Key_F4, this, SLOT(slotSinglePlayer()), actionCollection(), "game_singleplayer");
+ m_gameQuit = KStdGameAction::quit(this, SLOT(close()), actionCollection());
+ KStdGameAction::highscores(this, SLOT(slotHighscore()), actionCollection());
+ m_gameEnemyInfo = new KAction(i18n("&Enemy Info"), "view_text", Key_F11, this, SLOT(slotEnemyClientInfo()), actionCollection(), "game_enemyinfo");
+
+ m_configSound = new KToggleAction(i18n("&Play Sounds"), 0, actionCollection(), "options_configure_sound");
+ m_configGrid = new KToggleAction(i18n("&Show Grid"), 0, this, SLOT(slotShowGrid()), actionCollection(), "options_show_grid");
+ m_configGrid->setCheckedState(i18n("Hide Grid"));
+
+ m_gameEnemyInfo->setEnabled(false);
+
+ setupGUI( KMainWindow::Save | StatusBar | Keys | Create );
+}
+
+void KBattleshipWindow::initChat()
+{
+ connect(m_chat, SIGNAL(sigSendMessage(const QString &)), this, SLOT(slotSendChatMessage(const QString &)));
+ connect(m_chat, SIGNAL(sigChangeEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_chat, SIGNAL(sigChangeOwnNickname(const QString &)), this, SLOT(slotChangedNickCommand(const QString &)));
+}
+
+void KBattleshipWindow::changeShipPlacementDirection(){
+ shift = !shift;
+}
+
+void KBattleshipWindow::initShipPlacing()
+{
+ connect(m_ownshiplist, SIGNAL(sigOwnFieldDataChanged(int, int, int)), this, SLOT(slotChangeOwnFieldData(int, int, int)));
+ connect(m_ownshiplist, SIGNAL(sigLastShipAdded()), this, SLOT(slotShipsReady()));
+}
+
+void KBattleshipWindow::initView()
+{
+ QWidget *dummy = new QWidget(this, "dummy");
+ setCentralWidget(dummy);
+
+ QGridLayout *topLayout = new QGridLayout(dummy, 2, 2, 0, -1, "topLayout");
+
+ m_chat = new KChatWidget(dummy);
+ m_view = new KBattleshipView(dummy, "", m_configGrid->isChecked());
+ m_stat = new KStatDialog(dummy);
+ topLayout->setColStretch(1, 10);
+ topLayout->setRowStretch(1, 10);
+ topLayout->addWidget(m_view, 0, 0);
+ topLayout->addWidget(m_stat, 0, 1);
+ topLayout->addMultiCellWidget(m_chat, 1, 1, 0, 1);
+
+ m_ownshiplist = new KShipList();
+ m_enemyshiplist = new KShipList();
+
+ m_view->startDrawing();
+ setFocusProxy(m_view);
+
+ connect(m_view, SIGNAL(sigEnemyFieldClicked(int, int)), this, SLOT(slotEnemyFieldClick(int, int)));
+ connect(m_view, SIGNAL(sigOwnFieldClicked(int, int)), this, SLOT(slotPlaceShip(int, int)));
+ connect(m_view, SIGNAL(sigMouseOverField(int, int)), this, SLOT(slotPlaceShipPreview(int, int)));
+ connect(m_view, SIGNAL(changeShipPlacementDirection()), this, SLOT(changeShipPlacementDirection()));
+}
+
+void KBattleshipWindow::slotDeleteAI()
+{
+ m_aiHits = 0;
+ delete m_aiPlayer;
+ m_aiPlayer = 0;
+}
+
+void KBattleshipWindow::slotRestartAI()
+{
+ m_aiHits = 0;
+ slotStartBattleshipGame(false);
+}
+
+void KBattleshipWindow::slotEnemyFieldClick(int fieldx, int fieldy)
+{
+ if(m_connection != 0 || m_aiPlaying)
+ {
+ if(!m_aiPlaying && m_connection == 0)
+ return;
+
+ if(!m_serverHasClient && m_connection != 0)
+ return;
+
+ if(!m_shootable)
+ return;
+
+ if(m_view->enemyFieldState(fieldx, fieldy) == KBattleField::FREE)
+ {
+ if(!m_aiPlaying && !m_lost)
+ {
+ slotStatusMsg(i18n("Sending Message..."));
+ KMessage *msg = new KMessage(KMessage::SHOOT);
+ msg->addField("fieldx", QString::number(fieldx));
+ msg->addField("fieldy", QString::number(fieldy));
+ slotSendMessage(msg);
+ }
+
+ if(m_stat->hit() != 10 && m_aiPlaying)
+ {
+ m_stat->setShot();
+
+ int showstate;
+
+ if(m_enemyshiplist->shipTypeAt(fieldx, fieldy) == 99)
+ {
+ m_stat->setWater();
+ showstate = KBattleField::WATER;
+ }
+ else
+ {
+ m_stat->setHit();
+ showstate = KBattleField::HIT;
+ }
+
+ slotChangeEnemyFieldData(fieldx, fieldy, showstate);
+
+ if(showstate == KBattleField::HIT)
+ {
+ KShip *ship = m_enemyshiplist->shipAt(fieldx, fieldy);
+ typedef QValueList<int> DeathValueList;
+ DeathValueList deathList;
+ bool xokay = true, yokay = true;
+ int tempy = 0, tempx = 0;
+
+ if(ship->placedLeft())
+ {
+ for(tempx = ship->shipxstart(); tempx <= ship->shipxstop(); tempx++)
+ {
+ if(m_view->enemyFieldState(tempx, fieldy) == KBattleField::HIT)
+ {
+ deathList.append(tempx);
+ xokay = true;
+ yokay = false;
+ }
+ else
+ {
+ xokay = false;
+ yokay = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(tempy = ship->shipystart(); tempy <= ship->shipystop(); tempy++)
+ {
+ if(m_view->enemyFieldState(fieldx, tempy) == KBattleField::HIT)
+ {
+ deathList.append(tempy);
+ xokay = false;
+ yokay = true;
+ }
+ else
+ {
+ xokay = false;
+ yokay = false;
+ break;
+ }
+ }
+ }
+
+ if(xokay)
+ {
+ DeathValueList::Iterator it;
+ for(it = deathList.begin(); it != deathList.end(); ++it)
+ {
+ if(fieldy+1 < m_enemyshiplist->m_fieldy) m_view->changeEnemyFieldData(*it, fieldy+1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(*it, fieldy, KBattleField::DEATH);
+ if(fieldy > 0) m_view->changeEnemyFieldData(*it, fieldy-1, KBattleField::BORDER);
+ }
+ if(ship->shipxstart() > 0)
+ {
+ if (fieldy > 0) m_view->changeEnemyFieldData(ship->shipxstart()-1, fieldy-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(ship->shipxstart()-1, fieldy, KBattleField::BORDER);
+ if (fieldy < m_enemyshiplist->m_fieldy) m_view->changeEnemyFieldData(ship->shipxstart()-1, fieldy+1, KBattleField::BORDER);
+ }
+ if(ship->shipxstop() < m_enemyshiplist->m_fieldx)
+ {
+ if (fieldy>0) m_view->changeEnemyFieldData(ship->shipxstop()+1, fieldy-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(ship->shipxstop()+1, fieldy, KBattleField::BORDER);
+ if (fieldy < m_enemyshiplist->m_fieldy)m_view->changeEnemyFieldData(ship->shipxstop()+1,fieldy+1, KBattleField::BORDER);
+ }
+ }
+ else if(yokay)
+ {
+ DeathValueList::Iterator it;
+ for(it = deathList.begin(); it != deathList.end(); ++it)
+ {
+ if (fieldx>0) m_view->changeEnemyFieldData(fieldx-1, *it, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, *it, KBattleField::DEATH);
+ if(fieldx<m_enemyshiplist->m_fieldx) m_view->changeEnemyFieldData(fieldx+1, *it, KBattleField::BORDER);
+ }
+ if(ship->shipystart()>0)
+ {
+ if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ship->shipystart()-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, ship->shipystart()-1, KBattleField::BORDER);
+ if (fieldx<m_enemyshiplist->m_fieldx)m_view->changeEnemyFieldData(fieldx+1, ship->shipystart()-1, KBattleField::BORDER);
+ }
+ if(ship->shipystop()<m_enemyshiplist->m_fieldy)
+ {
+ if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ship->shipystop()+1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, ship->shipystop()+1, KBattleField::BORDER);
+ if (fieldx<m_enemyshiplist->m_fieldx)m_view->changeEnemyFieldData(fieldx+1, ship->shipystop()+1, KBattleField::BORDER);
+ }
+ }
+ }
+ }
+
+ if(m_stat->hit() == 10 && m_aiPlaying)
+ {
+ m_aiPlaying = false;
+ m_shootable = false;
+ slotChangeOwnPlayer("-");
+ slotChangeEnemyPlayer("-");
+ m_gameSingle->setText(i18n("S&ingle Player"));
+ m_gameNewServer->setEnabled(true);
+ m_gameServerConnect->setEnabled(true);
+ slotStatusMsg(i18n("You won the game :)"));
+ m_stat->slotAddOwnWon();
+ slotUpdateHighscore();
+ switch(KMessageBox::questionYesNo(this, i18n("Do you want to restart the game?"),QString::null,i18n("Restart"),i18n("Do Not Restart")))
+ {
+ case KMessageBox::Yes:
+ QTimer::singleShot(0, this, SLOT(slotRestartAI()));
+ break;
+
+ case KMessageBox::No:
+ QTimer::singleShot(0, this, SLOT(slotDeleteAI()));
+ break;
+ }
+ return;
+ }
+ else if(m_aiPlayer != 0 && m_aiPlaying)
+ m_aiPlayer->slotRequestShot();
+ }
+ }
+}
+
+void KBattleshipWindow::slotReceivedEnemyFieldData(int fieldx, int fieldy, int enemystate, int xstart, int xstop, int ystart, int ystop, bool death)
+{
+ m_stat->setShot();
+
+ int showstate;
+
+ if(enemystate == 99)
+ {
+ m_stat->setWater();
+ showstate = KBattleField::WATER;
+ }
+ else
+ {
+ m_stat->setHit();
+ showstate = KBattleField::HIT;
+ }
+
+ slotChangeEnemyFieldData(fieldx, fieldy, showstate);
+
+ if(death)
+ {
+ if(xstart == xstop)
+ {
+ for(int i = ystart; i <= ystop; i++)
+ {
+ if (fieldx>0) m_view->changeEnemyFieldData(fieldx-1, i, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, i, KBattleField::DEATH);
+ if(fieldx<m_enemyshiplist->m_fieldx) m_view->changeEnemyFieldData(fieldx+1, i, KBattleField::BORDER);
+ }
+ if(ystart>0)
+ {
+ if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ystart-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, ystart-1, KBattleField::BORDER);
+ if (fieldx<m_enemyshiplist->m_fieldx)m_view->changeEnemyFieldData(fieldx+1, ystart-1, KBattleField::BORDER);
+ }
+ if(ystop<m_enemyshiplist->m_fieldy)
+ {
+ if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ystop+1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, ystop+1, KBattleField::BORDER);
+ if (fieldx<m_enemyshiplist->m_fieldx)m_view->changeEnemyFieldData(fieldx+1, ystop+1, KBattleField::BORDER);
+ }
+ }
+ else if(ystart == ystop)
+ {
+ for(int i = xstart; i <= xstop; i++)
+ {
+ if(fieldy+1 < m_enemyshiplist->m_fieldy) m_view->changeEnemyFieldData(i, fieldy+1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(i, fieldy, KBattleField::DEATH);
+ if(fieldy > 0) m_view->changeEnemyFieldData(i, fieldy-1, KBattleField::BORDER);
+ }
+ if(xstart > 0)
+ {
+ if (fieldy > 0) m_view->changeEnemyFieldData(xstart-1, fieldy-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(xstart-1, fieldy, KBattleField::BORDER);
+ if (fieldy < m_enemyshiplist->m_fieldy) m_view->changeEnemyFieldData(xstart-1, fieldy+1, KBattleField::BORDER);
+ }
+ if(xstop < m_enemyshiplist->m_fieldx)
+ {
+ if (fieldy>0) m_view->changeEnemyFieldData(xstop+1, fieldy-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(xstop+1, fieldy, KBattleField::BORDER);
+ if (fieldy < m_enemyshiplist->m_fieldy)m_view->changeEnemyFieldData(xstop+1,fieldy+1, KBattleField::BORDER);
+ }
+ }
+ }
+
+ if(m_stat->hit() != 10)
+ slotStatusMsg(i18n("Waiting for enemy to shoot.."));
+ else
+ {
+ KMessage *msg = m_view->getAliveShips(m_ownshiplist); // let's show ai player ships
+ slotSendMessage(msg);
+ slotStatusMsg(i18n("You won the game :)"));
+ m_stat->slotAddOwnWon();
+ slotUpdateHighscore();
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ slotServerReplay();
+ else
+ slotClientReplay();
+ }
+}
+
+void KBattleshipWindow::slotClientLost()
+{
+ slotAbortNetworkGame();
+ slotStatusMsg(i18n("Enemy disconnected."));
+}
+
+void KBattleshipWindow::slotServerLost()
+{
+ slotAbortNetworkGame();
+ slotStatusMsg(i18n("Enemy disconnected."));
+}
+
+void KBattleshipWindow::slotAbortNetworkGame()
+{
+ slotStatusMsg(i18n("Ready"));
+ slotChangeOwnPlayer("-");
+ slotChangeEnemyPlayer("-");
+
+ m_gameServerConnect->setText(i18n("&Connect to server"));
+ m_gameNewServer->setText(i18n("&Start server"));
+ m_gameSingle->setText(i18n("S&ingle game"));
+ m_gameServerConnect->setEnabled(true);
+ m_gameNewServer->setEnabled(true);
+ m_gameSingle->setEnabled(true);
+ m_gameEnemyInfo->setEnabled(false);
+
+ m_chat->clear();
+
+ m_aiPlaying = false;
+ m_shootable = false;
+ m_placeable = false;
+ m_serverHasClient = false;
+
+ if (m_connection)
+ {
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ {
+ delete m_kbserver;
+ m_kbserver = 0;
+ }
+ else
+ {
+ delete m_kbclient;
+ m_kbclient = 0;
+ }
+ delete m_connection;
+ m_connection = 0;
+ }
+}
+
+void KBattleshipWindow::slotReplay()
+{
+ cleanup(true);
+ m_aiPlaying = false;
+ m_shootable = false;
+ m_lost = false;
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ m_placeable = true;
+ else
+ m_placeable = false;
+ m_stat->clear();
+}
+
+void KBattleshipWindow::slotPlaceShipPreview(int fieldx, int fieldy)
+{
+ int xadd = 0, yadd = 0;
+
+ if(m_connection != 0 || m_aiPlaying)
+ {
+ if(!m_aiPlaying && m_connection == 0)
+ return;
+
+ if(m_connection != 0 && !m_aiPlaying && !m_serverHasClient)
+ return;
+
+ if((m_placeable && m_ownshiplist->canAddShips()) || m_aiPlaying)
+ {
+ switch(m_ownshiplist->shipCount())
+ {
+ case 4:
+ for(int i = 0; i <= 3; i++)
+ {
+ if(!shift)
+ xadd = i;
+ else
+ yadd = i;
+ m_view->previewShip(fieldx + xadd, fieldy + yadd, KBattleField::SHIP4P1 + i, shift);
+ }
+ break;
+
+ case 3:
+ for(int i = 0; i <= 2; i++)
+ {
+ if(!shift)
+ xadd = i;
+ else
+ yadd = i;
+ m_view->previewShip(fieldx + xadd, fieldy + yadd, KBattleField::SHIP3P1 + i, shift);
+ }
+ break;
+
+ case 2:
+ for(int i = 0; i <= 1; i++)
+ {
+ if(!shift)
+ xadd = i;
+ else
+ yadd = i;
+ m_view->previewShip(fieldx + xadd, fieldy + yadd, KBattleField::SHIP2P1 + i, shift);
+ }
+ break;
+
+ case 1:
+ m_view->previewShip(fieldx, fieldy, KBattleField::SHIP1P1, shift);
+ break;
+ }
+
+ m_view->field()->drawField();
+ }
+ }
+}
+
+void KBattleshipWindow::slotPlaceShip(int fieldx, int fieldy)
+{
+ if(m_connection != 0 || m_aiPlaying)
+ {
+ if(!m_aiPlaying && m_connection == 0)
+ return;
+
+ if(m_connection != 0 && !m_aiPlaying && !m_serverHasClient)
+ return;
+
+ if(m_placeable && m_ownshiplist->canAddShips())
+ m_ownshiplist->addNewShip(shift, fieldx, fieldy);
+ }
+}
+
+void KBattleshipWindow::slotShipsReady()
+{
+ if(m_aiPlaying)
+ {
+ slotStatusMsg(i18n("Waiting for computer player to start the match..."));
+ m_placeable = false;
+ m_aiPlayer->slotRequestShot();
+ return;
+ }
+
+ KMessage *msg = new KMessage(KMessage::SHIPSREADY);
+ slotSendMessage(msg);
+
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ slotStatusMsg(i18n("Waiting for other player to place their ships..."));
+ else
+ slotStatusMsg(i18n("Waiting for other player to start the match..."));
+
+ m_placeable = false;
+}
+
+void KBattleshipWindow::slotSendMessage(int fieldx, int fieldy, int state)
+{
+ if(m_connection != 0)
+ {
+ KMessage *msg = new KMessage(KMessage::ANSWER_SHOOT);
+ msg->addField(QString("fieldx"), QString::number(fieldx));
+ msg->addField(QString("fieldy"), QString::number(fieldy));
+ msg->addField(QString("fieldstate"), QString::number(state));
+
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ m_kbserver->sendMessage(msg);
+ else
+ m_kbclient->sendMessage(msg);
+ }
+}
+
+void KBattleshipWindow::slotSendMessage(KMessage *msg)
+{
+ if(m_connection != 0)
+ {
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ m_kbserver->sendMessage(msg);
+ else
+ m_kbclient->sendMessage(msg);
+ }
+}
+
+void KBattleshipWindow::slotSendChatMessage(const QString &text)
+{
+ if(m_connection != 0 && m_serverHasClient)
+ {
+ KMessage *msg = new KMessage(KMessage::CHAT);
+ msg->chatMessage(m_ownNickname, text);
+ slotSendMessage(msg);
+ }
+}
+
+void KBattleshipWindow::slotChangedNickCommand(const QString &text)
+{
+ m_ownNickname = text;
+ slotChangeOwnPlayer(m_ownNickname);
+ m_chat->setNickname(m_ownNickname);
+}
+
+KShip *KBattleshipWindow::shipAt(int fieldx, int fieldy)
+{
+ return m_ownshiplist->shipAt(fieldx, fieldy);
+}
+
+KShip *KBattleshipWindow::enemyShipAt(int fieldx, int fieldy)
+{
+ return m_enemyshiplist->shipAt(fieldx, fieldy);
+}
+
+void KBattleshipWindow::slotUpdateHighscore()
+{
+ // Balancing factors
+ // a = shot-balance
+ // b = water-balance
+ double a = 3;
+ double b = 0.5;
+ double score = (a * m_stat->hit() - b * m_stat->water()) / (m_stat->shot() + m_stat->water()) * 1000;
+ if(score == 0) score = 1;
+
+ KScoreDialog *scoreDialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Custom1 | KScoreDialog::Custom2 | KScoreDialog::Custom3, this);
+ scoreDialog->addField(KScoreDialog::Custom1, i18n("Shots"), "shots");
+ scoreDialog->addField(KScoreDialog::Custom2, i18n("Hits"), "hits");
+ scoreDialog->addField(KScoreDialog::Custom3, i18n("Water"), "water");
+
+ KScoreDialog::FieldInfo info;
+ info[KScoreDialog::Name] = m_ownNickname;
+ info[KScoreDialog::Custom1] = QString::number(m_stat->shot());
+ info[KScoreDialog::Custom2] = QString::number(m_stat->hit());
+ info[KScoreDialog::Custom3] = QString::number(m_stat->water());
+
+ scoreDialog->addScore((int)score, info, false, false);
+}
+
+void KBattleshipWindow::saveOptions()
+{
+ m_config->setGroup("General");
+ m_config->writeEntry("PlaySounds", m_configSound->isChecked());
+ m_config->writeEntry("ShowGrid", m_configGrid->isChecked());
+ m_config->sync();
+}
+
+void KBattleshipWindow::readOptions()
+{
+ m_config->setGroup("General");
+ m_configSound->setChecked(m_config->readBoolEntry("PlaySounds", true));
+ m_configGrid->setChecked(m_config->readBoolEntry("ShowGrid", false));
+}
+
+void KBattleshipWindow::slotHighscore()
+{
+ KScoreDialog *scoreDialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Custom1 | KScoreDialog::Custom2 | KScoreDialog::Custom3, this);
+ scoreDialog->addField(KScoreDialog::Custom1, i18n("Shots"), "shots");
+ scoreDialog->addField(KScoreDialog::Custom2, i18n("Hits"), "hits");
+ scoreDialog->addField(KScoreDialog::Custom3, i18n("Water"), "water");
+ scoreDialog->show();
+}
+
+void KBattleshipWindow::slotEnemyClientInfo()
+{
+ KInfoDialog *m_info = new KInfoDialog(this);
+
+ m_info->lbl_clientIdentfier->setText(m_enemyClient);
+ m_info->lbl_clientVersion->setText(m_enemyClientVersion);
+ m_info->lbl_ClientInformation->setText(m_enemyClientDescription);
+ m_info->lbl_ProtocolVersion->setText(m_enemyProtocolVersion);
+
+ m_info->show();
+}
+
+void KBattleshipWindow::slotServerConnect()
+{
+ if(m_connection == 0)
+ {
+ if(m_client != 0) {
+ m_client->show();
+ return;
+ }
+
+ slotStatusMsg(i18n("Loading Connect-Server dialog..."));
+
+ m_client = new KClientDialog(this);
+ connect(m_client, SIGNAL(sigConnectServer()), this, SLOT(slotConnectToBattleshipServer()));
+ connect(m_client, SIGNAL(sigCancelConnect()), this, SLOT(slotDeleteConnectDialog()));
+ m_client->show();
+
+ slotStatusMsg(i18n("Ready"));
+ }
+ else
+ slotAbortNetworkGame();
+}
+
+void KBattleshipWindow::slotDeleteConnectDialog()
+{
+ delete m_client;
+ m_client = 0;
+}
+
+void KBattleshipWindow::slotReplayRequest()
+{
+ switch(KMessageBox::questionYesNo(this, i18n("The client is asking to restart the game. Do you accept?"),QString::null,i18n("Accept Restart"), i18n("Deny Restart")))
+ {
+ case KMessageBox::Yes:
+ if (m_connection)
+ { // the client could have closed while the user was thinking if he wanted to replay
+ slotReplay();
+ slotStatusMsg(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
+ }
+ else slotAbortNetworkGame();
+ break;
+
+ case KMessageBox::No:
+ slotAbortNetworkGame();
+ break;
+ }
+}
+
+void KBattleshipWindow::slotServerReplay()
+{
+ KMessage *msg = new KMessage(KMessage::REPLAY);
+ switch(KMessageBox::questionYesNo(this, i18n("Do you want to restart the game?"), QString::null, i18n("Restart"), i18n("Do Not Restart")))
+ {
+ case KMessageBox::Yes:
+ if (m_connection)
+ { // the client could have closed while the user was thinking if he wanted to replay
+ slotReplay();
+ slotStatusMsg(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
+ slotSendMessage(msg);
+ }
+ else
+ {
+ delete msg;
+ slotAbortNetworkGame();
+ }
+ break;
+
+ case KMessageBox::No:
+ delete msg;
+ slotAbortNetworkGame();
+ break;
+ }
+}
+
+void KBattleshipWindow::slotClientReplay()
+{
+ KMessage *msg = new KMessage(KMessage::REPLAY);
+ switch(KMessageBox::questionYesNo(this, i18n("Do you want to ask the server restarting the game?"), QString::null, i18n("Ask to Restart"), i18n("Do Not Ask")))
+ {
+ case KMessageBox::Yes:
+ if (m_connection)
+ { // the server could have closed while the user was thinking if he wanted to replay
+ slotReplay();
+ slotStatusMsg(i18n("Waiting for an answer..."));
+ slotSendMessage(msg);
+ }
+ else
+ {
+ delete msg;
+ slotAbortNetworkGame();
+ }
+ break;
+
+ case KMessageBox::No:
+ delete msg;
+ slotAbortNetworkGame();
+ break;
+ }
+}
+
+void KBattleshipWindow::cleanup(bool placechange)
+{
+ if(placechange)
+ m_placeable = false;
+ m_view->field()->setDrawField(false);
+ m_ownshiplist->clear();
+ m_enemyshiplist->clear();
+ m_view->clearField();
+ m_view->field()->setDrawField(true);
+ m_view->field()->drawField();
+}
+
+void KBattleshipWindow::slotNewServer()
+{
+ if(m_connection == 0)
+ {
+ if(m_server != 0)
+ return;
+
+ slotStatusMsg(i18n("Loading Start-Server dialog..."));
+
+ m_server = new KServerDialog(this);
+ connect(m_server, SIGNAL(okClicked()), this, SLOT(slotStartBattleshipServer()));
+ connect(m_server, SIGNAL(cancelClicked()), this, SLOT(slotDeleteServerDialog()));
+ m_server->show();
+
+ slotStatusMsg(i18n("Ready"));
+ }
+ else
+ slotAbortNetworkGame();
+}
+
+void KBattleshipWindow::slotDeleteServerDialog()
+{
+ delete m_server;
+ m_server = 0;
+}
+
+void KBattleshipWindow::slotSendVersion()
+{
+ KMessage *msg = new KMessage(KMessage::GETVERSION);
+ msg->versionMessage();
+ slotSendMessage(msg);
+
+ QTimer::singleShot(150, this, SLOT(slotSendGreet()));
+}
+
+void KBattleshipWindow::slotSendGreet()
+{
+ m_serverHasClient = true;
+ m_chat->slotAcceptMsg(true);
+
+ KMessage *msg = new KMessage(KMessage::GREET);
+ msg->addField(QString("nickname"), m_ownNickname);
+ slotSendMessage(msg);
+}
+
+void KBattleshipWindow::slotStartBattleshipServer()
+{
+ m_gameNewServer->setText(i18n("&Stop server"));
+ m_gameServerConnect->setEnabled(false);
+ m_gameSingle->setEnabled(false);
+ slotStatusMsg(i18n("Waiting for a player..."));
+ m_kbserver = new KBattleshipServer((m_server->port()).toInt(),m_server->gamename());
+ m_ownNickname = m_server->nickname();
+ m_chat->setNickname(m_ownNickname);
+ slotChangeOwnPlayer(m_ownNickname);
+ delete m_server;
+ m_server = 0;
+ cleanup(true);
+ m_aiPlaying = false;
+ m_shootable = false;
+ m_placeable = true;
+ m_stat->clear();
+ m_stat->clearWon();
+ if(m_connection == 0)
+ {
+ m_connection = new KonnectionHandling(this, m_kbserver);
+ connect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ connect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_connection, SIGNAL(sigSendNickname()), this, SLOT(slotSendGreet()));
+ connect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ connect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ connect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ connect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ connect(m_connection, SIGNAL(sigClientLost()), this, SLOT(slotClientLost()));
+ connect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ connect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplayRequest()));
+ connect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ connect(m_connection, SIGNAL(sigClientInformation(const QString &, const QString &, const QString &, const QString &)), this, SLOT(slotReceivedClientInformation(const QString &, const QString &, const QString &, const QString &)));
+ connect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ }
+ else
+ {
+ if(m_connection->type() == KonnectionHandling::CLIENT)
+ {
+ disconnect(m_kbclient, SIGNAL(sigConnected()), this, SLOT(slotSendVersion()));
+ disconnect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ disconnect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ disconnect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ disconnect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ disconnect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ disconnect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ disconnect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ disconnect(m_connection, SIGNAL(sigServerLost()), this, SLOT(slotServerLost()));
+ disconnect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplay()));
+ disconnect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ disconnect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ m_connection->updateInternal(m_kbserver);
+ connect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ connect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_connection, SIGNAL(sigSendNickname()), this, SLOT(slotSendGreet()));
+ connect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ connect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ connect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ connect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ connect(m_connection, SIGNAL(sigClientLost()), this, SLOT(slotClientLost()));
+ connect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ connect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplayRequest()));
+ connect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ connect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ }
+ else
+ m_connection->updateInternal(m_kbserver);
+ }
+ m_kbserver->init();
+}
+
+void KBattleshipWindow::slotLost(KMessage *msg)
+{
+ m_stat->slotAddEnemyWon();
+ if (!msg->field("ship0").isNull()) m_view->drawEnemyShipsHuman(msg, m_enemyshiplist);
+ m_lost = true;
+}
+
+void KBattleshipWindow::slotSendEnemyFieldState(int fieldx, int fieldy)
+{
+ int data, showstate;
+ bool xokay = false, yokay = false, is_kill = false;
+ typedef QValueList<int> DeathValueList;
+ DeathValueList deathList;
+
+ data = m_ownshiplist->shipTypeAt(fieldx, fieldy);
+ if(data == 99)
+ showstate = KBattleField::WATER;
+ else
+ showstate = KBattleField::HIT;
+
+ slotChangeOwnFieldData(fieldx, fieldy, showstate);
+
+ KMessage *msg = new KMessage(KMessage::ANSWER_SHOOT);
+
+ if(showstate == KBattleField::HIT)
+ {
+ if(m_ownshiplist->shipTypeAt(fieldx, fieldy) != 0 && m_ownshiplist->shipTypeAt(fieldx, fieldy) != 99)
+ {
+ KShip *ship = m_ownshiplist->shipAt(fieldx, fieldy);
+ int tempy = 0, tempx = 0;
+
+ if(ship->shipystart() == ship->shipystop() && ship->shipxstart() != ship->shipxstop())
+ {
+ for(tempx = ship->shipxstart(); tempx <= ship->shipxstop(); tempx++)
+ {
+ if(m_view->ownFieldState(tempx, fieldy) == KBattleField::HIT)
+ {
+ deathList.append(tempx);
+ xokay = true;
+ yokay = false;
+ }
+ else
+ {
+ xokay = false;
+ yokay = false;
+ break;
+ }
+ }
+ }
+ else if(ship->shipystart() != ship->shipystop() && ship->shipxstart() == ship->shipxstop())
+ {
+ for(tempy = ship->shipystart(); tempy <= ship->shipystop(); tempy++)
+ {
+ if(m_view->ownFieldState(fieldx, tempy) == KBattleField::HIT)
+ {
+ deathList.append(tempy);
+ xokay = false;
+ yokay = true;
+ }
+ else
+ {
+ xokay = false;
+ yokay = false;
+ break;
+ }
+ }
+ }
+ }
+ else if(m_ownshiplist->shipTypeAt(fieldx, fieldy) == 0)
+ {
+ msg->addField(QString("xstart"), QString::number(fieldx));
+ msg->addField(QString("xstop"), QString::number(fieldx));
+ msg->addField(QString("ystart"), QString::number(fieldy));
+ msg->addField(QString("ystop"), QString::number(fieldy));
+ msg->addField(QString("death"), QString("true"));
+ is_kill = true;
+ }
+ }
+
+ msg->addField(QString("fieldx"), QString::number(fieldx));
+ msg->addField(QString("fieldy"), QString::number(fieldy));
+
+ if(xokay)
+ {
+ msg->addField(QString("xstart"), QString::number(deathList.first()));
+ msg->addField(QString("xstop"), QString::number(deathList.last()));
+ msg->addField(QString("ystart"), QString::number(fieldy));
+ msg->addField(QString("ystop"), QString::number(fieldy));
+ msg->addField(QString("death"), QString("true"));
+ is_kill = true;
+ }
+ else if(yokay)
+ {
+ msg->addField(QString("xstart"), QString::number(fieldx));
+ msg->addField(QString("xstop"), QString::number(fieldx));
+ msg->addField(QString("ystart"), QString::number(deathList.first()));
+ msg->addField(QString("ystop"), QString::number(deathList.last()));
+ msg->addField(QString("death"), QString("true"));
+ is_kill = true;
+ }
+
+ if(is_kill)
+ // If sunk, reveal ship type
+ msg->addField(QString("fieldstate"), QString::number(data));
+ else if(showstate == KBattleField::HIT)
+ // On non-fatal hit, keep ship type secret
+ msg->addField(QString("fieldstate"), QString::number(1));
+ else /* showstate == KBattleField::WATER */
+ // Miss
+ msg->addField(QString("fieldstate"), QString::number(99));
+
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ m_kbserver->sendMessage(msg);
+ else
+ m_kbclient->sendMessage(msg);
+}
+
+void KBattleshipWindow::slotChangeOwnFieldData(int fieldx, int fieldy, int type)
+{
+ m_view->changeOwnFieldData(fieldx, fieldy, type);
+ playSound(true, type);
+}
+
+void KBattleshipWindow::playSound(bool enemy, int fieldstate)
+{
+ if (m_configSound->isChecked())
+ {
+ switch(fieldstate)
+ {
+ case KBattleField::WATER:
+ KNotifyClient::event(winId(), "shoot_water");
+ break;
+
+ case KBattleField::HIT:
+ if(enemy)
+ KNotifyClient::event(winId(), "shoot_hit_1");
+ else
+ KNotifyClient::event(winId(), "shoot_hit_2");
+ break;
+
+ case KBattleField::DEATH:
+ KNotifyClient::event(winId(), "shoot_sink");
+ break;
+ }
+ }
+}
+
+void KBattleshipWindow::slotChangeEnemyFieldData(int fieldx, int fieldy, int type)
+{
+ m_view->changeEnemyFieldData(fieldx, fieldy, type);
+ playSound(false, type);
+}
+
+void KBattleshipWindow::parseCommandLine() {
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if ( args->count() > 0 )
+ {
+ KURL u( args->url(0));
+ if(u.protocol().isEmpty())
+ u.setProtocol("kbattleship");
+ if( !u.isValid()) {
+ KMessageBox::sorry(this,
+ i18n("The URL passed to KDE Battleship '%1' is not a valid url")
+ .arg(args->arg(0)));
+ return;
+ }
+ if( u.protocol() != "kbattleship" ) {
+ KMessageBox::sorry(this,
+ i18n("The URL passed to KDE Battleship '%1' is not recognised "
+ "as a Battleship game.")
+ .arg(args->arg(0)));
+ return;
+ }
+
+ slotConnectToBattleshipServer(u.host(), u.port(), u.user());
+
+ }
+
+}
+
+void KBattleshipWindow::slotConnectToBattleshipServer()
+{
+ QString host = m_client->host();
+ int port = m_client->port().toInt();
+ QString nickname = m_client->nickname();
+ delete m_client;
+ m_client = 0;
+ slotConnectToBattleshipServer(host, port, nickname);
+}
+void KBattleshipWindow::slotConnectToBattleshipServer(const QString &host, int port, const QString &nickname)
+{
+ m_kbclient = new KBattleshipClient(host, port);
+ nickname.isEmpty() ? m_ownNickname = "TestUser" : m_ownNickname = nickname;
+ m_chat->setNickname(m_ownNickname);
+ slotChangeOwnPlayer(m_ownNickname);
+ cleanup(true);
+ m_aiPlaying = false;
+ m_shootable = false;
+ m_placeable = false;
+ m_stat->clear();
+ m_stat->clearWon();
+ m_gameServerConnect->setText(i18n("Dis&connect from server"));
+ m_gameNewServer->setEnabled(false);
+ m_gameSingle->setEnabled(false);
+ if(m_connection == 0)
+ {
+ m_connection = new KonnectionHandling(this, m_kbclient);
+ connect(m_kbclient, SIGNAL(sigConnected()), this, SLOT(slotSendVersion()));
+ connect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ connect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ connect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ connect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ connect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ connect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ connect(m_connection, SIGNAL(sigServerLost()), this, SLOT(slotServerLost()));
+ connect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplay()));
+ connect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ connect(m_connection, SIGNAL(sigClientInformation(const QString &, const QString &, const QString &, const QString &)), this, SLOT(slotReceivedClientInformation(const QString &, const QString &, const QString &, const QString &)));
+ connect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ }
+ else
+ {
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ {
+ disconnect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ disconnect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ disconnect(m_connection, SIGNAL(sigSendNickname()), this, SLOT(slotSendGreet()));
+ disconnect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ disconnect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ disconnect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ disconnect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ disconnect(m_connection, SIGNAL(sigClientLost()), this, SLOT(slotClientLost()));
+ disconnect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ disconnect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplayRequest()));
+ disconnect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ disconnect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ m_connection->updateInternal(m_kbclient);
+ connect(m_kbclient, SIGNAL(sigConnected()), this, SLOT(slotSendVersion()));
+ connect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ connect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ connect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ connect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ connect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ connect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ connect(m_connection, SIGNAL(sigServerLost()), this, SLOT(slotServerLost()));
+ connect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplay()));
+ connect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ m_kbclient->init();
+ connect(m_connection, SIGNAL(sigClientInformation(const QString &, const QString &, const QString &, const QString &)), this, SLOT(slotReceivedClientInformation(const QString &, const QString &, const QString &, const QString &)));
+ connect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ }
+ else
+ m_connection->updateInternal(m_kbclient);
+ }
+ m_kbclient->init();
+}
+
+void KBattleshipWindow::slotSetPlaceable(bool place)
+{
+ m_placeable = place;
+}
+
+void KBattleshipWindow::slotSetShootable(bool shoot)
+{
+ m_shootable = shoot;
+}
+
+void KBattleshipWindow::slotShowGrid()
+{
+ if(!m_configGrid->isChecked())
+ m_view->field()->disableGrid();
+ else
+ m_view->field()->enableGrid();
+}
+
+void KBattleshipWindow::slotStatusMsg(const QString &text)
+{
+ statusBar()->clear();
+ statusBar()->changeItem(text, ID_STATUS_MSG);
+}
+
+void KBattleshipWindow::slotChangeOwnPlayer(const QString &text)
+{
+ statusBar()->clear();
+ statusBar()->changeItem(i18n(" Player 1: %1 ").arg(text), ID_PLAYER_OWN);
+}
+
+void KBattleshipWindow::slotChangeEnemyPlayer(const QString &text)
+{
+ statusBar()->clear();
+ statusBar()->changeItem(i18n(" Player 2: %1 ").arg(text), ID_PLAYER_ENEMY);
+}
+
+void KBattleshipWindow::slotSinglePlayer()
+{
+ bool ok;
+ if(!m_aiPlaying)
+ {
+ KUser u;
+ m_ownNickname = KInputDialog::getText(i18n("Start Game"), i18n("Nick name:"),
+ u.loginName(), &ok, this);
+ if (ok)
+ {
+ slotStatusMsg(i18n("Ready"));
+ slotStartBattleshipGame();
+ }
+ }
+ else
+ {
+ if(m_aiPlayer != 0)
+ {
+ m_aiPlaying = false;
+ slotChangeOwnPlayer("-");
+ slotChangeEnemyPlayer("-");
+ m_gameSingle->setText(i18n("S&ingle Player"));
+ m_gameNewServer->setEnabled(true);
+ m_gameServerConnect->setEnabled(true);
+ slotStatusMsg(i18n("Ready"));
+ m_stat->clear();
+ m_chat->clear();
+ QTimer::singleShot(0, this, SLOT(slotDeleteAI()));
+ cleanup(false);
+ }
+ }
+}
+
+void KBattleshipWindow::slotStartBattleshipGame()
+{
+ slotStartBattleshipGame(true);
+}
+
+void KBattleshipWindow::slotStartBattleshipGame(bool clearstat)
+{
+ m_gameSingle->setText(i18n("&Stop game"));
+ m_gameNewServer->setEnabled(false);
+ m_gameServerConnect->setEnabled(false);
+ slotStatusMsg(i18n("Waiting for the AI player to place the ships..."));
+ slotChangeOwnPlayer(m_ownNickname);
+ slotChangeEnemyPlayer(KGameMisc::randomName());
+ cleanup(true);
+ if(m_connection != 0)
+ {
+ delete m_connection;
+ m_connection = 0;
+ }
+ m_aiPlaying = true;
+ m_shootable = false;
+ m_stat->clear();
+ if(clearstat)
+ m_stat->clearWon();
+
+ if(m_aiPlayer == 0)
+ {
+ m_aiPlayer = new KBAIPlayer();
+ m_aiPlayer->init(m_view->field(), m_enemyshiplist);
+ connect(m_aiPlayer, SIGNAL(sigReady()), this, SLOT(slotAIReady()));
+ connect(m_aiPlayer, SIGNAL(sigShootAt(const QPoint)), this, SLOT(slotAIShootsAt(const QPoint)));
+ }
+ m_aiPlayer->slotRestart();
+}
+
+void KBattleshipWindow::slotAIReady()
+{
+ slotStatusMsg(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
+ m_placeable = true;
+}
+
+void KBattleshipWindow::slotAIShootsAt(const QPoint pos)
+{
+ if(!m_shootable)
+ m_shootable = true;
+
+ int showstate = m_view->ownFieldState(pos.x(), pos.y());
+
+ if(showstate == KBattleField::HIT)
+ {
+ m_aiPlayer->slotRequestShot();
+ return;
+ }
+ else if(showstate == KBattleField::FREE)
+ showstate = KBattleField::WATER;
+ else if(showstate >= KBattleField::SHIP1P1)
+ {
+ showstate = KBattleField::HIT;
+ m_aiHits++;
+ }
+
+ slotStatusMsg(i18n("Enemy has shot. Shoot now."));
+ slotChangeOwnFieldData(pos.x(), pos.y(), showstate);
+
+ if(m_aiHits == 10 && m_stat->hit() != 10)
+ {
+ m_aiPlaying = false;
+ m_shootable = false;
+ slotChangeOwnPlayer("-");
+ slotChangeEnemyPlayer("-");
+ m_gameSingle->setText(i18n("S&ingle Player"));
+ m_gameNewServer->setEnabled(true);
+ m_gameServerConnect->setEnabled(true);
+ slotStatusMsg(i18n("You lost the game. :("));
+ m_stat->slotAddEnemyWon();
+ slotUpdateHighscore();
+ m_view->drawEnemyShipsAI(m_enemyshiplist); // let's show ai player ships
+ switch(KMessageBox::questionYesNo(this, i18n("Do you want to restart the game?"), QString::null, i18n("Restart"), i18n("Do Not Restart")))
+ {
+ case KMessageBox::Yes:
+ QTimer::singleShot(0, this, SLOT(slotRestartAI()));
+ break;
+
+ case KMessageBox::No:
+ QTimer::singleShot(0, this, SLOT(slotDeleteAI()));
+ break;
+ }
+ }
+ else
+ {
+ if(!m_shootable)
+ m_shootable = true;
+ }
+}
+
+void KBattleshipWindow::slotReceivedClientInformation(const QString &clientName, const QString &clientVersion, const QString &clientDescription, const QString &protocolVersion)
+{
+ m_enemyClient = clientName;
+ m_enemyClientVersion = clientVersion;
+ m_enemyClientDescription = clientDescription;
+ m_enemyProtocolVersion = protocolVersion;
+ m_gameEnemyInfo->setEnabled(true);
+
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ {
+ KMessage *msg = new KMessage(KMessage::GETVERSION);
+ msg->versionMessage();
+ slotSendMessage(msg);
+ }
+}
diff --git a/kbattleship/kbattleship/kbattleship.desktop b/kbattleship/kbattleship/kbattleship.desktop
new file mode 100644
index 00000000..48cd8dd1
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleship.desktop
@@ -0,0 +1,76 @@
+[Desktop Entry]
+Name=KBattleship
+Name[af]=Kbattleship
+Name[ar]=لعبة سفينة الحرب (KBattleship)
+Name[be]=Марскі бой
+Name[bn]=কে-ব্যাটেলশীপ
+Name[cs]=Lodě
+Name[de]=Schiffe versenken
+Name[hi]=के-बैटलशिप
+Name[hr]=KPotapanje brodova
+Name[is]=KSjóorrusta
+Name[nds]=Scheep versenken
+Name[ne]=केडीई ब्याटलसीप
+Name[pa]=ਕੇ-ਜੰਗੀ ਜਹਾਜ਼
+Name[ro]=Bătălie navală
+Name[sl]=KBojnaLadja
+Name[sv]=Kbattleship
+Name[ta]=கேபாட்டில்ஷிப்
+Name[tg]=KҶанги Киштиҳо
+Name[th]=เรือรบ - K
+Name[tr]=Amiral Battı
+Name[zh_TW]=KBattleship 戰艦
+Exec=kbattleship %i %m -caption "%c"
+Icon=kbattleship
+Type=Application
+DocPath=kbattleship/index.html
+GenericName=Battleship Game
+GenericName[be]=Гульня ў марскі бой
+GenericName[bg]=Морски шах
+GenericName[bn]=ব্যাটেলশীপ খেলা
+GenericName[bs]=Igra podmornica
+GenericName[ca]=Joc d'enfonsar la flota
+GenericName[cs]=Bitva lodí
+GenericName[cy]=Gêm Longau Rhyfel
+GenericName[da]=Krigsskibe-spil
+GenericName[de]=Schiffe versenken
+GenericName[el]=Παιχνίδι Battleship
+GenericName[eo]=Batalŝipa ludo
+GenericName[es]=Juego de la batalla de naves
+GenericName[et]=Laevade pommitamise mäng
+GenericName[eu]=Ontzi-guda jokoa
+GenericName[fa]=بازی Battleship
+GenericName[fi]=Meritaistelupeli
+GenericName[fr]=Jeu de bataille navale
+GenericName[he]=משחק צוללות
+GenericName[hr]=Igra potapanja brodova
+GenericName[hu]=Torpedós
+GenericName[is]=Sjóorustuleikur
+GenericName[it]=Gioco a battaglia navale
+GenericName[ja]=戦艦ゲーム
+GenericName[km]=ល្បែង​នាវា​ចម្បាំង
+GenericName[ko]=전함 게임
+GenericName[lt]=Laivų mūšio žaidimas
+GenericName[lv]=Jūras kaujas spēle
+GenericName[mk]=Игра со потопување бродови
+GenericName[nb]=Slagskip
+GenericName[nds]=Scheep versenken
+GenericName[ne]=ब्याटलसीप खेल
+GenericName[nl]=Zeeslagspel
+GenericName[nn]=Slagskip
+GenericName[pa]=ਜੰਗੀ ਜਹਾਜ਼ ਖੇਡ
+GenericName[pl]=Gra w statki
+GenericName[pt]=Jogo de Batalha Naval
+GenericName[pt_BR]=Jogo de Batalha Naval
+GenericName[ru]=Морской бой
+GenericName[sk]=Bojová loď hra
+GenericName[sl]=Igra potapljanja ladjic
+GenericName[sr]=Игра подморница
+GenericName[sr@Latn]=Igra podmornica
+GenericName[sv]=Sänka fartyg spel
+GenericName[ta]=போர்த்தள விளையாட்டு
+GenericName[uk]=Гра в морський бій
+GenericName[zh_TW]=戰艦遊戲
+Terminal=false
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Game;StrategyGame;
diff --git a/kbattleship/kbattleship/kbattleship.h b/kbattleship/kbattleship/kbattleship.h
new file mode 100644
index 00000000..7e606140
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleship.h
@@ -0,0 +1,162 @@
+/***************************************************************************
+ kbattleship.h
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBATTLESHIP_H
+#define KBATTLESHIP_H
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmainwindow.h>
+#include <kmenubar.h>
+#include <kmessagebox.h>
+#include <kstdaction.h>
+
+#include <qstring.h>
+
+#include "dialogs/infoDlg.h"
+
+#include "kbaiplayer.h"
+#include "kbattleshipclient.h"
+#include "kbattleshipserver.h"
+#include "kbattleshipview.h"
+#include "kchatwidget.h"
+#include "kclientdialog.h"
+#include "konnectionhandling.h"
+#include "kserverdialog.h"
+#include "kship.h"
+#include "kshiplist.h"
+#include "kstatdialog.h"
+
+class KBattleshipWindow : public KMainWindow
+{
+ Q_OBJECT
+public:
+ enum{ID_STATUS_MSG, ID_PLAYER_OWN, ID_PLAYER_ENEMY};
+ KBattleshipWindow();
+ ~KBattleshipWindow();
+
+ void init();
+
+ KShip *shipAt(int fieldx, int fieldy);
+ KShip *enemyShipAt(int fieldx, int fieldy);
+
+private slots:
+ void changeShipPlacementDirection();
+ void slotConfigureNotifications();
+ void slotLost(KMessage *msg);
+ void slotStatusMsg(const QString &text);
+ void slotReceivedEnemyFieldData(int fieldx, int fieldx1, int enemystate, int xstart, int xstop, int ystart, int ystop, bool death);
+ void slotSendEnemyFieldState(int, int);
+ void slotChangeOwnPlayer(const QString &text);
+ void slotChangeEnemyPlayer(const QString &text);
+ void slotSendVersion();
+ void slotSendGreet();
+ void slotShipsReady();
+ void slotSetPlaceable(bool place);
+ void slotSetShootable(bool shoot);
+ void slotEnemyFieldClick(int fieldx, int fieldy);
+ void slotSendMessage(int fieldx, int fieldy, int state);
+ void slotSendMessage(KMessage *msg);
+ void slotClientLost();
+ void slotServerLost();
+ void slotServerReplay();
+ void slotClientReplay();
+ void slotAIReady();
+ void slotAIShootsAt(const QPoint pos);
+ void slotDeleteAI();
+ void slotRestartAI();
+ void slotSinglePlayer();
+ void slotServerConnect();
+ void slotDeleteConnectDialog();
+ void slotNewServer();
+ void slotDeleteServerDialog();
+ void slotHighscore();
+ void slotShowGrid();
+ void slotStartBattleshipGame();
+ void slotStartBattleshipGame(bool clearstat);
+ void slotStartBattleshipServer();
+ /**
+ * Get server to connect to from "Connect to server" dialog.
+ */
+ void slotConnectToBattleshipServer();
+ void slotConnectToBattleshipServer(const QString &host, int port, const QString &nickname);
+ void slotPlaceShipPreview(int fieldx, int fieldy);
+ void slotPlaceShip(int fieldx, int fieldy);
+ void slotChangeOwnFieldData(int fieldx, int fieldy, int type);
+ void slotChangeEnemyFieldData(int fieldx, int fieldy, int type);
+ void slotUpdateHighscore();
+ void slotAbortNetworkGame();
+ void slotReplay();
+ void slotReplayRequest();
+ void slotChangedNickCommand(const QString &text);
+ void slotSendChatMessage(const QString &text);
+ void slotEnemyClientInfo();
+ void slotReceivedClientInformation(const QString &client, const QString &clientVersion, const QString &clientInformation, const QString &protocolVersion);
+
+private:
+ bool shift;
+ void initActions();
+ void initStatusBar();
+ void initView();
+ void initChat();
+ void initShipPlacing();
+ void saveOptions();
+ void readOptions();
+
+ void cleanup(bool placechange = true);
+ void playSound(bool enemy, int fieldstate);
+ void parseCommandLine();
+
+ bool m_placeable;
+ bool m_shootable;
+ bool m_aiPlaying;
+ bool m_serverHasClient;
+ bool m_lost;
+ int m_aiHits;
+
+ QString m_enemyClient;
+ QString m_enemyClientVersion;
+ QString m_enemyClientDescription;
+ QString m_enemyProtocolVersion;
+
+ KConfig *m_config;
+ KBAIPlayer *m_aiPlayer;
+ KonnectionHandling *m_connection;
+ KBattleshipServer *m_kbserver;
+ KBattleshipClient *m_kbclient;
+ KChatWidget *m_chat;
+ KStatDialog *m_stat;
+ KBattleshipView *m_view;
+ KAction *m_gameServerConnect;
+ KAction *m_gameNewServer;
+ KAction *m_gameQuit;
+ KAction *m_gameEnemyInfo;
+ KAction *m_gameSingle;
+ KToggleAction *m_configSound;
+ KToggleAction *m_configGrid;
+ KClientDialog *m_client;
+ KServerDialog *m_server;
+ KShipList *m_ownshiplist;
+ KShipList *m_enemyshiplist;
+ QString m_ownNickname;
+ QString m_enemyNickname;
+
+};
+#endif
diff --git a/kbattleship/kbattleship/kbattleshipclient.cpp b/kbattleship/kbattleship/kbattleshipclient.cpp
new file mode 100644
index 00000000..d8ae2a75
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleshipclient.cpp
@@ -0,0 +1,84 @@
+/***************************************************************************
+ kbattleshipclient.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+#include <sys/ioctl.h>
+#include <qsocketnotifier.h>
+#include "kmessage.h"
+#include "kbattleshipclient.moc"
+
+KBattleshipClient::KBattleshipClient(const QString &host, int port) : KExtendedSocket(host, port, inetSocket)
+{
+}
+
+void KBattleshipClient::init()
+{
+ if(connect())
+ {
+ emit sigSocketFailure(status());
+ return;
+ }
+
+ m_readNotifier = new QSocketNotifier(fd(), QSocketNotifier::Read, this);
+ QObject::connect(m_readNotifier, SIGNAL(activated(int)), SLOT(slotReadData()));
+ emit sigConnected();
+}
+
+void KBattleshipClient::sendMessage(KMessage *msg)
+{
+ QCString post = msg->sendStream().utf8();
+ writeBlock(post.data(), post.length());
+ emit sigMessageSent(msg);
+}
+
+void KBattleshipClient::slotReadData()
+{
+ int len;
+ ioctl(fd(), FIONREAD, &len);
+ if(!len)
+ {
+ delete m_readNotifier;
+ m_readNotifier = 0;
+ emit sigEndConnect();
+ return;
+ }
+
+ char *buf = new char[len + 1];
+ readBlock(buf, len);
+ buf[len] = 0;
+ m_readBuffer += QString::fromUtf8(buf);
+ delete []buf;
+ int pos;
+ while ((pos = m_readBuffer.find("</kmessage>")) >= 0)
+ {
+ pos += 11; // Length of "</kmessage>"
+ KMessage *msg = new KMessage();
+ msg->setDataStream(m_readBuffer.left(pos));
+ m_readBuffer.remove(0, pos);
+ emit sigNewMessage(msg);
+ }
+}
diff --git a/kbattleship/kbattleship/kbattleshipclient.h b/kbattleship/kbattleship/kbattleshipclient.h
new file mode 100644
index 00000000..d69ec7f9
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleshipclient.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ kbattleshipclient.h
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBATTLESHIPCLIENT_H
+#define KBATTLESHIPCLIENT_H
+
+#include <kextsock.h>
+#include <qsocketnotifier.h>
+#include "kmessage.h"
+
+class KBattleshipClient : public KExtendedSocket
+{
+ Q_OBJECT
+public:
+ KBattleshipClient(const QString &host, int port);
+
+ void init();
+ void sendMessage(KMessage *msg);
+
+private slots:
+ void slotReadData();
+
+signals:
+ void sigConnected();
+ void sigEndConnect();
+ void sigSocketFailure(int);
+ void sigNewMessage(KMessage *);
+ void sigMessageSent(KMessage *);
+
+private:
+ QSocketNotifier *m_readNotifier;
+ QString m_readBuffer;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbattleshipserver.cpp b/kbattleship/kbattleship/kbattleshipserver.cpp
new file mode 100644
index 00000000..d03bd213
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleshipserver.cpp
@@ -0,0 +1,124 @@
+/***************************************************************************
+ kbattleshipserver.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <config.h>
+
+#include <unistd.h>
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+#include <sys/ioctl.h>
+#include <qtimer.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include "kbattleshipserver.moc"
+
+KBattleshipServer::KBattleshipServer(int port, const QString& name)
+ : KExtendedSocket(QString::null, port, inetSocket | passiveSocket), m_name(name)
+{
+ m_port = port;
+ m_serverSocket = 0;
+}
+
+void KBattleshipServer::init()
+{
+ if(listen())
+ {
+ KMessageBox::error(0L, i18n("Failed to bind to local port \"%1\"\n\nPlease check if another KBattleship server instance\nis running or another application uses this port.").arg(m_port));
+ emit sigServerFailure();
+ return;
+ }
+ m_service.setServiceName(m_name);
+ m_service.setType(BATTLESHIP_SERVICE);
+ m_service.setPort(m_port);
+ m_service.publishAsync();
+ m_connectNotifier = new QSocketNotifier(fd(), QSocketNotifier::Read, this);
+ QObject::connect(m_connectNotifier, SIGNAL(activated(int)), SLOT(slotNewConnection()));
+}
+
+void KBattleshipServer::slotNewConnection()
+{
+ KExtendedSocket *sock;
+ accept(sock);
+ if(sock && m_serverSocket == 0)
+ {
+ m_service.stop();
+ m_serverSocket = sock;
+ m_readNotifier = new QSocketNotifier(sock->fd(), QSocketNotifier::Read, this);
+ QObject::connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(slotReadClient()));
+ emit sigNewConnect();
+ }
+ else
+ delete sock;
+}
+
+void KBattleshipServer::slotReadClient()
+{
+ int len;
+ ioctl(m_serverSocket->fd(), FIONREAD, &len);
+ if(!len)
+ {
+ slotDiscardClient(i18n("The connection broke down!"), false, true);
+ return;
+ }
+
+ char *buf = new char[len + 1];
+ m_serverSocket->readBlock(buf, len);
+ buf[len] = 0;
+ m_readBuffer += QString::fromUtf8(buf);
+ delete []buf;
+ int pos;
+ while ((pos = m_readBuffer.find("</kmessage>")) >= 0)
+ {
+ pos += 11; // Length of "</kmessage>"
+ KMessage *msg = new KMessage();
+ msg->setDataStream(m_readBuffer.left(pos));
+ m_readBuffer.remove(0, pos);
+ emit sigNewMessage(msg);
+ }
+}
+
+void KBattleshipServer::sendMessage(KMessage *msg)
+{
+ QCString post = msg->sendStream().utf8();
+ m_serverSocket->writeBlock(post.data(), post.length());
+ emit sigMessageSent(msg);
+}
+
+void KBattleshipServer::slotDiscardClient(const QString &reason, bool kmversion, bool bemit)
+{
+ KMessage *msg = new KMessage(KMessage::DISCARD);
+ msg->addField("reason", reason);
+ if(kmversion)
+ msg->addField("kmversion", "true");
+ else
+ msg->addField("kmversion", "false");
+ QCString post = msg->sendStream().utf8();
+ m_serverSocket->writeBlock(post.data(), post.length());
+ delete msg;
+
+ delete m_readNotifier;
+ m_readNotifier = 0;
+ delete m_serverSocket;
+ m_serverSocket = 0;
+
+ if(bemit)
+ emit sigEndConnect();
+}
diff --git a/kbattleship/kbattleship/kbattleshipserver.h b/kbattleship/kbattleship/kbattleshipserver.h
new file mode 100644
index 00000000..46f815e0
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleshipserver.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ kbattleshipserver.h
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBATTLESHIPSERVER_H
+#define KBATTLESHIPSERVER_H
+
+#include <kextsock.h>
+#include <qsocketnotifier.h>
+#include <dnssd/publicservice.h>
+#include "kmessage.h"
+
+class KBattleshipServer : public KExtendedSocket
+{
+ Q_OBJECT
+public:
+ KBattleshipServer(int port, const QString& name);
+ void init();
+ void sendMessage(KMessage *msg);
+
+public slots:
+ void slotDiscardClient(const QString &reason, bool kmversion, bool bemit);
+
+private slots:
+ void slotNewConnection();
+ void slotReadClient();
+
+signals:
+ void sigServerFailure();
+ void sigNewConnect();
+ void sigEndConnect();
+ void sigNewMessage(KMessage *);
+ void sigMessageSent(KMessage *);
+
+private:
+ QSocketNotifier *m_connectNotifier;
+ QSocketNotifier *m_readNotifier;
+ KExtendedSocket *m_serverSocket;
+ QString m_readBuffer;
+ DNSSD::PublicService m_service;
+ int m_port;
+ QString m_name;
+};
+
+#define BATTLESHIP_SERVICE "_kbattleship._tcp"
+
+#endif
diff --git a/kbattleship/kbattleship/kbattleshipui.rc b/kbattleship/kbattleship/kbattleshipui.rc
new file mode 100644
index 00000000..491fbb03
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleshipui.rc
@@ -0,0 +1,17 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kbattleship" version="2">
+
+<MenuBar>
+ <Menu name="game"><text>&amp;Game</text>
+ <Action name="game_serverconnect" append="new_merge"/>
+ <Action name="game_newserver" append="new_merge"/>
+ <Action name="game_singleplayer" append="new_merge"/>
+ <Action name="game_enemyinfo" append="misc_merge"/>
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="options_show_grid" append="show_merge"/>
+ <Action name="options_configure_sound" append="save_merge"/>
+ </Menu>
+</MenuBar>
+
+</kpartgui>
diff --git a/kbattleship/kbattleship/kbattleshipview.cpp b/kbattleship/kbattleship/kbattleshipview.cpp
new file mode 100644
index 00000000..86e8cbf6
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleshipview.cpp
@@ -0,0 +1,295 @@
+/***************************************************************************
+ kbattleshipview.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qlayout.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include "kbattleship.h"
+#include "kbattleshipview.moc"
+
+KBattleshipView::KBattleshipView(QWidget *parent, const char *name, bool draw)
+ : QWidget(parent, name, WResizeNoErase), m_drawGrid(draw)
+{
+ setFixedSize(20 * 32 + 30, 10 * 32 + 20);
+ setBackgroundMode(NoBackground);
+ setMouseTracking(true);
+ installEventFilter(this);
+
+ m_decide = false;
+ m_lastX = 0;
+ m_lastY = 0;
+ m_battlefield = 0;
+}
+
+KBattleshipView::~KBattleshipView()
+{
+ delete m_battlefield;
+}
+
+void KBattleshipView::startDrawing()
+{
+ m_battlefield = new KBattleField(this, m_drawGrid);
+}
+
+void KBattleshipView::clearField()
+{
+ m_battlefield->clearOwnField();
+ m_battlefield->clearEnemyField();
+}
+
+int KBattleshipView::ownFieldState(int fieldx, int fieldy)
+{
+ return m_battlefield->ownState(fieldx, fieldy);
+}
+
+int KBattleshipView::enemyFieldState(int &fieldx, int &fieldy)
+{
+ return m_battlefield->enemyState(fieldx, fieldy);
+}
+
+void KBattleshipView::previewShip(int fieldx, int fieldy, int type, bool rotate)
+{
+ m_battlefield->setPreviewState(fieldx, fieldy, type, rotate);
+}
+
+void KBattleshipView::changeOwnFieldData(int fieldx, int fieldy, int type)
+{
+ m_battlefield->setOwnState(fieldx, fieldy, type);
+ m_battlefield->drawField();
+}
+
+void KBattleshipView::changeEnemyFieldData(int fieldx, int fieldy, int type)
+{
+ m_battlefield->setEnemyState(fieldx, fieldy, type);
+ m_battlefield->drawField();
+}
+
+void KBattleshipView::drawEnemyShipsAI(KShipList *list)
+{
+ KShip *ship;
+ int state;
+ int grid = m_battlefield->gridSize();
+ int width = m_battlefield->enemyRect().width() / grid;
+ int height = m_battlefield->enemyRect().height() / grid;
+
+ for(int i = 0; i < width; i++)
+ {
+ for(int j = 0; j < height; j++)
+ {
+ ship = list->shipAt(i, j);
+ state = enemyFieldState(i, j);
+ if (ship && state != KBattleField::HIT && state != KBattleField::DEATH)
+ {
+ changeEnemyFieldData(i, j, ship->shipTypeEnum(i, j));
+ }
+ }
+ }
+}
+
+void KBattleshipView::drawEnemyShipsHuman(KMessage *msg, KShipList *list)
+{
+ int posx, posy, placedLeft;
+ bool left;
+ int i = 3;
+ while (!msg->field(QString("ship%1").arg(i)).isNull())
+ {
+ posx = msg->field(QString("ship%1").arg(i)).section(" ", 0, 0).toInt();
+ posy = msg->field(QString("ship%1").arg(i)).section(" ", 1, 1).toInt();
+ placedLeft = msg->field(QString("ship%1").arg(i)).section(" ", 2, 2).toInt();
+ if (placedLeft == 0) left = false;
+ else left = true;
+ list->addNewShip(!left, posx, posy);
+ i--;
+ }
+ drawEnemyShipsAI(list);
+}
+
+KMessage *KBattleshipView::getAliveShips(KShipList *list)
+{
+ KShip *ship;
+ QString shipPos, shipNum;
+ int shipType;
+ int grid = m_battlefield->gridSize();
+ int width = m_battlefield->enemyRect().width() / grid;
+ int height = m_battlefield->enemyRect().height() / grid;
+ KMessage *msg = new KMessage(KMessage::WON);
+ bool shipsFound[4] = {false, false, false, false};
+
+ for(int i = 0; i < width; i++)
+ {
+ for(int j = 0; j < height; j++)
+ {
+ ship = list->shipAt(i, j);
+ shipType = list->shipTypeAt(i, j);
+ if (ship && !shipsFound[shipType])
+ {
+ shipPos.sprintf("%d %d %d", i, j, ship->placedLeft());
+ shipsFound[shipType] = true;
+ shipNum.sprintf("ship%d",shipType);
+ msg->addField(shipNum, shipPos);
+ }
+ }
+ }
+ return msg;
+}
+
+bool KBattleshipView::eventFilter(QObject *object, QEvent *event)
+{
+ if(event->type() == QEvent::KeyPress && m_decide)
+ {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ if(keyEvent->key() == Key_Shift){
+ emit sigMouseOverField(m_lastX, m_lastY);
+ emit changeShipPlacementDirection();
+ }
+ }
+ else if(event->type() == QEvent::KeyRelease && m_decide)
+ {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ if(keyEvent->key() == Key_Shift){
+ emit sigMouseOverField(m_lastX, m_lastY);
+ emit changeShipPlacementDirection();
+ }
+ }
+ else if(event->type() == QEvent::MouseButtonRelease)
+ {
+ m_decide = false;
+
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+
+ if(mouseEvent->button() == RightButton){
+ emit sigMouseOverField(m_lastX, m_lastY);
+ emit changeShipPlacementDirection();
+ return true;
+ }
+
+ if(mouseEvent->button() != LeftButton)
+ return false;
+
+ QPoint point(mouseEvent->x(), mouseEvent->y());
+ QRect ownRect = m_battlefield->ownRect();
+ QRect enemyRect = m_battlefield->enemyRect();
+
+ QRect newRect;
+
+ int fieldx = 0;
+ int fieldy = 0;
+
+ if(ownRect.contains(point))
+ newRect = ownRect;
+ else if(enemyRect.contains(point))
+ newRect = enemyRect;
+ else
+ return false;
+
+ int j = -1;
+
+ for(int i = newRect.left(); i <= newRect.right(); i += m_battlefield->gridSize())
+ {
+ j++;
+ QRect tempRect(i, newRect.top(), m_battlefield->gridSize(), newRect.bottom() - newRect.top());
+
+ if(tempRect.contains(point))
+ {
+ fieldx = j;
+ break;
+ }
+ }
+
+ j = -1;
+
+ for(int i = newRect.top(); i <= newRect.bottom(); i += m_battlefield->gridSize())
+ {
+ j++;
+ QRect tempRect(newRect.left(), i, newRect.right() - newRect.left(), m_battlefield->gridSize());
+
+ if(tempRect.contains(point))
+ {
+ fieldy = j;
+ break;
+ }
+ }
+
+ if( newRect == ownRect)
+ emit sigOwnFieldClicked(fieldx, fieldy);
+ else if(newRect == enemyRect)
+ emit sigEnemyFieldClicked(fieldx, fieldy);
+
+ return true;
+ }
+ else if(event->type() == QEvent::MouseMove)
+ {
+ setFocus();
+ m_decide = true;
+
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+
+ QPoint point(mouseEvent->x(), mouseEvent->y());
+ QRect ownRect = m_battlefield->ownRect();
+
+ int fieldx = 0;
+ int fieldy = 0;
+
+ if(ownRect.contains(point))
+ {
+ int j = -1;
+
+ for(int i = ownRect.left(); i <= ownRect.right(); i += m_battlefield->gridSize())
+ {
+ j++;
+ QRect tempRect(i, ownRect.top(), m_battlefield->gridSize(), ownRect.bottom() - ownRect.top());
+
+ if(tempRect.contains(point))
+ {
+ fieldx = j;
+ break;
+ }
+ }
+
+ j = -1;
+
+ for(int i = ownRect.top(); i <= ownRect.bottom(); i += m_battlefield->gridSize())
+ {
+ j++;
+ QRect tempRect(ownRect.left(), i, ownRect.right() - ownRect.left(), m_battlefield->gridSize());
+
+ if(tempRect.contains(point))
+ {
+ fieldy = j;
+ break;
+ }
+ }
+
+ m_lastX = fieldx;
+ m_lastY = fieldy;
+
+ emit sigMouseOverField(fieldx, fieldy);
+ }
+ else
+ m_battlefield->drawField();
+
+ return true;
+ }
+ else if(event->type() == QEvent::Paint)
+ {
+ m_battlefield->drawField();
+ return true;
+ }
+
+ return QWidget::eventFilter(object, event);
+}
diff --git a/kbattleship/kbattleship/kbattleshipview.h b/kbattleship/kbattleship/kbattleshipview.h
new file mode 100644
index 00000000..f7f0a953
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleshipview.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ kbattleshipview.h
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBATTLESHIPVIEW_H
+#define KBATTLESHIPVIEW_H
+
+#include <kmainwindow.h>
+
+#include <qpainter.h>
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qwidget.h>
+
+#include "kbattlefield.h"
+#include "kmessage.h"
+#include "kship.h"
+#include "kshiplist.h"
+
+class KBattleshipView : public QWidget
+{
+ Q_OBJECT
+public:
+ KBattleshipView(QWidget *parent = 0, const char *name = 0, bool draw = false);
+ ~KBattleshipView();
+
+ KBattleField *field() { return m_battlefield; }
+
+ void startDrawing();
+ void clearField();
+ void changeOwnFieldData(int fieldx, int fieldy, int type);
+ void changeEnemyFieldData(int fieldx, int fieldy, int type);
+
+ void previewShip(int fieldx, int fieldy, int type, bool rotate);
+
+ int ownFieldState(int fieldx, int fieldy);
+ int enemyFieldState(int &fieldx, int &fieldy);
+
+ void drawEnemyShipsAI(KShipList *list);
+ void drawEnemyShipsHuman(KMessage *msg, KShipList *list);
+ KMessage *getAliveShips(KShipList *list);
+
+signals:
+ void sigEnemyFieldClicked(int, int);
+ void sigOwnFieldClicked(int, int);
+ void sigMouseOverField(int, int);
+ void changeShipPlacementDirection();
+
+private:
+ bool eventFilter(QObject *object, QEvent *event);
+
+ KBattleField *m_battlefield;
+ bool m_drawGrid;
+ bool m_decide;
+ int m_lastX;
+ int m_lastY;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbchooserstrategy.cpp b/kbattleship/kbattleship/kbchooserstrategy.cpp
new file mode 100644
index 00000000..f365c6d1
--- /dev/null
+++ b/kbattleship/kbattleship/kbchooserstrategy.cpp
@@ -0,0 +1,139 @@
+/***************************************************************************
+ kbchooserstrategy.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kbchooserstrategy.h"
+
+#include <kapplication.h>
+
+#include "kbrandomshotstrategy.h"
+#include "kbdiagonalwrapstrategy.h"
+#include "kbhorizontalstepstrategy.h"
+#include "kbverticalstepstrategy.h"
+
+#define MAX_CHILD_NUM 4
+
+KBChooserStrategy::KBChooserStrategy(KBStrategy *parent) : KBStrategy(parent)
+{
+ m_destroyer = new KBDestroyShipStrategy(this);
+ m_destroying = false;
+
+ m_child = 0;
+
+ m_random = new KRandomSequence(KApplication::random());
+}
+
+KBChooserStrategy::~KBChooserStrategy()
+{
+ delete m_destroyer;
+ delete m_child;
+ delete m_random;
+}
+
+void KBChooserStrategy::init(KBattleField *field, const QRect &field_rect)
+{
+ KBStrategy::init(field, field_rect);
+
+ if(m_destroyer != 0)
+ m_destroyer->init(field, field_rect);
+
+ advance();
+}
+
+const QPoint KBChooserStrategy::nextShot()
+{
+ if(hasMoreShots())
+ {
+ if(m_destroying)
+ return m_destroyer->nextShot();
+ else if(advance())
+ return m_child->nextShot();
+ }
+
+ return QPoint(0, 0);
+}
+
+bool KBChooserStrategy::advance()
+{
+ if(!m_destroying && m_prevShots.count() % 5 == 0)
+ {
+ delete m_child;
+
+ switch(m_random->getLong(MAX_CHILD_NUM))
+ {
+ case 0:
+ m_child = new KBVerticalStepStrategy(this);
+ break;
+
+ case 1:
+ m_child = new KBHorizontalStepStrategy(this);
+ break;
+
+ case 2:
+ m_child = new KBDiagonalWrapStrategy(this);
+ break;
+
+ default:
+ m_child = new KBRandomShotStrategy(this);
+ break;
+ }
+
+ m_child->init(m_battleField, m_fieldRect);
+ }
+
+ return true;
+}
+
+bool KBChooserStrategy::hasMoreShots()
+{
+ if(m_parent == 0)
+ {
+ if((!m_destroying) && m_prevShots.count() > 0)
+ {
+ QPoint pos = m_prevShots.last();
+ int state = m_battleField->ownState(pos.x(), pos.y());
+ if(state == KBattleField::HIT)
+ {
+ m_destroying = true;
+ m_destroyer->destroyShipAt(pos);
+ }
+ }
+
+ if(m_destroying)
+ {
+ if(m_destroyer->hasMoreShots())
+ return true;
+ else
+ m_destroying = false;
+ }
+ }
+
+ for(int row = 0; row < m_fieldRect.height(); row++)
+ {
+ for(int col = 0; col < m_fieldRect.width(); col++)
+ {
+ if(enemyFieldStateAt(col, row) != KBStrategy::SHOT)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void KBChooserStrategy::shotAt(const QPoint &pos)
+{
+ m_prevShots.append(pos);
+ m_child->shotAt(pos);
+}
diff --git a/kbattleship/kbattleship/kbchooserstrategy.h b/kbattleship/kbattleship/kbchooserstrategy.h
new file mode 100644
index 00000000..298cbe68
--- /dev/null
+++ b/kbattleship/kbattleship/kbchooserstrategy.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ kbchooserstrategy.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBCHOOSERSTRATEGY_H
+#define KBCHOOSERSTRATEGY_H
+
+#include <krandomsequence.h>
+
+#include "kbstrategy.h"
+#include "kbdestroyshipstrategy.h"
+
+class KBChooserStrategy : public KBStrategy
+{
+public:
+ KBChooserStrategy(KBStrategy *parent = 0);
+ virtual ~KBChooserStrategy();
+
+ virtual void init(KBattleField *field, const QRect &field_rect);
+ virtual const QPoint nextShot();
+ virtual bool hasMoreShots();
+ virtual void shotAt(const QPoint &pos);
+
+private:
+ bool advance();
+
+ KBStrategy *m_child;
+ KBDestroyShipStrategy *m_destroyer;
+ KRandomSequence *m_random;
+
+ bool m_destroying;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbdestroyshipstrategy.cpp b/kbattleship/kbattleship/kbdestroyshipstrategy.cpp
new file mode 100644
index 00000000..714bdd7c
--- /dev/null
+++ b/kbattleship/kbattleship/kbdestroyshipstrategy.cpp
@@ -0,0 +1,390 @@
+/***************************************************************************
+ kbdestroyshipstrategy.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+ (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kbdestroyshipstrategy.h"
+
+KBDestroyShipStrategy::KBDestroyShipStrategy(KBStrategy *parent) : KBStrategy(parent)
+{
+ m_working = false;
+}
+
+void KBDestroyShipStrategy::init(KBattleField *field, const QRect &field_rect)
+{
+ KBStrategy::init(field, field_rect);
+ m_working = false;
+}
+
+const QPoint KBDestroyShipStrategy::nextShot()
+{
+ if(hasMoreShots())
+ return QPoint(m_column, m_row);
+ else
+ return m_start;
+}
+
+bool KBDestroyShipStrategy::hasMoreShots()
+{
+ if(!m_working)
+ return false;
+
+ if(shipDestroyed())
+ {
+ m_working = false;
+ markBorderingFields();
+ return false;
+ }
+
+ if(enemyFieldStateAt(m_column, m_row) != KBStrategy::SHOT)
+ return true;
+
+ // last shot was no success :(
+ if(m_battleField->ownState(m_column, m_row) == KBattleField::WATER)
+ {
+ m_column = m_start.x();
+ m_row = m_start.y();
+ }
+
+ switch(m_direction)
+ {
+ case VERTICAL:
+ if(searchUp() || searchDown())
+ return true;
+ else
+ {
+ //kdDebug << "KBDestroyShipStrategy: failed vertical search!" << endl;
+ m_working = false;
+ }
+ break;
+
+ case HORIZONTAL:
+ if(searchLeft() || searchRight())
+ return true;
+ else
+ {
+ //kdDebug << "KBDestroyShipStrategy: failed horizontal search!" << endl;
+ m_working = false;
+ }
+ break;
+
+ default:
+ int up = m_row > 0 ? m_battleField->ownState(m_column, m_row - 1) : -1;
+ int down = m_row < (m_fieldRect.height() - 1) ? m_battleField->ownState(m_column, m_row + 1) : -1;
+ int left = m_column > 0 ? m_battleField->ownState(m_column - 1, m_row) : -1;
+ int right = m_column < (m_fieldRect.width() - 1) ? m_battleField->ownState(m_column + 1, m_row) : -1;
+
+ if((up != -1 && up == KBattleField::HIT) || (down != -1 && down == KBattleField::HIT))
+ {
+ m_direction = VERTICAL;
+ return hasMoreShots();
+ }
+
+ if((left != -1 && left == KBattleField::HIT) || (right != -1 && right == KBattleField::HIT))
+ {
+ m_direction = HORIZONTAL;
+ return hasMoreShots();
+ }
+
+ if(searchUp() || searchDown() || searchLeft() || searchRight())
+ return true;
+ else
+ {
+ //kdDebug << "KBDestroyStrategy: ship unsinkable?" << endl;
+ m_working = false;
+ }
+ break;
+ }
+ return false;
+}
+
+void KBDestroyShipStrategy::shotAt(const QPoint &pos)
+{
+ m_prevShots.append(pos);
+}
+
+void KBDestroyShipStrategy::destroyShipAt(const QPoint pos)
+{
+ if(enemyFieldStateAt(pos.x(), pos.y()) == FREE || m_battleField->ownState(pos.x(), pos.y()) == KBattleField::DEATH || m_battleField->ownState(pos.x(), pos.y()) == KBattleField::WATER)
+ m_working = false;
+ else
+ {
+ m_working = true;
+ m_start = pos;
+ m_column = pos.x();
+ m_row = pos.y();
+ m_direction = NODIR;
+ }
+}
+
+bool KBDestroyShipStrategy::searchUp()
+{
+ int row = m_row;
+ int prevCol = m_column - 1;
+ int nextCol = m_column + 1;
+
+ while(row >= 0 && (m_row - row) < 4 && enemyFieldStateAt(m_column, row) == KBStrategy::SHOT)
+ {
+ if(m_battleField->ownState(m_column, row) == KBattleField::WATER)
+ return false;
+
+ row--;
+
+ bool leftOK = true;
+ bool rightOK = true;
+ if(prevCol >= 0)
+ leftOK = (enemyFieldStateAt(prevCol, row) == FREE) || (m_battleField->ownState(prevCol, row) == KBattleField::WATER);
+
+ if(nextCol < m_fieldRect.width())
+ rightOK = (enemyFieldStateAt(nextCol, row) == FREE) || (m_battleField->ownState(nextCol, row) == KBattleField::WATER);
+
+ if(!(rightOK && leftOK))
+ return false;
+ }
+
+ if(row < 0 || (m_row - row) >= 4)
+ return false;
+
+ m_row = row;
+ return true;
+}
+
+bool KBDestroyShipStrategy::searchDown()
+{
+ int row = m_row;
+ int prevCol = m_column - 1;
+ int nextCol = m_column + 1;
+
+ while(row < m_fieldRect.height() && (row - m_row) < 4 && enemyFieldStateAt(m_column, row) == KBStrategy::SHOT)
+ {
+ if(m_battleField->ownState(m_column, row) == KBattleField::WATER)
+ return false;
+
+ row++;
+
+ bool leftOK = true;
+ bool rightOK = true;
+ if(prevCol >= 0)
+ leftOK = (enemyFieldStateAt(prevCol, row) == FREE) || (m_battleField->ownState(prevCol, row) == KBattleField::WATER);
+
+ if(nextCol < m_fieldRect.width())
+ rightOK = (enemyFieldStateAt(nextCol, row) == FREE) || (m_battleField->ownState(nextCol, row) == KBattleField::WATER);
+
+ if(!(rightOK && leftOK))
+ return false;
+ }
+
+ if(row >= m_fieldRect.height() || (row - m_row) >= 4)
+ return false;
+
+ m_row = row;
+ return true;
+}
+
+bool KBDestroyShipStrategy::searchLeft()
+{
+ int col = m_column;
+ int prevRow = m_row - 1;
+ int nextRow = m_row + 1;
+
+ while(col >= 0 && (m_column - col) < 4 && enemyFieldStateAt(col, m_row) == KBStrategy::SHOT)
+ {
+ if(m_battleField->ownState(col, m_row) == KBattleField::WATER)
+ return false;
+
+ col--;
+
+ bool upOK = true;
+ bool downOK = true;
+ if(prevRow >= 0)
+ upOK = (enemyFieldStateAt(col, prevRow) == FREE) || (m_battleField->ownState(col, prevRow) == KBattleField::WATER);
+
+ if(nextRow < m_fieldRect.height())
+ downOK = (enemyFieldStateAt(col, nextRow) == FREE) || (m_battleField->ownState(col, nextRow) == KBattleField::WATER);
+
+ if(!(upOK && downOK))
+ return false;
+ }
+
+ if(col < 0 || (m_column - col) >= 4)
+ return false;
+
+ m_column = col;
+ return true;
+}
+
+bool KBDestroyShipStrategy::searchRight()
+{
+ int col = m_column;
+ int prevRow = m_row - 1;
+ int nextRow = m_row + 1;
+
+ while(col < m_fieldRect.width() && (col - m_column) < 4 && enemyFieldStateAt(col, m_row) == KBStrategy::SHOT)
+ {
+ if(m_battleField->ownState(col, m_row) == KBattleField::WATER)
+ return false;
+
+ col++;
+
+ bool upOK = true;
+ bool downOK = true;
+ if(prevRow >= 0)
+ upOK = (enemyFieldStateAt(col, prevRow) == FREE) || (m_battleField->ownState(col, prevRow) == KBattleField::WATER);
+
+ if(nextRow < m_fieldRect.height())
+ downOK = (enemyFieldStateAt(col, nextRow) == FREE) || (m_battleField->ownState(col, nextRow) == KBattleField::WATER);
+
+ if(!(upOK && downOK))
+ return false;
+ }
+
+ if(col >= m_fieldRect.width() || (col - m_column) >= 4)
+ return false;
+
+ m_column = col;
+ return true;
+}
+
+bool KBDestroyShipStrategy::shipDestroyed()
+{
+ int col = m_start.x();
+ int row = m_start.y();
+ int state = m_battleField->ownState(col, row);
+
+ while(m_direction != HORIZONTAL && row >= 0 && state != KBattleField::FREE && state != KBattleField::WATER)
+ {
+ if(enemyFieldStateAt(col, row) == SHIP)
+ return false;
+
+ row--;
+ if(row >= 0)
+ state = m_battleField->ownState(col, row);
+ }
+
+ row = m_start.y();
+ state = m_battleField->ownState(col, row);
+ while(m_direction != HORIZONTAL && row < m_fieldRect.height() && state != KBattleField::FREE && state != KBattleField::WATER)
+ {
+ if(enemyFieldStateAt(col, row) == SHIP)
+ return false;
+
+ row++;
+ if(row < m_fieldRect.height())
+ state = m_battleField->ownState(col, row);
+ }
+
+ row = m_start.y();
+ state = m_battleField->ownState(col, row);
+ while(m_direction != VERTICAL && col >= 0 && state != KBattleField::FREE && state != KBattleField::WATER)
+ {
+ if(enemyFieldStateAt(col, row) == SHIP)
+ return false;
+
+ col--;
+ if(col >= 0)
+ state = m_battleField->ownState(col, row);
+ }
+
+ col = m_start.x();
+ state = m_battleField->ownState(col, row);
+ while(m_direction != VERTICAL && col < m_fieldRect.width() && state != KBattleField::FREE && state != KBattleField::WATER)
+ {
+ if(enemyFieldStateAt(col, row) == SHIP)
+ return false;
+
+ col++;
+ if(col < m_fieldRect.width())
+ state = m_battleField->ownState(col, row);
+ }
+
+ return true;
+}
+
+void KBDestroyShipStrategy::markBorderingFields()
+{
+ int col = m_start.x();
+ int row = m_start.y();
+ int i,j;
+
+ if (m_direction == VERTICAL)
+ {
+ while (m_fieldRect.contains(col, row) &&
+ m_battleField->ownState(col, row) == KBattleField::HIT)
+ {
+ row--;
+ }
+ if (row >= 0)
+ { // above the ship
+ setViablePos(col, row, false);
+ }
+ row++;
+ i = col+1; // right of the ship
+ j = col-1; // left of the ship
+ while (m_fieldRect.contains(col, row) &&
+ m_battleField->ownState(col, row) == KBattleField::HIT)
+ {
+ if (m_fieldRect.contains(i, row))
+ setViablePos(i, row, false);
+ if (m_fieldRect.contains(j, row))
+ setViablePos(j, row, false);
+ setViablePos(col, row, false);
+ row++;
+ }
+ if (m_fieldRect.contains(col, row))
+ { // below the ship
+ setViablePos(col, row, false);
+ }
+ }
+ else if (m_direction == HORIZONTAL)
+ {
+ while (m_fieldRect.contains(col, row) &&
+ m_battleField->ownState(col, row) == KBattleField::HIT)
+ {
+ col--;
+ }
+ if (col >= 0)
+ { // left of the ship
+ setViablePos(col, row, false);
+ }
+ col++;
+ i = row+1; // below the ship
+ j = row-1; // above the ship
+ while (m_fieldRect.contains(col, row) &&
+ m_battleField->ownState(col, row) == KBattleField::HIT)
+ {
+ if (m_fieldRect.contains(col, i))
+ setViablePos(col, i, false);
+ if (m_fieldRect.contains(col, j))
+ setViablePos(col, j, false);
+ setViablePos(col, row, false);
+ col++;
+ }
+ if (m_fieldRect.contains(col, row))
+ { // right of the ship
+ setViablePos(col, row, false);
+ }
+ }
+ else
+ {
+ if (row > 0)
+ setViablePos(col, (row-1), false);
+ if (row < (m_fieldRect.height()-1))
+ setViablePos(col, (row+1), false);
+ if (col > 0)
+ setViablePos((col-1), row, false);
+ if (col < (m_fieldRect.width()-1))
+ setViablePos((col+1), row, false);
+ }
+}
diff --git a/kbattleship/kbattleship/kbdestroyshipstrategy.h b/kbattleship/kbattleship/kbdestroyshipstrategy.h
new file mode 100644
index 00000000..0fb6ca92
--- /dev/null
+++ b/kbattleship/kbattleship/kbdestroyshipstrategy.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ kbdestroyshipstratgey.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+ (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBDESTROYSHIPSTRATEGY_H
+#define KBDESTROYSHIPSTRATEGY_H
+
+#include "kbstrategy.h"
+
+class KBDestroyShipStrategy : public KBStrategy
+{
+public:
+ KBDestroyShipStrategy(KBStrategy *parent = 0);
+
+ virtual void init(KBattleField *field, const QRect &field_rect);
+ virtual const QPoint nextShot();
+ virtual bool hasMoreShots();
+ virtual void shotAt(const QPoint &pos);
+
+ virtual void destroyShipAt(const QPoint pos);
+
+private:
+ enum {NODIR, VERTICAL, HORIZONTAL};
+
+ bool m_working;
+ QPoint m_start;
+
+ int m_column;
+ int m_row;
+
+ int m_direction;
+
+ virtual bool searchUp();
+ virtual bool searchDown();
+ virtual bool searchLeft();
+ virtual bool searchRight();
+
+ virtual bool shipDestroyed();
+ virtual void markBorderingFields();
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbdiagonalshotstrategy.cpp b/kbattleship/kbattleship/kbdiagonalshotstrategy.cpp
new file mode 100644
index 00000000..f0e0d6c3
--- /dev/null
+++ b/kbattleship/kbattleship/kbdiagonalshotstrategy.cpp
@@ -0,0 +1,110 @@
+/***************************************************************************
+ kbdiagonalshotstrategy.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kbdiagonalshotstrategy.h"
+
+KBDiagonalShotStrategy::KBDiagonalShotStrategy(KBStrategy *parent) : KBStrategy(parent)
+{
+ m_column = 0;
+ m_row = 0;
+ m_vertical = 0;
+ m_horizontal = 0;
+}
+
+const QPoint KBDiagonalShotStrategy::nextShot()
+{
+ if(hasMoreShots())
+ return QPoint(m_column, m_row);
+
+ return QPoint(0,0);
+}
+
+bool KBDiagonalShotStrategy::advance()
+{
+ while (m_fieldRect.contains(m_column, m_row))
+ {
+ if(enemyFieldStateAt(m_column, m_row) != KBStrategy::SHOT)
+ return true;
+ m_column += m_horizontal;
+ m_row += m_vertical;
+ }
+
+ return false;
+}
+
+bool KBDiagonalShotStrategy::hasMoreShots()
+{
+ return advance();
+}
+
+void KBDiagonalShotStrategy::shotAt(const QPoint &pos)
+{
+ m_prevShots.append(pos);
+}
+
+void KBDiagonalShotStrategy::startAt(int col, int row, Direction dir)
+{
+ m_column = col;
+ m_row = row;
+
+ switch(dir)
+ {
+ case LEFTUP:
+ m_vertical = -1;
+ m_horizontal = -1;
+ break;
+
+ case LEFTDOWN:
+ m_vertical = 1;
+ m_horizontal = -1;
+ break;
+
+ case RIGHTUP:
+ m_vertical = -1;
+ m_horizontal = 1;
+ break;
+
+ case RIGHTDOWN:
+ m_vertical = 1;
+ m_horizontal = 1;
+ break;
+
+ default:
+ m_vertical = 0;
+ m_horizontal = 0;
+ break;
+ }
+}
+
+QPoint KBDiagonalShotStrategy::endPoint()
+{
+ int row = m_row;
+ int col = m_column;
+
+ if(m_vertical == 0 || m_horizontal == 0)
+ return QPoint(col, row);
+
+ while(m_fieldRect.contains(col, row))
+ {
+ row += m_vertical;
+ col += m_horizontal;
+ }
+
+ row -= m_vertical;
+ col -= m_horizontal;
+
+ return QPoint(col, row);
+}
diff --git a/kbattleship/kbattleship/kbdiagonalshotstrategy.h b/kbattleship/kbattleship/kbdiagonalshotstrategy.h
new file mode 100644
index 00000000..b7c9b086
--- /dev/null
+++ b/kbattleship/kbattleship/kbdiagonalshotstrategy.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ kbdiagonalshotstrategy.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBDIAGONALSHOTSTRATEGY_H
+#define KBDIAGONALSHOTSTRATEGY_H
+
+#include "kbstrategy.h"
+
+class KBDiagonalShotStrategy : public KBStrategy
+{
+public:
+ enum Direction {LEFTUP, LEFTDOWN, RIGHTUP, RIGHTDOWN};
+ KBDiagonalShotStrategy(KBStrategy *parent = 0);
+
+ virtual const QPoint nextShot();
+ virtual bool hasMoreShots();
+ virtual void shotAt(const QPoint &pos);
+ virtual void startAt(int col, int row, Direction dir);
+ virtual QPoint endPoint();
+
+private:
+ bool advance();
+
+ int m_row;
+ int m_column;
+ int m_vertical;
+ int m_horizontal;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbdiagonalwrapstrategy.cpp b/kbattleship/kbattleship/kbdiagonalwrapstrategy.cpp
new file mode 100644
index 00000000..7f88fb54
--- /dev/null
+++ b/kbattleship/kbattleship/kbdiagonalwrapstrategy.cpp
@@ -0,0 +1,320 @@
+/***************************************************************************
+ kbdiagonalwrapstrategy.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <krandomsequence.h>
+#include "kbdiagonalwrapstrategy.h"
+
+KBDiagonalWrapStrategy::KBDiagonalWrapStrategy(KBStrategy *parent) : KBStrategy(parent)
+{
+ m_child = new KBDiagonalShotStrategy(this);
+
+ if(parent == 0)
+ {
+ m_destroyer = new KBDestroyShipStrategy(this);
+ m_destroying = false;
+ }
+ else
+ {
+ m_destroyer = 0;
+ m_destroying = false;
+ }
+}
+
+KBDiagonalWrapStrategy::~KBDiagonalWrapStrategy()
+{
+ delete m_child;
+ delete m_destroyer;
+}
+
+void KBDiagonalWrapStrategy::init(KBattleField *field, const QRect &field_rect)
+{
+ KBStrategy::init(field, field_rect);
+ KRandomSequence rand;
+
+ m_column = (int) rand.getLong(m_fieldRect.width());
+ m_row = (int) rand.getLong(m_fieldRect.height());
+
+ switch(rand.getLong(4))
+ {
+ case 0:
+ m_direction = KBDiagonalShotStrategy::RIGHTDOWN;
+ m_row = 0;
+ break;
+
+ case 1:
+ m_direction = KBDiagonalShotStrategy::RIGHTUP;
+ m_column = 0;
+ break;
+
+ case 2:
+ m_direction = KBDiagonalShotStrategy::LEFTDOWN;
+ m_column = m_fieldRect.width() - 1;
+ break;
+
+ default:
+ m_direction = KBDiagonalShotStrategy::LEFTUP;
+ m_row = m_fieldRect.height() - 1;
+ break;
+ }
+
+ m_child->init(field, field_rect);
+ m_child->startAt(m_column, m_row, m_direction);
+
+ m_start = QPoint(m_column, m_row);
+
+ if(m_destroyer != 0)
+ m_destroyer->init(field, field_rect);
+}
+
+const QPoint KBDiagonalWrapStrategy::nextShot()
+{
+ if(hasMoreShots())
+ {
+ if(m_destroying)
+ return m_destroyer->nextShot();
+ else if(m_child != 0)
+ return m_child->nextShot();
+ }
+
+ return m_start;
+}
+
+bool KBDiagonalWrapStrategy::advance()
+{
+ switch(m_direction)
+ {
+ case KBDiagonalShotStrategy::RIGHTDOWN:
+ if(!advanceRightDown())
+ return false;
+ break;
+
+ case KBDiagonalShotStrategy::RIGHTUP:
+ if(!advanceRightUp())
+ return false;
+ break;
+
+ case KBDiagonalShotStrategy::LEFTDOWN:
+ if(!advanceLeftDown())
+ return false;
+ break;
+
+ case KBDiagonalShotStrategy::LEFTUP:
+ if(!advanceLeftUp())
+ return false;
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool KBDiagonalWrapStrategy::hasMoreShots()
+{
+ if(m_parent == 0 && !m_destroying && m_prevShots.count() > 0)
+ {
+ QPoint pos = m_prevShots.last();
+ int state = m_battleField->ownState(pos.x(), pos.y());
+ if(state == KBattleField::HIT)
+ {
+ m_destroying = true;
+ m_destroyer->destroyShipAt(pos);
+ }
+ }
+
+ if(m_destroying)
+ {
+ if(m_destroyer->hasMoreShots())
+ return true;
+ else
+ m_destroying = false;
+ }
+
+ if(!m_child->hasMoreShots())
+ return advance();
+
+ return true;
+}
+
+void KBDiagonalWrapStrategy::shotAt(const QPoint &pos)
+{
+ m_prevShots.append(pos);
+
+ if(m_child != 0)
+ m_child->shotAt(pos);
+}
+
+bool KBDiagonalWrapStrategy::advanceRightDown()
+{
+ int col;
+
+ if(m_column == 0 && m_row != 0)
+ {
+ // start next
+ m_row = 0;
+ m_column = (m_start.x() + 3) % m_fieldRect.width();
+ m_child->startAt(m_column, m_row, m_direction);
+
+ if(!m_child->hasMoreShots())
+ {
+ col = 0;
+ m_child->startAt(col, m_row, m_direction);
+ while(!m_child->hasMoreShots())
+ {
+ col++;
+ if(col >= m_fieldRect.width())
+ return false;
+
+ m_child->startAt(col, m_row, m_direction);
+ }
+ m_column = col;
+ }
+ m_start = QPoint(m_column, m_row);
+ }
+ else
+ {
+ //wrap;
+ m_column = 0;
+ m_row = m_child->endPoint().y();
+
+ m_child->startAt(m_column, m_row, m_direction);
+ }
+
+ return true;
+}
+
+bool KBDiagonalWrapStrategy::advanceRightUp()
+{
+ int row;
+
+ if(m_row == (m_fieldRect.height() - 1) && m_column != 0)
+ {
+ // start next
+ m_column = 0;
+ m_row = m_start.y() - 3;
+ m_row = m_row < 0 ? m_row + m_fieldRect.height() : m_row;
+
+ m_child->startAt(m_column, m_row, m_direction);
+
+ if(!m_child->hasMoreShots())
+ {
+ row = m_fieldRect.height() - 1;
+ m_child->startAt(m_column, row, m_direction);
+ while(!m_child->hasMoreShots())
+ {
+ row--;
+ if(row < 0)
+ return false;
+
+ m_child->startAt(m_column, row, m_direction);
+ }
+ m_row = row;
+ }
+ m_start = QPoint(m_column, m_row);
+ }
+ else
+ {
+ //wrap;
+ m_row = m_fieldRect.height() - 1;
+ m_column = m_child->endPoint().x();
+
+ m_child->startAt(m_column, m_row, m_direction);
+ }
+
+ return true;
+}
+
+bool KBDiagonalWrapStrategy::advanceLeftDown()
+{
+ int row;
+
+ if(m_row == 0 && m_column != (m_fieldRect.width()-1))
+ {
+ // start next
+ m_column = m_fieldRect.width() - 1;
+ m_row = (m_start.y() + 3) % m_fieldRect.height();
+
+ m_child->startAt(m_column, m_row, m_direction);
+
+ if(!m_child->hasMoreShots())
+ {
+ row = 0;
+ m_child->startAt(m_column, row, m_direction);
+ while(!m_child->hasMoreShots())
+ {
+ row++;
+ if(row >= m_fieldRect.height())
+ return false;
+
+ m_child->startAt(m_column, row, m_direction);
+ }
+ m_row = row;
+ }
+ m_start = QPoint(m_column, m_row);
+ }
+ else
+ {
+ //wrap;
+ m_row = 0;
+ m_column = m_child->endPoint().x();
+
+ m_child->startAt(m_column, m_row, m_direction);
+ }
+
+ return true;
+}
+
+bool KBDiagonalWrapStrategy::advanceLeftUp()
+{
+ int col;
+
+ if(m_column == (m_fieldRect.width()-1) && m_row != (m_fieldRect.height()-1))
+ {
+ // start next
+ m_row = m_fieldRect.height() - 1;
+ m_column = m_start.x() - 3;
+ m_column = m_column < 0 ? m_column + m_fieldRect.width() : m_column;
+
+ m_child->startAt(m_column, m_row, m_direction);
+
+ if(!m_child->hasMoreShots())
+ {
+ col = m_fieldRect.width() - 1;
+ m_child->startAt(col, m_row, m_direction);
+ while(!m_child->hasMoreShots())
+ {
+ col--;
+ if(col < 0)
+ return false;
+
+ m_child->startAt(col, m_row, m_direction);
+ }
+ m_column = col;
+ }
+ m_start = QPoint(m_column, m_row);
+ }
+ else
+ {
+ //wrap;
+ m_column = m_fieldRect.width() - 1;
+ m_row = m_child->endPoint().y();
+
+ m_child->startAt(m_column, m_row, m_direction);
+ }
+
+ return true;
+}
diff --git a/kbattleship/kbattleship/kbdiagonalwrapstrategy.h b/kbattleship/kbattleship/kbdiagonalwrapstrategy.h
new file mode 100644
index 00000000..06ff8f6a
--- /dev/null
+++ b/kbattleship/kbattleship/kbdiagonalwrapstrategy.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ kbdiagonalwrapstrategy.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBDIAGONALWRAPSTRATEGY_H
+#define KBDIAGONALWRAPSTRATEGY_H
+
+#include "kbstrategy.h"
+#include "kbdestroyshipstrategy.h"
+#include "kbdiagonalshotstrategy.h"
+
+class KBDiagonalWrapStrategy : public KBStrategy
+{
+public:
+ KBDiagonalWrapStrategy(KBStrategy *parent = 0);
+ virtual ~KBDiagonalWrapStrategy();
+
+ virtual void init(KBattleField *field, const QRect &field_rect);
+ virtual const QPoint nextShot();
+ virtual bool hasMoreShots();
+ virtual void shotAt(const QPoint &pos);
+
+private:
+ bool advance();
+ bool advanceRightDown();
+ bool advanceRightUp();
+ bool advanceLeftDown();
+ bool advanceLeftUp();
+
+ int m_row;
+ int m_column;
+
+ QPoint m_start;
+ KBDiagonalShotStrategy *m_child;
+ KBDiagonalShotStrategy::Direction m_direction;
+
+ KBDestroyShipStrategy *m_destroyer;
+ bool m_destroying;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbhorizontalstepstrategy.cpp b/kbattleship/kbattleship/kbhorizontalstepstrategy.cpp
new file mode 100644
index 00000000..080bc08e
--- /dev/null
+++ b/kbattleship/kbattleship/kbhorizontalstepstrategy.cpp
@@ -0,0 +1,210 @@
+/***************************************************************************
+ kbhorizontalstepstrategy.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <krandomsequence.h>
+#include "kbhorizontalstepstrategy.h"
+
+KBHorizontalStepStrategy::KBHorizontalStepStrategy(KBStrategy *parent) : KBStrategy(parent)
+{
+ m_child = 0;
+ if(parent == 0) // only the master destroys ships
+ {
+ m_destroyer = new KBDestroyShipStrategy(this);
+ m_destroying = false;
+ }
+ else
+ {
+ m_destroyer = 0;
+ m_destroying = false;
+ }
+}
+
+KBHorizontalStepStrategy::~KBHorizontalStepStrategy()
+{
+ delete m_child;
+ delete m_destroyer;
+}
+
+void KBHorizontalStepStrategy::init(KBattleField *field, const QRect &field_rect)
+{
+ KBStrategy::init(field, field_rect);
+ KRandomSequence rand;
+ m_column = (int) rand.getLong(m_fieldRect.width());
+ m_row = (int) rand.getLong(m_fieldRect.height());
+ m_start = QPoint(m_column, m_row);
+ m_passes = 0;
+
+ if(m_destroyer != 0)
+ m_destroyer->init(field, field_rect);
+}
+
+const QPoint KBHorizontalStepStrategy::nextShot()
+{
+ if(hasMoreShots())
+ {
+ if(m_destroying)
+ return m_destroyer->nextShot();
+ else if(m_passes == 0)
+ return QPoint(m_column, m_row);
+ else if(m_parent == 0)
+ return m_child->nextShot();
+ }
+
+ return m_start;
+}
+
+bool KBHorizontalStepStrategy::advance()
+{
+ int col, row;
+
+ col = m_column;
+ row = m_row;
+
+ while(enemyFieldStateAt(col, row) == KBStrategy::SHOT)
+ {
+ col += 2;
+ if(col >= m_fieldRect.width())
+ {
+ col = m_column % 2;
+ row = (row + 2) % m_fieldRect.height();
+ }
+
+ if(col == m_start.x() && row == m_start.y())
+ {
+ col = (col + 1) % m_fieldRect.width();
+ row = (row + 1) % m_fieldRect.height();
+ }
+ }
+
+ if(enemyFieldStateAt(col, row) != KBStrategy::SHOT)
+ {
+ m_column = col;
+ m_row = row;
+ return true;
+ }
+
+ return false;
+}
+
+void KBHorizontalStepStrategy::setStart(int col, int row)
+{
+ m_start = QPoint(col, row);
+ m_column = col;
+ m_row = row;
+}
+
+bool KBHorizontalStepStrategy::hasMoreShots()
+{
+ if(m_parent != 0)
+ {
+ // Child Strategy
+ if(m_passes == 0)
+ {
+ if(enemyFieldStateAt(m_column, m_row) != KBStrategy::SHOT)
+ return true;
+ else if(advance())
+ return true;
+ else
+ {
+ m_passes++;
+ return false;
+ }
+ }
+ else
+ return false;
+ }
+ else
+ {
+ // Parent Strategy
+ if((!m_destroying) && m_prevShots.count() > 0)
+ {
+ QPoint pos = m_prevShots.last();
+ int state = m_battleField->ownState(pos.x(), pos.y());
+ if(state == KBattleField::HIT)
+ {
+ m_destroying = true;
+ m_destroyer->destroyShipAt(pos);
+ }
+ }
+ if(m_destroying)
+ {
+ if(m_destroyer->hasMoreShots())
+ return true;
+ else
+ m_destroying = false;
+ }
+ }
+
+ int x, y;
+ switch(m_passes)
+ {
+ case 0:
+ if(enemyFieldStateAt(m_column, m_row) != KBStrategy::SHOT || advance())
+ return true;
+
+ m_passes++;
+ m_child = new KBHorizontalStepStrategy(this);
+ m_child->init(m_battleField, m_fieldRect);
+
+ x = (m_start.x() + 1) % m_fieldRect.width();
+ y = (m_start.y() + 1) % m_fieldRect.height();
+ m_child->setStart(x, y);
+
+ case 1:
+ if(m_child->hasMoreShots())
+ return true;
+
+ m_passes++;
+ delete m_child;
+
+ m_child = new KBHorizontalStepStrategy(this);
+ m_child->init(m_battleField, m_fieldRect);
+
+ x = (m_start.x() + 1) % m_fieldRect.width();
+ y = m_start.y();
+ m_child->setStart(x, y);
+
+ case 2:
+ if(m_child->hasMoreShots())
+ return true;
+
+ m_passes++;
+ delete m_child;
+
+ m_child = new KBHorizontalStepStrategy(this);
+ m_child->init(m_battleField, m_fieldRect);
+
+ x = (m_start.x() + 2) % m_fieldRect.width();
+ y = (m_start.y() + 1) % m_fieldRect.height();
+ m_child->setStart(x, y);
+
+ case 3:
+ if(m_child->hasMoreShots())
+ return true;
+
+ m_passes++;
+
+ default:
+ return false;
+ }
+}
+
+void KBHorizontalStepStrategy::shotAt(const QPoint &pos)
+{
+ m_prevShots.append(pos);
+ if(m_child != 0)
+ m_child->shotAt(pos);
+}
diff --git a/kbattleship/kbattleship/kbhorizontalstepstrategy.h b/kbattleship/kbattleship/kbhorizontalstepstrategy.h
new file mode 100644
index 00000000..4e68e4e7
--- /dev/null
+++ b/kbattleship/kbattleship/kbhorizontalstepstrategy.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ kbhorizontalstepstrategy.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBHORIZONTALSTEPSTRATEGY_H
+#define KBHORIZONTALSTEPSTRATEGY_H
+
+#include "kbstrategy.h"
+#include "kbdestroyshipstrategy.h"
+
+class KBHorizontalStepStrategy : public KBStrategy
+{
+public:
+ KBHorizontalStepStrategy(KBStrategy *parent = 0);
+ virtual ~KBHorizontalStepStrategy();
+
+ virtual void init(KBattleField *field, const QRect &field_rect);
+ virtual const QPoint nextShot();
+ virtual bool hasMoreShots();
+ virtual void shotAt(const QPoint &pos);
+
+private:
+ bool advance();
+ void setStart(int col, int row);
+
+ int m_row;
+ int m_column;
+ int m_passes;
+
+ QPoint m_start;
+ KBHorizontalStepStrategy *m_child;
+ KBDestroyShipStrategy *m_destroyer;
+ bool m_destroying;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbrandomshotstrategy.cpp b/kbattleship/kbattleship/kbrandomshotstrategy.cpp
new file mode 100644
index 00000000..a3748a69
--- /dev/null
+++ b/kbattleship/kbattleship/kbrandomshotstrategy.cpp
@@ -0,0 +1,102 @@
+/***************************************************************************
+ kbrandomshotstrategy.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kbrandomshotstrategy.h"
+
+KBRandomShotStrategy::KBRandomShotStrategy(KBStrategy *parent) : KBStrategy(parent)
+{
+ m_destroyer = new KBDestroyShipStrategy(this);
+ m_destroying = false;
+}
+
+KBRandomShotStrategy::~KBRandomShotStrategy()
+{
+ delete m_destroyer;
+}
+
+void KBRandomShotStrategy::init(KBattleField *field, const QRect &field_rect)
+{
+ KBStrategy::init(field, field_rect);
+ KRandomSequence rand;
+ m_column = (int) rand.getLong(m_fieldRect.width());
+ m_row = (int) rand.getLong(m_fieldRect.height());
+
+ if(m_destroyer != 0)
+ m_destroyer->init(field, field_rect);
+}
+
+const QPoint KBRandomShotStrategy::nextShot()
+{
+ if(hasMoreShots())
+ {
+ if(m_destroying)
+ return m_destroyer->nextShot();
+ else if(advance())
+ return QPoint(m_column, m_row);
+ }
+
+ return QPoint(0, 0);
+}
+
+bool KBRandomShotStrategy::advance()
+{
+ while(enemyFieldStateAt(m_column, m_row) == KBStrategy::SHOT)
+ {
+ m_column = m_randomSeq.getLong(m_fieldRect.width());
+ m_row = m_randomSeq.getLong(m_fieldRect.height());
+ }
+ return true;
+}
+
+bool KBRandomShotStrategy::hasMoreShots()
+{
+ if(m_parent == 0)
+ {
+ if((!m_destroying) && m_prevShots.count() > 0)
+ {
+ QPoint pos = m_prevShots.last();
+ int state = m_battleField->ownState(pos.x(), pos.y());
+ if(state == KBattleField::HIT)
+ {
+ m_destroying = true;
+ m_destroyer->destroyShipAt(pos);
+ }
+ }
+ if(m_destroying)
+ {
+ if(m_destroyer->hasMoreShots())
+ return true;
+ else
+ m_destroying = false;
+ }
+ }
+
+ for(int row = 0; row < m_fieldRect.height(); row++)
+ {
+ for(int col = 0; col < m_fieldRect.width(); col++)
+ {
+ if(enemyFieldStateAt(col, row) != KBStrategy::SHOT)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void KBRandomShotStrategy::shotAt(const QPoint &pos)
+{
+ m_prevShots.append(pos);
+}
diff --git a/kbattleship/kbattleship/kbrandomshotstrategy.h b/kbattleship/kbattleship/kbrandomshotstrategy.h
new file mode 100644
index 00000000..1e93cefa
--- /dev/null
+++ b/kbattleship/kbattleship/kbrandomshotstrategy.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ kbrandomshotstrategy.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBRANDOMSHOTSTRATEGY_H
+#define KBRANDOMSHOTSTRATEGY_H
+
+#include <krandomsequence.h>
+
+#include "kbstrategy.h"
+#include "kbdestroyshipstrategy.h"
+
+class KBRandomShotStrategy : public KBStrategy
+{
+public:
+ KBRandomShotStrategy(KBStrategy *parent = 0);
+ virtual ~KBRandomShotStrategy();
+
+ virtual void init(KBattleField *field, const QRect &field_rect);
+ virtual const QPoint nextShot();
+ virtual bool hasMoreShots();
+ virtual void shotAt(const QPoint &pos);
+
+private:
+ bool advance();
+
+ int m_row;
+ int m_column;
+
+ KRandomSequence m_randomSeq;
+ KBDestroyShipStrategy *m_destroyer;
+ bool m_destroying;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbstrategy.cpp b/kbattleship/kbattleship/kbstrategy.cpp
new file mode 100644
index 00000000..f8183cfd
--- /dev/null
+++ b/kbattleship/kbattleship/kbstrategy.cpp
@@ -0,0 +1,108 @@
+/***************************************************************************
+ kbstrategy.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+ (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kbstrategy.h"
+
+KBStrategy::KBStrategy(KBStrategy *parent)
+{
+ m_parent = parent;
+ m_viableShots = 0;
+}
+
+KBStrategy::~KBStrategy()
+{
+ while ( !m_prevShots.empty() )
+ {
+ m_prevShots.remove( m_prevShots.last() );
+ }
+ if (m_parent == 0 && m_viableShots != 0)
+ {
+ delete[] m_viableShots;
+ }
+}
+
+/* Returns the master strategy's shot list. */
+QValueList<QPoint> KBStrategy::masterShotList()
+{
+ return (!m_parent) ? m_prevShots : m_parent->masterShotList();
+}
+
+/* the AI player decided to shoot at pos */
+void KBStrategy::shotAt(const QPoint &pos)
+{
+ m_prevShots.append(pos);
+}
+
+void KBStrategy::init(KBattleField *field, const QRect &field_rect)
+{
+ m_battleField = field;
+ m_fieldRect = field_rect;
+ if (!m_parent)
+ {
+ if (m_viableShots == 0)
+ {
+ m_viableShots = new bool[(field_rect.width()*field_rect.height())];
+ }
+ for (int x = 0; x < field_rect.width(); ++x)
+ {
+ for (int y = 0; y < field_rect.height(); ++y)
+ {
+ //m_viableShots[x, y] = true;
+ setViablePos(x, y, true);
+ }
+ }
+ }
+ else
+ {
+ m_viableShots = m_parent->getViableShots();
+ }
+}
+
+/* Returns the field type of position (x, y) on the user player's field */
+int KBStrategy::enemyFieldStateAt(int x, int y)
+{
+ if (!isViablePos(x, y))
+ return SHOT; // faking SHOT if position is not possible ship position
+
+ switch(m_battleField->ownState(x, y))
+ {
+ case KBattleField::FREE:
+ return KBStrategy::FREE;
+ case KBattleField::WATER:
+ case KBattleField::HIT:
+ case KBattleField::DEATH:
+ return KBStrategy::SHOT;
+ default:
+ return KBStrategy::SHIP;
+ }
+}
+
+bool* KBStrategy::getViableShots()
+{
+ return m_viableShots;
+}
+
+bool KBStrategy::isViablePos(int x, int y)
+{
+ return m_viableShots[(m_fieldRect.width()*y + x)];
+}
+
+void KBStrategy::setViablePos(int x, int y, bool viable)
+{
+ m_viableShots[(m_fieldRect.width()*y + x)] = viable;
+}
+
diff --git a/kbattleship/kbattleship/kbstrategy.h b/kbattleship/kbattleship/kbstrategy.h
new file mode 100644
index 00000000..55707a17
--- /dev/null
+++ b/kbattleship/kbattleship/kbstrategy.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ kbstrategy.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+ (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBSTRATEGY_H
+#define KBSTRATEGY_H
+
+#include <qvaluelist.h>
+#include <qpoint.h>
+#include "kbattlefield.h"
+
+class KBStrategy
+{
+public:
+ enum{FREE, SHOT, SHIP};
+ KBStrategy(KBStrategy *parent = 0);
+ virtual ~KBStrategy();
+
+ virtual const QPoint nextShot() = 0;
+ virtual void shotAt(const QPoint &pos);
+ virtual void init(KBattleField *field, const QRect &field_rect);
+ virtual bool hasMoreShots() = 0;
+
+protected:
+ QValueList<QPoint> masterShotList();
+ int enemyFieldStateAt(int x, int y);
+ bool* getViableShots();
+
+ QRect m_fieldRect;
+ bool* m_viableShots;
+ bool isViablePos(int x, int y);
+ void setViablePos(int x, int y, bool viable);
+ QValueList<QPoint> m_prevShots;
+
+ KBattleField *m_battleField;
+ KBStrategy *m_parent;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kbverticalstepstrategy.cpp b/kbattleship/kbattleship/kbverticalstepstrategy.cpp
new file mode 100644
index 00000000..736e9ac8
--- /dev/null
+++ b/kbattleship/kbattleship/kbverticalstepstrategy.cpp
@@ -0,0 +1,214 @@
+/***************************************************************************
+ kbverticalstepstrategy.cpp
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+ (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <krandomsequence.h>
+#include "kbverticalstepstrategy.h"
+
+KBVerticalStepStrategy::KBVerticalStepStrategy(KBStrategy *parent) : KBStrategy(parent)
+{
+ m_child = 0;
+
+ if(parent == 0) // only the master destroys ships
+ {
+ m_destroyer = new KBDestroyShipStrategy(this);
+ m_destroying = false;
+ }
+ else
+ {
+ m_destroyer = 0;
+ m_destroying = false;
+ }
+}
+
+KBVerticalStepStrategy::~KBVerticalStepStrategy()
+{
+ delete m_child;
+ delete m_destroyer;
+}
+
+void KBVerticalStepStrategy::init(KBattleField *field, const QRect &field_rect)
+{
+ KBStrategy::init(field, field_rect);
+ KRandomSequence rand;
+ m_column = (int) rand.getLong(m_fieldRect.width());
+ m_row = (int) rand.getLong(m_fieldRect.height());
+ m_start = QPoint(m_column, m_row);
+ m_passes = 0;
+
+ if(m_destroyer != 0)
+ m_destroyer->init(field, field_rect);
+}
+
+const QPoint KBVerticalStepStrategy::nextShot()
+{
+ if(hasMoreShots())
+ {
+ if(m_destroying)
+ return m_destroyer->nextShot();
+ else if(m_passes == 0)
+ return QPoint(m_column, m_row);
+ else if(m_parent == 0)
+ return m_child->nextShot();
+ }
+
+ return m_start;
+}
+
+bool KBVerticalStepStrategy::advance()
+{
+ int col, row;
+
+ col = m_column;
+ row = m_row;
+
+ while(enemyFieldStateAt(col, row) == KBStrategy::SHOT)
+ {
+ row += 2;
+ if(row >= m_fieldRect.height())
+ {
+ row = m_row % 2;
+ col = (col + 2) % m_fieldRect.width();
+ }
+
+ if(col == m_start.x() && row == m_start.y())
+ {
+ col = (col + 1) % m_fieldRect.width();
+ row = (row + 1) % m_fieldRect.height();
+ }
+ }
+
+ if(enemyFieldStateAt(col, row) != KBStrategy::SHOT)
+ {
+ m_column = col;
+ m_row = row;
+ return true;
+ }
+
+ return false;
+}
+
+void KBVerticalStepStrategy::setStart(int col, int row)
+{
+ m_start = QPoint(col, row);
+ m_column = col;
+ m_row = row;
+}
+
+bool KBVerticalStepStrategy::hasMoreShots()
+{
+ if(m_parent != 0)
+ {
+ // Child Strategy
+ if(m_passes == 0)
+ {
+ if(enemyFieldStateAt(m_column, m_row) != KBStrategy::SHOT)
+ return true;
+ else if(advance())
+ return true;
+ else
+ {
+ m_passes++;
+ return false;
+ }
+ }
+ else
+ return false;
+ }
+ else
+ {
+ // Parent Strategy
+ if((!m_destroying) && m_prevShots.count() > 0)
+ {
+ QPoint pos = m_prevShots.last();
+ int state = m_battleField->ownState(pos.x(), pos.y());
+ if(state == KBattleField::HIT)
+ {
+ m_destroying = true;
+ m_destroyer->destroyShipAt(pos);
+ }
+ }
+ if(m_destroying)
+ {
+ if(m_destroyer->hasMoreShots())
+ return true;
+ else
+ m_destroying = false;
+ }
+
+ int x, y;
+ switch(m_passes)
+ {
+ case 0:
+ if(enemyFieldStateAt(m_column, m_row) != KBStrategy::SHOT)
+ return true;
+ else if (advance())
+ return true;
+
+ m_passes++;
+ m_child = new KBVerticalStepStrategy(this);
+ m_child->init(m_battleField, m_fieldRect);
+
+ x = (m_start.x() + 1) % m_fieldRect.width();
+ y = (m_start.y() + 1) % m_fieldRect.height();
+ m_child->setStart(x, y);
+
+ case 1:
+ if(m_child->hasMoreShots())
+ return true;
+
+ m_passes++;
+ delete m_child;
+
+ m_child = new KBVerticalStepStrategy(this);
+ m_child->init(m_battleField, m_fieldRect);
+
+ x = m_start.x();
+ y = (m_start.y() + 1) % m_fieldRect.height();
+ m_child->setStart(x, y);
+
+ case 2:
+ if(m_child->hasMoreShots())
+ return true;
+
+ m_passes++;
+ delete m_child;
+
+ m_child = new KBVerticalStepStrategy(this);
+ m_child->init(m_battleField, m_fieldRect);
+
+ x = (m_start.x() + 1) % m_fieldRect.width();
+ y = (m_start.y() + 2) % m_fieldRect.height();
+ m_child->setStart(x, y);
+
+ case 3:
+ if(m_child->hasMoreShots())
+ return true;
+
+ m_passes++;
+
+ default:
+ return false;
+ }
+ }
+}
+
+void KBVerticalStepStrategy::shotAt(const QPoint &pos)
+{
+ m_prevShots.append(pos);
+ if(m_child != 0)
+ m_child->shotAt(pos);
+}
diff --git a/kbattleship/kbattleship/kbverticalstepstrategy.h b/kbattleship/kbattleship/kbverticalstepstrategy.h
new file mode 100644
index 00000000..904fa68e
--- /dev/null
+++ b/kbattleship/kbattleship/kbverticalstepstrategy.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ kbverticalstepstrategy.h
+ ----------
+ Developers: (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+ (c) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KBVERTICALSTEPSTRATEGY_H
+#define KBVERTICALSTEPSTRATEGY_H
+
+#include "kbstrategy.h"
+#include "kbdestroyshipstrategy.h"
+
+class KBVerticalStepStrategy : public KBStrategy
+{
+public:
+ KBVerticalStepStrategy(KBStrategy *parent = 0);
+ virtual ~KBVerticalStepStrategy();
+
+ virtual void init(KBattleField *field, const QRect &field_rect);
+ virtual const QPoint nextShot();
+ virtual bool hasMoreShots();
+ virtual void shotAt(const QPoint &pos);
+
+private:
+ bool advance();
+ void setStart(int col, int row);
+
+ int m_row;
+ int m_column;
+ int m_passes;
+
+ QPoint m_start;
+ KBVerticalStepStrategy *m_child;
+ KBDestroyShipStrategy *m_destroyer;
+ bool m_destroying;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kchatwidget.cpp b/kbattleship/kbattleship/kchatwidget.cpp
new file mode 100644
index 00000000..6c4755c6
--- /dev/null
+++ b/kbattleship/kbattleship/kchatwidget.cpp
@@ -0,0 +1,83 @@
+/***************************************************************************
+ kchatwidget.cpp
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kapplication.h>
+#include "kchatwidget.moc"
+
+KChatWidget::KChatWidget(QWidget *parent, const char *name) : chatDlg(parent, name)
+{
+ connect(sendBtn, SIGNAL(clicked()), this, SLOT(slotComputeMessage()));
+ connect(commentEdit, SIGNAL(returnPressed()), this, SLOT(slotComputeMessage()));
+ chatView->setFocusProxy(commentEdit);
+ chatView->setMinimumSize(0, 50);
+ commentEdit->installEventFilter(this);
+
+ m_currentNickname = QString::null;
+ slotAcceptMsg(false);
+}
+
+void KChatWidget::clear()
+{
+ m_currentNickname = QString::null;
+ slotAcceptMsg(false);
+ chatView->clear();
+ commentEdit->clear();
+}
+
+void KChatWidget::slotAcceptMsg(bool value)
+{
+ m_acceptMsgs = value;
+}
+
+void KChatWidget::slotReceivedMessage(const QString &nickname, const QString &msg, bool fromenemy)
+{
+ // Niko Z:
+ // IRC roxxx :)
+ if(msg.startsWith("/me "))
+ chatView->append(QString(" * ") + nickname + QString(" ") + msg.mid(4));
+ else if(msg.startsWith("/nick "))
+ if(fromenemy)
+ emit sigChangeEnemyNickname(msg.mid(6));
+ else
+ emit sigChangeOwnNickname(msg.mid(6));
+ else
+ chatView->append(nickname + QString(": ") + msg);
+ chatView->setCursorPosition(chatView->numLines(), 0);
+}
+
+bool KChatWidget::eventFilter(QObject *obj, QEvent *e)
+{
+ if(obj == commentEdit && e->type() == QEvent::Wheel)
+ {
+ kapp->notify(chatView, e);
+ return true;
+ }
+ return chatDlg::eventFilter(obj, e);
+}
+
+void KChatWidget::slotComputeMessage()
+{
+ if(!commentEdit->text().stripWhiteSpace().isEmpty() && m_acceptMsgs)
+ {
+ slotReceivedMessage(m_currentNickname, commentEdit->text(), false);
+ emit sigSendMessage(commentEdit->text());
+ commentEdit->setText("");
+ }
+ else if(commentEdit->text().stripWhiteSpace().isEmpty() && m_acceptMsgs)
+ commentEdit->setText("");
+ commentEdit->setFocus();
+}
diff --git a/kbattleship/kbattleship/kchatwidget.h b/kbattleship/kbattleship/kchatwidget.h
new file mode 100644
index 00000000..e9a756a7
--- /dev/null
+++ b/kbattleship/kbattleship/kchatwidget.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ kchatwidget.h
+ ---------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KCHATWIDGET_H
+#define KCHATWIDGET_H
+
+#include <qpushbutton.h>
+#include <qmultilineedit.h>
+#include <qlineedit.h>
+#include "dialogs/chatDlg.h"
+#include "kmessage.h"
+
+class KChatWidget : public chatDlg
+{
+ Q_OBJECT
+public:
+ KChatWidget(QWidget *parent = 0, const char *name = 0);
+
+ void clear();
+ void setNickname(const QString &nickname) { m_currentNickname = nickname; }
+
+public slots:
+ void slotAcceptMsg(bool value);
+ void slotComputeMessage();
+ void slotReceivedMessage(const QString &nickname, const QString &msg, bool fromenemy = true);
+
+signals:
+ void sigSendMessage(const QString &);
+ void sigChangeEnemyNickname(const QString &);
+ void sigChangeOwnNickname(const QString &);
+
+private:
+ virtual bool eventFilter(QObject *, QEvent *);
+
+ QString m_currentNickname;
+ bool m_acceptMsgs;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kclientdialog.cpp b/kbattleship/kbattleship/kclientdialog.cpp
new file mode 100644
index 00000000..78fc04de
--- /dev/null
+++ b/kbattleship/kbattleship/kclientdialog.cpp
@@ -0,0 +1,140 @@
+/***************************************************************************
+ kclientdialog.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qstring.h>
+#include <qglobal.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kcombobox.h>
+#include <kuser.h>
+#include <qlayout.h>
+#include "kbattleshipserver.h" // for BATTLESHIP_SERVICE
+#include "kclientdialog.moc"
+
+KClientDialog::KClientDialog(QWidget *parent, const char *name)
+ : KDialogBase(Plain, i18n("Connect to Server"), Ok|Cancel, Ok, parent, name, true, false, KGuiItem(i18n("&Connect")))
+{
+ QFrame* page = plainPage();
+ QGridLayout* pageLayout = new QGridLayout(page, 1, 1, 0, 0);
+ m_mainWidget = new clientConnectDlg(page);
+ pageLayout->addWidget(m_mainWidget, 0, 0);
+
+ enableButtonOK(false);
+ m_config = kapp->config();
+ KUser u;
+ m_mainWidget->nicknameEdit->setText(u.loginName());
+
+ connect(m_mainWidget->serverEdit, SIGNAL(returnPressed(const QString &)), this, SLOT(slotReturnPressed(const QString &)));
+ connect(m_mainWidget->serverEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slotCheckEnableOk()));
+
+ m_config->setGroup("History");
+ m_browser = new DNSSD::ServiceBrowser(QString::fromLatin1(BATTLESHIP_SERVICE));
+ connect(m_browser,SIGNAL(finished()),SLOT(nextBatch()));
+ m_browser->startBrowse();
+ connect(m_mainWidget->lanBox,SIGNAL(activated(int)),SLOT(gameSelected(int)));
+ m_mainWidget->serverEdit->completionObject()->setItems(m_config->readListEntry("CompletionList"));
+
+ m_mainWidget->serverEdit->setMaxCount(5);
+ m_mainWidget->serverEdit->setHistoryItems(m_config->readListEntry("HistoryList"));
+
+ m_mainWidget->serverEdit->setCurrentItem(m_config->readNumEntry("Index", -1));
+}
+
+KClientDialog::~KClientDialog()
+{
+ m_config->setGroup("History");
+ m_config->writeEntry("CompletionList", m_mainWidget->serverEdit->completionObject()->items());
+ m_config->writeEntry("HistoryList", m_mainWidget->serverEdit->historyItems());
+ m_config->writeEntry("Index", m_mainWidget->serverEdit->currentItem());
+ m_config->sync();
+}
+
+void KClientDialog::slotCheckEnableOk()
+{
+ enableButtonOK(!m_mainWidget->serverEdit->currentText().stripWhiteSpace().isEmpty());
+}
+
+void KClientDialog::slotOk()
+{
+ QString server = m_mainWidget->serverEdit->currentText().stripWhiteSpace();
+ if(!server.isEmpty())
+ {
+ hide();
+ m_mainWidget->serverEdit->addToHistory(server);
+ emit sigConnectServer();
+ }
+ else
+ m_mainWidget->serverEdit->clearEdit();
+}
+
+void KClientDialog::slotReturnPressed(const QString &hostname)
+{
+ if(!hostname.stripWhiteSpace().isEmpty())
+ m_mainWidget->serverEdit->addToHistory(hostname);
+ else
+ m_mainWidget->serverEdit->clearEdit();
+}
+
+void KClientDialog::slotCancel()
+{
+ hide();
+ emit sigCancelConnect();
+}
+
+QString KClientDialog::port() const
+{
+ return QString::number(m_mainWidget->portEdit->value());
+}
+
+QString KClientDialog::host() const
+{
+ return m_mainWidget->serverEdit->currentText();
+}
+
+QString KClientDialog::nickname() const
+{
+ return m_mainWidget->nicknameEdit->text();
+}
+
+void KClientDialog::nextBatch()
+{
+ bool autoselect=false;
+ if (!m_mainWidget->lanBox->count()) autoselect=true;
+ m_mainWidget->lanBox->clear();
+ QStringList names;
+ QValueList<DNSSD::RemoteService::Ptr>::ConstIterator itEnd = m_browser->services().end();
+ for (QValueList<DNSSD::RemoteService::Ptr>::ConstIterator it = m_browser->services().begin();
+ it!=itEnd; ++it) names << (*it)->serviceName();
+ m_mainWidget->lanBox->insertStringList(names);
+ if (autoselect && m_mainWidget->lanBox->count()) gameSelected(0);
+}
+
+void KClientDialog::gameSelected(int i)
+{
+ Q_ASSERT(i < m_browser->services().count()); if( i >= m_browser->services().count()) { slotCheckEnableOk(); return; }
+
+ DNSSD::RemoteService::Ptr srv = m_browser->services()[i];
+
+ Q_ASSERT(srv); if(!srv) { slotCheckEnableOk(); return; }
+
+ if (!srv->isResolved() && !srv->resolve()) return;
+ m_mainWidget->serverEdit->setCurrentItem(srv->hostName(),true);
+ m_mainWidget->portEdit->setValue(srv->port());
+ slotCheckEnableOk();
+}
+
+
diff --git a/kbattleship/kbattleship/kclientdialog.h b/kbattleship/kbattleship/kclientdialog.h
new file mode 100644
index 00000000..e3dbf341
--- /dev/null
+++ b/kbattleship/kbattleship/kclientdialog.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ kclientdialog.h
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KCLIENTDIALOG_H
+#define KCLIENTDIALOG_H
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <dnssd/servicebrowser.h>
+#include <dnssd/remoteservice.h>
+#include <qstring.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+#include <kdialogbase.h>
+#include "dialogs/connectDlg.h"
+
+class KClientDialog : public KDialogBase
+{
+ Q_OBJECT
+public:
+ KClientDialog(QWidget *parent = 0, const char *name = 0);
+ ~KClientDialog();
+
+ QString port() const;
+ QString host() const;
+ QString nickname() const;
+
+public slots:
+ virtual void slotOk();
+ virtual void slotCancel();
+ void slotReturnPressed(const QString &hostname);
+ void nextBatch();
+ void gameSelected(int);
+ void slotCheckEnableOk();
+
+signals:
+ void sigConnectServer();
+ void sigCancelConnect();
+
+private:
+ KConfig *m_config;
+ DNSSD::ServiceBrowser *m_browser;
+ clientConnectDlg *m_mainWidget;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kgridwidget.cpp b/kbattleship/kbattleship/kgridwidget.cpp
new file mode 100644
index 00000000..49a6d106
--- /dev/null
+++ b/kbattleship/kbattleship/kgridwidget.cpp
@@ -0,0 +1,416 @@
+/***************************************************************************
+ kgridwidget.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qapplication.h>
+#include <qimage.h>
+#include <qpainter.h>
+
+#include <kstandarddirs.h>
+#include <kimageeffect.h>
+#include <kdebug.h>
+
+#include "kbattlefield.h"
+#include "kgridwidget.h"
+
+KGridWidget::KGridWidget(QWidget *parent, bool draw) : m_drawGrid(draw)
+{
+ m_doubleBuffer = new QPixmap(parent->width(), parent->height());
+ m_parent = parent;
+
+ cleanBuffer();
+ cacheImages();
+}
+
+KGridWidget::~KGridWidget()
+{
+ delete m_doubleBuffer;
+}
+
+void KGridWidget::cacheImages()
+{
+ seaPng = QPixmap(findIcon("sea.png"));
+ waterPng = QPixmap(findIcon("water.png"));
+ hitPng = QPixmap(findIcon("hit.png"));
+ borderPng = QPixmap(findIcon("border.png"));
+ deathPng = QPixmap(findIcon("death.png"));
+ ship1p1Png = QPixmap(findIcon("ship1-1.png"));
+ ship1p1rPng = QPixmap(findIcon("ship1-1-r.png"));
+ ship2p1Png = QPixmap(findIcon("ship2-1.png"));
+ ship2p1rPng = QPixmap(findIcon("ship2-1-r.png"));
+ ship2p2Png = QPixmap(findIcon("ship2-2.png"));
+ ship2p2rPng = QPixmap(findIcon("ship2-2-r.png"));
+ ship3p1Png = QPixmap(findIcon("ship3-1.png"));
+ ship3p1rPng = QPixmap(findIcon("ship3-1-r.png"));
+ ship3p2Png = QPixmap(findIcon("ship3-2.png"));
+ ship3p2rPng = QPixmap(findIcon("ship3-2-r.png"));
+ ship3p3Png = QPixmap(findIcon("ship3-3.png"));
+ ship3p3rPng = QPixmap(findIcon("ship3-3-r.png"));
+ ship4p1Png = QPixmap(findIcon("ship4-1.png"));
+ ship4p1rPng = QPixmap(findIcon("ship4-1-r.png"));
+ ship4p2Png = QPixmap(findIcon("ship4-2.png"));
+ ship4p2rPng = QPixmap(findIcon("ship4-2-r.png"));
+ ship4p3Png = QPixmap(findIcon("ship4-3.png"));
+ ship4p3rPng = QPixmap(findIcon("ship4-3-r.png"));
+ ship4p4Png = QPixmap(findIcon("ship4-4.png"));
+ ship4p4rPng = QPixmap(findIcon("ship4-4-r.png"));
+}
+
+void KGridWidget::setValues(int x, int y, int size)
+{
+ m_x = x;
+ m_y = y;
+ m_size = size;
+}
+
+void KGridWidget::drawSquare()
+{
+ drawIcon(seaPng);
+}
+
+void KGridWidget::drawWaterIcon()
+{
+ drawIcon(waterPng);
+}
+
+void KGridWidget::drawHitIcon()
+{
+ drawIcon(hitPng);
+}
+
+void KGridWidget::drawDeathBorder()
+{
+ drawIcon(borderPng);
+}
+void KGridWidget::drawDeathIcon()
+{
+ drawIcon(deathPng);
+}
+
+void KGridWidget::drawShipIcon(int type, bool rotate, bool hit, bool water)
+{
+ int ship = 0;
+ int part = 0;
+
+ switch(type)
+ {
+ case KBattleField::SHIP1P1:
+ ship = 1;
+ part = 1;
+ break;
+
+ case KBattleField::SHIP2P1:
+ ship = 2;
+ if(!rotate)
+ part = 1;
+ else
+ part = 2;
+ break;
+
+ case KBattleField::SHIP2P2:
+ ship = 2;
+ if(!rotate)
+ part = 2;
+ else
+ part = 1;
+ break;
+
+ case KBattleField::SHIP3P1:
+ ship = 3;
+ if(!rotate)
+ part = 1;
+ else
+ part = 3;
+ break;
+
+ case KBattleField::SHIP3P2:
+ ship = 3;
+ if(!rotate)
+ part = 2;
+ else
+ part = 2;
+ break;
+
+ case KBattleField::SHIP3P3:
+ ship = 3;
+ if(!rotate)
+ part = 3;
+ else
+ part = 1;
+ break;
+
+ case KBattleField::SHIP4P1:
+ ship = 4;
+ if(!rotate)
+ part = 1;
+ else
+ part = 4;
+ break;
+
+ case KBattleField::SHIP4P2:
+ ship = 4;
+ if(!rotate)
+ part = 2;
+ else
+ part = 3;
+ break;
+
+ case KBattleField::SHIP4P3:
+ ship = 4;
+ if(!rotate)
+ part = 3;
+ else
+ part = 2;
+ break;
+
+ case KBattleField::SHIP4P4:
+ ship = 4;
+ if(!rotate)
+ part = 4;
+ else
+ part = 1;
+ break;
+ }
+
+ switch(ship)
+ {
+ case 1:
+ if(!rotate)
+ drawIcon(ship1p1Png, hit, water);
+ else
+ drawIcon(ship1p1rPng, hit, water, rotate);
+ break;
+
+ case 2:
+ switch(part)
+ {
+ case 1:
+ if(!rotate)
+ drawIcon(ship2p1Png, hit, water);
+ else
+ drawIcon(ship2p1rPng, hit, water, rotate);
+ break;
+
+ case 2:
+ if(!rotate)
+ drawIcon(ship2p2Png, hit, water);
+ else
+ drawIcon(ship2p2rPng, hit, water, rotate);
+ break;
+ }
+ break;
+
+ case 3:
+ switch(part)
+ {
+ case 1:
+ if(!rotate)
+ drawIcon(ship3p1Png, hit, water);
+ else
+ drawIcon(ship3p1rPng, hit, water, rotate);
+ break;
+
+ case 2:
+ if(!rotate)
+ drawIcon(ship3p2Png, hit, water);
+ else
+ drawIcon(ship3p2rPng, hit, water, rotate);
+ break;
+
+ case 3:
+ if(!rotate)
+ drawIcon(ship3p3Png, hit, water);
+ else
+ drawIcon(ship3p3rPng, hit, water, rotate);
+ break;
+ }
+ break;
+
+ case 4:
+ switch(part)
+ {
+ case 1:
+ if(!rotate)
+ drawIcon(ship4p1Png, hit, water);
+ else
+ drawIcon(ship4p1rPng, hit, water, rotate);
+ break;
+
+ case 2:
+ if(!rotate)
+ drawIcon(ship4p2Png, hit, water);
+ else
+ drawIcon(ship4p2rPng, hit, water, rotate);
+ break;
+
+ case 3:
+ if(!rotate)
+ drawIcon(ship4p3Png, hit, water);
+ else
+ drawIcon(ship4p3rPng, hit, water, rotate);
+ break;
+
+ case 4:
+ if(!rotate)
+ drawIcon(ship4p4Png, hit, water);
+ else
+ drawIcon(ship4p4rPng, hit, water, rotate);
+ break;
+ }
+ break;
+ }
+}
+
+void KGridWidget::drawShipIcon(int ship, int part, bool rotate, bool hit)
+{
+ switch(ship)
+ {
+ case 1:
+ if(!rotate)
+ drawIcon(ship1p1Png, hit);
+ else
+ drawIcon(ship1p1rPng, hit, false, rotate);
+ break;
+
+ case 2:
+ switch(part)
+ {
+ case 1:
+ if(!rotate)
+ drawIcon(ship2p1Png, hit);
+ else
+ drawIcon(ship2p1rPng, hit, false, rotate);
+ break;
+
+ case 2:
+ if(!rotate)
+ drawIcon(ship2p2Png, hit);
+ else
+ drawIcon(ship2p2rPng, hit, false, rotate);
+ break;
+ }
+ break;
+
+ case 3:
+ switch(part)
+ {
+ case 1:
+ if(!rotate)
+ drawIcon(ship3p1Png, hit);
+ else
+ drawIcon(ship3p1rPng, hit, false, rotate);
+ break;
+
+ case 2:
+ if(!rotate)
+ drawIcon(ship3p2Png, hit);
+ else
+ drawIcon(ship3p2rPng, hit, false, rotate);
+ break;
+
+ case 3:
+ if(!rotate)
+ drawIcon(ship3p3Png, hit);
+ else
+ drawIcon(ship3p3rPng, hit, false, rotate);
+ break;
+ }
+ break;
+
+ case 4:
+ switch(part)
+ {
+ case 1:
+ if(!rotate)
+ drawIcon(ship4p1Png, hit);
+ else
+ drawIcon(ship4p1rPng, hit, false, rotate);
+ break;
+
+ case 2:
+ if(!rotate)
+ drawIcon(ship4p2Png, hit);
+ else
+ drawIcon(ship4p2rPng, hit, false, rotate);
+ break;
+
+ case 3:
+ if(!rotate)
+ drawIcon(ship4p3Png, hit);
+ else
+ drawIcon(ship4p3rPng, hit, false, rotate);
+ break;
+
+ case 4:
+ if(!rotate)
+ drawIcon(ship4p4Png, hit);
+ else
+ drawIcon(ship4p4rPng, hit, false, rotate);
+ break;
+ }
+ break;
+ }
+}
+
+void KGridWidget::drawIcon(const QPixmap &icon, bool hitBlend, bool waterBlend, bool rotate)
+{
+ QPainter painter;
+ painter.begin(m_doubleBuffer);
+ if(!hitBlend && waterBlend)
+ {
+ QImage first = icon.convertToImage();
+ QImage second = seaPng.convertToImage();
+ painter.drawPixmap(m_x, m_y, seaPng);
+ if(rotate)
+ painter.drawImage(m_x, m_y, KImageEffect::blend(first, second, KImageEffect::VerticalGradient, 30, 30));
+ else
+ painter.drawImage(m_x, m_y, KImageEffect::blend(first, second, KImageEffect::HorizontalGradient, 30, 30));
+
+ }
+ else if(hitBlend && !waterBlend)
+ {
+ painter.drawPixmap(m_x, m_y, icon);
+ painter.drawPixmap(m_x, m_y, hitPng);
+ }
+ else
+ painter.drawPixmap(m_x, m_y, icon);
+
+ if(!m_drawGrid)
+ painter.end();
+ else
+ {
+ painter.setBrush(Qt::NoBrush);
+ painter.setPen(Qt::black);
+ painter.drawRect(m_x, m_y, m_size, m_size);
+ painter.end();
+ }
+}
+
+QString KGridWidget::findIcon(const QString &name) const
+{
+ return locate("data", "kbattleship/pictures/" + name);
+}
+
+void KGridWidget::finished()
+{
+ bitBlt(m_parent, 0, 0, m_doubleBuffer);
+ cleanBuffer();
+}
+
+void KGridWidget::cleanBuffer()
+{
+ m_doubleBuffer->fill(QApplication::palette().color(QPalette::Normal, QColorGroup::Background));
+}
diff --git a/kbattleship/kbattleship/kgridwidget.h b/kbattleship/kbattleship/kgridwidget.h
new file mode 100644
index 00000000..91f48eb0
--- /dev/null
+++ b/kbattleship/kbattleship/kgridwidget.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ kgridwidget.h
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KGRIDWIDGET_H
+#define KGRIDWIDGET_H
+
+#include <qpixmap.h>
+
+class KGridWidget
+{
+public:
+ KGridWidget(QWidget *parent, bool draw);
+ ~KGridWidget();
+
+ void enableGrid() { m_drawGrid = true; }
+ void disableGrid() { m_drawGrid = false; }
+
+protected:
+ void cleanBuffer();
+ void finished();
+ void setValues(int x, int y, int size);
+ void drawSquare();
+ void drawWaterIcon();
+ void drawDeathBorder();
+ void drawDeathIcon();
+ void drawHitIcon();
+ void drawShipIcon(int type, bool rotate = false, bool hit = false, bool water = false);
+ void drawShipIcon(int ship, int part, bool rotate = false, bool hit = false);
+
+private:
+ void cacheImages();
+ void drawIcon(const QPixmap &icon, bool hitBlend = false, bool waterBlend = false, bool rotate = false);
+ QString findIcon(const QString &name) const;
+
+ bool m_drawGrid;
+ int m_x, m_y, m_size;
+ QPixmap *m_doubleBuffer;
+ QPixmap seaPng, waterPng, hitPng, borderPng,deathPng;
+ QPixmap ship1p1Png, ship1p1rPng;
+ QPixmap ship2p1Png, ship2p1rPng;
+ QPixmap ship2p2Png, ship2p2rPng;
+ QPixmap ship3p1Png, ship3p1rPng;
+ QPixmap ship3p2Png, ship3p2rPng;
+ QPixmap ship3p3Png, ship3p3rPng;
+ QPixmap ship4p1Png, ship4p1rPng;
+ QPixmap ship4p2Png, ship4p2rPng;
+ QPixmap ship4p3Png, ship4p3rPng;
+ QPixmap ship4p4Png, ship4p4rPng;
+ QWidget *m_parent;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kmessage.cpp b/kbattleship/kbattleship/kmessage.cpp
new file mode 100644
index 00000000..5eccacd2
--- /dev/null
+++ b/kbattleship/kbattleship/kmessage.cpp
@@ -0,0 +1,101 @@
+/***************************************************************************
+ kmessage.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+//#define XMLDUMP
+
+#include <klocale.h>
+
+#ifdef XMLDUMP
+#include <kdebug.h>
+#endif
+
+#include "kmessage.h"
+
+const char *clientName = I18N_NOOP("KBattleship");
+const char *clientVersion = "1.1";
+const char *clientDescription = I18N_NOOP("The KDE Battleship clone");
+const char *protocolVersion = "0.1.0";
+
+KMessage::KMessage(int type)
+{
+ m_xmlDocument = QDomDocument("kmessage");
+ m_xmlDocument.appendChild(m_xmlDocument.createElement("kmessage"));
+ m_messageType = type;
+ addField("msgtype", QString::number(type));
+}
+
+KMessage::KMessage(KMessage *msg)
+{
+ m_xmlDocument.setContent(msg->m_xmlDocument.toString(), false);
+ m_messageType = msg->type();
+}
+
+KMessage::KMessage()
+{
+ m_xmlDocument = QDomDocument("kmessage");
+}
+
+void KMessage::addField(const QString &name, const QString &content)
+{
+ QDomElement xmlElement = m_xmlDocument.createElement(name);
+ QDomText xmlText = m_xmlDocument.createTextNode(content);
+ xmlElement.appendChild(xmlText);
+ m_xmlDocument.documentElement().appendChild(xmlElement);
+}
+
+void KMessage::setDataStream(const QString &stream)
+{
+ m_xmlDocument.setContent(stream);
+#ifdef XMLDUMP
+ kdDebug() << "*** XML-IN ***" << endl << stream << endl << "*** END ***" << endl;
+#endif
+}
+
+QString KMessage::sendStream() const
+{
+#ifdef XMLDUMP
+ kdDebug() << "*** XML OUT ***" << endl << m_xmlDocument.toString() << endl << "*** END ***" << endl;
+#endif
+ return m_xmlDocument.toString();
+}
+
+QString KMessage::field(const QString &name) const
+{
+ QDomNode xmlNode = m_xmlDocument.documentElement().namedItem(name);
+ if(!xmlNode.isNull())
+ return (xmlNode.toElement()).text();
+ return QString::null;
+}
+
+int KMessage::type()
+{
+ return field("msgtype").toInt();
+}
+
+void KMessage::chatMessage(const QString &nickname, const QString &message)
+{
+ addField("nickname", nickname);
+ addField("chat", message);
+}
+
+void KMessage::versionMessage()
+{
+ addField("protocolVersion", protocolVersion);
+ addField("clientName", clientName);
+ addField("clientVersion", clientVersion);
+ addField("clientDescription", clientDescription);
+}
diff --git a/kbattleship/kbattleship/kmessage.h b/kbattleship/kbattleship/kmessage.h
new file mode 100644
index 00000000..f1d6a0b5
--- /dev/null
+++ b/kbattleship/kbattleship/kmessage.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ kmessage.h
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KMESSAGE_H
+#define KMESSAGE_H
+
+#include <qdom.h>
+#include <qstring.h>
+
+class KMessage
+{
+public:
+ enum{GETVERSION, DISCARD, GREET, SHIPSREADY, SHOOT, ANSWER_SHOOT, WON, REPLAY, CHAT};
+
+ KMessage(int type);
+ KMessage(KMessage *msg);
+ KMessage();
+
+ int type();
+
+ void addField(const QString &name, const QString &content);
+ QString field(const QString &name) const;
+
+ void setDataStream(const QString &stream);
+ QString sendStream() const;
+
+ void chatMessage(const QString &nickname, const QString &message);
+ void versionMessage();
+
+private:
+ QDomDocument m_xmlDocument;
+ int m_messageType;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/konnectionhandling.cpp b/kbattleship/kbattleship/konnectionhandling.cpp
new file mode 100644
index 00000000..bcfefe04
--- /dev/null
+++ b/kbattleship/kbattleship/konnectionhandling.cpp
@@ -0,0 +1,246 @@
+/**************************************MM*************************************
+ konnectionhandling.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "konnectionhandling.moc"
+
+extern const char *protocolVersion;
+
+KonnectionHandling::KonnectionHandling(QWidget *parent, KBattleshipServer *server) : QObject(parent)
+{
+ m_kbserver = server;
+ m_kbclient = 0;
+ m_type = KonnectionHandling::SERVER;
+ connect(server, SIGNAL(sigServerFailure()), this, SIGNAL(sigAbortNetworkGame()));
+ connect(server, SIGNAL(sigNewConnect()), this, SLOT(slotNewClient()));
+ connect(server, SIGNAL(sigEndConnect()), this, SLOT(slotLostClient()));
+ connect(server, SIGNAL(sigNewMessage(KMessage *)), this, SLOT(slotNewMessage(KMessage *)));
+ connect(server, SIGNAL(sigMessageSent(KMessage *)), this, SLOT(slotMessageSent(KMessage *)));
+}
+
+KonnectionHandling::KonnectionHandling(QWidget *parent, KBattleshipClient *client) : QObject(parent)
+{
+ m_kbclient = client;
+ m_kbserver = 0;
+ m_type = KonnectionHandling::CLIENT;
+ connect(client, SIGNAL(sigEndConnect()), this, SLOT(slotLostServer()));
+ connect(client, SIGNAL(sigSocketFailure(int)), this, SLOT(slotSocketError(int)));
+ connect(client, SIGNAL(sigNewMessage(KMessage *)), this, SLOT(slotNewMessage(KMessage *)));
+ connect(client, SIGNAL(sigMessageSent(KMessage *)), this, SLOT(slotMessageSent(KMessage *)));
+}
+
+void KonnectionHandling::updateInternal(KBattleshipServer *server)
+{
+ m_kbserver = server;
+ m_kbclient = 0;
+ m_type = KonnectionHandling::SERVER;
+ connect(server, SIGNAL(sigServerFailure()), this, SIGNAL(sigAbortNetworkGame()));
+ connect(server, SIGNAL(sigNewConnect()), this, SLOT(slotNewClient()));
+ connect(server, SIGNAL(sigEndConnect()), this, SLOT(slotLostClient()));
+ connect(server, SIGNAL(sigNewMessage(KMessage *)), this, SLOT(slotNewMessage(KMessage *)));
+ connect(server, SIGNAL(sigMessageSent(KMessage *)), this, SLOT(slotMessageSent(KMessage *)));
+}
+
+void KonnectionHandling::updateInternal(KBattleshipClient *client)
+{
+ m_kbclient = client;
+ m_kbserver = 0;
+ m_type = KonnectionHandling::CLIENT;
+ connect(client, SIGNAL(sigEndConnect()), this, SLOT(slotLostServer()));
+ connect(client, SIGNAL(sigSocketFailure(int)), this, SLOT(slotSocketError(int)));
+ connect(client, SIGNAL(sigNewMessage(KMessage *)), this, SLOT(slotNewMessage(KMessage *)));
+ connect(client, SIGNAL(sigMessageSent(KMessage *)), this, SLOT(slotMessageSent(KMessage *)));
+}
+
+void KonnectionHandling::slotNewClient()
+{
+}
+
+void KonnectionHandling::slotLostClient()
+{
+ KMessageBox::error(0L, i18n("Connection to client lost. Aborting the game."));
+ emit sigClientLost();
+}
+
+void KonnectionHandling::slotMessageSent(KMessage *msg)
+{
+ if(msg->type() == KMessage::SHOOT)
+ emit sigShootable(false);
+
+ delete msg;
+}
+
+void KonnectionHandling::slotNewMessage(KMessage *msg)
+{
+ KMessage *copy;
+ if(type() == KonnectionHandling::CLIENT)
+ {
+ switch(msg->type())
+ {
+ // First possible message
+ case KMessage::DISCARD:
+ if(msg->field("kmversion") == QString("true"))
+ {
+ KMessageBox::error(0L, i18n("Connection dropped by enemy. The client's protocol implementation (%1) is not compatible with our (%2) version.").arg(msg->field("reason")).arg(protocolVersion));
+ emit sigAbortNetworkGame();
+ }
+ else
+ KMessageBox::error(0L, i18n(msg->field("reason").latin1()));
+ break;
+
+ // Got some informations
+ case KMessage::GETVERSION:
+ emit sigClientInformation(msg->field("clientName"), msg->field("clientVersion"), msg->field("clientDescription"), msg->field("protocolVersion"));
+ break;
+
+ // Got the enemy's nickname
+ case KMessage::GREET:
+ emit sigEnemyNickname(msg->field("nickname"));
+ emit sigStatusBar(i18n("Waiting for other player to place their ships..."));
+ break;
+
+ // The server wants ous to place the ships
+ case KMessage::SHIPSREADY:
+ emit sigPlaceShips(true);
+ emit sigStatusBar(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
+ break;
+
+ // The server shot and wants the field state
+ case KMessage::SHOOT:
+ emit sigSendFieldState(msg->field("fieldx").toInt(), msg->field("fieldy").toInt());
+ emit sigStatusBar(i18n("Enemy has shot. Shoot now."));
+ emit sigShootable(true);
+ break;
+
+ // The server gave us the field data of our last shot
+ case KMessage::ANSWER_SHOOT:
+ emit sigShootable(false);
+ emit sigEnemyFieldData(msg->field("fieldx").toInt(), msg->field("fieldy").toInt(), msg->field("fieldstate").toInt(), msg->field("xstart").toInt(), msg->field("xstop").toInt(), msg->field("ystart").toInt(), msg->field("ystop").toInt(), (msg->field("death") == QString("true")));
+ break;
+
+ // The server starts a new game
+ case KMessage::REPLAY:
+ emit sigStatusBar(i18n("Waiting for other player to place their ships..."));
+ emit sigReplay();
+ break;
+
+ // We lost the game
+ case KMessage::WON:
+ emit sigStatusBar(i18n("You lost the game :("));
+ copy = new KMessage(msg);
+ emit sigLost(copy);
+ break;
+
+ // We got a chat message
+ case KMessage::CHAT:
+ emit sigChatMessage(msg->field("nickname"), msg->field("chat"), true);
+ break;
+ }
+ }
+ else
+ {
+ switch(msg->type())
+ {
+ // First message....got client information
+ case KMessage::GETVERSION:
+ if(msg->field("protocolVersion") != QString::fromLatin1(protocolVersion))
+ {
+ m_kbserver->slotDiscardClient(protocolVersion, true, false);
+ KMessageBox::error(0L, i18n("Connection to client dropped. The client's protocol implementation (%1) is not compatible with our (%2) version.").arg(msg->field("protocolVersion")).arg(protocolVersion));
+ }
+ else
+ emit sigClientInformation(msg->field("clientName"), msg->field("clientVersion"), msg->field("clientDescription"), msg->field("protocolVersion"));
+ break;
+
+ // Got the enemy's nickname
+ case KMessage::GREET:
+ KMessageBox::information(0L, i18n("We have a player. Let's start..."));
+ emit sigStatusBar(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
+ emit sigEnemyNickname(msg->field("nickname"));
+ emit sigSendNickname();
+ emit sigPlaceShips(true);
+ break;
+
+ // The client placed his ships...we can shoot now
+ case KMessage::SHIPSREADY:
+ emit sigShootable(true);
+ emit sigStatusBar(i18n("You can shoot now."));
+ break;
+
+ // The client gave us the field data of our last shot
+ case KMessage::ANSWER_SHOOT:
+ emit sigShootable(false);
+ emit sigEnemyFieldData(msg->field("fieldx").toInt(), msg->field("fieldy").toInt(), msg->field("fieldstate").toInt(), msg->field("xstart").toInt(), msg->field("xstop").toInt(), msg->field("ystart").toInt(), msg->field("ystop").toInt(), (msg->field("death") == QString("true")));
+ break;
+
+ // The client shot and wants the field state
+ case KMessage::SHOOT:
+ emit sigSendFieldState(msg->field("fieldx").toInt(), msg->field("fieldy").toInt());
+ emit sigStatusBar(i18n("Enemy has shot. Shoot now."));
+ emit sigShootable(true);
+ break;
+
+ // The client asks for a replay
+ case KMessage::REPLAY:
+ emit sigReplay();
+ break;
+
+ // We lost the game
+ case KMessage::WON:
+ emit sigStatusBar(i18n("You lost the game :("));
+ copy = new KMessage(msg);
+ emit sigLost(copy);
+ break;
+
+ // We got a chat message
+ case KMessage::CHAT:
+ emit sigChatMessage(msg->field("nickname"), msg->field("chat"), true);
+ break;
+ }
+ }
+
+ delete msg;
+}
+
+void KonnectionHandling::slotSocketError(int error)
+{
+ switch(error)
+ {
+ case IO_ConnectError:
+ KMessageBox::error(0L, i18n("Connection refused by other host."));
+ break;
+
+ case IO_LookupError:
+ KMessageBox::error(0L, i18n("Couldn't lookup host."));
+ break;
+
+ case IO_ReadError:
+ KMessageBox::error(0L, i18n("Couldn't connect to server."));
+ break;
+
+ default:
+ KMessageBox::error(0L, i18n("Unknown error; No: %1").arg(error));
+ break;
+ }
+
+ emit sigAbortNetworkGame();
+}
+
+void KonnectionHandling::slotLostServer()
+{
+ KMessageBox::error(0L, i18n("Connection to server lost. Aborting the game."));
+ emit sigServerLost();
+}
diff --git a/kbattleship/kbattleship/konnectionhandling.h b/kbattleship/kbattleship/konnectionhandling.h
new file mode 100644
index 00000000..baa823df
--- /dev/null
+++ b/kbattleship/kbattleship/konnectionhandling.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ konnectionhandling.h
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KONNECTIONHANDLING_H
+#define KONNECTIONHANDLING_H
+
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include <qobject.h>
+
+#include "kbattleshipclient.h"
+#include "kbattleshipserver.h"
+#include "kmessage.h"
+
+class KonnectionHandling : public QObject
+{
+ Q_OBJECT
+public:
+ enum{SERVER, CLIENT};
+ KonnectionHandling(QWidget *parent, KBattleshipServer *server);
+ KonnectionHandling(QWidget *parent, KBattleshipClient *client);
+
+ int type() { return m_type; }
+
+ void updateInternal(KBattleshipServer *server);
+ void updateInternal(KBattleshipClient *client);
+
+public slots:
+ void slotNewMessage(KMessage *msg);
+ void slotMessageSent(KMessage *msg);
+ void slotNewClient();
+ void slotLostClient();
+ void slotLostServer();
+ void slotSocketError(int error);
+
+signals:
+ void sigStatusBar(const QString &);
+ void sigEnemyNickname(const QString &);
+ void sigEnemyFieldData(int, int, int, int, int, int, int, bool);
+ void sigClientInformation(const QString &, const QString &, const QString &, const QString &);
+ void sigSendNickname();
+ void sigSendFieldState(int, int);
+ void sigPlaceShips(bool);
+ void sigShootable(bool);
+ void sigClientLost();
+ void sigServerLost();
+ void sigReplay();
+ void sigLost(KMessage *);
+ void sigAbortNetworkGame();
+ void sigChatMessage(const QString &, const QString &, bool);
+
+private:
+ KBattleshipServer *m_kbserver;
+ KBattleshipClient *m_kbclient;
+ int m_type;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kserverdialog.cpp b/kbattleship/kbattleship/kserverdialog.cpp
new file mode 100644
index 00000000..3936bebf
--- /dev/null
+++ b/kbattleship/kbattleship/kserverdialog.cpp
@@ -0,0 +1,67 @@
+/***************************************************************************
+ kserverdialog.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <klocale.h>
+#include <kuser.h>
+#include <qlayout.h>
+
+#include "kserverdialog.h"
+
+KServerDialog::KServerDialog(QWidget *parent, const char *name) :
+ KDialogBase(Plain, i18n("Start Server"), Ok|Cancel, Ok, parent, name, true, false, KGuiItem(i18n("&Start")))
+{
+ QFrame* page = plainPage();
+ QGridLayout* pageLayout = new QGridLayout(page, 1, 1, 0, 0);
+ m_mainWidget = new serverStartDlg(page);
+ pageLayout->addWidget(m_mainWidget, 0, 0);
+
+ KUser u;
+ m_mainWidget->nicknameEdit->setText(u.loginName());
+
+ QString gamename = u.fullName();
+ if(gamename.isEmpty()) gamename = u.loginName();
+ m_mainWidget->gamenameEdit->setText(gamename);
+}
+
+void KServerDialog::slotOk()
+{
+ hide();
+ emit okClicked();
+}
+
+void KServerDialog::slotCancel()
+{
+ hide();
+ emit cancelClicked();
+}
+
+QString KServerDialog::port() const
+{
+ return QString::number(m_mainWidget->portEdit->value());
+}
+
+QString KServerDialog::nickname() const
+{
+ return m_mainWidget->nicknameEdit->text();
+}
+
+QString KServerDialog::gamename() const
+{
+ return m_mainWidget->gamenameEdit->text();
+}
+
+#include "kserverdialog.moc"
diff --git a/kbattleship/kbattleship/kserverdialog.h b/kbattleship/kbattleship/kserverdialog.h
new file mode 100644
index 00000000..e6655c1a
--- /dev/null
+++ b/kbattleship/kbattleship/kserverdialog.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ kserverdialog.h
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSERVERDIALOG_H
+#define KSERVERDIALOG_H
+
+#include <qstring.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+
+#include <kdialogbase.h>
+
+#include "dialogs/serverDlg.h"
+
+
+class KServerDialog : public KDialogBase
+{
+ Q_OBJECT
+public:
+ KServerDialog(QWidget *parent = 0, const char *name = 0);
+
+ QString port() const;
+ QString nickname() const;
+ QString gamename() const;
+
+public slots:
+ virtual void slotOk();
+ virtual void slotCancel();
+
+private:
+ serverStartDlg *m_mainWidget;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kship.cpp b/kbattleship/kbattleship/kship.cpp
new file mode 100644
index 00000000..a9fbb558
--- /dev/null
+++ b/kbattleship/kbattleship/kship.cpp
@@ -0,0 +1,105 @@
+/***************************************************************************
+ kship.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+ (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kship.h"
+
+#include "kbattlefield.h"
+
+KShip::KShip(int _shipxstart, int _shipxstop, int _shipystart, int _shipystop, int _shiplength, bool _placedLeft)
+{
+ m_shipxstart = _shipxstart;
+ m_shipxstop = _shipxstop;
+ m_shipystart = _shipystart;
+ m_shipystop = _shipystop;
+ m_shiptype = _shiplength;
+ m_placedLeft = _placedLeft;
+}
+
+int KShip::shipxstart()
+{
+ return m_shipxstart;
+}
+
+int KShip::shipxstop()
+{
+ return m_shipxstop;
+}
+
+int KShip::shipystart()
+{
+ return m_shipystart;
+}
+
+int KShip::shipystop()
+{
+ return m_shipystop;
+}
+
+int KShip::shiptype()
+{
+ return m_shiptype;
+}
+
+bool KShip::placedLeft()
+{
+ return m_placedLeft;
+}
+
+bool KShip::contains(int x, int y)
+{
+ return (x >= m_shipxstart && x <= m_shipxstop) && (y >= m_shipystart && y <= m_shipystop);
+}
+
+int KShip::shipTypeEnum(int x, int y)
+{
+ int ret;
+ ret = KBattleField::WATER;
+ if (contains(x, y))
+ {
+ switch(m_shiptype)
+ {
+ case 0:
+ ret = KBattleField::SHIP1P1;
+ break;
+ case 1:
+ if (x == m_shipxstart && y == m_shipystart) ret = KBattleField::SHIP2P1;
+ else ret = KBattleField::SHIP2P2;
+ break;
+ case 2:
+ if (x == m_shipxstart && y == m_shipystart) ret = KBattleField::SHIP3P1;
+ else if (x == m_shipxstop && y == m_shipystop) ret = KBattleField::SHIP3P3;
+ else ret = KBattleField::SHIP3P2;
+ break;
+ case 3:
+ if (x == m_shipxstart && y == m_shipystart) ret = KBattleField::SHIP4P1;
+ else if (x == m_shipxstop && y == m_shipystop) ret = KBattleField::SHIP4P4;
+ else if (placedLeft())
+ {
+ if (x == m_shipxstart + 1 && y == m_shipystart) ret = KBattleField::SHIP4P2;
+ else ret = KBattleField::SHIP4P3;
+ }
+ else
+ {
+ if (x == m_shipxstart && y == m_shipystart + 1) ret = KBattleField::SHIP4P2;
+ else ret = KBattleField::SHIP4P3;
+ }
+ break;
+ }
+ }
+ return ret;
+}
diff --git a/kbattleship/kbattleship/kship.h b/kbattleship/kbattleship/kship.h
new file mode 100644
index 00000000..df436c7a
--- /dev/null
+++ b/kbattleship/kbattleship/kship.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ kship.h
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+ (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSHIP_H
+#define KSHIP_H
+
+class KShip
+{
+public:
+ KShip(int, int, int, int, int, bool = false);
+
+ int shipxstart();
+ int shipxstop();
+ int shipystart();
+ int shipystop();
+ int shiptype();
+ int shipTypeEnum(int x, int y);
+
+ bool placedLeft();
+ bool contains(int x, int y);
+
+private:
+ int m_shipxstart;
+ int m_shipxstop;
+ int m_shipystart;
+ int m_shipystop;
+ int m_shiptype;
+ bool m_placedLeft;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kshiplist.cpp b/kbattleship/kbattleship/kshiplist.cpp
new file mode 100644
index 00000000..8a17ad37
--- /dev/null
+++ b/kbattleship/kbattleship/kshiplist.cpp
@@ -0,0 +1,175 @@
+/***************************************************************************
+ kshiplist.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+ (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kshiplist.moc"
+#include <kdebug.h>
+
+KShipList::KShipList() : QObject()
+{
+ m_shiplist.setAutoDelete(true);
+ m_shipsadded = 4;
+
+ m_fieldx = 10;
+ m_fieldy = 10;
+}
+
+void KShipList::clear()
+{
+ m_shipsadded = 4;
+ m_shiplist.clear();
+}
+
+int KShipList::shipTypeAt(int x, int y)
+{
+ int tempx, tempy;
+ KShip *shipiterator;
+ for(shipiterator = m_shiplist.first(); shipiterator != 0; shipiterator = m_shiplist.next())
+ {
+ if(shipiterator->shipystart() != shipiterator->shipystop())
+ {
+ for(tempy = shipiterator->shipystart(); tempy <= shipiterator->shipystop(); tempy++)
+ {
+ if(tempy == y)
+ {
+ if(shipiterator->shipxstart() != shipiterator->shipxstop())
+ {
+ for(tempx = shipiterator->shipxstart(); tempx <= shipiterator->shipxstop(); tempx++)
+ {
+ if(tempx == x)
+ return shipiterator->shiptype();
+ }
+ }
+ else
+ {
+ tempx = shipiterator->shipxstart();
+ if(tempx == x)
+ return shipiterator->shiptype();
+ }
+ }
+ }
+ }
+ else
+ {
+ tempy = shipiterator->shipystart();
+ if(tempy == y)
+ {
+ if(shipiterator->shipxstart() != shipiterator->shipxstop())
+ {
+ for(tempx = shipiterator->shipxstart(); tempx <= shipiterator->shipxstop(); tempx++)
+ {
+ if(tempx == x)
+ return shipiterator->shiptype();
+ }
+ }
+ else
+ {
+ tempx = shipiterator->shipxstart();
+ if(tempx == x)
+ return shipiterator->shiptype();
+ }
+ }
+ }
+ }
+ return 99;
+}
+
+KShip *KShipList::shipAt(int x, int y)
+{
+ int tempx, tempy;
+ KShip *shipiterator;
+ for(shipiterator = m_shiplist.first(); shipiterator != 0; shipiterator = m_shiplist.next())
+ {
+ for(tempy = shipiterator->shipystart(); tempy <= shipiterator->shipystop(); tempy++)
+ {
+ if(tempy == y)
+ {
+ for(tempx = shipiterator->shipxstart(); tempx <= shipiterator->shipxstop(); tempx++)
+ {
+ if(tempx == x)
+ return shipiterator;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+bool KShipList::canAddShips()
+{
+ if(m_shipsadded >= 1)
+ return true;
+ return false;
+}
+
+void KShipList::addNewShip(int button, int fieldx, int fieldy)
+{
+ if(!addNewShip(!(button == LeftButton), fieldx, fieldy))
+ KMessageBox::information(0L, i18n("You cannot place the ship here."));
+}
+
+bool KShipList::addNewShip(bool vertical, int fieldx, int fieldy)
+{
+ QRect ship = vertical ? QRect(fieldx, fieldy, 1, m_shipsadded) : QRect(fieldx, fieldy, m_shipsadded, 1);
+ QRect field = QRect(0, 0, m_fieldx, m_fieldy);
+ if(!field.contains(ship))
+ return false;
+
+ for(KShip *placedShip = m_shiplist.first(); placedShip != 0; placedShip = m_shiplist.next())
+ {
+ for(int i = fieldx-1; i < (fieldx + ship.width()+1); i++)
+ {
+ if(placedShip->contains(i, fieldy - 1) || placedShip->contains(i, fieldy + ship.height()))
+ return false;
+ }
+
+ for(int i = fieldy-1; i < (fieldy + ship.height()+1); i++)
+ {
+ if(placedShip->contains(fieldx - 1, i) || placedShip->contains(fieldx + ship.width(), i))
+ return false;
+ }
+ }
+
+ m_shipsadded--;
+
+ if(!vertical)
+ m_shiplist.append(new KShip(fieldx, fieldx + shipCount(), fieldy, fieldy, shipCount(), true));
+ else
+ m_shiplist.append(new KShip(fieldx, fieldx, fieldy, fieldy + shipCount(), shipCount(), false));
+
+ for(int i = 0; i < shipCount() + 1; i++)
+ {
+ int start = 0;
+ if(shipCount() == 3)
+ start = KBattleField::SHIP4P1;
+ else if(shipCount() == 2)
+ start = KBattleField::SHIP3P1;
+ else if(shipCount() == 1)
+ start = KBattleField::SHIP2P1;
+ else if(shipCount() == 0)
+ start = KBattleField::SHIP1P1;
+
+ if(!vertical)
+ emit sigOwnFieldDataChanged(fieldx + i, fieldy, start + i);
+ else
+ emit sigOwnFieldDataChanged(fieldx, fieldy + i, start + i);
+ }
+
+ if(m_shipsadded == 0)
+ emit sigLastShipAdded();
+ return true;
+}
diff --git a/kbattleship/kbattleship/kshiplist.h b/kbattleship/kbattleship/kshiplist.h
new file mode 100644
index 00000000..59915a5b
--- /dev/null
+++ b/kbattleship/kbattleship/kshiplist.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ kshiplist.h
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+ (c) 2001 Kevin Krammer <kevin.krammer@gmx.at>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSHIPLIST_H
+#define KSHIPLIST_H
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qptrlist.h>
+#include "kbattlefield.h"
+#include "kship.h"
+
+class KShipList : public QObject
+{
+ Q_OBJECT
+public:
+ KShipList();
+
+ KShip *shipAt(int x, int y);
+ int shipTypeAt(int x, int y);
+
+ void clear();
+
+ void addNewShip(int button, int fieldx, int fieldy);
+ bool addNewShip(bool vertical, int fieldx, int fieldy);
+
+ bool canAddShips();
+
+ int shipCount() { return m_shipsadded; }
+
+ int m_fieldx;
+ int m_fieldy;
+
+signals:
+ void sigLastShipAdded();
+ void sigOwnFieldDataChanged(int, int, int);
+
+private:
+ QPtrList<KShip> m_shiplist;
+ int m_shipsadded;
+};
+
+#endif
diff --git a/kbattleship/kbattleship/kstatdialog.cpp b/kbattleship/kbattleship/kstatdialog.cpp
new file mode 100644
index 00000000..9db2afe4
--- /dev/null
+++ b/kbattleship/kbattleship/kstatdialog.cpp
@@ -0,0 +1,92 @@
+/***************************************************************************
+ kstatdlg.cpp
+ -------------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qlcdnumber.h>
+#include <qlabel.h>
+#include "kstatdialog.moc"
+
+KStatDialog::KStatDialog(QWidget *parent, const char *name) : statDlg(parent, name)
+{
+}
+
+void KStatDialog::slotAddOwnWon()
+{
+ OwnLabel->setText(QString::number(OwnLabel->text().toInt() + 1));
+}
+
+void KStatDialog::slotAddEnemyWon()
+{
+ EnemyLabel->setText(QString::number(EnemyLabel->text().toInt() + 1));
+}
+
+void KStatDialog::setShot()
+{
+ setShot(shot() + 1);
+}
+
+void KStatDialog::setShot(int shot)
+{
+ ShotLCD->display(shot);
+}
+
+void KStatDialog::setHit()
+{
+ setHit(hit() + 1);
+}
+
+void KStatDialog::setHit(int hit)
+{
+ HitLCD->display(hit);
+}
+
+void KStatDialog::setWater()
+{
+ setWater(water() + 1);
+}
+
+void KStatDialog::setWater(int water)
+{
+ WaterLCD->display(water);
+}
+
+void KStatDialog::clear()
+{
+ ShotLCD->display(0);
+ HitLCD->display(0);
+ WaterLCD->display(0);
+}
+
+void KStatDialog::clearWon()
+{
+ OwnLabel->setText(QString::number(0));
+ EnemyLabel->setText(QString::number(0));
+}
+
+int KStatDialog::shot()
+{
+ return ShotLCD->intValue();
+}
+
+int KStatDialog::hit()
+{
+ return HitLCD->intValue();
+}
+
+int KStatDialog::water()
+{
+ return WaterLCD->intValue();
+}
diff --git a/kbattleship/kbattleship/kstatdialog.h b/kbattleship/kbattleship/kstatdialog.h
new file mode 100644
index 00000000..fd9b3dd7
--- /dev/null
+++ b/kbattleship/kbattleship/kstatdialog.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ kstatdialog.h
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KSTATDIALOG_H
+#define KSTATDIALOG_H
+
+#include "dialogs/statDlg.h"
+
+class KStatDialog : public statDlg
+{
+ Q_OBJECT
+public:
+ KStatDialog(QWidget *parent = 0, const char *name = 0);
+
+ void setShot();
+ void setShot(int shot);
+ void setHit();
+ void setHit(int hit);
+ void setWater();
+ void setWater(int water);
+
+ void clear();
+ void clearWon();
+
+ int shot();
+ int hit();
+ int water();
+
+public slots:
+ void slotAddOwnWon();
+ void slotAddEnemyWon();
+};
+
+#endif
diff --git a/kbattleship/kbattleship/main.cpp b/kbattleship/kbattleship/main.cpp
new file mode 100644
index 00000000..2fdba01e
--- /dev/null
+++ b/kbattleship/kbattleship/main.cpp
@@ -0,0 +1,70 @@
+/***************************************************************************
+ main.cpp
+ ----------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include "kbattleship.h"
+
+extern const char *clientName, *clientVersion, *clientDescription;
+
+static KCmdLineOptions options[] =
+{
+ {"!+[URL]", I18N_NOOP("URL of server to attach to. In the form kbattleship://host:port/ or host:port"), 0},
+ KCmdLineLastOption
+};
+
+int main(int argc, char *argv[])
+{
+ KAboutData aboutData("kbattleship", clientName, clientVersion, clientDescription, KAboutData::License_GPL, "(c) 2000-2005 Nikolas Zimmermann, Daniel Molkentin");
+
+ aboutData.addAuthor("Nikolas Zimmermann", I18N_NOOP("Project Founder, GUI Handling, Client/Server"), "wildfox@kde.org");
+ aboutData.addAuthor("Daniel Molkentin", I18N_NOOP("Dialog Stuff, Client/Server"), "molkentin@kde.org");
+ aboutData.addAuthor("Kevin Krammer", I18N_NOOP("Computer Player"), "kevin.krammer@gmx.at");
+ aboutData.addCredit("Benjamin Adler", I18N_NOOP("Icon"), "benadler@bigfoot.de");
+ aboutData.addCredit("Nils Trzebin", I18N_NOOP("Sounds"), "nils.trzebin@stud.uni-hannover.de");
+ aboutData.addCredit("Elmar Hoefner", I18N_NOOP("GFX"), "elmar.hoefner@uibk.ac.at");
+ aboutData.addCredit("Lukas Tinkl", I18N_NOOP("Non-Latin1 Support"), "lukas@kde.org");
+ aboutData.addCredit("Malte Starostik", I18N_NOOP("Various improvements"), "malte.starostik@t-online.de");
+ aboutData.addCredit("Albert Astals Cid", I18N_NOOP("Various improvements and bugfixes"), "tsdgeos@terra.es");
+ aboutData.addCredit("John Tapsell", I18N_NOOP("Various improvements and bugfixes"), "john@geola.co.uk");
+ aboutData.addCredit("Inge Wallin", I18N_NOOP("Bugfixes and refactoring"), "inge@lysator.liu.se");
+ aboutData.addCredit("Jakub Stachowski", I18N_NOOP("DNS-SD discovery"), "qbast@go2.pl");
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+ KApplication app;
+ KGlobal::locale()->insertCatalogue("libkdegames");
+
+ QString picDirCheck = locate("data", "kbattleship/pictures/");
+ QString onePicCheck = locate("data", "kbattleship/pictures/hit.png");
+ if(picDirCheck.isEmpty() || onePicCheck.isEmpty())
+ {
+ KMessageBox::error(0, i18n("You don't have KBattleship pictures installed. The game cannot run without them!"));
+ return 1;
+ }
+
+ if( app.isRestored() )
+ RESTORE(KBattleshipWindow)
+ else {
+ KBattleshipWindow *mainwin = new KBattleshipWindow;
+ mainwin->show();
+ }
+ return app.exec();
+}
+
diff --git a/kbattleship/kbattleship/pictures/Makefile.am b/kbattleship/kbattleship/pictures/Makefile.am
new file mode 100644
index 00000000..5bb50353
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/Makefile.am
@@ -0,0 +1,30 @@
+picsdir = $(kde_datadir)/kbattleship/pictures
+pics_DATA = sea.png \
+ water.png \
+ hit.png \
+ death.png \
+ border.png \
+ ship1-1.png \
+ ship2-1.png \
+ ship2-2.png \
+ ship3-1.png \
+ ship3-2.png \
+ ship3-3.png \
+ ship4-1.png \
+ ship4-2.png \
+ ship4-3.png \
+ ship4-4.png \
+ ship1-1-r.png \
+ ship2-1-r.png \
+ ship2-2-r.png \
+ ship3-1-r.png \
+ ship3-2-r.png \
+ ship3-3-r.png \
+ ship4-1-r.png \
+ ship4-2-r.png \
+ ship4-3-r.png \
+ ship4-4-r.png
+
+KDE_ICON = kbattleship
+
+EXTRA_DIST = $(pics_DATA)
diff --git a/kbattleship/kbattleship/pictures/border.png b/kbattleship/kbattleship/pictures/border.png
new file mode 100644
index 00000000..575b7d6e
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/border.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/death.png b/kbattleship/kbattleship/pictures/death.png
new file mode 100644
index 00000000..518450a5
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/death.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/hi128-app-kbattleship.png b/kbattleship/kbattleship/pictures/hi128-app-kbattleship.png
new file mode 100644
index 00000000..93db2a3a
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/hi128-app-kbattleship.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/hi16-app-kbattleship.png b/kbattleship/kbattleship/pictures/hi16-app-kbattleship.png
new file mode 100644
index 00000000..b7971c96
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/hi16-app-kbattleship.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/hi22-app-kbattleship.png b/kbattleship/kbattleship/pictures/hi22-app-kbattleship.png
new file mode 100644
index 00000000..27b8816d
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/hi22-app-kbattleship.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/hi32-app-kbattleship.png b/kbattleship/kbattleship/pictures/hi32-app-kbattleship.png
new file mode 100644
index 00000000..07e05fa9
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/hi32-app-kbattleship.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/hi48-app-kbattleship.png b/kbattleship/kbattleship/pictures/hi48-app-kbattleship.png
new file mode 100644
index 00000000..2f501a41
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/hi48-app-kbattleship.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/hi64-app-kbattleship.png b/kbattleship/kbattleship/pictures/hi64-app-kbattleship.png
new file mode 100644
index 00000000..1b4ac1e1
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/hi64-app-kbattleship.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/hit.png b/kbattleship/kbattleship/pictures/hit.png
new file mode 100644
index 00000000..ca2684bc
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/hit.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/sea.png b/kbattleship/kbattleship/pictures/sea.png
new file mode 100644
index 00000000..ab14e95d
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/sea.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship1-1-r.png b/kbattleship/kbattleship/pictures/ship1-1-r.png
new file mode 100644
index 00000000..eb96026c
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship1-1-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship1-1.png b/kbattleship/kbattleship/pictures/ship1-1.png
new file mode 100644
index 00000000..4794706c
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship1-1.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship1-view.png b/kbattleship/kbattleship/pictures/ship1-view.png
new file mode 100644
index 00000000..eb96026c
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship1-view.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship2-1-r.png b/kbattleship/kbattleship/pictures/ship2-1-r.png
new file mode 100644
index 00000000..9dba502d
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship2-1-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship2-1.png b/kbattleship/kbattleship/pictures/ship2-1.png
new file mode 100644
index 00000000..b451e834
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship2-1.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship2-2-r.png b/kbattleship/kbattleship/pictures/ship2-2-r.png
new file mode 100644
index 00000000..2020e637
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship2-2-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship2-2.png b/kbattleship/kbattleship/pictures/ship2-2.png
new file mode 100644
index 00000000..6bfc6209
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship2-2.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship2-view.png b/kbattleship/kbattleship/pictures/ship2-view.png
new file mode 100644
index 00000000..7d175815
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship2-view.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship3-1-r.png b/kbattleship/kbattleship/pictures/ship3-1-r.png
new file mode 100644
index 00000000..d86e783f
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship3-1-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship3-1.png b/kbattleship/kbattleship/pictures/ship3-1.png
new file mode 100644
index 00000000..f67b6079
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship3-1.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship3-2-r.png b/kbattleship/kbattleship/pictures/ship3-2-r.png
new file mode 100644
index 00000000..1586eb25
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship3-2-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship3-2.png b/kbattleship/kbattleship/pictures/ship3-2.png
new file mode 100644
index 00000000..416c972d
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship3-2.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship3-3-r.png b/kbattleship/kbattleship/pictures/ship3-3-r.png
new file mode 100644
index 00000000..1d5dda2e
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship3-3-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship3-3.png b/kbattleship/kbattleship/pictures/ship3-3.png
new file mode 100644
index 00000000..ab1ada4b
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship3-3.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship3-view.png b/kbattleship/kbattleship/pictures/ship3-view.png
new file mode 100644
index 00000000..19bcb136
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship3-view.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-1-r.png b/kbattleship/kbattleship/pictures/ship4-1-r.png
new file mode 100644
index 00000000..4d25ab10
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-1-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-1.png b/kbattleship/kbattleship/pictures/ship4-1.png
new file mode 100644
index 00000000..51241360
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-1.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-2-r.png b/kbattleship/kbattleship/pictures/ship4-2-r.png
new file mode 100644
index 00000000..187f0b17
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-2-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-2.png b/kbattleship/kbattleship/pictures/ship4-2.png
new file mode 100644
index 00000000..59f03e8f
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-2.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-3-r.png b/kbattleship/kbattleship/pictures/ship4-3-r.png
new file mode 100644
index 00000000..351843b7
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-3-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-3.png b/kbattleship/kbattleship/pictures/ship4-3.png
new file mode 100644
index 00000000..d6242c14
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-3.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-4-r.png b/kbattleship/kbattleship/pictures/ship4-4-r.png
new file mode 100644
index 00000000..cfebae84
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-4-r.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-4.png b/kbattleship/kbattleship/pictures/ship4-4.png
new file mode 100644
index 00000000..b34c6ca2
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-4.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/ship4-view.png b/kbattleship/kbattleship/pictures/ship4-view.png
new file mode 100644
index 00000000..d1e53f62
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/ship4-view.png
Binary files differ
diff --git a/kbattleship/kbattleship/pictures/water.png b/kbattleship/kbattleship/pictures/water.png
new file mode 100644
index 00000000..8f4adc3d
--- /dev/null
+++ b/kbattleship/kbattleship/pictures/water.png
Binary files differ
diff --git a/kbattleship/kbattleship/sounds/Makefile.am b/kbattleship/kbattleship/sounds/Makefile.am
new file mode 100644
index 00000000..459b8e50
--- /dev/null
+++ b/kbattleship/kbattleship/sounds/Makefile.am
@@ -0,0 +1,5 @@
+sounddir = $(kde_datadir)/kbattleship/sounds
+sound_DATA = ship-player-shoot-water.ogg \
+ ship-player1-shoot.ogg \
+ ship-player2-shoot.ogg \
+ ship-sink.ogg
diff --git a/kbattleship/kbattleship/sounds/ship-player-shoot-water.ogg b/kbattleship/kbattleship/sounds/ship-player-shoot-water.ogg
new file mode 100644
index 00000000..ad677670
--- /dev/null
+++ b/kbattleship/kbattleship/sounds/ship-player-shoot-water.ogg
Binary files differ
diff --git a/kbattleship/kbattleship/sounds/ship-player1-shoot.ogg b/kbattleship/kbattleship/sounds/ship-player1-shoot.ogg
new file mode 100644
index 00000000..5fa88f22
--- /dev/null
+++ b/kbattleship/kbattleship/sounds/ship-player1-shoot.ogg
Binary files differ
diff --git a/kbattleship/kbattleship/sounds/ship-player2-shoot.ogg b/kbattleship/kbattleship/sounds/ship-player2-shoot.ogg
new file mode 100644
index 00000000..d4becd0a
--- /dev/null
+++ b/kbattleship/kbattleship/sounds/ship-player2-shoot.ogg
Binary files differ
diff --git a/kbattleship/kbattleship/sounds/ship-sink.ogg b/kbattleship/kbattleship/sounds/ship-sink.ogg
new file mode 100644
index 00000000..f5dfac9b
--- /dev/null
+++ b/kbattleship/kbattleship/sounds/ship-sink.ogg
Binary files differ