Having trouble calling functions for a craps game I'm writing in Perl - perl

I'm writing a craps game in perl(rules provided via source code comments). One of the features in this craps game written in perl is the ability to ask the user whether they want to continue betting or whether they want to leave the game. The problem I am running into is that any time the user types in 'bet' none of the other functions seem to be getting called and the program simply terminates the same way it should terminate when the user types in 'leave'.
I have tried splitting up the program into even more functions and tracing the direction of the function calls by hand. While I would consider myself to have programing experience in other languages I'm relatively new to perl and the syntax is very different from other languages.
Expected results:
typing bet calls the other functions and depending on the dice roll those functions call other functions and when the user types in leave the program simply terminates.
Actual results:
the program terminates as soon as the user enters anything on the keyboard
use strict;
use warnings;
my $user_money= 500;#AMOUNT OF MONEY THE USER STARTS OUT WITH
my $die=0;#WHAT NUMBER THE DIE ROLLS, IS BETWEEN 1 AND 6
my $total_dicenum=0; #TOTAL VALUE OF THE ROLL
my $betorleave="";#TAKES IN USER INPUT REGARDING WHETHER THEY WANT TO CONTINUE BETTING OR LEAVE THE GAME
my $wager=0;#HOW MUCH MONEY THE USER BETS
my $numrolls=0;#KEEPS TRACK OF THE NUMBER OF TIMES THE USER HAS ROLLED THE DICE
my $player_point=0;#THE PLAYER'S 'POINT' THAT GET'S DETERMINED AFTER THE FIRST ROLL OF DICE
#DETERMINES WHETHER THE PLAYER HAS WON OR LOST A GAME
sub result(){
if($numrolls==1){
if($total_dicenum==7 or $total_dicenum==11){
print"you won!\n";
$player_point=$total_dicenum;
$user_money = $user_money +($wager*2);
$total_dicenum==0;
}
elsif($total_dicenum==2 or $total_dicenum==3 or $total_dicenum==12){
print"you lost\n";
$player_point=$total_dicenum;
$user_money = $user_money-$wager;
$total_dicenum==0;
}
else{
bet();
}
}
else{#ROLLS FOLLWING THE INITAL ROLL
if($total_dicenum==$player_point){
print"you won!\n";
$user_money = $user_money+($wager*2);
$total_dicenum=0;
main();
}
elsif($total_dicenum==7){
print"you lost\n";
$user_money = $user_money-$wager;
$total_dicenum=0;
main();
}
else{
bet();
}
}
}
#DICE ROLLER FUNCTION
sub rollDice(){
print"rolling dice...\n";
$die = 1 + int rand(6);
print"you rolled $die\n";
}
#BETTING FUNCTION
sub bet(){
print"how much money do you want to wager?\n";
print"you currently have $user_money dollars\n";
$wager=<STDIN>;
rollDice();
$total_dicenum+=$die;
print"your total score is $total_dicenum\n";
$numrolls++;
result();
}
#BELOW IS MAIN SUBROUTINE WHERE ALL THE ABOVE SUBROUTINES ARE CALLED
sub main(){
print"Welcome to craps! Here's $user_money dollars!\n";
print"would you like to place a bet or would you like to leave?(bet/leave)\n";
$betorleave=<STDIN>;
if($betorleave eq 'bet'){
bet();
}
if($betorleave eq 'leave'){
print"FINAL BALANCE:\n";
print"$user_money\n";
}
}
#CALLS THE MAIN FUNCTION
main();
#WHAT THIS PROGRAM IS SUPPOSED TO DO:
#Each player will start with $500.00. Initially, and after each turn give the user the option of betting or leaving the program.
#Implement this any way you wish, but make it clear to the user what their options are.
#If the user chooses to place a bet, ask for the amount that will be wagered and start that “turn,” or bet.
#Each turn will consist of one or more rolls of the dice.
#For each roll, the program should display the result of both die and the total value of the roll.
#Then indicate the outcome from that roll (win/lose/continue rolling).
#Once a turn, or bet is finished, indicate the outcome of the bet and the updated balance.
#When the user chooses to exit the program display their final balance.
#Total value of dice after first roll: 7 or 11 – player wins 2, 3, or 12 – player loses
#Any other value and the player rolls again – the total of the dice is now their “point”
#Total value of dice following the initial roll: The players “point” – player wins 7 – player loses
#Any other value and the player rolls again until rolling a 7 or their point

Whenever you read data from STDIN using <STDIN>, you get the newline attached to the end of the string. You usually don't want it, so you remove it using chomp().
So, where you have:
$betorleave=<STDIN>;
You need to have:
chomp($betorleave=<STDIN>);
Some more (free!) tips:
Please learn to indent your code.
Please don't use prototypes on subroutines (unless you can explain why they shouldn't be used in most cases).
Think about the scope of your variables. In general, global variables are bad and inside a subroutine you should only use variables that are either passed into the subroutine as parameters or declared inside the subroutine. Your $betorleave variable, for example, is only ever used in the main() subroutine, so it should be declared inside that subroutine.

Related

"While loop" not working in my Anylogic model

I have the model which I posted before on Stack. I am currently running the iterations through 5 Flow Chart blocks contain enter block and service block. when agent fill service block 5 in flow chart 5, the exit block should start to fill block one and so on. I have used While infinite loop to loop between the five flow chart blocks but it isn't working.
while(true)
{
for (Curing_Drying currProcess : collection) {
if (currProcess.allowedDay == (int)time(DAY)) {
currProcess.enter.take(agent);
}
}
if (queue10.size() <= Throughtput1){
break;
}
}
Image for further illustration 1
Image for further illustration 2
Wondering if someone can tell me what is wrong in the code.
Based on the description and the pictures provided, it isn't clear why the while loop is necessary. The On exit action is executed for each Agent arrival to the Exit block. It seems that the intention is to find the appropriate Curing_Drying block based on number of days since the model start time? If so, then just iterating through the collection is enough.
Also, it is generally a good practice to provide more meaningful names to collections. Using simply collection doesn't say anything about the contents and can get pretty confusing later on.

