Jump to content

Need random and unique but its not


wladeg

Recommended Posts

Its tarot website http://tarovartai.lt  where u pick 3 tarot cards from 21card desk, cards cant repeat but they repeat sometimes, please help

<div id="cards-list">
            <?php
                $numbers = range(1, 21);
                shuffle($numbers);
                foreach ($numbers as $number) {
            ?>
                <div id="card" class="card<?php echo $number; ?>" name="<?php echo $number; ?>"></div>
            <?php
                }
            ?>
        </div>
        
        <div id="picked-cards">
            <div id="picked-period"></div>
            <?php
                $cls = 0;
                $date = date('Y-m-d');
                $query = mysqli_query($conn, "SELECT * FROM history WHERE USERID = '$loggedin' AND DATE = '$date'");
                $count = mysqli_num_rows($query);
                if($count > 0)
                {
                    while($row = mysqli_fetch_assoc($query))
                    {
                        $cardID = $row['CARD'];
                        $queryCard = mysqli_query($conn, "SELECT * FROM cards WHERE ID = '$cardID'");
                        $row2 = mysqli_fetch_assoc($queryCard);
            ?>
            <div id="picked-card-desc">
                <table>
                    <tr>
                        <td id="forS" class="for">
                            <?php
                                if($cls == 0){
                                    echo "Veiksmas, situacija";
                                }elseif($cls == 1){
                                    echo "Ko saugotis ir vengti";
                                }else{
                                    echo "Rezultatas";
                                }
                            ?>
                        </td>
                    </tr>
                    <tr>
                        <td class="img"><img src="/images/cards/<?php echo $row2['IMG']; ?>"></td>
                    </tr>
                    <tr>
                        <td class="name"><?php echo $row2['NAME']; ?></td>
                    </tr>
                    <tr>
                        <td class="desc"><div class="scroll"><?php echo $row2['TEXT']; ?></div></td>
                    </tr>
                </table>
            </div>
            <?php
                        $cls++;
                    }
                }
            ?>
        </div>

korta1.jpg

korta2.jpg

Link to comment
Share on other sites

the fix is to define what you want, then write and test the code to do it.

the history table appears to be where the card state is remembered?

when a new game is started, i would insert 21 rows, with card ids 1-21, with the userid/date, into the history table, with a column that indicates if the card id is 'used' a 0 = not used, a 1 = used.

to generate a set of three new cards, retrieve the card ids from the history table that have not been used. if the number of unused card ids is zero, the game is over. store the unused card ids into an array, shuffle them, and pick three ids. update the history rows to set the 'used' column to a 1 for the three ids that were picked and display the cards that correspond to the three ids. when retrieving the card information for the card ids, run one query that gets the data you want in the order that you want it (don't run SELECT queries inside of loops.)

you should also not put 'dynamic' data values directly into the sql query statement. we don't know where the $loggedin value comes from, but if it could have come from user supplied data, it could be used to inject sql. you should use a prepared query when supplying potentially unsafe data to an sql query statement.

 

Link to comment
Share on other sites

Something like this will give you 3 random cards each day and prevent duplicates in the same week. Run once per day.

INSERT INTO tarot_history (date, card_id)
  SELECT CURDATE()
     , c.card_id
  FROM tarot_card c
	 LEFT JOIN
     tarot_history h 
		ON c.card_id = h.card_id
			AND WEEK(date) = WEEK(CURDATE())
  WHERE h.card_id IS NULL
  ORDER BY RAND()
  LIMIT 3;

 

Link to comment
Share on other sites

After which you need only a single query (not your while loops with two queries) to get today's cards

SELECT * FROM tarot_history
ORDER BY WEEK(date), card_id;

+------------+---------+
| date       | card_id |
+------------+---------+
| 2018-06-07 |       1 |  -- last week
| 2018-06-07 |       5 |  -- last week
| 2018-06-07 |       9 |  -- last week
| 2018-07-09 |       1 |
| 2018-07-08 |       2 |
| 2018-07-08 |       6 |
| 2018-07-09 |       8 |
| 2018-07-10 |      10 |  -- today
| 2018-07-08 |      12 |
| 2018-07-09 |      15 |
| 2018-07-10 |      18 |  -- today
| 2018-07-10 |      19 |  -- today
+------------+---------+

SELECT cardname
     , cardtext
     , imagefile
FROM tarot_history
      JOIN
     tarot_card USING (card_id)
WHERE date = CURDATE();

+----------+----------------------------------------------------------+-------------+
| cardname | cardtext                                                 | imagefile   |
+----------+----------------------------------------------------------+-------------+
| card_10  | Suspendisse dapibus lorem pellentesque magna.            | card_10.jpg |
| card_18  | Aliquam at eros. Etiam at ligula et tellus ullamcorper.  | card_18.jpg |
| card_19  | Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus | card_19.jpg |
+----------+----------------------------------------------------------+-------------+

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • 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.