By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,101 Members | 1,340 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,101 IT Pros & Developers. It's quick & easy.

A curses-game I need help with.

P: n/a
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.keypad(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.addstr(3,15, '+' + '-' * 62 + '+')
self.mainwin.addstr(22,15, '+' + '-' * 62 + '+')
self.mainwin.vline(4,15, '|', 18)
self.mainwin.vline(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 messagehandeling and -bar system."""
def __init__(self):
self.msgs = []

def printMore(self):
# Print the little #More#-sign
game.mainwin.addch(1, 71, curses.ACS_BLOCK, curses.A_REVERSE)
game.mainwin.addstr(1, 72, "More", curses.A_REVERSE)
game.mainwin.addch(1, 76, curses.ACS_BLOCK, curses.A_REVERSE)

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

def ereasMsg(self):
for count in range(0,2):
game.mainwin.move(count,0)
game.mainwin.clrtoeol()

def updateMsg(self):
count = len(self.msgs)
for msg in self.msgs: # Print one msg after
another
game.mainwin.addstr(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.refresh()
while 1:
next = game.mainwin.getch()
if next == ord(' '):
self.ereasMsg()
break
else:
continue
else:
game.mainwin.refresh()

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.addstr(0,0, item)
game.mainwin.refresh()
while 1:
next = game.mainwin.getch()
if next == ord(' '):
self.ereasMsg()
break
else:
continue
else:
game.mainwin.addstr(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.samuraichar = ord("X")

# spawn
game.mainwin.addch(self.loc['y'], self.loc['x'],
self.samuraichar)

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.inch(newY, newX) not in game.walls:

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

self.loc['x'] = newX
self.loc['y'] = newY
# Create a new character.
game.mainwin.addch(self.loc['y'], self.loc['x'],
self.samuraichar)

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.getch()

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

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

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

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

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

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

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

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

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(strlist)

elif key_command == ord('c'):
for count in range(0,2):
game.mainwin.move(count,0)
game.mainwin.clrtoeol()

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

if len(game.msg.msgs) == 0: # If there are any msgs.
game.mainwin.refresh()
else:
game.msg.updateMsg()

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

main()

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

Oct 8 '06 #1
Share this Question
Share on Google+
7 Replies


P: n/a
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 spellingmisstakes? Shitty code? No
one understands? No one got the answer? Should I wait a little longer?
Thank you.

Oct 9 '06 #2

P: n/a
"Gasten" <op*********@gmail.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.keypad(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.addstr(3,15, '+' + '-' * 62 + '+')
self.mainwin.addstr(22,15, '+' + '-' * 62 + '+')
self.mainwin.vline(4,15, '|', 18)
self.mainwin.vline(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 messagehandeling and -bar system."""
def __init__(self):
self.msgs = []

def printMore(self):
# Print the little #More#-sign
game.mainwin.addch(1, 71, curses.ACS_BLOCK, curses.A_REVERSE)
game.mainwin.addstr(1, 72, "More", curses.A_REVERSE)
game.mainwin.addch(1, 76, curses.ACS_BLOCK, curses.A_REVERSE)

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

def ereasMsg(self):
for count in range(0,2):
game.mainwin.move(count,0)
game.mainwin.clrtoeol()

def updateMsg(self):
count = len(self.msgs)
for msg in self.msgs: # Print one msg after
another
game.mainwin.addstr(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.refresh()
while 1:
next = game.mainwin.getch()
if next == ord(' '):
self.ereasMsg()
break
else:
continue
else:
game.mainwin.refresh()

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.addstr(0,0, item)
game.mainwin.refresh()
while 1:
next = game.mainwin.getch()
if next == ord(' '):
self.ereasMsg()
break
else:
continue
else:
game.mainwin.addstr(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.samuraichar = ord("X")

# spawn
game.mainwin.addch(self.loc['y'], self.loc['x'],
self.samuraichar)

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.inch(newY, newX) not in game.walls:

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

self.loc['x'] = newX
self.loc['y'] = newY
# Create a new character.
game.mainwin.addch(self.loc['y'], self.loc['x'],
self.samuraichar)

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.getch()
# I've moved erasing messages here
game.msg.ereasMsg()
>
if key_command == ord('8'): ## Movement-commands
player.move('up')

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

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

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

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

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

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

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

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(strlist)

elif key_command == ord('c'):
for count in range(0,2):
game.mainwin.move(count,0)
game.mainwin.clrtoeol()

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

if len(game.msg.msgs) == 0: # If there are any msgs.
game.mainwin.refresh()
else:
game.msg.updateMsg()

game.msg.ereasMsg()
# I've moved this line
# game.msg.eraseMsg
>

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

main()

curses.nocbreak(); game.mainwin.keypad(0); curses.echo()
curses.endwin()
(The code is GPL'ed, Martin Ahnelöv 06)
--
HTH,
Rob
Oct 9 '06 #3

P: n/a
"Gasten" <op*********@gmail.comwrites:
I would like to know what I did wrong. Too´many spellingmisstakes?
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

P: n/a
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

P: n/a
Rob Wolfe wrote:
while running:
key_command = game.mainwin.getch()

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

Gasten

Oct 10 '06 #6

P: n/a
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

P: n/a

Gasten wrote:
Rob Wolfe wrote:
while running:
key_command = game.mainwin.getch()
# I've moved erasing messages here
game.msg.ereasMsg()

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 discussion thread is closed

Replies have been disabled for this discussion.