Author Topic: Making a better flexible statistics system  (Read 2002 times)

Offline karnedge

  • Level 17
  • *
  • Posts: 170
  • Reputation: +4/-0
  • ctrlHack provides the server, you bring the skill.
    • View Profile
    • ctrl://Hack.game
Making a better flexible statistics system
« on: June 05, 2009, 04:57:41 PM »
After a while from the previous topic, I think I've come up with a pretty decent way to retrieve stats, profile, and other information on userIDs. The following class should help you with any tables that use ID numbers for each row pertaining to userID, itemID, etc.

Code: [Select]
<?php
/**
 * information.php - Information class to handle a row array in an easy to use format.
 * Example:
 *    $player = new Information('stats',$userID);
 *    $opponent  = new Information('stats',$opponentID);
 *    $damage = $player->attack - $opponent->defense;
 *
 * @copyright Copyright (C) 2009 - ctrlGames, Inc. All rights reserved.
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html
 */

class Information {
protected $data = array(); // Record of table row
protected $tableName null; // Table name
protected $rowID null; // Row ID

public function __construct($tableName,$rowID){
$this->tableName $tableName;
if(is_numeric($rowID)){
$this->rowID $rowID;
Database::query("SELECT * FROM %s WHERE id = '%s'",$tableName,$rowID);
$result Database::getResults('a');
if(is_array($result)){
$this->data $result;
}else{
throw new Exception("No results from '$tableName' at row ID: $rowID");
}
}
}

/**
 * @param (string) $var Name of var
 * @return  (mixed) Null if the var does not exist, var's value if it does
 */
public function __get($var){
if(isset($this->data[$var])){
return $this->data[$var];
}
return null;
}

/**
 * @param  (string) $var Name of var to set
 * @param  (mixed) $val Value of given var
 * @return  void
 */
public function __set($var,$val){
if(isset($this->data[$var])){
$this->data[$var] = $val;
Database::query("UPDATE %s SET %s = '%s' WHERE id = '%s'",$this->tableName,$var,$val,$this->rowID);
}
}

/**
 * @param  (string) $var Name of var to check if it's in $data
 * @return (bool)
 */
public function __isset($var){
return isset($this->data[$var]);
}
}
?>

Of course you will need to change the database queries to fit whatever database abstraction you may use. I would put in the queries for beginners who dont have a database abstraction but it would be alot more useless code that people should already know. If you have an abstraction layer then it's alot easier to replace 3 lines instead like 10.

If anyone wants to post a version of this with no database abstraction layer understood then go ahead.

Anyway, its really easy to use this class... assuming you have a table called Player_Stats with columns for each stat like attack, defense, points, hp and awesomeness:
Code: [Select]
<?php
require("information.php");
$player = new Information('Player_Stats',$_SESSION['userID']);
$opponent = new Information('Player_Stats',$opponentID);

$damage = ($player->attack $opponent->defense) * $player->awesomeness;
$opponent->hp $opponent->hp $damage;
if(
$opponent->hp <= 0){
echo "You killed him!";
}else{
echo "Keep going...";
}
?>

And so on and so forth, so the great this about this class is that it makes it very dynamic no matter if you add new skills or stats to the database, this class will automatically add it to the array. isset() still works for it and using the same $class->variable allows you to set it along with getting it.

If you can improve on this code or make alternates please post it below. I hope this helps anyone or at least points people out to the awesome class functions: __set(), __get(), and __isset()
ctrlHack - Hacking simulation RPG in development.
Latest blog: Back on Track
bbgFramework v0.1.3

Offline Crazy-T

  • Level 19
  • *
  • Posts: 197
  • Reputation: +0/-0
  • Building Games
    • View Profile
Re: Making a better flexible statistics system
« Reply #1 on: June 05, 2009, 05:19:05 PM »
Instead of having
Code: [Select]
<?php //for colors!!
protected $data = array(); // Record of table row
protected $tableName null; // Table name
protected $rowID null;
Couldn't you just have
Code: [Select]
<?php //for colors!!
 
protected $data = array(), $tableName null$rowID null;
Would that work?
Crazy-T

Offline Mufasa

  • Game Owner
  • Level 18
  • *
  • Posts: 189
  • Reputation: +3/-0
  • Maniac Developer
    • View Profile
