I am very new to programming. I have only touched the surface of one language, Python, which is what I am working with at the moment. I am trying to write a program that can display random rolling numbers between a range like 1-100. For lack of being able to explain it, I would rather show a video of what I am looking to do.
http://www.youtube.com/watch?v=88SENZe6Z3I
At about 33 seconds in you can see rolling numbers that the player must stop in order to assign it to a character trait. Less all the pretty graphics and everything, What I want to know is if it is possible to write a program that serves this same type of function in Python? If not Python, the only other 2 languages I am becoming a little familiar with are C# and Java. Would it be possible to write it with one or a combination of those?
If it is possible, can you point me in the direction for resources to this effort. I did do a search before posting this but I found myself coming up empty for lack of knowing what to search for.
Thanks!
The “problem” is that this is not directly possible using the command line interface. If you are looking into game development you are probably going to have some graphical interface anyway, so you should look if you find a library that gives you more options in animating things.
Nevertheless, a possible solution for the command line would involve multi-threading. The reason for that is that you cannot both print (continuously changing) numbers and also wait for keyboard input. The normal command line is actually quite limited in that way.
Below you can find a possible solution with a threading approach. But again, if you are going for some game development, you should rather check out actual graphic libraries, or even game libraries that can help you.
from random import randint
from time import sleep
from threading import Thread
import sys
class RollAnimation ( Thread ):
activated = True
number = None
def run ( self ):
while self.activated:
self.number = randint( 1, 100 )
sys.stdout.write( '\r{: >3}'.format( self.number ) )
sys.stdout.flush()
sleep( 0.05 )
t = RollAnimation()
t.start()
# Waiting for enter
input() # use raw_input() for Python 2.x
t.activated = False
print( 'Final roll result:', t.number )
You haven't formulated your question correctly if people has to watch a Youtube video to understand what you want to do. Without watching the video, I can only assume you want to know how random integers work.
import random
x = random.randint(1, 100)
If you want it rolling, you can simply either make three variables or display three random integers inside a for loop and place that in a while or a for loop.
Here's an example.
import random
import sys
try:
rolls = int(sys.argv[1])
except IndexError:
print "Usage: "+sys.argv[0]+" [rolls]"
sys.exit(1)
for i in range(1, rolls+1):
print "Roll "+str(i)
for i in range(0, 3):
print random.randint(1, 100)
For the graphical part of your application, you should look at pygame: http://pygame.org
Related
I've seen some similar questions, but they seemed to use some other programming language
So far I've got:
import turtle
turns=turtle.Turtle()
degree=input('enter a number: ')
for i in range(5):
turtle.left(degree)
turtle.forward(100);
Running this doesn't ask me to input a number and thus doesn't print anything
You should give commands to your turtle, which you named turns.
You invoked the methods on the class as a whole, which doesn't do anything useful for you. Try this:
for i in range(5):
turns.left(degree)
turns.forward(100)
For the input, just follow any input example for your Python version. For instance, for Python 3, try
degree = int(input("Enter the angle of the turn in degrees:"))
Also try inserting some debugging print statements to track the data and control flow.
I am attempting to create a very basic Combat Simulator. Here is my code:
import random
#from random import * I had, at one time, created a D20 generator that used the * function. I have since removed it in favor of using randint()
sword = 0
D20 = 0
class Hero:
def swing_and_hit(sword, D20):
sword = D20
print(D20)
if sword >= 10:
print("You have defeated the Villian!")
elif sword < 10:
print("You have died!")
D20 = randint(1,20)
Adventurer = Hero
#Adventurer.D20_Func() Ignore this...aborted effort to try something
Adventurer.swing_and_hit(sword, D20)
Every time I run this at http://pythontutor.com/visualize.html#mode=edit, the random number generator outputs 13. I cannot figure out why it does this...any thoughts? I have tried nesting the random number generation inside the function swing_and_hit, and it still generates the same number every time I run the program.
This seems to be a "feature" in Pythontutor to ensure different people will see the same results running the same code. (I am getting always 17)
Whether or not they define it as a feature, it is broken as it could be - random numbers should be random.
Just install Python in your own computer, and get going - it is a smaller than 20MB download from http://python.org if you are using Windows (and if you are not, you have Python installed already). There are interactive interpreters and even a simple development environment that is installed along with the language - there is no motive for you to hurt yourself with a web implementation that might be good for group study of some code, or introspecting what goes in each variable step by step. Python interactive environments are much more dynamic than the "click to run" you get on this site.
I think the random number generator producing the same number every time is a quirk of pythontutor.com. I get 17 every time with just this code:
import random
print(random.randint(1, 20))
If you must use a website to run your code, try repl.it.
I do believe that thread may accomplish this, although I am not sure. Most of the threads out there that address this problem doesn't address it to match my problem. I have created a simple mud-like fighting system that executes when you 'fight' an NPC. I have the code that runs under a while loop that checks health between you and NPC and if one of you dies then the loop ends.
However
During the loop I want to have it where a user can type in commands, instead of being stuck watching a looping code block without you being able to do anything. From what I have read online it looks like thread module may be of some help to me? Also if anyone has PyGame experience, maybe looking into that would be a solution? Please let me know what you think.
Below is a very simple example of what I am trying to accomplish.
import time
fighting = True
while fighting:
# do the magic here
time.sleep(4) # to give it a nice even pace between loop intervals
Although at any time i want to be able do input a command like a skill or spell.
Any ideas or suggestions?
You can separate your human interface and fight game into separate threads. The fight game uses a queue for input, which uses a timeout to continue. Here is a very simple queue structure that should minimally do what you want.
import time
import threading
import Queue
def fighter(input_queue):
while True:
start = time.time()
# do stuff
wait = time.time() - start()
if wait <= 0.0:
wait = 0
try:
msg = input_queue.get(wait, wait)
if msg == 'done':
return
# do something else with message
except Queue.Empty:
pass
def main():
input_queue = Queue.Queue()
fight_thread = threading.Thread(target=fighter, args=(input_queue,))
fight_thread.start()
while True:
msg = raw_input('hello ') # py 2.x
input_queue.put(msg)
if msg == 'done':
break
fight_thread.join()
If you only want this to work on Windows, and you want to keep your simple event loop:
fighting = True
inputbuf = ''
while fighting:
# do the magic here
while msvcrt.khbit():
newkey = msvcrt.getwche()
inputbuf += newkey
if newkey == '\r':
process_command(inputbuf)
inputbuf = ''
time.sleep(4) # to give it a nice even pace between loop intervals
On the other hand, if you want to use a background thread, it would be a lot simpler:
def background():
for line in sys.stdin:
process_command(line)
bt = threading.Thread(target=background)
bt.start
fighting = True
while fighting:
# do the magic here
time.sleep(4) # to give it a nice even pace between loop intervals
This works cross-platform, and it gives normal line-buffered input (including full readline support), which people will probably like.
However, I'm assuming you want that process_command to share information with the # do the magic here code, and possibly even to set fighting = False. If you do that without any thread synchronization, it will no longer work cross-platform. (It may work on both Windows CPython and Unix CPython, but will probably not work on IronPython or Jython—or, worse, it will work most of the time but randomly fail just often enough that you have to fix it but not often enough that you can debug it…)
What you may be looking for is a non-blocking raw_input implementation. This would allow the loop to keep going while allowing the user a possibility at entering commands.
There is an example of an implementation of this here and here. Maybe you can adapt one of them to suit your purpose.
Edit:
Or, if you're working on Windows...
I'm trying to build a program that controls an RGB LED through a RaspberryPi.
I was able to build a simple fade program in python using pi-blaster, which works fine but doesn't let me do what I want.
Here's my code:
import time
import sys
import os
blue = 21
green = 23
red = 22
def fade(color, direction, step):
if direction == 'up':
for i in range(0, 100, step):
f=(i/float(100))
os.system('echo "%d=%f" > /dev/pi-blaster' % (color, f))
return fade(color, 'down', step)
else:
step=-step
for i in range (100, 0, step):
f=(i/float(100))
os.system('echo "%d=%f" > /dev/pi-blaster' % (color, f))
return fade(color, 'up', step)
input = raw_input("Choose a color (r, g, b): ")
if input == 'r':
fade(red, 'up', 1)
if input == 'g':
fade(green, 'up', 1)
if input == 'b':
fade(blue, 'up', 1)
The problem is that I want to be able to control the fade through an external script / program.
My idea is to have a script which is always listening for user input, so when I type "red" it stops the ongoing fade and starts a new red one, by calling the function I posted before.
I also want to be able to change the speed of the loop but this is already implemented into the "fade" function.
I don't really understand how I could do this. I've read some things on here and I think I may have to use the Threading functions, but I don't really understand how those could work for my project.
Thanks in advance for your help and sorry for my English which is not very good :)
EDIT:
I solved it using a loop checking continuously for keyboard inputs which then calls the fade function using multiprocessing.
I can now kill the fade process using processName.terminate()
to get much better performance (and as a clarification to the first answer) it is much better to write using python - but you must put a new line after each write with a '\n'
Otherwise the code #daveydave400 gave is spot on
I'm doing something like this:
f = open('/dev/pi-blaster', 'w')
f.write('0=120\n')
#or
f.write('0=%s\n'%amount)
my actual code is in a function - in case you want to use that:
def changer(pin, amount):
f = open('/dev/pi-blaster', 'w')
f.write('%d=%s\n'%(pin, str(amount)))
if doing for loops using the the system command method you might find that python stops listening for keyboard input intermittently. This was certainly happening for me. I found that keyboardinterrupt was very hard to achieve with ctrl-c and had to repeatedly hit those keys to get the program to halt. Now i'm writing with python i'm not getting that issue.
There are a lot of ways to doing this, I'll describe a hard way and an easy way to get the basic functionality you want and hopefully they give you some ideas on how you want to solve this. The hard way involves creating a daemon-like script that sits in the background and reads a socket or file for when to change what it's doing. This is probably a good learning experience so don't be afraid of trying this. This method is also similar to the easy method I describe below. You would create a python script that opens a UDP or TCP socket, then it starts a separate process that calls the fade function. The main process listens to the socket, when it gets a new valid command (red, green, blue, quit, etc) it kills the child process and starts another with the new color. You could use threads, but I'm pretty sure killing threads from the parent is not so pretty, so you'd have to use events/locks and maybe some global variables. There are plenty of different ways to do this, but the general idea of one process/thread listens and one does the fading will be the same.
The easy/fast way is to have a bash script that wraps your color changes (red.sh, green.sh, blue.sh). In these scripts they kill any previously running scripts and then start the new fade command. Knowing what to kill can be done a couple of ways, the easiest is probably to write the PID to a file, then when it needs to be killed read that PID number in and kill it.
I know I didn't provide any code and this is long, but there are a lot of ways to do what you are trying to do. Also, you should be able open/write the "/dev/pi-blaster" directly in python (not sure opening device files this way will work):
blaster_file = open("/dev/pi-blaster", "a")
for i in range(100, 0, step):
blaster_file.write(...)
blaster_file.close()
To change the speed of the loop you could add a delay by using sleep and specify the duration with a keyword:
from time import sleep
def fade(color, direction, step, delay=0):
...
for i in range(100, 0, step):
...
sleep(delay)
return fade(color, direction, step, delay=delay)
I am trying to make a program which has a raw_input in a loop, if anyone presses a key while the long loop is running the next raw_input takes that as input, how do I avoid that?
I don't know what else to add to this simple question. Do let me know if more is required.
EDIT
Some code
for i in range(1000):
var = raw_input("Enter the number")
#.... do some long magic and stuff here which takes afew seconds
print 'Output is'+str(output)
So if someone presses something inside the magic phase, that is take as the input for the next loop. That is where the problem begins. (And yes the loop has to run for 1000 times).
This works for me with Windows 7 64bit, python 2.7.
import msvcrt
def flush_input():
while msvcrt.kbhit():
msvcrt.getch()
I put the OS in the title, window 7 64 bit to be specific. I saw the
answers there. They do apply but by god they are so big. Aren't there
other n00b friendly and safer ways to take inputs?
Let me try to explain why you need to do such an elaborate process. When you press a key it is stored in a section of computer memory called keyboard buffer (not to be confused with stdin buffer). This buffer stores the key's pressed until it is processed by your program. Python doesn't provide any platform independent wrapper to do this task. You have to rely on OS specific system calls to access this buffer, and flush it, read it or query it. msvcrt is a MS VC++ Runtime Library and python msvcrt provides a wrapper over it. Unless you wan't a platform independent solution, it is quite straight forward.
Use msvcrt getch to read a character from console. msvcrt.kbhit() to test if a key press is present in the keyboard buffer and so on. So as MattH has shown, it just a couple of lines code. And if you think you are a noob take this opportunity to learn something new.
Just collect your input outside of the loop (before you enter the loop). Do you really want the user to enter 1000 numbers? well maybe you do. but just include a loop at the top and collect the 1000 numbers at the start, and store them in an array.
then on the bottom half change your loop so it just does all the work. then if someone enters something no the keyboard, it doesn't really matter anymore.
something like this:
def getvars(top=1000):
vars = []
for i in range(0,top):
anum = int(raw_input('%d) Please enter another number: ' % i))
vars.append(anum)
return vars
def doMagic(numbers):
top = len(numbers)
for number in numbers:
# do magic number stuff
print 'this was my raw number %s' % number
if __name__ == "__main__":
numbers = getvars(top=10)
doMagic(numbers)
presented in a different sort of way and less os dependent
There is another way to do it that should work. I don't have a windows box handy to test it out on but its a trick i used to use and its rather undocumented. Perhaps I'm giving away secrets... but its basically like this: trick the os into thinking your app is a screensaver by calling the api that turns on the screensaver function at the start of your magic calculations. at the end of your magic calculations or when you are ready to accept input again, call the api again and turn off the screensaver functionality.
That would work.
There is another way to do it as well. Since you are in windows this will work too. but its a fair amount of work but not really too much. In windows, the window that is foreground (at the top of the Z order) that window gets the 'raw input thread'. The raw input thread receives the mouse and keyboard input. So to capture all input all you need to do is create a function that stands up a transparent or (non transparent) window that sits at the top of the Z order setWindowPos would do the trick , have it cover the entire screen and perhaps display a message such as Even Geduld or Please wait
when you are ready to prompt the user for more input, you use showwindow() to hide the window, show the previous results, get the input and then reshow the window and capture the keys/mouse all over again.
Of course all these solutions tie you to a particular OS unless you implement some sort of try/except handling and/or wrapping of the low level windows SDK calls.