Jump to content

Copying PHP variable array to a new variable array?


laZuRe

Recommended Posts

Hi guys im in the middle of optimizing code..

 

$sql = "SELECT * FROM sa_enemystats WHERE username='$username'";
	$res = mysql_query($sql);	
	while ($row = mysql_fetch_assoc($res)) {

		$enemy['current_health'] = $row['current_health'];
		$enemy['current_skill'] = $row['current_skill'];
		$enemy['level'] = $row['level'];
		$enemy['damage'] = $row['damage'];
		$enemy['evade'] = $row['evade'];
		$enemy['accuracy'] = $row['accuracy'];
		$enemy['speed'] = $row['speed'];
		$enemy['luck'] = $row['luck'];

		echo 'debug: variables synced with db table';
	}

I know that the setting of these variables are messy  and can be done in a better way... but how? I have tried foreach and copying other's code for an array copy but it lead no where. Then again my syntax could be wrong... I used something like

		foreach ( $enemy[$value] as $row => $value) {
			$enemy[$value] = $row[$value];
		}

 

 

Link to comment
Share on other sites

$enemy[] = $row;

 

didnt work. I wish it was that easy lol

 

It is that easy. Did you put it in the while loop?

 

while ($row = mysql_fetch_assoc($res)) {
     $enemy[] = $row;

     echo 'debug: variables synced with db table';
}

echo '<pre>' . print_r($enemy, true) . '</pre>';

Link to comment
Share on other sites

Yeah I did. The while loop only runs once though because the query gets it only from the one username.

When i run it the variables are not synced and the enemy's HP stays at about ~90 when I attack him.    Whereas before with the messy code, his hp drops with every attack.

 

btw here's the attack action

		if ( $battleAction == "attack" ):
		if ($enemy['current_health'] >= 0) :
			// Factor in the player level when calculating min and max damage.
			$randDamageMin = $player['rawDamage'] - $player['level'] * 2;
			$randDamageMax = $player['rawDamage'] + $player['level'] * 2;
			$randDamage = rand($randDamageMin, $randDamageMax);
			$enemy['current_health'] = $enemy['current_health'] - $randDamage;
			echo '<p style="text-align: center;">
					You deal '.$randDamage.' damage!'.
				'</p>';

			echo $enemy['current_health'];

			$sql = "UPDATE `sa_enemystats` SET enemy_id = '$enemyID', current_health = '$enemy[current_health]', current_skill = '$enemy[current_skill]', level = '$enemy[level]', damage = '$enemy[damage]', evade= '$enemy[evade]', accuracy = '$enemy[accuracy]', speed = '$enemy[speed]', luck = '$enemy[luck]' WHERE username = '$username'";
			$res = mysql_query($sql) or die(mysql_error());
			echo 'debug: new enemy stats table updated';


		endif;
	endif;

Link to comment
Share on other sites

I think it might be to do with the fact that the string arrays in the $row are actually MYSQL database entries while the ones in the $enemy are just PHP array variables... could that be it??

It did strange things when I have it with $enemy = $row. The health updated but all the other variables disappeared.

 

I have tested it on a php variable to php variable basis and it worked so it must be something with mysql i guess

 

<?php 
// test if variables are successfully copied.

$enemyID = 0;
$enemy = array( 
array(
	name => "Trejon Scout",
	health => 100,		
	skill => 100,
	level => 1,		
	damage => 10,			
	evade => 10,			
	accuracy => 60,			
	speed => 5,		
	luck => 5
),
array(
	name => "Trejon Civilian APC",		
	health => 125,		
	skill => 100,	
	level => 2,	
	damage => 6,			
	evade => 10,			
	accuracy => 74,			
	speed => 5,
	luck => 5		
)
);

$enemy['level'] = $enemy[$enemyID]['level'];

$row = $enemy;
echo $row['level'];
echo 'enemy = row <br/>';

$row[] = $enemy;
echo $row['level'];
echo 'enemy[] = row <br/>';


echo $enemy['level'];
echo 'enemy level <br/>';



?>

 

Returned:

1enemy = row

1enemy[] = row

1enemy level

Link to comment
Share on other sites

If you are expecting only one row from the query (which is what your first code implies), there's no need to use any loop. If $enemy doesn't exist and you want it to be an array that holds all the associative values that your query selected, just use -

