Jump to content
  • Advertisement
Sign in to follow this  
menyo

[web] 2 player turn battle script crashes.

This topic is 2851 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi folks,

If thought i finally managed to make a 2 player game with PHP and Jquery but i my whole computer gets stucked when the first player has gets his 2nd turn.

What i basically have are 2 .txt files where both players units are listed. I will read this file into an array. Each unit has a speed key wich value increases when that unit has made an action, i write the new speed to the file and the script runs again.

Heres the script that decides which unit goes first.


$time = 0;
$found = 0;
while ($found != 1)
{
foreach ($P1recruit as $p1)
{
if ($found == 1) break;
if ($p1['speed']<$time)
{
$p1['speed'] = $p1['speed'] * ceil ($time / $p1['speed']);
}

elseif ($p1['speed']==$time)
{
$p1turn = true;
$p2turn = false;
$found ++;
}
}

foreach ($P2recruit as $p2)
{
if ($found == 1) break;
if ($p2['speed']<$time)
{
$p2['speed'] = $p2['speed'] * ceil ($time / $p2['speed']);
}

elseif ($p2['speed']==$time)
{
$p1turn = false;
$p2turn = true;
$found ++;
}
}


$time ++;

}




Then follows all the HTML to build up the page. The player who has to act gets a form with choices to do with his unit. The other player gets "Opponents turn" in that window.

So in the above code you see $p1turn or $p2turn gets true or false. This is for the Jquery script at the end of all the HTML to tell wich player needs to keep polling the unit files until theres a unit for him to act. Heres the script:


if ($p1turn == true)
{
if ($battle['player2'] == $_SESSION['SESS_MEMBER_ID'])
{
echo "
<script type='text/javascript'>

function turnlistener() {
$('#main').load('battlegetnextunit.php');
};

$(function() {
setInterval('turnlistener()', 5000 );
});

</script>
";
}

}

if ($p2turn == true)
{
if ($battle['player1'] == $_SESSION['SESS_MEMBER_ID'])
{
echo "
<script type='text/javascript'>

function turnlistener() { $('#main').load('battlegetnextunit.php');
};

$(function() {
setInterval('turnlistener()', 5000 );
});

</script>
";
}
}
?>



Now for the first player (the one who starts the battle) he can act properly. The next player can act, but he still is longpolling the .txt files as the form resets. If he acts withing the 5 seconds (setInterval('turnlistener()', 5000 )) the other player gets his turn again but my whole computer starts strugling and i'm not able to select anything in the form.

Maybe it's like the players get double longpolling the 2nd turn. But i only have the last code once and obviously only 1 of 2 can run as either $p1turn or $p2turn can be true and it can only run for one player.

What could this be? Is doing it this way even possible? I'm trying to figure this out for days now, i really hope someone can help me out.

Thanks!

[Edited by - menyo on September 29, 2010 10:27:16 AM]

Share this post


Link to post
Share on other sites
Advertisement
First, a few things:

1) If you're going to post that much code, please use a code-paste site, such as http://codepaste.net/

2) Please continue to work on your coding capabilities (doing tutorials, etc). Don't take this the wrong way, but your code is border-line awful.

3) Why are you not using mysql/classes for this in lieu of text-files and arrays?

4) Congrats on starting a php game. I am a big fan of these.


Ok, onto the problem. Have you tried doing a reset() of $p1 and $p2 (which, btw's, I often refer to each player as $P[$i] in my combat code :P )? If you do not reset the array (ie, set the pointer back to the first row), you won't be able to walk it again with foreach() Not really sure how you're storing the array information, but I'd start here.

Also, you may want to add several 'echo' statements throughout your code so you can see where its getting hung at.

5) I'm putting this at the bottom because it may be a while off for you, but consider using a least-common-multiple function for finding the next players attack turn. If I have a speed of 3, and you a speed of 4, it makese 'sense' to let every '12th' point be the start of a new turn. In other words, I'd start with 3, you 4. I'd move up to 6, you 8. Then we'd hit 9 - 12, in which a turn event is triggered for you. This will save you several iterations during your combat sequence.

Share this post


Link to post
Share on other sites
Quote:
Original post by Cygnus_X
1) If you're going to post that much code, please use a code-paste site, such as http://codepaste.net/

I'd prefer it if he just used the source tags! (See the Forum FAQ.)

Anyway, I've no idea what the actual problem is, because there's this talk about "longpolling" (what does that mean?) of text files, except we don't get to see that code. Nor do we know what "battlegetnextunit.php" does.

