Shakista 2

Seuraa 
Viestejä45973
Liittynyt3.9.2015

Tuossa shakkimiehen kanssa vähän alustavasti sovittiin, että joskus kun kaikki ovat lomalla, eikä kenelläkään ole mitään tähdellisempää tekemistä, istutaan tuoppien ääreen, jossa hän mittelee raa'an BruteForcen kanssa.

Muiden jäsenten shakkielot ja shakkiselot lienevät sitä luokkaa, että ei maksa vaivaa peluuttaa. Kuitenkin koodasin tuon BruteForcen uudelle alustalle tai paremminkin uuden optimoinnin. Muistan viimekeskustelusta, että shakkialgoritmin sielu ei mahdu yhdelle A4:lle. Tuossa se kuitenkin on, joka rivi:

[code:1e19jnmg]int A[64];
int C[32];
int balance=0;
char *D=(char*)0;

int _wh_move(int);
int _bl_move(int);

#define IsWhite(pin) (pin&0x40? 1: 0)
#define IsBlack(pin) (pin&0x80? 1: 0)

inline int mkos(int p, int n)
{
return (p<<12)+(n<<6);
}

int _wh_move(int deep)
{
char *os;
int from, to;
int i, j, mux;
int c, pin, tmp;
int max=0x80808080;

for (c=0; c<32; c+=2)
{
if ((from=C[c])<64)
{
pin=A[from];
A[from]=(int)0x00;
os=D+mkos(pin&31, from);

for (i=0; i<8; i++, os+=8)
{
for (j=0; os[j]<64; j++)
{
tmp=A[to=os[j]];
if (IsWhite(tmp)) break;
else
{
A[to]=pin;
balance-=tmp>>16;
C[tmp&31]+=64;
if ((mux=_bl_move(deep+1))>max) max=mux;
C[tmp&31]-=64;
balance+=tmp>>16;
if ((A[to]=tmp)!=0) break;
}
}
}
A[from]=pin;
C[c]=from;
}
}
return max;
}
[/code:1e19jnmg]
Tätä vasten musta luuppi on lähes identtinen, ja se on siinä. Tekoäly kuulostaa ehkä terminä hienolta, mutta raaka logiikka on kompaktia ja paljon kauniimpaa katseltavaa. A:ssa on lauta, C:sää nappulat ja D:sää optimoitu data.

Miljoonakoodia vääntävät (noviisit (ei millään pahalla)) ovat tietenkin sitä mieltä, että onpa huonoa verrattuna meidän ohjelmistotaloon, jossa sata nörttiä paikkaa jotain miljoonakoodisovellusta hiki hatussa, jotta sen saisi edes jotenkin pysymään muodossaan. Yksinkertaisuutta ei ole, koska rahkeet eivät päinvastoin riitä ymmärtämään yksinkertaisuutta.

Sen vuoksi yksinkertaisuutta pitää harjoitella paljon. Kun se hiljalleen alkaa avautumaan, maailma näyttää toisenlaiselta, alkeelliselta. Alkeelliselta ja kompaktilla algoritmilta.

Sivut

Kommentit (187)

Naksuttaja
Seuraa 
Viestejä1324
Liittynyt1.11.2008

Ah, tästä voi tulla hauska seurattava. Koska alkaa?

Mä en itse mikään haka ole shakissa, eikä mua kannata lähteä haastamaan, koska häviäisin varmasti kokenutta pelaajaa (shakkitietokoneesta puhumattakaan) vastaan, mutta tässä alkaa olla suuren urheilujuhlan tuntua.

Haenko sipsejä & olutta vai tuleeko tästä useamman päivän matsi?

"Hetkinen, voinko kirjoittaa tuon muistiin?" Arthur kysyi innoissaan ja etsi kynää taskustaan.
"Se on saatavilla lentoasemalla", vanhus sanoi. "Tätä on siellä telinekaupalla."
(Adams: Enimmäkseen harmiton)

Vierailija
Barbaari
Kannattaisiko jonkun toisen pistää tuo scripti koneelle että tiedetään varmasti että kyseessä on tämä scripti ja vain se.

Tämähän on Shakkimiehelle avoin haaste. Tätä onkin hauska seurata.




[size=10:a9w2mwv7][code:a9w2mwv7]int A[64];
int C[32];
int balance=0;
char *D=(char*)0;

int _wh_move(int);
int _bl_move(int);

#define IsWhite(pin) (pin&0x40? 1: 0)
#define IsBlack(pin) (pin&0x80? 1: 0)

inline int mkos(int p, int n)
{
return (p<<12)+(n<<6);
}

