473,756 Members | 1,904 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

A curses-game I need help with.

Hello.
The last weeks I've been coding a roguelike (you know, like nethack) in
python using the nCurses library. Some week ago I ran into a problem:
When I made the object for messagebar-output, I found a bug that I
can't figure out (believe me; I've tried everything and asked for help
several times on the IRC-channel).

The updateMsg() and iMsg() takes a list of message-lines as argument
(or process a string to a list), and it'll output each of them to the
messagebar, output a sign that say: More, and wait for the user to hit
space, and then output another line. The last line will just be
outputed, without waiting for the user to hit space. Thou, that doesn't
work. It doesn't output the last line. Not when there are more than one
line, and not when there is just that one line.

I've tried calling noutrefresh() and doupdate() instead of just
refresh(), I've rebuilt the structure of the methods, and done all
sorts of things. By writing debug-messages to a file, I've understood
that the last addstr() DO output the line, but the refresh isn't
working. Or something else isn't working.

Can you help?

I'll just append all my code here (for anyone to test), so you who
doesn't want to read this humble beginners code can skip to another
message. Thank you for your time.

(So far I've understood, is that iMsg() and updateMsg() is wrong. Line
71 and 92.)
try:
import curses
except ImportError:
print "Missing the Curses-library."
print "Please install the curses-library correctly."
SystemExit

#---------------------------------------------------------------

class Game:
"""The Game-object. Controls the windows, global settings and so
on."""
def __init__(self):
self.mainwin = curses.initscr( )

## Some basic settings
curses.noecho()
curses.cbreak()
self.mainwin.ke ypad(1)
curses.curs_set (0)

