I am currently working on an elo based matchmaking system. Basically, I have a database where there are a bunch of users, each having their respective ratings.
Brief explanation of code, it chooses one user at random, and chooses another user if the second user is within +-100 difference-elo of the first user (so grandmasters don't play with bronze players). If there is no one within 100 elo, the difference-elo increments by 50 and checks again.
Problem: I created a test user that is 100 elo more than the other users to test the matchmaking system. The program works except for when the first selected player is my test user. The page never loads and it is stuck on "Waiting for localhost". I assumed this meant one of my while loops was going on infinitely, but after spending sometime editing them and trying to figure out why they might be going on infinitely, the error still persists.
<?php
include('mysql.php');
include('functions.php');
$result2 = executeQuery("SELECT * FROM images ORDER BY score DESC");
function executeQuery($query2){
$connect = mysqli_connect("localhost", "root", "password","database");
$result2 = mysqli_query($connect, $query2);
return $result2;
}
// Get random
$query="SELECT * FROM images ORDER BY RAND() LIMIT 0,1";
$result = #mysqli_query($connection, $query);
//Put random in images array
while($row = mysqli_fetch_object($result)) {
$images[] = (object) $row;
}
//Get elo of random
$elo1 = $images[0]->score;
--------------------------
//Point of Interest Below
--------------------------
//Sort database by DESC. Then go through entire database. If current row's elo is with +- difference (which right now is 100) of elo1's rating, ($elo1-100 < x < $elo1+100), then put into new array with all matchups.
//Get length of array, if length is 0 (meaning no match ups were found), increase difference by 50 and try again.
$potentialMatchup = [];
$diff = 100;
$arrayLength = count($potentialMatchup);
while ($arrayLength == 0){
$diff += 50;
while($row2 = mysqli_fetch_object($result2)){
if(($row2->score > $elo1-$diff) && ($row2->score < $elo1+$diff)){
$potentialMatchup[] = (object) $row2;
}
}
$arrayLength = count($potentialMatchup);
}
-------------------------------
//Get random index between 0 and length of array.
$randomNumber = rand(0, $arrayLength-1);
//Put match up into images array
$images[1] = (object) $potentialMatchup[$randomNumber];
//Get names of images
$nameLeft = $images[0]->filename;
$nameRight = $images[1]->filename;
//If same person, pick another random
while($nameLeft == $nameRight){
$randomNumber = rand(0, $arrayLength-1);
$images[1] = (object) $potentialMatchup[$randomNumber];
$nameRight = $images[1]->filename;
}
// Close the connection
mysqli_close($connection);
$leftName = str_replace("_", " ", $images[0]->filename);
$rightName = str_replace("_", " ", $images[1]->filename);
?>
Related
The issue is not how I am generating the number, that is working fine for a different app I have. The issue is counting the total number of boxes and iterating through a forloop that many times. Right now I am multiplying box_ct * qty_ord to get the total boxes. BTW, I am still trying to understand everything I can do with foreach and for loops, so if anyone has a better idea, Great.
CLARIFICATION: I am searching the database by order number and pulling back qty_ord, box_ct, and item_no for each. On some orders there is more than one item. So for each item I need to multiply qty_ord by box_ct = count and for that specific item I need to iterate through the loop based on what my count is.Right now if I remove the foreach and hardcode the for loop count variable it works fine. Any ideas on what is wrong with my foreach?
qty_ord | box_ct | item_no
------------------------
1 2 10001
3 3 10002
2 1 10003
2 3 10004
2 6 10005
Below is my code.
$sql ="SELECT imitmidx_sql.box_ct, oeordlin_sql.item_no, oeordlin_sql.qty_ord
FROM imitmidx_sql
JOIN oeordlin_sql ON oeordlin_sql.item_no = imitmidx_sql.item_no WHERE ord_no ='$orderNum'";
$query = odbc_exec($conn, $sql);
$row7 = odbc_fetch_array($query);
foreach($row7['item_no'] as $item){
$count = $row7['qty_ord'] * $row7['box_ct'];
for($counter = 0; $counter <= $count; $counter++){
//GRAB NUMBER FROM FILE
$sscc = file_get_contents("ucc128.txt");
//INCREMENT NUMBER
$sscc++;
//PUT THE NUMBER BACK IN FILE
$sscc = file_put_contents("ucc128.txt", $sscc);
//COMBINE STATIC NUMBER AND NUMBER FROM FILE
$ssccnumber = "00950000".$sscc;
//CREATE CHECK DIGIT MATH
$ssccnumArray = str_split((string)$ssccnumber);
$ssccstep1 = array_combine(range(1, count($ssccnumArray)), $ssccnumArray);
$ssccstep2 = 0;
$ssccstep4 = 0;
foreach($ssccnumArray as $k => $v){
if($k%2){
$ssccstep2 += (int)$v;
}else{
$ssccstep4 += (int)$v;
}
}
$ssccstep3 = (int)$ssccstep2 * 3;
$ssccstep5 = (int)$ssccstep3 + (int)$step4;
$ssccCheckDigit = (ceil($ssccstep5 / 10) * 10) - $ssccstep5;
//END CREATE CHECK DIGIT
//CONCATENATE FULL NUMBER
$sscc1 = $ssccnumber.$ssccCheckDigit;
$sql = "INSERT INTO ucc128 (sscc, ord_no) VALUES ('$sscc1' ,'$orderNum')";
#echo $sql.'<br />';
odbc_exec($connPRONUMBER, $sql);
}
}
I believe your issue may be with the following:
foreach($row7['item_no'] as $item){
$count = $row7['qty_ord'] * $row7['box_ct'];
//...
}
This should be:
foreach($row7['item_no'] as $item){
$count = $item['qty_ord'] * $item['box_ct'];
//...
}
You are grabbing data from the query results, as opposed to the current row.
My foreach was not working, so what I did instead was get the sum using my SQL query.
SELECT SUM(imitmidx_sql.box_ct * oeordlin_sql.qty_ord) AS total
FROM imitmidx_sql
JOIN oeordlin_sql ON oeordlin_sql.item_no = imitmidx_sql.item_no WHERE ord_no ='$orderNum'
I was then able to ouput it and save $row7['total'] to the variable $count.
On the page I'm creating there is graphic representation of pigeon-holes with five compartments for new comments. If there is new unread comment it should show up as graphic in one random compartment. But it won't happen if all of the 5 are
already occupied. So if someone writes new comment I like the code to check for if there is already five of them taken, and if not, than to randomly occupied one of the remaining ones. So "new_c" stands for number of
unread (new) comments, and c1-c5 stands for compartments. Value 0 means empty compartment for each "c". I was trying to make code that would first separate new_c from rest of the array after knowing the number is smaller than 5,
so I'm only working with 5 compartments. And than to determine which one is/are empty. And then randomly choose one empty to occupy. It's not really working as it is I probably am not using that array_keys properly as c2 is changed to some other value than 0 but still is being echoed, there is probably also a better/more efficient way to achieve that. I will really appreciate some input.
<?php
$tucQuery = "SELECT new_c,c1,c2,c3,c4,c5 FROM users WHERE id = '{$author_id}' LIMIT 1";
$result_tuc = mysqli_query($connection, $tucQuery);
$tucArray = mysqli_fetch_assoc($result_tuc);
mysqli_free_result($result_tuc);
$new_c = $tucArray[0];
if($new_c < 5){
$new_array = array_keys((array_slice($tucArray,1)), 0);
$rand_zero = array_rand($new_array, 1);
echo $rand_zero + 1;
}
?>
Bellow code works but it doesn't seem to be efficient and there is probably a better way.
if($new_c < 5){
$empties = array();
if($tucArray['c1'] == 0){
$empties[] = 1;
}
if($tucArray['c2'] == 0){
$empties[] = 2;
}
if($tucArray['c3'] == 0){
$empties[] = 3;
}
if($tucArray['c4'] == 0){
$empties[] = 4;
}
if($tucArray['c5'] == 0){
$empties[] = 5;
}
print_r($empties);
$rand_zero = array_rand((array_flip($empties)), 1);
echo $rand_zero;
}
Basically I am creating a simple music player in PHP and I am setting the id of each song that is played in an array. I have a script which pulls a random number and plays the song with the corresponding id. I want to make it so that if the song has already played that it wont play again.
Currently I have it generate a random number, and if that number has already been played then it adds 1 to the random number.
The problem is if the number that is the result of adding 1 to the random number, it will then play that song again. I was attempting to store the songs played in an array and just increment the number until it doesn't exist in the array but I am struggling to find a solution to the problem.
My code is as follows:
<?php
session_start();
$con=mysqli_connect("blah blah blah");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if (!isset($_SESSION['played'])) {
$_SESSION['played'] = array();
}
$result = mysqli_query($con,"SELECT * FROM Data") ;
$num_rows = mysqli_num_rows($result);
$numsongs= .20 * $num_rows;
$numsongs=floor($numsongs);
$music = rand(1,$numsongs);
if (in_array($music, $_SESSION['played'])) {$music = $music+1;};
/* goes on to play music below */
$_SESSION['played'][] = $music;
?>
I didn't put my whole script in, the script works minus the repeating of songs. I only included a snippet of how I wrote the repeating script to give an idea of how I attempted it.
Thanks in advance!
I think you are looking for this...
$music = rand(1,$numsongs);
while(in_array($music, $_SESSION['played'])){
$music = $music+1;
echo 'in array '.$music;
}
echo 'Not in array '.$music;
AHAAA!! I figured it out! I ended up using switch() but in a different form.
if (empty($_SESSION['played1'])) {
for ($i = 1; $i <= $numsongs; ++$i) {
$_SESSION['played1'][] = $i;}}
shuffle($_SESSION['played1']);
$music1= $_SESSION['played1'][0];
$result = mysqli_query($con,"SELECT * FROM Data WHERE position = '$music1'") ;
while($row = mysqli_fetch_array($result)){
$del_val=$row[position];
if(($key = array_search($del_val, $_SESSION['played1'])) !== false) {
unset($_SESSION['played1'][$key]);}
Basically created an array between 1 and 10. Then used switch() to randomize the array. Then picked the first number in the array, used it in mysqli query, and then removed it from the array. Problem Solved!!
So here is what I am doing.
Read a row each in for loop. (Because all at once is going to take some resources since I am in a shared hosting.)
2.Get the right field data to a variable.
3.Manipulate the req datas dependant on the extracted field.
4.update the new fields where filed=extracted data.
Bit of addition, I am adding the current position to a file, so that the script can continue from there next time it is run.
Problem : It doesnt seem to work. The counter.txt gets values like 3-4, but it simply resides there. my db has like 1000k rows.
my code :
require ("dbconnect.php");
header("refresh:29;url=process.php"); // so it doesnt ever end. I cant use max_execution_time here for some reason.
$count = mysql_query("SELECT COUNT(*) FROM collection ");
$data = mysql_fetch_array($count);
$count = $data[0];
echo $count;
$countfile = fopen("counter.txt", "r");
$counter = fgets($countfile);
echo fgets($countfile);
while (fgets($countfile) <= $count)
{
$i = fgets($countfile);
$takeword = mysql_query("SELECT word FROM collection WHERE id='$i'") or die();
$wd = mysql_fetch_array($takeword);
$data = $wd[0];
$d1 = hash($algorith='md2',$data);
$d2 = hash($algorith='md4',$data);
$write = mysql_query("UPDATE collection SET md2='$d1', md4='$d2' WHERE id='$i'") or die(mysql_error());
//opens, empties and write the new pointer to the file. closes, and open the file in readmode for the next read at the loop.
$counts = fopen("counter.txt", "w+");
fwrite($counts, $counter + 1);
fclose($counts);
$countfile = fopen("counter.txt", "r");
}
Any help would be appreciated :) Looking for code optimization and killing the error. Suggestions would do.:)
Alright I'd do something like this (sorry about the delayed response, I kept forgetting)
<?php
//main execution
$sql = mysql_connect(...);
if (!$sql)
die ("No database connection");
if (!mysql_select_db(..., $sql))
die ("Database does not exist in this schema");
//Run the query for this iteration.
processQuery();
//---
function getQueryOffset($file)
{
$offset = 0; //default offset
if (file_exists($file)) //check if the counter file exists
{
$contents = file_get_contents($file); //get the contents of the counter
if ($contents !== FALSE && is_numeric($contents)) //check if an appropriate counter value
$offset = intval($contents);
}
return $offset;
}
function processQuery()
{
$table = "collection"; //table to update
$counter = "counter.txt"; //where to look for the last execution's offset.
$maxrows = 10000; //update 10,000 rows each time this file is loaded.
$sql = $GLOBALS['sql'];
//calculate the number of rows in the table
$qCount = mysql_query("SELECT COUNT(*) max FROM $table", $sql);
$aCount = mysql_fetch_assoc($qCount);
mysql_free_result($qCount);
$max = $aCount["max"];
$offset = getQueryOffset($counter); //calculate the offset (or a default 0)
if ($offset < $max) //if offet >= max, we're done.
{
$qUpdate = mysql_query("SELECT word, id FROM $table LIMIT $offset, $maxrows", $sql); //get the next "maxrows" rows from the table.
if ($qUpdate)
{
$assoc = NULL;
while (($assoc = mysql_fetch_assoc($qUpdate)) != NULL)
{
$md4 = hash("md4", $assoc["word"]); //calculate the hashes
$md2 = hash("md2", $assoc["word"]);
$id = $assoc["id"]; //id the row
mysql_query("UPDATE $table SET md2='$md2', md4='$md4' WHERE id=$id", $sql); //update the table columns
}
//update the offset in the counter file.
file_put_contents($counter, ($offset + mysql_num_rows($qUpdate)));
mysql_free_result($qUpdate);
}
}
}
mysql_close($sql);
?>
1 issue that I am seeing here:
Check your update query - that seems to be wrong. According to me, it should be "SET md2='$d1' AND md4='$d2'"
Another issue that I am not sure about:
I am unsure if md2 and md4 are valid names of hashing algorithms
A better way of doing this:
1. Dont write to file!
2. Create an additional column in your SQL by the name 'status', default value to 0. On update, change that value to 1.
3. Search for rows to edit based on query "SELECT word FROM collection WHERE status=0 limit 0,1"
4. OR if the columns md2 and md4 are empty in the original table, query could also be "SELECT word FROM collection WHERE md2='' and md4='' limit 0,1"
Hope this helps.
I need to generate a unique extension for each user (this is separate from the ID but works much the same) the number should be 100 or greater and can be overwritten/custom set. Right now I am taking the next id and if it's less than 100 add 100.
So if the next id is 5 the number would be 105 but it the next id is 105 the number would just be 105. The problem is that because i'm letting the user pick their own extension if a user choose 105 before I want to make it automatically jump to the next number in this case 106. Now if there is 105, 106, and 108 I would want to jump to 107 then jump to 109. Here is the code I'm using to generate the numbers. I think the problem is with my while loop. I'm not sure how to make it keep on checking for unique numbers.
Here is the code, I'm sure I'm overcomplicated things A LOT.
$result = mysql_query("SELECT MAX(id)
FROM USERS");
$row = mysql_fetch_row($result);
$sql_extention = intval($row[0]);
//make sure it's at least 100
$extension = ($sql_extension < 100) ? $sql_extension+100 : $sql_extension;
//check to see if the extention is in use
$qry = "SELECT `extention`
FROM users
WHERE extention = '$extention'";
$result2 = mysql_query($qry);
//if the extention is in use then find the next available one (this isn't currently working)
if($result2) {
//get all results greater or equal to our extention
$qry3 = "SELECT `id`,`extention`
FROM admin_users
WHERE extention >= '$extention'";
$result3 = mysql_query($qry3);
//this loop needs to be rewritten somehow to get the next number by checking if the next number exist if not return that as the extention
$new_extention = $extention+1;
while($extention_data = mysql_fetch_array($result3)) {
if($new_extention != $extention_data['extention']+1) {
$extention = $new_extention;
}
$new_extention++;
}
I came up with this, haven't tested it thoroughly but i think it should return the next available value correctly
SELECT (a.extention + 1) as avail
FROM admin_users a LEFT JOIN admin_users b on ( (a.extention + 1) = b.extention )
WHERE a.extention >= 105 and b.extention is null
ORDER BY avail ASC
LIMIT 1
So if this works as expected you wont need the last few lines of code at all.
Edit:
Revised the query because i realized i was approaching it from the wrong side.
Shoddy attempt at PHP/pseudocode example as per my comment:
//nicer way to get the id of the user you just inserted!
$id = mysql_insert_id();
$sql = "SELECT `extension` FROM users ORDER BY `extension` ASC";
$res = mysql_query($sql);
$i=0;
while($n = mysql_fetch_array($res)){
if($i==0){
$i=$n['extension'];
}
if($i==$n['extension']){
$i++;
} else {
break;
}
}
//No existing users, start at 100
if($i==0){
$i=100;
}
Then use $i as your extension.
Ok, so you need the next available extention higher then a given number, that is not already in the database.
So, you ideally want an array from the database that has all available extentions higher then a given key sorted ascending. Then you loop from the given number increasing by one, until it does not match. You don't mention a max number of extention. I would do it like this:
<?php
$rs = mysql_unbuffered_query("SELECT extention, MAX(extention) FROM admin_users WHERE extention > '$extention' ORDER BY extention ASC");
$unavailable = array();
$max = 0;
while( ($row = mysql_fetch_row($rs)) )
{
$unavailable[] = $row[0];
if( !$max ) $max = $row[1];
}
mysql_free_result($rs);
// Optimization for the quite common case where no more extentions are available
if( count($unavailable) > 0 )
{
while($extention <= $max+1)
{
if( !in_array($extention, $unavailable) )
break;
$extention++;
}
}
else
$extention = $max+1;
// Worst case: $extention now is max + 1 and we looped through almost everything.
?>