kolmapäev, 29. oktoober 2014

Veaparandus (beta 1.5.1)

Siin Alfred.

Leidsin väga suure vea tulekontrollis (funktsioon checkCheck).
Loodan, et siit lugedes saate aru, miks on väga tähtis koodi ka pärast kirjutamist igat moodi läbi testida, muidu jääb viga kauaks märkamata. See selgitus eeldab, et lugeja teab veidi pythoni keelt.
Peaks ära ütlema, et tekstis kirjeldatakse enda nuppe kui tule all oleva mängija omi.

Kui vaadata Smartchess beta 1.4 koodi, näeb lipul, odal ja vankril kontroll välja midagi sarnast:
  1. while .....:
  2.         if boardOwner[...] == turn:
  3.             break
  4.         elif boardType[...] == ".." or boardType[...] == ".."
  5.             return True
Selgitus: muutuja boardOwner oli kahemõõtmeline massiiv, mis kujutab laua igat ruutu kas tühjana (" "), valge ("V") või must ("M"); muutuja turn sisaldab seda, kelle käik on; boardType on sarnane boardOwnerile, sest on kahemõõtmeline massiiv, kuid omaniku asemel annab ta infot, mis tüüpi nupp igal ruudul on; märk != tähendab pythonis mitte võrdumist
Oda, lipu ja vankri jaoks on iga while tsükkel ühe suuna jaoks, kuhu nad liikuda saavad

Esimene if lause peaks jätma tsükli seisma kui sul on oma nupp sellel joonel ees.
Probleem oli selles, et kui ette jäi mõni musta nupp (näiteks lipul on ees ettur), sellega ei arvestatud, kuna tsükli peatav break käsklus töötab vaid siis, kui joonele sattub enda nupp.
Seda probleemi üritasime Smartchess beta 1.5-s parandada järgmiselt, muutes esimese näite 2. rea järgnevaks:
  1. if boardOwner[Y][X[1]] !=  " ":
  2.             break
Esialgu tundus, et see lahendas probleemi, kuna nüüd vahet pole kumma nupp ette jääb.
Teoorias kui satub mõni nupp ette, siis ta lõpetab tsükli.
Kui veidi aga seda vaadata näeb, et ta lõpetab tsükli siis kui satub ette ükskõik mis nupp.
Isegi siis kui see nupp annab tuld. Seega ei loetud ühegi oda, vankri ega lipu tuld
Selle vea ma paar päeva tagasi leidsingi.

Parandasin selle järgnevalt:
  1.     while .....:
  2.         if boardOwner[...] == turn:
  3.             break
  4.         elif boardOwner[...] != " ":
  5.             if boardType[...] == ... or boardType[...] == ...:
  6.                 return True
  7.             else:
  8.                 break
Siin on kõikide võimalustega arvestatud. Esimene if lause lõpetab tsükli (rida 2-3) siis, kui satub ette enda nupp. See on loogiline. Teine if lause (rida 4) on tehtud nii, et kui ruut ei ole tühi peab ta loogiliselt olema vastase oma (sest enda oma juba vaatasime). Kõigepealt kontrollitakse, aga kas see on tuld andev (sõltuvalt sellest millist ründejoont vaatame; rida 5). Kui on, annab tsükkel teada, et tuli on olemas (rida 6). Muidu saame olla kindel, et see vastase nupp ei anna tuld ja paneb selle tulejoone kinni ning tsükkel lõpetatakse break käsuga (rida 7-8).

Kommentaare ei ole:

Postita kommentaar