I'm pretty new to IDL and as a way to learn I have tried to create a number guessing game. I have a Widget with three buttons: One that tells the program the number you are thinking of is larger than the one the computer asks about, one if it's smaller and one if it's correct.
My problem is that once you have pushed i.e. the larger button, if you press it again it won't do anything. E.g. the program starts to guess 500, if I press larger it guesses 750. If I now press larger again, the program doesn't respond.
My code is like this:
PRO test1_event, ev
WIDGET_CONTROL, ev.top, GET_UVALUE = stash
minimum = 0
maximum = 1000
IF (ev.Id EQ largerbutton) THEN BEGIN
minimum = (minimum+maximum)/2
maximum = maximum
ENDIF
IF (ev.Id EQ smallerbutton) THEN BEGIN
maximum = (minimum+maximum)/2
minimum = minimum
ENDIF
IF (ev.Id EQ correctbutton) THEN BEGIN
help2 = string('I got it!') ;This prints to a text widget
ENDIF
END
PRO test1
wBase = WIDGET_BASE(X_SCROLL_SIZE = 512, Y_SCROLL_SIZE = 512)
;wDraw = WIDGET_WINDOW(wBase, X_SCROLL_SIZE = 512, Y_SCROLL_SIZE = 512)
Lower = WIDGET_BUTTON(wBase, VALUE = 'Smaller', XOFFSET = 60, YOFFSET = 250)
Higher = WIDGET_BUTTON(wBase, VALUE = 'Larger', XOFFSET = 225, YOFFSET = 250)
Correct = WIDGET_BUTTON(wBase, VALUE = 'Correct', XOFFSET = 380, YOFFSET = 250)
minimum = 0
maximum = 1000
help1 = string('Please think of a number between' + string(minimum) + ' and ' + string(maximum))
help2 = string('Is your number ' + string((minimum + maximum)/2) + '?')
wText = WIDGET_TEXT(wBase, VALUE = ['Welcome to my little game. I will now try and guess a number you are thinking of.'], XSIZE = 63,XOFFSET = 50, YOFFSET = 100)
wText1 = WIDGET_TEXT(wBase, VALUE = help1, XSIZE = 63,XOFFSET = 50, YOFFSET = 120)
wText2 = WIDGET_TEXT(wBase, VALUE = help2, XSIZE = 63,XOFFSET = 50, YOFFSET = 140)
stash = {text1:wText, text2:wText1, text3:wText2, $
lower:Lower, higher:Higher, correct:Correct, minimum:minimum, maximum:maximum}
WIDGET_CONTROL, wBase, SET_UVALUE = stash, /REALIZE
XMANAGER, 'test1', wBase
end
I have tried using a while loop and also REPEAT, but then the program just goes right up to 999 if I press the larger button and to 0 if I press the smaller.
Any ideas to what I can do?
EDIT: Added the rest of the program
I think the buttons are working fine but your event handler doesn't actually do anything. First, I needed to change largerbutton, smallerbutton, and correctbutton to be stash.higher, stash.lower, stash.correct. Then, your code calculates the new minimum & maximum but it doesn't actually do anything with them.
I put a print statement into the event code and it's definitely getting the button presses.
In your event handler you probably want to use widget_control to update the text box with the new guess.
Related
This question already has answers here:
Pygame mouse clicking detection
(4 answers)
Closed 5 days ago.
i am working through a pygame code and am in the process of creating a second menu sequentially, however unlike the first menu the second one differs in that it only works when holding down on the position of the button.
i am wondering if anyone can help differentiate what makes the two work and if there is a fix for it.
import random
import time
import pygame
pygame.init()
WIDTH = 500
HEIGHT = 500
screen = pygame.display.set_mode([WIDTH, HEIGHT])
fps = 60
timer = pygame.time.Clock()
main_menu = False
font = pygame.font.Font('freesansbold.ttf', 24)
menu_command = 0
p1score = 0
p2score = 0
class Button:
def __init__(self, txt, pos):
self.text = txt
self.pos = pos
self.button = pygame.rect.Rect((self.pos[0], self.pos[1]), (200, 40))
def draw(self):
pygame.draw.rect(screen, 'light gray', self.button, 0, 5)
pygame.draw.rect(screen, 'dark gray', self.button, 5, 5)
text = font.render(self.text, True, 'black')
screen.blit(text, (self.pos[0] + 15, self.pos[1] + 7))
def check_clicked(self):
if self.button.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
return True
else:
return False
def draw_game():
button = Button('Main Menu', (120, 450))
button.draw()
menu = button.check_clicked()
return menu
def draw_menu():
command = -1
pygame.draw.rect(screen, 'black', [100, 100, 300, 300])
#exit menu button
menu_button = Button('Exit Menu', (120, 350))
btn1 = Button('Local Match', (120, 180))
btn2 = Button('Online Match', (120, 240))
btn3 = Button('Settings', (120, 300))
menu_button.draw()
btn1.draw()
btn2.draw()
btn3.draw()
if menu_button.check_clicked():
command = 0
if btn1.check_clicked():
command = 1
if btn2.check_clicked():
command = 2
if btn3.check_clicked():
command = 3
return command
def turndecide():
time.sleep(0.1)
firstturn = -1
p1button = Button('player 1', (120, 120))
p2button = Button('player 2', (120, 180))
ranbutton = Button('Random', (120, 240))
firstturntext = font.render(f'please select who will take the first turn', True, 'black')
screen.blit(firstturntext, (20, 20))
p1button.draw()
p2button.draw()
ranbutton.draw()
if p1button.check_clicked():
firstturn = 1
if p2button.check_clicked():
firstturn = 2
if ranbutton.check_clicked():
firstturn = random.randint(1, 2)
return firstturn
def localgame():
screen.fill('white')
turn = turndecide()
if turn > 0:
screen.fill('red')
outputtext = font.render(f'player {turn} will move first', True, 'black')
screen.blit(outputtext, (20, 20))
run = True
while run:
screen.fill('white')
timer.tick(fps)
if main_menu:
menu_command = draw_menu()
if menu_command != -1:
main_menu = False
else:
main_menu = draw_game()
if menu_command > 0:
if menu_command == 1:
localgame()
if menu_command == 2:
onlinegame()
if menu_command == 3:
settings()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.flip()
pygame.quit()
i tried adding a while loop to ensure the code does not move backward as it does
def localgame():
screen.fill('white')
turn = turndecide()
testvariable = True
while testvariable:
if turn > 0:
screen.fill('red')
outputtext = font.render(f'player {turn} will move first', True, 'black')
screen.blit(outputtext, (20, 20))
but this causes the program to crash.
In your check_clicked function, it will return True only if the user is actively clicking on the button. Whether or not you show the menu is, therefore, also linked to whether or not the user is actively clicking/holding the button.
Instead, each time the button is clicked, toggle the menu option. Only toggle the menu again once the player releases the mouse and presses it again. This avoids the menu being toggled really quickly constantly while holding the button down.
Perhaps, have a can_click variable that is set to False every time a click is registered and reset to True when the mouse is released.
Trying to plot a shape on the previous week's high, but having difficulty getting it to plot. Hope someone can help here
indicator("My script", overlay = true)
previousWeekHigh = request.security(syminfo.tickerid, 'W', high[1],lookahead=barmerge.lookahead_on, gaps = barmerge.gaps_off)
isNewWeek = timeframe.change("W")
anchor_point() =>
float anchor = na
if isNewWeek
anchor := previousWeekHigh
anchor
anchorBar = anchor_point()
plotshape(anchorBar, style=shape.xcross)```
You cannot really use the plotshape() for this purpose as the position of the weekly high bar will be dynamic.
I would just use two var variables, one for the price and one for the "bars since" count. You don't even need the security() here.
Here is an example:
//#version=5
indicator("My script", overlay=true)
is_new_week = ta.change(time("W"))
bgcolor(is_new_week ? color.new(color.blue, 85) : na)
var label weekly_high_lbl = label.new(na, na, "Weekly\nHigh", yloc=yloc.abovebar, style=label.style_label_down, color=color.green, textcolor=color.white)
var line weekly_high_line = line.new(na, na, na, na, extend=extend.right, color=color.green)
var float weekly_high_price = na
var int weekly_high_barssince = 0
if (is_new_week)
// Update the label and line first
label.set_xy(weekly_high_lbl, bar_index - weekly_high_barssince, weekly_high_price)
line.set_xy1(weekly_high_line, bar_index - weekly_high_barssince, weekly_high_price)
line.set_xy2(weekly_high_line, bar_index, weekly_high_price)
// Reset the variables
weekly_high_price := high
weekly_high_barssince := 0
else
// Check for new high
if (high >= weekly_high_price)
weekly_high_price := high
weekly_high_barssince := 1
else
weekly_high_barssince := weekly_high_barssince + 1 // Increase the counter
I have the following problem, described in the image above.
Actually sometimes when I use my script the "OK" button shows, and not at other times when I use the script. If I make the window bigger myself, using my mouse it will then show up (It was previously hidden because the window was to small). I don't understand why and I couldn't find anything really helpful on the internet. (Changing stuff like the value of padx and pady didn't work.)
There has to be a parameter to adjust the general window size but I can't find it.
My second problem is that if the strings are long as in the example; a scroll bar to scroll from left to right will show. I would like to show the full strings. I also don't know how to fix that, sadly.
Is there something to do about it?
My code is the following:
noms_var_manif is a character vector
win2 <- tktoplevel()
tkgrid(tk2label(win2, text = "Veuillez selectionner les variables appartenant à ce bloc",
wraplength = 200, justify = "left"),
padx = 10, pady = c(15, 5), sticky = "w", columnspan = 2)
# Note that 'selection' uses indices starting at 1, like R and not Tcl/Tk!
win2$env$lst <- tk2listbox(win2,values=noms_var_manif, height = 10, selectmode = "extended")
tkgrid(win2$env$lst, padx = 100, pady = c(10, 20), sticky = "ew", columnspan = 2)
onOK <- function() {
select_var_bloc<- noms_var_manif[as.numeric(tkcurselection(win2$env$lst)) + 1]
tkdestroy(win2)
if (!length(select_var_bloc)) {
msg <- "Il n'y a donc aucune variable dans ce bloc?"
} else {
msg <- paste0("Vous avez choisi les variables suivantes: ",
paste(select_var_bloc, collapse = ", "))
}
tkmessageBox(message = msg)
win2$env$select_var_bloc= select_var_bloc
tkdestroy(win2)
}
win2$env$butOK <-tk2button(win2, text = "OK ", width = -6, command = onOK)
tkgrid(win2$env$butOK, padx = 10, pady = c(10, 15))
tkwait.window(win2)
select_var_bloc=win2$env$select_var_bloc
What you want to do is (1) fix the height and width of the the listbox, and
(2) fix the height and width of the window so that it is big enough to allow the OK button to always show. You can also fix the window so that it cannot be resized.
I am using the DynamicControlsPlaceholder by Denis Bauer to save the viewstate of dynamic controls after postback.
I used DynamicControlsPlaceholder before in an earlier part of my project and it worked flawlessly.
However, today I have run into difficulty. I have created a page where there are a number of text labels, slider bars and textboxes (defined by how many elements there are on a database) as shown below. The slider bars are JuiceUI slider controls and the text boxes are normal ASP.NET textboxes.
After postback the text labels (literal controls) and pie chart disappear, the textboxes reduce in size (text inside remains) and the sliderbars are reset to the lowest value without the ability to move the slider (the sliders cannot move at all).
I am quite new to ASP.NET and I am completely stumped as to why this is happening. Do you think it is a problem with the dynamic control placeholder, JuiceUI slider or my code (see below)?
{
SqlCeCommand cmdb = new SqlCeCommand();
cmdb.CommandText = "SELECT CriteriaName,CriteriaDesc FROM tblCriteria WHERE (DecisionID = #DID)";
cmdb.Parameters.AddWithValue("#DID", DID.Text.Trim());
cmdb.Connection = sqlConnection1;
reader = cmdb.ExecuteReader();
string[] criterianames = new string[critno];
string[] criteriadescs = new string[critno];
int i = 0;
while (reader.Read())
{
criterianames[i] = reader["CriteriaName"].ToString().Trim();
criteriadescs[i] = reader["CriteriaDesc"].ToString().Trim();
i++;
}
reader.Close();
Cont2.Controls.Add(new LiteralControl("<h3>Thank you for contributing to the following decision.<h4>Decision Goal: " + dgoal + "</h4><br><br><center>"));
Series weights = new Series();
weights.ChartType = SeriesChartType.Pie;
double[] yBar = new double[critno];
string[] xBar = new string[critno];
xBar = criterianames;
for (i = 0; i < critno; i++)
{
yBar[i] = 1;
}
ChartArea ca = new ChartArea();
ca.Position = new ElementPosition(0, 0, 100, 100);
ca.InnerPlotPosition = new ElementPosition(0, 0, 100, 100);
ca.BackColor = System.Drawing.Color.Transparent;
Chart piechart = new Chart();
piechart.RenderType = RenderType.ImageTag;
piechart.ChartAreas.Add(ca);
piechart.BackColor = System.Drawing.Color.Transparent;
piechart.Palette= ChartColorPalette.BrightPastel;
piechart.BorderColor = System.Drawing.Color.Black;
piechart.BorderSkin.PageColor = System.Drawing.Color.Transparent;
piechart.BorderSkin.BackColor = System.Drawing.Color.Transparent;
piechart.Width = 800;
piechart.Series.Add(weights);
piechart.ImageStorageMode = ImageStorageMode.UseImageLocation;
piechart.ImageLocation = "~/TempImages/ChartPic_#SEQ(300,3)";
piechart.Series[0].Points.DataBindXY(xBar, yBar);
piechart.DataBind();
Cont2.Controls.Add(piechart);
Cont2.Controls.Add(new LiteralControl("</center><h3>Please provide a weighting for each criterion.</h3><p>Please provide a weighting for each criterion along with a description of why you made this choice. </p>"));
for (i = 0; i < critno; i++)
{
Cont3.Controls.Add(new LiteralControl("<h3>" + criterianames[i] + "</h3><p><strong>Description: </strong>" + criteriadescs[i] + "</p><center>"));
Juice.Slider weightslider = new Juice.Slider();
weightslider.ID = "w" + i.ToString();
weightslider.Min = 1;
weightslider.Value = 50;
weightslider.Max = 100;
weightslider.AutoPostBack = true;
Cont3.Controls.Add(weightslider);
weightslider.ValueChanged += (o, a) =>
{
ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + weightslider.Value.ToString() + "');", true);
};
TextBox wdesc = new TextBox();
wdesc.ID = "wd" + Convert.ToString(i);
wdesc.Rows = 3;
wdesc.Width = 900;
wdesc.TextMode = TextBoxMode.MultiLine;
Cont3.Controls.Add(wdesc);
Cont3.Controls.Add(new LiteralControl("</center>"));
}
Cont3.Controls.Add(new LiteralControl("<p align='right'>"));
Button continue1 = new Button();
continue1.Text = "Continue";
Cont3.Controls.Add(continue1);
Cont3.Controls.Add(new LiteralControl("</p>"));
// Database Disconnect
sqlConnection1.Close();
}
Many thanks for any help you can provide,
Kind regards,
Richard
You could eliminate or confirm the problem exists with Juice UI by creating a page containing nothing more than a Juice UI slider, one of these dynamic placeholders and a label. That'd be the first stop.
If you do run into problems with Juice UI, you can use it's cousin Brew
I'm currently trying to open an MsRdpClient connection in a web browser by opening a new tab and passing it dynamic server names. However, the following code doesn't seem to work and I can't dynimically populate any of the required values, namely servername and available screen width and height.
resWidth = request.querystring("width")
resHeight = request.querystring("height")
MsRdpClient.DesktopWidth = resWidth
MsRdpClient.DesktopHeight = resHeight
MsRdpClient.Width = resWidth
MsRdpClient.Height = resHeight
MsRdpClient.server = request.querystring("fqdn")
MsRdpClient.username = "username"
MsRdpClient.AdvancedSettings.ClearTextPassword = "password"
MsRdpClient.AdvancedSettings2.RDPPort = "3389"
MsRdpClient.Connect
I'm not really sure where to go from here. I see it's been asked on a few boards but no one has seem to come up with an answer. Any help would be greatly appreciated.
Below is the script I ended up using. putting the required variables in via scriptlets is what did the trick. i.e. the "<%=fqdn%>"
resWidth = (screen.AvailWidth - 45)
resHeight = (screen.AvailHeight - 150)
MsRdpClient.DesktopWidth = resWidth
MsRdpClient.DesktopHeight = resHeight
MsRdpClient.Width = resWidth
MsRdpClient.Height = resHeight
MsRdpClient.server = "<%=fqdn%>"
MsRdpClient.AdvancedSettings2.RDPPort = "3389"
MsRdpClient.Connect
sub MsRdpClient_OnDisconnected(disconnectCode)
history.go(-1)
end sub