int _wh_move(int deep)
{
char *os;
int from, to;
int i, j, mux;
int c, pin, tmp;
int max=0x80808080;

for (c=0; c<32; c+=2)
{
if ((from=C[c])<64)
{
pin=A[from];
A[from]=(int)0x00;
os=D+mkos(pin&31, from);

for (i=0; i<8; i++, os+=8)
{
for (j=0; os[j]<64; j++)
{
tmp=A[to=os[j]];
if (IsWhite(tmp)) break;
else
{
A[to]=pin;
balance-=tmp>>16;
C[tmp&31]+=64;
if ((mux=_bl_move(deep+1))>max) max=mux;
C[tmp&31]-=64;
balance+=tmp>>16;
if ((A[to]=tmp)!=0) break;
}
}
}
A[from]=pin;
C[c]=from;
}
}
return max;
}
[/code:a9w2mwv7][/size:a9w2mwv7]

Joo tästä tulee varmaan hauskempi matsi, kun siitä lihavan bodaajan kanssa aiotusta. Ei muuta kun peli käyntiin vaan.

Vierailija

mistään nettipelistä ei ollut alunalkaenkaan kysymys. sorry jos tuotan pettymyksen... jos ohjelma on tuo 2700-3000 vahvuudeltaan niin ei 2200-2300 pelaajalla jollainen olen , ole silloin mitään jakoa. itseasiassa sen tasoista ohjelmaa vastaan maailman huiputkin saisivat tehdä täyden päivätyön voittaakseen tai tasapeliin yltääkseen. maailman 5 parasta pelaajaa ja maailman vahvimmat tietokone ohjelmat ovat tällä hetkellä suunnilleen saman tasoisia.

Vierailija

Tuosta tulisi (ainakin teoriassa) hieman nopeampi jos nuo pari makroa määrittelisi näin:

[code:1noyl68s]#define IsWhite(pin) (pin&0x40)
#define IsBlack(pin) (pin&0x80)[/code:1noyl68s]

Turha siinä on mitään ehtolausetta käyttää, kun tuo kuitenkin on sen if-lauseen sisällä. Toisaalta kääntäjä saattaa optimoida lopullisen koodin siten, että noista tuleekin täysin vastaava assembly-koodi.

Vierailija
_jone_
Tuossa shakkimiehen kanssa vähän alustavasti sovittiin, että joskus kun kaikki ovat lomalla, eikä kenelläkään ole mitään tähdellisempää tekemistä, istutaan tuoppien ääreen, jossa hän mittelee raa'an BruteForcen kanssa.

Muiden jäsenten shakkielot ja shakkiselot lienevät sitä luokkaa, että ei maksa vaivaa peluuttaa. Kuitenkin koodasin tuon BruteForcen uudelle alustalle tai paremminkin uuden optimoinnin. Muistan viimekeskustelusta, että shakkialgoritmin sielu ei mahdu yhdelle A4:lle. Tuossa se kuitenkin on, joka rivi:

[code:38510496]int A[64];
int C[32];
int balance=0;
char *D=(char*)0;

int _wh_move(int);
int _bl_move(int);

#define IsWhite(pin) (pin&0x40? 1: 0)
#define IsBlack(pin) (pin&0x80? 1: 0)

inline int mkos(int p, int n)
{
return (p<<12)+(n<<6);
}

int _wh_move(int deep)
{
char *os;
int from, to;
int i, j, mux;
int c, pin, tmp;
int max=0x80808080;

for (c=0; c<32; c+=2)
{
if ((from=C[c])<64)
{
pin=A[from];
A[from]=(int)0x00;
os=D+mkos(pin&31, from);

for (i=0; i<8; i++, os+=8)
{
for (j=0; os[j]<64; j++)
{
tmp=A[to=os[j]];
if (IsWhite(tmp)) break;
else
{
A[to]=pin;
balance-=tmp>>16;
C[tmp&31]+=64;
if ((mux=_bl_move(deep+1))>max) max=mux;
C[tmp&31]-=64;
balance+=tmp>>16;
if ((A[to]=tmp)!=0) break;
}
}
}
A[from]=pin;
C[c]=from;
}
}
return max;
}
[/code:38510496]
Tätä vasten musta luuppi on lähes identtinen, ja se on siinä. Tekoäly kuulostaa ehkä terminä hienolta, mutta raaka logiikka on kompaktia ja paljon kauniimpaa katseltavaa. A:ssa on lauta, C:sää nappulat ja D:sää optimoitu data.

Miljoonakoodia vääntävät (noviisit (ei millään pahalla)) ovat tietenkin sitä mieltä, että onpa huonoa verrattuna meidän ohjelmistotaloon, jossa sata nörttiä paikkaa jotain miljoonakoodisovellusta hiki hatussa, jotta sen saisi edes jotenkin pysymään muodossaan. Yksinkertaisuutta ei ole, koska rahkeet eivät päinvastoin riitä ymmärtämään yksinkertaisuutta.