System call to count the number of system calls in xv6

I want to create a system call which gives the number of times every system call was done, since a certain switch was tripped. I.e, I want to define a certain variable (let's name it 'counting'). When the variable 'counting' is on ('counting' is being switched between 0 for OFF and 1 for ON by a different system call, but leave THAT thing for now), I want my system call to print a list of all the system calls and the number of times they have been done, since "counting" was last set to ON (a value of 1). If the variable 'counting' is set to OFF, then I want this system call to display no list, or just display some message that "Counting hasn't started yet" or "Counting has not been turned on" or whatever. How can I proceed with this?

B&R get drive serial number via MC_BR_GetHardwareInfo function block

I'm trying to retrieve the serial number from a drive using the MC_BR_GetHardwareInfo function block. Since the documentation lacks any kind of example code on this topic I'm getting nowhere.
Which information should I provide to the function block in order to get the desired serial number?
Below sample will crash in the PLC, probably because the function block requires certain pointers to be addressed:
MC_HARDWARE_INFO_REF hwinfo;
MC_BR_GetHardwareInfo(&hwinfo);
You are probably getting a page fault, because you provide the MC_BR_GetHardwareInfo function block (FUB) a wrong type, which leads to random behavior.
A function block is basically a function which requires a reference to a specific type as parameter. This type contains the actual in- and outputs which are used, internal state variables, etc. We need this, because of the synchronous execution of the code. This means unlike a function, you need to call a FUB until it is done.
Let's take a look to the help of the FUB:
Guid: 056444ea-2a15-4af6-a5ae-0675894b17d3
So the FUB needs a reference to the Axis object of which you want to know the HW info and an Execute command. It will give you some status bits, an error code and the actual data you want to have within the structure HardwareInfo of the type MC_HARDWARE_INFO_REF.
First we need to instantiate the FUB by create a variable of its type. We do this in the local *.var file of the task:
VAR
fbGetHwInfo : MC_BR_GetHardwareInfo := (0);
END_VAR
Then we call set the parameters of the FUB and call it, which might look like this:
void _CYCLIC ProgramCyclic(void)
{
//should be set by the application or in watch/monitor; now it only
//executes once
fbGetHwInfo.Execute = 1;
//reference to your axis object; when using a wizard the first axis
//will be gAxis01 on default
fbGetHwInfo.Axis = (UDINT)&gAxis01;
//call the FUB
MC_BR_GetHardwareInfo(&fbGetHwInfo);
if(fbGetHwInfo.Error == 1)
{
//TODO: errorhandling
}
else if(fbGetHwInfo.Done == 1)
{
//TODO use output
//fbGetHwInfo.HardwareInfo
}
}
typically you would do this in some statemachine. Also you probably have to wait until the network to the drive is initialized. You could check this with the MC_BR_ReadDriveStatus FUB. Just for testing it should be enough to wait for some seconds after reboot and set the Execute flag in monitor mode.

Anylogic: How to conditionally close/open a valve

I am very new at Anylogic. I have a simple model, using the Fluid dynamics library: two tanks and a valve between them. The valve have to open at a rate, say X, only when the amount in the first tank, say tank_1, were twice of the amount of the second tank, say tank_2
Could you please help me with that?
Regards
You probably have more conditions on what to use with the valve depending on different things. But it's a bad idea to make something occur when then tank_1 is exactly 2 times larger than tank_2... Instead, create a boolean variable that tells you if the current situation is that tank_1 is over or below 2*tank_2. Let's call it "belowTank2". I will assume tank_1 is below 2*tank_2 in the beginning of the simulation. so belowTank2 is true.
Then you create an event that runs cyclically every second or even more often if you want and you use the following code:
if(belowTank2){
if(tank_1.amount()>2*tank_2.amount()){
valve.set_openRate(0.1);
belowTank2=false;
}
}else{
if(tank_1.amount()<2*tank_2.amount()){
valve.set_openRate(0.3);
belowTank2=true;
}
}
So this means that whenever tank_1 surpases 2*tank_2, it will trigger the rate change on the valve. And it will trigger again a change when it's below 2*tank_2

unable to get simple program logic

i m making an iphone app in which when same person calls you and u dont pick the phone then the a sound will be played when same user calls u more than 4 times ,now when a call is incoming i am storing its callid in a string or whatever but my problem is i cant find logic to check that the same user has called four times or more??
Use an NSDictionary (a form of hash database). If the current callers name isn't there as the key, add it, and set the value to be count of 1. If the callers name exists as a key in the dictionary, increment the count value by 1. After that, read the count value and do whatever you want depending on the comparison against 4.
But getting the callers name may require some sort of non-stock OS on an iPhone.
Hm.
Loop through an array of received calls.
Instead of storing the callerId in a string, store it in an array called receievedCalls.
During each incoming call, loop through the array (foreach loop?), looking for the callerId of the current caller.
foreach (receivedCalls as $key => $value) {
if ($value == $callerId) {
count++;
}
if (count >= 4) {
(play sound)
}
}
Probably flawed logic but meh. Again, I haven't worked with iPhone apps before so I don't know what kind of language it uses.
No API for that, Sorry.