LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 02-11-2012, 08:55 AM   #1
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Rep: Reputation: 5
python front end to nethack?


I am playing around with the idea of a front end in python using nethack as the backend.
Anybody know how to capture signals from nethack and return commands in python?
 
Old 02-11-2012, 11:36 AM   #2
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
Googled here:
Code:
http://effbot.org/librarybook/os.htm
Tried the following:
Code:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

import os
print os.name

if os.name == "nt":
    command = "dir"
else:
    command = "ls -l"

resultat = os.system(command)
print resultat

resultat = os.system("nethack")
print resultat
which gave me:
Code:
]$ python nethackPython.py 
posix
total 4
-rw-rw-r-- 1 gillesg gillesg 235 Feb 11 12:28 nethackPython.py
0
/usr/games/nethack-3.4.3/nethack: error while loading shared libraries: libXaw.so.7: cannot open shared object file: No such file or directory
32512
The error message is ok. Nethack must be missing a lib, which is ok for now since it quits and I don't have to kill it.
I'm wondering what the two numbers mean: 0 and 32512. Are they handles to programs? Could I use them to feed commands to the programs? On second thought, it must be an error code that nethack is returning. Nuts!

Last edited by S. Chapelin; 02-11-2012 at 11:44 AM. Reason: second thoughts
 
Old 02-11-2012, 11:51 AM   #3
audriusk
Member
 
Registered: Mar 2011
Location: Klaipėda, Lithuania
Distribution: Slackware
Posts: 131

Rep: Reputation: 60
Quote:
Originally Posted by S. Chapelin View Post
I'm wondering what the two numbers mean: 0 and 32512. Are they handles to programs? Could I use them to feed commands to the programs? On second thought, it must be an error code that nethack is returning. Nuts!
Those are process exit codes, they're meant to indicate if a process finished successfully (0) or not (any other number). Programs can use different numbers to indicate different errors.

To communicate with a child process, you should use stdin and stdout. You should also use subprocess module instead of os.system(), it's better suited for subprocess handling. There are quite a few usage examples in its documentation.
 
1 members found this post helpful.
Old 02-11-2012, 12:15 PM   #4
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
Tried the following:
Code:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

import subprocess

subprocess.call("nethack")
Good result. Will try other subprocess commands. Thanks
 
Old 02-11-2012, 07:10 PM   #5
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
Code:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

import subprocess