Re: Making a better flexible statistics system
« Reply #2 on: June 05, 2009, 05:56:50 PM »
This would definitely work, but why so generic? Is it for an open source game engine you are planning? Otherwise, you'd be better off doing select field1, field2, field3 as SELECT *'s will kill a game once you start to get larger.

One method I use is a general class which does all the work of taking the database results and formatting them etc, and then for each thing like an item or user, extend the class, overwrite the constructor which should set the query, and then let it call the inherited function which actually executes said query and performs other generic tasks

Offline Crazy-T

  • Level 19
  • *
  • Posts: 197
  • Reputation: +0/-0
  • Building Games
    • View Profile
Re: Making a better flexible statistics system
« Reply #3 on: June 05, 2009, 06:01:46 PM »
Yeah could you use list? like:
Code: [Select]
<?php //Only for colors!!
 
list($var1$var2$var3$var4$var5) = mysql_fetch_array(mysql_query("SELECT `var1`, `var2`, `var3`, `var4`, `var5` FROM `players` WHERE `id` = "$userid));
Crazy-T

Offline Mufasa

  • Game Owner
  • Level 18
  • *
  • Posts: 189
  • Reputation: +3/-0
  • Maniac Developer
    • View Profile
Re: Making a better flexible statistics system
« Reply #4 on: June 05, 2009, 06:34:33 PM »
that, or...


$query 
mysql_query"SELECT field1, field2, field3 FROM table1 WHERE id = $id);
$data mysql_fetch_object$query );
foreach( 
$data as $var => $value ){
   
$this->$var stripslashes$value );
}


Then your class would have all the requested variables as properties.

Offline Crazy-T

  • Level 19
  • *
  • Posts: 197
  • Reputation: +0/-0
  • Building Games
    • View Profile
Re: Making a better flexible statistics system
« Reply #5 on: June 05, 2009, 06:44:34 PM »
that, or...


$query 
mysql_query"SELECT field1, field2, field3 FROM table1 WHERE id = $id);
$data mysql_fetch_object$query );
foreach( 
$data as $var => $value ){
   
$this->$var stripslashes$value );
}


Then your class would have all the requested variables as properties.

Yeah...
Whats better to use all do same thing *me think's
Code: [Select]
<?php //for colors!!
mysql_fetch_array();       //for $blah['username']'
mysql_fetch_assoc();      //for $blah['username'];
mysql_fetch_object();     //for $blah->username;
?>
Crazy-T

Offline Mufasa

  • Game Owner
  • Level 18
  • *
  • Posts: 189
  • Reputation: +3/-0
  • Maniac Developer
    • View Profile
Re: Making a better flexible statistics system
« Reply #6 on: June 05, 2009, 06:48:08 PM »
A lot of people use array, but for me object is faster to type.

For example, for me it's easier to type

Code: [Select]
$obj->variable
than it is to type

Code: [Select]
$obj['variable']
the " [' " and " '] " are clumsy keystrokes for me verses a quick "->"

Offline Crazy-T

  • Level 19
  • *
  • Posts: 197
  • Reputation: +0/-0
  • Building Games
    • View Profile
Re: Making a better flexible statistics system
« Reply #7 on: June 05, 2009, 06:51:18 PM »
A lot of people use array, but for me object is faster to type.

For example, for me it's easier to type

Code: [Select]
$obj->variable
than it is to type

Code: [Select]
$obj['variable']
the " [' " and " '] " are clumsy keystrokes for me verses a quick "->"
Yeah, $blah->var is faster to write than $blah['var']but witch is faster, to speed?
Crazy-T

Offline Harkins

  • Level 28
  • **
  • Posts: 424
  • Reputation: +11/-2
  • Coder, blogger, entrepreneur.
    • View Profile
    • Push CX - Blog
Re: Making a better flexible statistics system
« Reply #8 on: June 05, 2009, 08:59:07 PM »
It doesn't matter which is faster, it matters which leads to better code.

Visit #bbg on irc.freenode.net to talk browser games anytime.

Offline Mufasa

  • Game Owner
  • Level 18
  • *
  • Posts: 189
  • Reputation: +3/-0
  • Maniac Developer
    • View Profile
Re: Making a better flexible statistics system
« Reply #9 on: June 05, 2009, 10:36:33 PM »
It doesn't matter which is faster, it matters which leads to better code.

Care to expand on that statement?

Offline Harkins

  • Level 28
  • **
  • Posts: 424
  • Reputation: +11/-2
  • Coder, blogger, entrepreneur.
    • View Profile
    • Push CX - Blog
Re: Making a better flexible statistics system
« Reply #10 on: June 05, 2009, 10:47:12 PM »
The average page will do a handful of queries. Maybe one or two really big pages will do 30. The amount you'll save in -> vs
  • vs ['foo'] is nothing compared to what you'll get by fixing algorithms or compressing images/js/css or setting caching headers or writing a better query.


And in any case, it doesn't matter because a working "slow" system is better than an unreadable, unfinished "fast" system. I put the words in quotes because until you finish and actually start measuring you don't actually know if something is slow or fast. People in this forum keep talking about things being "faster" as if a byte mattered in the scale of their programs. Until you have an actual measurement it's all just wanking.

Visit #bbg on irc.freenode.net to talk browser games anytime.

Offline Mufasa

  • Game Owner
  • Level 18
  • *
  • Posts: 189
  • Reputation: +3/-0
  • Maniac Developer
    • View Profile
Re: Making a better flexible statistics system
« Reply #11 on: June 05, 2009, 11:05:17 PM »
OK I follow you, but I think to simplify:

--Crazy was asking, I think, which was faster from a script parsing standpoint (maybe thinking that if something is easier it comes with a speed/memory cost). To that, I have to honestly say I have no idea.

--Harkins is basically saying, the difference is negligible and the focus should be put on making sure the rest of your code is lean and optimized.

Offline Crazy-T

  • Level 19
  • *
  • Posts: 197
  • Reputation: +0/-0
  • Building Games
    • View Profile
Re: Making a better flexible statistics system
« Reply #12 on: June 05, 2009, 11:11:12 PM »
OK I follow you, but I think to simplify:

--Crazy was asking, I think, which was faster from a script parsing standpoint (maybe thinking that if something is easier it comes with a speed/memory cost). To that, I have to honestly say I have no idea.

--Harkins is basically saying, the difference is negligible and the focus should be put on making sure the rest of your code is lean and optimized.
Quote
--Crazy was asking, I think, which was faster from a script parsing standpoint (maybe thinking that if something is easier it comes with a speed/memory cost). To that, I have to honestly say I have no idea.
100% Correct!
Crazy-T

Offline JGadrow

  • Level 35
  • **
  • Posts: 1,133
  • Reputation: +23/-2
    • View Profile
Re: Making a better flexible statistics system
« Reply #13 on: June 06, 2009, 12:18:34 AM »
Until you have an actual measurement it's all just wanking.
Or, ya know, if you've gotten enough experience behind ya to know it. :P However, I prefer LEGIBLE code to FAST code. I mean, BINARY is some incredibly fast code! But I sure as hell don't want to maintain it! lol
Idiocy - Never underestimate the power of stupid people in large groups.


Offline karnedge

  • Level 17
  • *
  • Posts: 170
  • Reputation: +4/-0
  • ctrlHack provides the server, you bring the skill.
    • View Profile
    • ctrl://Hack.game
Re: Making a better flexible statistics system
« Reply #14 on: June 06, 2009, 01:20:14 AM »
that, or...


$query 
mysql_query"SELECT field1, field2, field3 FROM table1 WHERE id = $id);
$data mysql_fetch_object$query );
foreach( 
$data as $var => $value ){
   
$this->$var stripslashes$value );
}


Then your class would have all the requested variables as properties.

That is the way this class is set up... it already does this automatically with less code. That's what __get() function is for.

The $data array is the entire row (or SELECT field1, field2, field3 FROM table1 WHERE id = $id)

So if you used that query:
$stats = new Information('table1',$id);
echo $stats->field1;
echo $stats->field2;
echo $stats->field3;

It already does it for you.
ctrlHack - Hacking simulation RPG in development.
Latest blog: Back on Track
bbgFramework v0.1.3

Offline karnedge

  • Level 17
  • *
  • Posts: 170
  • Reputation: +4/-0
  • ctrlHack provides the server, you bring the skill.
    • View Profile
    • ctrl://Hack.game
Re: Making a better flexible statistics system
« Reply #15 on: June 06, 2009, 01:33:58 AM »
And I guess my database abstraction layer is confusing but this part:
Code: [Select]
Database::query("SELECT * FROM %s WHERE id = '%s'",$tableName,$rowID);
$result = Database::getResults('a');

equals this:
Code: [Select]
$query = sprintf("SELECT * FROM %s WHERE id = '%s'",$tableName,$rowID);
$result = mysql_fetch_assoc(mysql_query($query));

which means my table1 with field1, field2, field3 come out in an array like so:
Code: [Select]
[result] => array
  (
    [field1] => 3
    [field2] => something
    [field3] => 90
  )

Which I thought was understood...
ctrlHack - Hacking simulation RPG in development.
Latest blog: Back on Track
bbgFramework v0.1.3

Offline Crazy-T

  • Level 19
  • *
  • Posts: 197
  • Reputation: +0/-0
  • Building Games
    • View Profile
Re: Making a better flexible statistics system
« Reply #16 on: June 06, 2009, 02:06:51 AM »
And I guess my database abstraction layer is confusing but this part:
Code: [Select]
Database::query("SELECT * FROM %s WHERE id = '%s'",$tableName,$rowID);
$result = Database::getResults('a');

equals this:
Code: [Select]
$query = sprintf("SELECT * FROM %s WHERE id = '%s'",$tableName,$rowID);
$result = mysql_fetch_assoc(mysql_query($query));

which means my table1 with field1, field2, field3 come out in an array like so:
Code: [Select]
[result] => array
  (
    [field1] => 3
    [field2] => something
    [field3] => 90
  )

Which I thought was understood...
Won't sprintf() in every query, will slow the page's down by a whole lot?

Edited: Spelling error.
« Last Edit: June 06, 2009, 02:17:51 AM by Crazy-T »
Crazy-T

Offline karnedge

  • Level 17
  • *
  • Posts: 170
  • Reputation: +4/-0
  • ctrlHack provides the server, you bring the skill.
    • View Profile
    • ctrl://Hack.game
Re: Making a better flexible statistics system
« Reply #17 on: June 06, 2009, 02:15:37 AM »
Won't sprintf() in every query, will show the page's down by a whole lot?

The way you do your database query is up to you it doesn't matter. The class itself allows you to pull an array of data from a row in a table using mysql_fetch_assoc() and __get() will allow you to use $instance->variable instead of $instance['variable'].

That's the point at least.
ctrlHack - Hacking simulation RPG in development.
Latest blog: Back on Track
bbgFramework v0.1.3

Offline Crazy-T

  • Level 19
  • *
  • Posts: 197
  • Reputation: +0/-0
  • Building Games
    • View Profile
Re: Making a better flexible statistics system
« Reply #18 on: June 06, 2009, 02:16:57 AM »
Won't sprintf() in every query, will show the page's down by a whole lot?

The way you do your database query is up to you it doesn't matter. The class itself allows you to pull an array of data from a row in a table using mysql_fetch_assoc() and __get() will allow you to use $instance->variable instead of $instance['variable'].

That's the point at least.
Ahh ok :)
Crazy-T

Offline Delifisek

  • Level 12
  • *
  • Posts: 79
  • Reputation: +1/-1
    • View Profile
Re: Making a better flexible statistics system
« Reply #19 on: June 08, 2009, 03:26:46 PM »
Hehe nice statemens.

$foo['bar'];

much faster than

$foo->bar;

especially when that $foo thing getting bigger.

and you cant store all or some parts of object.

and you can store array $foo to file, apc or memcached easly.

and if you can't write maintenable code  it doesn't matter is object or procedural...

OO programming has a hight cost. Which Desktop programmers willing to pay to handle their static languages and able to modify somebody else's method or class. And you can recover some cost with staying alive in memory for a long time.

Your puny php script was just living sub seconds of time. Even lover sub seconds was more preferable.

And more interesting was.

PHP was simple string mixer. 
input ($_REQUEST or $_GET or $_POST) ->  your script -> output.

making this more complex, doesn't make look good or better.

it just more complex...

Regards




Offline Mufasa

  • Game Owner
  • Level 18
  • *
  • Posts: 189
  • Reputation: +3/-0
  • Maniac Developer
    • View Profile