$sql = "SELECT * FROM sa_enemystats WHERE username='$username'";
$res = mysql_query($sql);	
$enemy = mysql_fetch_assoc($res);

Link to comment
Share on other sites

Thanks guys that actually all worked. But is there a way to set a 2D array into a mysql database? 

The reason for the stuff ups was to do with that.

I have

$sql = "UPDATE `sa_enemystats` SET enemy_id = '$enemyID', current_health = '$enemy[current_health]', current_skill = '$enemy[current_skill]', level = '$enemy[level]', damage = '$enemy[damage]', evade= '$enemy[evade]', accuracy = '$enemy[accuracy]', speed = '$enemy[speed]', luck = '$enemy[luck]' WHERE username = '$username'";

 

Where the original variable was a 2D array and i had to make it a normal one. Like I want to put $enemy[$enemyID][current_health] into the database

 

 

returned:

 

Array

(

    [id] => 18

    [enemy_id] => 0

    [username] => asd

    [current_health] => -8

    [current_skill] => 100

    [level] => 1

    [damage] => 10

    [evade] => 10

    [accuracy] => 60

    [speed] => 5

    [luck] => 5

)

debug: variables synced with db table

 

 

 

 

Link to comment
Share on other sites

$sql = "SELECT * FROM sa_enemystats WHERE username='$username'";
$res = mysql_query($sql);	
$result = mysql_fetch_assoc($res); // Make sure this is only one result, or else loop through it

$enemy[$enemy['enemy_id']] = $result

 

What you're asking for is really basic shit. I'd suggest reading: http://php.net/manual/en/language.types.array.php to answer your own questions.

Link to comment
Share on other sites

I know its basic but im having problems with it..

 

At the moment the initial problem is fixed but just to optimize code better, I can't insert a 2D variable into a mySQL table: $enemy[$enemyID][current_health] ... does this mean i MUST make it $current_enemy = $enemy[$enemyID]; then insert into table?

 

i.e. this doesnt work...

 

$sql = "INSERT INTO `sa_enemystats` VALUES (null, '$enemyID','" . $_SESSION['username'] . "', '$enemy[$enemyID][current_health]')";

 

 

Link to comment
Share on other sites

You really shouldn't leave PHP to guess the index on associative arrays.

 

$sql = "INSERT INTO `sa_enemystats` VALUES (null, '$enemyID', '" . $_SESSION['username'] . "', '" . $enemy[$enemyID]['current_health'] . "')";

 

Now that should work ASSUMING $enemy[$enemyID]['current_health'] actually has the value you're looking for. So let's put echo $enemy[$enemyID]['current_health']; die; right before $sql and see if it returns what you want, okay?

Link to comment
Share on other sites

Thanks heaps man that makes a lot of sense. It all works now, but I just had to make a new variable altogether to store the database version of the variable as opposed to the one storing it to the pre-defined variable $enemy. Not sure if this is the best way to go about it but I just had problems since it overwrote the predefined $enemy[$enemyID]['name'] for instance because the database version doesn't have a Name row.

 

Here's the function in its entirety, maybe there are better ways of optimizing the code since im new to php. For eg I should be using a function call for the database updates because a lot of it is duplicate code - right?