popenArgs = ["nethack", "-s"]
nh = subprocess.Popen(popenArgs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sortie = nh.communicate()
print "sortie = " , sortie
print "nh.poll() = ", nh.poll()
if nh.poll():
    nh.kill()
OK. At least we're communicating. Now to set up a dialog.
 
Old 02-11-2012, 07:21 PM   #6
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
I want to open nethack, then close it with "q"
Code:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

import subprocess

popenArgs = ["nethack"]
nh = subprocess.Popen(popenArgs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sortie = nh.communicate("q")
print "sortie = " , sortie
print "nh.poll() = ", nh.poll()
if nh.poll():
    nh.kill()
Result:
Code:
$ python nethackPython.py 
sortie =  ('\x1b[?1049h\x1b[H\x1b[2J\x1b[H\x1b[2;1HNetHack, Copyright 1985-2003\r\x1b[3;1H         By Stichting Mathematisch Centrum and M. Stephenson.\r\x1b[4;1H         See license for details.\r\x1b[5;1H\x1b[H\x1b[2J\x1b[H\x1b[?1049lYou must play from a terminal.\n', 'NetHack (gettty): Invalid argument\nNetHack (settty): Invalid argument\n')
nh.poll() =  1
Traceback (most recent call last):
  File "nethackPython.py", line 12, in <module>
    nh.kill()
  File "/usr/lib/python2.7/subprocess.py", line 1446, in kill
    self.send_signal(signal.SIGKILL)
  File "/usr/lib/python2.7/subprocess.py", line 1436, in send_signal
    os.kill(self.pid, sig)
OSError: [Errno 3] No such process
Hmmm. Curiouser and curiouser.
1. Nethack wants a terminal.
2. nh.kill() doesn't work.
 
Old 02-11-2012, 08:12 PM   #7
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
I used to be able to read c files.
They used to begin with the calling of main(argc,argv).
I guess that was a long time ago.
Now I can't find the point of entry in the nethack src files.
I would like to see where the check for the tty, the console.

I seem to remember vaguely that nethack, or was it some other program, had a slave mode that you could turn on with some switch. Going to have to look that up, but for now I've had enough for one day.

Last edited by S. Chapelin; 02-11-2012 at 08:21 PM. Reason: afterthought
 
Old 02-12-2012, 07:00 AM   #8
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
What argument would a terminal send to nethack?
 
Old 02-13-2012, 06:33 AM   #9
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
Does anyone know how to simulate a terminal call from within python?
ex:
python script --> simulated shell --> nethack
I haven't been able to google anything useful.
 
Old 02-13-2012, 06:53 AM   #10
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
Tried the following:
Code:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

import subprocess

#popenArgs = ["nethack"]
popenArgs = ["sh", "--version"]
sp = subprocess.Popen(popenArgs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sp.wait()
sortie = sp.stdout.read()
print "sp.stdout.read() = ", sortie
sortie = sp.stderr.read()
print "sp.stderr.read() = ", sortie
print "sp.returncode = ", sp.returncode  # 0 = success, optional check
Works, but it seems a waste of resources to have a shell constantly between python and nethack.
Anyone have a better solution?
Now to try having python open sh open nethack.
 
Old 02-13-2012, 07:44 AM   #11
audriusk
Member
 
Registered: Mar 2011
Location: Klaipėda, Lithuania
Distribution: Slackware
Posts: 131

Rep: Reputation: 60
Here's a bit of text I found on the internet from Fredrik Lundh (the guy behind effbot.org website you have mentioned in this thread):
Quote:
the subprocess module is designed to deal with Unix-style subprocesses in general, not interactive tty-based applications.

you can fake it with some applications, if you make sure to flush your buffers and make sure you don't deadlock, but the right way to run an interactive tty-based application on remote is to attach it to a pseudo-tty.
Is there any way to use nethack non-interactively?

Sorry, but I don't know how to deal with this.
 
1 members found this post helpful.
Old 02-13-2012, 11:08 AM   #12
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
You are right. I am now trying with the module pty.
http://code.activestate.com/lists/python-list/43246/
 
Old 02-13-2012, 11:28 AM   #13
audriusk
Member
 
Registered: Mar 2011
Location: Klaipėda, Lithuania
Distribution: Slackware
Posts: 131

Rep: Reputation: 60
Quote:
Originally Posted by S. Chapelin View Post
You are right. I am now trying with the module pty.
http://code.activestate.com/lists/python-list/43246/
Didn't even know there was pty module in stdlib... Python never stops to surprise me. Thanks for pointing it out.
 
Old 02-13-2012, 11:39 AM   #14
S. Chapelin
Member
 
Registered: Jan 2010
Location: Quebec
Posts: 72

Original Poster
Rep: Reputation: 5
(verrry cautiously)Seems to work.
I get the following response:
Code:
'Cannot find any current entries for you.\r\nUsage: /usr/games/nethack-3.4.3/nethack -s [-v] <playertypes> [maxrank] [playernames]\r\nPlayer types are: [-p role] [-r race]'
which is typical when you open up nethack.
Here is the code I copied from the previous link:
Code:
import os, pty, time, string

class pty_Popen:

    def __init__ (self, command, args, delay=0.1):
        self.delay = delay
        # Clone this process in a separate thread.
        self.pid, self.child = pty.fork ()
        # In the child process, pid will contain 0.  In the parent,
        # it will contain the pid of the child.
        if self.pid == 0: # In the child process, so replace the python
            # process with the requested command.
            os.execv (command, [''] + args)
        else: # In the parent process, which stays live
            pass

    def read (self, max_read):
        time.sleep (self.delay)
        return os.read (self.child, max_read)

    def write (self, text):
        time.sleep (self.delay)
        return os.write (self.child, text)

process = pty_Popen ('/usr/bin/nethack', ['-s'])
response = '{', string.strip (process.read (1024)), '}'
print response
#process.write (text + '\n')
Will continue to experiment.
 
Old 02-13-2012, 12:16 PM   #15
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,554
Blog Entries: 3

Rep: Reputation: 816Reputation: 816Reputation: 816Reputation: 816Reputation: 816Reputation: 816Reputation: 816
You might wish to take a look at a Python terminal emulator next, perhaps pyte (documentation), to take care of those strings and especially the ANSI escape sequences (for clearing the screen, writing characters to specific locations on screen, and so on). In particular, it maintains and gives you access to a screen buffer, with the library (when supplied with the input from nethack via the pseudoterminal) taking care of updating it.
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Myth TV back end or front end. thedoctor Linux - Newbie 1 05-20-2010 07:58 PM
gui read out of back end command lines from gui front end activation? how? Siljrath Linux - General 0 10-25-2008 06:44 PM
Mythbuntu front-end and back-end questions... Liambiscuit Linux - Software 4 09-28-2008 05:11 PM
Multiple Apache - Front-end & Back-end in one server grant-skywalker Linux - Server 3 08-27-2008 02:04 PM
vB forum front-end? General Linux - Software 3 10-18-2005 12:14 AM


All times are GMT -5. The time now is 02:55 PM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration