I'm new to php and have been struggling to get my rock, paper, scissors game to work! I know what I'm trying to do but just can't get my head aound where I've gone wrong......it works for rock but for paper and scissors I'm getting two outputs!!Please help a novice out...thanks!!
P.S I know there are much slicker ways of doing this!!
<?php
// user enters a value R P or S - NEED TO RETURN A COUPLE OF
TIMES AFTER, not sure why?
echo "What do you select - R for rock, P for paper or S for
scissors?\n";
$input=
$R = stream_get_line(STDIN, 1, "\n");
$P = stream_get_line(STDIN, 1, "\n");
$S = stream_get_line(STDIN, 1, "\n");
//program converts the value into Rock, Paper or Scissors
switch ($input) {
case 'R' :
case 'r':
echo $R = "You selected Rock\n" ;
break;
case 'P' :
case 'p':
echo $P = "You selected Paper\n" ;
break;
case 'S' :
case 's':
echo $S = "You selected Scissors\n" ;
break;
}
//computer generates a random value 0,1,2 & converts to R P or S
echo "\nComputer is now making its selection....\n";
//$options = ('Rock=0, Paper=1, Scissors=2');
$output = (rand(0,2) );
echo $output;
if ($output== 0)
{
echo "\nComputer Selected Rock\n"; //goto Rock;
}
elseif ($output==1)
{
echo "\nComputer Selected Paper\n"; //goto Paper;
}
elseif ($output==2)
{
echo "\nComputer Selected Scissors\n"; //goto Scissors;
}
//compare user and computers choise
Rock:
if ($R && $output===0)//.($P && $output==1),($S && $output==2))
{
echo "\nITS A DRAW";
}
elseif ($R && $output===1)//.($P && $output==2).($S &&
$output==0))
{
echo "\nCOMPUTER WINS";
}
elseif ($R && $output===2)//.($P && $output==0).($S &&
$output==1))
{
echo "\nYOU WIN";
}
Paper:
if ($P && $output===1)
{
echo "\nITS A DRAW";
}
elseif ($P && $output===2)
{
echo "\nCOMPUTER WINS";
}
elseif ($P && $output===0)
{
echo "\nYOU WIN";
}
Scissors:
if ($S && $output===2)
{
echo "\nITS A DRAW";
}
elseif ($S && $output===0)
{
echo "\nCOMPUTER WINS";
}
elseif ($S && $output===1)
{
echo "\nYOU WIN";
}
You should inicialize $R, $P and $S to false first. Then read user input 1x into $input.
The rest of the script seams to be ok.
<?php
$R = $P = $S = false;
$input= stream_get_line(STDIN, 1, "\n");
// user enters a value R P or S - NEED TO RETURN A COUPLE OF TIMES AFTER, not sure why?
because
$input=
$R = stream_get_line(STDIN, 1, "\n");
$P = stream_get_line(STDIN, 1, "\n");
$S = stream_get_line(STDIN, 1, "\n");
You're calling stream_get_line() three times so your script wants three lines of input.
Also, I'm not sure if this was intended, but you're getting your user input seemingly purely by chance as $input = $R = stream_get_line() stores the first user input in $R and $input.
I'd suggest only doing $input = stream_get_line() and nothign else.
Then in your switch/case block you do e.g. echo $R = "..."; and further down you do if ($R && ...).
Evaluating strings as booleans is not recommended.
I would recommend something like
$R = $P = $S = false; // initialize all variables to false
switch ($input)
{
case "R":
$R = true; // set selected variable to true
echo "You have selected Rock\n";
break;
// ...
}
Finally, you seem to be using jump marks to comment your code.
Rock:
if ( ...
While this doesn't cause any problems (yet), it's generally considered bad style to abuse language features for documentation purposes.
These should become comments:
// Rock
if ( ...
Related
I've been working on a console-based Hangman Game with PHP and have come across a somewhat big issue.
When the user guesses the correct word, it functions as needed. It reveals the letter and continues to ask the user to guess the next.
Now, the issue comes when the player gets it wrong. My intentions were when the user gets a letter wrong, the $playerErrors variable gets +1 value, and once $playerErrors has a value of 6, aka the player has made 6 wrong guesses, the program terminates. This is not what happens however, instead, if the word they're guessing has 5 letters for example, and they guessed 1 letter wrong, they will get +5 $playerErrors instead of just +1 $playerErrors.
So as a result of the player getting say 5 $playerErrors in one guess, the player will really only have 1 or 2 lives instead of 6.
Here is the code from the main section:
while ($playerErrors < 6) {
if (strpos($shwWord, '_') === false){
echo "You won! Congratulations!\n";
break;
}
$guess = readline('Guess a letter: ');
for ($g = 0; $g < count($secretArray); $g+=1) {
if ($guess === $secretArray[$g]){
$displayedLetters[$g] = $guess;
}
else{
$playerErrors += 1;
echo "Errors: " . $playerErrors;
echo "\n";
}
}
$shwWord = implode(' ', $displayedLetters);
echo "\n $shwWord \n\n";
}
if ($playerErrors >= 6) {
echo "you lost" . PHP_EOL;
}
You are incrementing the errors within your 'check letters' loop, meaning that you increment once for each 'wrong letter'.
Try this code:
while ($playerErrors < 6) {
if (strpos($shwWord, '_') === false){
echo "You won! Congratulations!\n";
break;
}
$guess = readline('Guess a letter: ');
$foundLetter = false;
for ($g = 0; $g < count($secretArray); $g+=1) {
if ($guess === $secretArray[$g])
{
$displayedLetters[$g] = $guess;
$foundLetter = true;
}
}
if (!$foundLetter)
{
$playerErrors += 1;
echo "Errors: " . $playerErrors;
echo "\n";
}
$shwWord = implode(' ', $displayedLetters);
echo "\n $shwWord \n\n";
}
if ($playerErrors >= 6) {
echo "you lost" . PHP_EOL;
}
I am working on a bit of PHP and I've come upon a bit of issues.
I am using PHP to randomly choose a number from 1-360. I am trying to compare the answer to a list of value determined by range.
$NumberA = rand(0,180);
$NumberB = rand(0,180);
$NumberC = $NumberA + $NumberB;
if ($NumberC = range(0,21) {
$result = "Orange";
}
elseif ($NumberC = range(22,42) {
$result = "Red";
}
elseif ($NumberC = range(43,63) {
$result = "Blue";
}
//This goes on for a while ...
else {
$result = "Green";
}
echo = $result;
Anytime i do this, the result always assigns the value of "Orange" to $result .
Im sure im doing something wrong here, please help!
First of all, you used just one '=' to compare while it should have been '=='. Second range() generates an array and you cannot compare an integer to an array. Third why generating the range every single time when you can check that $NumberC lies between the minimum and the maximum numbers of the range?
Change your code to:
$NumberA = rand(0,180);
$NumberB = rand(0,180);
$NumberC = $NumberA + $NumberB;
if ($NumberC >= 0 && $NumberC <= 21) {
$result = "Orange";
} elseif ($NumberC >= 22 && $NumberC <= 42) {
$result = "Red";
} elseif ($NumberC >= 43 && $NumberC <= 63) {
$result = "Blue";
} else {
$result = "Green";
}
echo $result;
Shall work. Hope this helps.
This is the problem I'm having with code:
I have a function that creates an updating bar;
I have a function that creates a loop, each number of loop makes some other stuffs and the same number represent the progress of the bar (from 1 to 155);
this loop works when user make a "search" on the site for "all" countries;
BUT user can also make a "search" only choosing 1-5 different countries;
this way we have a function that makes the PROGRESS BAR, another one that makes the PROGRESS PART of the BAR that should understand how to progress.
So the point is that I don't know how make the function for progress bar to interpret the situation in order to know that user choosed only some countries and not "all" countries (the option will post to the function some "numbers of the loop" like "3", "4", "56"... corresponding to choosed country) - and this is the easy part (with maybe isset($var)).
The next hard part is that after that it will be called the PROGRESS BAR function with those "country-numbers" so that if you choose "Canada-USA-France" the numbers will be "34-12-45" and the progress bar will write "34%-12%-45%".
But it's incorrect because if you have 3 options choosed, it should be 33%-66%-99% (and not 34%-12%-45%)...
What I don't know is how to make that function understand that everytime the function receive the "country-number", and it comes from user choice different from "all", the function should get that number and modify it (and this can be made with an array) in order to adapt it to the correct bar progression so that if you have: 34, than 12 than 45, the function should understand that the 1st time 34 should become 33, the 2nd time 12 should become 66 and the 3rd time 45 should become 99 (or 100)...
Here is the code part of interest:
1. receiving _POST and verifying it:
function getData() {
$a = strtolower($_POST["CountryOne"]);
$b = strtolower($_POST["CountryTwo"]);
$c = strtolower($_POST["CountryThree"]);
$d = strtolower($_POST["CountryFour"]);
$d = strtolower($_POST["CountryFive"]);
$numPost = count($_POST);
if ($numPost == 0) {
echo("<p class='Verify'>Select an option to start search...<br></p>");
} else {
echo "<div class='Verify' id='progressbar' style='width:620px;height:16px'></div>
<div class='VerifyBar' id='information' style='width'></div>";
};
2. Jump to next part after checking it user choosed "all" or "some countries" - here is the loop:
function loopNum($x) {
$i = 0+$x;
$y = $x+3;
for ($x = $i; $x <= $y; $x++) {
$iscountryID = ("$country".$x."");
createUrl($iscountryID);
} if($y != 155) {
return loopNum($x);
} else if($y < 155) {
echo("<font size='2' face='Tahoma, Geneva, sans-serif' style='font-variant: small-caps' color='#FF0000'><i>ERROR: unxepected data extraction interruption</font></i><br>");
} else {
echo("<font size='2' face='Tahoma, Geneva, sans-serif' style='font-variant: small-caps' color='#00CC00'><i>FINISHED: data extraction ended</font></i><br>");
}};
3. than it makes a lot of other stuff and call progress bar function
function completeBar($iscountryID) {
//***** PART UNDER CONSTRUCTION WHERE I NEED HELP *****
$countryOne = strtolower($_POST["CountryOne"]);
$countryTwo = strtolower($_POST["CountryTwo"]);
$countryThree = strtolower($_POST["CountryThree"]);
$countryFour = strtolower($_POST["CountryFour"]);
$countryFive = strtolower($_POST["CountryFive"]);
if (($countryOne !== 'all') and ($countryTwo !== 'all') and ($countryThree !== 'all') and ($countryFour !== 'all') and ($countryFive !== 'all')) {
$numQuery = array("$countryOne","$countryTwo","$countryThree","$countryFour","$countryFive");
foreach ($numQuery as $value) {
if(is_numeric($value)) {
$j++;
}}; // AT THIS POINT I WOULD KNOW HOW MANY VALUES IN THE ARREY ARE DIFFERENT FROM "ALL" AND "NO_COUNTRY" OPTIONS AND SO ARE NUMERIC VALUES
//***** FROM HERE I DUNNO HOW TO PRECEED *****
} else { //the next part works with "all" option choosed
if ($iscountryID < 155) {
$i = $iscountryID;
$percent = $i."%";
$pxbar = 4*$i."px";
$percentage = round((($pxbar*100)/624),0); //bar is 624px long
// Javascript for updating the progress bar and information
echo '<script language="javascript">
document.getElementById("progressbar").innerHTML="<div style=\"width:'.$pxbar.';background-color:#ddd;\">'.$percentage.'% </div>";
document.getElementById("information").innerHTML="'.$i.'/155 country(s) processed... loading your data, hold on..."</script>';
// This is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
// Send output to browser immediately
flush();
sleep(1);
} else if ($iscountryID == 155) { //so on loop complete
$i = $iscountryID;
$percent = $i."%";
$pxbar = 4*$i."px";
$percentage = round((($pxbar*100)/624),0);
echo '<script language="javascript">
document.getElementById("progressbar").innerHTML="<div style=\"width:'.$pxbar.';background-color:#ddd;\">'.$percentage.'% </div>";
document.getElementById("information").innerHTML="'.$i.'/155 country(s) processed... loading your data, hold on..."</script>';
echo str_repeat(' ',1024*64);
flush();
sleep(1);
// Tell user that the process is completed
echo '<script language="javascript">
document.getElementById("progressbar").innerHTML="<div style=\"width:'.$pxbar.';background-color:#ddd;\">100% </div>";
document.getElementById("information").innerHTML="<div>Process completed, all countries verified...</div>";
document.getElementById("information").style.color="green";
</script>';
echo str_repeat(' ',1024*64);
flush();
sleep(1);
}
}};
Ah... I've tried to make the following working but the problem is that with the following, I'll have the function updating the bar getting values from the array too fast. Using the VAR sent from the rest of the file, I'll have an updating bar that follows the updating output of the server.
function partialBar() {
$countryOne = strtolower($_POST["CountryOne"]);
$countryTwo = strtolower($_POST["CountryTwo"]);
$countryThree = strtolower($_POST["CountryThree"]);
$countryFour = strtolower($_POST["CountryFour"]);
$countryFive = strtolower($_POST["CountryFive"]);
$numQuery = array("$countryOne","$countryTwo","$countryThree","$countryFour","$countryFive");
foreach ($numQuery as $value) {
if(is_numeric($value)) {
$j++;
};
};
if ($j == 1) {
$iscountryID = 155;
completeBar($iscountryID);
} else if ($j == 2) {
$iscountryID = array("78","155");
completeBar($iscountryID[0]);
completeBar($iscountryID[1]);
} else if ($j == 3) {
$iscountryID = array("52","104","155");
completeBar($iscountryID[0]);
completeBar($iscountryID[1]);
completeBar($iscountryID[2]);
} else if ($j == 4) {
$iscountryID = array("39","78","117","155");
completeBar($iscountryID[0]);
completeBar($iscountryID[1]);
completeBar($iscountryID[2]);
completeBar($iscountryID[3]);
} else if ($j == 5) {
$iscountryID = array("31","62","93","124","155"); //these numbers are the corresponding loop number in other to get 20%-40%-60%-80%-100% from the completeBar() function
completeBar($iscountryID[0]);
completeBar($iscountryID[1]);
completeBar($iscountryID[2]);
completeBar($iscountryID[3]);
completeBar($iscountryID[4]);
} else echo ("<div class='Verify'>Something went wrong!</div>");
};
Here is solution:
make a counter in the central function in order to know how many times have been called, so you know which number of the array you have to call for the correct calculation of the % of progress bar.
Here is where the following functions are called:
if (($countryNameTitOne == 'all') or ($countryNameTitTwo == 'all')
or ($countryNameTitThree == 'all') or ($countryNameTitFour == 'all')
or ($countryNameTitFive == 'all')) {
completeBar($iscountryID);
} else {
$callCounter = callCounterFunc();
partialbar($iscountryID,$callCounter);
}};
Than here are the functions called:
function completeBar($iscountryID) {
if ($iscountryID < 155) {
$i = $iscountryID;
$percent = $i."%";
$pxbar = 4*$i."px";
$percentage = round((($pxbar*100)/624),0);
echo '<script language="javascript">
document.getElementById("progressbar").innerHTML="<div style=\"width:'.$pxbar.';background-color:#ddd;\">'.$percentage.'% </div>";
document.getElementById("information").innerHTML="'.$i.'/155 country(s) processed... loading your data, hold on..."</script>';
echo str_repeat(' ',1024*64);
flush();
sleep(1);
} else if ($iscountryID == 155) {
$i = $iscountryID;
$percent = $i."%";
$pxbar = 4*$i."px";
$percentage = round((($pxbar*100)/624),0);
echo '<script language="javascript">
document.getElementById("progressbar").innerHTML="<div style=\"width:'.$pxbar.';background-color:#ddd;\">'.$percentage.'% </div>";
document.getElementById("information").innerHTML="'.$i.'/155 country(s) processed... loading your data, hold on..."</script>';
echo str_repeat(' ',1024*64);
flush();
sleep(1);
echo '<script language="javascript">
document.getElementById("progressbar").innerHTML="<div style=\"width:'.$pxbar.';background-color:#ddd;\">100% </div>";
document.getElementById("information").innerHTML="<div>Process completed, all countries verified...</div>";
document.getElementById("information").style.color="green";
</script>';
echo str_repeat(' ',1024*64);
flush();
sleep(1);
}
};
function partialBar($iscountryID,$callCounter) {
$countryOne = strtolower($_POST["CountryOne"]);
$countryTwo = strtolower($_POST["CountryTwo"]);
$countryThree = strtolower($_POST["CountryThree"]);
$countryFour = strtolower($_POST["CountryFour"]);
$countryFive = strtolower($_POST["CountryFive"]);
$numQuery = array("$countryOne","$countryTwo","$countryThree","$countryFour","$countryFive");
foreach ($numQuery as $value) {
if(is_numeric($value)) {
$j++;
}};
if ($j == 1) {
if ($callCounter == 1) {
$iscountryID = 155;
completeBar($iscountryID);
};
} else if ($j == 2) {
$iscountryID = array("78","155");
if ($callCounter == 1) {
completeBar($iscountryID[0]);
} else if ($callCounter == 2) {
completeBar($iscountryID[1]);
};
} else if ($j == 3) {
$iscountryID = array("52","104","155");
if ($callCounter == 1) {
completeBar($iscountryID[0]);
} else if ($callCounter == 2) {
completeBar($iscountryID[1]);
} else if ($callCounter == 3) {
completeBar($iscountryID[2]);
};
} else if ($j == 4) {
$iscountryID = array("39","78","117","155");
if ($callCounter == 1) {
completeBar($iscountryID[0]);
} else if ($callCounter == 2) {
completeBar($iscountryID[1]);
} else if ($callCounter == 3) {
completeBar($iscountryID[2]);
} else if ($callCounter == 4) {
completeBar($iscountryID[3]);
};
} else if ($j == 5) {
$iscountryID = array("31","62","93","124","155");
if ($callCounter == 1) {
completeBar($iscountryID[0]);
} else if ($callCounter == 2) {
completeBar($iscountryID[1]);
} else if ($callCounter == 3) {
completeBar($iscountryID[2]);
} else if ($callCounter == 4) {
completeBar($iscountryID[3]);
} else if ($callCounter == 5) {
completeBar($iscountryID[4]);
};
} else echo ("<div class='Verify'>Something went wrong!</div>");
};
function callCounterFunc() {
static $calls = 0;
++$calls;
return $calls;
};
I have an array of numbers, these numbers are sometimes hyphenated, à la software version numbers. What I'm trying to do is echo "Missing!" or run a specific function when a number is missing.
For example:
$numbers = array('1', '2', '3', '5', '6', '8');
Prints:
1
2
3
Missing!
5
6
Missing!
8
I'm running into problems with the hyphens.
For example:
$numbers = array('1', '1-1', '1-3', '3-1-1', '3-1-3');
Prints:
1
1-1
Missing!
1-3
Missing!
3-1-1
Missing!
3-1-3
Plus my code seems awfully long/doing too many things for what -- seems to me -- should be a simple task. Is there a method or algorithm for this sort of thing?
Here's my code:
<?php
$numbers = array(
'1',
'1-1',
'1-3',
'3-1-1',
'3-1-3'
);
foreach ($numbers as $number) {
if (isset($prev_number)) {
$curr_number = explode('-', $number);
$prev_levels = explode('-', $prev_number);
if (preg_match('/-/', $number) and !preg_match('/-/', $prev_number)) {
if (current() - $prev_levels[0] >= 1) {
echo 'Missing!<br>' . PHP_EOL;
}
}
for ($missing = 1; ((count($curr_number) - count($prev_levels)) - $missing) >= 1; $missing++) {
echo 'Missing!<br>' . PHP_EOL;
}
foreach ($curr_number as $hyphen => $part) {
for ($missing = 1; ($part - $missing) - $prev_levels[$hyphen] >= 1; $missing++) {
echo 'Missing!<br>' . PHP_EOL;
}
}
} else {
if ($number != '1') {
echo 'Missing!<br>' . PHP_EOL;
foreach ($curr_number as $part) {
for ($missing = 1; $part > $missing; $missing++) {
echo 'Missing!<br>' . PHP_EOL;
}
}
}
}
echo $number . '<br>' . PHP_EOL;
$prev_number = $number;
}
?>
Only a partial answer.
Plus my code seems awfully long/doing too many things for what -- seems to me -- should be a simple task.
Right observation. If it's doing too many things, try to split up the task into pieces. Modularize.
For example: I see 6 explode calls in your code. You constantly struggling with transforming the input into a usable data format. Do a pre-process stage, convert the strings into arrays with explode once, and then work on that data format.
You can iterate through the list and for each pair you attempt to reach the second by applying a transformation on the first:
Increase the last value, e.g. "1" becomes "2" and "1-1" becomes "1-2".
Add a new sub value, e.g. "1" becomes "1-1" and "1-1" becomes "1-1-1".
#1 can be expanded by increasing from right to left.
If none of the transformations match the number is considered missing. In code:
$numbers = array('1', '1-1', '1-2', '1-3', '3-1-1', '3-1-3');
$first = array_shift($numbers);
echo "$first\n";
while (($second = array_shift($numbers)) !== null) {
if (find_next($first, $second) === false) {
echo "Missing\n";
}
echo "$second\n";
$first = $second;
}
// attempt to transform between current and next
function find_next($current, $next)
{
if (increment_last($current) == $next) {
return $next; // first transformation worked
} elseif (add_suffix($current) == $next) {
return $next; // second transformation worked
}
return false; // nothing worked
}
// transformation 1
function increment_last($value)
{
if (($pos = strpos($value, '-')) !== false) {
$last = substr($value, $pos + 1) + 1;
return substr_replace($value, $last, $pos + 1, strlen($last));
} else {
return $value + 1;
}
}
// transformation 2
function add_suffix($value)
{
return "$value-1";
}
This is not an algorithm, but a heuristic; it does a best effort at doing what you want but there's no formal proof that it works.
The way I have made the following code is so that it gets the four newest images and HTML documents in a specific folder, and then displays them in order of date posted. Even though it gets the image sorting correct, the overlay system I'm using isn't working correctly.
NEW EDIT for this paragraph: I have fixed most problems except for one. For some reason now, the overlays have decided two trade images, so image 1 displays image 2's overlay, whilst image 2 displays image one's overlay.
If somebody can help, it would be greatly appreciated. I can give an example of the problem at the website I use the code on. The website, click on the thumbnails in the blue box-ish area.
<?php
$i = 1;
$maxiterations = 4;
foreach (glob("news_archive/*.png") as $path)
{
if($i < $maxiterations)
{
$docs[filemtime($path)] = $path;
}
else
{
break;
}
}
asort($docs);
$i2 = 1;
$maxiterations2 = 4;
foreach (glob("news_archive/*.html") as $path2)
{
if($i2 < $maxiterations2)
{
$docs2[filemtime($path2)] = $path2;
}
else
{
break;
}
}
asort($docs2);
$var1;
$var2;
$var3;
$var4;
foreach($docs2 as $timestamp2 => $path2)
{
if($i2 <= $maxiterations2)
{
if($i2 == 1)
{
$var1 = $path2;
}
elseif($i2 == 2)
{
$var2 = $path2;
}
elseif($i2 == 3)
{
$var3 = $path2;
}
elseif($i2 == 4)
{
$var4 = $path2;
}
$i2 = $i2 + 1;
}
else
{
break;
}
}
$varcount = 1;
$varcountmax = 4;
foreach($docs as $timestamp => $path)
{
if($varcount <= $varcountmax)
{
if($varcount == 1)
{
$prersub=substr($var1, 13, 16);
$output="<img class='scroll' src='$path' rel='#$prersub' />";
echo($output);
}
if($varcount == 2)
{
$prersub=substr($var2, 13, 16);
$output="<img class='scroll' src='$path' rel='#$prersub' />";
echo($output);
}
if($varcount == 3)
{
$prersub=substr($var3, 13, 16);
$output="<img class='scroll' src='$path' rel='#$prersub' />";
echo($output);
}
if($varcount == 4)
{
$prersub=substr($var4, 13, 16);
$output="<img class='scroll' src='$path' rel='#$prersub' />";
echo($output);
}
$varcount = $varcount + 1;
}
}
?>
Edit: I still have not solved the issue and differences in parts, when corrected, break other parts of the site completely.