Author Topic: Python and curses issues  (Read 22827 times)

Scautura

  • Rogueliker
  • ***
  • Posts: 55
  • Karma: +0/-0
    • View Profile
    • CyberRogue
    • Email
Python and curses issues
« on: July 11, 2008, 08:37:28 AM »
I'm trying to translate my (currently Windows only) fledgling roguelike (CyberRogue) to work with Linux and curses - and I'm having a few issues with curses (which I have been cursing steadily since trying).

I'm not what I would call a Python expert by any stretch of the imagination (I've only just started developing in it), and the less said about my curses knowledge the better (and probably still too much). I still haven't got got the hang of throwing/catching exceptions, so I end up with a cursed terminal if I crash (and I haven't even added an endwin() call yet - legacy of Console, rather than not knowing curses).
As such, I've been having problems with some functions calls, such as scroll() (gives me an error), and I was wondering if anyone could give me a hand?

My long term goal would be to create an IO wrapper so that it can be system agnostic - currently I have a log of duplicated functionality in a Linux and Windows version of the same file, and the Linux version of the game doesn't even look the same (or, in places, even work!)

I'm happy to share my source (it's GPL'd) but the latest version of CR is not currently on my blog, so let me know if you'd like to take a look.
Edit: I've upload the file on its own to my blog.
« Last Edit: July 11, 2008, 08:52:58 AM by Scautura »
Duct tape is like the Force - it has a Dark side, a Light side, and it holds the Universe together.
CyberRogue

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: Python and curses issues
« Reply #1 on: July 11, 2008, 01:50:52 PM »
I kind of abandoned the idea of a roguelike in Python+curses because the curses library for Python is only available for Linux. What exactly are you using in Windows?

I also abandoned the idea of using curses altogether, because at the time I didn't know much about compiling/linking and pdcurses was hell to me! Result: I don't know curses at all!

It might actually be easier to use a simple graphical API to simulate the text, though I know many devs and players are against that.

-- edit --

For anyone trying to get this to run under Linux:

$ grep "import Console" *
Go to all the files and comment out those lines. There's probably a geekier faster way to do this, but I can't be bothered right now. It's like, two files.

$ grep "import IOSystem" *
Go to all the files and change IOSystem to IOSystemLinux.

It should start. If you get garbled stuff with an exception, increase the terminal size. Run it again, and it should work :)

Couldn't move around, it just told me what key I pressed. At one point I guess I pressed "i" because I got to an empty inventory and couldn't get out ;)



Also: may I suggest www.diveintopython.org? There's a section on exceptions. They're really not something out of this world, it's just what they say it is. The concept might take a bit to sink in, but none of it is "dark magic" stuff. What I'd do right now, is stuff the main function inside an exception catching block (try-except). Depending on the error type you get, just print out a message before exiting :)
« Last Edit: July 11, 2008, 02:03:19 PM by Anvilfolk »
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

Scautura

  • Rogueliker
  • ***
  • Posts: 55
  • Karma: +0/-0
    • View Profile
    • CyberRogue
    • Email
Re: Python and curses issues
« Reply #2 on: July 11, 2008, 01:58:56 PM »
I'm against a graphical emulation due to people who play RLs on terms over telnet or the like. I'm not against graphics for display as an alternative, however.

On Windows, I'm using Console, which is not as "in depth" as curses (doesn't do its own windowing/panelling) but that's not necessarily a bad thing. It's also nowhere near as complex, which means it's nice and easy to develop for.

Because I use Py2Exe, you should never need to install Python or Console to enjoy CyberRogue, and N*X users are (usually) knowledgable enough to deal with it for themselves. I don't want CR to be a single OS game, hence why I chose Python (worst case, I use Console and write a wrapper thing to make both curses and Console work, best case, curses actually works for Windows).
« Last Edit: July 11, 2008, 02:01:14 PM by Scautura »
Duct tape is like the Force - it has a Dark side, a Light side, and it holds the Universe together.
CyberRogue

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: Python and curses issues
« Reply #3 on: July 11, 2008, 02:09:59 PM »
I think people have been expecting a python windows curses library for quite some time. There have been a couple of attempts, but none of them quite successful, as far as I know. Also, I updated my first post after you posted.

The way you have it seems to be OK. I don't understand why you import Console on files that should have nothing to do with low-level input. I commented them and the game worked anyway. You could also probably launch two different functions/classes depending on whether which operating system you are.

