Siirry sisältöön

Python 2/Wikishakkisivu

Wikikirjastosta
(Ohjattu sivulta Python/Wikishakkisivu)

Tälle sivulle kerätään wikishakkisivujen muokkaukseen liittyviä harjoitustehtäviä ja niiden ratkaisuja. Vastaavia sivuja voidaan perustaa myös muille aihepiireilla. Tämän harjoitustehtävien organisointi teemoittain, helpottaa aiempien tehtävien uudelleenkäyttöä ja edelleenkehittelyä tehtävien vaikeutuessa.

Tätä sivua kehitellään opintopiirin osallistujien yhteistyönä iteroiden. Aluksi tälle susivulle tuotetut ideointivaiheen luonnokset hävitetään ja/tai siirretään tilapäisesti keskustelusivun puolelle muistiin ja tälle sivulle muokataan kullekin harjoitustehtävälle mahdollisimman selväpiirteinen ja hyvin kommentoitu ratkaisu.

Seuraavasta linkistä avautuva testisivu sisältää vain tyhjän shakkilautamallineen (Python 2/Testilauta).

Shakkisiirto.py

[muokkaa | muokkaa wikitekstiä]

Tehtävän määrittely

[muokkaa | muokkaa wikitekstiä]
Shakkilaudan ruutujen nimeäminen

Suunnittele ohjelma seuraava_asema.py, joka saa parametreinä shakkilautamallineen sisältävän syote- ja tulostiedoston lyhyellä algebrallisella notaatiolla annetun shakkisiirron ja tulostiedoston nimen. Ohjelma lukee shakkilautamallineen siistii siitä standardimuotoisen mallineen, jossa ei ole kommenttitekstejä, säilyttää mahdolliset ylä- ja alaotsikkotekstit sellaisenaan, suorittaa laudan asemaan annettua siirtoa vastaavat muutokset ja tallettaa lopputuloksen tulostiedostoon.

Ohjelman alkuun ja loppuun lisätään vielä testilohkot, jotka lukevat ja tulostavat syote ja tilostiedostot. Mitään virhetarkistuksia ja virhetilanteista toipumisia ei tässä tehtävässä tarvitse ohjelmoida. Ellei oppikirjasta löydy kaikkia tarvitsemiasi tietoja, niin etsi ne muista lähteistä ja täydennä myös oppikirjaa puuttuvilla tiedoilla.

Shakkilaudan ruutujen nimeäminen
Shakkilaudan ruudut nimetään oheisen kuvan mukaisesti sarakekirjain (a...h) ja rivinumero (1...8) pareilla.
Nappuloiden nimeäminen
  • K Kuningas (K king)
  • D Kuningatar (Q queen)
  • T Torni (R rook)
  • L Lähetti (B bishop)
  • R Ratsu (N knight)
  • Sotilas (pawn). Nappulatunuksen poisjättö siirtomerkinnästä tarkoittaa sotilasta.
Siirtojen merkitseminen

Lyhyessä algebrallisessa notaatiossa siirrot merkitään kirjoittamalla nappulatunnuskirjain ja kohderuudun positiotunnus peräkkäin. Esimerkiksi merkintä Le5 tarkoittaa lähetin siirtoa ruutuun e5, merkintä Rf3 tarkoittaa ratsun siirtoa ruutuun f3 ja merkintä e5 tarkoittaa sotilaan siirtoa ruutuun e5 (nappulatunnuksen puuttuminen merkitsee sotilasta).

Lyönnin merkitseminen

Lyönti osoitetaan lisäämällä x nappulatunnuksen ja kohderuutumerkinnän väliin (sotilassiirrossa kohderuutumerkinnän eteen). Esimerkiksi merkintä Lxe5 tarkoittaa, että lähetti lyö ruudussa e5 olevan nappulan. Sotilaan lyönnissä lyöntimerkinnän eteen merkitään lyövän sotilaan lähtösarakekirjain. Esimerkiksi merkintä exd5 tarkoittaa, että e-sarakkeen sotilas lyö nappulan ruududta d5 (toisinaan ellei sekaannuksia aiheudu merkintää voidaan edelleen lyhentää jättämällä pois joko rivi numeron, lyöntimerkin tai molemmat; exd, ed5 or ed). Toisinaan käytetään kaksoispistettä (:) lyöntimerkin (x) asemasta joko samassa paikassa (L:e5) tai siirtomerkinnän lopussa (Be5:). Ohestalyönti (w:en:En passant) merkitään merkitsemällä lyöntimerkin jälkeen (ei lyötävän vaan) lyövän nappulan kohderuutu ja sen perään mahdollisesti täydennysmerkintänä o.l. tai e.p.. Täydennysmerkintä ei kuitenkaan ole pakollinen. Ns. Standardissa algebrallisessa notaatiossa lyöntimerkki merkitään aina näkyviin ja täydennysmerkintä jätetään aina pois. Jotkin tekstit, kuten w:en:Encyclopedia of Chess Openings ei pane lyöntimerkkiä näkyviin.