self.msg = Msg()
self.msg.msg(["Welcome to The Game! Lets watch another fearless
samurai", "get beaten bloody in the arena!"])

self.mainwin.ad dstr(3,15, '+' + '-' * 62 + '+')
self.mainwin.ad dstr(22,15, '+' + '-' * 62 + '+')
self.mainwin.vl ine(4,15, '|', 18)
self.mainwin.vl ine(4,78, '|', 18)
movedir = {
'up': {'x':0, 'y':-1},
'down': {'x':0, 'y':+1},
'right': {'x':+1, 'y':0},
'left': {'x':-1, 'y':0},
'downright': {'x':+1, 'y':+1},
'upright': {'x':+1, 'y':-1},
'downleft': {'x':-1, 'y':+1},
'upleft': {'x':-1, 'y':-1}
}

walls = (
ord('|'),
ord('+'),
ord('-')
)

#---------------------------------------------------------------

class Msg:
"""The messagehandelin g and -bar system."""
def __init__(self):
self.msgs = []

def printMore(self) :
# Print the little #More#-sign
game.mainwin.ad dch(1, 71, curses.ACS_BLOC K, curses.A_REVERS E)
game.mainwin.ad dstr(1, 72, "More", curses.A_REVERS E)
game.mainwin.ad dch(1, 76, curses.ACS_BLOC K, curses.A_REVERS E)

def msg(self, msg):
if isinstance(msg, str):
self.msgs.appen d(msg)
else:
self.msgs = self.msgs + msg

def ereasMsg(self):
for count in range(0,2):
game.mainwin.mo ve(count,0)
game.mainwin.cl rtoeol()

def updateMsg(self) :
count = len(self.msgs)
for msg in self.msgs: # Print one msg after
another
game.mainwin.ad dstr(0,0, msg) # Print the actual message
if count 1: # If there are two or more
laft, print a #More#-sign.
count -= 1
self.printMore( )
game.mainwin.re fresh()
while 1:
next = game.mainwin.ge tch()
if next == ord(' '):
self.ereasMsg()
break
else:
continue
else:
game.mainwin.re fresh()

self.msgs = [] # When done, kill all messages
return True

def iMsg(self, msg):
"""Same as msg(), but the screen will refresh instantly.
'i' is standing for Interface or Instant message."""
if isinstance(msg, str):
msg = [msg] # List'it!
count = len(msg)
for item in msg:
if count 1:
count -= 1
self.printMore( )
game.mainwin.ad dstr(0,0, item)
game.mainwin.re fresh()
while 1:
next = game.mainwin.ge tch()
if next == ord(' '):
self.ereasMsg()
break
else:
continue
else:
game.mainwin.ad dstr(0,0, item)

return
#---------------------------------------------------------------

class Samurai:
"""This is the object of the mighty Samurai. Phe4r him. He can
move.
He can spawn. He will be able to kick som robo butt too,
but not now."""
def __init__(self):
## Configuring game values.
self.loc = {
"x": 20,
"y": 8
}
self.samuraicha r = ord("X")

# spawn
game.mainwin.ad dch(self.loc['y'], self.loc['x'],
self.samuraicha r)

def move(self, dir, speed=1):
# Move in dir speed number of times.
for count in range(1, speed + 1):
newX = self.loc['x'] + game.movedir[dir]['x']
newY = self.loc['y'] + game.movedir[dir]['y']

# Checks that all is clear.
if game.mainwin.in ch(newY, newX) not in game.walls:

# Delete old
game.mainwin.ad dch(self.loc['y'], self.loc['x'], ' ')

self.loc['x'] = newX
self.loc['y'] = newY
# Create a new character.
game.mainwin.ad dch(self.loc['y'], self.loc['x'],
self.samuraicha r)

else:
game.msg.iMsg(" You can't go there.")
return

#---------------------------------------------------------------

def main():
global game, player
game = Game()
player = Samurai()

running = True
while running:
key_command = game.mainwin.ge tch()

if key_command == ord('8'): ## Movement-commands
player.move('up ')

elif key_command == ord('2'):
player.move('do wn')

elif key_command == ord('4'):
player.move('le ft')

elif key_command == ord('6'):
player.move('ri ght')

elif key_command == ord('7'):
player.move('up left')

elif key_command == ord('9'):
player.move('up right')

elif key_command == ord('1'):
player.move('do wnleft')

elif key_command == ord('3'):
player.move('do wnright')

elif key_command == ord('Q'): ## Exit
break

elif key_command == ord('5'): ## Wait
pass

elif key_command == ord('x'): ## print location
game.msg.iMsg(" X: " + str(player.loc['x']) + ", Y: " +
str(player.loc['y']))

elif key_command == ord('z'):
strlist = ""
for i in game.walls:
strlist = strlist + str(i) + " "
game.msg.iMsg(s trlist)

elif key_command == ord('c'):
for count in range(0,2):
game.mainwin.mo ve(count,0)
game.mainwin.cl rtoeol()

else:
game.msg.iMsg(" That is not a valid command.")

if len(game.msg.ms gs) == 0: # If there are any msgs.
game.mainwin.re fresh()
else:
game.msg.update Msg()

game.msg.ereasM sg()
if __name__ == "__main__":
try:
import psyco
psyco.full()
except ImportError:
# Don't use something that doesn't exists.
pass

main()

curses.nocbreak (); game.mainwin.ke ypad(0); curses.echo()
curses.endwin()
(The code is GPL'ed, Martin Ahnelöv 06)

Oct 8 '06 #1
7 2853
Hi. I would like to know why no one have answered my post
http://groups.google.com/group/comp....24904058bd1734
..
It were my first post here (and on the Usenet overall), so I would like
to know what I did wrong. Too´many spellingmisstak es? Shitty code? No
one understands? No one got the answer? Should I wait a little longer?
Thank you.

Oct 9 '06 #2
"Gasten" <op*********@gm ail.comwrites:
Can you help?
I'm not a guru on curses by any means, but I've moved one line
of your code and IMHO it works fine now.
Look below for the code I've changed.
I'll just append all my code here (for anyone to test), so you who
doesn't want to read this humble beginners code can skip to another
message. Thank you for your time.

(So far I've understood, is that iMsg() and updateMsg() is wrong. Line
71 and 92.)
try:
import curses
except ImportError:
print "Missing the Curses-library."
print "Please install the curses-library correctly."
SystemExit

#---------------------------------------------------------------

class Game:
"""The Game-object. Controls the windows, global settings and so
on."""
def __init__(self):
self.mainwin = curses.initscr( )

## Some basic settings
curses.noecho()
curses.cbreak()
self.mainwin.ke ypad(1)
curses.curs_set (0)

self.msg = Msg()
self.msg.msg(["Welcome to The Game! Lets watch another fearless
samurai", "get beaten bloody in the arena!"])

self.mainwin.ad dstr(3,15, '+' + '-' * 62 + '+')
self.mainwin.ad dstr(22,15, '+' + '-' * 62 + '+')
self.mainwin.vl ine(4,15, '|', 18)
self.mainwin.vl ine(4,78, '|', 18)
movedir = {
'up': {'x':0, 'y':-1},
'down': {'x':0, 'y':+1},
'right': {'x':+1, 'y':0},
'left': {'x':-1, 'y':0},
'downright': {'x':+1, 'y':+1},
'upright': {'x':+1, 'y':-1},
'downleft': {'x':-1, 'y':+1},
'upleft': {'x':-1, 'y':-1}
}

walls = (
ord('|'),
ord('+'),
ord('-')
)

#---------------------------------------------------------------

class Msg:
"""The messagehandelin g and -bar system."""
def __init__(self):
self.msgs = []

def printMore(self) :
# Print the little #More#-sign
game.mainwin.ad dch(1, 71, curses.ACS_BLOC K, curses.A_REVERS E)
game.mainwin.ad dstr(1, 72, "More", curses.A_REVERS E)
game.mainwin.ad dch(1, 76, curses.ACS_BLOC K, curses.A_REVERS E)

def msg(self, msg):
if isinstance(msg, str):
self.msgs.appen d(msg)
else:
self.msgs = self.msgs + msg

def ereasMsg(self):
for count in range(0,2):
game.mainwin.mo ve(count,0)
game.mainwin.cl rtoeol()

def updateMsg(self) :
count = len(self.msgs)
for msg in self.msgs: # Print one msg after
another
game.mainwin.ad dstr(0,0, msg) # Print the actual message
if count 1: # If there are two or more
laft, print a #More#-sign.
count -= 1
self.printMore( )
game.mainwin.re fresh()
while 1:
next = game.mainwin.ge tch()
if next == ord(' '):
self.ereasMsg()
break
else:
continue
else:
game.mainwin.re fresh()

self.msgs = [] # When done, kill all messages
return True

def iMsg(self, msg):
"""Same as msg(), but the screen will refresh instantly.
'i' is standing for Interface or Instant message."""
if isinstance(msg, str):
msg = [msg] # List'it!
count = len(msg)
for item in msg:
if count 1:
count -= 1
self.printMore( )
game.mainwin.ad dstr(0,0, item)
game.mainwin.re fresh()
while 1:
next = game.mainwin.ge tch()
if next == ord(' '):
self.ereasMsg()
break
else:
continue
else:
game.mainwin.ad dstr(0,0, item)

return
#---------------------------------------------------------------

class Samurai:
"""This is the object of the mighty Samurai. Phe4r him. He can
move.
He can spawn. He will be able to kick som robo butt too,
but not now."""
def __init__(self):
## Configuring game values.
self.loc = {
"x": 20,
"y": 8
}
self.samuraicha r = ord("X")

# spawn
game.mainwin.ad dch(self.loc['y'], self.loc['x'],
self.samuraicha r)

def move(self, dir, speed=1):
# Move in dir speed number of times.
for count in range(1, speed + 1):
newX = self.loc['x'] + game.movedir[dir]['x']
newY = self.loc['y'] + game.movedir[dir]['y']

# Checks that all is clear.
if game.mainwin.in ch(newY, newX) not in game.walls:

# Delete old
game.mainwin.ad dch(self.loc['y'], self.loc['x'], ' ')

self.loc['x'] = newX
self.loc['y'] = newY
# Create a new character.
game.mainwin.ad dch(self.loc['y'], self.loc['x'],
self.samuraicha r)

else:
game.msg.iMsg(" You can't go there.")
return

#---------------------------------------------------------------

def main():
global game, player
game = Game()
player = Samurai()

running = True
while running:
key_command = game.mainwin.ge tch()
# I've moved erasing messages here
game.msg.ereasM sg()
>
if key_command == ord('8'): ## Movement-commands
player.move('up ')

elif key_command == ord('2'):
player.move('do wn')

elif key_command == ord('4'):
player.move('le ft')

elif key_command == ord('6'):
player.move('ri ght')

elif key_command == ord('7'):
player.move('up left')

elif key_command == ord('9'):
player.move('up right')

elif key_command == ord('1'):
player.move('do wnleft')

elif key_command == ord('3'):
player.move('do wnright')

elif key_command == ord('Q'): ## Exit
break

elif key_command == ord('5'): ## Wait
pass

elif key_command == ord('x'): ## print location
game.msg.iMsg(" X: " + str(player.loc['x']) + ", Y: " +
str(player.loc['y']))

elif key_command == ord('z'):
strlist = ""
for i in game.walls:
strlist = strlist + str(i) + " "
game.msg.iMsg(s trlist)

elif key_command == ord('c'):
for count in range(0,2):
game.mainwin.mo ve(count,0)
game.mainwin.cl rtoeol()

else:
game.msg.iMsg(" That is not a valid command.")

if len(game.msg.ms gs) == 0: # If there are any msgs.
game.mainwin.re fresh()
else:
game.msg.update Msg()

game.msg.ereasM sg()
# I've moved this line
# game.msg.eraseM sg
>

if __name__ == "__main__":
try:
import psyco
psyco.full()
except ImportError:
# Don't use something that doesn't exists.
pass

main()

curses.nocbreak (); game.mainwin.ke ypad(0); curses.echo()
curses.endwin()
(The code is GPL'ed, Martin Ahnelöv 06)
--
HTH,
Rob
Oct 9 '06 #3
"Gasten" <op*********@gm ail.comwrites:
I would like to know what I did wrong. Too´many spellingmisstak es?
Shitty code? No one understands? No one got the answer? Should I
wait a little longer? Thank you.
For my part, I skipped over your post because the code was far too long.

If you have a problem you'd like a lot of people to look at, the most
effective way is to make a short, complete example that demonstrates
exactly the problem you're trying to understand.

This approach has the bonus benefit that, in isolating the problem for
this purpose, you often gain a better understanding of it yourself
before posting it :-)

--
\ "Earth gets its price for what Earth gives us." -- James |
`\ Russell Lowell |
_o__) |
Ben Finney

Oct 9 '06 #4
Ben Finney wrote:
If you have a problem you'd like a lot of people to look at, the most
effective way is to make a short, complete example that demonstrates
exactly the problem you're trying to understand.
I should make a demo, you say? I'm gonna do that next time. Thanks.

Oct 10 '06 #5
Rob Wolfe wrote:
while running:
key_command = game.mainwin.ge tch()

# I've moved erasing messages here
game.msg.ereasM sg()
Man... I didn't even think of that. It's embarassing. Thanks. It works
perfect now. Again, thanks.

Gasten

Oct 10 '06 #6
try:
import curses
except ImportError:
print "Missing the Curses-library."
print "Please install the curses-library correctly."
SystemExit
~~~~~~~~~
Does this work ? Maybe *raise SystemExit* ??

Oct 10 '06 #7

Gasten wrote:
Rob Wolfe wrote:
while running:
key_command = game.mainwin.ge tch()
# I've moved erasing messages here
game.msg.ereasM sg()

Man... I didn't even think of that. It's embarassing. Thanks. It works
perfect now. Again, thanks.

Gasten
By the way, I also started doing a small rogue-like with a twist that
you control monsters. I used curses, too. It's very small and
incomplete, and I think there was a bug with monsters going through
walls, but it may help you..

You can find it at silmarill.org -programs -I, monster.

I'd be interested in looking at your game, as it gets imporved, too, do
you have a webpage for it yet? Please post..

Oct 10 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
911
by: Chris Share | last post by:
I've been writing an application using curses, and have been trying to handle resizing the terminal, if running in xterm or similar. Increasing the window size is working perfectly, however shrinking it is not working at all. No matter how much I shrink the window, the size returned by getmaxyx() does not change. However as soon as I increase it again, it works fine. I've tracked the problem down to the fact I have created a window...
1
412
by: Cecil H. Whitley | last post by:
Hi, I had done a quick read of the curses documentation for python. Upon the second reading I found that curses is not supported on windows. I was wondering if it would be relatively simple to use the python wrapper for curses on unix (is there such a beast?) to wrap ncurses or the like on windows? Optionally, are there any major obstacles to writing a python wrapper for ncurses or any other curses-like library for windows? Thanks,...
1
3107
by: Matt Garman | last post by:
I've been working on a curses-based application in Python. My application effectively has a series of screens (or windows). When one screen closes, the previous screen should be exactly redrawin in its original state (i.e., before the sub-screen was created). As far as I can tell, the putwin() and getwin() functions can easily solve this problem. So I can do something like this: # draw/write some stuff on stdscr......
4
4126
by: schwerdy | last post by:
Hi together, can someone provide an example of a curses application that works in a xterm that can be resized? I could not find any working example yet... Thanks in advance, Sebastian 'Schwerdy' Schwerdhöfer
1
3732
by: ale.of.ginger | last post by:
Now that I have gotoxy() down for moving the cursor around, I want that to be a result of keypresses (namely from the numpad -- 7 = NorthWest, 8 = North, 9 = NE, etc...). I have little clue how to do this. After searching google, I've come upon this; include: import curses in the header. However, I've found various methods of actually reading the keyboard press (getch(), raw_input, etc.). What is the best method to use for reading...
0
1035
by: mike.baranski | last post by:
So, can someone tell me why the following code is wrong? When you run it, it will place a . as you arrow key around the screen. Everything works, until you get to the bottom right corner of the screen, trying to move off of this square causes addstr to throw and exception. Every other spot works. Any idea why? Thanks:
3
4869
by: Simon Morgan | last post by:
Hi, I'm having trouble with the following code. The problem is that the value read by getch() when I hit the up or down keys doesn't match curses.KEY_UP or curses.KEY_DOWN respectively. Other keys, such as 'z' in my example code, work fine. I only seem to have this problem when dealing with newly created windows and not with the standard/default/root one created by curses.wrapper() and passed to main().
15
4813
by: pinkfloydhomer | last post by:
I need to develop a cross-platform text-mode application. I would like to do it in Python and I would like to use a mature text-mode library for the UI stuff. The obvious choice, I thought, was ncurses. But as far as I can tell, it is not available for Python on Windows? Is there a workaround? Or are there alternative libraries that might be used instead of (n)curses? I know I can use (n)curses on *nix and console on Windows etc., but...
5
6329
by: 7stud | last post by:
I can't see to get any y, x coordinates to work with curses. Here is an example: import curses def my_program(screen): while True: ch = screen.getch() if ch == ord("q"): break
8
5697
by: linkmaster032000 | last post by:
I tried curses.setsyx(2,3) in my script and it doesn't move the curses cursor. Any alternatives/solutions?
0
9456
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10034
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9843
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9713
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8713
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7248
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5142
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5304
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2666
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.