Basically, you should have one IO class of your own, say IOClass, like an "interface". It should have all the IO methods that the game uses. The game will use this class ONLY. If purely abstract methods are not allowed in Python (can't honestly remember), then just implement them as empty functions or with just "return 1" or whatever.

Then, make two other classes that inherit from IOClass, LinuxIOClass and WindowsIOClass, and re-implement IOClass' methods platform-specifically in each of those new subclasses. This means that you can have one single IOClass variable and stuff either LinuxIOClass or WindowsIOClass instances in there, depending on your operating system. You might be able to do this dynamically, when you run the game. Again, I don't remember much Python, but you might want to check this idea out!

-- edit --

import os
os.uname()

and this chapter of Dive into Python!
« Last Edit: July 11, 2008, 02:15:20 PM by Anvilfolk »
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

Scautura

  • Rogueliker
  • ***
  • Posts: 55
  • Karma: +0/-0
    • View Profile
    • CyberRogue
    • Email
Re: Python and curses issues
« Reply #4 on: July 11, 2008, 02:36:19 PM »
As far as I remember, I've only got Console imported in main.py (fixed as of r27), and IOSystem.py (Oops, and System.py, that'll be fixed as of r28). The reason for those are the legacy of not separating IO and content, and I hadn't stripped it out of all the files yet. We learn as we go along!

Moving should be on numbers (1,2, etc...) rather than control keys (PgUp, PgDn, etc...), but will be customizable as well. Printing the last hit key is so I can work out what keys give what results - Console gives a "pretty print" answer to keys such as space ("Space"), esc ("Escape") etc... I haven't figured out how curses returns these (yet) so that's why the inventory doesn't work - it's expecting you to hit the key which returns "Space". Hence the wrapper (so both curses and Console give the same output to whatever input - a black box)

I plan on figuring which OS is running and dynamically import IOWin or IOLin in the future, I've pretty much just thrown the Linux version together right now and test when I can.
Edit: Done as of r28, along with fixing the Console includes - committed when I get home.

I think a lot of what you are saying, and a lot of the ideas I have in my head, are along very similar lines, so I feel like I must be doing something right! I just need to obtain the skill required to get me from where I am right now, to where I want to be post-idea.
« Last Edit: July 11, 2008, 02:42:13 PM by Scautura »
Duct tape is like the Force - it has a Dark side, a Light side, and it holds the Universe together.
CyberRogue

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: Python and curses issues
« Reply #5 on: July 11, 2008, 03:00:35 PM »
Well, I believe this might be the "standard" way to do this kind of stuff, so if you're getting there by yourself, you're doing just fine! :)

Right now, it seems to me you just have to think about the interface, and get to know the libraries you're using so that you can implement them based on those libraries. Then you're set to go on the actual game part! :D

Edit: just managed to get killed by a random monster! Oh noes!
« Last Edit: July 11, 2008, 03:02:28 PM by Anvilfolk »
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

Scautura

  • Rogueliker
  • ***
  • Posts: 55
  • Karma: +0/-0
    • View Profile
    • CyberRogue
    • Email
Re: Python and curses issues
« Reply #6 on: July 11, 2008, 05:08:35 PM »
More fixings. r29 (currently available for download from the blog) is "most complete" in the current style. Before I go too much further, I'm going to switch from the way I'm currently doing it (duplicating large quantities of code, but it got it working in the short term) to a more agnostic method - some of my experiments in curses have failed, but I'm still a better dev-guru (hah!) for it.

Because "Escape" has issues on curses/terms (not so much issues, but it does make life a little awkward) I've moved quit to "Q" (caps count), and it actually drops out of curses gracefully.

PS: os.uname() didn't work, but:
Code: [Select]
if os.name.lower()=='nt':
    import IOWin
else:
    import IOLin
works (pseudo names).

There are a few things I do need to work on (does curses support upto 256 colours/colour pairs? Console does, hence certain things are easy to do - wrapper, should make this easy, but curses wants the colours pre-initialised?)
Duct tape is like the Force - it has a Dark side, a Light side, and it holds the Universe together.
CyberRogue

Scautura

  • Rogueliker
  • ***
  • Posts: 55
  • Karma: +0/-0
    • View Profile
    • CyberRogue
    • Email
Re: Python and curses issues
« Reply #7 on: July 13, 2008, 08:36:56 AM »
I know I probably shouldn't double post but...

CyberRogue v0.0.5 r33 (not currently available) brings Linux support closer to reality. My curses-fu is still weak enough that I can't get the message box to scroll properly, which is important before I go to a wrapper system.
"Why?" you may ask - because it's the last little bit of the puzzle I need to make the whole system work "as intended (as far as I can see, of course). I've managed to fake out "getchar()" to return (some) results the same for both systems (a work in progress, of course), get the screen to look (mostly) similar for both, but I still just can't "get" scrolling. I'm thinking I can fake it using insstr() though...
Another issue is the cursor - it moves to the end of whatever I've just output - even with leaveok(1). This screws up e'x'amining tiles... I'm trying something else out right now, but it seems to be a little, well, not working...

Feh, I'll get there in the end.
Edit: And I did (I think). e'x'amine fakes the cursor by outputting the tile in reverse (special cases for black on black and white on white, they didn't show up properly - probably not doing it the right way, but it works!), and I hadn't used "scrollok(1)" to say scrolling was OK.
« Last Edit: July 13, 2008, 11:18:58 AM by Scautura »
Duct tape is like the Force - it has a Dark side, a Light side, and it holds the Universe together.
CyberRogue