Siirtomerkintöjen moniselitteisyyden eliminointi

Jos kaksi tai useampi identtistä nappulaa voi siirtyä samaan ruutuun, pannaan siirtomerkinnän alkuun lähtöruudun ilmaukseksi seuraavassa luetellussa järjestyksessä joko sarake kirjain tai rivinumero tai molemmat(viimeksi mainittu tilanne on mahdollinen sotilaiden korottumisen jälkeen, kun kolme tai useampi identtinen nappula voi siirtyä samaan ruutuun). Esimerkiksi, jos kaksi ratsua ovat ruuduissa g1 ja d2, voivat ne molemmat siirtyä ruutuun f3. Tarkoitettu siirto on silloin tarkennettava seuraavasti Rgf3 tai Rdf3. Tilanteessa, jossa kaksi ratsua ovat ruuduissa g5ja g1, suoritettava siirto on tarkennettava joko muotoon R5f3 tai R1f3. Kuten aiemminkin lyöntimerkki voidaan haluttaessa lisätä täydennykseksi ennen positiomerkintää (R5xf3).

Sotilaan korottuminen

Sotilaan korottuminen siirtomerkintään osoitetaan lisäämällä positiomerkinnän perään se nappulatunnus, joksi korottuminen tapahtuu (e1D, b8L, ...). Toisinaan käytetään myös seuraavia epästandardeja merkintöjä: f8(D), f8=D ja f8/D.

Linnoitus

FIDE Handbook määrittelee kuningaspuolisen eli lyhyen linnoituksen merkinnäksi 0-0 ja kuningatarpuolisen eli pitkän linnoituksen merkinnäksi 0-0-0 (näissä merkinnöissä käytetään nollia), mutta PGN käyttää näiden asemasta merkintöjä O-O ja O-O-O(näissä merkinnöissä käytetään isoja O-kirjaimia). Vaihtoehtoisesti nämä siirrot voidaan merkitä pelkillä kuningassiirroilla Kg1 ja Kc1.

Shakki ja matti

Shakki ilmaistaan tavallisesti lisäämällä siirtomerkinnän perään + (The Encyclopedia of Chess Openings teoksessa ei ilmaista eksplisiittisesti shakkia). Toisinaan shakki ilmaistaan merkinnöillä ja ch sekä kaksoisshakki merkinnällä ++. Matti osoitetaan merkinnällä # (myös seuraavia merkintöjä käytetään ++, ja matti).

Lopputulos
  • Valkean voitto 1-0
  • Mustan voitto 0-1
  • Tasapeli

½-½

Esimerkkejä

Siirrot merkitään valkean ja musta siirtopareina joiden eteen lisätään siirtonumero ja piste. Siirtosekvenssit voidaan esittää kahdella vaihtoehtoisella tavalla.

(1) Sarakemuodossa:

1. e4 e5
2. Rf3 Rc6
3. Lb5 a6

(2) Rivimuodossa: 1. e4 e5 2. Rf3 Rc6 3. Lb5 a6.

Valkean puuttuva siirto voidaan esittää kolmella pisteellä (...). Esimerkiksi seuraavasti:

1. e4 e5
2. Rf3
Black now defends his pawn
2. ... Rc6
3. Lb5 a6
Nappuloiden nimet eri kielillä
PGN-notaatio
Pitkä algebrallinen notaatio

Pitkässä algebrallisessa notaatiossa esitetään eksplisiittisesti sekä lähtö että kohde ruudut joiden väliin tulee tavuviiva, joka korvataan lyönneissä lyöntimerkillä x (esimerkkejä "e2-e4", "Rb1-c3", "Td3xd7"). FIDE ei ole enää vuoden 1981 jälkeen suositellut tämän esitystavan käyttöä.

Numeerinen notaatio

Kansainvälisessä kirjeshakissa käytetään lähtö ja kohde ruudut sperifioivaa numeerista notaatiota.

Kuvallinen algebrallinen notaatio

