summaryrefslogtreecommitdiffstats
path: root/ktron
diff options
context:
space:
mode:
Diffstat (limited to 'ktron')
-rw-r--r--ktron/AUTHORS2
-rw-r--r--ktron/ChangeLog21
-rw-r--r--ktron/Makefile.am22
-rw-r--r--ktron/README39
-rw-r--r--ktron/TODO10
-rw-r--r--ktron/ai.ui141
-rw-r--r--ktron/appearance.ui302
-rw-r--r--ktron/general.ui219
-rw-r--r--ktron/ktron.cpp195
-rw-r--r--ktron/ktron.desktop66
-rw-r--r--ktron/ktron.h67
-rw-r--r--ktron/ktron.kcfg84
-rw-r--r--ktron/ktronui.rc3
-rw-r--r--ktron/main.cpp59
-rw-r--r--ktron/pics/Makefile.am15
-rw-r--r--ktron/pics/hi128-app-ktron.pngbin0 -> 10435 bytes
-rw-r--r--ktron/pics/hi16-app-ktron.pngbin0 -> 531 bytes
-rw-r--r--ktron/pics/hi22-app-ktron.pngbin0 -> 973 bytes
-rw-r--r--ktron/pics/hi32-app-ktron.pngbin0 -> 1490 bytes
-rw-r--r--ktron/pics/hi48-app-ktron.pngbin0 -> 2733 bytes
-rw-r--r--ktron/pics/hi64-app-ktron.pngbin0 -> 3971 bytes
-rw-r--r--ktron/player.cpp57
-rw-r--r--ktron/player.h56
-rw-r--r--ktron/settings.kcfgc5
-rw-r--r--ktron/tron.cpp1654
-rw-r--r--ktron/tron.h178
-rw-r--r--ktron/version.h1
27 files changed, 3196 insertions, 0 deletions
diff --git a/ktron/AUTHORS b/ktron/AUTHORS
new file mode 100644
index 00000000..2dc6d21a
--- /dev/null
+++ b/ktron/AUTHORS
@@ -0,0 +1,2 @@
+Matthias Kiefer <matthias.kiefer@gmx.de>
+Benjamin Meyer <ben at meyerhome dot net>
diff --git a/ktron/ChangeLog b/ktron/ChangeLog
new file mode 100644
index 00000000..317f9ac4
--- /dev/null
+++ b/ktron/ChangeLog
@@ -0,0 +1,21 @@
+Changes 1.0:
+- added possibility to load background images
+- added possibility to give names to players
+
+Changes 0.5:
+- new drawing style: 3d-line
+- new improved computerplayer with possibility to change the skill
+
+Changes 0.4:
+- worked over to compile with KDE 1.1.1
+- flickering fixed
+- added some options
+ (block accelerator, disable changing color)
+- some finetuning at drawing players and frame
+
+Changes 0.3.3:
+- use of bitBlt(...) to get less flickering
+- crashes are now shown by changing the color
+- after a crash, the game is blocked for one second
+- possiblity to change the size of the players
+- possibility to change style of the players
diff --git a/ktron/Makefile.am b/ktron/Makefile.am
new file mode 100644
index 00000000..e7629bd2
--- /dev/null
+++ b/ktron/Makefile.am
@@ -0,0 +1,22 @@
+SUBDIRS=pics
+
+bin_PROGRAMS = ktron
+INCLUDES = -I$(top_srcdir)/libkdegames $(all_includes)
+
+ktron_SOURCES = ai.ui appearance.ui general.ui tron.cpp player.cpp ktron.cpp main.cpp settings.kcfgc
+ktron_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+ktron_LDADD = $(LIB_KIO) $(LIB_KDEGAMES)
+ktron_DEPENDENCIES = $(LIB_KDEGAMES_DEP)
+
+EXTRA_DIST = ktron.desktop
+
+xdg_apps_DATA = ktron.desktop
+kde_kcfg_DATA = ktron.kcfg
+
+METASOURCES = AUTO
+
+rcdir = $(kde_datadir)/ktron
+rc_DATA = ktronui.rc
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/ktron.pot
diff --git a/ktron/README b/ktron/README
new file mode 100644
index 00000000..3f48d78d
--- /dev/null
+++ b/ktron/README
@@ -0,0 +1,39 @@
+Hello!
+
+KTron is a simple tron-clone for the K Desktop Environment.
+I think it's just nothing to say about the game:
+avoid running into walls, your own tail, and that of your opponent.
+
+Read the Online-Documentation for more details.
+
+
+Notice:
+Parts of the code, especially parts of the algorithm for the computerplayer
+are from xtron-1.1 by Rhett D. Jacobs <rhett@hotel.canberra.edu.au>
+
+
+Copyright:
+
+KTron
+
+Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+KTron 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 or any later version.
+
+KTron 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.
+
+
+Hope you have a lot of fun :-)
+
+---------------
+Matthias Kiefer <matthias.kiefer@gmx.de>
+27 February 2000
diff --git a/ktron/TODO b/ktron/TODO
new file mode 100644
index 00000000..6ff85f99
--- /dev/null
+++ b/ktron/TODO
@@ -0,0 +1,10 @@
+KTron in general does everything I wanted it to do. :-)
+
+Plans for the future are:
+- possibility to create, load, save playfield with walls
+- real cool would be to play KTron over the internet
+
+------------------
+Matthias Kiefer
+5/99
+
diff --git a/ktron/ai.ui b/ktron/ai.ui
new file mode 100644
index 00000000..3abcef57
--- /dev/null
+++ b/ktron/ai.ui
@@ -0,0 +1,141 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>Ai</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Ai</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>302</width>
+ <height>168</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame9</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Computer Controls</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_Computerplayer1</cstring>
+ </property>
+ <property name="text">
+ <string>Player &amp;1</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_Computerplayer2</cstring>
+ </property>
+ <property name="text">
+ <string>Player &amp;2</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>101</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel15</cstring>
+ </property>
+ <property name="text">
+ <string>Intelligence:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>Beginner</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Average</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Expert</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_Skill</cstring>
+ </property>
+ <property name="currentItem">
+ <number>1</number>
+ </property>
+ </widget>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>60</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/ktron/appearance.ui b/ktron/appearance.ui
new file mode 100644
index 00000000..af50183f
--- /dev/null
+++ b/ktron/appearance.ui
@@ -0,0 +1,302 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>Appearance</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Appearance</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>284</width>
+ <height>337</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame4</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel16</cstring>
+ </property>
+ <property name="text">
+ <string>Line style:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="2">
+ <item>
+ <property name="text">
+ <string>3D Line</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>3D Rectangles</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Flat</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Circles</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>kcfg_Style</cstring>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Line Size</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabel13</cstring>
+ </property>
+ <property name="text">
+ <string>Large</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel11</cstring>
+ </property>
+ <property name="text">
+ <string>Small</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabel12</cstring>
+ </property>
+ <property name="text">
+ <string>Medium</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QSlider" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kcfg_RectSize</cstring>
+ </property>
+ <property name="minValue">
+ <number>4</number>
+ </property>
+ <property name="maxValue">
+ <number>16</number>
+ </property>
+ <property name="lineStep">
+ <number>3</number>
+ </property>
+ <property name="pageStep">
+ <number>3</number>
+ </property>
+ <property name="value">
+ <number>10</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Right</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kcfg_BackgroundImageChoice</cstring>
+ </property>
+ <property name="title">
+ <string>Background</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>BackgroundColorChoice</cstring>
+ </property>
+ <property name="text">
+ <string>Color:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_BackgroundImage</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>BackgroundImageChoice</cstring>
+ </property>
+ <property name="text">
+ <string>Image:</string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_Color_Background</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="color">
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>Player 1 color:</string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="3" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_Color_Player1</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="color">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel8</cstring>
+ </property>
+ <property name="text">
+ <string>Player 2 color:</string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="4" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_Color_Player2</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="color">
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ </widget>
+ <spacer row="5" column="2">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>BackgroundColorChoice</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>kcfg_Color_Background</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>BackgroundImageChoice</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>kcfg_BackgroundImage</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>kcfg_Style</tabstop>
+ <tabstop>kcfg_RectSize</tabstop>
+ <tabstop>kcfg_Color_Player1</tabstop>
+ <tabstop>kcfg_Color_Player2</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kcolorbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/ktron/general.ui b/ktron/general.ui
new file mode 100644
index 00000000..ca492b9e
--- /dev/null
+++ b/ktron/general.ui
@@ -0,0 +1,219 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>General</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>General</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>379</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame4</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Behavior</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_ChangeWinnerColor</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Show winner by changing color</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_AcceleratorBlocked</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Disable acceleration</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_OppositeDirCrashes</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Crash when moving in the opposite direction</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Player Names</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_NamePlayer1</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_NamePlayer2</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Player 1:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Player 2:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Speed</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>kcfg_Velocity</cstring>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>9</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>5</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Right</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Slow</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Default</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>Fast</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/ktron/ktron.cpp b/ktron/ktron.cpp
new file mode 100644
index 00000000..67151ff0
--- /dev/null
+++ b/ktron/ktron.cpp
@@ -0,0 +1,195 @@
+/* ****************************************************************************
+ This file is part of the game 'KTron'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+ 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.
+
+ *****************************************************************************/
+
+#include "ktron.h"
+
+#include <kconfigdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kaction.h>
+#include <kstdgameaction.h>
+#include <kapplication.h>
+#include <kstatusbar.h>
+
+// Settings
+#include "settings.h"
+#include "general.h"
+#include "ai.h"
+#include "appearance.h"
+
+#define ID_STATUS_BASE 40
+#define MESSAGE_TIME 2000
+#define WINNING_DIFF 5
+
+/**
+ * Constuctor
+ */
+KTron::KTron(QWidget *parent, const char *name) : KMainWindow(parent, name) {
+ playerPoints[0]=playerPoints[1]=0;
+
+ tron=new Tron(this, "Tron");
+ connect(tron,SIGNAL(gameEnds(Player)),SLOT(changeStatus(Player)));
+ setCentralWidget(tron);
+ tron->setMinimumSize(200,180);
+
+ // create statusbar
+ statusBar()->insertItem("abcdefghijklmnopqrst: 0 ",ID_STATUS_BASE+1);
+ statusBar()->insertItem("abcdefghijklmnopqrst: 0 ",ID_STATUS_BASE+2);
+
+ // We match up keyboard events ourselves in Tron::keyPressEvent()
+ // We must disable the actions, otherwise we don't get the keyPressEvent's
+ KAction *act;
+ act = new KAction(i18n("Player 1 Up"), Key_R, 0, 0, actionCollection(), "Pl1Up");
+ act->setEnabled(false);
+ act = new KAction(i18n("Player 1 Down"), Key_F, 0, 0, actionCollection(), "Pl1Down");
+ act->setEnabled(false);
+ act = new KAction(i18n("Player 1 Right"), Key_G, 0, 0, actionCollection(), "Pl1Right");
+ act->setEnabled(false);
+ act = new KAction(i18n("Player 1 Left"), Key_D, 0, 0, actionCollection(), "Pl1Left");
+ act->setEnabled(false);
+ act = new KAction(i18n("Player 1 Accelerator"), Key_A, 0, 0, actionCollection(), "Pl1Ac");
+ act->setEnabled(false);
+
+ act = new KAction(i18n("Player 2 Up"), Key_Up, 0, 0, actionCollection(), "Pl2Up");
+ act->setEnabled(false);
+ act = new KAction(i18n("Player 2 Down"), Key_Down, 0, 0, actionCollection(), "Pl2Down");
+ act->setEnabled(false);
+ act = new KAction(i18n("Player 2 Right"), Key_Right, 0, 0, actionCollection(), "Pl2Right");
+ act->setEnabled(false);
+ act = new KAction(i18n("Player 2 Left"), Key_Left, 0, 0, actionCollection(), "Pl2Left");
+ act->setEnabled(false);
+ act = new KAction(i18n("Player 2 Accelerator"), Key_0, 0, 0, actionCollection(), "Pl2Ac");
+ act->setEnabled(false);
+
+ tron->setActionCollection(actionCollection());
+
+ KStdGameAction::pause(tron, SLOT(togglePause()), actionCollection());
+ KStdGameAction::gameNew( tron, SLOT( newGame() ), actionCollection() );
+ KStdGameAction::quit(this, SLOT( close() ), actionCollection());
+ KStdAction::preferences(this, SLOT(showSettings()), actionCollection());
+
+ setupGUI( KMainWindow::Keys | StatusBar | Save | Create);
+ loadSettings();
+}
+
+void KTron::loadSettings() {
+ playerName[0]=Settings::namePlayer1();
+ if ( playerName[0].isEmpty() )
+ playerName[0] = i18n("Player 1");
+ playerName[1]=Settings::namePlayer2();
+ if ( playerName[1].isEmpty() )
+ playerName[1] = i18n("Player 2");
+
+ updateStatusbar();
+}
+
+void KTron::updateStatusbar(){
+ for(int i=0;i<2;i++){
+ Player player;
+ player=(i==0?One:Two);
+
+ QString name;
+ if(tron->isComputer(Both))
+ name=i18n("Computer(%1)").arg(i+1);
+ else if(tron->isComputer(player))
+ name=i18n("Computer");
+ else
+ name=playerName[i];
+ QString string = QString("%1: %2").arg(name).arg(playerPoints[i]);
+ statusBar()->changeItem(string,ID_STATUS_BASE+i+1);
+ }
+}
+
+void KTron::changeStatus(Player player) {
+ // if player=Nobody, then new game
+ if(player==Nobody){
+ playerPoints[0]=playerPoints[1]=0;
+ updateStatusbar();
+ return;
+ }
+
+ if(player==One)
+ playerPoints[0]++;
+ else if(player==Two)
+ playerPoints[1]++;
+ else if(player==Both){
+ playerPoints[0]++;
+ playerPoints[1]++;
+ }
+
+ updateStatusbar();
+
+ if(playerPoints[0]>=WINNING_DIFF && playerPoints[1] < playerPoints[0]-1)
+ showWinner(One);
+ else if(playerPoints[1]>=WINNING_DIFF && playerPoints[0] < playerPoints[1]-1)
+ showWinner(Two);
+}
+
+void KTron::showWinner(Player winner){
+ if(tron->isComputer(Both) || (winner != One && winner != Two))
+ return;
+
+ QString loserName = i18n("KTron");
+ int loser = Two;
+ if(winner == Two)
+ loser = One;
+ if(!tron->isComputer(((Player)loser)))
+ loserName = playerName[loser];
+
+ QString winnerName = i18n("KTron");
+ if(!tron->isComputer(winner))
+ winnerName = playerName[winner];
+
+ QString message=i18n("%1 has won!").arg(winnerName);
+ statusBar()->message(message,MESSAGE_TIME);
+
+ message = i18n("%1 has won versus %2 with %3 : %4 points!");
+ message=message.arg(winnerName).arg(loserName);
+ message=message.arg(playerPoints[winner]).arg(playerPoints[loser]);
+
+ KMessageBox::information(this, message, i18n("Winner"));
+ tron->newGame();
+}
+
+void KTron::paletteChange(const QPalette &/*oldPalette*/){
+ update();
+ tron->updatePixmap();
+ tron->update();
+}
+
+/**
+ * Show Settings dialog.
+ */
+void KTron::showSettings(){
+ if(KConfigDialog::showDialog("settings"))
+ return;
+
+ KConfigDialog *dialog = new KConfigDialog(this, "settings", Settings::self());
+ dialog->addPage(new General(0, "General"), i18n("General"), "package_settings");
+ dialog->addPage(new Ai(0, "Ai"), i18n("A.I."), "personal");
+ dialog->addPage(new Appearance(0, "Appearance"), i18n("Appearance"), "style");
+ connect(dialog, SIGNAL(settingsChanged()), tron, SLOT(loadSettings()));
+ connect(dialog, SIGNAL(settingsChanged()), this, SLOT(loadSettings()));
+ dialog->show();
+}
+
+#include "ktron.moc"
+
diff --git a/ktron/ktron.desktop b/ktron/ktron.desktop
new file mode 100644
index 00000000..20930d16
--- /dev/null
+++ b/ktron/ktron.desktop
@@ -0,0 +1,66 @@
+[Desktop Entry]
+Type=Application
+Exec=ktron -caption "%c" %i %m
+Icon=ktron
+DocPath=ktron/index.html
+GenericName=Tron-like Game
+GenericName[be]=“уğь½Ñ ˘Ñ€½
+GenericName[bg]=›³¸Ñ‡µÑş° ¸³Ñ€°
+GenericName[bn]=àĤŸà§àĤ°àĤ¨-àĤœàĤàĤ¤à§€à§Ÿ àĤ–েàĤ²àĤ
+GenericName[br]=C'hoari doare Tron
+GenericName[bs]=Igra nalik na Tron
+GenericName[ca]=Joc a l'estil Tron
+GenericName[cs]=Hra podobnĦ Tronu
+GenericName[cy]=GŞm sy'n debyg i Tron
+GenericName[da]=Tron-lignende spil
+GenericName[de]=Tron-¤hnliches Spiel
+GenericName[el]=ΠÎħÎıÏ‡Î½ÎŻÎ´Îı πÎħρόÎĵÎżÎıÎż Îĵε Ï„Îż Tron
+GenericName[eo]="Tron"-simila ludo
+GenericName[es]=Juego similar a Tron
+GenericName[et]=Tron
+GenericName[eu]=Tron-en antzeko jokoa
+GenericName[fa]=Ĝ¨Ĝ§Ĝ²ÛŒ Ĝ´Ĝ¨ÛŒÙ‡Tron
+GenericName[fi]=Tron-tyylinen peli
+GenericName[fr]=Jeu dans le style de Tron
+GenericName[he]=מ×İחק חיקוי Tron
+GenericName[hr]=Igra poput Trona
+GenericName[hu]=Tron-szerĊħ
+GenericName[is]=Leikur sem l­kist Tron
+GenericName[it]=Gioco simile a Tron
+GenericName[ja]=ƒˆƒ­ƒ³‚ˆ†Ş‚²ƒĵƒ 
+GenericName[km]=ល្បែង​ដážĵច Tron
+GenericName[lv]=Tron lÄĞdzÄĞga spēle
+GenericName[mk]=˜³Ñ€° сğ¸Ñ‡½° ½° Tron
+GenericName[nb]=Tron-lignende spill
+GenericName[nds]=Tron-liek Speel
+GenericName[ne]=टàà¤°à‹à¤¨ जसàà¤¤àˆ खà‡à¤²
+GenericName[nl]=Tron-achtig spel
+GenericName[nn]=Tron-liknande spel
+GenericName[pl]=Gra typu Tron
+GenericName[pt]=Jogo tipo Tron
+GenericName[pt_BR]=Jogo parecido com Tron
+GenericName[ru]=˘Ñ€½
+GenericName[se]=Tron-lĦgan speallu
+GenericName[sk]=Hra typu Tron
+GenericName[sl]=Igra podobna Tronu
+GenericName[sr]=˜³Ñ€° ½°ğ¸ş ½° Tron
+GenericName[sr@Latn]=Igra nalik na Tron
+GenericName[sv]=Tron-liknande spel
+GenericName[ta]=àŸàŻà°àŻ‹àİàŻ àŞàŻ‹àİàŻàħ àµàżà³àŻˆàŻààŸàŻàŸàŻ
+GenericName[uk]=“Ñ€° схĥ° ½° ³Ñ€Ñƒ "˘Ñ€½"
+GenericName[zh_TW]=éĦžäĵĵ Tron 遊ĉˆ²
+Terminal=false
+Name=KTron
+Name[af]=Ktron
+Name[be]=˘Ñ€½
+Name[bn]=àĤ•à§‡-àĤŸà§àĤ°àĤ¨
+Name[hi]=कà‡-टàà¤°à¤à¤¨
+Name[nb]=Tron
+Name[ne]=कà‡à¤Ħà€à¤ˆ टàà¤°à‹à¤¨
+Name[sv]=Ktron
+Name[ta]=KàŸàŻà°ààİàŻ
+Name[tg]=K˘Ñ€½
+Name[zu]=I-KTron
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Game;ArcadeGame;
diff --git a/ktron/ktron.h b/ktron/ktron.h
new file mode 100644
index 00000000..191f2b44
--- /dev/null
+++ b/ktron/ktron.h
@@ -0,0 +1,67 @@
+/* ***************************************************************************
+ This file is part of the game 'KTron'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+ 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.
+
+ ****************************************************************************/
+
+#ifndef KTRON_H
+#define KTRON_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kmainwindow.h>
+#include "tron.h"
+
+class KAccel;
+class KSelectAction;
+class Tron;
+
+/**
+ * @short The main window of KTron
+ */
+class KTron : public KMainWindow {
+
+Q_OBJECT
+
+public:
+ KTron(QWidget *parent=0, const char *name=0);
+
+private:
+ KAccel *accel;
+ Tron *tron;
+ QString playerName[2];
+ int playerPoints[2];
+ void updateStatusbar();
+
+protected:
+ /** calls tron->updatePixmap to draw frame in the new colors */
+ void paletteChange(const QPalette &oldPalette);
+
+private slots:
+ void loadSettings();
+ /** updates players points in statusbar and checks if someone has won */
+ void changeStatus(Player);
+
+ void showWinner(Player winner);
+ void showSettings();
+};
+
+#endif // KTRON_H
+
diff --git a/ktron/ktron.kcfg b/ktron/ktron.kcfg
new file mode 100644
index 00000000..d46c2a76
--- /dev/null
+++ b/ktron/ktron.kcfg
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="ktronrc"/>
+ <group name="Game">
+ <entry name="Color_Background" type="Color">
+ <label>The background color of the game.</label>
+ <default>black</default>
+ </entry>
+ <entry name="Color_Player1" type="Color">
+ <label>The color of player 1</label>
+ <default>red</default>
+ </entry>
+ <entry name="Color_Player2" type="Color">
+ <label>The color of player 2</label>
+ <default>blue</default>
+ </entry>
+ <entry name="ChangeWinnerColor" type="Bool">
+ <label>Whether to show the winner by changing color.</label>
+ <default>true</default>
+ </entry>
+ <entry name="AcceleratorBlocked" type="Bool">
+ <label>Whether to disable acceleration.</label>
+ <default>false</default>
+ </entry>
+ <entry name="OppositeDirCrashes" type="Bool">
+ <label>Whether changing in the opposite direction causes a crash.</label>
+ <default>false</default>
+ </entry>
+ <entry name="RectSize" type="Int">
+ <label>The width of the line.</label>
+ <default>10</default>
+ </entry>
+ <entry name="Velocity" type="Int">
+ <label>The speed of the line.</label>
+ <default>5</default>
+ </entry>
+
+ <entry name="Skill" type="Enum">
+ <label>The skill of the computer player.</label>
+ <choices>
+ <choice name="Easy"/>
+ <choice name="Medium"/>
+ <choice name="Hard"/>
+ </choices>
+ <default>Medium</default>
+ </entry>
+ <entry name="Style" type="Enum">
+ <label>The line style.</label>
+ <choices>
+ <choice name="OLine"/>
+ <choice name="ORect"/>
+ <choice name="Line"/>
+ <choice name="Circle"/>
+ </choices>
+ <default>OLine</default>
+ </entry>
+
+ <entry name="BackgroundImageChoice" type="Bool">
+ <label>Whether to use a custom background image.</label>
+ <default>false</default>
+ </entry>
+ <entry name="BackgroundImage" type="Path">
+ <label>Custom background image to use.</label>
+ </entry>
+
+ <entry name="Computerplayer1" type="Bool">
+ <label>Whether player 1 is a computer player.</label>
+ <default>true</default>
+ </entry>
+ <entry name="Computerplayer2" type="Bool">
+ <label>Whether player 2 is a computer player.</label>
+ <default>false</default>
+ </entry>
+ <entry name="NamePlayer1" type="String" key="Name_Pl1">
+ <label>The name of player 1.</label>
+ </entry>
+ <entry name="NamePlayer2" type="String" key="Name_Pl2">
+ <label>The name of player 2.</label>
+ </entry>
+ </group>
+</kcfg>
diff --git a/ktron/ktronui.rc b/ktron/ktronui.rc
new file mode 100644
index 00000000..2d5a6c99
--- /dev/null
+++ b/ktron/ktronui.rc
@@ -0,0 +1,3 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="ktron" version="3">
+</kpartgui>
diff --git a/ktron/main.cpp b/ktron/main.cpp
new file mode 100644
index 00000000..17be8fe1
--- /dev/null
+++ b/ktron/main.cpp
@@ -0,0 +1,59 @@
+/******************************************************************************
+ This file is part of the game 'KTron'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+ 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.
+
+ ****************************************************************************/
+#include <kapplication.h>
+#include <kimageio.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+
+#include "ktron.h"
+#include "version.h"
+
+static const char description[] = I18N_NOOP("A race in hyperspace");
+static const char notice[] = I18N_NOOP("(c) 1998-2000, Matthias Kiefer\n\n"
+"Parts of the algorithms for the computer player are from\n"
+"xtron-1.1 by Rhett D. Jacobs <rhett@hotel.canberra.edu.au>");
+
+
+int main(int argc, char* argv[])
+{
+ KAboutData aboutData( "ktron", I18N_NOOP("KTron"),
+ KTRON_VERSION, description, KAboutData::License_GPL, notice);
+ aboutData.addAuthor("Matthias Kiefer",I18N_NOOP("Original author"), "matthias.kiefer@gmx.de");
+ aboutData.addAuthor("Benjamin Meyer",I18N_NOOP("Various improvements"), "ben+ktron@meyerhome.net");
+ KCmdLineArgs::init( argc, argv, &aboutData );
+
+ KApplication a;
+ KGlobal::locale()->insertCatalogue("libkdegames");
+
+ // used for loading background pixmaps
+ KImageIO::registerFormats();
+
+ if(a.isRestored()){
+ RESTORE(KTron)
+ }
+ else {
+ KTron *ktron = new KTron();
+ a.setMainWidget(ktron);
+ ktron->show();
+ }
+ return a.exec();
+}
+
diff --git a/ktron/pics/Makefile.am b/ktron/pics/Makefile.am
new file mode 100644
index 00000000..751de516
--- /dev/null
+++ b/ktron/pics/Makefile.am
@@ -0,0 +1,15 @@
+KDE_ICON=AUTO
+
+generate:
+ @echo "Converting SVG files to PNG files. Sizes: 16x16; 22x22; 32x32; 48x48; 64x64; 128x128"
+
+ @for file in *.svg*; do \
+ echo "Processing: $$file..."; \
+ ksvgtopng 16 16 $$file `basename $$file | sed -e 's/crsc/cr16/' | sed -e 's/svg\|svgz/png/'`; \
+ ksvgtopng 22 22 $$file `basename $$file | sed -e 's/crsc/cr22/' | sed -e 's/svg\|svgz/png/'`; \
+ ksvgtopng 32 32 $$file `basename $$file | sed -e 's/crsc/cr32/' | sed -e 's/svg\|svgz/png/'`; \
+ ksvgtopng 48 48 $$file `basename $$file | sed -e 's/crsc/cr48/' | sed -e 's/svg\|svgz/png/'`; \
+ ksvgtopng 64 64 $$file `basename $$file | sed -e 's/crsc/cr64/' | sed -e 's/svg\|svgz/png/'`; \
+ ksvgtopng 128 128 $$file `basename $$file | sed -e 's/crsc/cr128/' | sed -e 's/svg\|svgz/png/'`; \
+ done
+
diff --git a/ktron/pics/hi128-app-ktron.png b/ktron/pics/hi128-app-ktron.png
new file mode 100644
index 00000000..a2433c02
--- /dev/null
+++ b/ktron/pics/hi128-app-ktron.png
Binary files differ
diff --git a/ktron/pics/hi16-app-ktron.png b/ktron/pics/hi16-app-ktron.png
new file mode 100644
index 00000000..c6ee2edf
--- /dev/null
+++ b/ktron/pics/hi16-app-ktron.png
Binary files differ
diff --git a/ktron/pics/hi22-app-ktron.png b/ktron/pics/hi22-app-ktron.png
new file mode 100644
index 00000000..2058ee2e
--- /dev/null
+++ b/ktron/pics/hi22-app-ktron.png
Binary files differ
diff --git a/ktron/pics/hi32-app-ktron.png b/ktron/pics/hi32-app-ktron.png
new file mode 100644
index 00000000..2d96ffec
--- /dev/null
+++ b/ktron/pics/hi32-app-ktron.png
Binary files differ
diff --git a/ktron/pics/hi48-app-ktron.png b/ktron/pics/hi48-app-ktron.png
new file mode 100644
index 00000000..5cc088f1
--- /dev/null
+++ b/ktron/pics/hi48-app-ktron.png
Binary files differ
diff --git a/ktron/pics/hi64-app-ktron.png b/ktron/pics/hi64-app-ktron.png
new file mode 100644
index 00000000..8961e2d0
--- /dev/null
+++ b/ktron/pics/hi64-app-ktron.png
Binary files differ
diff --git a/ktron/player.cpp b/ktron/player.cpp
new file mode 100644
index 00000000..76cef9de
--- /dev/null
+++ b/ktron/player.cpp
@@ -0,0 +1,57 @@
+/**********************************************************************************
+ This file is part of the game 'KTron'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+ 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.
+
+ *******************************************************************************/
+
+#include "player.h"
+
+player::player()
+{
+ computer=false;
+ score=0;
+ reset();
+ dir=Directions::Up;
+ last_dir=Directions::None;
+}
+
+
+void player::reset()
+{
+ alive=true;
+ accelerated=false;
+ if(computer)
+ keyPressed=true;
+ else
+ keyPressed=false;
+}
+
+void player::setCoordinates(int x, int y)
+{
+ xCoordinate=x;
+ yCoordinate=y;
+}
+
+void player::setComputer(bool isComputer)
+{
+ computer=isComputer;
+ if(computer)
+ keyPressed=true;
+ else keyPressed=false;
+}
+
diff --git a/ktron/player.h b/ktron/player.h
new file mode 100644
index 00000000..eefad62c
--- /dev/null
+++ b/ktron/player.h
@@ -0,0 +1,56 @@
+/* ********************************************************************************
+ This file is part of the kde-game 'KTron'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+ 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.
+
+ *******************************************************************************/
+
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+namespace Directions
+{
+ enum Direction{ None, Up, Down, Left, Right};
+}
+
+/**
+* @short This class represents a player with current position and several flags
+*/
+class player
+{
+public:
+ player();
+ void reset();
+ void setCoordinates(int x, int y);
+ void setComputer(bool computer);
+
+ int xCoordinate,yCoordinate;
+ int score;
+ bool alive;
+ Directions::Direction dir;
+ Directions::Direction last_dir;
+ bool accelerated;
+ bool keyPressed;
+ bool computer;
+};
+
+#endif
+
diff --git a/ktron/settings.kcfgc b/ktron/settings.kcfgc
new file mode 100644
index 00000000..de60e440
--- /dev/null
+++ b/ktron/settings.kcfgc
@@ -0,0 +1,5 @@
+# Code generation options for kconfig_compiler
+File=ktron.kcfg
+ClassName=Settings
+Singleton=true
+Mutators=false
diff --git a/ktron/tron.cpp b/ktron/tron.cpp
new file mode 100644
index 00000000..494d96bc
--- /dev/null
+++ b/ktron/tron.cpp
@@ -0,0 +1,1654 @@
+/****************************************************************************
+ This file is part of the game 'KTron'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+ 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.
+
+ ***************************************************************************/
+// Background
+#include <kio/netaccess.h>
+#include <kmessagebox.h>
+
+// Normal class
+#include <qtimer.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcolordialog.h>
+#include <kaction.h>
+
+#include "settings.h"
+#include "tron.h"
+
+#define TRON_FRAMESIZE 2
+
+/**
+ * init-functions
+ **/
+
+Tron::Tron(QWidget *parent,const char *name)
+ : QWidget(parent,name)
+{
+ pixmap=0;
+ playfield=0;
+ beginHint=false;
+ lookForward=15;
+
+ random.setSeed(0);
+
+ setFocusPolicy(QWidget::StrongFocus);
+ setBackgroundMode(NoBackground);
+
+ gameBlocked=false;
+ rectSize=10;
+
+ timer = new QTimer(this,"timer");
+ loadSettings();
+ connect(timer, SIGNAL(timeout()), SLOT(doMove()));
+ QTimer::singleShot(15000, this,SLOT(showBeginHint()));
+}
+
+void Tron::loadSettings(){
+ setPalette(Settings::color_Background());
+
+ // Size
+ int newSize = Settings::rectSize();
+ if(newSize!=rectSize){
+ rectSize=newSize;
+ createNewPlayfield();
+ }
+
+ reset();
+
+ // Velocity
+ setVelocity( Settings::velocity() );
+
+ // Style
+ if(pixmap){
+ updatePixmap();
+ repaint();
+ }
+
+ // Backgroundimage
+ setBackgroundPix(NULL);
+ if(Settings::backgroundImageChoice()){
+ KURL url ( Settings::backgroundImage() );
+ if(!url.isEmpty()){
+ QString tmpFile;
+ KIO::NetAccess::download(url, tmpFile, this);
+ QPixmap pix(tmpFile);
+ if(!pix.isNull()){
+ setBackgroundPix(pix);
+ } else {
+ QString msg=i18n("Wasn't able to load wallpaper\n%1");
+ msg=msg.arg(tmpFile);
+ KMessageBox::sorry(this, msg);
+ }
+ KIO::NetAccess::removeTempFile(tmpFile);
+ }
+ else setBackgroundPix(NULL);
+ }
+ setComputerplayer(One, Settings::computerplayer1());
+ setComputerplayer(Two, Settings::computerplayer2());
+}
+
+Tron::~Tron()
+{
+ if(playfield)
+ {
+ delete [] playfield;
+ }
+ if(pixmap)
+ delete pixmap;
+ delete timer;
+
+}
+
+void Tron::createNewPlayfield()
+{
+ if(playfield)
+ delete [] playfield;
+
+ if(pixmap)
+ delete pixmap;
+
+ // field size
+ fieldWidth=(width()-2*TRON_FRAMESIZE)/rectSize;
+ fieldHeight=(height()-2*TRON_FRAMESIZE)/rectSize;
+
+ // start positions
+ playfield=new QMemArray<int>[fieldWidth];
+ for(int i=0;i<fieldWidth;i++)
+ playfield[i].resize(fieldHeight);
+
+ pixmap=new QPixmap(size());
+ pixmap->fill(Settings::color_Background());
+
+ //int min=(fieldWidth<fieldHeight) ? fieldWidth : fieldHeight;
+ //lookForward=min/4;
+}
+
+void Tron::newGame()
+{
+ players[0].score=0;
+ players[1].score=0;
+ emit gameEnds(Nobody);
+ reset();
+
+ QTimer::singleShot(15000,this,SLOT(showBeginHint()));
+}
+
+void Tron::reset()
+{
+ gamePaused=false;
+ stopGame();
+
+ players[0].reset();
+ players[1].reset();
+
+ // If playfield exists, then clean it
+ // ans set start coordinates
+ if(playfield)
+ {
+ int i;
+ for(i=0;i<fieldWidth;i++)
+ playfield[i].fill(BACKGROUND);
+
+ // set start coordinates
+
+ players[0].setCoordinates(fieldWidth/3, fieldHeight/2);
+ players[1].setCoordinates(2*fieldWidth/3, fieldHeight/2);
+
+ playfield[players[0].xCoordinate][players[0].yCoordinate]=
+ PLAYER1 | TOP | BOTTOM | LEFT | RIGHT;
+ playfield[players[1].xCoordinate][players[1].yCoordinate]=
+ PLAYER2 | TOP | BOTTOM | LEFT | RIGHT;
+
+ updatePixmap();
+ update();
+ }
+
+ setFocus();
+
+ emit gameReset();
+}
+
+void Tron::computerStart()
+{
+ if(isComputer(Both))
+ {
+ reset();
+ startGame();
+ }
+}
+
+/* *************************************************************** **
+** ??? functions **
+** *************************************************************** */
+
+void Tron::startGame()
+{
+ gameEnded=false;
+ beginHint=false;
+ timer->start(velocity);
+}
+
+void Tron::stopGame()
+{
+ timer->stop();
+ gameEnded=true;
+ players[0].last_dir = Directions::None;
+ players[1].last_dir = Directions::None;
+}
+
+void Tron::togglePause() // pause or continue game
+{
+ if(!gameEnded)
+ {
+ if(gamePaused)
+ {
+ gamePaused=false;
+ update();
+ timer->start(velocity);
+ }
+ else
+ {
+ gamePaused=true;
+ timer->stop();
+ update();
+ }
+ }
+}
+
+void Tron::showWinner(Player player)
+{
+ int i,j;
+
+ if(player != Both && Settings::changeWinnerColor())
+ {
+ int winner;
+ int loser;
+ if(player==One)
+ {
+ winner=PLAYER1;
+ loser=PLAYER2;
+ }
+ else
+ {
+ winner=PLAYER2;
+ loser=PLAYER1;
+ }
+
+ for(i=0;i<fieldWidth;i++)
+ for(j=0;j<fieldHeight;j++)
+ {
+ if(playfield[i][j]!=BACKGROUND)
+ {
+ // change player
+ playfield[i][j] |= winner;
+ playfield[i][j] &= ~loser;
+ }
+ }
+
+ updatePixmap();
+ }
+
+ repaint();
+
+ emit gameEnds(player);
+
+ if(isComputer(Both))
+ {
+ QTimer::singleShot(1000,this,SLOT(computerStart()));
+ }
+}
+
+/* *************************************************************** **
+** paint functions **
+** *************************************************************** */
+
+void Tron::updatePixmap()
+{
+ int i,j;
+
+ if(!bgPix.isNull())
+ {
+ int pw=bgPix.width();
+ int ph=bgPix.height();
+ for (int x = 0; x <= width(); x+=pw)
+ for (int y = 0; y <= height(); y+=ph)
+ bitBlt(pixmap, x, y, &bgPix);
+ }
+ else
+ {
+ pixmap->fill(Settings::color_Background());
+ }
+
+ QPainter p;
+ p.begin(pixmap);
+
+ // alle Pixel prüfen und evt. zeichnen
+ for(i=0;i<fieldWidth;i++)
+ for(j=0;j<fieldHeight;j++)
+ {
+ if(playfield[i][j]!=BACKGROUND)
+ {
+ drawRect(p,i,j);
+ }
+ }
+
+ // draw frame
+ QColor light=parentWidget()->colorGroup().midlight();
+ QColor dark=parentWidget()->colorGroup().mid();
+
+ p.setPen(NoPen);
+ p.setBrush(light);
+ p.drawRect(width()-TRON_FRAMESIZE,0,TRON_FRAMESIZE,height());
+ p.drawRect(0,height()-TRON_FRAMESIZE,width(),TRON_FRAMESIZE);
+ p.setBrush(dark);
+ p.drawRect(0,0,width(),TRON_FRAMESIZE);
+ p.drawRect(0,0,TRON_FRAMESIZE,height());
+
+ p.end();
+}
+
+// draw new player rects
+void Tron::paintPlayers()
+{
+ QPainter p;
+ p.begin(this);
+ drawRect(p,players[0].xCoordinate,players[0].yCoordinate);
+ drawRect(p,players[1].xCoordinate,players[1].yCoordinate);
+ p.end();
+
+ p.begin(pixmap);
+ drawRect(p,players[0].xCoordinate,players[0].yCoordinate);
+ drawRect(p,players[1].xCoordinate,players[1].yCoordinate);
+ p.end();
+}
+
+void Tron::drawRect(QPainter & p, int x, int y)
+{
+ int xOffset=x*rectSize+(width()-fieldWidth*rectSize)/2;
+ int yOffset=y*rectSize+(height()-fieldHeight*rectSize)/2;
+
+ int type=playfield[x][y];
+
+ // find out which color to draw
+ QColor toDraw;
+ int player;
+ if(type&PLAYER1) // check player bit
+ {
+ toDraw=Settings::color_Player1();
+ player=0;
+ }
+ else if(type&PLAYER2)
+ {
+ toDraw=Settings::color_Player2();
+ player=1;
+ }
+ else
+ {
+ kdDebug() << "No player defined in Tron::drawRect(...)" << endl;
+ return;
+ }
+
+ switch(Settings::style())
+ {
+ case Settings::EnumStyle::Line:
+ p.setBrush(toDraw);
+ p.setPen(toDraw);
+ p.drawRect(xOffset,yOffset,rectSize,rectSize);
+ break;
+ case Settings::EnumStyle::OLine:
+ {
+ p.setBrush(toDraw);
+ p.setPen(toDraw);
+ p.drawRect(xOffset,yOffset,rectSize,rectSize);
+ p.setPen(toDraw.light());
+ if(type&TOP)
+ {
+ p.drawLine(xOffset,yOffset,xOffset+rectSize-1,yOffset);
+ }
+ if(type&LEFT)
+ {
+ p.drawLine(xOffset,yOffset,xOffset,yOffset+rectSize-1);
+ }
+ p.setPen(toDraw.dark());
+ if(type&RIGHT)
+ {
+ p.drawLine(xOffset+rectSize-1,yOffset,xOffset+rectSize-1,yOffset+rectSize-1);
+ }
+ if(type&BOTTOM)
+ {
+ p.drawLine(xOffset,yOffset+rectSize-1,xOffset+rectSize-1,yOffset+rectSize-1);
+ }
+
+ break;
+ }
+ case Settings::EnumStyle::Circle:
+ p.setBrush(toDraw);
+ p.setPen(toDraw);
+ p.drawEllipse(xOffset ,yOffset ,rectSize,rectSize);
+ break;
+ case Settings::EnumStyle::ORect:
+ p.setBrush(toDraw);
+ p.setPen(toDraw.light());
+ p.drawRect(xOffset,yOffset,rectSize,rectSize);
+ p.setPen(toDraw.dark());
+ p.drawLine(xOffset,yOffset+rectSize-1,xOffset+rectSize-1
+ ,yOffset+rectSize-1);
+ p.drawLine(xOffset+rectSize-1,yOffset,xOffset+rectSize-1,yOffset+rectSize-1);
+ break;
+ }
+}
+
+/* *************************************************************** **
+** config functions **
+** *************************************************************** */
+
+void Tron::setActionCollection(KActionCollection *a)
+{
+ actionCollection = a;
+}
+
+void Tron::setBackgroundPix(QPixmap pix)
+{
+ bgPix=pix;
+
+ if(pixmap!=0){
+ updatePixmap();
+ // most pictures have colors, that you can read white text
+ setPalette(QColor("black"));
+ }
+}
+
+void Tron::setVelocity(int newVel) // set new velocity
+{
+ velocity=(10-newVel)*15;
+
+ if(!gameEnded && !gamePaused)
+ timer->changeInterval(velocity);
+}
+
+void Tron::setComputerplayer(Player player, bool flag) {
+ if(player==One)
+ players[0].setComputer(flag);
+ else if(player==Two)
+ players[1].setComputer(flag);
+
+ if(isComputer(Both))
+ QTimer::singleShot(1000,this,SLOT(computerStart()));
+}
+
+bool Tron::isComputer(Player player)
+{
+ if(player==One)
+ return players[0].computer;
+ else if(player==Two)
+ return players[1].computer;
+ else if(player==Both)
+ {
+ if(players[0].computer && players[1].computer)
+ return true;
+ }
+
+ return false;
+}
+
+/* *************************************************************** **
+** moving functions **
+** *************************************************************** */
+
+bool Tron::crashed(int playerNr,int xInc, int yInc) const
+{
+ bool flag;
+ int newX=players[playerNr].xCoordinate+xInc;
+ int newY=players[playerNr].yCoordinate+yInc;
+
+ if(newX<0 || newY <0 || newX>=fieldWidth || newY>=fieldHeight)
+ flag=true;
+ else if(playfield[newX][newY] != BACKGROUND)
+ flag=true;
+ else flag=false;
+
+ return flag;
+}
+
+void Tron::switchDir(int playerNr,Directions::Direction newDirection)
+{
+ if(playerNr!=0 && playerNr != 1)
+ {
+ kdDebug() << "wrong playerNr" << endl;
+ return;
+ }
+
+ if (Settings::oppositeDirCrashes()==false)
+ {
+ if (newDirection==Directions::Up && players[playerNr].last_dir==Directions::Down)
+ return;
+ if (newDirection==Directions::Down && players[playerNr].last_dir==Directions::Up)
+ return;
+ if (newDirection==Directions::Left && players[playerNr].last_dir==Directions::Right)
+ return;
+ if (newDirection==Directions::Right && players[playerNr].last_dir==Directions::Left)
+ return;
+ }
+
+ players[playerNr].dir=newDirection;
+}
+
+void Tron::updateDirections(int playerNr)
+{
+ if(playerNr==-1 || playerNr==0)
+ {
+ int x=players[0].xCoordinate;
+ int y=players[0].yCoordinate;
+
+ // necessary for drawing the 3d-line
+ switch(players[0].dir)
+ {
+ // unset drawing flags in the moving direction
+ case Directions::Up:
+ {
+ playfield[x][y] &= (~TOP);
+ break;
+ }
+ case Directions::Down:
+ playfield[x][y] &= (~BOTTOM);
+ break;
+ case Directions::Right:
+ playfield[x][y] &= (~RIGHT);
+ break;
+ case Directions::Left:
+ playfield[x][y] &= (~LEFT);
+ break;
+ default:
+ break;
+ }
+ players[0].last_dir = players[0].dir;
+
+ }
+ if(playerNr==-1 || playerNr==1)
+ {
+ int x=players[1].xCoordinate;
+ int y=players[1].yCoordinate;
+
+ // necessary for drawing the 3d-line
+ switch(players[1].dir)
+ {
+ // unset drawing flags in the moving direction
+ case Directions::Up:
+ {
+ playfield[x][y] &= (~TOP);
+ break;
+ }
+ case Directions::Down:
+ playfield[x][y] &= (~BOTTOM);
+ break;
+ case Directions::Right:
+ playfield[x][y] &= (~RIGHT);
+ break;
+ case Directions::Left:
+ playfield[x][y] &= (~LEFT);
+ break;
+ default:
+ break;
+ }
+ players[1].last_dir = players[1].dir;
+
+ }
+
+ paintPlayers();
+}
+
+/* *************************************************************** **
+** Events **
+** *************************************************************** */
+
+void Tron::paintEvent(QPaintEvent *e)
+{
+ bitBlt(this,e->rect().topLeft(),pixmap,e->rect());
+
+ // if game is paused, print message
+ if(gamePaused)
+ {
+ QString message=i18n("Game paused");
+ QPainter p(this);
+ QFontMetrics fm=p.fontMetrics();
+ int w=fm.width(message);
+ p.drawText(width()/2-w/2,height()/2,message);
+ }
+
+ // If game ended, print "Crash!"
+ else if(gameEnded)
+ {
+ QString message=i18n("Crash!");
+ QPainter p(this);
+ int w=p.fontMetrics().width(message);
+ int h=p.fontMetrics().height();
+ for(int i=0;i<2;i++)
+ {
+ if(!players[i].alive)
+ {
+ int x=players[i].xCoordinate*rectSize;
+ int y=players[i].yCoordinate*rectSize;
+ while(x<0) x+=rectSize;
+ while(x+w>width()) x-=rectSize;
+ while(y-h<0) y+=rectSize;
+ while(y>height()) y-=rectSize;
+ p.drawText(x,y,message);
+ }
+ }
+
+ // draw begin hint
+ if(beginHint)
+ {
+ QString hint=i18n("Press any of your direction keys to start!");
+ int x=p.fontMetrics().width(hint);
+ x=(width()-x)/2;
+ int y=height()/2;
+
+ p.drawText(x,y,hint);
+ }
+ }
+}
+
+void Tron::resizeEvent(QResizeEvent *)
+{
+ createNewPlayfield();
+ reset();
+}
+
+void Tron::keyPressEvent(QKeyEvent *e)
+{
+ KKey key(e);
+ if(!players[1].computer)
+ {
+ if(actionCollection->action("Pl2Up")->shortcut().contains(key))
+ {
+ switchDir(1,Directions::Up);
+ players[1].keyPressed=true;
+ }
+ else if(actionCollection->action("Pl2Left")->shortcut().contains(key))
+ {
+ switchDir(1,Directions::Left);
+ players[1].keyPressed=true;
+ }
+ else if(actionCollection->action("Pl2Right")->shortcut().contains(key))
+ {
+ switchDir(1,Directions::Right);
+ players[1].keyPressed=true;
+ }
+ else if(actionCollection->action("Pl2Down")->shortcut().contains(key))
+ {
+ switchDir(1,Directions::Down);
+ players[1].keyPressed=true;
+ }
+ else if(actionCollection->action("Pl2Ac")->shortcut().contains(key))
+ {
+ if(!Settings::acceleratorBlocked())
+ players[1].accelerated=true;
+
+ }
+ }
+
+ if(!players[0].computer)
+ {
+ if(actionCollection->action("Pl1Left")->shortcut().contains(key))
+ {
+ switchDir(0,Directions::Left);
+ players[0].keyPressed=true;
+ }
+ else if(actionCollection->action("Pl1Right")->shortcut().contains(key))
+ {
+ switchDir(0,Directions::Right);
+ players[0].keyPressed=true;
+ }
+ else if(actionCollection->action("Pl1Up")->shortcut().contains(key))
+ {
+ switchDir(0,Directions::Up);
+ players[0].keyPressed=true;
+ }
+ else if(actionCollection->action("Pl1Down")->shortcut().contains(key))
+ {
+ switchDir(0,Directions::Down);
+ players[0].keyPressed=true;
+ }
+ else if(actionCollection->action("Pl1Ac")->shortcut().contains(key))
+ {
+ if(!Settings::acceleratorBlocked())
+ players[0].accelerated=true;
+ }
+ }
+
+ e->ignore(); // if key is unknown: ignore
+
+ // if both players press keys at the same time, start game...
+ if(gameEnded && !gameBlocked)
+ {
+ if(players[0].keyPressed && players[1].keyPressed)
+ {
+ reset();
+ startGame();
+ }
+ }
+ // ...or continue
+ else if(gamePaused)
+ {
+ if(players[0].keyPressed && players[1].keyPressed)
+ {
+ togglePause();
+ }
+ }
+}
+
+void Tron::keyReleaseEvent(QKeyEvent * e)
+{
+ KKey key(e);
+
+ if(!players[1].computer)
+ {
+ if(actionCollection->action("Pl2Ac")->shortcut().contains(key))
+ {
+ players[1].accelerated=false;
+ return;
+ }
+ else if(actionCollection->action("Pl2Left")->shortcut().contains(key))
+ {
+ players[1].keyPressed=false;
+ return;
+ }
+ else if(actionCollection->action("Pl2Right")->shortcut().contains(key))
+ {
+ players[1].keyPressed=false;
+ return;
+ }
+ else if(actionCollection->action("Pl2Up")->shortcut().contains(key))
+ {
+ players[1].keyPressed=false;
+ return;
+ }
+ else if(actionCollection->action("Pl2Down")->shortcut().contains(key))
+ {
+ players[1].keyPressed=false;
+ return;
+ }
+ }
+
+ if(!players[0].computer)
+ {
+ if(actionCollection->action("Pl1Left")->shortcut().contains(key))
+ {
+ players[0].keyPressed=false;
+ return;
+ }
+ else if(actionCollection->action("Pl1Right")->shortcut().contains(key))
+ {
+ players[0].keyPressed=false;
+ return;
+ }
+ else if(actionCollection->action("Pl1Up")->shortcut().contains(key))
+ {
+ players[0].keyPressed=false;
+ return;
+ }
+ else if(actionCollection->action("Pl1Down")->shortcut().contains(key))
+ {
+ players[0].keyPressed=false;
+ return;
+ }
+ else if(actionCollection->action("Pl1Ac")->shortcut().contains(key))
+ {
+ players[0].accelerated=false;
+ return;
+ }
+ }
+
+ e->ignore(); // if pressed key is unknown, ignore it
+
+}
+
+// if playingfield loses keyboard focus, pause game
+void Tron::focusOutEvent(QFocusEvent *)
+{
+ if(!gameEnded && !gamePaused)
+ {
+ togglePause();
+ }
+}
+
+/* *************************************************************** **
+** slots **
+** *************************************************************** */
+
+void Tron::unblockGame()
+{
+ gameBlocked=false;
+}
+
+void Tron::showBeginHint()
+{
+ if(gameEnded)
+ {
+ // show only at the beginning of a game
+ if(players[0].score==0 && players[1].score==0)
+ {
+ beginHint=true;
+ repaint();
+ }
+ }
+}
+
+// doMove() is called from QTimer
+void Tron::doMove()
+{
+ int i;
+ for(i=0;i<2;i++)
+ {
+ // Überprüfen, ob Acceleratortaste gedrückt wurde...
+ if(players[i].accelerated)
+ {
+ updateDirections(i);
+
+ int newType; // determine type of rect to set
+ if(i==0)
+ {
+ newType=PLAYER1;
+ }
+ else
+ {
+ newType=PLAYER2;
+ }
+ switch(players[i].dir)
+ {
+ case Directions::Up:
+ if(crashed(i,0,-1))
+ players[i].alive=false;
+ else
+ {
+ players[i].yCoordinate--;
+ newType|=(TOP | LEFT | RIGHT);
+ }
+ break;
+ case Directions::Down:
+ if(crashed(i,0,1))
+ players[i].alive=false;
+ else
+ {
+ players[i].yCoordinate++;
+ newType |= (BOTTOM | LEFT | RIGHT);
+ }
+ break;
+ case Directions::Left:
+ if(crashed(i,-1,0))
+ players[i].alive=false;
+ else
+ {
+ players[i].xCoordinate--;
+ newType |= (LEFT | TOP | BOTTOM);
+ }
+ break;
+ case Directions::Right:
+ if(crashed(i,1,0))
+ players[i].alive=false;
+ else
+ {
+ players[i].xCoordinate++;
+ newType |= (RIGHT | TOP | BOTTOM);
+ }
+ break;
+ default:
+ break;
+ }
+ if(players[i].alive)
+ playfield[players[i].xCoordinate][players[i].yCoordinate]=newType;
+ }
+ }
+
+ if(players[0].accelerated || players[1].accelerated)
+ {
+ /* player collision check */
+ if(!players[1].alive)
+ {
+ int xInc=0,yInc=0;
+ switch(players[1].dir)
+ {
+ case Directions::Left:
+ xInc = -1;
+ break;
+ case Directions::Right:
+ xInc = 1;
+ break;
+ case Directions::Up:
+ yInc = -1;
+ break;
+ case Directions::Down:
+ yInc = 1;
+ break;
+ default:
+ break;
+ }
+ if ((players[1].xCoordinate+xInc) == players[0].xCoordinate)
+ if ((players[1].yCoordinate+yInc) == players[0].yCoordinate)
+ {
+ players[0].alive=false;
+ }
+ }
+
+ paintPlayers();
+
+ // crashtest
+ if(!players[0].alive && !players[1].alive)
+ {
+ stopGame();
+ players[0].score++;
+ players[1].score++;
+ showWinner(Both);
+ }
+ else
+ {
+ for(i=0;i<2;i++)
+ {
+ if(!players[i].alive)
+ {
+ stopGame();
+ showWinner((i==0)? Two:One);
+ players[i].score++;
+ }
+ }
+ }
+
+
+ if(gameEnded)
+ {
+ //this is for waiting 0,5s before starting next game
+ gameBlocked=true;
+ QTimer::singleShot(1000,this,SLOT(unblockGame()));
+ return;
+ }
+ }
+
+ // neue Spielerstandorte festlegen
+ for(i=0;i<2;i++)
+ {
+ if(players[i].computer)
+ think(i);
+ }
+
+ updateDirections();
+
+ for(i=0;i<2;i++)
+ {
+ int newType;
+ if(i==0)
+ newType=PLAYER1;
+ else
+ newType=PLAYER2;
+
+ switch(players[i].dir)
+ {
+ case Directions::Up:
+ if(crashed(i,0,-1))
+ players[i].alive=false;
+ else
+ {
+ players[i].yCoordinate--;
+ newType |= (TOP | RIGHT | LEFT);
+ }
+ break;
+ case Directions::Down:
+ if(crashed(i,0,1))
+ players[i].alive=false;
+ else
+ {
+ players[i].yCoordinate++;
+ newType |= (BOTTOM | RIGHT | LEFT);
+ }
+ break;
+ case Directions::Left:
+ if(crashed(i,-1,0))
+ players[i].alive=false;
+ else
+ {
+ players[i].xCoordinate--;
+ newType |= (LEFT | TOP | BOTTOM);
+ }
+ break;
+ case Directions::Right:
+ if(crashed(i,1,0))
+ players[i].alive=false;
+ else
+ {
+ players[i].xCoordinate++;
+ newType |= (RIGHT | TOP | BOTTOM);
+ }
+ break;
+ default:
+ break;
+
+ }
+ if(players[i].alive)
+ playfield[players[i].xCoordinate][players[i].yCoordinate]=newType;
+ }
+
+ /* player collision check */
+ if(!players[1].alive)
+ {
+ int xInc=0,yInc=0;
+ switch(players[1].dir)
+ {
+ case Directions::Left:
+ xInc = -1; break;
+ case Directions::Right:
+ xInc = 1; break;
+ case Directions::Up:
+ yInc = -1; break;
+ case Directions::Down:
+ yInc = 1; break;
+ default:
+ break;
+ }
+ if ((players[1].xCoordinate+xInc) == players[0].xCoordinate)
+ if ((players[1].yCoordinate+yInc) == players[0].yCoordinate)
+ {
+ players[0].alive=false;
+ }
+ }
+
+ paintPlayers();
+
+ if(!players[0].alive && !players[1].alive)
+ {
+ stopGame();
+ players[0].score++;
+ players[1].score++;
+ showWinner(Both);
+ }
+ else
+ for(i=0;i<2;i++)
+ {
+ // crashtests
+ if(!players[i].alive)
+ {
+ stopGame();
+ showWinner((i==0)? Two:One);
+ players[i].score++;
+ }
+ }
+
+ if(gameEnded)
+ {
+ //this is for waiting 1s before starting next game
+ gameBlocked=true;
+ QTimer::singleShot(1000,this,SLOT(unblockGame()));
+ }
+
+}
+
+/* *************************************************************** **
+** algoritm for the computerplayer **
+** *************************************************************** */
+
+// This part is partly ported from
+// xtron-1.1 by Rhett D. Jacobs <rhett@hotel.canberra.edu.au>
+void Tron::think(int playerNr)
+{
+if(Settings::skill() != Settings::EnumSkill::Easy)
+{
+ int opponent=(playerNr==1)? 0 : 1;
+
+ // determines left and right side
+ Directions::Direction sides[2];
+ // increments for moving to the different sides
+ int flags[6]={0,0,0,0,0,0};
+ int index[2];
+ // distances to barrier
+ int dis_forward, dis_left, dis_right;
+
+ dis_forward = dis_left = dis_right = 1;
+
+
+ switch (players[playerNr].dir)
+ {
+ case Directions::Left:
+ //forward flags
+ flags[0] = -1;
+ flags[1] = 0;
+
+ //left flags
+ flags[2] = 0;
+ flags[3] = 1;
+
+ // right flags
+ flags[4] = 0;
+ flags[5] = -1;
+
+ //turns to either side
+ sides[0] = Directions::Down;
+ sides[1] = Directions::Up;
+ break;
+ case Directions::Right:
+ flags[0] = 1;
+ flags[1] = 0;
+ flags[2] = 0;
+ flags[3] = -1;
+ flags[4] = 0;
+ flags[5] = 1;
+ sides[0] = Directions::Up;
+ sides[1] = Directions::Down;
+ break;
+ case Directions::Up:
+ flags[0] = 0;
+ flags[1] = -1;
+ flags[2] = -1;
+ flags[3] = 0;
+ flags[4] = 1;
+ flags[5] = 0;
+ sides[0] = Directions::Left;
+ sides[1] = Directions::Right;
+ break;
+ case Directions::Down:
+ flags[0] = 0;
+ flags[1] = 1;
+ flags[2] = 1;
+ flags[3] = 0;
+ flags[4] = -1;
+ flags[5] = 0;
+ sides[0] = Directions::Right;
+ sides[1] = Directions::Left;
+ break;
+ default:
+ break;
+
+ }
+
+ // check forward
+ index[0] = players[playerNr].xCoordinate+flags[0];
+ index[1] = players[playerNr].yCoordinate+flags[1];
+ while (index[0] < fieldWidth && index[0] >= 0 &&
+ index[1] < fieldHeight && index[1] >= 0 &&
+ playfield[index[0]][index[1]] == BACKGROUND)
+ {
+ dis_forward++;
+ index[0] += flags[0];
+ index[1] += flags[1];
+ }
+
+ // check left
+ index[0] = players[playerNr].xCoordinate+flags[2];
+ index[1] = players[playerNr].yCoordinate+flags[3];
+ while (index[0] < fieldWidth && index[0] >= 0 &&
+ index[1] < fieldHeight && index[1] >= 0 &&
+ playfield[index[0]][index[1]] == BACKGROUND) {
+ dis_left++;
+ index[0] += flags[2];
+ index[1] += flags[3];
+ }
+
+ // check right
+ index[0] = players[playerNr].xCoordinate+flags[4];
+ index[1] = players[playerNr].yCoordinate+flags[5];
+ while (index[0] < fieldWidth && index[0] >= 0 &&
+ index[1] < fieldHeight && index[1] >= 0 &&
+ playfield[index[0]][index[1]] == BACKGROUND) {
+ dis_right++;
+ index[0] += flags[4];
+ index[1] += flags[5];
+ }
+
+ // distances to opponent
+ int hor_dis=0; // negative is opponent to the right
+ int vert_dis=0; // negative is opponent to the bottom
+ hor_dis=players[playerNr].xCoordinate-players[opponent].xCoordinate;
+ vert_dis=players[playerNr].yCoordinate-players[opponent].yCoordinate;
+
+ int opForwardDis=0; // negative is to the back
+ int opSideDis=0; // negative is to the left
+ bool opMovesOppositeDir=false;
+ bool opMovesSameDir=false;
+ bool opMovesRight=false;
+ bool opMovesLeft=false;
+
+ switch(players[playerNr].dir)
+ {
+ case Directions::Up:
+ opForwardDis=vert_dis;
+ opSideDis=-hor_dis;
+ if(players[opponent].dir==Directions::Down)
+ opMovesOppositeDir=true;
+ else if(players[opponent].dir==Directions::Up)
+ opMovesSameDir=true;
+ else if(players[opponent].dir==Directions::Left)
+ opMovesLeft=true;
+ else if(players[opponent].dir==Directions::Right)
+ opMovesRight=true;
+ break;
+ case Directions::Down:
+ opForwardDis=-vert_dis;
+ opSideDis=hor_dis;
+ if(players[opponent].dir==Directions::Up)
+ opMovesOppositeDir=true;
+ else if(players[opponent].dir==Directions::Down)
+ opMovesSameDir=true;
+ else if(players[opponent].dir==Directions::Left)
+ opMovesRight=true;
+ else if(players[opponent].dir==Directions::Right)
+ opMovesLeft=true;
+ break;
+ case Directions::Left:
+ opForwardDis=hor_dis;
+ opSideDis=vert_dis;
+ if(players[opponent].dir==Directions::Right)
+ opMovesOppositeDir=true;
+ else if(players[opponent].dir==Directions::Left)
+ opMovesSameDir=true;
+ else if(players[opponent].dir==Directions::Down)
+ opMovesLeft=true;
+ else if(players[opponent].dir==Directions::Up)
+ opMovesRight=true;
+ break;
+ case Directions::Right:
+ opForwardDis=-hor_dis;
+ opSideDis=-vert_dis;
+ if(players[opponent].dir==Directions::Left)
+ opMovesOppositeDir=true;
+ else if(players[opponent].dir==Directions::Right)
+ opMovesSameDir=true;
+ else if(players[opponent].dir==Directions::Up)
+ opMovesLeft=true;
+ else if(players[opponent].dir==Directions::Down)
+ opMovesRight=true;
+ break;
+ default:
+ break;
+
+ }
+
+ int doPercentage = 100;
+ switch(Settings::skill())
+ {
+ case Settings::EnumSkill::Easy:
+ // Never reached
+ break;
+
+ case Settings::EnumSkill::Medium:
+ doPercentage=5;
+ break;
+
+ case Settings::EnumSkill::Hard:
+ doPercentage=90;
+ break;
+ }
+
+ // if opponent moves the opposite direction as we
+ if(opMovesOppositeDir)
+ {
+ // if opponent is in front
+ if(opForwardDis>0)
+ {
+ // opponent is to the right and we have the chance to block the way
+ if(opSideDis>0 && opSideDis < opForwardDis && opSideDis < dis_right && opForwardDis < lookForward)
+ {
+ if ((int)random.getLong(100) <= doPercentage || dis_forward==1)
+ switchDir(playerNr,sides[1]); // turn right
+ }
+ // opponent is to the left and we have the chance to block the way
+ else if(opSideDis<0 && -opSideDis < opForwardDis && -opSideDis < dis_left && opForwardDis < lookForward)
+ {
+ if ((int)random.getLong(100) <= doPercentage || dis_forward==1)
+ switchDir(playerNr,sides[0]); // turn left
+ }
+ // if we can do nothing, go forward
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ // opponent is in back of us and moves away: do nothing
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ } // end if(opMovesOppositeDir)
+
+ else if(opMovesSameDir)
+ {
+ // if opponent is to the back
+ if(opForwardDis < 0)
+ {
+ // opponent is to the right and we have the chance to block the way
+ if(opSideDis>0 && opSideDis < -opForwardDis && opSideDis < dis_right)
+ {
+ if ((int)random.getLong(100) <= doPercentage || dis_forward==1)
+ switchDir(playerNr,sides[1]); // turn right
+ }
+ // opponent is to the left and we have the chance to block the way
+ else if(opSideDis<0 && -opSideDis < -opForwardDis && -opSideDis < dis_left)
+ {
+ if ((int)random.getLong(100) <= doPercentage || dis_forward==1)
+ switchDir(playerNr,sides[0]); // turn left
+ }
+ // if we can do nothing, go forward
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ // opponent is in front of us and moves away
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ } // end if(opMovesSameDir)
+
+ else if(opMovesRight)
+ {
+ // opponent is in front of us
+ if(opForwardDis>0)
+ {
+ // opponent is to the left
+ if(opSideDis < 0 && -opSideDis < opForwardDis && -opSideDis < dis_left)
+ {
+ if(opForwardDis < lookForward && dis_left > lookForward)
+ {
+ if ((int)random.getLong(100) <= doPercentage/2 || dis_forward==1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ // op is to the right and moves away, but maybe we can block him
+ else if(opSideDis>=0 && opSideDis < dis_right)
+ {
+ if(opForwardDis < lookForward && dis_right>lookForward)
+ {
+ if ((int)random.getLong(100) <= doPercentage/2 || dis_forward==1)
+ switchDir(playerNr,sides[1]); // turn right
+ }
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ // opponent is in the back of us
+ else
+ {
+ // opponent is right from us and we already blocked him
+ if(opSideDis>0 && opForwardDis < lookForward && opSideDis < dis_right)
+ {
+ if ((int)random.getLong(100) <= doPercentage/2 || dis_forward==1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ else if(dis_forward<lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ } // end if(opMovesRight)
+
+ else if(opMovesLeft)
+ {
+ // opponent is in front of us
+ if(opForwardDis>0)
+ {
+ // opponent is to the right, moves towards us and could block us
+ if(opSideDis > 0 && opSideDis < opForwardDis && opSideDis < dis_right)
+ {
+ if(opForwardDis < lookForward && dis_right>lookForward)
+ {
+ if ((int)random.getLong(100) <= doPercentage/2 || dis_forward==1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ // op is to the left and moves away, but maybe we can block him
+ else if(opSideDis<=0 && opSideDis < dis_left)
+ {
+ if(opForwardDis < lookForward && dis_left>lookForward)
+ {
+ if ((int)random.getLong(100) <= doPercentage/2 || dis_forward==1)
+ switchDir(playerNr,sides[0]); // turn left
+ }
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+
+ }
+ else if(dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ // opponent is in the back of us
+ else //if(opForwardDis<=0)
+ {
+ // opponent is left from us and we already blocked him
+ if(opSideDis<0 && opForwardDis < lookForward && -opSideDis < dis_left)
+ {
+ if ((int)random.getLong(100) <= doPercentage/2 || dis_forward==1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ else if(dis_forward<lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 1)
+ changeDirection(playerNr,dis_right,dis_left);
+ }
+ }
+ } // end if(opMovesLeft)
+
+}
+// This part is completely ported from
+// xtron-1.1 by Rhett D. Jacobs <rhett@hotel.canberra.edu.au>
+else // Settings::skill() == Settings::EnumSkill::Easy
+{
+ Directions::Direction sides[2];
+ int flags[6] = {0,0,0,0,0,0};
+ int index[2];
+ int dis_forward, dis_left, dis_right;
+
+ dis_forward = dis_left = dis_right = 1;
+
+ switch (players[playerNr].dir) {
+ case Directions::Left:
+
+ //forward flags
+ flags[0] = -1;
+ flags[1] = 0;
+
+ //left flags
+ flags[2] = 0;
+ flags[3] = 1;
+
+ // right flags
+ flags[4] = 0;
+ flags[5] = -1;
+
+ //turns to either side
+ sides[0] = Directions::Down;
+ sides[1] = Directions::Up;
+ break;
+ case Directions::Right:
+ flags[0] = 1;
+ flags[1] = 0;
+ flags[2] = 0;
+ flags[3] = -1;
+ flags[4] = 0;
+ flags[5] = 1;
+ sides[0] = Directions::Up;
+ sides[1] = Directions::Down;
+ break;
+ case Directions::Up:
+ flags[0] = 0;
+ flags[1] = -1;
+ flags[2] = -1;
+ flags[3] = 0;
+ flags[4] = 1;
+ flags[5] = 0;
+ sides[0] = Directions::Left;
+ sides[1] = Directions::Right;
+ break;
+ case Directions::Down:
+ flags[0] = 0;
+ flags[1] = 1;
+ flags[2] = 1;
+ flags[3] = 0;
+ flags[4] = -1;
+ flags[5] = 0;
+ sides[0] = Directions::Right;
+ sides[1] = Directions::Left;
+ break;
+ default:
+ break;
+ }
+
+ // check forward
+ index[0] = players[playerNr].xCoordinate+flags[0];
+ index[1] = players[playerNr].yCoordinate+flags[1];
+ while (index[0] < fieldWidth && index[0] >= 0 &&
+ index[1] < fieldHeight && index[1] >= 0 &&
+ playfield[index[0]][index[1]] == BACKGROUND) {
+ dis_forward++;
+ index[0] += flags[0];
+ index[1] += flags[1];
+ }
+
+ if (dis_forward < lookForward)
+ {
+ dis_forward = 100 - 100/dis_forward;
+
+ // check left
+ index[0] = players[playerNr].xCoordinate+flags[2];
+ index[1] = players[playerNr].yCoordinate+flags[3];
+ while (index[0] < fieldWidth && index[0] >= 0 &&
+ index[1] < fieldHeight && index[1] >= 0 &&
+ playfield[index[0]][index[1]] == BACKGROUND) {
+ dis_left++;
+ index[0] += flags[2];
+ index[1] += flags[3];
+ }
+
+ // check right
+ index[0] = players[playerNr].xCoordinate+flags[4];
+ index[1] = players[playerNr].yCoordinate+flags[5];
+ while (index[0] < fieldWidth && index[0] >= 0 &&
+ index[1] < fieldHeight && index[1] >= 0 &&
+ playfield[index[0]][index[1]] == BACKGROUND) {
+ dis_right++;
+ index[0] += flags[4];
+ index[1] += flags[5];
+ }
+ if(!(dis_left == 1 && dis_right == 1))
+ if ((int)random.getLong(100) >= dis_forward || dis_forward == 0) {
+
+ // change direction
+ if ((int)random.getLong(100) <= (100*dis_left)/(dis_left+dis_right))
+ if (dis_left != 1)
+
+ // turn to the left
+ switchDir(playerNr,sides[0]);
+ else
+
+ // turn to the right
+ switchDir(playerNr,sides[1]);
+ else
+ if (dis_right != 1)
+
+ // turn to the right
+ switchDir(playerNr,sides[1]);
+ else
+
+ // turn to the left
+ switchDir(playerNr,sides[0]);
+ }
+ }
+ }
+}
+
+void Tron::changeDirection(int playerNr,int dis_right,int dis_left)
+{
+ Directions::Direction currentDir=players[playerNr].dir;
+ Directions::Direction sides[2];
+ switch (currentDir)
+ {
+ case Directions::Left:
+ //turns to either side
+ sides[0] = Directions::Down;
+ sides[1] = Directions::Up;
+ break;
+ case Directions::Right:
+ sides[0] = Directions::Up;
+ sides[1] = Directions::Down;
+ break;
+ case Directions::Up:
+ sides[0] = Directions::Left;
+ sides[1] = Directions::Right;
+ break;
+ case Directions::Down:
+ sides[0] = Directions::Right;
+ sides[1] = Directions::Left;
+ break;
+ default:
+ break;
+
+ }
+
+ if(!(dis_left == 1 && dis_right == 1))
+ {
+ // change direction
+ if ((int)random.getLong(100) <= (100*dis_left)/(dis_left+dis_right))
+ {
+ if (dis_left != 1)
+ // turn to the left
+ switchDir(playerNr,sides[0]);
+ else
+ // turn to the right
+ switchDir(playerNr,sides[1]);
+ }
+ else
+ {
+ if (dis_right != 1)
+ // turn to the right
+ switchDir(playerNr,sides[1]);
+ else
+ // turn to the left
+ switchDir(playerNr,sides[0]);
+ }
+ }
+}
+
+#include "tron.moc"
+
diff --git a/ktron/tron.h b/ktron/tron.h
new file mode 100644
index 00000000..ebfc1d56
--- /dev/null
+++ b/ktron/tron.h
@@ -0,0 +1,178 @@
+/* ********************************************************************************
+ This file is part of the game 'KTron'
+
+ Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
+
+ 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.
+
+ *******************************************************************************/
+
+#ifndef TRON_H
+#define TRON_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qwidget.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <math.h>
+#include <krandomsequence.h>
+
+class KActionCollection;
+
+#include "player.h"
+
+enum Player{One,Two,Both,Nobody};
+// Bits that defines the rect and which sides to draw
+enum {BACKGROUND=0, PLAYER1=1,PLAYER2=2,TOP=4,BOTTOM=8,LEFT=16,RIGHT=32};
+
+/**
+* @short The playingfield
+*/
+class Tron : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Tron(QWidget *parent=0, const char *name=0);
+ ~Tron();
+ void setActionCollection(KActionCollection*);
+ void updatePixmap();
+ void setBackgroundPix(QPixmap);
+ void setComputerplayer(Player player, bool);
+ bool isComputer(Player player);
+ void setVelocity(int);
+ void setRectSize(int newSize);
+
+public slots:
+ /** Starts a new game. The difference to reset is, that the players
+ * points are set to zero. Emits gameEnds(Nobody).
+ */
+ void newGame();
+ void togglePause();
+
+ /**
+ * checks if both players are computer and starts the game
+ */
+ void computerStart();
+
+ void loadSettings();
+
+signals:
+ void gameEnds(Player loser);
+ void gameReset();
+
+protected:
+ /** bitBlt´s the rect that has to be updated from the
+ * bufferpixmap on the screen and writes eventually text
+ */
+ void paintEvent(QPaintEvent *);
+ /** resets game and creates a new playingfield */
+ void resizeEvent(QResizeEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void keyReleaseEvent(QKeyEvent *);
+ /** pauses game */
+ void focusOutEvent(QFocusEvent *);
+
+private:
+ /** Stores key shortcuts */
+ KActionCollection* actionCollection;
+ /** Drawing buffer */
+ QPixmap *pixmap;
+ /** The playingfield */
+ QMemArray<int> *playfield;
+ /** game status flag */
+ bool gamePaused;
+ /** game status flag */
+ bool gameEnded;
+ /** used for waiting after game ended */
+ bool gameBlocked;
+ /** flag, if a string should be drawn, how to start the game */
+ bool beginHint;
+ /** Height of the playingfield in number of rects*/
+ int fieldHeight;
+ /** Width of the playingfield in number of rects*/
+ int fieldWidth;
+ QTimer *timer;
+ player players[2];
+
+ /** Backgroundpixmap **/
+ QPixmap bgPix;
+
+ /** time in ms between two moves */
+ int velocity;
+ /** size of the rects */
+ int rectSize;
+
+ /** The random sequence generator **/
+ KRandomSequence random;
+
+ // Options
+ /** determines level of computerplayer */
+ int lookForward;
+
+ // Funktionen
+ /** resets the game */
+ void reset();
+ /** starts the game timer */
+ void startGame();
+ /** stops the game timer */
+ void stopGame();
+ /** creates a new playfield and a bufferpixmap */
+ void createNewPlayfield();
+ /** paints players at current player coordinates */
+ void paintPlayers();
+ /** draws a rect in current TronStyle at position x,y of the playingfield */
+ void drawRect(QPainter & p, int x, int y);
+ /** emits gameEnds(Player) and displays the winner by changing color*/
+ void showWinner(Player winner);
+
+ /** calculates if player playerNr would crash
+ * if he moves xInc in x-direction and yInc in y-direction
+ */
+ bool crashed(int playerNr,int xInc, int yInc) const;
+ /** calculates if player playerNr should change direction */
+ void think(int playerNr);
+ void changeDirection(int playerNr,int dis_right,int dis_left);
+
+ /** sets the direction of player playerNr to newDirection */
+ void switchDir(int playerNr,Directions::Direction newDirection);
+ /**
+ * updates the the rect at current position to not draw a
+ * border in the direction of the next step.
+ * (only used in mode OLine)
+ *
+ * -1 means update both players
+ */
+ void updateDirections(int playerNr=-1);
+
+private slots:
+ /**
+ * This is the main function of KTron.
+ * It checkes if an accelerator is pressed and than moves this player
+ * forward. Then it checkes if a crash occurred.
+ * If no crash happen it moves both players forward and checks again
+ * if someone crashed.
+ */
+ void doMove();
+ void unblockGame();
+ void showBeginHint();
+};
+
+
+#endif // TRON_H
+
diff --git a/ktron/version.h b/ktron/version.h
new file mode 100644
index 00000000..71fdda43
--- /dev/null
+++ b/ktron/version.h
@@ -0,0 +1 @@
+#define KTRON_VERSION "1.1"