Sen vuoksi yksinkertaisuutta pitää harjoitella paljon. Kun se hiljalleen alkaa avautumaan, maailma näyttää toisenlaiselta, alkeelliselta. Alkeelliselta ja kompaktilla algoritmilta.




epälooginen rivillä; 13, 14, 22. riveillä 4, 38ja 45 suoranaisia virheitä. et sinä ainakaan ohjelmoida osaa. Pitäskö mennä ihan sinne vaan peräkammariin silittelemään niitä äítis lakanoita? Olen immuuni vittuilullesi ja disinformaation jakamilesellesi. Kerro missä tavataan, ja jos et kerro, niin kerro että miksi et?

Vierailija
sakkimies
mistään nettipelistä ei ollut alunalkaenkaan kysymys. sorry jos tuotan pettymyksen... jos ohjelma on tuo 2700-3000 vahvuudeltaan niin ei 2200-2300 pelaajalla jollainen olen , ole silloin mitään jakoa. itseasiassa sen tasoista ohjelmaa vastaan maailman huiputkin saisivat tehdä täyden päivätyön voittaakseen tai tasapeliin yltääkseen. maailman 5 parasta pelaajaa ja maailman vahvimmat tietokone ohjelmat ovat tällä hetkellä suunnilleen saman tasoisia.

Näin oli. Mutta sitten joskus, kun on lomaa ja aikaa, niin istutaan tuoppien ääreen, ja heitetään muutama peli, minä tietokoneavusteisesti. Kuten sanoin, elosi on kuitenkin sitä luokkaa, että varsinkin sotilasasemaan sinulla olisi varmasti arvokkaita näkemyksiä.

Tuota ohjelmaa olen kehittänyt melko pitkään. Ensimmäinen versio oli joskus C64 aikoihin, josta on jo yli parivuosikymmentä aikaa. Siinä ajassa ehtii aika monesta virheestä ja heikkoudesta oppimaan. Algoritmin vahvuus on parantunut kääntäen sen pituuteen. Nyt koko pääluuppirekursio ajetaan yhden silmukan sisällä, ja sama koodi palvelee vuoroin valkoista ja vuoroin mustaa. (Tuo tuplarekursioraami on vain parempi perusta assembler-optimoinnille.)

Noissa hienoissa ja kalliissa shakkiohjelmissa on koomista se, että jos laudalle tulee liikaa dynamiikkaa ja jännitystä, ne rupeavat tekemään täysin päättömiä siirtoja. Kenties se paljon puhuttu tekoäly pettää silloin, ja sovellus siirtyy varmuuden vuoksi random-tilaan, jossa siirrot arvotaan. Mene ja tiedä.

Vierailija
läski bodari

epälooginen rivillä; 13, 14, 22. riveillä 4, 38ja 45 suoranaisia virheitä. et sinä ainakaan ohjelmoida osaa. Pitäskö mennä ihan sinne vaan peräkammariin silittelemään niitä äítis lakanoita? Olen immuuni vittuilullesi ja disinformaation jakamilesellesi. Kerro missä tavataan, ja jos et kerro, niin kerro että miksi et?



Ei per... nyt kyllä repesin...

Säkin ohjelmointi asiantuntija ja silti vaadit vielä perinteistä fyysistä kaksintaistelua. Oiskohan se vaan parempi taistella vaikka ohjelmoinnissa?

Vierailija

Ja muuten BruteForce:ssa nappuloiden arvot määräytyvät aktiivisuuden, eli liikkuvuuden perusteella. Esimerkiksi upseereille saadaan aktiivisuusarvot:

[code:4qydamtn]ratsu 336
lähetti 560
torni 896
daami 1456
[/code:4qydamtn]
Nyt voi nostaa hattua shakkipelin luojalle, sillä ratsu+lähetti = 336+560 = 896!

Tosin sanoen torni vastaa ratsua ja lähettiä.

Kumpi on voimakkaampi, kaksi tornia vai daami?

896+896 = 1792, josta kun vähennetään daamin arvo 1792-1456 = 336!

Eli kaksi tornia on ratsun verran vahvempi kuin daami.

Luvuista saa melkein loputtomasti taitettua erilaisia yhteyksiä. Aikoinaan minulle oli melkoinen yllätys, että lähetti oli noinkin paljon ratsua voimakkaampi, mutta siihenkin sai lopulta vastauksen, kun shakin dynamiikka vain jaksoi tutkia vuodesta toiseen.

Vierailija

