4

I'm trying to build a browser card game with mostly PHP and maybe some other useful languages thrown in to test and expand my PHP knowledge with something I always wanted to make. But every online solution I've read and tried to implement wouldn't work and I don't know why. I have logic like this:

//find game form
        print "<form method='post' action='game.php'>
        <label>Enter host generated game #</label><br>
        <label><input type='text' name='gamenumber'></label><br>
        <label><input type='submit' name='findgame' value='FindGame'></label><br><br>
        </form>";

        //host game button
        print "<form method='post' action='game.php'>
        <label><input type='submit' name='hostgame' value='HostGame'></label>
        </form>";

//game logic



if(isset($_POST['hostgame'])) 
    {
        $roomnumber = rand();
        print $roomnumber;

        insertField($Ausername,$roomnumber); //insert field GUI

        //link game to host for future field printing
        $query = "UPDATE game".$roomnumber." SET host='".$Ausername."' WHERE host='null'";
        $result = mysqli_query($link, $query);

        print "<div id='quote'>"; //populate host just disappears <meta http-equiv='refresh' content='5' />

        //populates self and opponents in hosts perspsective
        populatehost($roomnumber); 

        print "</div>";


    }

    if(isset($_POST['findgame'])) //this processes after user submits data.
    {
        $roomnumber = $_POST['gamenumber'];
        $_SESSION['gamenumber'] = $_POST['gamenumber'];

        //link game to find for future field printing
        $query = "UPDATE game".$roomnumber." SET find='".$Ausername."'WHERE find='null'";
        $result = mysqli_query($link, $query);

        print "<form method='post' action='game.php'>
        <label><input type='submit' name='startgame' value='StartGame'></label>
        </form>";

        //populates self and opponents in finds perspsective
        populatefind($roomnumber); 

    }


    if(isset($_POST['startgame'])) //this processes after user submits data.
    {
        print "<br>Game started.<br>";

        print "heads or tails?\n\n";

        print "<form method='post' action='game.php'>
        <label><input type='text' name='headstails'></label><br>
        <label><input type='submit' name='select' value='Select'></label><br><br>
        </form>";

        //finder always starts game
        populatefind($_SESSION['gamenumber']);
    }

    $gameStatus="";
    $flip = rand(1,2);
    $coin = "heads";
    $gameStarted = "game not started";

    if($flip==1)
        $coin="heads";
    else if($flip==2)
        $coin="tails";

    if(isset($_POST['headstails'])) //this processes after user submits data.
    {
        if($_POST['headstails']==$coin)
        {
            print "find game player goes first";
            $gameStarted = "game started";
            //notify find game player he goes first
            //do logic where he goes first
        }
        else
        {
            print "host game player goes first";
            $gameStarted = "game started";
            //notify host game player he goes first
            //do logic where he goes first
        }

        populatefind($_SESSION['gamenumber']);
    }

this is the jquery function I tried that I pasted at the bottom of the page.

?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js%22%3E%3C/script%3E">
    jQuery(function () {
        var $els = $('div[id^=quote]'),
            i = 0,
            len = $els.length;

        $els.slice(1).hide();
        setInterval(function () {
            $els.eq(i).fadeOut(function () {
                i = (i + 1) % len
                $els.eq(i).fadeIn();
            })
        }, 2500)
    })
</script>

</body>
</html>

so I was able to get the field printed for both the host and finder, and once the finder flips the coin it says who goes first from their perspective.. but I'm having trouble getting that to appear on the other player's perspective. I was thinking of implementing that by refreshing a div with the function that does all the printing, but nothing seemed to work no matter what. I tried the php sleep method in many different ways, I tried some jquery function, nothing worked. And btw populate host and populate find are just functions with giant tables based on arrays of variables.

