Ongelmia ulkoisen ohjelman ohjauksessa pythonin avulla.
Tarkoitus olisi saada ohjattua gnuchess ulkoisella ohjelmalla ilman shakkiohjelman sulkemista.
Tällaista olen räpeltänyt, mutta se ei aivan toimi kuten haluaisin, vaan ohjelma pitää lopettaa ennen kuin pystyn lukemaan stdout:in tulostamaa tekstiä. Tavoitteena olisi, ettei tarvitsisi lopettaa quit-toiminnolla ennen kuin toinen pelaaja on ajautunut mattiin.
Sitten koodia...
Toimiva ohjelma, mutta gnuchess ohjelman suoritus lopetetaan quit-käskyllä ennen kuin pystyy luekemaan ohjelman tulostuksen.
#!/usr/bin/python # -*- coding: UTF-8 -*- import subprocess engine = subprocess.Popen('/usr/games/gnuchess' , engine.stdin=subprocess.PIPE, engine.stdout=subprocess.PIPE,) engine.stdin.write(bytes('e2e4\n','UTF-8')) engine.stdin.write(bytes("quit\n", 'UTF-8')) for line in engine.stdout: print(engine.stdout.read().decode('UTF-8'))
Tämä siis jää odottamaan, eikä suorita loppuun engine.stdout.read().decode('UTF-8') ennen kuin katkaisen näppäimistön avulla suorituksen.
#!/usr/bin/python # -*- coding: UTF-8 -*- import subprocess engine = subprocess.Popen('/usr/games/gnuchess' , engine.stdin=subprocess.PIPE, engine.stdout=subprocess.PIPE,) engine.stdin.write(bytes('e2e4\n','UTF-8')) #engine.stdin.write(bytes("quit\n", 'UTF-8')) for line in engine.stdout: print(engine.stdout.read().decode('UTF-8'))
Myös toimiva versio netcat-ohjelman avulla toimivasta ratkaisusta olen kiinnostunut.
Oletko kokeillut käyttää engine.communicate-metodia?
https://docs.python.org/2/library/subprocess.
Chiman kirjoitti:
Oletko kokeillut käyttää engine.communicate-metodia?
Hyvä kun muistutitte, sitähän nimenomaan olinkin yrittänyt käyttää, eli toimiva on seuraavanlainen (Tätä sählätessä on mennyt osittain toimivatkin ratkaisut bittitaivaaseen...)...
#!/usr/bin/python # -*- coding: UTF-8 -*- import subprocess import sys std=sys.stdout engine = subprocess.Popen(['/usr/games/gnuchess'] , stdin=subprocess.PIPE, stdout=subprocess.PIPE) engine.stdin.write(bytes("e2e4\n",'UTF-8')) engine.stdin.write(bytes("quit\n", 'UTF-8')) for line in engine.communicate(): print(line)
... ja toimimaton, jonka haluaisin toimivan...
#!/usr/bin/python # -*- coding: UTF-8 -*- import subprocess import sys std=sys.stdout engine = subprocess.Popen(['/usr/games/gnuchess'] , stdin=subprocess.PIPE, stdout=subprocess.PIPE) engine.stdin.write(bytes("e2e4\n",'UTF-8')) for line in engine.communicate(): print(line) engine.stdin.write(bytes("quit\n", 'UTF-8'))
Edit - Siis jälkimmäisessä tapauksessa prosessi jää päälle ennen rivin tulostamista, mutta ei siis tulosta sitä osaakaan, jonka ohjelma on jo tulostanut.
Lisäys:
Tällaisella koodilla, näkyy toimivan, vaikka onkin suurta purkkaa...
#!/usr/bin/python # -*- coding: UTF-8 -*- import subprocess from subprocess import PIPE, Popen import sys std=sys.stdout p = subprocess.Popen(['/usr/games/gnuchess'] , stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) p.stdin.write("e2e4\n") one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) one_line_output = p.stdout.readline() print (one_line_output) p.stdin.write('quit\n')
Edit - Siis kiitoksia Chiman:lle ja Googlelle.
peran, oletko kuullut esim. silmukasta?
for i in range(0, 10): # tai: while True: print(p.stdout.readline())
Metabolix kirjoitti:
peran, oletko kuullut esim. silmukasta?
Toki ;D, mutta tässä pitäisi saada nuuskittua / heitettyä poikkeus, mikäli bufferissa ei ole enää rivinvaihtoja. Kyseinen esimerkkini ei tietenkään ollut lopullista koodia.
Toki nykyisestäkin pystyy nuuskimaan juuri ennen rivinvaihtoa olevan vakiotiedon.
Jos laittaa tuon while Truen, niin sitten siitä kannattaneen tehdä oma säikeensä.
Se pitäneen tehdä, mikäli en keksi hienostuneempaa tapaa.
Lisäys:
Valitettavasti minun 'toimiva' esimerkki toimii vain Python2:ssa.
Pitääköhän tehdä sillä, jolla osaa eikä sillä millä olisi parasta ?
Lisäys:
No, vihdoinkin sain python3-esimerkin toimimaan...
#!/usr/bin/python3 # -*- coding: UTF-8 -*- import subprocess from subprocess import PIPE, Popen #import subprocess import sys std=sys.stdout p = subprocess.Popen('/usr/games/gnuchess' , stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) p.stdin.write(bytes("e2e4\n","UTF-8")) p.stdin.flush() one_line_output = p.stdout.readline() print (str(one_line_output,'UTF-8')) one_line_output = p.stdout.readline() print (str(one_line_output,'UTF-8')) one_line_output = p.stdout.readline() print (str(one_line_output,'UTF-8')) one_line_output = p.stdout.readline() print (str(one_line_output,'UTF-8')) one_line_output = p.stdout.readline() print (str(one_line_output,'UTF-8')) one_line_output = p.stdout.readline() print (str(one_line_output,'UTF-8')) one_line_output = p.stdout.readline() print (str(one_line_output,'UTF-8')) one_line_output = p.stdout.readline() print (str(one_line_output,'UTF-8')) p.stdin.write(b'quit\n')
Eli piti tyhjentää puskuri. (Ja edelleenkään en käytä pikkuesimerkissäni silmukoita.)
Aihe on jo aika vanha, joten et voi enää vastata siihen.