There's no good reason why the whole computer would have a problem. Are you running PHP on the same machine that you're using the browser from? What does Task Manager say is taking up all the CPU time when this happens?

Share this post


Link to post
Share on other sites
Quote:
Original post by menyo
Sorry i tried to use [php] and .
[code] provides plain formatting, but we would rather you use [source], which provides syntax colouring and scrolling.
Quote:
Can't find anything about source tags in the forum FAQ.
See here.

Share this post


Link to post
Share on other sites
We're still only 4 lines into your code and we have a variable that we don't know how it got defined.

$P1recruit

where does this come from?

Also, on a separate topic, the htmlentities() function doesn't always want to work right in the forums. It would be nice if someone could look into this.

[Edited by - Cygnus_X on September 29, 2010 10:32:34 AM]

Share this post


Link to post
Share on other sites
Srry, just read the Forum faq.

Also i used clearInterval without succes.

Anyways

@Cygnus_X
What you mean by borderline awfull? Do you mean the code is bad or how i format/layout it is bad? I know i have much to learn and i will :D.

I'm not yet familiar with classes, i will look into it. Why i'm using txt files? Actually i wanted to test out if it would work with txt files and increase my knowledge a little in that area. I made some tests and it seemed to work. I'm using JSON to write an array as an object to a txt file. then read it back in and convert it back to an array again. I was wondering what would be faster, query the DB for the 8 units each couple of second or reading out the file each couple of seconds. Don't know the answere yet as this major problem occured (topic).

So on to the problem. I don't think i need to reset() the array. I read it out from the file each time. It's like this battle.php loads getnextunit.php here the whole page is build up wich works fine then form battle.php gets from getnextunit.php is sent to battleaction.php wich does the math changes the array writes it back to the file and loads battleaction.php again. So the player won't leave battle.php. As this works for 2 turns i see no problem here.

I have put several echos into the code, but once it hangs the browser of the player who needs to act just crashes.

Not sure what you ment by 5) but i was going to sent the time to each page and include that into the txt file or database. I tested the code and if i manualy set the time to milions it still gave the next unit correctly and instant.


@Kylotan

Longpolling is a script that keeps running on the client with something like setInterval. In my case it keeps calling battlegetnextunit.php to look if theres a unit that belongs to him that is next to act. If so the page generates the command form.


Here is my complete code for the battle.
battle.php:
http://codepaste.net/1pbik4

battlegetnextunit.php:
http://codepaste.net/t42b8r

battleaction.php:
http://codepaste.net/etcqsi

Thx!

Share this post


Link to post
Share on other sites
Quote:
Original post by Cygnus_X
We're still only 4 lines into your code and we have a variable that we don't know how it got defined.

$P1recruit

where does this come from?

Also, on a separate topic, the htmlentities() function doesn't always want to work right in the forums. It would be nice if someone could look into this.


battle.php