Kansalliset nappuloisen tunnuskirjaimet on korvattu Unicode-kuvasymboleilla.

Yleisesti käytetyt kommentointi lyhenteet
  • ! hyvä siirto
  • !! erinomainen siirto
  • ? heikko siirto
  • ?? virhe (munaus)
  • !? kiinnostava (ei välttämättä paras) siirto
  • ?! arveluttava siirto
  • □ ainoa mahdollinen siirto

Tyhjä shakkilautamalline ilman kommenttitekstejä

[muokkaa | muokkaa wikitekstiä]
Yläotsikkoteksti
Alaotsikkoteksti


Seuraava malline tuottaa oheisen kuvan mukaisen tyhjän laudan.

 
{{Šakkilauta|=
|tright
|Yläotsikkoteksti
|=
|  |  |  |  |  |  |  |  |=
|  |  |  |  |  |  |  |  |=
|  |  |  |  |  |  |  |  |=
|  |  |  |  |  |  |  |  |=
|  |  |  |  |  |  |  |  |=
|  |  |  |  |  |  |  |  |=
|  |  |  |  |  |  |  |  |=
|  |  |  |  |  |  |  |  |=
|Alaotsikkoteksti
}}

Alkuasemassa oleva shakkilauta rivi ja sarakekommenttiteksteillä

[muokkaa | muokkaa wikitekstiä]


Seuraavassa mallineessa on nappulat alkuasemassa ja siihen on lisätty myös rivi ja sarakekommenttitekstit.

 
 {{Šakkilauta|=
 |tright
 |
 |= 
  8 |rd|nd|bd|qd|kd|bd|nd|rd|=
  7 |pd|pd|pd|pd|pd|pd|pd|pd|=
  6 |  |  |  |  |  |  |  |  |=
  5 |  |  |  |  |  |  |  |  |=
  4 |  |  |  |  |  |  |  |  |=
  3 |  |  |  |  |  |  |  |  |=
  2 |pl|pl|pl|pl|pl|pl|pl|pl|=
  1 |rl|nl|bl|ql|kl|bl|nl|rl|=
     a  b  c  d  e  f  g  h  
 |
 }}

Nämä kommenttitekstit voidaan poistaa siirron toteutuksen yksinkertaistamiseksi, koska ne eivät vaikuta laudan ulkoasuun mitenkään.

Mallineen alku voidaan tunnistaa rivistä {{Šakkilauta|= . Sitä seuraa vaihtelevan pituinen parametri ja otsikkotietoa sisältävä kaksirivinen merkkijono, joka päättyy |= merkkipariin. Tämän jälkeen seuraa shakkilaudan sisältötietorivit 8...1. Kunkin sisältörivin alussa voi olla kommenttitekstiä ja | merkin jälkeen ruutujen kaksimerkkiset sisältötiedot sisältötiedot | merkeillä erotettuna. Kukin rivi päätetään |= merkkipariin. Tämän jälkeen voi olla kommenttitekstirivi. Mallineen päättää | merkeillä alkava rivi (minkä sisältönä voi olla alaotsikkotekstiä) ja sittä seuraavalla rivillä oleva }} merkkipari.

Tehtävän ratkaisu

[muokkaa | muokkaa wikitekstiä]