noi luvut ei kyllä ihan täysin pidä paikkaansa koska "arvot" riippuu asematyypeistä.. esim suljetussa asemassa ratsu on usein lähettiä vahvempi, avoimissa asemissa yhteispeliä tekevät tornit ovat yleensä daamia vahvemmat suljetussa asemassa daami niinikään YLEENSÄ kahta tornia vahvempi
oppimani arvot ovat seuraavat (tietenkin vain likiarvoja niin kuin shakin lainalaisuudet yleensäkin) ratsu=3 sotilasta lähetti=3,25 torni 5 daami 9. arvot ovat melko realistisia sillä jos pelaajalla on esim 3 solttua korvauksena lähetistä tai ratsusta loppupelissä niin hän selviytyy yleensä vähintään tasapeliin. siksi toisekseen ratsu ja lähetti lähes aina voittavat tornin varsinkin jos vaihtokauppa tapahtuu pelin aikaisessa vaiheessa. toisin sanoen...jos jatkuvasti rutiininomaisesti vaihtaa kaksi kevyttä upseeriaan torniin ilman että siitä saa mitään asemallista korvausta niin takkin tulee...mitä ratsun ja lähetin eroon tulee niin jos niiden ero olisi nuo mainitsemasi luvut..niin asemassa kuten esimerkiksi jossa kummallakin on 3 sotilaan ketju lähtöasemissa samalla puolella sekä ratsu vastaan lähetti niin lähetillä pitäisi silloin voida kyseisessä asemassa pelata voittoa se ei kuitenkaan onnistu sillä e.m asemassa on ratsu itseasiassa hitusen verran ketterämpi, vaikka asema on tietysti selvä tasapeli.

mattile71
Seuraa 
Viestejä198
Liittynyt6.9.2006

Kai nappuloiden liikkuvuus on kuitenkin funktio siitä, mikä on nappuloiden määrä pöydällä.Alkupelissä rartsu on hyvä, mutta loppupelissä huonompi.Vastaavasti torni on loppupelissä huomattavasti parempi kuin alussa nurkassa ollessaan.

Luin kerran Pasilan kirjastossa 600 sivuista kirjaa tietokoneshakista, joka oli kirjoitettu 70-luvulla.

Nuo tekniikat min-max algoritmi ja alpha -beta pruning on jo aikoa sitten kehitetty eikä tietokoneshakissa ole oikeastaan mitään kiinnostavaa enään.
Se on sama kuin testaisi kahta tietokonetta kumpi laskee nopeammin ja sitten laitettaisiin ihminen laskemaan.Aivan varmasti kone suoriutuu paremmin.

Minkä tahansa tietokoneohjelman pääohjelma saadaan kutistettua yhteen sivuun.

Vierailija
_jone_
Ja muuten BruteForce:ssa nappuloiden arvot määräytyvät aktiivisuuden, eli liikkuvuuden perusteella. Esimerkiksi upseereille saadaan aktiivisuusarvot:

[code:2imewdyl]ratsu 336
lähetti 560
torni 896
daami 1456
[/code:2imewdyl]
Nyt voi nostaa hattua shakkipelin luojalle, sillä ratsu+lähetti = 336+560 = 896!

Tosin sanoen torni vastaa ratsua ja lähettiä.

Kumpi on voimakkaampi, kaksi tornia vai daami?

896+896 = 1792, josta kun vähennetään daamin arvo 1792-1456 = 336!

Eli kaksi tornia on ratsun verran vahvempi kuin daami.

Luvuista saa melkein loputtomasti taitettua erilaisia yhteyksiä. Aikoinaan minulle oli melkoinen yllätys, että lähetti oli noinkin paljon ratsua voimakkaampi, mutta siihenkin sai lopulta vastauksen, kun shakin dynamiikka vain jaksoi tutkia vuodesta toiseen.




Pelataan sakkia vai kuinka? Mutta onko älyä haastaa todelliseen shakki peliin mies miestä vastaan? Itse olen kehitellyt algoritmin ja ohjelmoinut MAC:llä sellasen ohjelman, että jonen mulkkulle haisevat ohjelmat ovat todellakin vain amiksen käyneen harrasteliohjelmoijan kyrpä tuotoksia. Kyrpä on se, miksi jone itseään tulee kutsumaan ja kun ajatellaan vielä _jonen vajaita ohjelmointi taitoja niin kuka tahansa voi kuvitella että kaverihan on ihan torspo. Muka shakki argoritmeja kehittelemässä...hahahhaaaaa. Tuskin tietää mikä on sotilaan ja hevosen ero ja kuinka ne liikkuvat shakki laudalla.

Vierailija

No, jos nuo arvot normalisoidaan mittakaavaan 9, saadaan:

daami=9.00
torni=5.54
lahetti=3.46
ratsu=2.08

Kaiketi ollaan silloin samalla hehtaarilla. Toki asemallinen dynamiikka summautuu BruteForce:ssa näihin teoreettisiin suhteisiin automaattisesti.

Sivut

Uusimmat

Suosituimmat