$p1recruit = array();
while ($player1recruits = mysql_fetch_assoc($recruits1query))
{
$P1recruitquery = mysql_query ("
SELECT recruitID, name, type, health, stamina, energy, damage, defense, reaction, accuracy, speed FROM army WHERE recruitID = ".$player1recruits['recruitID']."
")or die(mysql_error());

$P1recruit[] = mysql_fetch_assoc($P1recruitquery);
}

$p2recruit = array();
while ($player2recruits = mysql_fetch_assoc($recruits2query))
{
$P2recruitquery = mysql_query ("
SELECT recruitID, name, type, health, stamina, energy, damage, defense, reaction, accuracy, speed FROM army WHERE recruitID = ".$player2recruits['recruitID']."
")or die(mysql_error());

$P2recruit[] = mysql_fetch_assoc($P2recruitquery);
}


if (!file_exists("".$battle['player1']."-".$battle['battleID'].".txt"))
{

//create file for player 1 recruits
$P1file = "".$battle['player1']."-".$battle['battleID'].".txt";
$handle1 = fopen($P1file, 'w+') or die("can't open file");

//Put player1 recruits array into a JSON string to write to file
$arraytojson = "".json_encode($P1recruit)."";
fwrite($handle1, $arraytojson);
//close file
fclose($handle1);
}

if (!file_exists("".$battle['player2']."-".$battle['battleID'].".txt"))
{
//create file for player 2 recruits
$P2file = "".$battle['player2']."-".$battle['battleID'].".txt";
$handle2 = fopen($P2file, 'w+') or die("can't open file");

//Put player2 recruits array into a JSON string to write to file
$arraytojson = "".json_encode($P2recruit)."";
fwrite($handle2, $arraytojson);
//close file
fclose($handle2);
}



battlegetnextunit.php

//open battle file for player 1, --> Make sure to delete file when battle finishes.
$player1 = file_get_contents("".$battle['player1']."-".$battle['battleID'].".txt");
$obj1 = (json_decode($player1));

$P1recruit = objectToArray( $obj1 );
/*print_r($P1recruit);
echo "<br><br>";*/


//open battle file for player 2, --> Make sure to delete file when battle finishes.
$player2 = file_get_contents("".$battle['player2']."-".$battle['battleID'].".txt");
$obj2 = (json_decode($player2));

$P2recruit = objectToArray( $obj2 );
/*print_r($P2recruit);
echo "<br><br>";*/




Share this post


Link to post
Share on other sites
opera seems to be causing the crashing as it is using over 1GB of memory. I have a crappy 4 year old computer with only 2GB of memory the other 2GB burned a year ago. But i'm planning on buying a brand new PC in a couple of weeks. But still that would not solve it.

Would the file handling be the problem? It loads the file each couple of second. It seems to do alright for a minute or 2.

-edit-
Well the opera thing is not happening every time. I am aware that the code isn't that efficient. I tried many many ways to get this to work and fix this problem.

I'm gonna scrap what i have and start over. Maybe read something about classes or try it just with polling the database.

Cygnus_X

Can you offer me some more insight on how you would make this type of turn based game? What i'm trying to achief here is that if unit 1 has 3 speed and unit 2 has 5 speed it would go like this: unit1(3) -> unit2(5) -> unit1(6) -> unit1(9) ->unit2(10)



[Edited by - menyo on September 29, 2010 11:21:48 AM]

Share this post


Link to post
Share on other sites
While reading over this code, I couldn't help thinking that you just need to start over. I'm glad you said it first. Storing data in a text file that you're constantly having to update, un-encode and re-encode is a bad design when you have an available database to work with.

Since you are unfamiliar with classes, I'll give you my explanation. As a pre-warning though, I'm self-taught much like yourself, and many of the users on these forums are many times more technical and knowledgeable than I.

The biggest benefit of classes, IMO, is that they offer superior variable management. Consider having a function called round() that rounds a number to the nearest integer. We don't care about how the code works, we just know the basic structure is:

function round($x)
{ ..... }

Lets say this is a good function for us, and we use it a million times over the course of 10 years. Then, one day, we decide that we want to round to the nearest tenth decimal place. We have two options:

Options 1 - change to function to round($x, $precision) and then re-write the function. The problem with this is that we'd have to change all previous 1 million instances of round($x) to round($x, $precision) to get the new code to work properly.

Option 2 - Create a new function. This option is better than option 1 for this example, but now we have 2 functions that do virtually the same thing.

So, here is where classes come in. With classes, we'd write this as:

class math
{
function --construct()
{ }

function round($x)
{ ... }
}

And we'd call this method via:

$Math = new math;
$MyVar = $Math->round('3.45');

Whats so great about this? Well, if we wanted to change the precision, all we'd have to do is add $this->precision = 0; to the __constructor function (ie, method cause its in a class), and for the next time we call it, we'd use:

$Math = new math;
$Math->precision = 1;
$MyVar = $Math->round('3.45');

The idea here is, the __constructor method gets called every time the class is defined. So, once we realize we need to add precision, we can go back and auto-define the default precision to 0. Then, when we need it, we can up it to 1 without having to worry about the million plus previous instances of the code. We do a little rework of the code inside round(), and bam, its works retroactively and has more functionality.


AS FOR THE ATTACK TIMER:

I'd set a clock inside my combat script (which I'd make as a class) that was the lcm * 2 of the two players speed. I'd then increment just as you did in a loop. I'd probably call the variable Initiative. And just do $P->Initiative += $P->Speed.

I'd then loop through all $P classes, get the highest initiative, compare it to the 'clock', then go again.

AS FOR YOUR CODE:

I'd have to see your design documents to lay this out better, but I'd set up a class that auto loads all the data it needs from the database. So, when you say:

$P[1] = new fighter($ID1);
$P[2] = new fighter($ID2);

These two lines of code can replace all the loops, etc, that you're currently using to load information out of the database and into an array. The possibilities only grow from here.



As I said earlier, I love php games. So i'd be happy to help you more with this (I have code you can look at) if you'd like.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!