Re: Making a better flexible statistics system
« Reply #20 on: June 08, 2009, 03:28:10 PM »
Someone please translate.

Offline JGadrow

  • Level 35
  • **
  • Posts: 1,133
  • Reputation: +23/-2
    • View Profile
Re: Making a better flexible statistics system
« Reply #21 on: June 08, 2009, 03:52:55 PM »
Basically, I think it means he's a proceedural programmer who's opposed to object-oriented programming because it adds a few milliseconds of processing to achieve.

You know, because modular code that solves a specific problem WELL doesn't make up for that difference by being reusable at all. It's another 'negative criticism' post similar to the one here that I kind of went off on.
Idiocy - Never underestimate the power of stupid people in large groups.


Offline Nox

  • Level 35
  • **
  • Posts: 768
  • Reputation: +12/-2
    • View Profile
Re: Making a better flexible statistics system
« Reply #22 on: June 08, 2009, 03:54:20 PM »
I have a tip for you, although it's possible that many of you know that, but I've just discovered it...so that would explain my enthusiasm, but it's not excuse, so if it's too obvious, it can be deleted
Also I'm not sure to which topic this would belong best, so it can be moved

Stats system can be easier using view (for those who don't know what views are...there are something like shortcuts, they are static querys presented as table...when you execute an query, you get a set of results, so you get the same with view, but it permanently remains among your tables and is updated every time you change relating data...I'm afraid that was not really understandable :( )

I just created a view like this:
Code: [Select]
alter view vwStats as
select stats_char.id, stats.name, stats.short, stats_char.value as total, stats_base_char.value as base, stats_char.id_char
from stats
join stats_char on stats_char.id_stat=stats.id
join stats_base_char on stats_base_char.id_current=stats_char.id
order by stats.id

And now I can simply use
Code: [Select]
"SELECT (what you want) FROM vwStats WHERE id_char=$id"and I get the set of results I wanted.

The downside is, that every time any of mentioned tables is changed, the view must be updated as well.
On the other hand, the view's query is compiled, so the update is heavily optimized and quick. Still it's extra operation.
So it's suitable when you have a something used mainly for reading than writing, which I believe stats in my game will be, although not
by a large margin, will try to lower update query's as much as possible.

I hope it is helpful

Standard rules apply - feel free to correct me on whatever I might have written incorrectly or questionably etc.
Meet us at an IRC irc.freenode.net #bbg as well
https://vimeo.com/36579366 (a must-watch) | Join BOINC - no longer a hype, but you can help never the less

Offline Mufasa

  • Game Owner
  • Level 18
  • *
  • Posts: 189
  • Reputation: +3/-0
  • Maniac Developer
    • View Profile
Re: Making a better flexible statistics system
« Reply #23 on: June 08, 2009, 04:06:11 PM »
Basically, I think it means he's a proceedural programmer who's opposed to object-oriented programming because it adds a few milliseconds of processing to achieve.

You know, because modular code that solves a specific problem WELL doesn't make up for that difference by being reusable at all. It's another 'negative criticism' post similar to the one here that I kind of went off on.

Oh.. one of those. I wonder how "bloated" the code is when I've got one function or class of functions that's reused multiple times instead of rewritten (or copy and pasted into place) each time I need them?

I'd say the clutter-savings alone is worth it, but what happens when that particular function has to have a variable change? Mass find-and-replace?

Silly procedurals.

edit:

Nox, the views thing is new to me!

Offline Scion

  • Level 27
  • **
  • Posts: 402
  • Reputation: +11/-0
    • View Profile
Re: Making a better flexible statistics system
« Reply #24 on: June 09, 2009, 02:22:26 AM »
However, I prefer LEGIBLE code to FAST code. I mean, BINARY is some incredibly fast code! But I sure as hell don't want to maintain it! lol
lol....

I cant really comment too much about the php world with regards to performance since ive never really had to sit down and do any tunning yet...but in the java world its quite interesting that often the simple and easy to understand algorithm runs faster than one where the developer has tried to be tricky to get it to run fast.

Back in the old days when i was just a nipper we were told to

Make it Work,
Make it Simple
Make it Fast....In that order.

 


SimplePortal 2.3.3 © 2008-2010, SimplePortal