I have encountered a logical hurdle!
I have a page with 6 actions on. when you click an action, it simply returns a true or false.
Each action has its own chance of success, and the true /false is based on whether a random generated number is higher or lower than the actions success value.
the chance values are stored in the database like: 10-20-30-40-50-60
I call these values using explode and insert them using implode.
What I want to achieve is to change these chances values to either 1 more, 1 less or the same (upto a max of 65), each time an action is clicked and the form submitted,
This is what I have attempted but to no avail.
<?PHP
//CHANCE 0 (action 1)
if ($chance[0] = 0 ){
$chance[0] = rand(0,1);
}elseif ($chance[0] = 1 ){
$chance[0] = rand(1,2);
}elseif ($chance[0] >= 2 ){
$chance[0] = $chance[0] + rand(-1,1) ;
}elseif ($chance[0] >= 65 ){
$chance[0] = 65;
}
//CHANCE 1 (action 2)
if ($chance[1] = 0 ){
$chance[1] = rand(0,1);
}elseif ($chance[1] = 1 ){
$chance[1] = rand(1,2);
}elseif ($chance[1] >= 2 ){
$chance[1] = $chance[0] + rand(-1,1) ;
}elseif ($chance[1] >= 65 ){
$chance[1] = 65;
}
etc.. for all chance[0] to chance[5]
then,
$chancearray = array($chance[0], $chance[1], $chance[2], $chance[3], $chance[4], $chance[5]);
$newchancearray = implode("-",$chancearray);
?>
and insert it into the database.
can anyone help me with the logic for adding -1, 0 or 1 to the chance values after submitting the form?
at the moment its changing all values to 2 ??
so if chance was 10-20-30-40-50-60, once submitted, it becomes 2-2-2-2-2-2.
help? :(
change the = to == at the boolean expressions used on IF's
instead of
if ($chance[1] = 0 ){
should be
if ($chance[1] == 0 ){
You know about "=="?
The code is wrong
Related
I am trying to show echo 2 but its not working
$zipcode1 = 07300-011;
$zipcode= str_replace("-","",$zipcode1);
$zipcode = 07300011;
if ($zipcode >= 20000000 && $zipcode <= 26600999) {
echo '1';
}
elseif ($zipcode >= 07000001 && $zipcode <= 07399999) {
echo '2';
}
else {
echo 'no value';
}
Please let me know where i am doing wrong. Thank you for the help
Result = 2
You need to compare string with string if the leading 0 of the zipcode is important:
$zipcode1 = "07300-011";
$zipcode= str_replace("-","",$zipcode1);
$zipcode = "07300011";
if ($zipcode >= "20000000" && $zipcode <= "26600999") {
echo '1';
} elseif ($zipcode >= "07000001" && $zipcode <= "07399999") {
echo '2';
} else {
echo 'no value';
}
You made two mistakes.
One is that the value assigned to $zipcode1 is not a string, but rather the result of an arithmetic operation. I'm saying $zipcode1 is not "07300-011", but rather 07300-011, which is equal to the octal number 7300 (3776 in base 10) minus octal 11 (9 in base 10), i.e 3776 - 9 which is 3767.
The second is that you're trying to do a numeric comparison using strings. "20" > "1000" is not the same as 20 > 1000. The first would resolve to true, whereas the second would give false (which is likely what you want).
To fix this, you have to first convert both of them to numbers. You can either cast them:
((int) $zipcode1) > (int) $zipcode2
or you can use the + sign instead:
(+$zipcode1) > (+$zipcode2)
In both cases, you need to first remove whitespaces and every other non-numeric character from the zipcode.
$zipcode = str_replace([' ', '-'], '', $zipcode);
Read the following topics in the php docs for more info:
Numeric Strings
Comparison Operators
I'm trying to create a bingo game that generates 120 tickets. Each Ticket is a [3x9 matrix] and contains numbers between 1-90. Rules for generating tickets are:
RULE #1 - Each row cannot have more than 5 numbers.
RULE #2 - Each column is assigned a range of numbers: (ex. 1-9 can appear only in column 1, 10-19 can appear only in column 2 and so on. And in column 9 numbers between 80-90 can appear)
RULE #3 - In a specific column, numbers must be arranged in ascending order from top to bottom.
RULE #4 - Each column must have at least one number in it.
RULE #5 - All the numbers 1 to 90 are used only once in each set of 6 tickets.
I'm able to fulfill all rules except RULE #5. Here's my code that I've written so far.
$batch_numbers = array(); //to keep track of numbers used in the set of 6 ticekts
$reset = false; // to check if the set is complete
$ticket_set = 1; // set count
for ($t=1; $t <= 120; $t++) {
$ticket_array = array(array(0,0,0,0,0,0,0,0,0), array(0,0,0,0,0,0,0,0,0), array(0,0,0,0,0,0,0,0,0));
$numbers = range(1, 90);
$indices = array();
$random_indices = array();
$used_numbers = array(); // to check unique numbers in a ticket
$full_ticket = array();
for($i=0;$i<3;$i++){
for($j=0;$j<9;$j++){
$indice = array($i, $j);
array_push($indices, $indice);
}
}
#if reset is true (means a set of 6 is complete) so set the batch_numbers array to empty and increment the ticket_set value
if($reset){
$batch_numbers = array();
$reset = false;
$ticket_set++;
}
#if ticket number is divisible by 6 set the reset variable to true to indicate the end of a set of 6 tickets
if(($t%6)==0){
$reset = true;
}
#selecting 5 random positions to fill the first row
$first_row_numbers = range(0,8);
shuffle($first_row_numbers);
$keys_one = array_rand($first_row_numbers, 5);
$first_row = array();
foreach ($keys_one as $row_one_key) {
array_push($first_row, $indices[$row_one_key]);
}
#selecting 5 random positions to fill the second row
$second_row_numbers = range(9,17);
shuffle($second_row_numbers);
$keys_two = array_rand($second_row_numbers, 5);
$second_row = array();
foreach ($keys_two as $row_two_key) {
array_push($second_row, $indices[$second_row_numbers[$row_two_key]]);
}
#selecting 5 random positions to fill the third row
$third_row_numbers = range(18,26);
shuffle($third_row_numbers);
$keys_three = array_rand($third_row_numbers, 5);
$third_row = array();
foreach ($keys_three as $row_three_key) {
array_push($third_row, $indices[$third_row_numbers[$row_three_key]]);
}
#push the selected 5 positions of first row to random_indices array that satisfies RULE #1
foreach($first_row as $row_one){
array_push($random_indices, $row_one);
}
#push the selected 5 positions of second row to random_indices array that satisfies RULE #1
foreach($second_row as $row_two){
array_push($random_indices, $row_two);
}
#push the selected 5 positions of third row to random_indices array that satisfies RULE #1
foreach($third_row as $row_three){
array_push($random_indices, $row_three);
}
#assign the numbers between 1-90 according to its column position to satisfy RULE #2
foreach($random_indices as $indice){
list($row, $column) = $indice;
#generate a unique number for the current set of 6 tickets
$rand = $this->generateRandomColumnNumber($column, $batch_numbers);
#assign the number to the array
$ticket_array[$row][$column] = $rand;
#push the unique number to batch_numbers array so that we can keep track of the numbers used in set of 6 tickets that satisfies RULE #5
array_push($batch_numbers, $rand);
#Push the unique number to used_numbers array so that we can keep track of the numbers already used in the individual ticket
array_push($used_numbers, $rand);
}
#Sort the ticket_array column wise to satisfy the RULE #3
for($k=0; $k<9; $k++){
# if all the rows are filled with random number
if($ticket_array[0][$k] != 0 && $ticket_array[1][$k] != 0 && $ticket_array[2][$k] != 0){
$temp_1 = NULL;
$temp_2 = NULL;
if($ticket_array[0][$k] > $ticket_array[1][$k]){
$temp_1 = $ticket_array[0][$k];
$ticket_array[0][$k] = $ticket_array[1][$k];
$ticket_array[1][$k] = $temp_1;
}
if($ticket_array[1][$k] > $ticket_array[2][$k]){
$temp_2 = $ticket_array[1][$k];
$ticket_array[1][$k] = $ticket_array[2][$k];
$ticket_array[2][$k] = $temp_2;
}
}
# if 1st and 2nd row are filled by random number
elseif($ticket_array[0][$k] != 0 && $ticket_array[1][$k] != 0 && $ticket_array[2][$k] == 0){
if($ticket_array[0][$k] > $ticket_array[1][$k]){
$temp = $ticket_array[0][$k];
$ticket_array[0][$k] = $ticket_array[1][$k];
$ticket_array[1][$k] = $temp;
}
}
# if 1st and 3rd row are filled by random number
elseif($ticket_array[0][$k] != 0 && $ticket_array[1][$k] == 0 && $ticket_array[2][$k] != 0){
if($ticket_array[0][$k] > $ticket_array[2][$k]){
$temp = $ticket_array[0][$k];
$ticket_array[0][$k] = $ticket_array[2][$k];
$ticket_array[2][$k] = $temp;
}
}
# if 2nd and 3rd rows are filled with random numbers
elseif($ticket_array[0][$k] == 0 && $ticket_array[1][$k] != 0 && $ticket_array[2][$k] != 0){
if($ticket_array[1][$k] > $ticket_array[2][$k]){
$temp = $ticket_array[1][$k];
$ticket_array[1][$k] = $ticket_array[2][$k];
$ticket_array[2][$k] = $temp;
}
}
# if 1st, 2nd and 3rd rows are empty we need to assign a value to the column so that it satisfies RULE #4
elseif($ticket_array[0][$k] == 0 && $ticket_array[1][$k] == 0 && $ticket_array[2][$k] == 0){
$modified_array = $this->fillEmptyColumn($k, $ticket_array, $batch_numbers, $batch, $game_id);
$ticket_array = $modified_array;
}
}
/* Code to store the ticket data in database */
}
protected function fillEmptyColumn($column, $ticket_array, $batch_numbers){
for ($i=0; $i < 9; $i++) {
if($i == $column){
continue;
}else{
//Check if all three rows have digits
if($ticket_array[0][$i] != 0 && $ticket_array[1][$i] != 0 && $ticket_array[2][$i] != 0){
$new_number = $this->generateRandomColumnNumber($column, $batch_numbers);
$ticket_array[2][$i] = 0;
$ticket_array[2][$column] = $new_number;
break;
}
//Check if 1st and 2nd rows have digits
elseif($ticket_array[0][$i] != 0 && $ticket_array[1][$i] != 0 && $ticket_array[2][$i] == 0){
$new_number = $this->generateRandomColumnNumber($column, $batch_numbers);
$ticket_array[1][$i] = 0;
$ticket_array[1][$column] = $new_number;
break;
}
//Check if 1st and 3rd rows have digits
elseif($ticket_array[0][$i] != 0 && $ticket_array[1][$i] == 0 && $ticket_array[2][$i] != 0){
$new_number = $this->generateRandomColumnNumber($column, $batch_numbers);
$ticket_array[2][$i] = 0;
$ticket_array[2][$column] = $new_number;
break;
}
//Check if 2nd and 3rd rows have digits
elseif($ticket_array[0][$i] == 0 && $ticket_array[1][$i] != 0 && $ticket_array[2][$i] != 0){
$new_number = $this->generateRandomColumnNumber($column, $batch_numbers);
$ticket_array[2][$i] = 0;
$ticket_array[2][$column] = $new_number;
break;
}
}
}
return $ticket_array;
}
protected function generateRandomColumnNumber($column, $batch_numbers)
{
#assign the numbers according to the column
if($column == 0){
$rand = rand(1, 9);
}elseif($column == 8){
$rand = rand(80,90);
}
else{
$rand = rand(($column *10), ((($column+1)*10)-1));
}
# check if numbers already exists in the current set of 6 tickets
if(in_array($rand, $batch_numbers)){
return $this->generateRandomColumnNumber($column, $batch_numbers);
}
return $rand;
}
Every time I try to call the generateRandomColumnNumber to generate a unique number and pass the batch_numbers array (to check unique number in the set of 6 tickets) instead of used_numbers array ( to check unique number in a individual ticket ) I get 500 error instantly but doesn't show why it is caused. Could anyone please help me out to point out what's wrong in my code and help me solve this. Been stuck at this for a couple of days now. It'd be of great help. Thanks
Example: When I have only two select options
input_one = 'one';
input_two = 'two';
when I select only input_one
if((isset($_POST['input_one']) && (!isset($_POST['input_two']) {
//query
}
When I select only input_two
elseif((!isset($_POST['input_one']) && (isset($_POST['input_two'])) {
//query
}
When I don't select any of those
elseif((!isset($_POST['input_one']) && (!isset($_POST['input_two'])) {
//query
}
When I select both of them
elsif((isset($_POST['input_one']) && (!isset($_POST['input_two'])) {
//query
}
but when I have 6 input options then I need to write a number of conditions. How do I reduce those, if there is any alternate method?
$query = "some query";
foreach($_POST as $key => $post){
switch($key){
case 1:
$query .= " AND some condition";
break;
case 2:
$query .= " AND some condition";
break;
}
}
mysqli_query($sql,$query);
I will give my answer based on the hypothesis, that the inputs are dependent on each other. Or let's call it interdependent.
If you are looking at your code, you'll notice that your conditions can be abstracted by basic binary calculations.
So let's assume we speak about two states:
isset = 1,
!isset = 0
And each input can have one of the two states.
If you have 1 input, then you can have 2exp(1) = 2 possibilities.
0
1
If you have 2 inputs, then you can have 2exp(2) = 4 possibilities. Nota bene: each column represents the states that an input can take in dependence with the other one.
00
01
10
11
If you have 3 inputs, then you can have 2exp(3) = 8 possibilities.
000
001
010
011
100
101
110
111
...
If you have 6 inputs, then you can have 2exp(6) = 64 states in total.
000000
000001
...
111110
111111
The general formula is:
N = 2exp(x)
Where:
N = total number of possibilities;
x: Number of observable elements, each can achieve 2 states (0 or 1).
So, as you see, it's hard to maintain such a structure.
And take into consideration that you'll probably need to make validations on empty() values too. At least.
I recommend you, that you really change something in your code, so that your inputs are not anymore so dependable on each other.
So, my answer would be "no", there is no way to do it, better than you already do it. The if-elseif-else is the proper one. But that doesn't help you a lot if you have more than, let's say 3 interdependent inputs.
EDIT 1:
One relative maintainable solution would be to divide the interdependent inputs in groups of maximum 3. And only for these 3 to send a request to the server.
EDIT 2:
Or to ensure that in one request moment, only one input has been set or have a value.
Or to ensure that each of the inputs have at least a default value (like '0') on the request moment.
an example for four conditions:
<?php
$c = 0;
//basic conditions...............
if( isset($_POST['input_1'] ) $c += 1; //set 1st bit
if( isset($_POST['input_2'] ) $c += 2; //set 2nd bit
if( isset($_POST['input_3'] ) $c += 4; //set 3rd bit
if( isset($_POST['input_4'] ) $c += 8; //set 4th bit
//additional conditions...............
if($c < 8){ //0..7
if($c < 4){ //0..3
if($c < 2){ //0..1
if($c == 0){ //nothing set
}else{ // 1 //input_1
}
}else{ //2..3
if($c == 2){ //input_2
}else{ //3 //input_1 input_2
}
}
}else{ //4..7
if($c < 6){//4..5
if($c == 4){ //input_3
}else{ // 5 //input_1 input_3
}
}else{//6..7
if($c == 6) { //input_2 input_3
}else{ // 7 //input_1 input_2 input_3
}
}
}
}else{ //8..15
if($c < 12){ //8..11
if($c < 10){ //8..9
if($c == 8){ //input_4
}else{ // 9 //input_1 input_4
}
}else{ //10..11
if($c == 10){ //input_2 input_4
}else{ //11 //input_1 input_2 input_4
}
}
}else{ //12..15
if($c < 14){//12..13
if($c == 12){ //input_3 input_4
}else{ // 13 //input_1 input_3 input_4
}
}else{//14..15
if($c == 14) { //input_2 input_3 input_4
}else{ // 15 //input_1 input_2 input_3 input_4
}
}
}
}
?>
In this case we have to check 8 condition to get all the issets states.
So it could not be the optimal solution when we have only 4 parameters what produces only 2^4=16 possibilities.
But if we take 6 arguments:
Then we have to check 6 basic onditions and 6 additionals.
So it gives 12 conditions to check when there is 2^6=64 possibilites.
Lets take 7 args:
Then we have 7 + 7 = 14 condition to check to get one of 2^7=128 possibilities.
And now we start to see advantages for bigger amount of arguments.
I have managed to create an algorithm to check the rank of a poker hand. It works 100% correctly, but it's very slow. I've been analysing the code, and the check straight function is one of the slowest parts of it.
So my question is, is there a better way of calculating whether a hand make a straight?
Here is some details:
7 cards, 2 from holder, 5 from board. A can be high or low.
Each card is assigned a value:
2 = 2
3 = 3
..
9 = 9
T = 10
J = 11
Q = 12
K = 13
A = 14
The script has an array of all 7 cards:
$cards = array(12,5,6,7,4,11,3);
So now I need to be able to sort this into an array where it:
discards duplicates
orders the card from lowest to highest
only returns 5 consecutive cards I.e. (3,4,5,6,7)
It needs to be fast; loops and iterations are very costly. This is what I currently use and when it tries to analyse say 15000 hands, it takes its toll on the script.
For the above, I used:
discard duplicates (use array_unique)
order cards from lowest to highest (use sort())
only return 5 consecutive cards (use a for loop to check the values of cards)
Does anyone have any examples of how I could improve on this? Maybe even in another language that I could perhaps look at and see how it's done?
Instead of working with array deduping and sorting, consider using a bitmask instead, and setting bits to 1 where the card value is set. A bitmask works like a Set datastructure and comes with additional advantages when it comes to detecting contiguous elements.
for ($i = 0; $i < count($cards); $i++) {
$card = $cards[$i];
// For each card value, set the bit
if ($card == 14) {
// If card is an ace, also set bit 1 for wheel
$cardBitmask |= 0x2;
}
$cardBitmask |= (1 << $card);
}
// To compare, you simply write a for loop checking for 5 consecutive bits
for($i = 10; $i > 0; $i--)
{
if ($cardBitmask & (0x1F << $i) == (0x1F << $i)) {
// Straight $i high was found!
}
}
Consider the Java implementation at this link. I've included it here:
public static boolean isStraight( Card[] h )
{
int i, testRank;
if ( h.length != 5 )
return(false);
sortByRank(h); // Sort the poker hand by the rank of each card
/* ===========================
Check if hand has an Ace
=========================== */
if ( h[4].rank() == 14 )
{
/* =================================
Check straight using an Ace
================================= */
boolean a = h[0].rank() == 2 && h[1].rank() == 3 &&
h[2].rank() == 4 && h[3].rank() == 5 ;
boolean b = h[0].rank() == 10 && h[1].rank() == 11 &&
h[2].rank() == 12 && h[3].rank() == 13 ;
return ( a || b );
}
else
{
/* ===========================================
General case: check for increasing values
=========================================== */
testRank = h[0].rank() + 1;
for ( i = 1; i < 5; i++ )
{
if ( h[i].rank() != testRank )
return(false); // Straight failed...
testRank++; // Next card in hand
}
return(true); // Straight found !
}
}
A quick Google search for "check for poker straight (desired_lang)" will give you other implementations.
You could just sort the cards and loop over them in an array - saving always the last card and compare them with the current one.
$cards = array(12,5,6,7,4,11,3);
sort($cards);
$last = 0;
$count = 0;
$wheel = false;
foreach ($cards as $card) {
if ($card == $last) {
continue;
} else if ($card == ++$last) {
$count++;
} else {
if ($last == 6) $wheel = true;
$count = 1;
$last = $card;
}
if ($count == 5 || ($card == 14 && $wheel)) {
echo "straight $last";
$straight = range($last - 4, $last);
break;
}
}
You may go like this, you don't need to sort or anything (assuming that 2 is 2 and 14 is ace):
$cards = [12,5,6,7,4,11,3];
function _inc(&$i) {
if ($i == 14)
$i = 2;
else
$i++;
return $i;
}
$straight = false;
for($i = 2; $i <= 14; $i++) {
$ind = $i;
if (!in_array($ind, $cards)) continue;
$s = [$ind, _inc($ind), _inc($ind), _inc($ind), _inc($ind)];
$straight = count(array_intersect($s, $cards)) == count($s);
if ($straight) break;
}
print $straight;
I have 3 options, and they have to happen in a particular ratio.
Out of 10 times, this is the ratio:
8x Option 1
1x Option 2
1x Option 3
Right now I have the following:
if (rand(8,10)) {
option1();
} elseif (rand(1,10)) {
option2();
} elseif (rand(1,10)) {
option3();
}
But this gets option 1 way more than 8 times. Option 2 never occurs and option 3 rarely.
So, what is the correct way to achieve this?
Try with something like this.
$roll = rand(1,10);
if ($roll == 1) {
option2();
} elseif ($roll == 2) {
option3();
} else {
option1();
}
If random number is 1 (10% of the time), option 2.
If random number is 2 (10% of the time), option 3.
If random number is anything else (80% of the time), option 1.
$r = rand() / getrandmax();
if ($r <= 0.8) {
option1();
} elseif ($r <= 0.9) {
option2();
} else {
option3();
}
No, this is not the right way. You can use something like:
<?php
// Store in DB use of options 1, 2 and 3
// field value
// -----------------
// options1 0
// options2 0
// options3 0
// If $options1 = 8, $options2= 1 and $options3 = 1, then clear all values from DB
$random = rand(1,3);
if ($random == 1) {
if ($options1 < 9) { option1(); } else { // tryagain; }
} elseif (
...
// update DB with new value for used option
Sorry the code is slightly messed up (the if part) but I guess you can understand. Let me know if you need the whole code.