function battle($username = '') {
global $player;
global $enemy;
global $enemyID;
global $battleAction;


// Set Variables

if (!isset($enemy[$enemyID]['current_health'])) { $enemy[$enemyID]['current_health'] = $enemy[$enemyID]['health']; }
if (!isset($enemy[$enemyID]['current_skill'])) { $enemy[$enemyID]['current_skill'] = $enemy[$enemyID]['skill']; }


$sql = "SELECT * FROM sa_enemystats WHERE username='$username'";
$res = mysql_query($sql);
if (mysql_num_rows($res) > 0) :

	$sql = "SELECT * FROM sa_enemystats WHERE username='$username'";
	$res = mysql_query($sql);	
	$db_enemy[$enemyID] = mysql_fetch_assoc($res);

	echo '<pre>' . print_r($db_enemy[$enemyID], true) . '</pre>';
	echo 'debug: variables synced with db table';


	if ($db_enemy[$enemyID]['current_health'] < 0 ) :
		$db_enemy[$enemyID]['current_health'] = $enemy[$enemyID]['health'];
		$sql = "UPDATE `sa_enemystats` SET enemy_id = '$enemyID',  current_health = '" . $db_enemy[$enemyID]['current_health'] . "', current_skill = '" . $db_enemy[$enemyID]['current_skill'] . "', level = '" .$db_enemy[$enemyID]['level'] . "', damage = '" . $db_enemy[$enemyID]['damage'] . "', evade= '" . $db_enemy[$enemyID]['evade'] . "', accuracy = '" . $db_enemy[$enemyID]['accuracy'] . "', speed = '" . $db_enemy[$enemyID]['speed'] . "', luck = '" . $db_enemy[$enemyID]['luck'] . "' WHERE username = '$username'";
		$res = mysql_query($sql) or die(mysql_error());
		echo 'debug: new enemy stats table updated';

		$sql = "SELECT * FROM sa_enemystats WHERE username='$username'";
		$res = mysql_query($sql);	
		$db_enemy[$enemyID] = mysql_fetch_assoc($res);
	endif;


else :
	$sql = "INSERT INTO `sa_enemystats` VALUES (null, '$enemyID','" . $_SESSION['username'] . "', '" . $enemy[$enemyID]['current_health'] . "', '" . $enemy[$enemyID]['current_skill'] . "', '" . $enemy[$enemyID]['level'] . "', '" . $enemy[$enemyID]['damage'] . "', '" . $enemy[$enemyID]['evade'] . "', '" . $enemy[$enemyID]['accuracy'] . "', '" . $enemy[$enemyID]['speed'] . "', '" . $enemy[$enemyID]['luck'] . "')";
	$res = mysql_query($sql) or die(mysql_error());
	echo 'debug: new enemy stats table created';

	$sql = "SELECT * FROM sa_enemystats WHERE username='$username'";
	$res = mysql_query($sql);	
	$db_enemy[$enemyID] = mysql_fetch_assoc($res);
endif;


echo '<div id="wrap-battle">';
	//turn box
	echo '<div id="UI-turnBox">';
		if ( $player['rawSpeed'] >= $enemy[$enemyID][6] ) :
			echo $player['name'].'\'s Turn';
		else :
			echo $enemy[$enemyID][0].'\'s Turn';
		endif;
	echo '</div>';

	//actions
	echo '<p style="text-align: center;">
			<a href="?battleAction=attack">Attack</a> | 
			<a href="?battleAction=defend">Defensive Maneuvers</a> | 
			<a href="?battleAction=evade">Evasive Maneuvers</a> | 
			<a href="?battleAction=skill">Skill</a> | 
			<a href="?battleAction=run">Run</a>
		</p>';

	if ( $battleAction == "attack" ):
		if ($db_enemy[$enemyID]['current_health'] >= 0) :
			// Factor in the player level when calculating min and max damage.
			$randDamageMin = $player['rawDamage'] - $player['level'] * 2;
			$randDamageMax = $player['rawDamage'] + $player['level'] * 2;
			$randDamage = rand($randDamageMin, $randDamageMax);
			$db_enemy[$enemyID]['current_health'] = $db_enemy[$enemyID]['current_health'] - $randDamage;
			echo '<p style="text-align: center;">
					You deal '.$randDamage.' damage!'.
				'</p>';

			echo $db_enemy[$enemyID]['current_health'];

			$sql = "UPDATE `sa_enemystats` SET enemy_id = '$enemyID',  current_health = '" . $db_enemy[$enemyID]['current_health'] . "', current_skill = '" . $db_enemy[$enemyID]['current_skill'] . "', level = '" .$db_enemy[$enemyID]['level'] . "', damage = '" . $db_enemy[$enemyID]['damage'] . "', evade= '" . $db_enemy[$enemyID]['evade'] . "', accuracy = '" . $db_enemy[$enemyID]['accuracy'] . "', speed = '" . $db_enemy[$enemyID]['speed'] . "', luck = '" . $db_enemy[$enemyID]['luck'] . "' WHERE username = '$username'";
			$res = mysql_query($sql) or die(mysql_error());
			echo 'debug: new enemy stats table updated';


		endif;
	endif;


	// decide who is first
	echo '<div id="UI-statsEnemy">'.
			'<h2>'.$enemy[$enemyID]['name'].'</h2>'.
			'<br/>HP: '.$db_enemy[$enemyID]['current_health'].'/'.$enemy[$enemyID]['health'].
			'<br/>SP: '.$db_enemy[$enemyID]['current_skill'].'/'.$enemy[$enemyID]['skill'].
			'<br/>DMG: '.$db_enemy[$enemyID]['damage'].
			'<br/>EVD: '.$db_enemy[$enemyID]['evade'].
			'<br/>ACC: '.$db_enemy[$enemyID]['accuracy'].
			'<br/>SPD: '.$db_enemy[$enemyID]['speed'].
		'</div>';
	// Print Player Stats
	echo '<div id="UI-statsPlayer">'.
			'<h2>'.$player['name'].'</h2>'.
			'<br/>HP: '.$player['rawHealth'].
			'<br/>SP: '.$player['rawSkillPoint'].
			'<br/>DMG: '.$player['rawDamage'].
			'<br/>EVD: '.$player['rawEvade'].
			'<br/>ACC: '.$player['rawAccuracy'].
			'<br/>SPD: '.$player['rawSpeed'].
		'</div>';

echo '</div>';
}

