Commit 49813579 authored by Parker Coates's avatar Parker Coates
Browse files

Replaced my homegrown Python Ruleset class generator with KConfigXT.

svn path=/trunk/playground/games/killbots/; revision=804023
parent ec640f6d
......@@ -21,7 +21,7 @@ SET( killbots_SRCS
view.cpp
)
KDE4_ADD_KCFG_FILES( killbots_SRCS settings.kcfgc )
KDE4_ADD_KCFG_FILES( killbots_SRCS settings.kcfgc rulesetbase.kcfgc )
KDE4_ADD_EXECUTABLE( killbots ${killbots_SRCS} )
......
......@@ -57,18 +57,21 @@ Killbots::Engine::~Engine()
void Killbots::Engine::newGame()
{
if ( ! m_rules.load( Settings::ruleset() ) )
m_rules.loadDefault();
m_rules = Ruleset::load( Settings::ruleset() );
if ( ! m_rules )
m_rules = Ruleset::loadDefault();
emit newGame( & m_rules );
Q_ASSERT( m_rules != 0 );
emit newGame( m_rules );
cleanUpRound();
m_round = 0;
m_score = 0;
m_energy = m_rules.energyAtGameStart();
m_robotCount = m_rules.robotsAtGameStart() - m_rules.robotsAddedEachRound();
m_fastbotCount = m_rules.fastbotsAtGameStart() - m_rules.fastbotsAddedEachRound();
m_energy = m_rules->energyAtGameStart();
m_robotCount = m_rules->robotsAtGameStart() - m_rules->robotsAddedEachRound();
m_fastbotCount = m_rules->fastbotsAtGameStart() - m_rules->fastbotsAddedEachRound();
animateThenGoToNextPhase( NewRound );
}
......@@ -85,21 +88,21 @@ void Killbots::Engine::newRound()
m_junkheaps.clear();
m_spriteMap.clear();
m_robotCount += m_rules.robotsAddedEachRound();
m_fastbotCount += m_rules.fastbotsAddedEachRound();
m_robotCount += m_rules->robotsAddedEachRound();
m_fastbotCount += m_rules->fastbotsAddedEachRound();
// Place the hero in the centre of the board.
QPoint centre = QPoint( qRound( m_rules.columns() / 2 ), qRound( m_rules.rows() / 2 ) );
QPoint centre = QPoint( qRound( m_rules->columns() / 2 ), qRound( m_rules->rows() / 2 ) );
m_hero = m_scene->createSprite( Hero, centre );
m_spriteMap.insert( centre, m_hero );
// Create and randomly place junkheaps.
for ( int i = 0; i < m_rules.junkheapsAtGameStart(); i++ )
for ( int i = 0; i < m_rules->junkheapsAtGameStart(); i++ )
{
QPoint point;
do
point = QPoint( KRandom::random() % m_rules.columns(), KRandom::random() % m_rules.rows() );
point = QPoint( KRandom::random() % m_rules->columns(), KRandom::random() % m_rules->rows() );
while ( m_spriteMap.contains( point ) );
m_junkheaps << m_scene->createSprite( Junkheap, point );
......@@ -111,7 +114,7 @@ void Killbots::Engine::newRound()
{
QPoint point;
do
point = QPoint( KRandom::random() % m_rules.columns(), KRandom::random() % m_rules.rows() );
point = QPoint( KRandom::random() % m_rules->columns(), KRandom::random() % m_rules->rows() );
while ( m_spriteMap.contains( point ) );
m_bots << m_scene->createSprite( Robot, point );
......@@ -123,7 +126,7 @@ void Killbots::Engine::newRound()
{
QPoint point;
do
point = QPoint( KRandom::random() % m_rules.columns(), KRandom::random() % m_rules.rows() );
point = QPoint( KRandom::random() % m_rules->columns(), KRandom::random() % m_rules->rows() );
while ( m_spriteMap.contains( point ) );
m_bots << m_scene->createSprite( Fastbot, point );
......@@ -142,7 +145,7 @@ void Killbots::Engine::newRound()
emit scoreChanged( m_score );
emit enemyCountChanged( m_bots.size() );
emit energyChanged( m_energy );
emit canAffordSafeTeleport( m_energy >= m_rules.costOfSafeTeleport() );
emit canAffordSafeTeleport( m_energy >= m_rules->costOfSafeTeleport() );
}
......@@ -166,7 +169,7 @@ void Killbots::Engine::goToNextPhase()
newRound();
// If board is over half full, reset the counts.
if ( m_robotCount + m_fastbotCount > m_rules.rows() * m_rules.columns() / 2 )
if ( m_robotCount + m_fastbotCount > m_rules->rows() * m_rules->columns() / 2 )
animateThenGoToNextPhase( BoardFull );
else
animateThenGoToNextPhase( ReadyToStart );
......@@ -187,7 +190,7 @@ void Killbots::Engine::goToNextPhase()
if ( ! m_hero )
{
m_nextPhase = GameOver;
emit gameOver( m_rules.name(), m_score, m_round );
emit gameOver( m_rules->name(), m_score, m_round );
}
else if ( m_bots.isEmpty() )
animateThenGoToNextPhase( RoundComplete );
......@@ -206,7 +209,7 @@ void Killbots::Engine::goToNextPhase()
if ( ! m_hero )
{
m_nextPhase = GameOver;
emit gameOver( m_rules.name(), m_score, m_round );
emit gameOver( m_rules->name(), m_score, m_round );
}
else if ( m_bots.isEmpty() )
animateThenGoToNextPhase( RoundComplete );
......@@ -215,8 +218,8 @@ void Killbots::Engine::goToNextPhase()
}
else if ( m_nextPhase == BoardFull )
{
m_robotCount = m_rules.robotsAtGameStart() - m_rules.robotsAddedEachRound();
m_fastbotCount = m_rules.fastbotsAtGameStart() - m_rules.fastbotsAddedEachRound();
m_robotCount = m_rules->robotsAtGameStart() - m_rules->robotsAddedEachRound();
m_fastbotCount = m_rules->fastbotsAtGameStart() - m_rules->fastbotsAddedEachRound();
--m_round;
m_nextPhase = CleanUpRound;
......@@ -252,10 +255,10 @@ void Killbots::Engine::doAction( HeroAction action )
moveHero( action );
else if ( action == Teleport )
teleportHero();
else if ( action == TeleportSafely && m_energy >= m_rules.costOfSafeTeleport() )
else if ( action == TeleportSafely && m_energy >= m_rules->costOfSafeTeleport() )
teleportHeroSafely();
else if ( action == TeleportSafelyIfPossible )
if ( m_energy >= m_rules.costOfSafeTeleport() )
if ( m_energy >= m_rules->costOfSafeTeleport() )
teleportHeroSafely();
else
teleportHero();
......@@ -314,10 +317,10 @@ void Killbots::Engine::pushJunkheap( Sprite * junkheap, HeroAction direction )
else
{
destroySprite( currentOccupant );
m_score += m_rules.squashKillPointBonus();
m_energy = qMin( m_energy + m_rules.squashKillEnergyBonus(), m_rules.maxEnergyAtGameStart() );
m_score += m_rules->squashKillPointBonus();
m_energy = qMin( m_energy + m_rules->squashKillEnergyBonus(), m_rules->maxEnergyAtGameStart() );
emit energyChanged( m_energy );
emit canAffordSafeTeleport( m_energy >= m_rules.costOfSafeTeleport() );
emit canAffordSafeTeleport( m_energy >= m_rules->costOfSafeTeleport() );
}
}
......@@ -329,7 +332,7 @@ void Killbots::Engine::teleportHero()
{
QPoint point;
do
point = QPoint( KRandom::random() % m_rules.columns(), KRandom::random() % m_rules.rows() );
point = QPoint( KRandom::random() % m_rules->columns(), KRandom::random() % m_rules->rows() );
while ( spriteTypeAt( point ) != NoSprite || point == m_hero->gridPos() );
m_scene->teleportSprite( m_hero, point );
......@@ -340,18 +343,18 @@ void Killbots::Engine::teleportHero()
void Killbots::Engine::teleportHeroSafely()
{
// Choose a random cell...
QPoint startPoint = QPoint( KRandom::random() % m_rules.columns(), KRandom::random() % m_rules.rows() );
QPoint startPoint = QPoint( KRandom::random() % m_rules->columns(), KRandom::random() % m_rules->rows() );
QPoint point = startPoint;
// ...and step through all the cells on the board looking for a safe cell.
do
{
if ( point.x() < m_rules.columns() - 1 )
if ( point.x() < m_rules->columns() - 1 )
point.rx()++;
else
{
point.rx() = 0;
if ( point.y() < m_rules.rows() - 1 )
if ( point.y() < m_rules->rows() - 1 )
point.ry()++;
else
point.ry() = 0;
......@@ -368,8 +371,8 @@ void Killbots::Engine::teleportHeroSafely()
animateThenGoToNextPhase( BoardFull );
else
{
emit energyChanged( m_energy -= m_rules.costOfSafeTeleport() );
emit canAffordSafeTeleport( m_energy >= m_rules.costOfSafeTeleport() );
emit energyChanged( m_energy -= m_rules->costOfSafeTeleport() );
emit canAffordSafeTeleport( m_energy >= m_rules->costOfSafeTeleport() );
m_scene->teleportSprite( m_hero, point );
animateThenGoToNextPhase( MoveRobots );
......@@ -426,7 +429,7 @@ void Killbots::Engine::assessDamage()
emit scoreChanged( m_score );
emit enemyCountChanged( m_bots.size() );
emit energyChanged( m_energy );
emit canAffordSafeTeleport( m_energy >= m_rules.costOfSafeTeleport() );
emit canAffordSafeTeleport( m_energy >= m_rules->costOfSafeTeleport() );
}
}
......@@ -456,8 +459,8 @@ int Killbots::Engine::spriteTypeAt( const QPoint & cell ) const
bool Killbots::Engine::cellIsValid( const QPoint & cell ) const
{
return 0 <= cell.x() && cell.x() < m_rules.columns()
&& 0 <= cell.y() && cell.y() < m_rules.rows();
return 0 <= cell.x() && cell.x() < m_rules->columns()
&& 0 <= cell.y() && cell.y() < m_rules->rows();
}
......@@ -465,7 +468,7 @@ bool Killbots::Engine::canPushJunkheap( Sprite * junkheap, HeroAction direction
{
QPoint nextCell = junkheap->gridPos() + vectorFromDirection( direction );
if ( ! m_rules.junkheapsArePushable() || ! cellIsValid( nextCell ) )
if ( ! m_rules->junkheapsArePushable() || ! cellIsValid( nextCell ) )
return false;
else if ( spriteTypeAt( nextCell ) == Junkheap )
return canPushJunkheap( m_spriteMap.value( nextCell ), direction );
......@@ -721,20 +724,20 @@ void Killbots::Engine::destroySprite( Sprite * sprite )
{
if ( m_waitOutRound )
{
m_score += m_rules.waitKillPointBonus();
m_energy = qMin( m_energy + m_rules.waitKillEnergyBonus(), m_rules.maxEnergyAtGameStart() );
m_score += m_rules->waitKillPointBonus();
m_energy = qMin( m_energy + m_rules->waitKillEnergyBonus(), m_rules->maxEnergyAtGameStart() );
}
m_score += m_rules.pointsPerRobotKilled();
m_score += m_rules->pointsPerRobotKilled();
m_bots.removeOne( sprite );
}
else if ( type == Fastbot )
{
if ( m_waitOutRound )
{
m_score += m_rules.waitKillPointBonus();
m_energy = qMin( m_energy + m_rules.waitKillEnergyBonus(), m_rules.maxEnergyAtGameStart() );
m_score += m_rules->waitKillPointBonus();
m_energy = qMin( m_energy + m_rules->waitKillEnergyBonus(), m_rules->maxEnergyAtGameStart() );
}
m_score += m_rules.pointsPerFastbotKilled();
m_score += m_rules->pointsPerFastbotKilled();
m_bots.removeOne( sprite );
}
else if ( type == Junkheap )
......
......@@ -125,7 +125,7 @@ namespace Killbots
bool m_waitOutRound;
HeroAction m_lastDirection;
Ruleset m_rules;
Ruleset * m_rules;
int m_round;
int m_score;
int m_energy;
......
#! /usr/bin/python
import sys
orderedKeys= []
typeDict = {}
valueDict = {}
desktopFile = open(sys.argv[1])
for line in desktopFile :
if line.isspace() or line.startswith('[') or line.startswith("Name"):
continue
(key, sep, value) = line.rstrip('\n').partition('=')
orderedKeys.append(key)
if value == "true" or value == "false" :
typeDict[key] = "bool"
else :
typeDict[key] = "int"
valueDict[key] = value
header = '''/*
* Killbots
* Copyright (C) 2006-2008 Parker Coates <parker.coates@gmail.com>
*
* 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, see <http://www.gnu.org/licenses>
* or write to the Free Software Foundation, Inc., 51 Franklin Street,
* Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KILLBOTS_RULESET_H
#define KILLBOTS_RULESET_H
#include <QtCore/QString>
namespace Killbots
{
class Ruleset
{
public:
explicit Ruleset( const QString & filePath = QString() );
~Ruleset();
bool load( const QString & filename );
bool loadDefault();
bool isValid() const;
QString filePath() const;
QString fileName() const;
QString name() const;
'''
for key in orderedKeys :
header += "\t\t" + typeDict[key] + ' ' + key[0].lower() + key[1:] + "() const;\n"
header += '''
private:
QString m_filePath;
bool m_valid;
QString m_name;
'''
for key in orderedKeys :
header += "\t\t" + typeDict[key] + ' m_' + key[0].lower() + key[1:] + ";\n"
header += ''' };
}
#endif
'''
print "Header"
print "-" * 78
print header
print "-" * 78 + "\n\n"
try :
headerFile = open("ruleset.h", "w" )
headerFile.write(header)
except :
print "\nERROR WRITING TO HEADER FILE"
source = '''/*
* Killbots
* Copyright (C) 2006-2008 Parker Coates <parker.coates@gmail.com>
*
* 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, see <http://www.gnu.org/licenses>
* or write to the Free Software Foundation, Inc., 51 Franklin Street,
* Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "ruleset.h"
#include <KDE/KConfig>
#include <KDE/KConfigGroup>
#include <KDE/KDebug>
#include <KDE/KStandardDirs>
#include <QtCore/QFileInfo>
Killbots::Ruleset::Ruleset( const QString & filePath )
: m_filePath( filePath ),
m_valid( false )
{
if ( ! m_filePath.isEmpty() )
load( m_filePath );
}
Killbots::Ruleset::~Ruleset()
{
}
bool Killbots::Ruleset::load( const QString & fileName )
{
kDebug() << "Attempting to load ruleset at" << fileName;
QString filePath = KStandardDirs::locate("ruleset", fileName);
static const QString groupName("KillbotsRuleset");
KConfig configFile( filePath, KConfig::SimpleConfig );
if ( configFile.hasGroup( groupName ) )
{
m_filePath = filePath;
m_valid = true;
KConfigGroup group = configFile.group( groupName );
m_name = group.readEntry( "Name", QString("Unnamed") );
'''
for key in orderedKeys :
source += "\t\tm_" + key[0].lower() + key[1:] + " = group.readEntry( \"" + key + "\", " + valueDict[key] + ");\n"
source += ''' }
return isValid();
}
bool Killbots::Ruleset::loadDefault()
{
return load( "default.desktop" );
}
bool Killbots::Ruleset::isValid() const
{
return m_valid;
}
QString Killbots::Ruleset::filePath() const
{
return m_filePath;
}
QString Killbots::Ruleset::fileName() const
{
return QFileInfo( m_filePath ).fileName();
}
QString Killbots::Ruleset::name() const
{
return m_name;
}
'''
for key in orderedKeys :
source += "\n\n" +typeDict[key] + ' Killbots::Ruleset::' + key[0].lower() + key[1:] + "() const\n"
source += "{\n"
source += "\treturn m_" + key[0].lower() + key[1:] + ";\n"
source += "}\n"
print "Source"
print "-" * 78
print source
print "-" * 78 + "\n\n"
try :
sourceFile = open("ruleset.cpp", "w" )
sourceFile.write(source)
except :
print "\nERROR WRITING TO SOURCE FILE"
......@@ -28,7 +28,7 @@
#include <QtGui/QFormLayout>
#include <QtGui/QGridLayout>
#include <QtGui/QLabel>
#include <QtGui/QSlider>
OptionsPage::OptionsPage( QWidget *parent )
: QWidget( parent )
......@@ -55,6 +55,8 @@ OptionsPage::OptionsPage( QWidget *parent )
kcfg_AnimationSpeed = new QSlider( Qt::Horizontal, this );
kcfg_AnimationSpeed->setObjectName( "kcfg_AnimationSpeed" );
kcfg_AnimationSpeed->setSingleStep( 1 );
kcfg_AnimationSpeed->setPageStep( 1 );
QGridLayout * speedLayout = new QGridLayout();
speedLayout->setMargin( 0 );
......@@ -70,7 +72,6 @@ OptionsPage::OptionsPage( QWidget *parent )
label->setAlignment( Qt::AlignRight );
speedLayout->addWidget( label, 1, 2 );
QFormLayout * formLayout = new QFormLayout( this );
formLayout->setLabelAlignment( Qt::AlignRight );
formLayout->setMargin( 0 );
......
......@@ -33,7 +33,7 @@ namespace Killbots
{
namespace Render
{
bool loadTheme( const QString & filename );
bool loadTheme( const QString & fileName );
bool loadDefaultTheme();
QPixmap renderElement( const QString & elementId, QSize size );
QPixmap renderGrid( int rows, int columns, QSize cellSize );
......
......@@ -20,218 +20,65 @@
#include "ruleset.h"
#include <KDE/KConfig>
#include <KDE/KConfigGroup>
#include <KDE/KDebug>
#include <KDE/KStandardDirs>
#include <QtCore/QFileInfo>
Killbots::Ruleset::Ruleset( const QString & filePath )
: m_filePath( filePath ),
m_valid( false )
Killbots::Ruleset * Killbots::Ruleset::load( const QString & fileName )
{
if ( ! m_filePath.isEmpty() )
load( m_filePath );
}
Ruleset * result = 0;
Killbots::Ruleset::~Ruleset()
{
}
bool Killbots::Ruleset::load( const QString & fileName )
{
kDebug() << "Attempting to load ruleset at" << fileName;
QString filePath = KStandardDirs::locate("ruleset", fileName);
static const QString groupName("KillbotsRuleset");
KConfig configFile( filePath, KConfig::SimpleConfig );
if ( configFile.hasGroup( groupName ) )
if ( ! fileName.isEmpty() )
{
m_filePath = filePath;
m_valid = true;
KConfigGroup group = configFile.group( groupName );
m_name = group.readEntry( "Name", QString("Unnamed") );
m_rows = group.readEntry( "Rows", 16);
m_columns = group.readEntry( "Columns", 16);
m_robotsAtGameStart = group.readEntry( "RobotsAtGameStart", 8);
m_robotsAddedEachRound = group.readEntry( "RobotsAddedEachRound", 4);
m_fastbotsAtGameStart = group.readEntry( "FastbotsAtGameStart", -2);
m_fastbotsAddedEachRound = group.readEntry( "FastbotsAddedEachRound", 2);
m_energyAtGameStart = group.readEntry( "EnergyAtGameStart", 0);
m_energyAddedEachRound = group.readEntry( "EnergyAddedEachRound", 0);
m_maxEnergyAtGameStart = group.readEntry( "MaxEnergyAtGameStart", 12);
m_maxEnergyAddedEachRound = group.readEntry( "MaxEnergyAddedEachRound", 0);
m_costOfSafeTeleport = group.readEntry( "CostOfSafeTeleport", 1);
m_junkheapsArePushable = group.readEntry( "JunkheapsArePushable", true);
m_junkheapsAtGameStart = group.readEntry( "JunkheapsAtGameStart", 0);
m_junkheapsAddedEachRound = group.readEntry( "JunkheapsAddedEachRound", 0);
m_pointsPerRobotKilled = group.readEntry( "PointsPerRobotKilled", 5);
m_pointsPerFastbotKilled = group.readEntry( "PointsPerFastbotKilled", 10);
m_waitKillPointBonus = group.readEntry( "WaitKillPointBonus", 0);
m_waitKillEnergyBonus = group.readEntry( "WaitKillEnergyBonus", 1);
m_squashKillPointBonus = group.readEntry( "SquashKillPointBonus", 0);
m_squashKillEnergyBonus = group.readEntry( "SquashKillEnergyBonus", 1);
QString filePath = KStandardDirs::locate("ruleset", fileName);
if ( ! filePath.isEmpty() )
{
KConfig configFile( filePath, KConfig::SimpleConfig );
if ( configFile.hasGroup( "KillbotsRuleset" ) )
result = new Ruleset( filePath );
}
}
return isValid();
return result;
}
bool Killbots::Ruleset::loadDefault()
Killbots::Ruleset * Killbots::Ruleset::loadDefault()
{
return load( "default.desktop" );
}
bool Killbots::Ruleset::isValid() const
{
return m_valid;
}
QString Killbots::Ruleset::filePath() const
{
return m_filePath;
}
QString Killbots::Ruleset::fileName() const
{
return QFileInfo( m_filePath ).fileName();
}
QString Killbots::Ruleset::name() const
{
return m_name;