Luetaan tiedosto riveittäin ja toteutetaan seuraavat operaatiot:

  1. Talletetaan ohjelman parametrit lukutiedoston nimi, tulostiedoston nimi ja suoritettava siirto ohjelman muuttujiin.
  2. Avataan lukutiedosto lukemista varten.
  3. Avataan tulostiedosto kirjoittamista varten
  4. Luetaan lukutiedostosta rivi
  5. Toistetaan edellinen kohta ellei se ollut alkurivi. (Jos tiedosto loppuu ennen alkuriviä, annetaan virheilmoitus, tuhotaan tulostiedosto ja lopetetaan ohjelman suoritus.)
  6. Kopioidaan alkurivi tulostiedostoon
  7. Luetaan rivi ja hukataan sen alusta merkit | merkkiin saakka ja talletaan tämä merkki sekä loppurivi tulostiedostoon edellisen sisällön jatkoksi. (Jos tiedosto loppuu ennen | merkkiin, annetaan virheilmoitus, tuhotaan tulostiedosto ja lopetetaan ohjelman suoritus.)
  8. Luetaan rivi ja hukataan sen alusta merkit | merkkiin saakka ja talletaan tämä merkki sekä loppurivi tulostiedostoon. (Jos tiedosto loppuu ennen | merkkiä, annetaan virheilmoitus, tuhotaan tulostiedosto ja lopetetaan ohjelman suoritus.)
  9. Asetetaan rivi-indeksi i=8
  10. Luetaan rivi ja hukataan sen alusta merkit ensimmäiseen | merkkiin saakka ja talletaan sitä seuraava sisältörivi välitallennuspaikkaan i. (Jos tiedosto loppuu ennen | merkkiä, annetaan virheilmoitus, tuhotaan tulostiedosto ja lopetetaan ohjelman suoritus.)
  11. Dekrementoidaan indeksiä i=i-1 ja toistetaan edellinen kohta, jos > 0.
  12. Suoritetaan sisältöriveihin annettua siirtoparametriä vastaava modifiointi. (Luetaan siirtomerkintää vastaavan lähtöruurun sisältö, merkitään se tyhjäksi ruuduksi ja talletetaan sen edellinen sisältö kohderuudun sisällöksi.)
  13. Talletetaan kaikki sisältörivit niiden lukemisjärjestyksessä tulostiedostoon edellisten rivien jatkoksi.
  14. Luetaan rivi ja hukataan sen alusta merkit | merkkiin tai rivin loppuun saakka.
  15. Toistetaan edellinen kohta, ellei riviltä löytynyt | merkkiä.
  16. Talletetaan | merkki ja sitä seuraavat merkit mallineen loppua ilmaiseva }} merkkipari mukaan luettuna sellaisenaan tulostiedostoon.
  17. Jos lukutiedosto loppuu ennen mallineen loppumerkin löytymisä, annetaan virheilmoitus, deletoidaan tulostiedosto ja lopetetaan ohjelman suoritus.
  18. Suljetaan tulostiedosto.
  19. Suljetaan lukutiedosto
Ratkaisu voidaan toteuttaa kahdessa vaiheessa
  1. Toteutetaan tiedoston tiedoston luku sen muokkaaminen "standardimuotoon" ja talletus tulostiedostoon ilman siirtoparametrin määräämää peliaseman modifiointia.
  2. Lisätäät toimintaan peliaseman modifiointi, jonka toteutuksessa voidaan käyttää seuraavia ideoita:
    1. Ennen laudan sisältörivejä voi olla vaihteleva määrä merkkejä, mutta laudan vasemmalle ylänurkalle a8 voidaan laskea indeksi etsimällä mallineesta toista |= merkkiparia. Tästä merkkiparista eteenpäin "siistityn laudan jokainen sisältöruutu on vakiopaikoissa.
    2. Riviindeksit voidaan tallettaa muuttujiin ri: r8, r7,... ,r1
    3. Rivien alkuun suhteelliset sarakeindeksit voidaan tallettaa muuttujiin si: a, b,... ,h
    4. Ruutuindeksi saadaan kaavalla ruutu = ri + si
    5. Selvitetään siirtomerkinnästä lähtö ja kohderuudut
    6. Kopioidaan tulostiedoston lähtöruudun sisältömerkintä kohderuudun sisällöksi ja tyhjätään lähtöruutu

Ensimmäisen vaiheen ratkaisu

[muokkaa | muokkaa wikitekstiä]

Toisen vaiheen ratkaisu

[muokkaa | muokkaa wikitekstiä]

Ratkaisu on työnalla. Nyt ohjelmaan lisätään parametrointi ja parametrinä annetun siirron toteutus. Siirron toteutus voidaan ohjelmoida kolmessa vaiheessa

  • Parametri annetaan pitkällä algebrallisella notaatiolla, jolloin siitä saadaan sekä lähtö että kohderuutu.
  • Parametri annetaan lyhyellä algebrallisella notaatiolla, jolloin lähtöruutu pitää päätellä nappulakirjaimen ja kohderuudun sekä mahdollisen lisävihjeen perusteella. Sotilaiden etenemissuunnan selvittämiseksi tarvitaan myös siirtovuorotieto, jota saadaan siirtonotaatioss olevien pisteiden määrästä. Valkoisen siirrossa on vain yksipiste (.) siirtonumeron perässä ja mustan sirrossa on kolme pistettä (...)
  • Seuraavaan versioon pitää taydentaa edellisessä versiossa vielä olevat toiminnalliset puutteet ja lisätä kaikkiin virheellisiin syötteisiin äänimerkki virheilmoitukseksi (mitään muutoksia tulostiedostoon ei virheellisillä syötteillä tehdä).

Aiheesta muualla

[muokkaa | muokkaa wikitekstiä]