Link to comment
Share on other sites

I have a basic question about your overall game play.

 

For each turn (i.e. one click on someone else's username link) the current visitor (in $_SESSION['username']) only battles that ONE username that he clicked on? If so, why would you have an array of enemies that you use the $enemyID to access one of in the first place? For any turn, you only need the current visitor's data (I'm not sure if he is the player or the enemy) and the data for the username that the current visitor clicked on.

 

Part of the reason I need to ask such a basic question is because we only see the code you post and the posted code does not (clearly) indicate what the values you are passing into the function mean and it has much excess/unclear data and code (without any comments), it is difficult for us to know what the overall code and data is doing or means.

 

Here's at least one unneeded bit in the code you posted - you don't need to make $db_enemy a 2D array because it only exists inside that function where you are retrieving the data at and it only contains the data for the username that the query retrieved. I also suspect that you have probably already retrieved that username's data somewhere else in the overall code and should either use the already retrieved values or you should only retrieve the username's data in the battle function code and not elsewhere.

Link to comment
Share on other sites

Well actually I have the enemy database stored globally before the function. The gameplay is suppose to be a single player one where you VS AI monsters of different levels. But could be in future when I learn more about multiplayer it could be user vs user. I never knew anything about databases before I started this project.

I think in terms of the username fetching it's fairly optimized.. i dont see where I did something wrong. But I think for the updating /inserting into SQL table it could be written as functions instead.

 

Thanks

 

// Enemy Database Tables
$enemyID = 0;
$enemy = array( 
array(
	name => "Trejon Scout",
	health => 100,		
	skill => 100,
	level => 1,		
	damage => 10,			
	evade => 10,			
	accuracy => 60,			
	speed => 5,		
	luck => 5
),
array(
	name => "Trejon Civilian APC",		
	health => 125,		
	skill => 100,	
	level => 2,	
	damage => 6,			
	evade => 10,			
	accuracy => 74,			
	speed => 5,
	luck => 5		
)
);

 

I have a basic question about your overall game play.

 

For each turn (i.e. one click on someone else's username link) the current visitor (in $_SESSION['username']) only battles that ONE username that he clicked on? If so, why would you have an array of enemies that you use the $enemyID to access one of in the first place? For any turn, you only need the current visitor's data (I'm not sure if he is the player or the enemy) and the data for the username that the current visitor clicked on.

 

Part of the reason I need to ask such a basic question is because we only see the code you post and the posted code does not (clearly) indicate what the values you are passing into the function mean and it has much excess/unclear data and code (without any comments), it is difficult for us to know what the overall code and data is doing or means.

 

Here's at least one unneeded bit in the code you posted - you don't need to make $db_enemy a 2D array because it only exists inside that function where you are retrieving the data at and it only contains the data for the username that the query retrieved. I also suspect that you have probably already retrieved that username's data somewhere else in the overall code and should either use the already retrieved values or you should only retrieve the username's data in the battle function code and not elsewhere.

Link to comment
Share on other sites

Based on what I have been able to determine from the code you have posted, the sa_enemystats table can have multiple rows for each player's username, one for each enemy that a user has battled? If so, your queries that select and update the sa_enemystats table must have WHERE username = '$username' AND enemy_id = $enemyID so that they operate on the correct row.

 

Also, please DON'T use the global keyword in your functions to bring values into the function. You should pass values into functions as call time parameters, the same way you are passing in the $username value into the battle function.

 

And, unless the programming editor you are using supports matching up elements using the alternative syntax for control structures (using if(): else: endif;) I recommend that you use the traditional syntax (using if(){}else{}) so that your editor can help you match up elements belonging to the same block.

Link to comment
Share on other sites

I dont like having multiple rows for a single user in one table so as far as the enemyID goes, it will just be dynamically changed. So far the battle system is 1 on 1... so therefore I just need to store one instance of the ID and the next battle will update the ID to reference the variables from the global array.

 

Is there a good reason why global keyword is bad?  Also I'm not using classes, just functions. Maybe I should be looking into that when the project gets larger

 

As far as syntax goes I'm not sure on what matching up means, here's a ss of my editor 11l4j9l.png

Link to comment
Share on other sites

Is there a good reason why global keyword is bad?

 

Yes, for your specific example, it means that the battle function can only do one thing without being rewritten (and retested), because the input values it operates on are hard-coded into it (it might as well not have function name (){} syntax around the code in it.)

 

However, if your battle function was written to be general purpose so that it accepts all the input data it needs, for the two parties that are to battle, as call time parameters, it would be reusable, as is, for your current case, were a real player is battling the computer, if you have a real player battling another real player, or you want the computer to battle itself. You would just supply the correct two sets (arrays) of data when you call the battle function -

 

<?php
function battle($player,$opponent,$battleAction){

//... code uses the $player array, $opponent array, and the $battleAction call time parameters for all the data it needs

}

// for your current case of a real player VS computer -

$result = battle($player,$enemy[$enemyID],$_GET['battleAction']);

// for the case of a real player VS a real player -

$result = battle($player1,$player2,$_GET['battleAction']);

// for the case of the computer VS itself -

$result = battle($enemy[$enemyID1],$enemy[$enemyID2],$someRandomAction);

 

Also for this specific example it would force the data structures to be consistent and contain all the relevant data, which will tend to simplify and clarify the logic. Your current code has a $username, which might or might not be the same as $player['name'], and those might or might not be the same as $_SESSION['username'].

 

Short-answer: As far as your main code is concerned, functions should be general purpose black boxes, that optionally accept input data as call time parameters, perform some useful operation, and returns the result back to the main code. Once you write and test a function, you should be able to use it in any application that needs the operation that it performs, without needing to rewrite and retest it every time you use it with a different source of input data.

 

For the Alternative syntax vs traditional syntax suggestion. I can tell by the left-hand side of your editor's screen that it take no special notice of the Alternate syntax. If you use the traditional {} syntax in php aware editors, the editor keeps track of the matching opening/closing {} and you can put the cursor on one and have the matching one highlighted and you can expand/hide blocks of code between matching {} to get it out of view if it is not currently relevant or if you just want to see the program logic without the code.

Link to comment
Share on other sites

Thanks a lot for the explanation. I understand that logic and i'll get rid of the global. I have another question - I've seen how classes are coded, they use something like var then give it a variable and set it to something. but its quite limiting, like you cant do maths on that variable set or you can't call a function on that variable. And currently my Game.php (the same one with the battle function) sets the $player stats and $enemy stats tables every time it is run. so I'm just not sure if i should be doing that. ie.

// ## PLAYER STATS ##
$player = array();
$player['name'] = "Default Player";
$player['level'] = 1;
$player['statsAccuracy'] = 5;
$player['statsEvasion'] = 5;
$player['statsRepair'] = 5; 
$player['statsIntelligence'] = 5;
$player['statsSpeed'] = 5;
$player['statsLuck'] = 5;

// ## CALC PLAYER BASE STATS ##
$player['rawHealth'] = $player['statsRepair'] * 5 + 100;
$player['currentHealth'] = $player['rawHealth'];
$player['rawSkillPoint'] = 100;
$player['rawActionPoint'] = $player['statsIntelligence']/2 + 100;
$player['rawDamage'] = 10;
$player['rawSpeed'] = 5 + $player['statsSpeed'];
$player['rawEvade'] = 10;
$player['rawAccuracy'] =  $player['statsAccuracy']/2 + 60 - $enemy[$enemyID][4];

 

Currently the battle function is coded so that its entirely CPU orientated.. Maybe if its player vs player the whole code needs a new function altogether.

 

 

 

w02obc.png

 

Oh and you have to mouseover to see the triangles in this editor. It does it so that it keeps the interface minimal, so I guess it's fine?

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.