2316354654
  • 279
  • 2
  • 3
  • 14
  • Have you tried Ajax calls ? – Krunal Limbad Feb 05 '18 at 09:55
  • Please rephrase the question. It is not understandable a little bit. And whats is your problem and what do you want. I cannot find these in your question. Be clear. Make separate paragraph for your points. – Munim Munna Feb 05 '18 at 11:33
  • It would be extremely painful to handle it with normal php and ajax. Check PHP Socket. This [SO post](https://stackoverflow.com/questions/6802741/php-ajax-multiplayer-game) may be useful – Yuri Feb 05 '18 at 12:38
  • Don't use ```script``` tags with ```src``` and ```content``` at same time. You can see details in [this thread](https://stackoverflow.com/a/6528343/1202416). – moreirapontocom Feb 08 '18 at 11:49

2 Answers2

7

This sort of thing you're trying to achieve will spend a lot of resources of your server using regular Ajax calls.

Similar Question : Link

Let's consider a chat between two users as example:

User's 1 page have a Javascript timer asking every second for new messages: "hey server, send me new messages." With or without new messages, the server will handle the request, search for new messages to reply "I've got no messages for you right now" or "here is your new message". Same for user 2.

If both users keep the chat page open for 10 seconds, your server will receive 20 requests for new messages, will run 20 searches for new messages and will send 20 replies with the new messages or "no new messages" reply. Even if both users had send nothing, just keeping the page open. Imagine if 1000 users are connected to your chat room!

The best approach in this case is Socket. In the same chat example, user 1 and user 2 will stay listening for new messages instead asking for them each second. When user 1 send a message, the server will notify the user 2 "I have a new message for you. Here is."

If 1000 users are connected, there is no problem at all. The server will send the new message to a socket channel and all users connected will be notified. No delay.

In your specific case, will work like this: player 1 and player 2 are listening for new messages. When player 1 clicks on card, will trigger a command for server. Server will receive and send a message for a socket channel: "hey everyone who is awaiting for new cards, here is" then every player will be notified. Instantly.

Another problem with the first scenario, using Javascript timers: if you increase the timer interval, the replies will be delivery delayed.

Another good thing about sockets: it's independent of technology. PHP, Java, Node, etc.

GitHub Project for using WebSocket with Php : Link

You can see some socket demos here

Here is a repository with some tests I ran when I tried Socket earlier

Vishnu Bhadoriya
  • 1,655
  • 1
  • 20
  • 28
moreirapontocom
  • 458
  • 3
  • 10
  • [PHP React](https://reactphp.org/) is a good place to get started. They have a chat server example in the docs somewhere. – Brainfeeder Feb 07 '18 at 22:35
  • @Brainfeeder I tried copying that PHP react demo into a bare bones php script and nothing printed.. I'm not sure why, I feel like I don't have a grasp of server programming and networking. – 2316354654 Feb 09 '18 at 03:53
  • @moreirapontocom I tried using the javascript demo in a script at the bottom of the page, but I'm not sure if I'm doing it right. I've always been a bit un-confident with javascript. And I tried running "composer require textalk/websocket 1.0.*" on my school server (im not sure if thats where I'm supposed to type that, I'm using windows 7 btw.) but got "composer: No match." Could you show me how to run one of those socket demos in a way where a coin flip status is updated for one user once a different user presses the coin flip button on the other end? Please and thank you very much. – 2316354654 Feb 09 '18 at 04:11
  • For React, you should run the server in console first. And be sure the ports you set for sockets are open and not used by something else. It is all in the docs. I admit it can be abstract at first.. but once it works you’ll be amased of what is possible with sockets. – Brainfeeder Feb 09 '18 at 07:39
3

You can do it this way:

setInterval(function refresh(){
  var value = Math.round(Math.random()*100);
  $("#target").addClass("hidden");
  $("#target").html(value);
  $("#target").removeClass("hidden");
}
, 1500);
.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="target">
</div>
SamratV
  • 224
  • 2
  • 12
  • I think it's good stuff. It can be nice to provide a pure js solution too. In fact it is pretty close to be pure js. – NVRM Feb 10 '18 at 16:35
  • can you tell me how the javascript file for that function looks? I'm having trouble getting it to work. – 2316354654 Feb 16 '18 at 16:16
  • Nvm. i wrapped it in: window.onload = function() { } – 2316354654 Feb 16 '18 at 16:32
  • You don't need to wrap it. Just make sure that you import JQuery library before writing that function. Write the CSS and JQuery import inside the head tag and the function near the end of body tag but within script tag. – SamratV Feb 16 '18 at 16:56
  • this doesn't work for two different players playing in the same game. only the person who changes value sees changes – 2316354654 Mar 21 '18 at 14:52